summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Makefile1
-rw-r--r--builddefs/bootloader.mk8
-rw-r--r--builddefs/build_keyboard.mk39
-rw-r--r--builddefs/build_test.mk7
-rw-r--r--builddefs/common_features.mk143
-rw-r--r--builddefs/common_rules.mk117
-rw-r--r--builddefs/mcu_selection.mk62
-rw-r--r--builddefs/show_options.mk2
-rw-r--r--builddefs/testlist.mk1
-rw-r--r--data/mappings/defaults.json12
-rw-r--r--data/mappings/info_config.json4
-rw-r--r--data/mappings/info_rules.json3
-rw-r--r--data/schemas/definitions.jsonschema41
-rw-r--r--data/schemas/keyboard.jsonschema125
-rw-r--r--data/schemas/keymap.jsonschema5
-rw-r--r--docs/_summary.md7
-rw-r--r--docs/cli_commands.md68
-rw-r--r--docs/compatible_microcontrollers.md8
-rw-r--r--docs/config_options.md4
-rw-r--r--docs/custom_matrix.md6
-rw-r--r--docs/eeprom_driver.md103
-rw-r--r--docs/feature_converters.md95
-rw-r--r--docs/feature_dynamic_macros.md1
-rw-r--r--docs/feature_macros.md2
-rw-r--r--docs/feature_mouse_keys.md6
-rw-r--r--docs/feature_pointing_device.md262
-rw-r--r--docs/feature_rgb_matrix.md30
-rw-r--r--docs/feature_send_string.md224
-rw-r--r--docs/feature_split_keyboard.md5
-rw-r--r--docs/feature_stenography.md123
-rw-r--r--docs/feature_tap_dance.md143
-rw-r--r--docs/feature_terminal.md107
-rw-r--r--docs/flashing.md43
-rw-r--r--docs/ja/_summary.md1
-rw-r--r--docs/ja/config_options.md2
-rw-r--r--docs/ja/custom_matrix.md6
-rw-r--r--docs/ja/feature_dynamic_macros.md1
-rw-r--r--docs/ja/feature_tap_dance.md1
-rw-r--r--docs/ja/feature_terminal.md112
-rw-r--r--docs/ja/understanding_qmk.md1
-rw-r--r--docs/keycodes.md3
-rw-r--r--docs/keycodes_magic.md3
-rw-r--r--docs/platformdev_chibios_earlyinit.md2
-rw-r--r--docs/platformdev_proton_c.md77
-rw-r--r--docs/platformdev_rp2040.md125
-rw-r--r--docs/proton_c_conversion.md91
-rw-r--r--docs/quantum_painter.md25
-rw-r--r--docs/reference_info_json.md36
-rw-r--r--docs/serial_driver.md322
-rw-r--r--docs/understanding_qmk.md1
-rw-r--r--docs/ws2812_driver.md62
-rw-r--r--docs/zh-cn/_summary.md1
-rw-r--r--docs/zh-cn/custom_quantum_functions.md7
-rw-r--r--drivers/eeprom/eeprom_i2c.h5
-rw-r--r--drivers/eeprom/eeprom_spi.c42
-rw-r--r--drivers/eeprom/eeprom_wear_leveling.c23
-rw-r--r--drivers/gpio/pca9505.c166
-rw-r--r--drivers/gpio/pca9505.h67
-rw-r--r--drivers/led/aw20216.c6
-rw-r--r--drivers/led/issi/is31fl3733-simple.c6
-rw-r--r--drivers/led/issi/is31fl3733.c6
-rw-r--r--drivers/led/issi/is31fl3736.c6
-rw-r--r--drivers/led/issi/is31fl3737.c6
-rw-r--r--drivers/led/issi/is31fl3741.c6
-rw-r--r--drivers/painter/gc9a01/qp_gc9a01.c9
-rw-r--r--drivers/painter/ili9xxx/qp_ili9163.c9
-rw-r--r--drivers/painter/ili9xxx/qp_ili9341.c9
-rw-r--r--drivers/painter/ili9xxx/qp_ili9488.c120
-rw-r--r--drivers/painter/ili9xxx/qp_ili9488.h37
-rw-r--r--drivers/painter/ili9xxx/qp_ili9xxx_opcodes.h1
-rw-r--r--drivers/painter/ssd1351/qp_ssd1351.c9
-rw-r--r--drivers/painter/st77xx/qp_st7789.c9
-rw-r--r--drivers/painter/tft_panel/qp_tft_panel.c60
-rw-r--r--drivers/painter/tft_panel/qp_tft_panel.h16
-rw-r--r--drivers/ps2/ps2.h1
-rw-r--r--drivers/ps2/ps2_interrupt.c4
-rw-r--r--drivers/ps2/ps2_mouse.c19
-rw-r--r--drivers/sensors/cirque_pinnacle.c232
-rw-r--r--drivers/sensors/cirque_pinnacle.h62
-rw-r--r--drivers/sensors/cirque_pinnacle_gestures.c227
-rw-r--r--drivers/sensors/cirque_pinnacle_gestures.h107
-rw-r--r--drivers/sensors/cirque_pinnacle_i2c.c4
-rw-r--r--drivers/sensors/cirque_pinnacle_regdefs.h405
-rw-r--r--drivers/sensors/cirque_pinnacle_spi.c4
-rw-r--r--drivers/sensors/pimoroni_trackball.c13
-rw-r--r--drivers/sensors/pimoroni_trackball.h1
-rw-r--r--drivers/sensors/pmw3360.c567
-rw-r--r--drivers/sensors/pmw3360.h134
-rw-r--r--drivers/sensors/pmw3360_firmware.h288
-rw-r--r--drivers/sensors/pmw3389.c580
-rw-r--r--drivers/sensors/pmw3389.h135
-rw-r--r--drivers/sensors/pmw3389_firmware.h307
-rw-r--r--drivers/sensors/pmw33xx_common.c219
-rw-r--r--drivers/sensors/pmw33xx_common.h150
-rw-r--r--drivers/serial.h10
-rw-r--r--drivers/wear_leveling/wear_leveling_flash_spi.c101
-rw-r--r--drivers/wear_leveling/wear_leveling_flash_spi_config.h34
-rw-r--r--keyboards/1k/keymaps/tap_dance/config.h1
-rw-r--r--keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/config.h3
-rw-r--r--keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/keymap.c2
-rw-r--r--keyboards/40percentclub/gherkin/keymaps/itsaferbie/keymap.c2
-rw-r--r--keyboards/40percentclub/half_n_half/keymaps/Boy_314/keymap.c4
-rw-r--r--keyboards/40percentclub/mf68/keymaps/delivrance/rules.mk1
-rw-r--r--keyboards/adafruit/macropad/config.h137
-rw-r--r--keyboards/adafruit/macropad/halconf.h28
-rw-r--r--keyboards/adafruit/macropad/info.json24
-rw-r--r--keyboards/adafruit/macropad/keymaps/default/keymap.c114
-rw-r--r--keyboards/adafruit/macropad/lib/oled_driver_spi.h29
-rw-r--r--keyboards/adafruit/macropad/lib/ssd1306_sh1106.c827
-rw-r--r--keyboards/adafruit/macropad/macropad.c56
-rw-r--r--keyboards/adafruit/macropad/macropad.h (renamed from keyboards/boardsource/holiday/spooky/spooky.h)35
-rw-r--r--keyboards/adafruit/macropad/mcuconf.h22
-rw-r--r--keyboards/adafruit/macropad/readme.md37
-rw-r--r--keyboards/adafruit/macropad/rules.mk26
-rw-r--r--keyboards/aidansmithdotdev/fine40/config.h12
-rw-r--r--keyboards/aidansmithdotdev/fine40/fine40.c85
-rw-r--r--keyboards/aidansmithdotdev/fine40/fine40.h3
-rw-r--r--keyboards/aidansmithdotdev/fine40/info.json231
-rw-r--r--keyboards/aidansmithdotdev/fine40/keymaps/default/keymap.c43
-rw-r--r--keyboards/aidansmithdotdev/fine40/keymaps/via/keymap.c43
-rw-r--r--keyboards/aidansmithdotdev/fine40/keymaps/via/rules.mk1
-rw-r--r--keyboards/aidansmithdotdev/fine40/readme.md27
-rw-r--r--keyboards/aidansmithdotdev/fine40/rules.mk1
-rw-r--r--keyboards/annepro2/c15/config.h18
-rw-r--r--keyboards/annepro2/c15/rules.mk4
-rw-r--r--keyboards/annepro2/c18/config.h18
-rw-r--r--keyboards/annepro2/c18/rules.mk4
-rw-r--r--keyboards/annepro2/halconf.h4
-rw-r--r--keyboards/annepro2/mcuconf.h8
-rw-r--r--keyboards/bandominedoni/keymaps/led/keymap.c2
-rw-r--r--keyboards/bandominedoni/keymaps/via/keymap.c2
-rw-r--r--keyboards/basekeys/slice/rev1/keymaps/2moons/keymap.c4
-rw-r--r--keyboards/basekeys/slice/rev1_rgb/keymaps/2moons_rgb/keymap.c4
-rw-r--r--keyboards/bastardkb/charybdis/3x5/config.h4
-rw-r--r--keyboards/bastardkb/charybdis/3x5/keymaps/drashna/config.h6
-rw-r--r--keyboards/bastardkb/charybdis/4x6/config.h4
-rw-r--r--keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h8
-rw-r--r--keyboards/bastardkb/charybdis/charybdis.c51
-rw-r--r--keyboards/bastardkb/charybdis/post_config.h5
-rw-r--r--keyboards/bastardkb/charybdis/readme.md20
-rw-r--r--keyboards/bbrfkr/dynamis/config.h2
-rw-r--r--keyboards/biacco42/ergo42/keymaps/hdbx/keymap.c4
-rw-r--r--keyboards/boardsource/holiday/spooky/config.h129
-rw-r--r--keyboards/boardsource/holiday/spooky/info.json58
-rw-r--r--keyboards/boardsource/holiday/spooky/keymaps/default/keymap.c14
-rw-r--r--keyboards/boardsource/holiday/spooky/keymaps/rip_mx/keymap.c84
-rw-r--r--keyboards/boardsource/holiday/spooky/keymaps/rip_my_wallet/keymap.c83
-rw-r--r--keyboards/boardsource/holiday/spooky/rules.mk21
-rw-r--r--keyboards/boardsource/lulu/config.h50
-rw-r--r--keyboards/boardsource/lulu/info.json187
-rw-r--r--keyboards/boardsource/lulu/keymaps/default/keymap.c21
-rw-r--r--keyboards/boardsource/lulu/keymaps/via/keymap.c1
-rw-r--r--keyboards/boardsource/lulu/lulu.c425
-rw-r--r--keyboards/boardsource/lulu/lulu.h29
-rw-r--r--keyboards/boardsource/lulu/rules.mk25
-rw-r--r--keyboards/bpiphany/frosty_flake/keymaps/nikchi/config.h1
-rw-r--r--keyboards/bpiphany/frosty_flake/keymaps/nikchi/keymap.c32
-rw-r--r--keyboards/bpiphany/frosty_flake/keymaps/nikchi/variableTapDance.md5
-rw-r--r--keyboards/bpiphany/kitten_paw/keymaps/ickerwx/keymap.c4
-rw-r--r--keyboards/bpiphany/pegasushoof/keymaps/blowrak/keymap.c2
-rw-r--r--keyboards/cannonkeys/ortho75/ortho75.c73
-rw-r--r--keyboards/cannonkeys/satisfaction75/satisfaction75.c2
-rw-r--r--keyboards/cannonkeys/satisfaction75/satisfaction_oled.c4
-rwxr-xr-xkeyboards/ckeys/handwire_101/keymaps/default/keymap.c8
-rwxr-xr-xkeyboards/ckeys/handwire_101/rules.mk1
-rw-r--r--keyboards/ckeys/washington/keymaps/default/keymap.c4
-rw-r--r--keyboards/clueboard/66/keymaps/magicmonty/keymap.c2
-rw-r--r--keyboards/contra/keymaps/default/keymap.c2
-rw-r--r--keyboards/crkbd/keymaps/dsanchezseco/keymap.c2
-rw-r--r--keyboards/crkbd/keymaps/edvorakjp/keymap.c4
-rw-r--r--keyboards/crkbd/keymaps/edvorakjp/oled.c2
-rw-r--r--keyboards/crkbd/keymaps/jarred/keymap.c2
-rw-r--r--keyboards/delikeeb/vaneela/keymaps/default/keymap.c2
-rw-r--r--keyboards/delikeeb/vaneela/keymaps/via/keymap.c2
-rwxr-xr-xkeyboards/dichotomy/keymaps/default/keymap.c4
-rw-r--r--keyboards/dm9records/plaid/keymaps/default/keymap.c2
-rw-r--r--keyboards/dm9records/plaid/keymaps/thehalfdeafchef/keymap.c2
-rw-r--r--keyboards/doio/kb16/keymaps/default/keymap.c3
-rw-r--r--keyboards/doppelganger/doppelganger.c36
-rw-r--r--keyboards/duck/lightsaver/keymaps/rasmus/keymap.c4
-rw-r--r--keyboards/dz60/keymaps/iso_split-spacebar/keymap.c28
-rw-r--r--keyboards/dz60/keymaps/marianas/customLogic.c2
-rw-r--r--keyboards/dz60/keymaps/xtonhasvim/keymap.c4
-rw-r--r--keyboards/dztech/dz60rgb/keymaps/matthewrobo/keymap.c2
-rw-r--r--keyboards/dztech/dz60rgb/keymaps/mekanist/keymap.c4
-rw-r--r--keyboards/dztech/dz60rgb/keymaps/perseid/keymap.c4
-rw-r--r--keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c4
-rw-r--r--keyboards/dztech/dz65rgb/keymaps/drootz/keymap.c156
-rw-r--r--keyboards/dztech/dz65rgb/keymaps/matthewrobo/keymap.c2
-rwxr-xr-xkeyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/blakedietz/keymap.c3
-rw-r--r--keyboards/ergodox_ez/keymaps/bpruitt-goddard/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/default_osx/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/dvorak_42_key/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/hacker_dvorak/config.h1
-rw-r--r--keyboards/ergodox_ez/keymaps/hacker_dvorak/tap_dance/tap_dance_actions.c38
-rw-r--r--keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/heartrobotninja/keymap.c4
-rw-r--r--keyboards/ergodox_ez/keymaps/kou/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/lukaus/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/matrixman/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/nathanvercaemert/keymap.c3
-rw-r--r--keyboards/ergodox_ez/keymaps/nfriend/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/profet_80/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/pvinis/keymap.c6
-rw-r--r--keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c3
-rw-r--r--keyboards/ergodox_ez/keymaps/rishka/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/skug/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/smurmann/keymap.c8
-rw-r--r--keyboards/ergodox_ez/keymaps/steno/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/testing/keymap.c2
-rw-r--r--keyboards/ergodox_ez/keymaps/vim/keymap.c2
-rwxr-xr-xkeyboards/ergodox_ez/util/compile_keymap.py110
-rw-r--r--keyboards/ergoslab/keymaps/default/keymap.c2
-rw-r--r--keyboards/exclusive/e65/keymaps/masterzen/keymap.c2
-rw-r--r--keyboards/exclusive/e7v1/keymaps/masterzen/keymap.c2
-rw-r--r--keyboards/flehrad/bigswitch/keymaps/333fred/config.h1
-rw-r--r--keyboards/fractal/keymaps/default/keymap.c2
-rw-r--r--keyboards/gboards/gergo/keymaps/colemak/keymap.c5
-rw-r--r--keyboards/gboards/gergoplex/keymaps/georgepetri/config.h2
-rw-r--r--keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c11
-rw-r--r--keyboards/gh60/revc/keymaps/dbroqua/keymap.c4
-rw-r--r--keyboards/gh60/revc/keymaps/default/keymap.c2
-rw-r--r--keyboards/gh60/revc/keymaps/robotmaxtron/keymap.c2
-rw-r--r--keyboards/gh60/satan/keymaps/addcninblue/keymap.c2
-rw-r--r--keyboards/glenpickle/chimera_ergo/keymaps/default/keymap.c2
-rw-r--r--keyboards/glenpickle/chimera_ls/keymaps/default/keymap.c2
-rw-r--r--keyboards/glenpickle/chimera_ortho/keymaps/default/keymap.c2
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/ansi.c332
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/ansi.h54
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/config.h (renamed from quantum/process_keycode/process_terminal_nop.h)7
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/info.json119
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/keymap.c46
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/readme.md1
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/config.h22
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/keymap.c53
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/rules.mk1
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/readme.md23
-rw-r--r--keyboards/gmmk/gmmk2/p96/ansi/rules.mk22
-rw-r--r--keyboards/gmmk/gmmk2/p96/config.h130
-rw-r--r--keyboards/gmmk/gmmk2/p96/halconf.h29
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/config.h21
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/info.json120
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/iso.c328
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/iso.h54
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/keymaps/default/keymap.c44
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/keymaps/default/readme.md1
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/keymaps/via/config.h22
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/keymaps/via/keymap.c51
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/keymaps/via/rules.mk1
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/readme.md23
-rw-r--r--keyboards/gmmk/gmmk2/p96/iso/rules.mk22
-rw-r--r--keyboards/gmmk/gmmk2/p96/mcuconf.h30
-rw-r--r--keyboards/gmmk/gmmk2/p96/p96.c17
-rw-r--r--keyboards/gmmk/gmmk2/p96/p96.h (renamed from quantum/process_keycode/process_terminal.h)11
-rw-r--r--keyboards/gon/nerdtkl/keymaps/gam3cat/keymap.c2
-rw-r--r--keyboards/handwired/ergocheap/config.h1
-rw-r--r--keyboards/handwired/frenchdev/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/hillside/0_1/0_1.c4
-rw-r--r--keyboards/handwired/hillside/0_1/keymaps/default/keymap.json101
-rw-r--r--keyboards/handwired/hillside/0_1/keymaps/default/readme.md212
-rw-r--r--keyboards/handwired/hillside/48/48.c4
-rw-r--r--keyboards/handwired/hillside/48/48.h (renamed from keyboards/handwired/hillside/0_1/0_1.h)2
-rw-r--r--keyboards/handwired/hillside/48/config.h (renamed from keyboards/handwired/hillside/0_1/config.h)0
-rw-r--r--keyboards/handwired/hillside/48/info.json (renamed from keyboards/handwired/hillside/0_1/info.json)22
-rw-r--r--keyboards/handwired/hillside/48/keymaps/default/config.h9
-rw-r--r--keyboards/handwired/hillside/48/keymaps/default/keymap.json88
-rw-r--r--keyboards/handwired/hillside/48/keymaps/default/readme.md159
-rw-r--r--keyboards/handwired/hillside/48/keymaps/default/rules.mk1
-rwxr-xr-xkeyboards/handwired/hillside/48/keymaps/json2hill48.py (renamed from keyboards/handwired/hillside/0_1/keymaps/json2hill.py)40
-rw-r--r--keyboards/handwired/hillside/48/keymaps/via/keymap.json (renamed from keyboards/handwired/hillside/0_1/keymaps/via/keymap.json)2
-rw-r--r--keyboards/handwired/hillside/48/readme.md (renamed from keyboards/handwired/hillside/0_1/readme.md)6
-rw-r--r--keyboards/handwired/hillside/48/rules.mk (renamed from keyboards/handwired/hillside/0_1/rules.mk)0
-rw-r--r--keyboards/handwired/kbod/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/onekey/config.h1
-rw-r--r--keyboards/handwired/onekey/elite_c/config.h3
-rw-r--r--keyboards/handwired/onekey/keymaps/chibios_waiting_test/config.h12
-rw-r--r--keyboards/handwired/onekey/keymaps/chibios_waiting_test/keymap.c47
-rw-r--r--keyboards/handwired/onekey/onekey.c11
-rw-r--r--keyboards/handwired/onekey/promicro/config.h3
-rw-r--r--keyboards/handwired/onekey/rp2040/config.h22
-rw-r--r--keyboards/handwired/onekey/rp2040/readme.md12
-rw-r--r--keyboards/handwired/onekey/rp2040/rules.mk3
-rw-r--r--keyboards/handwired/onekey/teensy_2/config.h3
-rw-r--r--keyboards/handwired/onekey/teensy_2pp/config.h3
-rw-r--r--keyboards/handwired/onekey/teensy_35/chconf.h28
-rw-r--r--keyboards/handwired/onekey/teensy_35/config.h32
-rw-r--r--keyboards/handwired/onekey/teensy_35/halconf.h28
-rw-r--r--keyboards/handwired/onekey/teensy_35/mcuconf.h50
-rw-r--r--keyboards/handwired/onekey/teensy_35/rules.mk8
-rw-r--r--keyboards/handwired/ortho5x14/keymaps/2u/keymap.c6
-rw-r--r--keyboards/handwired/ortho5x14/keymaps/split1/keymap.c6
-rw-r--r--keyboards/handwired/ortho_brass/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/prime_exl/keymaps/via/keymap.c2
-rw-r--r--keyboards/handwired/promethium/keymaps/default/keymap.c6
-rw-r--r--keyboards/handwired/promethium/keymaps/priyadi/config.h6
-rw-r--r--keyboards/handwired/promethium/keymaps/priyadi/keymap.c8
-rw-r--r--keyboards/handwired/riblee_f401/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/riblee_f411/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/rs60/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/terminus_mini/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/tractyl_manuform/4x6_right/config.h4
-rw-r--r--keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h4
-rw-r--r--keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h5
-rw-r--r--keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h5
-rw-r--r--keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h4
-rw-r--r--keyboards/handwired/tractyl_manuform/tractyl_manuform.c27
-rw-r--r--keyboards/handwired/traveller/keymaps/default/keymap.c2
-rw-r--r--keyboards/handwired/tritium_numpad/keymaps/blu/keymap.c2
-rw-r--r--keyboards/handwired/uthol/rev3/config.h1
-rw-r--r--keyboards/helix/pico/keymaps/mtei/config.h2
-rw-r--r--keyboards/helix/pico/keymaps/mtei/keymap.c2
-rw-r--r--keyboards/helix/rev2/keymaps/default/oled_display.c2
-rw-r--r--keyboards/helix/rev2/keymaps/edvorakjp/keymap.c4
-rw-r--r--keyboards/helix/rev2/keymaps/edvorakjp/oled.c2
-rw-r--r--keyboards/helix/rev2/keymaps/five_rows/config.h2
-rw-r--r--keyboards/helix/rev2/keymaps/five_rows/keymap.c4
-rw-r--r--keyboards/helix/rev3_5rows/keymaps/five_rows/config.h2
-rw-r--r--keyboards/helix/rev3_5rows/keymaps/five_rows/keymap.c4
-rw-r--r--keyboards/hineybush/h87a/keymaps/gam3cat/keymap.c2
-rw-r--r--keyboards/hotdox/keymaps/default/keymap.c2
-rw-r--r--keyboards/hotdox/keymaps/eozaki/keymap.c2
-rw-r--r--keyboards/hotdox/keymaps/kloki/keymap.c2
-rw-r--r--keyboards/idobao/id67/config.h140
-rw-r--r--keyboards/idobao/id67/id67.c100
-rw-r--r--keyboards/idobao/id67/id67.h36
-rw-r--r--keyboards/idobao/id67/info.json161
-rw-r--r--keyboards/idobao/id67/keymaps/default/keymap.c50
-rw-r--r--keyboards/idobao/id67/keymaps/idobao/keymap.c341
-rw-r--r--keyboards/idobao/id67/keymaps/idobao/rules.mk (renamed from keyboards/idobao/id80/v3/keymaps/via/rules.mk)0
-rw-r--r--keyboards/idobao/id67/keymaps/thewerther/config.h18
-rw-r--r--keyboards/idobao/id67/keymaps/thewerther/keymap.c25
-rw-r--r--keyboards/idobao/id67/keymaps/via/keymap.c63
-rw-r--r--keyboards/idobao/id67/keymaps/vinorodrigues/config.h22
-rw-r--r--keyboards/idobao/id67/keymaps/vinorodrigues/keymap.c80
-rw-r--r--keyboards/idobao/id67/keymaps/vinorodrigues/rules.mk4
-rw-r--r--keyboards/idobao/id67/post_rules.mk10
-rw-r--r--keyboards/idobao/id67/readme.md23
-rw-r--r--keyboards/idobao/id67/rules.mk16
-rw-r--r--keyboards/idobao/id80/v3/ansi/ansi.c76
-rw-r--r--keyboards/idobao/id80/v3/ansi/ansi.h6
-rw-r--r--keyboards/idobao/id80/v3/ansi/config.h97
-rw-r--r--keyboards/idobao/id80/v3/ansi/info.json121
-rw-r--r--keyboards/idobao/id80/v3/ansi/keymaps/default/keymap.c56
-rw-r--r--keyboards/idobao/id80/v3/ansi/keymaps/idobao/keymap.c315
-rw-r--r--keyboards/idobao/id80/v3/ansi/keymaps/idobao/rules.mk2
-rw-r--r--keyboards/idobao/id80/v3/ansi/keymaps/via/keymap.c90
-rw-r--r--keyboards/idobao/id80/v3/ansi/keymaps/via/rules.mk2
-rw-r--r--keyboards/idobao/id80/v3/ansi/rules.mk5
-rw-r--r--keyboards/idobao/id80/v3/config.h131
-rw-r--r--keyboards/idobao/id80/v3/info.json96
-rw-r--r--keyboards/idobao/id80/v3/keymaps/default/keymap.c36
-rw-r--r--keyboards/idobao/id80/v3/keymaps/default/readme.md1
-rw-r--r--keyboards/idobao/id80/v3/keymaps/via/keymap.c52
-rw-r--r--keyboards/idobao/id80/v3/readme.md31
-rw-r--r--keyboards/idobao/id80/v3/rules.mk25
-rw-r--r--keyboards/idobao/id80/v3/v3.c62
-rw-r--r--keyboards/idobao/id80/v3/v3.h37
-rw-r--r--keyboards/idobao/id87/v2/config.h200
-rw-r--r--keyboards/idobao/id87/v2/info.json209
-rw-r--r--keyboards/idobao/id87/v2/keymaps/default/keymap.c77
-rw-r--r--keyboards/idobao/id87/v2/keymaps/default/readme.md1
-rw-r--r--keyboards/idobao/id87/v2/keymaps/idobao/config.h4
-rw-r--r--keyboards/idobao/id87/v2/keymaps/idobao/keymap.c299
-rw-r--r--keyboards/idobao/id87/v2/keymaps/idobao/rules.mk3
-rw-r--r--keyboards/idobao/id87/v2/keymaps/via/config.h4
-rw-r--r--keyboards/idobao/id87/v2/keymaps/via/keymap.c115
-rw-r--r--keyboards/idobao/id87/v2/keymaps/via/rules.mk1
-rw-r--r--keyboards/idobao/id87/v2/readme.md28
-rw-r--r--keyboards/idobao/id87/v2/rules.mk21
-rw-r--r--keyboards/idobao/id87/v2/v2.c104
-rw-r--r--keyboards/idobao/id87/v2/v2.h38
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/default/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/gordon/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/halfkeyboard/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/input_club/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/narze/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/nordic_ergo/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/rask/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/rjhilgefort/keymap.c2
-rw-r--r--keyboards/input_club/ergodox_infinity/keymaps/trulyergonomic/keymap.c2
-rw-r--r--keyboards/input_club/infinity60/keymaps/jpetermans/keymap.c4
-rw-r--r--keyboards/jc65/v32u4/keymaps/gam3cat/keymap.c2
-rw-r--r--keyboards/jones/v03/keymaps/default_jp/config.h1
-rw-r--r--keyboards/jones/v03/keymaps/default_jp/keymap.c15
-rw-r--r--keyboards/jones/v03_1/keymaps/default_ansi/config.h1
-rw-r--r--keyboards/jones/v03_1/keymaps/default_ansi/keymap.c17
-rw-r--r--keyboards/jones/v03_1/keymaps/default_jp/config.h1
-rw-r--r--keyboards/jones/v03_1/keymaps/default_jp/keymap.c17
-rw-r--r--keyboards/kakunpc/angel64/alpha/keymaps/default/keymap.c2
-rw-r--r--keyboards/kakunpc/angel64/rev1/keymaps/kakunpc/keymap.c2
-rw-r--r--keyboards/kakunpc/suihankey/alpha/keymaps/default/keymap.c2
-rw-r--r--keyboards/kakunpc/suihankey/rev1/keymaps/default/keymap.c2
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/othi/keymap.c3
-rw-r--r--keyboards/kbdfans/kbd75/keymaps/edulpn/keymap.c2
-rw-r--r--keyboards/kbdfans/niu_mini/keymaps/tobias/keymap.c30
-rw-r--r--keyboards/kbdfans/niu_mini/keymaps/xtonhasvim/keymap.c2
-rw-r--r--keyboards/keebio/bdn9/keymaps/vosechu-ksp/keymap.c2
-rw-r--r--keyboards/keebio/bfo9000/keymaps/abstractkb/keymap.c5
-rw-r--r--keyboards/keebio/iris/keymaps/edvorakjp/keymap.c4
-rw-r--r--keyboards/keebio/iris/keymaps/jerryhcooke/keymap.c4
-rw-r--r--keyboards/keebio/iris/keymaps/sq5rix/keymap.c3
-rw-r--r--keyboards/keebio/levinson/keymaps/issmirnov/keymap.c2
-rw-r--r--keyboards/keebio/levinson/keymaps/issmirnov/rgb.c2
-rw-r--r--keyboards/keebio/levinson/keymaps/issmirnov/rgb.h2
-rw-r--r--keyboards/keebio/levinson/keymaps/xtonhasvim/keymap.c2
-rw-r--r--keyboards/keebio/nyquist/keymaps/danielhklein/config.h4
-rw-r--r--keyboards/keebio/nyquist/keymaps/pitty/keymap.c2
-rw-r--r--keyboards/keebio/quefrency/keymaps/georgepetri/keymap.c2
-rw-r--r--keyboards/keycapsss/o4l_5x12/keymaps/default/keymap.c2
-rw-r--r--keyboards/keychron/q2/config.h3
-rw-r--r--keyboards/keychron/q2/rev_0110/rules.mk3
-rw-r--r--keyboards/keychron/q2/rev_0111/rules.mk3
-rw-r--r--keyboards/keychron/q2/rev_0112/rules.mk3
-rw-r--r--keyboards/keychron/q2/rev_0113/rules.mk3
-rwxr-xr-xkeyboards/keyhive/honeycomb/keymaps/default/keymap.c2
-rw-r--r--keyboards/keyhive/navi10/keymaps/default/keymap.c2
-rw-r--r--keyboards/keyhive/navi10/keymaps/devdev/keymap.c2
-rw-r--r--keyboards/keyhive/navi10/keymaps/emdarcher/keymap.c2
-rw-r--r--keyboards/kinesis/keymaps/milestogo/keymap.c2
-rw-r--r--keyboards/kprepublic/bm40hsrgb/keymaps/gabustoledo/config.h4
-rw-r--r--keyboards/kprepublic/bm40hsrgb/keymaps/signynt/config.h4
-rw-r--r--keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_loud/config.h4
-rw-r--r--keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_quiet/config.h4
-rw-r--r--keyboards/kprepublic/cospad/keymaps/detrus/keymap.c6
-rw-r--r--keyboards/kprepublic/jj50/keymaps/abstractkb/keymap.c2
-rw-r--r--keyboards/kprepublic/jj50/keymaps/abstractkb_gergomatch/keymap.c2
-rw-r--r--keyboards/kprepublic/jj50/keymaps/archetype/config.h2
-rw-r--r--keyboards/kprepublic/jj50/keymaps/archetype/keymap.c11
-rw-r--r--keyboards/ktec/ergodone/keymaps/eozaki/keymap.c2
-rw-r--r--keyboards/ktec/ergodone/keymaps/erovia/keymap.c2
-rw-r--r--keyboards/ktec/ergodone/keymaps/kloki/keymap.c2
-rw-r--r--keyboards/ktec/ergodone/keymaps/vega/keymap.c2
-rw-r--r--keyboards/leeku/finger65/keymaps/madhatter/keymap.c2
-rw-r--r--keyboards/lets_split/keymaps/cpeters1982/keymap.c2
-rw-r--r--keyboards/lets_split/keymaps/geripgeri/keymap.c2
-rw-r--r--keyboards/lets_split/keymaps/pitty/keymap.c2
-rw-r--r--keyboards/lily58/lib/layer_state_reader.c2
-rw-r--r--keyboards/m10a/keymaps/gam3cat/keymap.c2
-rw-r--r--keyboards/maple_computing/lets_split_eh/keymaps/romus/keymap.c4
-rw-r--r--keyboards/massdrop/alt/keymaps/pregame/rules.mk1
-rw-r--r--keyboards/massdrop/ctrl/keymaps/endgame/rules.mk1
-rw-r--r--keyboards/massdrop/ctrl/keymaps/matthewrobo/rules.mk1
-rw-r--r--keyboards/massdrop/ctrl/keymaps/xanimos/rules.mk1
-rw-r--r--keyboards/mechkeys/mechmini/v2/keymaps/wsturgiss/keymap.c3
-rw-r--r--keyboards/mechllama/g35/keymaps/default/keymap.c2
-rw-r--r--keyboards/mechlovin/hannah910/hannah910.c6
-rw-r--r--keyboards/mechlovin/hex4b/keymaps/nazzer/keymap.c28
-rw-r--r--keyboards/minimacro5/keymaps/devdev/keymap.c2
-rw-r--r--keyboards/mitosis/keymaps/carvac_dv/keymap.c3
-rw-r--r--keyboards/mitosis/keymaps/datagrok/keymap.c4
-rw-r--r--keyboards/mitosis/keymaps/default/keymap.c5
-rw-r--r--keyboards/mitosis/keymaps/mjt/keymap.c4
-rw-r--r--keyboards/mitosis/keymaps/nzen/keymap.c4
-rw-r--r--keyboards/mlego/m48/keymaps/default/keymap.c8
-rw-r--r--keyboards/mschwingen/modelm/modelm.c4
-rw-r--r--keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c4
-rw-r--r--keyboards/oddball/config.h2
-rw-r--r--keyboards/pearl/keymaps/cijanzen/keymap.c2
-rw-r--r--keyboards/pearl/keymaps/jetpacktuxedo/keymap.c2
-rwxr-xr-xkeyboards/pearl/keymaps/phil/keymap.c2
-rw-r--r--keyboards/pearl/keymaps/rask/keymap.c2
-rw-r--r--keyboards/percent/canoe/keymaps/dhertz/keymap.c4
-rw-r--r--keyboards/phoenix/phoenix.c2
-rw-r--r--keyboards/planck/keymaps/ariccb/config.h1
-rw-r--r--keyboards/planck/keymaps/ariccb/keymap.c13
-rw-r--r--keyboards/planck/keymaps/aviator/keymap.c8
-rw-r--r--keyboards/planck/keymaps/charlesrocket/keymap.c2
-rw-r--r--keyboards/planck/keymaps/default/keymap.c2
-rw-r--r--keyboards/planck/keymaps/grahampheath/keymap.c2
-rw-r--r--keyboards/planck/keymaps/oryx/keymap.c2
-rw-r--r--keyboards/planck/keymaps/priyadi/config.h6
-rw-r--r--keyboards/planck/keymaps/roguepullrequest/rules.mk1
-rw-r--r--keyboards/planck/keymaps/rootiest/config.h1
-rw-r--r--keyboards/planck/keymaps/rootiest/keymap.c25
-rw-r--r--keyboards/planck/keymaps/rootiest/rules.mk3
-rw-r--r--keyboards/planck/keymaps/synth_sample/keymap.c8
-rw-r--r--keyboards/planck/keymaps/synth_wavetable/keymap.c8
-rw-r--r--keyboards/planck/keymaps/tom/keymap.c2
-rw-r--r--keyboards/planck/keymaps/tylerwince/keymap.c4
-rw-r--r--keyboards/planck/rev6_drop/matrix.c25
-rw-r--r--keyboards/ploopyco/mouse/config.h4
-rw-r--r--keyboards/ploopyco/mouse/keymaps/drashna/config.h2
-rw-r--r--keyboards/ploopyco/trackball/config.h4
-rw-r--r--keyboards/preonic/keymaps/default/keymap.c2
-rw-r--r--keyboards/preonic/keymaps/dudeofawesome/keymap.c2
-rw-r--r--keyboards/preonic/keymaps/senseored/keymap.c2
-rw-r--r--keyboards/preonic/rev3_drop/matrix.c25
-rw-r--r--keyboards/primekb/prime_e/keymaps/via/keymap.c2
-rw-r--r--keyboards/redox_w/keymaps/italian/keymap.c12
-rw-r--r--keyboards/redscarf_i/redscarf_i.c2
-rw-r--r--keyboards/rgbkb/pan/keymaps/default/keymap.c2
-rw-r--r--keyboards/rgbkb/sol/keymaps/default/keymap.c4
-rw-r--r--keyboards/rgbkb/sol/keymaps/xyverz/keymap.c4
-rw-r--r--keyboards/rgbkb/zen/rev2/rev2.c2
-rw-r--r--keyboards/rgbkb/zygomorph/keymaps/default_oled/keymap.c2
-rw-r--r--keyboards/rocketboard_16/keymaps/default/keymap.c4
-rw-r--r--keyboards/rocketboard_16/keymaps/via/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/7skb/keymaps/salicylic/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/7splus/keymaps/salicylic/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/jisplit89/keymaps/salicylic/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/naked60/keymaps/salicylic/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_nafuda/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_setta21/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/naked64/keymaps/salicylic/keymap.c4
-rw-r--r--keyboards/salicylic_acid3/naked64/keymaps/salicylic_with_setta21/keymap.c4
-rw-r--r--keyboards/satt/comet46/keymaps/default-rgbled/keymap.c2
-rw-r--r--keyboards/satt/comet46/keymaps/default/keymap.c4
-rw-r--r--keyboards/satt/comet46/keymaps/satt/keymap.c4
-rw-r--r--keyboards/splitkb/kyria/keymaps/j-inc/keymap.c2
-rw-r--r--keyboards/splitkb/kyria/keymaps/j-inc/rules.mk1
-rw-r--r--keyboards/splitkb/kyria/keymaps/ninjonas/oled.c2
-rw-r--r--keyboards/splitkb/kyria/keymaps/thomasbaart/keymap.c4
-rw-r--r--keyboards/splitography/keymaps/jeandeaual/keymap.c2
-rw-r--r--keyboards/splitography/keymaps/multi/keymap.c2
-rwxr-xr-xkeyboards/tetris/keymaps/default/keymap.c4
-rw-r--r--keyboards/thevankeyboards/minivan/keymaps/belak/config.h1
-rw-r--r--keyboards/thevankeyboards/minivan/keymaps/belak/keymap.c21
-rw-r--r--keyboards/thevankeyboards/minivan/keymaps/halvves/config.h1
-rw-r--r--keyboards/thevankeyboards/roadkit/keymaps/flipphone/keymap.c2
-rw-r--r--keyboards/tzarc/djinn/djinn.c2
-rw-r--r--keyboards/tzarc/djinn/graphics/theme_djinn_default.c10
-rw-r--r--keyboards/v60_type_r/keymaps/xtonhasvim/keymap.c3
-rw-r--r--keyboards/woodkeys/bigseries/1key/keymaps/dudeofawesome/config.h1
-rw-r--r--keyboards/work_louder/work_board/keymaps/default/keymap.c6
-rw-r--r--keyboards/xiudi/xd002/keymaps/tap_dance/config.h1
-rw-r--r--keyboards/xiudi/xd60/keymaps/birkir/keymap.c2
-rw-r--r--keyboards/xiudi/xd60/keymaps/kmontag42/keymap.c2
-rw-r--r--keyboards/xiudi/xd75/keymaps/arpinfidel/keymap.c2
-rw-r--r--keyboards/xiudi/xd75/keymaps/cbbrowne/keymap.c2
-rw-r--r--keyboards/xiudi/xd75/keymaps/kloki/keymap.c2
-rw-r--r--keyboards/xiudi/xd75/keymaps/tdl-jturner/keymap.c2
-rw-r--r--keyboards/zfrontier/big_switch/config.h1
-rw-r--r--layouts/community/66_ansi/xyverz/config.h1
-rw-r--r--layouts/community/ergodox/ab/keymap.c2
-rw-r--r--layouts/community/ergodox/absenth/keymap.c2
-rw-r--r--layouts/community/ergodox/adam/config.h2
-rw-r--r--layouts/community/ergodox/adam/keymap.c2
-rw-r--r--layouts/community/ergodox/adnw_k_o_y/keymap.c2
-rw-r--r--layouts/community/ergodox/alexjj/keymap.c2
-rw-r--r--layouts/community/ergodox/andrew_osx/keymap.c2
-rw-r--r--layouts/community/ergodox/berfarah/keymap.c4
-rw-r--r--layouts/community/ergodox/bryan/keymap.c2
-rw-r--r--layouts/community/ergodox/choromanski/keymap.c42
-rw-r--r--layouts/community/ergodox/colemak/keymap.c2
-rw-r--r--layouts/community/ergodox/colemak_code_friendly/keymap.c20
-rw-r--r--layouts/community/ergodox/colemak_programmer/keymap.c8
-rw-r--r--layouts/community/ergodox/common_nighthawk/keymap.c2
-rw-r--r--layouts/community/ergodox/csharp_dev/keymap.c40
-rw-r--r--layouts/community/ergodox/dave/keymap.c2
-rw-r--r--layouts/community/ergodox/deadcyclo/keymap.c16
-rw-r--r--layouts/community/ergodox/dragon788/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_emacs/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_emacs_software/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_intl_squisher/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_plover/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_programmer/keymap.c68
-rw-r--r--layouts/community/ergodox/dvorak_programmer_swe/keymap.c2
-rw-r--r--layouts/community/ergodox/dvorak_spanish/keymap.c43
-rw-r--r--layouts/community/ergodox/dvorak_svorak_a5/keymap.c2
-rw-r--r--layouts/community/ergodox/emacs_osx_dk/keymap.c2
-rw-r--r--layouts/community/ergodox/french_hacker/keymap.c2
-rw-r--r--layouts/community/ergodox/galson/keymap.c4
-rw-r--r--layouts/community/ergodox/german-kinergo/keymap.c2
-rw-r--r--layouts/community/ergodox/german-lukas/keymap.c2
-rw-r--r--layouts/community/ergodox/german-manuneo/compile_keymap.py110
-rw-r--r--layouts/community/ergodox/german-manuneo/keymap.c2
-rw-r--r--layouts/community/ergodox/german/keymap.c2
-rw-r--r--layouts/community/ergodox/haegin/keymap.c2
-rw-r--r--layouts/community/ergodox/ishigoya-jp/keymap.c78
-rw-r--r--layouts/community/ergodox/issmirnov/keymap.c6
-rw-r--r--layouts/community/ergodox/italian/keymap.c4
-rw-r--r--layouts/community/ergodox/j3rn/keymap.c2
-rw-r--r--layouts/community/ergodox/jackhumbert/keymap.c14
-rw-r--r--layouts/community/ergodox/jacobono/keymap.c2
-rw-r--r--layouts/community/ergodox/jafo/keymap.c2
-rw-r--r--layouts/community/ergodox/jgarr/keymap.c2
-rw-r--r--layouts/community/ergodox/josh/keymap.c2
-rw-r--r--layouts/community/ergodox/kastyle/keymap.c4
-rw-r--r--layouts/community/ergodox/kejadlen/keymap.c2
-rw-r--r--layouts/community/ergodox/kines-ish/keymap.c2
-rw-r--r--layouts/community/ergodox/kristian/keymap.c2
-rw-r--r--layouts/community/ergodox/maz/keymap.c2
-rw-r--r--layouts/community/ergodox/mclennon_osx/keymap.c2
-rw-r--r--layouts/community/ergodox/meagerfindings/keymap.c2
-rw-r--r--layouts/community/ergodox/msc/keymap.c2
-rw-r--r--layouts/community/ergodox/naps62/keymap.c2
-rw-r--r--layouts/community/ergodox/neo2_on_qwertz_hardware/keymap.c4
-rw-r--r--layouts/community/ergodox/osx_de/keymap.c197
-rw-r--r--layouts/community/ergodox/osx_de_adnw_koy/keymap.c153
-rw-r--r--layouts/community/ergodox/osx_de_experimental/keymap.c555
-rw-r--r--layouts/community/ergodox/osx_fr/keymap.c2
-rw-r--r--layouts/community/ergodox/osx_kinesis_pnut/keymap.c2
-rw-r--r--layouts/community/ergodox/osx_neo2/keymap.c2
-rw-r--r--layouts/community/ergodox/phoenix/keymap.c2
-rw-r--r--layouts/community/ergodox/plover/keymap.c2
-rw-r--r--layouts/community/ergodox/qwerty_code_friendly/keymap.c2
-rw-r--r--layouts/community/ergodox/reset_eeprom/keymap.c2
-rw-r--r--layouts/community/ergodox/romanzolotarev-norman-plover-osx-hjkl/keymap.c2
-rw-r--r--layouts/community/ergodox/romanzolotarev-norman-plover-osx/keymap.c2
-rw-r--r--layouts/community/ergodox/romanzolotarev-norman-qwerty-osx/keymap.c2
-rw-r--r--layouts/community/ergodox/sethbc/keymap.c2
-rw-r--r--layouts/community/ergodox/siroken3/keymap.c2
-rw-r--r--layouts/community/ergodox/sneako/keymap.c2
-rw-r--r--layouts/community/ergodox/software_neo2/keymap.c2
-rw-r--r--layouts/community/ergodox/swedish-lindhe/keymap.c2
-rw-r--r--layouts/community/ergodox/swedish/keymap.c2
-rw-r--r--layouts/community/ergodox/swissgerman/keymap.c2
-rw-r--r--layouts/community/ergodox/techtomas/keymap.c2
-rw-r--r--layouts/community/ergodox/tkuichooseyou/keymap.c2
-rw-r--r--layouts/community/ergodox/tonyabra_osx/keymap.c2
-rw-r--r--layouts/community/ergodox/townk_osx/keymap.c2
-rw-r--r--layouts/community/ergodox/twentylives_dvorak_with_hebrew/keymap.c22
-rw-r--r--layouts/community/ergodox/win10_writers-block/keymap.c28
-rw-r--r--layouts/community/ergodox/xyverz/keymap.c6
-rw-r--r--layouts/community/ergodox/zweihander-macos/keymap.c2
-rw-r--r--layouts/community/ortho_4x12/peej/keymap.c2
m---------lib/chibios0
m---------lib/chibios-contrib0
-rw-r--r--lib/fnv/Makefile304
-rw-r--r--lib/fnv/README158
-rw-r--r--lib/fnv/fnv.h249
-rw-r--r--lib/fnv/fnv32.c467
-rw-r--r--lib/fnv/fnv64.c591
-rw-r--r--lib/fnv/hash_32.c156
-rw-r--r--lib/fnv/hash_32a.c144
-rw-r--r--lib/fnv/hash_64.c312
-rw-r--r--lib/fnv/hash_64a.c291
-rw-r--r--lib/fnv/have_ulong64.c58
-rw-r--r--lib/fnv/longlong.h18
-rw-r--r--lib/fnv/qmk_fnv_type_validation.c14
-rw-r--r--lib/fnv/test_fnv.c2237
m---------lib/lufa0
m---------lib/pico-sdk0
m---------lib/printf0
-rw-r--r--lib/python/qmk/c_parse.py3
-rw-r--r--lib/python/qmk/cli/__init__.py3
-rw-r--r--lib/python/qmk/cli/doctor/macos.py2
-rw-r--r--lib/python/qmk/cli/flash.py2
-rwxr-xr-xlib/python/qmk/cli/generate/config_h.py36
-rwxr-xr-xlib/python/qmk/cli/generate/info_json.py8
-rw-r--r--lib/python/qmk/cli/import/__init__.py0
-rw-r--r--lib/python/qmk/cli/import/kbfirmware.py25
-rw-r--r--lib/python/qmk/cli/import/keyboard.py23
-rw-r--r--lib/python/qmk/cli/import/keymap.py23
-rw-r--r--lib/python/qmk/constants.py2
-rw-r--r--lib/python/qmk/git.py4
-rw-r--r--lib/python/qmk/importers.py148
-rw-r--r--lib/python/qmk/info.py62
-rw-r--r--lib/python/qmk/json_schema.py6
m---------lib/vusb0
-rw-r--r--platforms/arm_atsam/platform.mk3
-rw-r--r--platforms/avr/drivers/i2c_master.c12
-rw-r--r--platforms/avr/drivers/i2c_master.h2
-rw-r--r--platforms/avr/drivers/ps2/ps2_usart.c4
-rw-r--r--platforms/avr/platform.mk3
-rw-r--r--platforms/chibios/_pin_defs.h5
-rw-r--r--platforms/chibios/_wait.h6
-rw-r--r--platforms/chibios/boards/GENERIC_PROMICRO_RP2040/board/board.mk9
-rw-r--r--platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/board.h12
-rw-r--r--platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/chconf.h13
-rw-r--r--platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/config.h62
-rw-r--r--platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h98
-rw-r--r--platforms/chibios/boards/GENERIC_RP_RP2040/board/board.mk9
-rw-r--r--platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h12
-rw-r--r--platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h13
-rw-r--r--platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h98
-rw-r--r--platforms/chibios/boards/QMK_PM2040/board/board.mk9
-rw-r--r--platforms/chibios/boards/QMK_PM2040/configs/board.h12
-rw-r--r--platforms/chibios/boards/QMK_PM2040/configs/chconf.h13
-rw-r--r--platforms/chibios/boards/QMK_PM2040/configs/config.h21
-rw-r--r--platforms/chibios/boards/QMK_PM2040/configs/halconf.h9
-rw-r--r--platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h98
-rw-r--r--platforms/chibios/boards/common/ld/RP2040_FLASH_TIMECRIT.ld117
-rw-r--r--platforms/chibios/boards/common/ld/RP2040_rules_data_with_timecrit.ld46
-rw-r--r--platforms/chibios/bootloaders/rp2040.c56
-rw-r--r--platforms/chibios/bootloaders/stm32_dfu.c4
-rw-r--r--platforms/chibios/chibios_config.h50
-rw-r--r--platforms/chibios/converters/promicro_to_kb2040/_pin_defs.h36
-rw-r--r--platforms/chibios/converters/promicro_to_kb2040/converter.mk9
-rw-r--r--platforms/chibios/converters/promicro_to_promicro_rp2040/_pin_defs.h36
-rw-r--r--platforms/chibios/converters/promicro_to_promicro_rp2040/converter.mk9
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_stm32.c (renamed from platforms/chibios/eeprom_stm32.c)0
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_stm32.h (renamed from platforms/chibios/eeprom_stm32.h)0
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_stm32_defs.h (renamed from platforms/chibios/eeprom_stm32_defs.h)0
-rw-r--r--platforms/chibios/drivers/eeprom/eeprom_teensy.c (renamed from platforms/chibios/eeprom_teensy.c)0
-rwxr-xr-xplatforms/chibios/drivers/eeprom/eeprom_teensy.h (renamed from platforms/chibios/eeprom_teensy.h)0
-rw-r--r--platforms/chibios/drivers/flash/flash_stm32.c (renamed from platforms/chibios/flash_stm32.c)0
-rw-r--r--platforms/chibios/drivers/flash/flash_stm32.h (renamed from platforms/chibios/flash_stm32.h)0
-rw-r--r--platforms/chibios/drivers/serial.c18
-rw-r--r--platforms/chibios/drivers/serial_protocol.c164
-rw-r--r--platforms/chibios/drivers/serial_protocol.h49
-rw-r--r--platforms/chibios/drivers/serial_usart.c322
-rw-r--r--platforms/chibios/drivers/serial_usart.h118
-rw-r--r--platforms/chibios/drivers/spi_master.c39
-rw-r--r--platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c471
-rw-r--r--platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c189
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c143
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_efl_config.h50
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_legacy.c59
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_legacy_config.h67
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c221
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash_config.h32
-rw-r--r--platforms/chibios/flash.mk10
-rw-r--r--platforms/chibios/platform.mk27
-rw-r--r--platforms/chibios/vendors/RP/RP2040.mk287
-rw-r--r--platforms/chibios/vendors/RP/_pin_defs.h37
-rw-r--r--platforms/chibios/vendors/RP/pico_sdk_shims.c13
-rw-r--r--platforms/chibios/vendors/RP/stage2_bootloaders.c178
-rw-r--r--platforms/eeprom.h2
-rw-r--r--platforms/synchronization_util.h34
-rw-r--r--platforms/test/platform.mk2
-rw-r--r--platforms/test/rules.mk5
-rw-r--r--quantum/action.c2
-rw-r--r--quantum/action_layer.h2
-rw-r--r--quantum/action_tapping.c12
-rw-r--r--quantum/audio/song_list.h6
-rw-r--r--quantum/command.c4
-rw-r--r--quantum/debounce.h16
-rw-r--r--quantum/debounce/asym_eager_defer_pk.c11
-rw-r--r--quantum/debounce/none.c11
-rw-r--r--quantum/debounce/sym_defer_g.c12
-rw-r--r--quantum/debounce/sym_defer_pk.c12
-rw-r--r--quantum/debounce/sym_defer_pr.c14
-rw-r--r--quantum/debounce/sym_eager_pk.c7
-rw-r--r--quantum/debounce/sym_eager_pr.c11
-rw-r--r--quantum/debounce/tests/debounce_test_common.cpp6
-rw-r--r--quantum/dynamic_keymap.c21
-rw-r--r--quantum/encoder.c31
-rw-r--r--quantum/keyboard.c2
-rw-r--r--quantum/keycode_config.c4
-rw-r--r--quantum/keycode_config.h1
-rw-r--r--quantum/keymap.h7
-rw-r--r--quantum/keymap_extras/keymap_steno.h28
-rw-r--r--quantum/keymap_introspection.c30
-rw-r--r--quantum/keymap_introspection.h15
-rw-r--r--quantum/led.c12
-rw-r--r--quantum/led.h3
-rw-r--r--quantum/led_matrix/led_matrix.c12
-rw-r--r--quantum/led_matrix/led_matrix.h1
-rw-r--r--quantum/logging/print.c2
-rw-r--r--quantum/logging/print.h68
-rw-r--r--quantum/logging/print.mk17
-rw-r--r--quantum/matrix.c5
-rw-r--r--quantum/matrix_common.c5
-rw-r--r--quantum/mousekey.c27
-rw-r--r--quantum/mousekey.h4
-rw-r--r--quantum/painter/qp.h4
-rw-r--r--quantum/painter/rules.mk13
-rw-r--r--quantum/pointing_device.c38
-rw-r--r--quantum/pointing_device.h19
-rw-r--r--quantum/pointing_device_drivers.c247
-rw-r--r--quantum/pointing_device_gestures.c133
-rw-r--r--quantum/pointing_device_gestures.h58
-rw-r--r--quantum/process_keycode/process_auto_shift.c2
-rw-r--r--quantum/process_keycode/process_dynamic_macro.c3
-rw-r--r--quantum/process_keycode/process_dynamic_tapping_term.c2
-rw-r--r--quantum/process_keycode/process_leader.c1
-rw-r--r--quantum/process_keycode/process_magic.c10
-rw-r--r--quantum/process_keycode/process_steno.c312
-rw-r--r--quantum/process_keycode/process_steno.h24
-rw-r--r--quantum/process_keycode/process_tap_dance.c137
-rw-r--r--quantum/process_keycode/process_tap_dance.h33
-rw-r--r--quantum/process_keycode/process_terminal.c330
-rw-r--r--quantum/quantum.c3
-rw-r--r--quantum/quantum.h11
-rw-r--r--quantum/quantum_keycodes.h14
-rw-r--r--quantum/quantum_keycodes_legacy.h3
-rw-r--r--quantum/rgb_matrix/animations/pixel_rain_anim.h14
-rw-r--r--quantum/rgb_matrix/animations/raindrops_anim.h15
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_anim.h3
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_cross.h3
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_nexus.h3
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_simple_anim.h3
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_wide.h3
-rw-r--r--quantum/rgb_matrix/animations/typing_heatmap_anim.h88
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c23
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h1
-rw-r--r--quantum/send_string.h54
-rw-r--r--quantum/send_string/send_string.c (renamed from quantum/send_string.c)126
-rw-r--r--quantum/send_string/send_string.h152
-rw-r--r--quantum/send_string/send_string_keycodes.h434
-rw-r--r--quantum/send_string_keycodes.h505
-rw-r--r--quantum/split_common/split_util.c12
-rw-r--r--quantum/via.c21
-rw-r--r--quantum/via.h2
-rw-r--r--quantum/wear_leveling/tests/backing_mocks.cpp154
-rw-r--r--quantum/wear_leveling/tests/backing_mocks.hpp210
-rw-r--r--quantum/wear_leveling/tests/rules.mk66
-rw-r--r--quantum/wear_leveling/tests/testlist.mk6
-rw-r--r--quantum/wear_leveling/tests/wear_leveling_2byte.cpp228
-rw-r--r--quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp295
-rw-r--r--quantum/wear_leveling/tests/wear_leveling_4byte.cpp193
-rw-r--r--quantum/wear_leveling/tests/wear_leveling_8byte.cpp178
-rw-r--r--quantum/wear_leveling/tests/wear_leveling_general.cpp204
-rw-r--r--quantum/wear_leveling/wear_leveling.c768
-rw-r--r--quantum/wear_leveling/wear_leveling.h54
-rw-r--r--quantum/wear_leveling/wear_leveling_internal.h151
-rw-r--r--readme.md4
-rw-r--r--tests/tap_dance/config.h (renamed from keyboards/boardsource/holiday/spooky/spooky.c)6
-rw-r--r--tests/tap_dance/examples.c199
-rw-r--r--tests/tap_dance/examples.h33
-rw-r--r--tests/tap_dance/test.mk22
-rw-r--r--tests/tap_dance/test_examples.cpp319
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.c2
-rw-r--r--tmk_core/protocol/chibios/usb_main.c106
-rw-r--r--tmk_core/protocol/host.c5
-rw-r--r--tmk_core/protocol/report.h18
-rw-r--r--tmk_core/protocol/usb_descriptor.c15
-rw-r--r--tmk_core/protocol/vusb/vusb.c16
-rw-r--r--users/333fred/333fred.c2
-rw-r--r--users/333fred/rgb.c4
-rw-r--r--users/bbaserdem/bbaserdem.c20
-rw-r--r--users/bcat/rules.mk1
-rw-r--r--users/billypython/billypython.c2
-rw-r--r--users/billypython/billypython.h2
-rw-r--r--users/dhertz/dhertz.c3
-rw-r--r--users/doogle999/doogle999.c6
-rw-r--r--users/edvorakjp/edvorakjp.c2
-rw-r--r--users/edvorakjp/edvorakjp.h2
-rw-r--r--users/edvorakjp/edvorakjp_tap_dance.c13
-rwxr-xr-xusers/ericgebhart/ericgebhart.c2
-rwxr-xr-xusers/ericgebhart/tap_dances.c4
-rw-r--r--users/gourdo1/gourdo1.c2
-rw-r--r--users/hvp/config.h3
-rw-r--r--users/kuchosauronad0/kuchosauronad0.c6
-rw-r--r--users/kuchosauronad0/kuchosauronad0.h4
-rw-r--r--users/kuchosauronad0/rgblight_user.c20
-rw-r--r--users/kuchosauronad0/template.c4
-rw-r--r--users/manna-harbour_miryoku/post_rules.mk2
-rw-r--r--users/manna-harbour_miryoku/rules.mk2
-rw-r--r--users/mnil/config.h1
-rw-r--r--users/mnil/mnil.c4
-rw-r--r--users/mtdjr/mtdjr.c2
-rw-r--r--users/ninjonas/config.h3
-rw-r--r--users/ninjonas/oled.c2
-rw-r--r--users/ninjonas/tap_dances.c16
-rw-r--r--users/pvinis/pvinis.c2
-rw-r--r--users/pvinis/pvinis.h2
-rw-r--r--users/romus/romus.c4
-rw-r--r--users/sigma/sigma.c4
-rw-r--r--users/stanrc85/layer_rgb.c2
-rw-r--r--users/talljoe/config.h4
-rw-r--r--users/talljoe/talljoe.c2
-rw-r--r--users/tominabox1/config.h2
-rw-r--r--users/tominabox1/tominabox1.c4
-rw-r--r--users/turbomech/backupturbomech.c6
-rw-r--r--users/xulkal/custom_oled.c2
-rw-r--r--users/zer09/zer09.c2
-rwxr-xr-xutil/uf2conv.py3
-rwxr-xr-xutil/update_chibios_mirror.sh2
853 files changed, 26337 insertions, 8079 deletions
diff --git a/.gitmodules b/.gitmodules
index 681693a5a4..48c7035afa 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -18,3 +18,6 @@
[submodule "lib/printf"]
path = lib/printf
url = https://github.com/qmk/printf
+[submodule "lib/pico-sdk"]
+ path = lib/pico-sdk
+ url = https://github.com/qmk/pico-sdk.git
diff --git a/Makefile b/Makefile
index 4c2e6a04dc..fc6d016448 100644
--- a/Makefile
+++ b/Makefile
@@ -401,6 +401,7 @@ ifndef SKIP_GIT
if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi
if [ ! -e lib/vusb ]; then git submodule sync lib/vusb && git submodule update --depth 50 --init lib/vusb; fi
if [ ! -e lib/printf ]; then git submodule sync lib/printf && git submodule update --depth 50 --init lib/printf; fi
+ if [ ! -e lib/pico-sdk ]; then git submodule sync lib/pico-sdk && git submodule update --depth 50 --init lib/pico-sdk; fi
git submodule status --recursive 2>/dev/null | \
while IFS= read -r x; do \
case "$$x" in \
diff --git a/builddefs/bootloader.mk b/builddefs/bootloader.mk
index eba8e280e4..51e9b7d558 100644
--- a/builddefs/bootloader.mk
+++ b/builddefs/bootloader.mk
@@ -105,8 +105,8 @@ ifeq ($(strip $(BOOTLOADER)), halfkay)
ifeq ($(strip $(MCU)), at90usb1286)
BOOTLOADER_SIZE = 1024
endif
- # Teensy LC, 3.x
- ifneq (,$(filter $(MCU_ORIG), MKL26Z64 MK20DX128 MK20DX256 MK66FX1M0))
+ # Teensy LC, 3.0, 3.1/2, 3.5, 3.6
+ ifneq (,$(filter $(MCU_ORIG), MKL26Z64 MK20DX128 MK20DX256 MK64FX512 MK66FX1M0))
FIRMWARE_FORMAT = hex
endif
endif
@@ -200,6 +200,10 @@ ifeq ($(strip $(BOOTLOADER)), tinyuf2)
OPT_DEFS += -DBOOTLOADER_TINYUF2
BOOTLOADER_TYPE = tinyuf2
endif
+ifeq ($(strip $(BOOTLOADER)), rp2040)
+ OPT_DEFS += -DBOOTLOADER_RP2040
+ BOOTLOADER_TYPE = rp2040
+endif
ifeq ($(strip $(BOOTLOADER)), halfkay)
OPT_DEFS += -DBOOTLOADER_HALFKAY
BOOTLOADER_TYPE = halfkay
diff --git a/builddefs/build_keyboard.mk b/builddefs/build_keyboard.mk
index dc86b232df..fe95dcaf15 100644
--- a/builddefs/build_keyboard.mk
+++ b/builddefs/build_keyboard.mk
@@ -13,6 +13,14 @@ endif
include paths.mk
include $(BUILDDEFS_PATH)/message.mk
+# Helper to add defines with a 'QMK_' prefix
+define add_qmk_prefix_defs
+ ifdef $1
+ # Need to cater for 'STM32L4xx+'
+ OPT_DEFS += -DQMK_$(2)="$($1)" -DQMK_$(2)_$(shell echo $($1) | sed -e 's@+@Plus@g' -e 's@[^a-zA-Z0-9]@_@g' | tr '[:lower:]' '[:upper:]')
+ endif
+endef
+
# Set the qmk cli to use
QMK_BIN ?= qmk
@@ -390,10 +398,18 @@ ifneq ("$(KEYMAP_H)","")
CONFIG_H += $(KEYMAP_H)
endif
+OPT_DEFS += -DKEYMAP_C=\"$(KEYMAP_C)\"
+
+# If a keymap or userspace places their keymap array in another file instead, allow for it to be included
+# !!NOTE!! -- For this to work, the source file cannot be part of $(SRC), so users should not add it via `SRC += <file>`
+ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
+OPT_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
+endif
+
# project specific files
SRC += \
$(KEYBOARD_SRC) \
- $(KEYMAP_C) \
+ $(QUANTUM_DIR)/keymap_introspection.c \
$(QUANTUM_SRC) \
$(QUANTUM_DIR)/main.c \
@@ -436,6 +452,14 @@ else
include $(TMK_PATH)/protocol/$(PLATFORM_KEY).mk
endif
+# Setup definitions based on the selected MCU
+$(eval $(call add_qmk_prefix_defs,MCU_ORIG,MCU))
+$(eval $(call add_qmk_prefix_defs,MCU_ARCH,MCU_ARCH))
+$(eval $(call add_qmk_prefix_defs,MCU_PORT_NAME,MCU_PORT_NAME))
+$(eval $(call add_qmk_prefix_defs,MCU_FAMILY,MCU_FAMILY))
+$(eval $(call add_qmk_prefix_defs,MCU_SERIES,MCU_SERIES))
+$(eval $(call add_qmk_prefix_defs,BOARD,BOARD))
+
# TODO: remove this bodge?
PROJECT_DEFS := $(OPT_DEFS)
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
@@ -469,6 +493,19 @@ check-size: build
check-md5: build
objs-size: build
+ifeq ($(strip $(TOP_SYMBOLS)),yes)
+all: top-symbols
+check-size: top-symbols
+top-symbols: build
+ echo "###########################################"
+ echo "# Highest flash usage:"
+ $(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep -i ' [t] ' | head -n10 | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
+ echo "###########################################"
+ echo "# Highest RAM usage:"
+ $(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep -i ' [dbv] ' | head -n10 | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
+ echo "###########################################"
+endif
+
include $(BUILDDEFS_PATH)/show_options.mk
include $(BUILDDEFS_PATH)/common_rules.mk
diff --git a/builddefs/build_test.mk b/builddefs/build_test.mk
index 5ad33b19c5..64db99fed9 100644
--- a/builddefs/build_test.mk
+++ b/builddefs/build_test.mk
@@ -38,11 +38,11 @@ CREATE_MAP := no
VPATH += \
$(LIB_PATH)/googletest \
$(LIB_PATH)/googlemock \
- $(LIB_PATH)/printf
+ $(COMMON_VPATH) \
+ $(TEST_PATH)
all: elf
-VPATH += $(COMMON_VPATH)
PLATFORM:=TEST
PLATFORM_KEY:=test
BOOTLOADER_TYPE:=none
@@ -63,6 +63,8 @@ include $(TMK_PATH)/protocol.mk
include $(QUANTUM_PATH)/debounce/tests/rules.mk
include $(QUANTUM_PATH)/encoder/tests/rules.mk
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
+include $(QUANTUM_PATH)/wear_leveling/tests/rules.mk
+include $(QUANTUM_PATH)/logging/print.mk
include $(PLATFORM_PATH)/test/rules.mk
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
include $(BUILDDEFS_PATH)/build_full_test.mk
@@ -70,7 +72,6 @@ endif
$(TEST)_SRC += \
tests/test_common/main.c \
- $(LIB_PATH)/printf/printf.c \
$(QUANTUM_PATH)/logging/print.c
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index c976b8296d..d7a00ba944 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -15,7 +15,6 @@
QUANTUM_SRC += \
$(QUANTUM_DIR)/quantum.c \
- $(QUANTUM_DIR)/send_string.c \
$(QUANTUM_DIR)/bitwise.c \
$(QUANTUM_DIR)/led.c \
$(QUANTUM_DIR)/action.c \
@@ -92,10 +91,29 @@ ifeq ($(MUSIC_ENABLE), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
endif
+VALID_STENO_PROTOCOL_TYPES := geminipr txbolt all
+STENO_PROTOCOL ?= all
ifeq ($(strip $(STENO_ENABLE)), yes)
- OPT_DEFS += -DSTENO_ENABLE
- VIRTSER_ENABLE ?= yes
- SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
+ ifeq ($(filter $(STENO_PROTOCOL),$(VALID_STENO_PROTOCOL_TYPES)),)
+ $(call CATASTROPHIC_ERROR,Invalid STENO_PROTOCOL,STENO_PROTOCOL="$(STENO_PROTOCOL)" is not a valid stenography protocol)
+ else
+ OPT_DEFS += -DSTENO_ENABLE
+ VIRTSER_ENABLE ?= yes
+
+ ifeq ($(strip $(STENO_PROTOCOL)), geminipr)
+ OPT_DEFS += -DSTENO_ENABLE_GEMINI
+ endif
+ ifeq ($(strip $(STENO_PROTOCOL)), txbolt)
+ OPT_DEFS += -DSTENO_ENABLE_BOLT
+ endif
+ ifeq ($(strip $(STENO_PROTOCOL)), all)
+ OPT_DEFS += -DSTENO_ENABLE_ALL
+ OPT_DEFS += -DSTENO_ENABLE_GEMINI
+ OPT_DEFS += -DSTENO_ENABLE_BOLT
+ endif
+
+ SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
+ endif
endif
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
@@ -131,19 +149,21 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_i2c)
OPT_DEFS += -DSTM32_I2C -DHAL_USE_I2C=TRUE
SRC += drivers/sensors/cirque_pinnacle.c
+ SRC += drivers/sensors/cirque_pinnacle_gestures.c
+ SRC += $(QUANTUM_DIR)/pointing_device_gestures.c
QUANTUM_LIB_SRC += i2c_master.c
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_spi)
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
SRC += drivers/sensors/cirque_pinnacle.c
+ SRC += drivers/sensors/cirque_pinnacle_gestures.c
+ SRC += $(QUANTUM_DIR)/pointing_device_gestures.c
QUANTUM_LIB_SRC += spi_master.c
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball)
OPT_DEFS += -DSTM32_SPI -DHAL_USE_I2C=TRUE
QUANTUM_LIB_SRC += i2c_master.c
- else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
- OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
- QUANTUM_LIB_SRC += spi_master.c
- else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3389)
+ else ifneq ($(filter $(strip $(POINTING_DEVICE_DRIVER)),pmw3360 pmw3389),)
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
+ SRC += drivers/sensors/pmw33xx_common.c
QUANTUM_LIB_SRC += spi_master.c
endif
endif
@@ -154,33 +174,36 @@ ifeq ($(strip $(QUANTUM_PAINTER_ENABLE)), yes)
include $(QUANTUM_DIR)/painter/rules.mk
endif
-VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
+VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi wear_leveling
EEPROM_DRIVER ?= vendor
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
$(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
else
OPT_DEFS += -DEEPROM_ENABLE
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
+ COMMON_VPATH += $(DRIVER_PATH)/eeprom
+ COMMON_VPATH += $(PLATFORM_COMMON_DIR)
ifeq ($(strip $(EEPROM_DRIVER)), custom)
# Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
SRC += eeprom_driver.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling)
+ # Wear-leveling EEPROM implementation
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
+ SRC += eeprom_driver.c eeprom_wear_leveling.c
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
# External I2C EEPROM implementation
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
QUANTUM_LIB_SRC += i2c_master.c
SRC += eeprom_driver.c eeprom_i2c.c
else ifeq ($(strip $(EEPROM_DRIVER)), spi)
# External SPI EEPROM implementation
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
QUANTUM_LIB_SRC += spi_master.c
SRC += eeprom_driver.c eeprom_spi.c
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
# Transient EEPROM implementation -- no data storage but provides runtime area for it
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
SRC += eeprom_driver.c eeprom_transient.c
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
# Vendor-implemented EEPROM
@@ -191,17 +214,18 @@ else
ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
# Emulated EEPROM
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
- SRC += eeprom_driver.c
- SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
- SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
+ COMMON_VPATH += $(DRIVER_PATH)/flash
+ SRC += eeprom_driver.c eeprom_stm32.c flash_stm32.c
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
# True EEPROM on STM32L0xx, L1xx
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
- COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
- SRC += eeprom_driver.c
- SRC += eeprom_stm32_L0_L1.c
+ SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
+ else ifneq ($(filter $(MCU_SERIES),RP2040),)
+ # Wear-leveling EEPROM implementation, backed by RP2040 flash
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
+ SRC += eeprom_driver.c eeprom_wear_leveling.c
+ WEAR_LEVELING_DRIVER = rp2040_flash
else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
# Teensy EEPROM implementations
OPT_DEFS += -DEEPROM_TEENSY
@@ -209,32 +233,64 @@ else
else
# Fall back to transient, i.e. non-persistent
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
SRC += eeprom_driver.c eeprom_transient.c
endif
else ifeq ($(PLATFORM),ARM_ATSAM)
# arm_atsam EEPROM
OPT_DEFS += -DEEPROM_SAMD
- SRC += $(PLATFORM_COMMON_DIR)/eeprom_samd.c
+ SRC += eeprom_samd.c
else ifeq ($(PLATFORM),TEST)
# Test harness "EEPROM"
OPT_DEFS += -DEEPROM_TEST_HARNESS
- SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
+ SRC += eeprom.c
+ endif
+ endif
+endif
+
+VALID_WEAR_LEVELING_DRIVER_TYPES := custom embedded_flash spi_flash rp2040_flash legacy
+WEAR_LEVELING_DRIVER ?= none
+ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none)
+ ifeq ($(filter $(WEAR_LEVELING_DRIVER),$(VALID_WEAR_LEVELING_DRIVER_TYPES)),)
+ $(call CATASTROPHIC_ERROR,Invalid WEAR_LEVELING_DRIVER,WEAR_LEVELING_DRIVER="$(WEAR_LEVELING_DRIVER)" is not a valid wear leveling driver)
+ else
+ FNV_ENABLE := yes
+ OPT_DEFS += -DWEAR_LEVELING_ENABLE
+ OPT_DEFS += -DWEAR_LEVELING_$(strip $(shell echo $(WEAR_LEVELING_DRIVER) | tr '[:lower:]' '[:upper:]'))
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling
+ COMMON_VPATH += $(DRIVER_PATH)/wear_leveling
+ COMMON_VPATH += $(QUANTUM_DIR)/wear_leveling
+ SRC += wear_leveling.c
+ ifeq ($(strip $(WEAR_LEVELING_DRIVER)), embedded_flash)
+ OPT_DEFS += -DHAL_USE_EFL
+ SRC += wear_leveling_efl.c
+ POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_efl_config.h
+ else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), spi_flash)
+ FLASH_DRIVER := spi
+ SRC += wear_leveling_flash_spi.c
+ POST_CONFIG_H += $(DRIVER_PATH)/wear_leveling/wear_leveling_flash_spi_config.h
+ else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), rp2040_flash)
+ SRC += wear_leveling_rp2040_flash.c
+ POST_CONFIG_H += $(DRIVER_PATH)/wear_leveling/wear_leveling_rp2040_flash_config.h
+ else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), legacy)
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
+ SRC += flash_stm32.c wear_leveling_legacy.c
+ POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_legacy_config.h
endif
endif
endif
VALID_FLASH_DRIVER_TYPES := spi
-FLASH_DRIVER ?= no
-ifneq ($(strip $(FLASH_DRIVER)), no)
+FLASH_DRIVER ?= none
+ifneq ($(strip $(FLASH_DRIVER)), none)
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
- $(error FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid FLASH driver)
+ $(call CATASTROPHIC_ERROR,Invalid FLASH_DRIVER,FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid flash driver)
else
OPT_DEFS += -DFLASH_ENABLE
- ifeq ($(strip $(FLASH_DRIVER)), spi)
+ ifeq ($(strip $(FLASH_DRIVER)),spi)
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
COMMON_VPATH += $(DRIVER_PATH)/flash
SRC += flash_spi.c
+ QUANTUM_LIB_SRC += spi_master.c
endif
endif
endif
@@ -500,7 +556,7 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
endif
endif
-VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c
+VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c vendor
WS2812_DRIVER ?= bitbang
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
@@ -542,12 +598,6 @@ ifeq ($(strip $(LED_TABLES)), yes)
SRC += $(QUANTUM_DIR)/led_tables.c
endif
-ifeq ($(strip $(TERMINAL_ENABLE)), yes)
- SRC += $(QUANTUM_DIR)/process_keycode/process_terminal.c
- OPT_DEFS += -DTERMINAL_ENABLE
- OPT_DEFS += -DUSER_PRINT
-endif
-
ifeq ($(strip $(VIA_ENABLE)), yes)
DYNAMIC_KEYMAP_ENABLE := yes
RAW_ENABLE := yes
@@ -595,6 +645,14 @@ ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
QUANTUM_SRC += $(QUANTUM_DIR)/debounce/$(strip $(DEBOUNCE_TYPE)).c
endif
+
+VALID_SERIAL_DRIVER_TYPES := bitbang usart vendor
+
+SERIAL_DRIVER ?= bitbang
+ifeq ($(filter $(SERIAL_DRIVER),$(VALID_SERIAL_DRIVER_TYPES)),)
+ $(call CATASTROPHIC_ERROR,Invalid SERIAL_DRIVER,SERIAL_DRIVER="$(SERIAL_DRIVER)" is not a valid SERIAL driver)
+endif
+
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
OPT_DEFS += -DSPLIT_KEYBOARD
@@ -619,11 +677,11 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
endif
endif
- SERIAL_DRIVER ?= bitbang
OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
QUANTUM_LIB_SRC += serial.c
else
+ QUANTUM_LIB_SRC += serial_protocol.c
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
endif
endif
@@ -635,6 +693,12 @@ ifeq ($(strip $(CRC_ENABLE)), yes)
SRC += crc.c
endif
+ifeq ($(strip $(FNV_ENABLE)), yes)
+ OPT_DEFS += -DFNV_ENABLE
+ VPATH += $(LIB_PATH)/fnv
+ SRC += qmk_fnv_type_validation.c hash_32a.c hash_64a.c
+endif
+
ifeq ($(strip $(HAPTIC_ENABLE)),yes)
COMMON_VPATH += $(DRIVER_PATH)/haptic
@@ -711,6 +775,13 @@ ifeq ($(strip $(MAGIC_ENABLE)), yes)
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
endif
+SEND_STRING_ENABLE ?= yes
+ifeq ($(strip $(SEND_STRING_ENABLE)), yes)
+ OPT_DEFS += -DSEND_STRING_ENABLE
+ COMMON_VPATH += $(QUANTUM_DIR)/send_string
+ SRC += $(QUANTUM_DIR)/send_string/send_string.c
+endif
+
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_auto_shift.c
OPT_DEFS += -DAUTO_SHIFT_ENABLE
diff --git a/builddefs/common_rules.mk b/builddefs/common_rules.mk
index d3acddc87b..6573257c78 100644
--- a/builddefs/common_rules.mk
+++ b/builddefs/common_rules.mk
@@ -1,19 +1,5 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
-# WinAVR Makefile Template written by Eric B. Weddington, Jî’šg Wunsch, et al.
-#
-# Released to the Public Domain
-#
-# Additional material for this makefile was written by:
-# Peter Fleury
-# Tim Henigan
-# Colin O'Flynn
-# Reiner Patommel
-# Markus Pfaff
-# Sander Pool
-# Frederik Rouleau
-# Carlos Lamas
-#
# Enable vpath seraching for source files only
# Without this, output files, could be read from the wrong .build directories
@@ -38,36 +24,15 @@ NO_LTO_OBJ := $(filter %.a,$(OBJ))
MASTER_OUTPUT := $(firstword $(OUTPUTS))
-
-
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Optimization level, can be [0, 1, 2, 3, s].
-# 0 = turn off optimization. s = optimize for size.
-# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT ?= s
-# Compiler flag to set the C Standard level.
-# c89 = "ANSI" C
-# gnu89 = c89 plus GCC extensions
-# c99 = ISO C99 standard (not yet fully implemented)
-# gnu99 = c99 plus GCC extensions
-CSTANDARD = -std=gnu99
-
-
-# Place -D or -U options here for C sources
-#CDEFS +=
-
-
-# Place -D or -U options here for ASM sources
-#ADEFS +=
-
-
-# Place -D or -U options here for C++ sources
-#CXXDEFS += -D__STDC_LIMIT_MACROS
-#CXXDEFS += -D__STDC_CONSTANT_MACROS
-#CXXDEFS +=
+# Compiler flag to set the C and C++ language standard level
+CSTANDARD = -std=gnu11
+CXXSTANDARD = -std=gnu++14
# Speed up recompilations by opt-in usage of ccache
USE_CCACHE ?= no
@@ -75,12 +40,8 @@ ifneq ($(USE_CCACHE),no)
CC_PREFIX ?= ccache
endif
-#---------------- Compiler Options C ----------------
-# -g*: generate debugging information
-# -O*: optimization level
-# -f...: tuning, see GCC manual and avr-libc documentation
-# -Wall...: warning level
-# -Wa,...: tell GCC to pass this to the assembler.
+#---------------- C Compiler Options ----------------
+
ifeq ($(strip $(LTO_ENABLE)), yes)
ifeq ($(PLATFORM),ARM_ATSAM)
$(info Enabling LTO on arm_atsam-targeting boards is known to have a high likelihood of failure.)
@@ -111,23 +72,14 @@ CFLAGS += -Wstrict-prototypes
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CFLAGS += -Werror
endif
-#CFLAGS += -mshort-calls
-#CFLAGS += -fno-unit-at-a-time
-#CFLAGS += -Wundef
-#CFLAGS += -Wunreachable-code
-#CFLAGS += -Wsign-compare
CFLAGS += $(CSTANDARD)
# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
# Fixing of multiple variable definitions must be made.
CFLAGS += -fcommon
-#---------------- Compiler Options C++ ----------------
-# -g*: generate debugging information
-# -O*: optimization level
-# -f...: tuning, see GCC manual and avr-libc documentation
-# -Wall...: warning level
-# -Wa,...: tell GCC to pass this to the assembler.
+#---------------- C++ Compiler Options ----------------
+
ifeq ($(strip $(DEBUG_ENABLE)),yes)
CXXFLAGS += -g$(DEBUG)
endif
@@ -141,57 +93,17 @@ CXXFLAGS += -Wundef
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CXXFLAGS += -Werror
endif
-#CXXFLAGS += -mshort-calls
-#CXXFLAGS += -fno-unit-at-a-time
-#CXXFLAGS += -Wstrict-prototypes
-#CXXFLAGS += -Wunreachable-code
-#CXXFLAGS += -Wsign-compare
-#CXXFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
+
ASFLAGS += $(ADEFS)
ifeq ($(VERBOSE_AS_CMD),yes)
ASFLAGS += -v
endif
-#---------------- Library Options ----------------
-# Minimalistic printf version
-PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
-
-# Floating point printf version (requires MATH_LIB = -lm below)
-PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
-
-# If this is left blank, then it will use the Standard printf version.
-PRINTF_LIB =
-#PRINTF_LIB = $(PRINTF_LIB_MIN)
-#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
-
-
-# Minimalistic scanf version
-SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
-
-# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
-SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
-
-# If this is left blank, then it will use the Standard scanf version.
-SCANF_LIB =
-#SCANF_LIB = $(SCANF_LIB_MIN)
-#SCANF_LIB = $(SCANF_LIB_FLOAT)
-
-
-MATH_LIB = -lm
-CREATE_MAP ?= yes
-
-
#---------------- Linker Options ----------------
-# -Wl,...: tell GCC to pass this to linker.
-# -Map: create map file
-# --cref: add cross reference to map file
-#
-# Comennt out "--relax" option to avoid a error such:
-# (.vectors+0x30): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_12'
-#
+CREATE_MAP ?= yes
ifeq ($(CREATE_MAP),yes)
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
endif
@@ -201,20 +113,11 @@ endif
#LDFLAGS += -Wl,--relax
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
-LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
-#LDFLAGS += -T linker_script.x
+LDFLAGS += -lm
# You can give EXTRALDFLAGS at 'make' command line.
LDFLAGS += $(EXTRALDFLAGS)
#---------------- Assembler Listings ----------------
-# -Wa,...: tell GCC to pass this to the assembler.
-# -adhlns: create listing
-# -gstabs: have the assembler create line number information; note that
-# for use in COFF files, additional information about filenames
-# and function names needs to be present in the assembler source
-# files -- see avr-libc docs [FIXME: not yet described there]
-# -listing-cont-lines: Sets the maximum number of continuation lines of hex
-# dump that will be displayed for a given single line of source input.
ADHLNS_ENABLE ?= no
ifeq ($(ADHLNS_ENABLE),yes)
diff --git a/builddefs/mcu_selection.mk b/builddefs/mcu_selection.mk
index d5fb731e08..7528aa6842 100644
--- a/builddefs/mcu_selection.mk
+++ b/builddefs/mcu_selection.mk
@@ -87,6 +87,33 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
BOARD ?= PJRC_TEENSY_3_1
endif
+ifneq ($(findstring MK64FX512, $(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 = K60x
+
+ # Linker script to use
+ # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
+ # or <keyboard_dir>/ld/
+ MCU_LDSCRIPT ?= MK64FX512
+
+ # Startup code to use
+ # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
+ MCU_STARTUP ?= k60x
+
+ # Board: it should exist either in <chibios>/os/hal/boards/,
+ # <keyboard_dir>/boards/, or drivers/boards/
+ BOARD ?= PJRC_TEENSY_3_5
+endif
+
ifneq ($(findstring MK66FX1M0, $(MCU)),)
# Cortex version
MCU = cortex-m4
@@ -116,6 +143,41 @@ ifneq ($(findstring MK66FX1M0, $(MCU)),)
BOARD ?= PJRC_TEENSY_3_6
endif
+ifneq ($(findstring RP2040, $(MCU)),)
+ # Cortex version
+ MCU = cortex-m0plus
+
+ # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
+ CHIBIOS_PORT = ARMv6-M-RP2
+
+ ## chip/board settings
+ # - the next two should match the directories in
+ # <chibios[-contrib]>/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)
+ # OR
+ # <chibios[-contrib]>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
+ MCU_FAMILY = RP
+ MCU_SERIES = RP2040
+
+ # Linker script to use
+ # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
+ # or <keyboard_dir>/ld/
+ STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld
+ MCU_LDSCRIPT ?= RP2040_FLASH_TIMECRIT
+ LDFLAGS += -L $(STARTUPLD_CONTRIB)
+
+ # Startup code to use
+ # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
+ MCU_STARTUP ?= rp2040
+
+ # Board: it should exist either in <chibios>/os/hal/boards/,
+ # <keyboard_dir>/boards/, or drivers/boards/
+ BOARD ?= GENERIC_PROMICRO_RP2040
+
+ # Default UF2 Bootloader settings
+ UF2_FAMILY ?= RP2040
+ FIRMWARE_FORMAT ?= uf2
+endif
+
ifneq ($(findstring STM32F042, $(MCU)),)
# Cortex version
MCU = cortex-m0
diff --git a/builddefs/show_options.mk b/builddefs/show_options.mk
index f67d009191..98537e6da2 100644
--- a/builddefs/show_options.mk
+++ b/builddefs/show_options.mk
@@ -5,7 +5,6 @@ BUILD_OPTION_NAMES = \
CONSOLE_ENABLE \
COMMAND_ENABLE \
NKRO_ENABLE \
- TERMINAL_ENABLE \
CUSTOM_MATRIX \
DEBOUNCE_TYPE \
SPLIT_KEYBOARD \
@@ -46,6 +45,7 @@ OTHER_OPTION_NAMES = \
LEADER_ENABLE \
PRINTING_ENABLE \
STENO_ENABLE \
+ STENO_PROTOCOL \
TAP_DANCE_ENABLE \
VIRTSER_ENABLE \
OLED_ENABLE \
diff --git a/builddefs/testlist.mk b/builddefs/testlist.mk
index b8d22bce80..8a30a44972 100644
--- a/builddefs/testlist.mk
+++ b/builddefs/testlist.mk
@@ -4,6 +4,7 @@ FULL_TESTS := $(notdir $(TEST_LIST))
include $(QUANTUM_PATH)/debounce/tests/testlist.mk
include $(QUANTUM_PATH)/encoder/tests/testlist.mk
include $(QUANTUM_PATH)/sequencer/tests/testlist.mk
+include $(QUANTUM_PATH)/wear_leveling/tests/testlist.mk
include $(PLATFORM_PATH)/test/testlist.mk
define VALIDATE_TEST_LIST
diff --git a/data/mappings/defaults.json b/data/mappings/defaults.json
index e62ab688d6..c6cb53f4c3 100644
--- a/data/mappings/defaults.json
+++ b/data/mappings/defaults.json
@@ -16,6 +16,18 @@
"board": "QMK_PROTON_C",
"pin_compatible": "promicro"
},
+ "kb2040": {
+ "processor": "RP2040",
+ "bootloader": "rp2040",
+ "board": "QMK_PM2040",
+ "pin_compatible": "promicro"
+ },
+ "promicro_rp2040": {
+ "processor": "RP2040",
+ "bootloader": "rp2040",
+ "board": "QMK_PM2040",
+ "pin_compatible": "promicro"
+ },
"bluepill": {
"processor": "STM32F103",
"bootloader": "stm32duino",
diff --git a/data/mappings/info_config.json b/data/mappings/info_config.json
index 5f0d903bd7..fcceb98025 100644
--- a/data/mappings/info_config.json
+++ b/data/mappings/info_config.json
@@ -12,6 +12,7 @@
"AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "bool"},
"BACKLIGHT_BREATHING": {"info_key": "backlight.breathing", "value_type": "bool"},
"BREATHING_PERIOD": {"info_key": "backlight.breathing_period", "value_type": "int"},
+ "BACKLIGHT_ON_STATE": {"info_key": "backlight.on_state", "value_type": "int"},
"BACKLIGHT_PIN": {"info_key": "backlight.pin"},
"BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "bool"},
"CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"},
@@ -35,6 +36,9 @@
"LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"},
"LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"},
"LED_SCROLL_LOCK_PIN": {"info_key": "indicators.scroll_lock"},
+ "LED_COMPOSE_PIN": {"info_key": "indicators.compose"},
+ "LED_KANA_PIN": {"info_key": "indicators.kana"},
+ "LED_PIN_ON_STATE": {"info_key": "indicators.on_state", "value_type": "int"},
"MANUFACTURER": {"info_key": "manufacturer"},
"MATRIX_HAS_GHOST": {"info_key": "matrix_pins.ghost", "value_type": "bool"},
"MATRIX_IO_DELAY": {"info_key": "matrix_pins.io_delay", "value_type": "int"},
diff --git a/data/mappings/info_rules.json b/data/mappings/info_rules.json
index d4eec37ba0..279b5ac213 100644
--- a/data/mappings/info_rules.json
+++ b/data/mappings/info_rules.json
@@ -13,6 +13,7 @@
"BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false},
"BLUETOOTH": {"info_key": "bluetooth.driver"},
"CAPS_WORD_ENABLE": {"info_key": "caps_word.enabled", "value_type": "bool"},
+ "ENCODER_ENABLE": {"info_key": "encoder.enabled", "value_type": "bool"},
"FIRMWARE_FORMAT": {"info_key": "build.firmware_format"},
"KEYBOARD_SHARED_EP": {"info_key": "usb.shared_endpoint.keyboard", "value_type": "bool"},
"MOUSE_SHARED_EP": {"info_key": "usb.shared_endpoint.mouse", "value_type": "bool"},
@@ -27,6 +28,8 @@
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"},
+ "STENO_ENABLE": {"info_key": "stenography.enabled", "value_type": "bool"},
+ "STENO_PROTOCOL": {"info_key": "stenography.protocol"},
# Items we want flagged in lint
"CTPC": {"info_key": "_deprecated.ctpc", "deprecated": true},
diff --git a/data/schemas/definitions.jsonschema b/data/schemas/definitions.jsonschema
index 1bdfbbeb03..8b68a58482 100644
--- a/data/schemas/definitions.jsonschema
+++ b/data/schemas/definitions.jsonschema
@@ -1,5 +1,5 @@
{
- "$schema": "http://json-schema.org/draft-07/schema#",
+ "$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.definitions.v1",
"title": "Common definitions used across QMK's jsonschemas.",
"type": "object",
@@ -65,8 +65,7 @@
]
},
"key_unit": {
- "type": "number",
- "min": 0.25
+ "type": "number"
},
"keyboard": {
"oneOf": [
@@ -103,8 +102,11 @@
"pattern": "^LINE_PIN\\d{1,2}$"
},
{
- "type": "number",
- "multipleOf": 1
+ "type": "string",
+ "pattern": "^GP\\d{1,2}$"
+ },
+ {
+ "type": "integer"
},
{
"type": "null"
@@ -115,14 +117,12 @@
"type": "number"
},
"signed_int": {
- "type": "number",
- "multipleOf": 1
+ "type": "integer"
},
"signed_int_8": {
- "type": "number",
- "min": -127,
- "max": 127,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": -127,
+ "maximum": 127
},
"string_array": {
"type": "array",
@@ -138,17 +138,20 @@
},
"unsigned_decimal": {
"type": "number",
- "min": 0
+ "minimum": 0
},
"unsigned_int": {
- "type": "number",
- "min": 0,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0
},
"unsigned_int_8": {
- "type": "number",
- "min": 0,
- "max": 255,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "bit": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 1
}
}
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index fd60920578..166a5d4d3b 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -1,7 +1,27 @@
{
- "$schema": "http://json-schema.org/draft-07/schema#",
+ "$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.keyboard.v1",
"title": "Keyboard Information",
+ "definitions": {
+ "encoder_config": {
+ "type": "object",
+ "properties": {
+ "rotary": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pin_a", "pin_b"],
+ "properties": {
+ "pin_a": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "pin_b": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "resolution": {"$ref": "qmk.definitions.v1#/unsigned_int"}
+ }
+ }
+ }
+ }
+ }
+ },
"type": "object",
"properties": {
"keyboard_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
@@ -14,7 +34,7 @@
},
"development_board": {
"type": "string",
- "enum": ["promicro", "elite_c", "proton_c", "bluepill", "blackpill_f401", "blackpill_f411"]
+ "enum": ["promicro", "elite_c", "proton_c", "kb2040", "promicro_rp2040", "bluepill", "blackpill_f401", "blackpill_f411"]
},
"pin_compatible": {
"type": "string",
@@ -22,7 +42,7 @@
},
"processor": {
"type": "string",
- "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
+ "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK64FX512", "MK66FX1M0", "RP2040", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
},
"audio": {
"type": "object",
@@ -40,12 +60,12 @@
"breathing": {"type": "boolean"},
"breathing_period": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
"levels": {
- "type": "number",
- "min": 1,
- "max": 31,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 31
},
- "pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}
+ "pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "on_state": {"$ref": "qmk.definitions.v1#/bit"}
}
},
"bluetooth": {
@@ -66,7 +86,7 @@
},
"bootloader": {
"type": "string",
- "enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "custom", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "md-boot", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"],
+ "enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "custom", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "md-boot", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2", "rp2040"],
},
"bootloader_instructions": {
"type": "string",
@@ -113,13 +133,22 @@
"type": "array",
"items": {"$ref": "qmk.definitions.v1#/filename"}
},
+ "encoder": {
+ "$ref": "#/definitions/encoder_config",
+ "properties": {
+ "enabled": {"type": "boolean"}
+ }
+ },
"features": {"$ref": "qmk.definitions.v1#/boolean_array"},
"indicators": {
"type": "object",
"properties": {
"caps_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
"num_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
- "scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"}
+ "scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "compose": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "kana": {"$ref": "qmk.definitions.v1#/mcu_pin"},
+ "on_state": {"$ref": "qmk.definitions.v1#/bit"}
}
},
"layout_aliases": {
@@ -154,12 +183,11 @@
"minItems": 2,
"maxItems": 2,
"items": {
- "type": "number",
- "min": 0,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0
}
},
- "r": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
+ "r": {"$ref": "qmk.definitions.v1#/signed_decimal"},
"rx": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
"ry": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
"h": {"$ref": "qmk.definitions.v1#/key_unit"},
@@ -230,14 +258,13 @@
"minItems": 2,
"maxItems": 2,
"items": {
- "type": "number",
- "min": 0,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0
}
},
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
- "flags": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}
+ "flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
}
}
}
@@ -258,14 +285,13 @@
"minItems": 2,
"maxItems": 2,
"items": {
- "type": "number",
- "min": 0,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0
}
},
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
- "flags": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}
+ "flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
}
}
}
@@ -290,10 +316,9 @@
"blink": {"type": "boolean"},
"enabled": {"type": "boolean"},
"max": {
- "type": "number",
- "min": 1,
- "max": 32,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 32
},
"override_rgb": {"type": "boolean"}
}
@@ -307,8 +332,8 @@
"split": {"type": "boolean"},
"split_count": {
"type": "array",
- "minLength": 2,
- "maxLength": 2,
+ "minItems": 2,
+ "maxItems": 2,
"items": {"$ref": "qmk.definitions.v1#/unsigned_int"}
}
}
@@ -322,21 +347,31 @@
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"unlock_sequence": {
"type": "array",
- "minLength": 1,
- "maxLength": 5,
+ "minItems": 1,
+ "maxItems": 5,
"items": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
- "type": "number",
- "min": 0,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0
}
}
}
}
},
+ "stenography": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled": {"type": "boolean"},
+ "protocol": {
+ "type": "string",
+ "enum": ["all", "geminipr", "txbolt"]
+ }
+ }
+ },
"split": {
"type": "object",
"additionalProperties": false,
@@ -365,16 +400,24 @@
}
}
},
+ "encoder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "right": {
+ "$ref": "#/definitions/encoder_config"
+ }
+ }
+ },
"main": {
"type": "string",
"enum": ["eeprom", "left", "matrix_grid", "pin", "right"]
},
"soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
"soft_serial_speed": {
- "type": "number",
- "min": 0,
- "max": 5,
- "multipleOf": 1
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 5
},
"transport": {
"type": "object",
@@ -428,7 +471,7 @@
"force_nkro": {"type": "boolean"},
"pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
"vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
- "max_power": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
+ "max_power": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"no_startup_check": {"type": "boolean"},
"polling_interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
"shared_endpoint": {
@@ -439,7 +482,7 @@
"mouse": {"type": "boolean"}
}
},
- "suspend_wakeup_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
+ "suspend_wakeup_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"wait_for": {"type": "boolean"},
}
},
@@ -448,8 +491,8 @@
"additionalProperties": false,
"properties": {
"keys_per_scan": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
- "tap_keycode_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
- "tap_capslock_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
+ "tap_keycode_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"},
+ "tap_capslock_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"},
}
},
"qmk_lufa_bootloader": {
diff --git a/data/schemas/keymap.jsonschema b/data/schemas/keymap.jsonschema
index 3803301a66..92a1ce533d 100644
--- a/data/schemas/keymap.jsonschema
+++ b/data/schemas/keymap.jsonschema
@@ -1,5 +1,5 @@
{
- "$schema": "http://json-schema.org/draft-07/schema#",
+ "$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.keymap.v1",
"title": "Keymap Information",
"type": "object",
@@ -50,8 +50,7 @@
},
"config": {"$ref": "qmk.keyboard.v1"},
"notes": {
- "type": "string",
- "description": "asdf"
+ "type": "string"
}
},
"required": [
diff --git a/docs/_summary.md b/docs/_summary.md
index b7fcddc237..66f2d60af0 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -85,11 +85,11 @@
* [Pointing Device](feature_pointing_device.md)
* [Raw HID](feature_rawhid.md)
* [Secure](feature_secure.md)
+ * [Send String](feature_send_string.md)
* [Sequencer](feature_sequencer.md)
* [Swap Hands](feature_swap_hands.md)
* [Tap Dance](feature_tap_dance.md)
* [Tap-Hold Configuration](tap_hold.md)
- * [Terminal](feature_terminal.md)
* [Unicode](feature_unicode.md)
* [Userspace](feature_userspace.md)
* [WPM Calculation](feature_wpm.md)
@@ -108,6 +108,7 @@
* [Audio](feature_audio.md)
* [Bluetooth](feature_bluetooth.md)
* [Bootmagic Lite](feature_bootmagic.md)
+ * [Converters](feature_converters.md)
* [Custom Matrix](custom_matrix.md)
* [Digitizer](feature_digitizer.md)
* [DIP Switch](feature_dip_switch.md)
@@ -116,7 +117,6 @@
* [Joystick](feature_joystick.md)
* [LED Indicators](feature_led_indicators.md)
* [MIDI](feature_midi.md)
- * [Proton C Conversion](proton_c_conversion.md)
* [PS/2 Mouse](feature_ps2_mouse.md)
* [Split Keyboard](feature_split_keyboard.md)
* [Stenography](feature_stenography.md)
@@ -148,6 +148,7 @@
* [SPI Driver](spi_driver.md)
* [WS2812 Driver](ws2812_driver.md)
* [EEPROM Driver](eeprom_driver.md)
+ * [Flash Driver](flash_driver.md)
* ['serial' Driver](serial_driver.md)
* [UART Driver](uart_driver.md)
* [GPIO Controls](gpio_control.md)
@@ -166,6 +167,8 @@
* Arm/ChibiOS
* [Selecting an MCU](platformdev_selecting_arm_mcu.md)
* [Early initialization](platformdev_chibios_earlyinit.md)
+ * [Raspberry Pi RP2040](platformdev_rp2040.md)
+ * [Proton C](platformdev_proton_c.md)
* QMK Reference
* [Contributing to QMK](contributing.md)
diff --git a/docs/cli_commands.md b/docs/cli_commands.md
index a380d3eb2f..56767d962b 100644
--- a/docs/cli_commands.md
+++ b/docs/cli_commands.md
@@ -352,6 +352,73 @@ $ qmk via2json -kb ai03/polaris -o polaris_keymap.json polaris_via_backup.json
Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
```
+## `qmk import-keyboard`
+
+This command imports a data-driven `info.json` keyboard into the repo.
+
+**Usage**:
+
+```
+usage: qmk import-keyboard [-h] filename
+```
+
+**Example:**
+
+```
+$ qmk import-keyboard ~/Downloads/forever60.json
+Ψ Importing forever60.json.
+
+Ψ Imported a new keyboard named forever60.
+Ψ To start working on things, `cd` into keyboards/forever60,
+Ψ or open the directory in your preferred text editor.
+Ψ And build with qmk compile -kb forever60 -km default.
+```
+
+## `qmk import-keymap`
+
+This command imports a data-driven `keymap.json` keymap into the repo.
+
+**Usage**:
+
+```
+usage: qmk import-keymap [-h] filename
+```
+
+**Example:**
+
+```
+qmk import-keymap ~/Downloads/asdf2.json
+Ψ Importing asdf2.json.
+
+Ψ Imported a new keymap named asdf2.
+Ψ To start working on things, `cd` into keyboards/takashicompany/dogtag/keymaps/asdf2,
+Ψ or open the directory in your preferred text editor.
+Ψ And build with qmk compile -kb takashicompany/dogtag -km asdf2.
+```
+
+## `qmk import-kbfirmware`
+
+This command creates a new keyboard based on a [Keyboard Firmware Builder](https://kbfirmware.com/) export.
+
+**Usage**:
+
+```
+usage: qmk import-kbfirmware [-h] filename
+```
+
+**Example:**
+
+```
+$ qmk import-kbfirmware ~/Downloads/gh62.json
+Ψ Importing gh62.json.
+
+âš  Support here is basic - Consider using 'qmk new-keyboard' instead
+Ψ Imported a new keyboard named gh62.
+Ψ To start working on things, `cd` into keyboards/gh62,
+Ψ or open the directory in your preferred text editor.
+Ψ And build with qmk compile -kb gh62 -km default.
+```
+
---
# Developer Commands
@@ -527,3 +594,4 @@ This command converts a TTF font to an intermediate format for editing, before c
## `qmk painter-convert-font-image`
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
+
diff --git a/docs/compatible_microcontrollers.md b/docs/compatible_microcontrollers.md
index cee8986829..cc9c0b7f92 100644
--- a/docs/compatible_microcontrollers.md
+++ b/docs/compatible_microcontrollers.md
@@ -62,9 +62,17 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50)
* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72)
* PJRC Teensy 3.2
+ * [MK64FX512](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k64-120-mhz-256-kb-sram-microcontrollers-mcus-based-on-arm-cortex-m4-core:K64_120)
+ * PJRC Teensy 3.5
* [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180)
* PJRC Teensy 3.6
+### Raspberry Pi
+
+* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html)
+
+For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md).
+
## Atmel ATSAM
There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware.
diff --git a/docs/config_options.md b/docs/config_options.md
index 8227a0e074..c35227a407 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -141,7 +141,7 @@ If you define these options you will enable the associated feature, which may in
## Behaviors That Can Be Configured
* `#define TAPPING_TERM 200`
- * how long before a tap becomes a hold, if set above 500, a key tapped during the tapping term will turn it into a hold too
+ * how long before a key press becomes a hold
* `#define TAPPING_TERM_PER_KEY`
* enables handling for per key `TAPPING_TERM` settings
* `#define RETRO_TAPPING`
@@ -174,6 +174,8 @@ If you define these options you will enable the associated feature, which may in
* sets the timer for leader key chords to run on each key press rather than overall
* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
* Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
+* `#define MOUSE_EXTENDED_REPORT`
+ * Enables support for extended reports (-32767 to 32767, instead of -127 to 127), which may allow for smoother reporting, and prevent maxing out of the reports. Applies to both Pointing Device and Mousekeys.
* `#define ONESHOT_TIMEOUT 300`
* how long before oneshot times out
* `#define ONESHOT_TAP_TOGGLE 2`
diff --git a/docs/custom_matrix.md b/docs/custom_matrix.md
index 8f6878f94a..6d6ae5e972 100644
--- a/docs/custom_matrix.md
+++ b/docs/custom_matrix.md
@@ -81,17 +81,17 @@ void matrix_init(void) {
}
uint8_t matrix_scan(void) {
- bool matrix_has_changed = false;
+ bool changed = false;
// TODO: add matrix scanning routine here
// Unless hardware debouncing - use the configured debounce routine
- debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
+ changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
// This *must* be called for correct keyboard behavior
matrix_scan_quantum();
- return matrix_has_changed;
+ return changed;
}
```
diff --git a/docs/eeprom_driver.md b/docs/eeprom_driver.md
index 6dcf10c04d..50d8bcb7b3 100644
--- a/docs/eeprom_driver.md
+++ b/docs/eeprom_driver.md
@@ -2,12 +2,15 @@
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
+Selecting the EEPROM driver is done in your keyboard's `rules.mk`:
+
Driver | Description
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
+`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
## Vendor Driver Configuration :id=vendor-eeprom-driver-configuration
@@ -43,8 +46,9 @@ Module | Equivalent `#define` | Source
-----------------|---------------------------------|------------------------------------------
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
-24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/wwwproducts/en/24LC64>
-24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/wwwproducts/en/24LC128>
+24LC32A EEPROM | `#define EEPROM_I2C_24LC32A` | <https://www.microchip.com/en-us/product/24LC32A>
+24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/en-us/product/24LC64>
+24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/en-us/product/24LC128>
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
@@ -54,13 +58,13 @@ MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/p
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
-`config.h` override | Description | Default Value
------------------------------------------------|--------------------------------------------------------------------------------------|--------------
-`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | SPI Slave select pin in order to inform that the EEPROM is currently being addressed | _none_
-`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | Clock divisor used to divide the peripheral clock to derive the SPI frequency | `64`
-`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
-`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
-`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
+`config.h` override | Default Value | Description
+-----------------------------------------------|---------------|-------------------------------------------------------------------------------------
+`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | _none_ | SPI Slave select pin in order to inform that the EEPROM is currently being addressed
+`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | `64` | Clock divisor used to divide the peripheral clock to derive the SPI frequency
+`#define EXTERNAL_EEPROM_BYTE_COUNT` | `8192` | Total size of the EEPROM in bytes
+`#define EXTERNAL_EEPROM_PAGE_SIZE` | `32` | Page size of the EEPROM in bytes, as specified in the datasheet
+`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | `2` | The number of bytes to transmit for the memory location within the EEPROM
!> There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
@@ -73,3 +77,84 @@ The only configurable item for the transient EEPROM driver is its size:
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
+
+## Wear-leveling Driver Configuration :id=wear_leveling-eeprom-driver-configuration
+
+The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
+
+There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
+
+# Wear-leveling Configuration :id=wear_leveling-configuration
+
+The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
+
+Driver | Description
+----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU.
+`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals.
+`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
+`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
+
+!> All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
+
+## Wear-leveling Embedded Flash Driver Configuration :id=wear_leveling-efl-driver-configuration
+
+This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
+
+Configurable options in your keyboard's `config.h`:
+
+`config.h` override | Default | Description
+-----------------------------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration.
+`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting.
+`#define WEAR_LEVELING_LOGICAL_SIZE` | `1024` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
+`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
+`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
+
+!> If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
+
+## Wear-leveling SPI Flash Driver Configuration :id=wear_leveling-flash_spi-driver-configuration
+
+This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver.md) documentation for more information.
+
+Configurable options in your keyboard's `config.h`:
+
+`config.h` override | Default | Description
+----------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------
+`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm.
+`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm.
+`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB.
+`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
+`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
+
+!> There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
+
+## Wear-leveling RP2040 Driver Configuration :id=wear_leveling-rp2040-driver-configuration
+
+This driver performs writes to the same underlying storage that the RP2040 executes its code.
+
+Configurable options in your keyboard's `config.h`:
+
+`config.h` override | Default | Description
+------------------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------
+`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board.
+`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located.
+`#define WEAR_LEVELING_LOGICAL_SIZE` | `4096` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
+`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
+`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
+
+## Wear-leveling Legacy EEPROM Emulation Driver Configuration :id=wear_leveling-legacy-driver-configuration
+
+This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
+
+By default, `1024` bytes of emulated EEPROM is provided:
+
+MCU | EEPROM Provided | Flash Used
+----------|-----------------|--------------
+STM32F042 | `1024` bytes | `2048` bytes
+STM32F070 | `1024` bytes | `2048` bytes
+STM32F072 | `1024` bytes | `2048` bytes
+STM32F401 | `1024` bytes | `16384` bytes
+STM32F411 | `1024` bytes | `16384` bytes
+
+Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code.
diff --git a/docs/feature_converters.md b/docs/feature_converters.md
new file mode 100644
index 0000000000..9cca76e8e8
--- /dev/null
+++ b/docs/feature_converters.md
@@ -0,0 +1,95 @@
+# Converters
+
+Since many drop-in replacement controllers now exist, we've done our best to make them easy to use in existing designs.
+
+This page documents the handy automated process for converting keyboards.
+
+### Supported Converters
+
+Currently the following converters are available:
+
+| From | To |
+|------------|-------------------|
+| `promicro` | `proton_c` |
+| `promicro` | `kb2040` |
+| `promicro` | `promicro_rp2040` |
+
+See below for more in depth information on each converter.
+
+## Overview
+
+Each converter category is broken down by its declared `pin compatibility`.
+This ensures that only valid combinations are attempted.
+
+You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
+
+```sh
+qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
+```
+
+You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing.
+
+?> If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
+
+### Conditional Configuration
+
+Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag that you can use in your code with `#ifdef`s, For example:
+
+```c
+#ifdef CONVERT_TO_PROTON_C
+ // Proton C code
+#else
+ // Pro Micro code
+#endif
+```
+
+## Pro Micro
+
+If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are:
+
+| Device | Target |
+|------------------------------------------------------------------------|-------------------|
+| [Proton C](https://qmk.fm/proton-c/) | `proton_c` |
+| [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` |
+| [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `promicro_rp2040` |
+
+Converter summary:
+
+| Target | Argument | `rules.mk` | Condition |
+|-------------------|---------------------------------|------------------------------|-------------------------------------|
+| `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` |
+| `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` |
+| `promicro_rp2040` | `-e CONVERT_TO=promicro_rp2040` | `CONVERT_TO=promicro_rp2040` | `#ifdef CONVERT_TO_PROMICRO_RP2040` |
+
+### Proton C :id=proton_c
+
+The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`:
+
+```c
+#define CONVERT_TO_PROTON_C_RXLED
+```
+
+The following defaults are based on what has been implemented for STM32 boards.
+
+| Feature | Notes |
+|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
+| [Audio](feature_audio.md) | Enabled |
+| [RGB Lighting](feature_rgblight.md) | Disabled |
+| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
+| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
+| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
+
+### Adafruit KB2040 :id=kb2040
+
+The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards.
+
+| Feature | Notes |
+|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
+| [RGB Lighting](feature_rgblight.md) | Enabled via `PIO` vendor driver |
+| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
+| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
+| [Split keyboards](feature_split_keyboard.md) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
+
+### SparkFun Pro Micro - RP2040 :id=promicro_rp2040
+
+Currently identical to [Adafruit KB2040](#kb2040).
diff --git a/docs/feature_dynamic_macros.md b/docs/feature_dynamic_macros.md
index 01f2a0ca40..0660e0c065 100644
--- a/docs/feature_dynamic_macros.md
+++ b/docs/feature_dynamic_macros.md
@@ -35,6 +35,7 @@ There are a number of options added that should allow some additional degree of
|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. |
|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. |
|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). |
+|`DYNAMIC_MACRO_DELAY` |*Not Defined* |Sets the waiting time (ms unit) when sending each key. |
If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header).
diff --git a/docs/feature_macros.md b/docs/feature_macros.md
index 78bc4ba0a5..f5b163d5df 100644
--- a/docs/feature_macros.md
+++ b/docs/feature_macros.md
@@ -106,6 +106,8 @@ Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_`
### `SEND_STRING()` & `process_record_user`
+See also: [Send String](feature_send_string.md)
+
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
Here is an example `keymap.c` for a two-key keyboard:
diff --git a/docs/feature_mouse_keys.md b/docs/feature_mouse_keys.md
index 905da36e43..8e474c4245 100644
--- a/docs/feature_mouse_keys.md
+++ b/docs/feature_mouse_keys.md
@@ -87,9 +87,9 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode |
|`MOUSEKEY_DELAY` |5 |Delay between pressing a movement key and cursor movement |
|`MOUSEKEY_INTERVAL` |10 |Time between cursor movements in milliseconds |
-|`MOUSEKEY_MOVE_DELTA` |5 |Step size for accelerating from initial to base speed |
+|`MOUSEKEY_MOVE_DELTA` |16 |Step size for accelerating from initial to base speed |
|`MOUSEKEY_INITIAL_SPEED` |100 |Initial speed of the cursor in pixel per second |
-|`MOUSEKEY_BASE_SPEED` |1000 |Maximum cursor speed at which acceleration stops |
+|`MOUSEKEY_BASE_SPEED` |5000 |Maximum cursor speed at which acceleration stops |
|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed |
|`MOUSEKEY_ACCELERATED_SPEED` |3000 |Accelerated cursor speed |
|`MOUSEKEY_WHEEL_INITIAL_MOVEMENTS` |16 |Initial number of movements of the mouse wheel |
@@ -100,7 +100,7 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
Tips:
* The smoothness of the cursor movement depends on the `MOUSEKEY_INTERVAL` setting. The shorter the interval is set the smoother the movement will be. Setting the value too low makes the cursor unresponsive. Lower settings are possible if the micro processor is fast enough. For example: At an interval of `8` milliseconds, `125` movements per second will be initiated. With a base speed of `1000` each movement will move the cursor by `8` pixels.
-* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `1`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
+* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `2`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
### Constant mode
diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md
index 02c1e64a31..6343ed073d 100644
--- a/docs/feature_pointing_device.md
+++ b/docs/feature_pointing_device.md
@@ -22,11 +22,11 @@ POINTING_DEVICE_DRIVER = adns5050
The ADNS 5050 sensor uses a serial type protocol for communication, and requires an additional light source.
-| Setting | Description |
-|--------------------|---------------------------------------------------------------------|
-|`ADNS5050_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. |
-|`ADNS5050_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. |
-|`ADNS5050_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. |
+| Setting | Description |
+| ------------------- | ------------------------------------------------------------------- |
+| `ADNS5050_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. |
+| `ADNS5050_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. |
+| `ADNS5050_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. |
The CPI range is 125-1375, in increments of 125. Defaults to 500 CPI.
@@ -40,13 +40,13 @@ POINTING_DEVICE_DRIVER = adns9800
The ADNS 9800 is an SPI driven optical sensor, that uses laser output for surface tracking.
-| Setting | Description | Default |
-|--------------------------------|------------------------------------------------------------------------|---------------|
-|`ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
-|`ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
-|`ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
-|`ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
-|`ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
+| Setting | Description | Default |
+| ----------------------- | ---------------------------------------------------------------------- | ------------- |
+| `ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
+| `ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
+| `ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
+| `ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
+| `ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
The CPI range is 800-8200, in increments of 200. Defaults to 1800 CPI.
@@ -61,17 +61,16 @@ POINTING_DEVICE_DRIVER = analog_joystick
The Analog Joystick is an analog (ADC) driven sensor. There are a variety of joysticks that you can use for this.
-| Setting | Description | Default |
-|----------------------------------|----------------------------------------------------------------------------|---------------|
-|`ANALOG_JOYSTICK_X_AXIS_PIN` | (Required) The pin used for the vertical/X axis. | _not defined_ |
-|`ANALOG_JOYSTICK_Y_AXIS_PIN` | (Required) The pin used for the horizontal/Y axis. | _not defined_ |
-|`ANALOG_JOYSTICK_AXIS_MIN` | (Optional) Sets the lower range to be considered movement. | `0` |
-|`ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` |
-|`ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` |
-|`ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` |
-|`ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` |
-|`ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ |
-
+| Setting | Description | Default |
+| --------------------------------- | -------------------------------------------------------------------------- | ------------- |
+| `ANALOG_JOYSTICK_X_AXIS_PIN` | (Required) The pin used for the vertical/X axis. | _not defined_ |
+| `ANALOG_JOYSTICK_Y_AXIS_PIN` | (Required) The pin used for the horizontal/Y axis. | _not defined_ |
+| `ANALOG_JOYSTICK_AXIS_MIN` | (Optional) Sets the lower range to be considered movement. | `0` |
+| `ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` |
+| `ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` |
+| `ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` |
+| `ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` |
+| `ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ |
### Cirque Trackpad
@@ -90,29 +89,52 @@ POINTING_DEVICE_DRIVER = cirque_pinnacle_spi
This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported.
-| Setting | Description | Default |
-|---------------------------------|---------------------------------------------------------------------------------|-----------------------|
-|`CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` |
-|`CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` |
-|`CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` |
-|`CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` |
-|`CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
-|`CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
-
-| I2C Setting | Description | Default |
-|--------------------------|---------------------------------------------------------------------------------|---------|
-|`CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` |
-|`CIRQUE_PINNACLE_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `20` |
-
-| SPI Setting | Description | Default |
-|-------------------------------|------------------------------------------------------------------------|---------------|
-|`CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
-|`CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
-|`CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
-|`CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
-|`CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
-
-Default Scaling/CPI is 1024.
+| Setting | Description | Default |
+| -------------------------------- | ---------------------------------------------------------- | ------------------ |
+| `CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` |
+| `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` |
+| `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` |
+| `CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` |
+| `CIRQUE_PINNACLE_DIAMETER_MM` | (Optional) Diameter of the trackpad sensor in millimeters. | `40` |
+| `CIRQUE_PINNACLE_ATTENUATION` | (Optional) Sets the attenuation of the sensor data. | `ADC_ATTENUATE_4X` |
+| `CIRQUE_PINNACLE_CURVED_OVERLAY` | (Optional) Applies settings tuned for curved overlay. | _not defined_ |
+
+**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be.
+
+Default attenuation is set to 4X, although if you are using a thicker overlay (such as the curved overlay) you will want a lower attenuation such as 2X. The possible values are:
+* `ADC_ATTENUATE_4X`: Least sensitive
+* `ADC_ATTENUATE_3X`
+* `ADC_ATTENUATE_2X`
+* `ADC_ATTENUATE_1X`: Most sensitive
+
+| I2C Setting | Description | Default |
+| ------------------------- | ------------------------------------------------------------------------------- | ------- |
+| `CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` |
+| `CIRQUE_PINNACLE_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `20` |
+
+| SPI Setting | Description | Default |
+| ------------------------------ | ---------------------------------------------------------------------- | ------------- |
+| `CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
+| `CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
+| `CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
+| `CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
+| `CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
+
+Default Scaling is 1024. Actual CPI depends on trackpad diameter.
+
+Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when using Cirque Pinnacle, which matches the internal update rate of the position registers (in standard configuration). Advanced configuration for pen/stylus usage might require lower values.
+
+#### Cirque Trackpad gestures
+
+| Gesture Setting | Description | Default |
+| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
+| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction | _not defined_ |
+| `CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE` | (Optional) Enable circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll. | _not defined_ |
+| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ |
+| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
+| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
+
+**`POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`** is not specific to Cirque trackpad; any pointing device with a lift/contact status can integrate this gesture into its driver. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `pointing_device_get_report()` is needed to generate glide reports.
### Pimoroni Trackball
@@ -124,62 +146,69 @@ POINTING_DEVICE_DRIVER = pimoroni_trackball
The Pimoroni Trackball module is a I2C based breakout board with an RGB enable trackball.
-| Setting | Description | Default |
-|-------------------------------------|------------------------------------------------------------------------------------|---------|
-|`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
-|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
-|`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
-|`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
-|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
+| Setting | Description | Default |
+| ------------------------------------ | ---------------------------------------------------------------------------------- | ------- |
+| `PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
+| `PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
+| `PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
+| `PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
+| `PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
+
+### PMW 3360 and PMW 3389 Sensor
-### PMW 3360 Sensor
+This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
-This drivers supports multiple sensors _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
-To use the PMW 3360 sensor, add this to your `rules.mk`
+To use the **PMW 3360** sensor, add this to your `rules.mk`
```make
POINTING_DEVICE_DRIVER = pmw3360
```
-The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking.
+The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.
-| Setting | Description | Default |
-|-----------------------------|--------------------------------------------------------------------------------------------|---------------|
-|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
-|`PMW3360_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
-|`PMW3360_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
-|`PMW3360_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
-|`PMW3360_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
-|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
-|`PMW3360_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
-|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor.| `0` |
-|`PMW3360_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |
+To use the **PMW 3389** sensor, add this to your `rules.mk`
-The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.
+```make
+POINTING_DEVICE_DRIVER = pmw3389
+```
+
+The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.
-To use multiple sensors, instead of setting `PMW3360_CS_PIN` you need to set `PMW3360_CS_PINS` and also handle and merge the read from this sensor in user code.
+Both PMW 3360 and PMW 3389 are SPI driven optical sensors, that use a built in IR LED for surface tracking.
+
+| Setting | Description | Default |
+| ---------------------------- | ------------------------------------------------------------------------------------------- | ------------- |
+| `PMW33XX_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
+| `PMW33XX_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
+| `PMW33XX_CPI` | (Optional) Sets counts per inch sensitivity of the sensor. | _varies_ |
+| `PMW33XX_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
+| `PMW33XX_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
+| `PMW33XX_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
+| `ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` |
+
+To use multiple sensors, instead of setting `PMW33XX_CS_PIN` you need to set `PMW33XX_CS_PINS` and also handle and merge the read from this sensor in user code.
Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported.
```c
// in config.h:
-#define PMW3360_CS_PINS { B5, B6 }
-
+#define PMW33XX_CS_PINS { B5, B6 }
// in keyboard.c:
#ifdef POINTING_DEVICE_ENABLE
void pointing_device_init_kb(void) {
- pmw3360_init(1); // index 1 is the second device.
- pointing_device_set_cpi(800); // applies to both sensors
+ pmw33xx_init(1); // index 1 is the second device.
+ pmw33xx_set_cpi(0, 800); // applies to first sensor
+ pmw33xx_set_cpi(1, 800); // applies to second sensor
pointing_device_init_user();
}
// Contains report from sensor #0 already, need to merge in from sensor #1
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
- report_pmw3360_t data = pmw3360_read_burst(1);
- if (data.isOnSurface && data.isMotion) {
+ pmw33xx_report_t report = pmw33xx_read_burst(1);
+ if (!report.motion.b.is_lifted && report.motion.b.is_motion) {
// From quantum/pointing_device_drivers.c
#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
- mouse_report.x = constrain_hid(mouse_report.x + data.dx);
- mouse_report.y = constrain_hid(mouse_report.y + data.dy);
+ mouse_report.x = constrain_hid(mouse_report.x + report.delta_x);
+ mouse_report.y = constrain_hid(mouse_report.y + report.delta_y);
}
return pointing_device_task_user(mouse_report);
}
@@ -187,30 +216,6 @@ report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
```
-### PMW 3389 Sensor
-
-To use the PMW 3389 sensor, add this to your `rules.mk`
-
-```make
-POINTING_DEVICE_DRIVER = pmw3389
-```
-
-The PMW 3389 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking.
-
-| Setting | Description | Default |
-|---------------------------------|--------------------------------------------------------------------------------------------|---------------|
-|`PMW3389_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
-|`PMW3389_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
-|`PMW3389_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
-|`PMW3389_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
-|`PMW3389_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
-|`PMW3389_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
-|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 30 degrees directly in the sensor. | `0` |
-|`PMW3389_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |
-
-The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.
-
-
### Custom Driver
If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk`
@@ -232,15 +237,15 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
## Common Configuration
-| Setting | Description | Default |
-|----------------------------------|-----------------------------------------------------------------------|-------------------|
-|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
-|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
-|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
-|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
-|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
-|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
-|`POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
+| Setting | Description | Default |
+| ---------------------------------- | --------------------------------------------------------------------- | ------------- |
+| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
+| `POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
+| `POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
+| `POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
+| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
+| `POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
+| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
@@ -249,24 +254,25 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
-| Setting | Description | Default |
-|----------------------------------------|-----------------------------------------------------------------------|---------------|
-|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
-|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
-|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
-|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
-|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
-|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
-|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
-|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
+| Setting | Description | Default |
+| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------- |
+| `POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
+| `POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
+| `POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
+| `POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
+| `POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
+| `POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
+| `POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
+| `POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
+| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127) |
!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
## Callbacks and Functions
-| Function | Description |
-|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
+| Function | Description |
+| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
@@ -274,11 +280,11 @@ The following configuration options are only available when using `SPLIT_POINTIN
| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
-| `pointing_device_get_report(void)` | Returns the current mouse report (as a `mouse_report_t` data structure). |
-| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
-| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
+| `pointing_device_get_report(void)` | Returns the current mouse report (as a `mouse_report_t` data structure). |
+| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
+| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
-| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
+| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
## Split Keyboard Callbacks and Functions
@@ -286,7 +292,7 @@ The following configuration options are only available when using `SPLIT_POINTIN
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
| Function | Description |
-|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
+| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. |
| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` |
| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) |
diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
index b664ccd698..f9ab395488 100644
--- a/docs/feature_rgb_matrix.md
+++ b/docs/feature_rgb_matrix.md
@@ -86,6 +86,7 @@ You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_<N>` de
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 |
+| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
@@ -172,6 +173,7 @@ Configure the hardware via your `config.h`:
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 |
+| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
@@ -409,6 +411,7 @@ You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
+| `AW_SPI_MODE` | (Optional) Mode for SPI communication (0-3, defines polarity and phase of the clock) | 3 |
| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 |
Here is an example using 2 drivers.
@@ -665,11 +668,36 @@ In order to change the delay of temperature decrease define `RGB_MATRIX_TYPING_H
#define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 50
```
-Heatmap effect may not light up the correct adjacent LEDs for certain key matrix layout such as split keyboards. The following define will limit the effect to pressed keys only:
+As heatmap uses the physical position of the leds set in the g_led_config, you may need to tweak the following options to get the best effect for your keyboard. Note the size of this grid is `224x64`.
+
+Limit the distance the effect spreads to surrounding keys.
+
+```c
+#define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40
+```
+
+Limit how hot surrounding keys get from each press.
+
+```c
+#define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16
+```
+
+Remove the spread effect entirely.
+
```c
#define RGB_MATRIX_TYPING_HEATMAP_SLIM
```
+### RGB Matrix Effect Solid Reactive :id=rgb-matrix-effect-solid-reactive
+
+Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define:
+
+```c
+#define RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+```
+
+Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`).
+
## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder.
diff --git a/docs/feature_send_string.md b/docs/feature_send_string.md
new file mode 100644
index 0000000000..67df0224e9
--- /dev/null
+++ b/docs/feature_send_string.md
@@ -0,0 +1,224 @@
+# Send String
+
+The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically.
+
+The full ASCII character set is supported, along with all of the keycodes in the Basic Keycode range (as these are the only ones that will actually be sent to the host).
+
+?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
+
+## Usage
+
+Send String is enabled by default, so there is usually no need for any special setup. However, if it is disabled, add the following to your `rules.mk`:
+
+```make
+SEND_STRING_ENABLE = yes
+```
+
+## Basic Configuration
+
+Add the following to your `config.h`:
+
+|Define |Default |Description |
+|-----------------|----------------|------------------------------------------------------------------------------------------------------------|
+|`SENDSTRING_BELL`|*Not defined* |If the [Audio](feature_audio.md) feature is enabled, the `\a` character (ASCII `BEL`) will beep the speaker.|
+|`BELL_SOUND` |`TERMINAL_SOUND`|The song to play when the `\a` character is encountered. By default, this is an eighth note of C5. |
+
+## Keycodes
+
+The Send String functions accept C string literals, but specific keycodes can be injected with the below macros. All of the keycodes in the [Basic Keycode range](keycodes_basic.md) are supported (as these are the only ones that will actually be sent to the host), but with an `X_` prefix instead of `KC_`.
+
+|Macro |Description |
+|--------------|-------------------------------------------------------------------|
+|`SS_TAP(x)` |Send a keydown, then keyup, event for the given Send String keycode|
+|`SS_DOWN(x)` |Send a keydown event for the given Send String keycode |
+|`SS_UP(x)` |Send a keyup event for the given Send String keycode |
+|`SS_DELAY(ms)`|Wait for `ms` milliseconds |
+
+The following characters are also mapped to their respective keycodes for convenience:
+
+|Character|Hex |ASCII|Keycode |
+|---------|------|-----|--------------|
+|`\b` |`\x08`|`BS` |`KC_BACKSPACE`|
+|`\e` |`\x09`|`ESC`|`KC_ESCAPE` |
+|`\n` |`\x0A`|`LF` |`KC_ENTER` |
+|`\t` |`\x1B`|`TAB`|`KC_TAB` |
+| |`\x7F`|`DEL`|`KC_DELETE` |
+
+### Language Support
+
+By default, Send String assumes your OS keyboard layout is set to US ANSI. If you are using a different keyboard layout, you can [override the lookup tables used to convert ASCII characters to keystrokes](reference_keymap_extras.md#sendstring-support).
+
+## Examples
+
+### Hello World
+
+A simple custom keycode which types out "Hello, world!" and the Enter key when pressed.
+
+Add the following to your `keymap.c`:
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case SS_HELLO:
+ if (record->event.pressed) {
+ SEND_STRING("Hello, world!\n");
+ }
+ return false;
+ }
+
+ return true;
+}
+```
+
+### Keycode Injection
+
+This example types out opening and closing curly braces, then taps the left arrow key to move the cursor between the two.
+
+```c
+SEND_STRING("{}" SS_TAP(X_LEFT));
+```
+
+This example types Ctrl+A, then Ctrl+C, without releasing Ctrl.
+
+```c
+SEND_STRING(SS_LCTL("ac"));
+```
+
+## API
+
+### `void send_string(const char *string)`
+
+Type out a string of ASCII characters.
+
+This function simply calls `send_string_with_delay(string, 0)`.
+
+#### Arguments
+
+ - `const char *string`
+ The string to type out.
+
+---
+
+### `void send_string_with_delay(const char *string, uint8_t interval)`
+
+Type out a string of ASCII characters, with a delay between each character.
+
+#### Arguments
+
+ - `const char *string`
+ The string to type out.
+ - `uint8_t interval`
+ The amount of time, in milliseconds, to wait before typing the next character.
+
+---
+
+### `void send_string_P(const char *string)`
+
+Type out a PROGMEM string of ASCII characters.
+
+On ARM devices, this function is simply an alias for `send_string_with_delay(string, 0)`.
+
+#### Arguments
+
+ - `const char *string`
+ The string to type out.
+
+---
+
+### `void send_string_with_delay_P(const char *string, uint8_t interval)`
+
+Type out a PROGMEM string of ASCII characters, with a delay between each character.
+
+On ARM devices, this function is simply an alias for `send_string_with_delay(string, interval)`.
+
+#### Arguments
+
+ - `const char *string`
+ The string to type out.
+ - `uint8_t interval`
+ The amount of time, in milliseconds, to wait before typing the next character.
+
+---
+
+### `void send_char(char ascii_code)`
+
+Type out an ASCII character.
+
+#### Arguments
+
+ - `char ascii_code`
+ The character to type.
+
+---
+
+### `void send_dword(uint32_t number)`
+
+Type out an eight digit (unsigned 32-bit) hexadecimal value.
+
+The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`.
+
+#### Arguments
+
+ - `uint32_t number`
+ The value to type, from 0 to 4,294,967,295.
+
+---
+
+### `void send_word(uint16_t number)`
+
+Type out a four digit (unsigned 16-bit) hexadecimal value.
+
+The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`.
+
+#### Arguments
+
+ - `uint16_t number`
+ The value to type, from 0 to 65,535.
+
+---
+
+### `void send_byte(uint8_t number)`
+
+Type out a two digit (8-bit) hexadecimal value.
+
+The format is `[0-9a-f]{2}`, eg. `00` through `ff`.
+
+#### Arguments
+
+ - `uint8_t number`
+ The value to type, from 0 to 255.
+
+---
+
+### `void send_nibble(uint8_t number)`
+
+Type out a single hexadecimal digit.
+
+The format is `[0-9a-f]{1}`, eg. `0` through `f`.
+
+#### Arguments
+
+ - `uint8_t number`
+ The value to type, from 0 to 15.
+
+---
+
+### `void tap_random_base64(void)`
+
+Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
+
+---
+
+### `SEND_STRING(string)`
+
+Shortcut macro for `send_string_with_delay_P(PSTR(string), 0)`.
+
+On ARM devices, this define evaluates to `send_string_with_delay(string, 0)`.
+
+---
+
+### `SEND_STRING_DELAY(string, interval)`
+
+Shortcut macro for `send_string_with_delay_P(PSTR(string), interval)`.
+
+On ARM devices, this define evaluates to `send_string_with_delay(string, interval)`.
diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md
index eefafdbf75..e53b3525cb 100644
--- a/docs/feature_split_keyboard.md
+++ b/docs/feature_split_keyboard.md
@@ -143,6 +143,9 @@ Next, you will have to flash the EEPROM files once for the correct hand to the c
* ARM controllers with a DFU compatible bootloader (e.g. Proton-C):
* `:dfu-util-split-left`
* `:dfu-util-split-right`
+* ARM controllers with a UF2 compatible bootloader:
+ * `:uf2-split-left`
+ * `:uf2-split-right`
Example:
@@ -367,7 +370,7 @@ There are some settings that you may need to configure, based on how the hardwar
#define MATRIX_COL_PINS_RIGHT { <col pins> }
```
-This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency).
+This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). The number of pins in the right and left matrices must be the same, if you have a board with a different number of rows or columns on one side, pad out the extra spaces with `NO_PIN` and make sure you add the unused rows or columns to your matrix.
```c
#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
diff --git a/docs/feature_stenography.md b/docs/feature_stenography.md
index 2b52bb17a6..e13fe845c5 100644
--- a/docs/feature_stenography.md
+++ b/docs/feature_stenography.md
@@ -8,46 +8,107 @@ The [Open Steno Project](https://www.openstenoproject.org/) has built an open-so
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
-To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
+To enable NKRO, add `NKRO_ENABLE = yes` in your `rules.mk` and make sure to press `NK_ON` to turn it on because `NKRO_ENABLE = yes` merely adds the possibility of switching to NKRO mode but it doesn't automatically switch to it. If you want to automatically switch, add `#define FORCE_NKRO` in your `config.h`.
+
+You may also need to adjust your layout, either in QMK or in Plover, if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
## Plover with Steno Protocol :id=plover-with-steno-protocol
-Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
+Plover also understands the language of several steno machines. QMK can speak a couple of these languages: TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
+
+When QMK speaks to Plover over a steno protocol, Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
+
+In this mode, Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard.
-When QMK speaks to Plover over a steno protocol Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
+> Note: Due to hardware limitations, you might not be able to run both a virtual serial port and mouse emulation at the same time.
-In this mode Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard. By default QMK will speak the TX Bolt protocol but can be switched to GeminiPR; the last protocol used is stored in non-volatile memory so QMK will use the same protocol on restart.
+!> Serial stenography protocols are not supported on [V-USB keyboards](compatible_microcontrollers#atmel-avr).
-> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
+To enable stenography protocols, add the following lines to your `rules.mk`:
+```mk
+STENO_ENABLE = yes
+```
### TX Bolt :id=tx-bolt
-TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
+TX Bolt communicates the status of 24 keys over a simple protocol in variable-sized (1&ndash;4 bytes) packets.
-### GeminiPR :id=geminipr
+To select TX Bolt, add the following lines to your `rules.mk`:
+```mk
+STENO_ENABLE = yes
+STENO_PROTOCOL = txbolt
+```
-GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
+Each byte of the packet represents a different group of steno keys. Determining the group of a certain byte of the packet is done by checking the first two bits, the remaining bits are set if the corresponding steno key was pressed for the stroke. The last set of keys (as indicated by leading `11`) needs to keep track of less keys than there are bits so one of the bits is constantly 0.
-## Configuring QMK for Steno :id=configuring-qmk-for-steno
+The start of a new packet can be detected by comparing the group “ID†(the two MSBs) of the current byte to that of the previously received byte. If the group “ID†of the current byte is smaller or equal to that of the previous byte, it means that the current byte is the beginning of a new packet.
-Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
+The format of TX Bolt packets is shown below.
+```
+00HWPKTS 01UE*OAR 10GLBPRF 110#ZDST
+```
+
+Examples of steno strokes and the associated packet:
+- `EUBG` = `01110000 10101000`
+- `WAZ` = `00010000 01000010 11001000`
+- `PHAPBGS` = `00101000 01000010 10101100 11000010`
+
+### GeminiPR :id=geminipr
+
+GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including differentiating between top and bottom `S-`, and supporting non-English theories.
-```make
+To select GeminiPR, add the following lines to your `rules.mk`:
+```mk
STENO_ENABLE = yes
-MOUSEKEY_ENABLE = no
+STENO_PROTOCOL = geminipr
```
-In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
+All packets in the GeminiPR protocol consist of exactly six bytes, used as bit-arrays for different groups of keys. The beginning of a packet is indicated by setting the most significant bit (MSB) to 1 while setting the MSB of the remaining five bytes to 0.
-```c
-void eeconfig_init_user() {
- steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
-}
+The format of GeminiPR packets is shown below.
+```
+1 Fn #1 #2 #3 #4 #5 #6
+0 S1- S2- T- K- P- W- H-
+0 R- A- O- *1 *2 res1 res2
+0 pwr *3 *4 -E -U -F -R
+0 -P -B -L -G -T -S -D
+0 #7 #8 #9 #A #B #C -Z
```
-Once you have your keyboard flashed launch Plover. Click the 'Configure...' button. In the 'Machine' tab select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
+Examples of steno strokes and the associated packet:
+- `EUBG` = `10000000 00000000 00000000 00001100 00101000 00000000`
+- `WAZ` = `10000000 00000010 00100000 00000000 00000000 00000001`
+- `PHAPBGS` = `10000000 00000101 00100000 00000000 01101010 00000000`
-On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
+### Switching protocols on the fly :id=switching-protocols-on-the-fly
+
+If you wish to switch the serial protocol used to transfer the steno chords without having to recompile your keyboard firmware every time, you can press the `QK_STENO_BOLT` and `QK_STENO_GEMINI` keycodes in order to switch protocols on the fly.
+
+To enable these special keycodes, add the following lines to your `rules.mk`:
+```mk
+STENO_ENABLE = yes
+STENO_PROTOCOL = all
+```
+
+If you want to switch protocols programatically, as part of a custom macro for example, don't use `tap_code(QK_STENO_*)`, as `tap_code` only supports [basic keycodes](keycodes_basic). Instead, you should use `steno_set_mode(STENO_MODE_*)`, whose valid arguments are `STENO_MODE_BOLT` and `STENO_MODE_GEMINI`.
+
+The default protocol is Gemini PR but the last protocol used is stored in non-volatile memory so QMK will remember your choice between reboots of your keyboard &mdash; assuming that your keyboard features (emulated) EEPROM.
+
+Naturally, this option takes the most amount of firmware space as it needs to compile the code for all the available stenography protocols. In most cases, compiling a single stenography protocol is sufficient.
+
+The default value for `STENO_PROTOCOL` is `all`.
+
+## Configuring QMK for Steno :id=configuring-qmk-for-steno
+
+After enabling stenography and optionally selecting a protocol, you may also need disable mouse keys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
+
+!> If you had *explicitly* set `VIRSTER_ENABLE = no`, none of the serial stenography protocols (GeminiPR, TX Bolt) will work properly. You are expected to either set it to `yes`, remove the line from your `rules.mk` or send the steno chords yourself in an alternative way using the [provided interceptable hooks](#interfacing-with-the-code).
+
+In your keymap, create a new layer for Plover, that you can fill in with the [steno keycodes](#keycode-reference) (you will need to include `keymap_steno.h`, see `planck/keymaps/steno/keymap.c` for an example). Remember to create a key to switch to the layer as well as a key for exiting the layer.
+
+Once you have your keyboard flashed, launch Plover. Click the 'Configure...' button. In the 'Machine' tab, select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
+
+To test your keymap, you can chord keys on your keyboard and either look at the output of the 'paper tape' (Tools > Paper Tape) or that of the 'layout display' (Tools > Layout Display). If your strokes correctly show up, you are now ready to steno!
## Learning Stenography :id=learning-stenography
@@ -60,7 +121,7 @@ On the display tab click 'Open stroke display'. With Plover disabled you should
The steno code has three interceptable hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things.
```c
-bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]);
+bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE]);
```
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
@@ -72,15 +133,23 @@ bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
```c
-bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
+bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE], int8_t n_pressed_keys);
```
-This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys.
+This function is called after a key has been processed, but before any decision about whether or not to send a chord. This is where to put hooks for things like, say, live displays of steno chords or keys.
+
+If `IS_PRESSED(record->event)` is false, and `n_pressed_keys` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This relieves you of the need of keeping track of where a packet ends and another begins.
+
+The `chord` argument contains the packet of the current chord as specified by the protocol in use. This is *NOT* simply a list of chorded steno keys of the form `[STN_E, STN_U, STN_BR, STN_GR]`. Refer to the appropriate protocol section of this document to learn more about the format of the packets in your steno protocol/mode of choice.
+The `n_pressed_keys` argument is the number of physical keys actually being held down.
+This is not always equal to the number of bits set to 1 (aka the [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight)) in `chord` because it is possible to simultaneously press down four keys, then release three of those four keys and then press yet another key while the fourth finger is still holding down its key.
+At the end of this scenario given as an example, `chord` would have five bits set to 1 but
+`n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down.
## Keycode Reference :id=keycode-reference
-As defined in `keymap_steno.h`.
+You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_steno.h"` before you can use these keycodes
> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both.
@@ -124,10 +193,10 @@ As defined in `keymap_steno.h`.
|`STN_SR`|`STN_SR`| `-S`|
|`STN_DR`|`STN_DR`| `-D`|
|`STN_ZR`|`STN_ZR`| `-Z`|
-|`STN_FN`|| (GeminiPR only)|
-|`STN_RES1`||(GeminiPR only)|
-|`STN_RES2`||(GeminiPR only)|
-|`STN_PWR`||(GeminiPR only)|
+|`STN_FN`|| (Function)|
+|`STN_RES1`||(Reset 1)|
+|`STN_RES2`||(Reset 2)|
+|`STN_PWR`||(Power)|
If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file.
diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md
index c055a9989a..05134ec229 100644
--- a/docs/feature_tap_dance.md
+++ b/docs/feature_tap_dance.md
@@ -14,55 +14,48 @@ Optionally, you might want to set a custom `TAPPING_TERM` time by adding somethi
```c
#define TAPPING_TERM 175
+#define TAPPING_TERM_PER_KEY
```
-The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead.
+The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. The `TAPPING_TERM_PER_KEY` definition is only needed if you control the tapping term through a [custom `get_tapping_term` function](tap_hold.md#tapping_term), which may be needed because `TAPPING_TERM` affects not just tap-dance keys.
-Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that takes a number which will later be used as an index into the `tap_dance_actions` array.
+Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro. That macro takes a number which will later be used as an index into the `tap_dance_actions` array and turns it into a tap-dance keycode.
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
- * This is the same as `ACTION_TAP_DANCE_DUAL_ROLE`, but renamed to something that is clearer about its functionality. Both names will work.
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
-* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`.
- * This is deprecated in favor of the Per Key Tapping Term functionality, as outlined [here](tap_hold.md#tapping-term). You'd want to check for the specific `TD()` macro that you want to use (such as `TD(TD_ESC_CAPS)`) instead of using this specific Tap Dance function.
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
!> Keep in mind that only [basic keycodes](keycodes_basic.md) are supported here. Custom keycodes are not supported.
-Similar to the first option, the second option is good for simple layer-switching cases.
+Similar to the first option, the second and third option are good for simple layer-switching cases.
-For more complicated cases, use the third or fourth options (examples of each are listed below).
-
-Finally, the fifth option is particularly useful if your non-Tap-Dance keys start behaving weirdly after adding the code for your Tap Dance keys. The likely problem is that you changed the `TAPPING_TERM` time to make your Tap Dance keys easier for you to use, and that this has changed the way your other keys handle interrupts.
+For more complicated cases, like blink the LEDs, fiddle with the backlighting, and so on, use the fourth or fifth option. Examples of each are listed below.
## Implementation Details :id=implementation
Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works!
-The main entry point is `process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and reset the timer.
-
-This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
+Let's go over the three functions mentioned in `ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same too arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tap dance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tap dance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`.
-Our next stop is `tap_dance_task()`. This handles the timeout of tap-dance keys.
+To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
-For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros.
+This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
## Examples :id=examples
-### Simple Example :id=simple-example
+### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap :id=simple-example
Here's a simple example for a single definition:
1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes`
-2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200`
-3. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
+2. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
```c
// Tap Dance declarations
@@ -92,40 +85,15 @@ All the enums used in the examples are declared like this:
```c
// Enums defined for all examples:
enum {
- CT_SE,
- CT_CLN,
+ TD_ESC_CAPS,
CT_EGG,
CT_FLSH,
- X_TAP_DANCE
-};
-```
-
-#### Example 1: Send `:` on Single Tap, `;` on Double Tap :id=example-1
-
-```c
-void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) {
- if (state->count == 1) {
- register_code16(KC_COLN);
- } else {
- register_code(KC_SCLN);
- }
-}
-
-void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) {
- if (state->count == 1) {
- unregister_code16(KC_COLN);
- } else {
- unregister_code(KC_SCLN);
- }
-}
-
-// All tap dance functions would go here. Only showing this one.
-qk_tap_dance_action_t tap_dance_actions[] = {
- [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
+ CT_CLN,
+ X_CTL,
};
```
-#### Example 2: Send "Safety Dance!" After 100 Taps :id=example-2
+#### Example 1: Send "Safety Dance!" After 100 Taps :id=example-1
```c
void dance_egg(qk_tap_dance_state_t *state, void *user_data) {
@@ -140,7 +108,7 @@ qk_tap_dance_action_t tap_dance_actions[] = {
};
```
-#### Example 3: Turn LED Lights On Then Off, One at a Time :id=example-3
+#### Example 2: Turn LED Lights On Then Off, One at a Time :id=example-2
```c
// On each tap, light up one LED, from right to left
@@ -181,15 +149,74 @@ void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) {
ergodox_right_led_3_off();
}
-// All tap dances now put together. Example 3 is "CT_FLASH"
+// All tap dances now put together. Example 2 is "CT_FLSH"
qk_tap_dance_action_t tap_dance_actions[] = {
- [CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT),
- [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
+ [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
};
```
+#### Example 3: Send `:` on Tap, `;` on Hold :id=example-3
+
+With a little effort, powerful tap-hold configurations can be implemented as tap dances. To emit taps as early as possible, we need to act on releases of the tap dance key. There is no callback for this in the tap dance framework, so we use `process_record_user()`.
+
+```c
+typedef struct {
+ uint16_t tap;
+ uint16_t hold;
+ uint16_t held;
+} tap_dance_tap_hold_t;
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ qk_tap_dance_action_t *action;
+
+ switch (keycode) {
+ case TD(CT_CLN): // list all tap dance keycodes with tap-hold configurations
+ action = &tap_dance_actions[TD_INDEX(keycode)];
+ if (!record->event.pressed && action->state.count && !action->state.finished) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
+ tap_code16(tap_hold->tap);
+ }
+ }
+ return true;
+}
+
+void tap_dance_tap_hold_finished(qk_tap_dance_state_t *state, void *user_data) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
+
+ if (state->pressed) {
+ if (state->count == 1
+#ifndef PERMISSIVE_HOLD
+ && !state->interrupted
+#endif
+ ) {
+ register_code16(tap_hold->hold);
+ tap_hold->held = tap_hold->hold;
+ } else {
+ register_code16(tap_hold->tap);
+ tap_hold->held = tap_hold->tap;
+ }
+ }
+}
+
+void tap_dance_tap_hold_reset(qk_tap_dance_state_t *state, void *user_data) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
+
+ if (tap_hold->held) {
+ unregister_code16(tap_hold->held);
+ tap_hold->held = 0;
+ }
+}
+
+#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \
+ { .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), }
+
+qk_tap_dance_action_t tap_dance_actions[] = {
+ [CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN),
+};
+```
+
#### Example 4: 'Quad Function Tap-Dance' :id=example-4
By [DanielGGordon](https://github.com/danielggordon)
@@ -329,7 +356,7 @@ And then simply use `TD(X_CTL)` anywhere in your keymap.
If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace.
-> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
+> In this configuration "hold" takes place **after** tap dance timeout. To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
#### Example 5: Using tap dance for advanced mod-tap and layer-tap keys :id=example-5
@@ -511,8 +538,18 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
// Associate our tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
- [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275)
+ [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset)
};
+
+// Set a long-ish tapping term for tap-dance keys
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
+ return 275;
+ default:
+ return TAPPING_TERM;
+ }
+}
```
The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active.
@@ -521,6 +558,6 @@ The use of `cur_dance()` and `ql_tap_state` mirrors the above examples.
The `case: TD_SINGLE_TAP` in `ql_finished` is similar to the above examples. The `TD_SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `TD_DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`.
-`tap_dance_actions[]` works similar to the above examples. Note that I used `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` instead of `ACTION_TAP_DANCE_FN_ADVANCED()`. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here.
+`tap_dance_actions[]` works similar to the above examples. Note that, additionally, I set a longer tapping term for the tap dance keys. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here. In order for the per-key tapping terms to take effect, `TAPPING_TERM_PER_KEY` must be defined in your `config.h`.
Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`.
diff --git a/docs/feature_terminal.md b/docs/feature_terminal.md
deleted file mode 100644
index f850622165..0000000000
--- a/docs/feature_terminal.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Terminal
-
-> This feature is currently *huge*, and should probably only be put on boards with a lot of memory, or for fun.
-
-The terminal feature is a command-line-like interface designed to communicate through a text editor with keystrokes. It's beneficial to turn off auto-indent features in your editor.
-
-To enable, stick this in your `rules.mk` or `Makefile`:
-
- TERMINAL_ENABLE = yes
-
-And use the `TERM_ON` and `TERM_OFF` keycodes to turn it on or off.
-
-When enabled, a `> ` prompt will appear, where you'll be able to type, backspace (a bell will ding if you reach the beginning and audio is enabled), and hit enter to send the command. Arrow keys are currently disabled so it doesn't get confused. Moving your cursor around with the mouse is discouraged.
-
-`#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page.
-
-Pressing "up" and "down" will allow you to cycle through the past 5 commands entered.
-
-## Future Ideas
-
-* Keyboard/user-extensible commands
-* Smaller footprint
-* Arrow key support
-* Command history - Done
-* SD card support
-* LCD support for buffer display
-* Keycode -> name string LUT
-* Layer status
-* *Analog/digital port read/write*
-* RGB mode stuff
-* Macro definitions
-* EEPROM read/write
-* Audio control
-
-## Current Commands
-
-### `about`
-
-Prints out the current version of QMK with a build date:
-
-```
-> about
-QMK Firmware
- v0.5.115-7-g80ed73-dirty
- Built: 2017-08-29-20:24:44
-```
-
-
-### `print-buffer`
-
-Outputs the last 5 commands entered
-
-```
-> print-buffer
-0. print-buffer
-1. help
-2. about
-3. keymap 0
-4. help
-5. flush-buffer
-```
-
-### `flush-buffer`
-
-Clears command buffer
-```
-> flush-buffer
-Buffer cleared!
-```
-
-
-### `help`
-
-
-Prints out the available commands:
-
-```
-> help
-commands available:
- about help keycode keymap exit print-buffer flush-buffer
-```
-
-### `keycode <layer> <row> <col>`
-
-Prints out the keycode value of a certain layer, row, and column:
-
-```
-> keycode 0 1 0
-0x29 (41)
-```
-
-### `keymap <layer>`
-
-Prints out the entire keymap for a certain layer
-
-```
-> keymap 0
-0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a,
-0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034,
-0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028,
-0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f,
->
-```
-
-### `exit`
-
-Exits the terminal - same as `TERM_OFF`.
diff --git a/docs/flashing.md b/docs/flashing.md
index 271e15b13c..5e5dcb34e4 100644
--- a/docs/flashing.md
+++ b/docs/flashing.md
@@ -358,3 +358,46 @@ CLI Flashing sequence:
2. Wait for the OS to detect the device
3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/blackpill_f411_tinyuf2 --keymap default`
4. Wait for the keyboard to become available
+
+### `make` Targets
+
+* `:uf2-split-left` and `:uf2-split-right`: Flashes the firmware but also sets the handedness setting in EEPROM by generating a side specific firmware.
+
+## Raspberry Pi RP2040 UF2
+
+The `rules.mk` setting for this bootloader is `rp2040`, and can be specified at the keymap or user level.
+
+To ensure compatibility with the rp2040 bootloader, make sure this block is present in your `rules.mk`:
+
+```make
+# Bootloader selection
+BOOTLOADER = rp2040
+```
+
+Compatible flashers:
+
+* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_.
+
+Flashing sequence:
+
+1. Enter the bootloader using any of the following methods:
+ * Tap the `QK_BOOTLOADER` keycode
+ * Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
+ * Double-tap the `RESET` button on the PCB<sup>1</sup>.
+2. Wait for the OS to detect the device
+3. Copy the .uf2 file to the new USB disk
+4. Wait for the keyboard to become available
+
+or
+
+CLI Flashing sequence:
+
+1. Enter the bootloader using any of the following methods:
+ * Tap the `QK_BOOTLOADER` keycode
+ * Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
+ * Double-tap the `RESET` button on the PCB<sup>1</sup>.
+2. Wait for the OS to detect the device
+3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/rpi_pico --keymap default`
+4. Wait for the keyboard to become available
+
+<sup>1</sup>: This works only if QMK was compiled with `RP2040_BOOTLOADER_DOUBLE_TAP_RESET` defined.
diff --git a/docs/ja/_summary.md b/docs/ja/_summary.md
index 81b5756c27..8516a5eaaa 100644
--- a/docs/ja/_summary.md
+++ b/docs/ja/_summary.md
@@ -85,7 +85,6 @@
* [スワップãƒãƒ³ãƒ‰](ja/feature_swap_hands.md)
* [タップダンス](ja/feature_tap_dance.md)
* [タップホールド設定](ja/tap_hold.md)
- * [ターミナル](ja/feature_terminal.md)
* [ユニコード](ja/feature_unicode.md)
* [ユーザスペース](ja/feature_userspace.md)
* [WPM 計算](ja/feature_wpm.md)
diff --git a/docs/ja/config_options.md b/docs/ja/config_options.md
index fb43d015f2..42dd9d502a 100644
--- a/docs/ja/config_options.md
+++ b/docs/ja/config_options.md
@@ -144,7 +144,7 @@ QMK ã§ã®å…¨ã¦ã®åˆ©ç”¨å¯èƒ½ãªè¨­å®šã«ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãŒã‚ã‚Šã¾ã™ã€‚ã
## 設定å¯èƒ½ãªæŒ™å‹• :id=behaviors-that-can-be-configured
* `#define TAPPING_TERM 200`
- * タップãŒãƒ›ãƒ¼ãƒ«ãƒ‰ã«ãªã‚‹ã¾ã§ã®æ™‚間。500以上ã«è¨­å®šã•ã‚ŒãŸå ´åˆã€ã‚¿ãƒƒãƒ—期間中ã«ã‚¿ãƒƒãƒ—ã•ã‚ŒãŸã‚­ãƒ¼ã‚‚ホールドã«ãªã‚Šã¾ã™ã€‚(訳注: PERMISSIVE_HOLDã‚‚å‚ç…§)
+ * タップãŒãƒ›ãƒ¼ãƒ«ãƒ‰ã«ãªã‚‹ã¾ã§ã®æ™‚間。
* `#define TAPPING_TERM_PER_KEY`
* キーã”ã¨ã® `TAPPING_TERM` 設定ã®å‡¦ç†ã‚’有効ã«ã—ã¾ã™
* `#define RETRO_TAPPING`
diff --git a/docs/ja/custom_matrix.md b/docs/ja/custom_matrix.md
index 277fc658d3..2c697bb148 100644
--- a/docs/ja/custom_matrix.md
+++ b/docs/ja/custom_matrix.md
@@ -87,17 +87,17 @@ void matrix_init(void) {
}
uint8_t matrix_scan(void) {
- bool matrix_has_changed = false;
+ bool changed = false;
// TODO: ã“ã“ã«ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ãƒ«ãƒ¼ãƒãƒ³ã‚’追加ã—ã¾ã™
// ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã«ã‚ˆã‚‹ãƒ‡ãƒã‚¦ãƒ³ã‚¹ãŒãªã„å ´åˆ - 設定ã•ã‚Œã¦ã„るデãƒã‚¦ãƒ³ã‚¹ãƒ«ãƒ¼ãƒãƒ³ã‚’使用ã—ã¾ã™
- debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
+ changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
// æ­£ã—ã„キーボード動作ã®ãŸã‚ã«ã“れを呼ã³å‡ºã™*å¿…è¦ãŒã‚ã‚Šã¾ã™*
matrix_scan_quantum();
- return matrix_has_changed;
+ return changed;
}
```
diff --git a/docs/ja/feature_dynamic_macros.md b/docs/ja/feature_dynamic_macros.md
index 951b903127..3cff788007 100644
--- a/docs/ja/feature_dynamic_macros.md
+++ b/docs/ja/feature_dynamic_macros.md
@@ -40,6 +40,7 @@ QMK ã¯ãã®å ´ã§ä½œã‚‰ã‚ŒãŸä¸€æ™‚çš„ãªãƒžã‚¯ãƒ­ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™ã€‚ã
| `DYNAMIC_MACRO_SIZE` | 128 | 動的マクロãŒä½¿ç”¨ã§ãるメモリé‡ã‚’設定ã—ã¾ã™ã€‚ã“ã‚Œã¯é™ã‚‰ã‚ŒãŸãƒªã‚½ãƒ¼ã‚¹ã§ã‚ã‚Šã€ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã«ä¾å­˜ã—ã¾ã™ã€‚ |
| `DYNAMIC_MACRO_USER_CALL` | *定義ãªã—* | ã“れを定義ã™ã‚‹ã¨ã€ãƒ¦ãƒ¼ã‚¶ã® `keymap.c` ファイルを使ã£ã¦ãƒžã‚¯ãƒ­ãŒèµ·å‹•ã•ã‚Œã¾ã™ã€‚ |
| `DYNAMIC_MACRO_NO_NESTING` | *定義ãªã—* | ã“れを定義ã™ã‚‹ã¨ã€åˆ¥ã®ãƒžã‚¯ãƒ­ã‹ã‚‰ãƒžã‚¯ãƒ­ã‚’呼ã³å‡ºã™(入れå­ã«ãªã£ãŸãƒžã‚¯ãƒ­)機能を無効ã«ã—ã¾ã™ã€‚ |
+| `DYNAMIC_MACRO_DELAY` | *定義ãªã—* | å„キーをé€ä¿¡ã™ã‚‹æ™‚ã®å¾…ã¡æ™‚間(mså˜ä½ï¼‰ã‚’設定ã—ã¾ã™ã€‚ |
記録中ã«ã‚­ãƒ¼ã‚’押ã™ãŸã³ã« LED ãŒç‚¹æ»…ã—始ã‚ãŸå ´åˆã¯ã€ãƒžã‚¯ãƒ­ãƒãƒƒãƒ•ã‚¡ã«ãƒžã‚¯ãƒ­ã‚’入れるスペースãŒã‚‚ã†ç„¡ã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚マクロを入れるã«ã¯ã€ä»–ã®ãƒžã‚¯ãƒ­(ãれらã¯åŒã˜ãƒãƒƒãƒ•ã‚¡ã‚’共有ã—ã¾ã™)を短ãã™ã‚‹ã‹ã€`config.h` ã« `DYNAMIC_MACRO_SIZE` 定義を追加ã™ã‚‹ã“ã¨ã§ãƒãƒƒãƒ•ã‚¡ã‚’増やã—ã¾ã™(デフォルト値: 128; ヘッダ内ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’読んã§ãã ã•ã„)。
diff --git a/docs/ja/feature_tap_dance.md b/docs/ja/feature_tap_dance.md
index a6d108f1e9..762816f21b 100644
--- a/docs/ja/feature_tap_dance.md
+++ b/docs/ja/feature_tap_dance.md
@@ -28,7 +28,6 @@
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: 1回タップã™ã‚‹ã¨ `kc1` キーコードをé€ä¿¡ã—ã€2回タップã™ã‚‹ã¨ `kc2` キーコードをé€ä¿¡ã—ã¾ã™ã€‚キーを押ã—続ã‘ã¦ã„ã‚‹ã¨ãã¯ã€é©åˆ‡ãªã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ãŒç™»éŒ²ã•ã‚Œã¾ã™: キーを押ã—続ã‘ãŸå ´åˆã¯ `kc1`ã€ä¸€åº¦ã‚¿ãƒƒãƒ—ã—ã¦ã‹ã‚‰ç¶šã‘ã¦ã‚‚ã†ä¸€åº¦ã‚­ãƒ¼ã‚’押ã—ã¦ãã®ã¾ã¾æŠ¼ã—続ã‘ãŸã¨ãã¯ã€ `kc2` ãŒç™»éŒ²ã•ã‚Œã¾ã™ã€‚
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: 1回タップã™ã‚‹ã¨ `kc` キーコードãŒé€ä¿¡ã•ã‚Œã€2回タップã™ã‚‹ã¨ `layer` レイヤーã«ç§»å‹•ã—ã¾ã™(ã“れ㯠`TO` レイヤーキーコードã®ã‚ˆã†ã«æ©Ÿèƒ½ã—ã¾ã™)。
- * ã“ã®æ©Ÿèƒ½ã¯ `ACTION_TAP_DANCE_DUAL_ROLE` ã¨åŒã˜ã§ã™ãŒã€æ©Ÿèƒ½ãŒæ˜Žç¢ºã«ãªã‚‹ã‚ˆã†ã«é–¢æ•°åを変更ã—ã¾ã—ãŸã€‚ã©ã¡ã‚‰ã®é–¢æ•°åã§ã‚‚実行ã§ãã¾ã™ã€‚
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: 1回タップã™ã‚‹ã¨ `kc` キーコードãŒé€ä¿¡ã•ã‚Œã€2回タップã™ã‚‹ã¨ `layer` ã®çŠ¶æ…‹ã‚’トグルã—ã¾ã™(ã“れ㯠`TG` レイヤーキーコードã®ã‚ˆã†ã«æ©Ÿèƒ½ã—ã¾ã™)。
* `ACTION_TAP_DANCE_FN(fn)`: ユーザーキーマップã«å®šç¾©ã—ãŸæŒ‡å®šã®é–¢æ•°ãŒå‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚タップダンス実行ã®å›žæ•°åˆ†ã‚¿ãƒƒãƒ—ã™ã‚‹ã¨ã€æœ€å¾Œã®æ™‚点ã§å‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: タップã™ã‚‹åº¦ã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚­ãƒ¼ãƒžãƒƒãƒ—ã«å®šç¾©ã—ãŸæœ€åˆã®é–¢æ•°ãŒå‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚タップダンスã®å®Ÿè¡ŒãŒçµ‚ã‚ã£ãŸæ™‚点ã§2番目ã®é–¢æ•°ãŒå‘¼ã³å‡ºã•ã‚Œã€ã‚¿ãƒƒãƒ—ダンスã®å®Ÿè¡Œã‚’リセットã™ã‚‹ã¨ãã«æœ€å¾Œã®é–¢æ•°ãŒå‘¼ã³å‡ºã•ã‚Œã¾ã™ã€‚
diff --git a/docs/ja/feature_terminal.md b/docs/ja/feature_terminal.md
deleted file mode 100644
index 8e125ecee0..0000000000
--- a/docs/ja/feature_terminal.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# ターミナル
-
-<!---
- original document: 0.8.147:docs/feature_terminal.md
- git diff 0.8.147 HEAD -- docs/feature_terminal.md | cat
--->
-
-> ã“ã®æ©Ÿèƒ½ã¯ç¾åœ¨ã®ã¨ã“ã‚*巨大*ã§ã‚ã‚Šã€ãŠãらã大é‡ã®ãƒ¡ãƒ¢ãƒªã‚’æ­è¼‰ã—ãŸã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã€ã¾ãŸã¯æ¥½ã—ã¿ã®ãŸã‚ã«ã®ã¿é…ç½®ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
-
-ターミナル機能ã¯ãƒ†ã‚­ã‚¹ãƒˆã‚¨ãƒ‡ã‚£ã‚¿ã‚’介ã—ã¦ã‚­ãƒ¼ã‚¹ãƒˆãƒ­ãƒ¼ã‚¯ã§é€šä¿¡ã™ã‚‹ã‚ˆã†ã«è¨­è¨ˆã•ã‚ŒãŸã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã®ã‚ˆã†ãªã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹ã§ã™ã€‚エディタã§è‡ªå‹•ã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆæ©Ÿèƒ½ã‚’オフã«ã™ã‚‹ã“ã¨ã¯æœ‰ç›Šã§ã™ã€‚
-
-有効ã«ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã‚’ `rules.mk` ã¾ãŸã¯ `Makefile` ã«è²¼ã‚Šä»˜ã‘ã¾ã™:
-
- TERMINAL_ENABLE = yes
-
-ãã—ã¦ã€ã‚ªãƒ³ã¾ãŸã¯ã‚ªãƒ•ã«ã™ã‚‹ãŸã‚ã«ã€`TERM_ON` ãŠã‚ˆã³ `TERM_OFF` キーコードを使ã„ã¾ã™ã€‚
-
-有効ãªå ´åˆã€`> ` プロンプトãŒç¾ã‚Œã€ã“ã“ã§ã‚³ãƒžãƒ³ãƒ‰ã‚„ãƒãƒƒã‚¯ã‚¹ãƒšãƒ¼ã‚¹(オーディオãŒæœ‰åŠ¹ãªå ´åˆã¯ã€å…ˆé ­ã«åˆ°é”ã™ã‚‹ã¨ãƒ™ãƒ«ãŒé³´ã‚Šã¾ã™)を入力ã™ã‚‹ã“ã¨ãŒã§ãã€ã‚¨ãƒ³ã‚¿ãƒ¼ã‚’入力ã™ã‚‹ã¨ã‚³ãƒžãƒ³ãƒ‰ã‚’é€ä¿¡ã—ã¾ã™ã€‚矢å°ã‚­ãƒ¼ã¯ç¾åœ¨ã®ã¨ã“ã‚無効ãªãŸã‚ã€æ··ä¹±ã™ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。マウスã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’移動ã™ã‚‹ã“ã¨ã¯ãŠå‹§ã‚ã—ã¾ã›ã‚“。
-
-`#define TERMINAL_HELP` ã¯ã€ã“ã®ãƒšãƒ¼ã‚¸ã§ã¯å®Ÿéš›ã«ã¯å¿…è¦ã®ãªã„ä»–ã®å‡ºåŠ›ãƒ˜ãƒ«ãƒ‘ーを有効ã«ã—ã¾ã™ã€‚
-
-"上矢å°" ãŠã‚ˆã³ "下矢å°" ã«ã‚ˆã‚Šã€éŽåŽ»ã«å…¥åŠ›ã—ãŸ5ã¤ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’é †ã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
-
-## 今後ã®ã‚¢ã‚¤ãƒ‡ã‚¢
-
-* キーボード/ユーザ拡張å¯èƒ½ãªã‚³ãƒžãƒ³ãƒ‰
-* よりå°ã•ãªãƒ•ãƒƒãƒˆãƒ—リント
-* 矢å°ã‚­ãƒ¼ã®ã‚µãƒãƒ¼ãƒˆ
-* コマンド履歴 - 完了
-* SD カードã®ã‚µãƒãƒ¼ãƒˆ
-* ãƒãƒƒãƒ•ã‚¡ãƒ‡ã‚£ã‚¹ãƒ—レイã®ãŸã‚ã® LCD サãƒãƒ¼ãƒˆ
-* キーコード -> å称ã®å¯¾å¿œè¡¨
-* レイヤー状態
-* *アナログ/デジタル ãƒãƒ¼ãƒˆã®èª­ã¿è¾¼ã¿/書ãè¾¼ã¿*
-* RGB モード関連機能
-* マクロ定義
-* EEPROM ã®èª­ã¿è¾¼ã¿/書ãè¾¼ã¿
-* オーディオ制御
-
-## ç¾åœ¨ã®ã‚³ãƒžãƒ³ãƒ‰
-
-### `about`
-
-ç¾åœ¨ã® QMK ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ“ルドã—ãŸæ—¥ã®å‡ºåŠ›:
-
-```
-> about
-QMK Firmware
- v0.5.115-7-g80ed73-dirty
- Built: 2017-08-29-20:24:44
-```
-
-
-### `print-buffer`
-
-最後ã«å…¥åŠ›ã—ãŸ5ã¤ã®ã‚³ãƒžãƒ³ãƒ‰ã®å‡ºåŠ›
-
-```
-> print-buffer
-0. print-buffer
-1. help
-2. about
-3. keymap 0
-4. help
-5. flush-buffer
-```
-
-### `flush-buffer`
-
-コマンドãƒãƒƒãƒ•ã‚¡ã‚’クリア
-```
-> flush-buffer
-Buffer cleared!
-```
-
-
-### `help`
-
-
-利用å¯èƒ½ãªã‚³ãƒžãƒ³ãƒ‰ã®å‡ºåŠ›:
-
-```
-> help
-commands available:
- about help keycode keymap exit print-buffer flush-buffer
-```
-
-### `keycode <layer> <row> <col>`
-
-特定ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã€è¡ŒãŠã‚ˆã³åˆ—ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰å€¤ã®å‡ºåŠ›:
-
-```
-> keycode 0 1 0
-0x29 (41)
-```
-
-### `keymap <layer>`
-
-特定ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã®å…¨ã¦ã®ã‚­ãƒ¼ãƒžãƒƒãƒ—ã®å‡ºåŠ›
-
-```
-> keymap 0
-0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a,
-0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034,
-0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028,
-0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f,
->
-```
-
-### `exit`
-
-ターミナルã®çµ‚了 - `TERM_OFF` ã¨åŒã˜ã€‚
diff --git a/docs/ja/understanding_qmk.md b/docs/ja/understanding_qmk.md
index 1654f8e002..550ee3a7c0 100644
--- a/docs/ja/understanding_qmk.md
+++ b/docs/ja/understanding_qmk.md
@@ -161,7 +161,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
- * [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
* [Quantum 固有ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’識別ã—ã¦å‡¦ç†ã™ã‚‹](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
ã“ã®ä¸€é€£ã®ã‚¤ãƒ™ãƒ³ãƒˆã®ä¸­ã®ä»»æ„ã®ã‚¹ãƒ†ãƒƒãƒ—㧠(`process_record_kb()` ã®ã‚ˆã†ãª)関数㯠`false` ã‚’è¿”ã—ã¦ã€ä»¥é™ã®å‡¦ç†ã‚’åœæ­¢ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
diff --git a/docs/keycodes.md b/docs/keycodes.md
index bd5af32dd3..37e9d00392 100644
--- a/docs/keycodes.md
+++ b/docs/keycodes.md
@@ -337,6 +337,9 @@ See also: [Magic Keycodes](keycodes_magic.md)
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
+|`MAGIC_SWAP_ESCAPE_CAPSLOCK` |`EC_SWAP`|Swap Caps Lock and Escape |
+|`MAGIC_UNSWAP_ESCAPE_CAPSLOCK` |`EC_NORM`|Unswap Caps Lock and Escape |
+|`MAGIC_TOGGLE_ESCAPE_CAPSLOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap |
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
diff --git a/docs/keycodes_magic.md b/docs/keycodes_magic.md
index 01eb69168e..982a301630 100644
--- a/docs/keycodes_magic.md
+++ b/docs/keycodes_magic.md
@@ -7,6 +7,9 @@
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
+|`MAGIC_SWAP_ESCAPE_CAPSLOCK` |`EC_SWAP`|Swap Caps Lock and Escape |
+|`MAGIC_UNSWAP_ESCAPE_CAPSLOCK` |`EC_NORM`|Unswap Caps Lock and Escape |
+|`MAGIC_TOGGLE_ESCAPE_CAPSLOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap |
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
diff --git a/docs/platformdev_chibios_earlyinit.md b/docs/platformdev_chibios_earlyinit.md
index aaa91ba438..e1256f2714 100644
--- a/docs/platformdev_chibios_earlyinit.md
+++ b/docs/platformdev_chibios_earlyinit.md
@@ -20,7 +20,7 @@ As such, if you wish to override this API consider limiting use to writing to lo
| `#define STM32_BOOTLOADER_DUAL_BANK` | Relevant for dual-bank STM32 MCUs, signifies that a GPIO is to be toggled in order to enter bootloader mode. | `FALSE` |
| `#define STM32_BOOTLOADER_DUAL_BANK_GPIO` | Relevant for dual-bank STM32 MCUs, the pin to toggle when attempting to enter bootloader mode, e.g. `B8` | `<none>` |
| `#define STM32_BOOTLOADER_DUAL_BANK_POLARITY` | Relevant for dual-bank STM32 MCUs, the value to set the pin to in order to trigger charging of the RC circuit. e.g. `0` or `1`. | `0` |
-| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100000` |
+| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100` |
Kinetis MCUs have no configurable options.
diff --git a/docs/platformdev_proton_c.md b/docs/platformdev_proton_c.md
new file mode 100644
index 0000000000..3afec893fa
--- /dev/null
+++ b/docs/platformdev_proton_c.md
@@ -0,0 +1,77 @@
+# Proton C
+
+The Proton C is an Arm STM32F303xC based drop-in replacement for the Pro Micro.
+
+<img src="https://i.imgur.com/GdsN1Rdh.jpg" alt="Proton C" />
+
+#### Features
+
+* Through-hole mounted USB-C Port
+* 32-bit 72MHz Cortex-M4 processor (STM32F303CCT6)
+* I2C, SPI, PWM, DMA, DAC, USART, I2S
+* 23x 3.3V I/O Ports
+* 1x 5V output for WS2812 LED chains
+* 256kB flash
+* 40kB RAM
+* AST1109MLTRQ speaker footprint
+* Reset button
+
+## Warnings
+
+Some of the PCBs compatible with Pro Micro have VCC (3.3V) and RAW (5V) pins connected (shorted) on the pcb. Using the Proton C will short 5V power from USB and regulated 3.3V which is connected directly to the MCU. Shorting those pins may damage the MCU on the Proton C.
+
+So far, it appears that this is only an issue on the Gherkin PCBs, but other PCBs may be affected in this way.
+
+In this case, you may want to not hook up the RAW pin at all.
+
+## Manual Conversion
+
+To use the Proton C natively, without having to specify `CONVERT_TO=proton_c`, you need to change the `MCU` line in `rules.mk`:
+
+```
+MCU = STM32F303
+BOARD = QMK_PROTON_C
+```
+
+Remove these variables if they exist:
+
+* `BOOTLOADER`
+* `EXTRA_FLAGS`
+
+Finally convert all pin assignments in `config.h` to the stm32 equivalents.
+
+| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right |
+|-----------|----------|-|----------|-----------|
+| `D3` | `A9` | | 5v | RAW (5v) |
+| `D2` | `A10` | | GND | GND |
+| GND | GND | | FLASH | RESET |
+| GND | GND | | 3.3v | VCC <sup>1</sup> |
+| `D1` | `B7` | | `A2` | `F4` |
+| `D0` | `B6` | | `A1` | `F5` |
+| `D4` | `B5` | | `A0` | `F6` |
+| `C6` | `B4` | | `B8` | `F7` |
+| `D7` | `B3` | | `B13` | `B1` |
+| `E6` | `B2` | | `B14` | `B3` |
+| `B4` | `B1` | | `B15` | `B2` |
+| `B5` | `B0` | | `B9` | `B6` |
+| `B0` (RX LED) | `C13` <sup>2</sup> | | `C13` <sup>2</sup> | `D5` (TX LED) |
+
+You can also make use of several new pins on the extended portion of the Proton C:
+
+| Left | | Right |
+|------|-|-------|
+| `A4`<sup>3</sup> | | `B10` |
+| `A5`<sup>4</sup> | | `B11` |
+| `A6` | | `B12` |
+| `A7` | | `A14`<sup>5</sup> (SWCLK) |
+| `A8` | | `A13`<sup>5</sup> (SWDIO) |
+| `A15` | | RESET<sup>6</sup> |
+
+Notes:
+
+1. On a Pro Micro VCC can be 3.3v or 5v.
+2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`.
+3. `A4` is shared with the speaker.
+4. `A5` is shared with the speaker.
+5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last.
+6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU.
diff --git a/docs/platformdev_rp2040.md b/docs/platformdev_rp2040.md
new file mode 100644
index 0000000000..d690ebebf8
--- /dev/null
+++ b/docs/platformdev_rp2040.md
@@ -0,0 +1,125 @@
+# Raspberry Pi RP2040
+
+The following table shows the current driver status for peripherals on RP2040 MCUs:
+
+| System | Support |
+| ---------------------------------------------------------------- | ---------------------------------------------- |
+| [ADC driver](adc_driver.md) | Support planned (no ETA) |
+| [Audio](audio_driver.md) | Support planned (no ETA) |
+| [I2C driver](i2c_driver.md) | :heavy_check_mark: |
+| [SPI driver](spi_driver.md) | :heavy_check_mark: |
+| [WS2812 driver](ws2812_driver.md) | :heavy_check_mark: using `PIO` driver |
+| [External EEPROMs](eeprom_driver.md) | :heavy_check_mark: using `I2C` or `SPI` driver |
+| [EEPROM emulation](eeprom_driver.md#wear_leveling-configuration) | :heavy_check_mark: |
+| [serial driver](serial_driver.md) | :heavy_check_mark: using `SIO` or `PIO` driver |
+| [UART driver](uart_driver.md) | Support planned (no ETA) |
+
+## GPIO
+
+<img alt="Raspberry Pi Pico pinout" src="https://i.imgur.com/nLaiYDE.jpg" width="48%"/>
+<img alt="Sparkfun RP2040 Pro Micro pinout" src="https://i.imgur.com/1TPAhrs.jpg" width="48%"/>
+
+!> The GPIO pins of the RP2040 are not 5V tolerant!
+
+### Pin nomenclature
+
+To address individual pins on the RP2040, QMK uses the `GPx` abbreviation -- where the `x` stands for the GPIO number of the pin. This number can likely be found on the official pinout diagram of your board. Note that these GPIO numbers match the RP2040 MCU datasheet, and don't necessarily match the number you see printed on the board. For instance the Raspberry Pi Pico uses numbers from 1 to 40 for their pins, but these are not identical to the RP2040's GPIO numbers. So if you want to use the pin 11 of the Pico for your keyboard, you would refer to it as `GP8` in the config files.
+
+### Alternate functions
+
+The RP2040 features flexible GPIO function multiplexing, this means that every pin can be connected to nearly all the internal peripherals like I2C, SPI, UART or PWM. This allows for flexible PCB designs that are much less restricted in the selection of GPIO pins. To find out which pin can use which peripheral refer to the official [Raspberry PI RP2040 datasheet](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#page=14) section 1.4.3 GPIO functions.
+
+## Selecting hardware peripherals and drivers
+
+QMK RP2040 support builds upon ChibiOS and thus follows their convention for activating drivers and associated hardware peripherals. These tables only give a quick overview which values have to be used, please refer to the ChibiOS specific sections on the driver pages.
+
+### I2C Driver
+
+| RP2040 Peripheral | `mcuconf.h` values | `I2C_DRIVER` |
+| ----------------- | ------------------ | ------------ |
+| `I2C0` | `RP_I2C_USE_I2C0` | `I2CD1` |
+| `I2C1` | `RP_I2C_USE_I2C1` | `I2CD2` |
+
+To configure the I2C driver please read the [ChibiOS/ARM](i2c_driver.md#arm-configuration) section.
+
+### SPI Driver
+
+| RP2040 Peripheral | `mcuconf.h` values | `SPI_DRIVER` |
+| ----------------- | ------------------ | ------------ |
+| `SPI0` | `RP_SPI_USE_SPI0` | `SPID0` |
+| `SPI1` | `RP_SPI_USE_SPI1` | `SPID1` |
+
+To configure the SPI driver please read the [ChibiOS/ARM](spi_driver.md#chibiosarm-configuration) section.
+
+## Double-tap reset boot-loader entry :id=double-tap
+
+The double-tap reset mechanism is an alternate way in QMK to enter the embedded mass storage UF2 boot-loader of the RP2040. It enables bootloader entry by a fast double-tap of the reset pin on start up, which is similar to the behavior of AVR Pro Micros. This feature activated by default for the Pro Micro RP2040 board, but has to be configured for other boards. To activate it, add the following options to your keyboards `config.h` file:
+
+```c
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET // Activates the double-tap behavior
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U // Timeout window in ms in which the double tap can occur.
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK 0U // Specify a optional status led which blinks when entering the bootloader
+```
+
+## Pre-defined RP2040 boards
+
+QMK defines two boards that you can choose from to base your RP2040 powered keyboard upon. These boards provide pre-configured default pins and drivers.
+
+### Generic Pro Micro RP2040
+
+This is the default board that is chosen, unless any other RP2040 board is selected in your keyboards `rules.mk` file. It assumes a pin layout for the I2C, SPI and Serial drivers which is identical to the Sparkfun Pro Micro RP2040, however all values can be overwritten by defining them in your keyboards `config.h` file. The [double-tap](#double-tap) reset to enter boot-loader behavior is activated by default.
+
+
+| Driver configuration define | Value |
+| -------------------------------------------------------------------------- | ------------------------------------ |
+| **I2C driver** | |
+| `I2C_DRIVER` | `I2CD2` |
+| `I2C1_SDA_PIN` | `GP2` |
+| `I2C1_SCL_PIN` | `GP3` |
+| **SPI driver** | |
+| `SPI_DRIVER` | `SPID0` |
+| `SPI_SCK_PIN` | `GP18` |
+| `SPI_MISO_PIN` | `GP20` |
+| `SPI_MOSI_PIN` | `GP19` |
+| **Serial driver** | |
+| `SERIAL_USART_DRIVER` ([SIO Driver](serial_driver.md#the-sio-driver) only) | `SIOD0` |
+| `SOFT_SERIAL_PIN` | undefined, use `SERIAL_USART_TX_PIN` |
+| `SERIAL_USART_TX_PIN` | `GP0` |
+| `SERIAL_USART_RX_PIN` | `GP1` |
+
+?> The pin-outs of Adafruit's KB2040 and Boardsource's Blok both deviate from the Sparkfun Pro Micro RP2040. Lookup the pin-out of these boards and adjust your keyboards pin definition accordingly if you want to use these boards.
+
+### Generic RP2040 board
+
+This board can be chosen as a base for RP2040 keyboards which configure all necessary pins and drivers themselves and do not wish to leverage the configuration matching the Generic Pro Micro RP2040 board. Thus it doesn't provide any pre-configured pins or drivers. To select this board add the following line to your keyboards `rules.mk` file.
+
+```make
+BOARD = GENERIC_RP_RP2040
+```
+
+## Split keyboard support
+
+Split keyboards are fully supported using the [serial driver](serial_driver.md) in both full-duplex and half-duplex configurations. Two driver subsystems are supported by the RP2040, the hardware UART based `SIO` and the Programmable IO based `PIO` driver.
+
+| Feature | [SIO Driver](serial_driver.md#the-sio-driver) | [PIO Driver](serial_driver.md#the-pio-driver) |
+| ----------------------------- | --------------------------------------------- | --------------------------------------------- |
+| Half-Duplex operation | | :heavy_check_mark: |
+| Full-Duplex operation | :heavy_check_mark: | :heavy_check_mark: |
+| `TX` and `RX` pin swapping | | :heavy_check_mark: |
+| Any GPIO as `TX` and `RX` pin | Only UART capable pins | :heavy_check_mark: |
+| Simple configuration | | :heavy_check_mark: |
+
+The `PIO` driver is much more flexible then the `SIO` driver, the only "downside" is the usage of `PIO` resources which in turn are not available for advanced user programs. Under normal circumstances, this resource allocation will be a non-issue.
+
+## RP2040 second stage bootloader selection
+
+As the RP2040 does not have any internal flash memory it depends on an external SPI flash memory chip to store and execute instructions from. To successfully interact with a wide variety of these chips a second stage bootloader that is compatible with the chosen external flash memory has to be supplied with each firmware image. By default an `W25Q080` compatible bootloader is assumed, but others can be chosen by adding one of the defines listed in the table below to your keyboards `config.h` file.
+
+| Compatible with flash chip | Selection |
+| :------------------------- | ---------------------------------- |
+| W25Q080 | Selected by default |
+| AT25SF128A | `#define RP2040_FLASH_AT25SF128A` |
+| GD25Q64CS | `#define RP2040_FLASH_GD25Q64CS` |
+| W25X10CL | `#define RP2040_FLASH_W25X10CL` |
+| IS25LP080 | `#define RP2040_FLASH_IS25LP080` |
+| Generic 03H flash | `#define RP2040_FLASH_GENERIC_03H` |
diff --git a/docs/proton_c_conversion.md b/docs/proton_c_conversion.md
deleted file mode 100644
index 1e1b1e806d..0000000000
--- a/docs/proton_c_conversion.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# Converting a board to use the Proton C
-
-Since the Proton C is a drop-in replacement for a Pro Micro we've made it easy to use. This page documents a handy automated process for converting keyboards, as well as documenting the manual process if you'd like to make use of Proton C features that aren't available on Pro Micros.
-
-## Automatic Conversion
-
-If a board currently supported in QMK uses a Pro Micro (or compatible board) and you want to use the Proton C, you can generate the firmware by appending `CONVERT_TO_PROTON_C=yes` (or `CTPC=yes`) to your make argument, like this:
-
- make 40percentclub/mf68:default CTPC=yes
-
-You can add the same argument to your keymap's `rules.mk`, which will accomplish the same thing.
-
-This exposes the `CONVERT_TO_PROTON_C` flag that you can use in your code with `#ifdef`s, like this:
-
-```c
-#ifdef CONVERT_TO_PROTON_C
- // Proton C code
-#else
- // Pro Micro code
-#endif
-```
-
-If you get errors about `PORTB/DDRB`, etc not being defined, so you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
-
-The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this like to your `config.h`:
-
- #define CONVERT_TO_PROTON_C_RXLED
-
-## Feature Conversion
-
-These are defaults based on what has been implemented for ARM boards.
-
-| Feature | Notes |
-|-------------------------------------|------------------------------------------------------------------------------------------------------------------|
-| [Audio](feature_audio.md) | Enabled |
-| [RGB Lighting](feature_rgblight.md) | Disabled |
-| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
-| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
-| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
-
-## Manual Conversion
-
-To use the Proton C natively, without having to specify `CTPC=yes`, you need to change the `MCU` line in `rules.mk`:
-
-```
-MCU = STM32F303
-BOARD = QMK_PROTON_C
-```
-
-Remove these variables if they exist:
-
-* `BOOTLOADER`
-* `EXTRA_FLAGS`
-
-Finally convert all pin assignments in `config.h` to the stm32 equivalents.
-
-| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right |
-|-----------|----------|-|----------|-----------|
-| `D3` | `A9` | | 5v | RAW (5v) |
-| `D2` | `A10` | | GND | GND |
-| GND | GND | | FLASH | RESET |
-| GND | GND | | 3.3v | VCC <sup>1</sup> |
-| `D1` | `B7` | | `A2` | `F4` |
-| `D0` | `B6` | | `A1` | `F5` |
-| `D4` | `B5` | | `A0` | `F6` |
-| `C6` | `B4` | | `B8` | `F7` |
-| `D7` | `B3` | | `B13` | `B1` |
-| `E6` | `B2` | | `B14` | `B3` |
-| `B4` | `B1` | | `B15` | `B2` |
-| `B5` | `B0` | | `B9` | `B6` |
-| `B0` (RX LED) | `C13` <sup>2</sup> | | `C13` <sup>2</sup> | `D5` (TX LED) |
-
-You can also make use of several new pins on the extended portion of the Proton C:
-
-| Left | | Right |
-|------|-|-------|
-| `A4`<sup>3</sup> | | `B10` |
-| `A5`<sup>4</sup> | | `B11` |
-| `A6` | | `B12` |
-| `A7` | | `A14`<sup>5</sup> (SWCLK) |
-| `A8` | | `A13`<sup>5</sup> (SWDIO) |
-| `A15` | | RESET<sup>6</sup> |
-
-Notes:
-
-1. On a Pro Micro VCC can be 3.3v or 5v.
-2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`.
-3. `A4` is shared with the speaker.
-4. `A5` is shared with the speaker.
-5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last.
-6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU.
diff --git a/docs/quantum_painter.md b/docs/quantum_painter.md
index a3705b62ce..2386a70933 100644
--- a/docs/quantum_painter.md
+++ b/docs/quantum_painter.md
@@ -24,6 +24,7 @@ Hardware supported:
| GC9A01 | RGB LCD (circular) | 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = gc9a01_spi` |
| ILI9163 | RGB LCD | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9163_spi` |
| ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9341_spi` |
+| ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9488_spi` |
| SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ssd1351_spi` |
| ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = st7789_spi` |
@@ -654,6 +655,30 @@ The maximum number of displays can be configured by changing the following in yo
#define ILI9341_NUM_DEVICES 3
```
+### ILI9488 :id=qp-driver-ili9488
+
+Enabling support for the ILI9488 in Quantum Painter is done by adding the following to `rules.mk`:
+
+```make
+QUANTUM_PAINTER_ENABLE = yes
+QUANTUM_PAINTER_DRIVERS = ili9488_spi
+```
+
+Creating a ILI9488 device in firmware can then be done with the following API:
+
+```c
+painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
+```
+
+The device handle returned from the `qp_ili9488_make_spi_device` function can be used to perform all other drawing operations.
+
+The maximum number of displays can be configured by changing the following in your `config.h` (default is 1):
+
+```c
+// 3 displays:
+#define ILI9488_NUM_DEVICES 3
+```
+
### SSD1351 :id=qp-driver-ssd1351
Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`:
diff --git a/docs/reference_info_json.md b/docs/reference_info_json.md
index aa59711592..52f16b4401 100644
--- a/docs/reference_info_json.md
+++ b/docs/reference_info_json.md
@@ -239,6 +239,42 @@ Example:
The device version is a BCD (binary coded decimal) value, in the format `MMmr`, so the below value would look like `0x0100` in the generated code. This also means the maximum valid values for each part are `99.9.9`, despite it being a hexadecimal value under the hood.
+### Encoders
+
+This section controls the basic [rotary encoder](feature_encoders.md) support.
+
+The following items can be set. Not every value is required.
+
+* `pin_a`
+ * __Required__. A pad definition
+* `pin_b`
+ * __Required__. B pad definition
+* `resolution`
+ * How many pulses the encoder registers between each detent
+
+Examples:
+
+```json
+{
+ "encoder": {
+ "rotary": [
+ { "pin_a": "B5", "pin_b": "A2" }
+ ]
+ }
+}
+```
+
+```json
+{
+ "encoder": {
+ "rotary": [
+ { "pin_a": "B5", "pin_b": "A2", "resolution": 4 }
+ { "pin_a": "B6", "pin_b": "A3", "resolution": 2 }
+ ]
+ }
+}
+```
+
### Secure
The following options can be configured:
diff --git a/docs/serial_driver.md b/docs/serial_driver.md
index 3e89deffad..fff63109a1 100644
--- a/docs/serial_driver.md
+++ b/docs/serial_driver.md
@@ -1,129 +1,301 @@
# 'serial' Driver
-This driver powers the [Split Keyboard](feature_split_keyboard.md) feature.
+
+The serial driver powers the [Split Keyboard](feature_split_keyboard.md) feature. Several implementations are available, depending on the platform of your split keyboard. Note that none of the drivers support split keyboards with more then two halves.
+
+| Driver | AVR | ARM | Connection between halves |
+| --------------------------------------- | ------------------ | ------------------ | --------------------------------------------------------------------------------------------- |
+| [Bitbang](#bitbang) | :heavy_check_mark: | :heavy_check_mark: | Single wire communication. One wire is used for reception and transmission. |
+| [USART Half-duplex](#usart-half-duplex) | | :heavy_check_mark: | Efficient single wire communication. One wire is used for reception and transmission. |
+| [USART Full-duplex](#usart-full-duplex) | | :heavy_check_mark: | Efficient two wire communication. Two distinct wires are used for reception and transmission. |
?> Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards.
-Drivers in this category have the following characteristics:
-* bit bang and USART Half-duplex provide data and signaling over a single conductor
-* USART Full-duplex provide data and signaling over two conductors
-* They are all limited to single master and single slave communication scheme
+<hr>
+
+## Bitbang
+
+This is the Default driver, the absence of configuration assumes this driver. It works by [bit banging](https://en.wikipedia.org/wiki/Bit_banging) a GPIO pin using the CPU. It is therefore not as efficient as a dedicated hardware peripheral, which the Half-duplex and Full-duplex drivers use.
-## Supported Driver Types
+!> On ARM platforms the bitbang driver causes connection issues when using it together with the bitbang WS2812 driver. Choosing alternate drivers for both serial and WS2812 (instead of bitbang) is strongly recommended.
-| | AVR | ARM |
-| ----------------- | ------------------ | ------------------ |
-| bit bang | :heavy_check_mark: | :heavy_check_mark: |
-| USART Half-duplex | | :heavy_check_mark: |
-| USART Full-duplex | | :heavy_check_mark: |
+### Pin configuration
+
+```
+ LEFT RIGHT
++-------+ SERIAL +-------+
+| SSP |-----------------| SSP |
+| | VDD | |
+| |-----------------| |
+| | GND | |
+| |-----------------| |
++-------+ +-------+
+```
-## Driver configuration
+One GPIO pin is needed for the bitbang driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SOFT_SERIAL_PIN` (SSP) in the configuration. A simple TRS or USB cable provides enough conductors for this driver to work.
-### Bitbang
-Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk:
+### Setup
+
+To use the bitbang driver follow these steps to activate it.
+
+1. Change the `SERIAL_DRIVER` to `bitbang` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = bitbang
```
-Configure the driver via your config.h:
+2. Configure the GPIO pin of your keyboard via the `config.h` file:
+
```c
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
-#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
- // 0: about 189kbps (Experimental only)
- // 1: about 137kbps (default)
- // 2: about 75kbps
- // 3: about 39kbps
- // 4: about 26kbps
- // 5: about 20kbps
```
-#### ARM
+3. On ARM platforms you must turn on ChibiOS `PAL_USE_CALLBACKS` feature:
+
+* In `halconf.h` add the line `#define PAL_USE_CALLBACKS TRUE`.
+
+<hr>
+
+## USART Half-duplex
+
+Targeting ARM boards based on ChibiOS, where communication is offloaded to a USART hardware device that supports Half-duplex operation. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible.
+
+### Pin configuration
+
+```
+ LEFT RIGHT
++-------+ | | +-------+
+| | R R | |
+| | | SERIAL | | |
+| TX |-----------------| TX |
+| | VDD | |
+| |-----------------| |
+| | GND | |
+| |-----------------| |
++-------+ +-------+
+```
+
+Only one GPIO pin is needed for the Half-duplex driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SERIAL_USART_TX_PIN` in the configuration. Take care that the pin you chose can act as the TX pin of the USART peripheral. A simple TRS or USB cable provides enough conductors for this driver to work. As the split connection is configured to work in open-drain mode, an **external pull-up resistor is needed to keep the line high**. Resistor values of 1.5kΩ to 8.2kΩ are known to work.
-!> The bitbang driver causes connection issues with bitbang WS2812 driver
+### Setup
-Along with the generic options above, you must also turn on the `PAL_USE_CALLBACKS` feature in your halconf.h.
+To use the Half-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1.
-### USART Half-duplex
-Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. `SERIAL_PIN_TX` for this driver is the configured USART TX pin. As this Pin is configured in open-drain mode an **external pull-up resistor is needed to keep the line high** (resistor values of 1.5k to 8.2k are known to work). To configure it, add this to your rules.mk:
+1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = usart
```
-Configure the hardware via your config.h:
+2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
+
+```make
+SERIAL_DRIVER = vendor
+```
+
+3. Configure the hardware of your keyboard via the `config.h` file:
+
+```c
+#define SERIAL_USART_TX_PIN B6 // The GPIO pin that is used split communication.
+```
+
+For STM32 MCUs several GPIO configuration options can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus).
+
```c
-#define SOFT_SERIAL_PIN B6 // USART TX pin
-//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
-#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
- // 0: about 460800 baud
- // 1: about 230400 baud (default)
- // 2: about 115200 baud
- // 3: about 57600 baud
- // 4: about 38400 baud
- // 5: about 19200 baud
-#define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1
+#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
-#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
```
-You must also enable the ChibiOS `SERIAL` feature:
-* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE`
-* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU)
+1. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
-Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
+<hr>
-### USART Full-duplex
-Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. USART Full-Duplex requires two conductors **without** pull-up resistors instead of one conductor with a pull-up resistor unlike the Half-duplex driver. Due to its internal design it is more efficent, which can result in even faster transmission speeds.
+## USART Full-duplex
-#### Pin configuration
+Targeting ARM boards based on ChibiOS where communication is offloaded to an USART hardware device. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible. Due to its internal design it is slightly more efficient then the Half-duplex driver, but it should be primarily chosen if Half-duplex operation is not supported by the USART peripheral.
-`SERIAL_USART_TX_PIN` is the USART `TX` pin, `SERIAL_USART_RX_PIN` is the USART `RX` pin. No external pull-up resistors are needed as the `TX` pin operates in push-pull mode. To use this driver the usart peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refeer to the corresponding datasheets of your MCU or find those settings in the table below.
+### Pin configuration
+
+```
+ LEFT RIGHT
++-------+ +-------+
+| | SERIAL | |
+| TX |-----------------| RX |
+| | SERIAL | |
+| RX |-----------------| TX |
+| | VDD | |
+| |-----------------| |
+| | GND | |
+| |-----------------| |
++-------+ +-------+
+```
-#### Connecting the halves and Pin Swap
-Please note that `TX` of the master half has to be connected with the `RX` pin of the slave half and `RX` of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the pcb. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU, this feature can be enabled using `#define SERIAL_USART_PIN_SWAP` in your config.h.
+Two GPIO pins are needed for the Full-duplex driver, as two distinct wires are used for receiving and transmitting data. The pin transmitting data is the `TX` pin and refereed to as the `SERIAL_USART_TX_PIN`, the pin receiving data is the `RX` pin and refereed to as the `SERIAL_USART_RX_PIN` in this configuration. Please note that `TX` pin of the master half has to be connected with the `RX` pin of the slave half and the `RX` pin of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the PCB. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU. A simple TRRS or USB cable provides enough conductors for this driver to work.
-#### Setup
-To use the driver, add this to your rules.mk:
+To use this driver the usart peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refer to the corresponding datasheets of your MCU or find those settings in the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus).
+
+### Setup
+
+To use the Full-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1.
+
+1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = usart
```
-Next configure the hardware via your config.h:
+2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
+
+```make
+SERIAL_DRIVER = vendor
+```
+
+3. Configure the hardware of your keyboard via the `config.h` file:
```c
#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode.
#define SERIAL_USART_TX_PIN B6 // USART TX pin
#define SERIAL_USART_RX_PIN B7 // USART RX pin
-//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
-//#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve.
- // Check if this feature is necessary with your keyboard design and available on the mcu.
-#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
- // 0: 460800 baud
- // 1: 230400 baud (default)
- // 2: 115200 baud
- // 3: 57600 baud
- // 4: 38400 baud
- // 5: 19200 baud
-#define SERIAL_USART_DRIVER SD1 // USART driver of TX and RX pin. default: SD1
+```
+
+For STM32 MCUs several GPIO configuration options, including the ability for `TX` to `RX` pin swapping, can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus).
+
+```c
+#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve. (Only available on some MCUs)
+#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
-#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
+```
+
+1. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
+
+<hr>
+
+## Choosing a driver subsystem
+
+### The `SERIAL` driver
+
+The `SERIAL` Subsystem is supported for the majority of ChibiOS MCUs and should be used whenever supported. Follow these steps in order to activate it:
+
+1. In your keyboards `halconf.h` add:
+
+```c
+#define HAL_USE_SERIAL TRUE
+```
+
+2. In your keyboards `mcuconf.h`: activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
+
+Just below `#include_next <mcuconf.h>` add:
+
+```c
+#include_next <mcuconf.h>
+
+#undef STM32_SERIAL_USE_USARTn
+#define STM32_SERIAL_USE_USARTn TRUE
+```
+
+Where 'n' matches the peripheral number of your selected USART on the MCU.
+
+3. In you keyboards `config.h`: override the default USART `SERIAL` driver if you use a USART peripheral that does not belong to the default selected `SD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SD3`.
+
+```c
+ #define SERIAL_USART_DRIVER SD3
+ ```
+
+### The `SIO` driver
+
+The `SIO` Subsystem was added to ChibiOS with the 21.11 release and is only supported on selected MCUs. It should only be chosen when the `SERIAL` subsystem is not supported by your MCU.
+
+Follow these steps in order to activate it:
+
+1. In your keyboards `halconf.h` add:
+
+```c
+#define HAL_USE_SIO TRUE
+```
+
+2. In your keyboards `mcuconf.h:` activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
+
+Just below `#include_next <mcuconf.h>` add:
+
+```c
+#include_next <mcuconf.h>
+
+#undef STM32_SIO_USE_USARTn
+#define STM32_SIO_USE_USARTn TRUE
+```
+
+Where 'n' matches the peripheral number of your selected USART on the MCU.
+
+3. In you keyboards `config.h`: override the default USART `SIO` driver if you use a USART peripheral that does not belong to the default selected `SIOD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SIOD3`.
+
+```c
+ #define SERIAL_USART_DRIVER SIOD3
+ ```
+
+### The `PIO` driver
+
+The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU. Because of the flexible nature of the PIO peripherals, **any** GPIO pin can be used as a `TX` or `RX` pin. Half-duplex and Full-duplex operation is fully supported. The Half-duplex operation mode uses the built-in pull-ups and GPIO manipulation on the RP2040 to drive the line high by default. An external pull-up is therefore not necessary.
+
+Configure the hardware via your config.h:
+```c
+#define SERIAL_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the Serial implementation uses the PIO0 peripheral
+```
+
+The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on.
+
+<hr>
+
+## Advanced Configuration
+
+There are several advanced configuration options that can be defined in your keyboards `config.h` file:
+
+### Baudrate
+
+If you're having issues or need a higher baudrate with serial communication, you can change the baudrate which in turn controls the communication speed for serial. You want to lower the baudrate if you experience failed transactions.
+
+```c
+#define SELECT_SOFT_SERIAL_SPEED {#}
+```
+
+| Speed | Bitbang | Half-duplex and Full-duplex |
+| ----- | -------------------------- | --------------------------- |
+| `0` | 189000 baud (experimental) | 460800 baud |
+| `1` | 137000 baud (default) | 230400 baud (default) |
+| `2` | 75000 baud | 115200 baud |
+| `3` | 39000 baud | 57600 baud |
+| `4` | 26000 baud | 38400 baud |
+| `5` | 20000 baud | 19200 baud |
+
+Alternatively you can specify the baudrate directly by defining `SERIAL_USART_SPEED`.
+
+### Timeout
+
+This is the default time window in milliseconds in which a successful communication has to complete. Usually you don't want to change this value. But you can do so anyways by defining an alternate one in your keyboards `config.h` file:
+
+```c
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
```
-You must also enable the ChibiOS `SERIAL` feature:
-* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE`
-* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU)
+<hr>
+
+## Troubleshooting
+
+If you're having issues withe serial communication, you can enable debug messages that will give you insights which part of the communication failed. The enable these messages add to your keyboards `config.h` file:
+
+```c
+#define SERIAL_DEBUG
+```
+
+?> The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md).
-Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
+## Alternate Functions for selected STM32 MCUs
-#### Pins for USART Peripherals with Alternate Functions for selected STM32 MCUs
+Pins for USART Peripherals with
-##### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf)
+### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf)
Pin Swap available: :heavy_check_mark:
-| Pin | Function | Mode |
+| Pin | Function | Mode |
| ---------- | -------- | ---- |
| **USART1** | | |
| PA9 | TX | AF7 |
@@ -151,11 +323,11 @@ Pin Swap available: :heavy_check_mark:
| PD8 | TX | AF7 |
| PD9 | RX | AF7 |
-##### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf)
+### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf)
Pin Swap available: :heavy_check_mark:
-| Pin | Function | Mode |
+| Pin | Function | Mode |
| ------ | -------- | ---- |
| USART1 | | |
| PA9 | TX | AF1 |
@@ -180,7 +352,7 @@ Pin Swap available: :heavy_check_mark:
| PA0 | TX | AF4 |
| PA1 | RX | AF4 |
-##### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)
+### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)
Pin Swap available: N/A
@@ -190,7 +362,7 @@ Pin remapping:
The pins of USART Peripherals use default Pins that can be remapped to use other pins using the AFIO registers. Default pins are marked **bold**. Add the appropriate defines to your config.h file.
-| Pin | Function | Mode | USART_REMAP |
+| Pin | Function | Mode | USART_REMAP |
| ---------- | -------- | ---- | ------------------- |
| **USART1** | | | |
| **PA9** | TX | AFPP | |
diff --git a/docs/understanding_qmk.md b/docs/understanding_qmk.md
index 9b80fb179e..c1bcfe3ce9 100644
--- a/docs/understanding_qmk.md
+++ b/docs/understanding_qmk.md
@@ -155,7 +155,6 @@ The `process_record()` function itself is deceptively simple, but hidden within
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
* `bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record)`
- * [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
* [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing.
diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md
index 8acac0b3aa..54e6e77d81 100644
--- a/docs/ws2812_driver.md
+++ b/docs/ws2812_driver.md
@@ -11,11 +11,12 @@ These LEDs are called "addressable" because instead of using a wire per color, e
## Supported Driver Types
| | AVR | ARM |
-|----------|--------------------|--------------------|
+| -------- | ------------------ | ------------------ |
| bit bang | :heavy_check_mark: | :heavy_check_mark: |
| I2C | :heavy_check_mark: | |
| SPI | | :heavy_check_mark: |
| PWM | | :heavy_check_mark: |
+| PIO | | :heavy_check_mark: |
## Driver configuration
@@ -33,11 +34,11 @@ The default setting is 280 µs, which should work for most cases, but this can b
Some variants of the WS2812 may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB.
In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values:
-|Byte order |Known devices |
-|---------------------------------|-----------------------------|
-|`WS2812_BYTE_ORDER_GRB` (default)|Most WS2812's, SK6812, SK6805|
-|`WS2812_BYTE_ORDER_RGB` |WS2812B-2020 |
-|`WS2812_BYTE_ORDER_BGR` |TM1812 |
+| Byte order | Known devices |
+| --------------------------------- | ----------------------------- |
+| `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 |
+| `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 |
+| `WS2812_BYTE_ORDER_BGR` | TM1812 |
### Bitbang
@@ -54,13 +55,13 @@ WS2812_DRIVER = bitbang
The WS2812 LED communication topology depends on a serialized timed window. Different versions of the addressable LEDs have differing requirements for the timing parameters, for instance, of the SK6812.
You can tune these parameters through the definition of the following macros:
-| Macro |Default | AVR | ARM |
-|---------------------|--------------------------------------------|--------------------|--------------------|
-|`WS2812_TIMING` |`1250` | :heavy_check_mark: | :heavy_check_mark: |
-|`WS2812_T0H` |`350` | :heavy_check_mark: | :heavy_check_mark: |
-|`WS2812_T0L` |`WS2812_TIMING - WS2812_T0H` | | :heavy_check_mark: |
-|`WS2812_T1H` |`900` | :heavy_check_mark: | :heavy_check_mark: |
-|`WS2812_T1L` |`WS2812_TIMING - WS2812_T1H` | | :heavy_check_mark: |
+| Macro | Default | AVR | ARM |
+| --------------- | ---------------------------- | ------------------ | ------------------ |
+| `WS2812_TIMING` | `1250` | :heavy_check_mark: | :heavy_check_mark: |
+| `WS2812_T0H` | `350` | :heavy_check_mark: | :heavy_check_mark: |
+| `WS2812_T0L` | `WS2812_TIMING - WS2812_T0H` | | :heavy_check_mark: |
+| `WS2812_T1H` | `900` | :heavy_check_mark: | :heavy_check_mark: |
+| `WS2812_T1L` | `WS2812_TIMING - WS2812_T1H` | | :heavy_check_mark: |
### I2C
Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk:
@@ -107,16 +108,16 @@ To adjust the baudrate at which the SPI peripheral is configured, users will nee
Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported by hardware.
-|Define |Default|Description |
-|--------------------|-------|-------------------------------------|
-|`WS2812_SPI_DIVISOR`|`16` |SPI source clock peripheral divisor |
+| Define | Default | Description |
+| -------------------- | ------- | ----------------------------------- |
+| `WS2812_SPI_DIVISOR` | `16` | SPI source clock peripheral divisor |
#### Testing Notes
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | SPI1 | SPI2 | SPI3 |
-|------|---------------------------------------------|-----------------------------------------|-----------------------|
+| ---- | ------------------------------------------- | --------------------------------------- | --------------------- |
| f072 | ? | B15 :heavy_check_mark: (needs SCK: B13) | N/A |
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
@@ -150,15 +151,32 @@ You must also turn on the PWM feature in your halconf.h and mcuconf.h
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
-| | Status |
-|-|-|
-| f072 | ? |
-| f103 | :heavy_check_mark: |
-| f303 | :heavy_check_mark: |
+| | Status |
+| --------- | ------------------ |
+| f072 | ? |
+| f103 | :heavy_check_mark: |
+| f303 | :heavy_check_mark: |
| f401/f411 | :heavy_check_mark: |
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*
+### PIO
+
+Targeting Raspberry Pi RP2040 boards only where WS2812 support is offloaded to an dedicated PIO implementation. This offloads processing of the WS2812 protocol from the MCU to a dedicated PIO program using DMA transfers.
+
+To configure it, add this to your rules.mk:
+
+```make
+WS2812_DRIVER = vendor
+```
+
+Configure the hardware via your config.h:
+```c
+#define WS2812_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the WS2812 implementation uses the PIO0 peripheral
+```
+
+The WS2812 PIO programm uses 1 state machine, 4 instructions and does not use any interrupt handlers.
+
### Push Pull and Open Drain Configuration
The default configuration is a push pull on the defined pin.
This can be configured for bitbang, PWM and SPI.
diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md
index dbad1021fa..3baee6dc2e 100644
--- a/docs/zh-cn/_summary.md
+++ b/docs/zh-cn/_summary.md
@@ -91,7 +91,6 @@
* [æ¢æ‰‹](zh-cn/feature_swap_hands.md)
* [一键多用](zh-cn/feature_tap_dance.md)
* [点按é…ç½®](zh-cn/tap_hold.md)
- * [终端](zh-cn/feature_terminal.md)
* [Unicode](zh-cn/feature_unicode.md)
* [用户空间](zh-cn/feature_userspace.md)
* [WPM计算](zh-cn/feature_wpm.md)
diff --git a/docs/zh-cn/custom_quantum_functions.md b/docs/zh-cn/custom_quantum_functions.md
index 29c5089052..dba9e7e7c0 100644
--- a/docs/zh-cn/custom_quantum_functions.md
+++ b/docs/zh-cn/custom_quantum_functions.md
@@ -240,7 +240,7 @@ void suspend_wakeup_init_user(void) {
```c
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
rgblight_setrgb (0x00, 0x00, 0xFF);
break;
@@ -267,7 +267,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
### `layer_state_set_*` 函数文档
-* 键盘/å„å­ç‰ˆæœ¬ï¼š`uint32_t layer_state_set_kb(uint32_t state)`
+* 键盘/å„å­ç‰ˆæœ¬ï¼š`layer_state_t layer_state_set_kb(layer_state_t state)`
* 布局: `layer_state_t layer_state_set_user(layer_state_t state)`
@@ -325,7 +325,7 @@ void keyboard_post_init_user(void) {
```c
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
break;
@@ -474,4 +474,3 @@ cancel_deferred_exec(my_token);
```c
#define MAX_DEFERRED_EXECUTORS 16
```
-
diff --git a/drivers/eeprom/eeprom_i2c.h b/drivers/eeprom/eeprom_i2c.h
index 77eea66d63..85317c9ea5 100644
--- a/drivers/eeprom/eeprom_i2c.h
+++ b/drivers/eeprom/eeprom_i2c.h
@@ -54,6 +54,11 @@
# define EXTERNAL_EEPROM_PAGE_SIZE 32
# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
# define EXTERNAL_EEPROM_WRITE_TIME 5
+#elif defined(EEPROM_I2C_24LC32A)
+# define EXTERNAL_EEPROM_BYTE_COUNT 4096
+# define EXTERNAL_EEPROM_PAGE_SIZE 32
+# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
+# define EXTERNAL_EEPROM_WRITE_TIME 5
#elif defined(EEPROM_I2C_MB85RC256V)
# define EXTERNAL_EEPROM_BYTE_COUNT 32768
# define EXTERNAL_EEPROM_PAGE_SIZE 128
diff --git a/drivers/eeprom/eeprom_spi.c b/drivers/eeprom/eeprom_spi.c
index 25955498c4..51ba25dece 100644
--- a/drivers/eeprom/eeprom_spi.c
+++ b/drivers/eeprom/eeprom_spi.c
@@ -58,14 +58,20 @@ static bool spi_eeprom_start(void) {
static spi_status_t spi_eeprom_wait_while_busy(int timeout) {
uint32_t deadline = timer_read32() + timeout;
- spi_status_t response;
- do {
+ spi_status_t response = SR_WIP;
+ while (response & SR_WIP) {
+ if (!spi_eeprom_start()) {
+ return SPI_STATUS_ERROR;
+ }
+
spi_write(CMD_RDSR);
response = spi_read();
+ spi_stop();
+
if (timer_read32() >= deadline) {
return SPI_STATUS_TIMEOUT;
}
- } while (response & SR_WIP);
+ }
return SPI_STATUS_SUCCESS;
}
@@ -105,27 +111,21 @@ void eeprom_driver_erase(void) {
void eeprom_read_block(void *buf, const void *addr, size_t len) {
//-------------------------------------------------
// Wait for the write-in-progress bit to be cleared
- bool res = spi_eeprom_start();
- if (!res) {
- dprint("failed to start SPI for WIP check\n");
- memset(buf, 0, len);
- return;
- }
-
spi_status_t response = spi_eeprom_wait_while_busy(EXTERNAL_EEPROM_SPI_TIMEOUT);
- spi_stop();
- if (response == SPI_STATUS_TIMEOUT) {
- dprint("SPI timeout for WIP check\n");
+ if (response != SPI_STATUS_SUCCESS) {
+ spi_stop();
memset(buf, 0, len);
+ dprint("SPI timeout for WIP check\n");
return;
}
//-------------------------------------------------
// Perform read
- res = spi_eeprom_start();
+ bool res = spi_eeprom_start();
if (!res) {
- dprint("failed to start SPI for read\n");
+ spi_stop();
memset(buf, 0, len);
+ dprint("failed to start SPI for read\n");
return;
}
@@ -158,15 +158,9 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
//-------------------------------------------------
// Wait for the write-in-progress bit to be cleared
- res = spi_eeprom_start();
- if (!res) {
- dprint("failed to start SPI for WIP check\n");
- return;
- }
-
spi_status_t response = spi_eeprom_wait_while_busy(EXTERNAL_EEPROM_SPI_TIMEOUT);
- spi_stop();
- if (response == SPI_STATUS_TIMEOUT) {
+ if (response != SPI_STATUS_SUCCESS) {
+ spi_stop();
dprint("SPI timeout for WIP check\n");
return;
}
@@ -175,6 +169,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
// Enable writes
res = spi_eeprom_start();
if (!res) {
+ spi_stop();
dprint("failed to start SPI for write-enable\n");
return;
}
@@ -186,6 +181,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
// Perform the write
res = spi_eeprom_start();
if (!res) {
+ spi_stop();
dprint("failed to start SPI for write\n");
return;
}
diff --git a/drivers/eeprom/eeprom_wear_leveling.c b/drivers/eeprom/eeprom_wear_leveling.c
new file mode 100644
index 0000000000..bd77eef35c
--- /dev/null
+++ b/drivers/eeprom/eeprom_wear_leveling.c
@@ -0,0 +1,23 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <stdint.h>
+#include <string.h>
+
+#include "eeprom_driver.h"
+#include "wear_leveling.h"
+
+void eeprom_driver_init(void) {
+ wear_leveling_init();
+}
+
+void eeprom_driver_erase(void) {
+ wear_leveling_erase();
+}
+
+void eeprom_read_block(void *buf, const void *addr, size_t len) {
+ wear_leveling_read((uint32_t)addr, buf, len);
+}
+
+void eeprom_write_block(const void *buf, void *addr, size_t len) {
+ wear_leveling_write((uint32_t)addr, buf, len);
+}
diff --git a/drivers/gpio/pca9505.c b/drivers/gpio/pca9505.c
new file mode 100644
index 0000000000..5803746c96
--- /dev/null
+++ b/drivers/gpio/pca9505.c
@@ -0,0 +1,166 @@
+// Copyright 2022 nirim000
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "i2c_master.h"
+#include "pca9505.h"
+
+#include "debug.h"
+
+#define SLAVE_TO_ADDR(n) (n << 1)
+#define TIMEOUT 100
+
+enum {
+ CMD_INPUT_0 = 0,
+ CMD_INPUT_1,
+ CMD_INPUT_2,
+ CMD_INPUT_3,
+ CMD_INPUT_4,
+ CMD_OUTPUT_0 = 8,
+ CMD_OUTPUT_1,
+ CMD_OUTPUT_2,
+ CMD_OUTPUT_3,
+ CMD_OUTPUT_4,
+ CMD_INVERSION_0 = 16,
+ CMD_INVERSION_1,
+ CMD_INVERSION_2,
+ CMD_INVERSION_3,
+ CMD_INVERSION_4,
+ CMD_CONFIG_0 = 24,
+ CMD_CONFIG_1,
+ CMD_CONFIG_2,
+ CMD_CONFIG_3,
+ CMD_CONFIG_4,
+};
+
+void pca9505_init(uint8_t slave_addr) {
+ static uint8_t s_init = 0;
+ if (!s_init) {
+ i2c_init();
+
+ s_init = 1;
+ }
+
+ // TODO: could check device connected
+ // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE);
+ // i2c_stop();
+}
+
+bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
+ uint8_t addr = SLAVE_TO_ADDR(slave_addr);
+ uint8_t cmd = 0;
+ switch (port) {
+ case 0:
+ cmd = CMD_CONFIG_0;
+ break;
+ case 1:
+ cmd = CMD_CONFIG_1;
+ break;
+ case 2:
+ cmd = CMD_CONFIG_2;
+ break;
+ case 3:
+ cmd = CMD_CONFIG_3;
+ break;
+ case 4:
+ cmd = CMD_CONFIG_4;
+ break;
+ }
+
+ i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
+ if (ret != I2C_STATUS_SUCCESS) {
+ print("pca9505_set_config::FAILED\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool pca9505_set_polarity(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
+ uint8_t addr = SLAVE_TO_ADDR(slave_addr);
+ uint8_t cmd = 0;
+ switch (port) {
+ case 0:
+ cmd = CMD_INVERSION_0;
+ break;
+ case 1:
+ cmd = CMD_INVERSION_1;
+ break;
+ case 2:
+ cmd = CMD_INVERSION_2;
+ break;
+ case 3:
+ cmd = CMD_INVERSION_3;
+ break;
+ case 4:
+ cmd = CMD_INVERSION_4;
+ break;
+ }
+
+ i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
+ if (ret != I2C_STATUS_SUCCESS) {
+ print("pca9505_set_polarity::FAILED\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool pca9505_set_output(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
+ uint8_t addr = SLAVE_TO_ADDR(slave_addr);
+ uint8_t cmd = 0;
+ switch (port) {
+ case 0:
+ cmd = CMD_OUTPUT_0;
+ break;
+ case 1:
+ cmd = CMD_OUTPUT_1;
+ break;
+ case 2:
+ cmd = CMD_OUTPUT_2;
+ break;
+ case 3:
+ cmd = CMD_OUTPUT_3;
+ break;
+ case 4:
+ cmd = CMD_OUTPUT_4;
+ break;
+ }
+
+ i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
+ if (ret != I2C_STATUS_SUCCESS) {
+ print("pca9505_set_output::FAILED\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool pca9505_readPins(uint8_t slave_addr, pca9505_port_t port, uint8_t* out) {
+ uint8_t addr = SLAVE_TO_ADDR(slave_addr);
+ uint8_t cmd = 0;
+ switch (port) {
+ case 0:
+ cmd = CMD_INPUT_0;
+ break;
+ case 1:
+ cmd = CMD_INPUT_1;
+ break;
+ case 2:
+ cmd = CMD_INPUT_2;
+ break;
+ case 3:
+ cmd = CMD_INPUT_3;
+ break;
+ case 4:
+ cmd = CMD_INPUT_4;
+ break;
+ }
+
+ i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
+ if (ret != I2C_STATUS_SUCCESS) {
+ print("pca9505_readPins::FAILED\n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/drivers/gpio/pca9505.h b/drivers/gpio/pca9505.h
new file mode 100644
index 0000000000..732ddb88ea
--- /dev/null
+++ b/drivers/gpio/pca9505.h
@@ -0,0 +1,67 @@
+// Copyright 2022 nirim000
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * Port ID
+ */
+typedef enum {
+ PCA9505_PORT0,
+ PCA9505_PORT1,
+ PCA9505_PORT2,
+ PCA9505_PORT3,
+ PCA9505_PORT4,
+} pca9505_port_t;
+
+/**
+ * Helpers for set_config
+ */
+enum {
+ ALL_NORMAL = 0,
+ ALL_INVERTED = 0xFF,
+};
+
+/**
+ * Helpers for set_config
+ */
+enum {
+ ALL_OUTPUT = 0,
+ ALL_INPUT = 0xFF,
+};
+
+/**
+ * Helpers for set_output
+ */
+enum {
+ ALL_LOW = 0,
+ ALL_HIGH = 0xFF,
+};
+
+/**
+ * Init expander and any other dependent drivers
+ */
+void pca9505_init(uint8_t slave_addr);
+
+/**
+ * Configure input/output to a given port
+ */
+bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf);
+
+/**
+ * Configure polarity to a given port
+ */
+bool pca9505_set_polarity(uint8_t slave_addr, pca9505_port_t port, uint8_t conf);
+
+/**
+ * Write high/low to a given port
+ */
+bool pca9505_set_output(uint8_t slave_addr, pca9505_port_t port, uint8_t conf);
+
+/**
+ * Read state of a given port
+ */
+bool pca9505_readPins(uint8_t slave_addr, pca9505_port_t port, uint8_t* ret);
diff --git a/drivers/led/aw20216.c b/drivers/led/aw20216.c
index 448accdcd3..55083936ef 100644
--- a/drivers/led/aw20216.c
+++ b/drivers/led/aw20216.c
@@ -53,6 +53,10 @@
# define AW_GLOBAL_CURRENT_MAX 150
#endif
+#ifndef AW_SPI_MODE
+# define AW_SPI_MODE 0
+#endif
+
#ifndef AW_SPI_DIVISOR
# define AW_SPI_DIVISOR 4
#endif
@@ -63,7 +67,7 @@ bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
bool AW20216_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) {
static uint8_t s_spi_transfer_buffer[2] = {0};
- if (!spi_start(cs_pin, false, 3, AW_SPI_DIVISOR)) {
+ if (!spi_start(cs_pin, false, AW_SPI_MODE, AW_SPI_DIVISOR)) {
spi_stop();
return false;
}
diff --git a/drivers/led/issi/is31fl3733-simple.c b/drivers/led/issi/is31fl3733-simple.c
index af006f756d..2f41a7b1a9 100644
--- a/drivers/led/issi/is31fl3733-simple.c
+++ b/drivers/led/issi/is31fl3733-simple.c
@@ -70,6 +70,10 @@
# define ISSI_CSPULLUP PUR_0R
#endif
+#ifndef ISSI_GLOBALCURRENT
+# define ISSI_GLOBALCURRENT 0xFF
+#endif
+
// Transfer buffer for TWITransmitData()
uint8_t g_twi_transfer_buffer[20];
@@ -182,7 +186,7 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) {
// Set de-ghost pull-down resistors (CSx)
IS31FL3733_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
// Set global current to maximum.
- IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
+ IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
// Disable software shutdown.
IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((ISSI_PWM_FREQUENCY & 0b111) << 3) | 0x01);
diff --git a/drivers/led/issi/is31fl3733.c b/drivers/led/issi/is31fl3733.c
index a2fdaa90fa..add998f256 100644
--- a/drivers/led/issi/is31fl3733.c
+++ b/drivers/led/issi/is31fl3733.c
@@ -69,6 +69,10 @@
# define ISSI_CSPULLUP PUR_0R
#endif
+#ifndef ISSI_GLOBALCURRENT
+# define ISSI_GLOBALCURRENT 0xFF
+#endif
+
// Transfer buffer for TWITransmitData()
uint8_t g_twi_transfer_buffer[20];
@@ -172,7 +176,7 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) {
// Set de-ghost pull-down resistors (CSx)
IS31FL3733_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
// Set global current to maximum.
- IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
+ IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
// Disable software shutdown.
IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((ISSI_PWM_FREQUENCY & 0b111) << 3) | 0x01);
diff --git a/drivers/led/issi/is31fl3736.c b/drivers/led/issi/is31fl3736.c
index 7752a3f6cb..e9943614d2 100644
--- a/drivers/led/issi/is31fl3736.c
+++ b/drivers/led/issi/is31fl3736.c
@@ -63,6 +63,10 @@
# define ISSI_CSPULLUP PUR_0R
#endif
+#ifndef ISSI_GLOBALCURRENT
+# define ISSI_GLOBALCURRENT 0xFF
+#endif
+
// Transfer buffer for TWITransmitData()
uint8_t g_twi_transfer_buffer[20];
@@ -154,7 +158,7 @@ void IS31FL3736_init(uint8_t addr) {
// Set de-ghost pull-down resistors (CSx)
IS31FL3736_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
// Set global current to maximum.
- IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
+ IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
// Disable software shutdown.
IS31FL3736_write_register(addr, ISSI_REG_CONFIGURATION, 0x01);
diff --git a/drivers/led/issi/is31fl3737.c b/drivers/led/issi/is31fl3737.c
index bce0c34b2c..932530ac0a 100644
--- a/drivers/led/issi/is31fl3737.c
+++ b/drivers/led/issi/is31fl3737.c
@@ -69,6 +69,10 @@
# define ISSI_CSPULLUP PUR_0R
#endif
+#ifndef ISSI_GLOBALCURRENT
+# define ISSI_GLOBALCURRENT 0xFF
+#endif
+
// Transfer buffer for TWITransmitData()
uint8_t g_twi_transfer_buffer[20];
@@ -161,7 +165,7 @@ void IS31FL3737_init(uint8_t addr) {
// Set de-ghost pull-down resistors (CSx)
IS31FL3737_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
// Set global current to maximum.
- IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
+ IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
// Disable software shutdown.
IS31FL3737_write_register(addr, ISSI_REG_CONFIGURATION, ((ISSI_PWM_FREQUENCY & 0b111) << 3) | 0x01);
diff --git a/drivers/led/issi/is31fl3741.c b/drivers/led/issi/is31fl3741.c
index 393b0179b5..ba6b6761a3 100644
--- a/drivers/led/issi/is31fl3741.c
+++ b/drivers/led/issi/is31fl3741.c
@@ -69,6 +69,10 @@
# define ISSI_CSPULLUP PUR_32KR
#endif
+#ifndef ISSI_GLOBALCURRENT
+# define ISSI_GLOBALCURRENT 0xFF
+#endif
+
#define ISSI_MAX_LEDS 351
// Transfer buffer for TWITransmitData()
@@ -163,7 +167,7 @@ void IS31FL3741_init(uint8_t addr) {
IS31FL3741_write_register(addr, ISSI_REG_CONFIGURATION, 0x01);
// Set Golbal Current Control Register
- IS31FL3741_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
+ IS31FL3741_write_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
// Set Pull up & Down for SWx CSy
IS31FL3741_write_register(addr, ISSI_REG_PULLDOWNUP, ((ISSI_CSPULLUP << 4) | ISSI_SWPULLUP));
diff --git a/drivers/painter/gc9a01/qp_gc9a01.c b/drivers/painter/gc9a01/qp_gc9a01.c
index ad76d58b07..37700a28a4 100644
--- a/drivers/painter/gc9a01/qp_gc9a01.c
+++ b/drivers/painter/gc9a01/qp_gc9a01.c
@@ -102,12 +102,11 @@ const struct tft_panel_dc_reset_painter_driver_vtable_t gc9a01_driver_vtable = {
.flush = qp_tft_panel_flush,
.pixdata = qp_tft_panel_pixdata,
.viewport = qp_tft_panel_viewport,
- .palette_convert = qp_tft_panel_palette_convert,
- .append_pixels = qp_tft_panel_append_pixels,
+ .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped,
+ .append_pixels = qp_tft_panel_append_pixels_rgb565,
},
- .rgb888_to_native16bit = qp_rgb888_to_rgb565_swapped,
- .num_window_bytes = 2,
- .swap_window_coords = false,
+ .num_window_bytes = 2,
+ .swap_window_coords = false,
.opcodes =
{
.display_on = GC9A01_CMD_DISPLAY_ON,
diff --git a/drivers/painter/ili9xxx/qp_ili9163.c b/drivers/painter/ili9xxx/qp_ili9163.c
index beaac0fbb5..14363c7d04 100644
--- a/drivers/painter/ili9xxx/qp_ili9163.c
+++ b/drivers/painter/ili9xxx/qp_ili9163.c
@@ -67,12 +67,11 @@ const struct tft_panel_dc_reset_painter_driver_vtable_t ili9163_driver_vtable =
.flush = qp_tft_panel_flush,
.pixdata = qp_tft_panel_pixdata,
.viewport = qp_tft_panel_viewport,
- .palette_convert = qp_tft_panel_palette_convert,
- .append_pixels = qp_tft_panel_append_pixels,
+ .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped,
+ .append_pixels = qp_tft_panel_append_pixels_rgb565,
},
- .rgb888_to_native16bit = qp_rgb888_to_rgb565_swapped,
- .num_window_bytes = 2,
- .swap_window_coords = false,
+ .num_window_bytes = 2,
+ .swap_window_coords = false,
.opcodes =
{
.display_on = ILI9XXX_CMD_DISPLAY_ON,
diff --git a/drivers/painter/ili9xxx/qp_ili9341.c b/drivers/painter/ili9xxx/qp_ili9341.c
index 1f41dcfc0b..9608f109bd 100644
--- a/drivers/painter/ili9xxx/qp_ili9341.c
+++ b/drivers/painter/ili9xxx/qp_ili9341.c
@@ -74,12 +74,11 @@ const struct tft_panel_dc_reset_painter_driver_vtable_t ili9341_driver_vtable =
.flush = qp_tft_panel_flush,
.pixdata = qp_tft_panel_pixdata,
.viewport = qp_tft_panel_viewport,
- .palette_convert = qp_tft_panel_palette_convert,
- .append_pixels = qp_tft_panel_append_pixels,
+ .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped,
+ .append_pixels = qp_tft_panel_append_pixels_rgb565,
},
- .rgb888_to_native16bit = qp_rgb888_to_rgb565_swapped,
- .num_window_bytes = 2,
- .swap_window_coords = false,
+ .num_window_bytes = 2,
+ .swap_window_coords = false,
.opcodes =
{
.display_on = ILI9XXX_CMD_DISPLAY_ON,
diff --git a/drivers/painter/ili9xxx/qp_ili9488.c b/drivers/painter/ili9xxx/qp_ili9488.c
new file mode 100644
index 0000000000..55cf9f896f
--- /dev/null
+++ b/drivers/painter/ili9xxx/qp_ili9488.c
@@ -0,0 +1,120 @@
+// Copyright 2021 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "qp_internal.h"
+#include "qp_comms.h"
+#include "qp_ili9488.h"
+#include "qp_ili9xxx_opcodes.h"
+#include "qp_tft_panel.h"
+
+#ifdef QUANTUM_PAINTER_ILI9488_SPI_ENABLE
+# include <qp_comms_spi.h>
+#endif // QUANTUM_PAINTER_ILI9488_SPI_ENABLE
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Common
+
+// Driver storage
+tft_panel_dc_reset_painter_device_t ili9488_drivers[ILI9488_NUM_DEVICES] = {0};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Initialization
+
+bool qp_ili9488_init(painter_device_t device, painter_rotation_t rotation) {
+ // clang-format off
+ const uint8_t ili9488_init_sequence[] = {
+ // Command, Delay, N, Data[N]
+ ILI9XXX_CMD_RESET, 120, 0,
+ ILI9XXX_SET_PGAMMA, 0, 15, 0x00, 0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F,
+ ILI9XXX_SET_NGAMMA, 0, 15, 0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F,
+ ILI9XXX_SET_POWER_CTL_1, 0, 2, 0x17, 0x15,
+ ILI9XXX_SET_POWER_CTL_2, 0, 1, 0x41,
+ ILI9XXX_SET_VCOM_CTL_1, 0, 3, 0x00, 0x12, 0x80,
+ ILI9XXX_SET_PIX_FMT, 0, 1, 0x66,
+ ILI9XXX_SET_RGB_IF_SIG_CTL, 0, 1, 0x80,
+ ILI9XXX_SET_FRAME_CTL_NORMAL, 0, 1, 0xA0,
+ ILI9XXX_SET_INVERSION_CTL, 0, 1, 0x02,
+ ILI9XXX_SET_FUNCTION_CTL, 0, 2, 0x02, 0x02,
+ ILI9XXX_SET_IMAGE_FUNCTION, 0, 1, 0x00,
+ ILI9XXX_SET_PUMP_RATIO_CTL, 0, 4, 0xA9, 0x51, 0x2C, 0x82,
+ ILI9XXX_CMD_SLEEP_OFF, 5, 0,
+ ILI9XXX_CMD_DISPLAY_ON, 20, 0
+ };
+ // clang-format on
+ qp_comms_bulk_command_sequence(device, ili9488_init_sequence, sizeof(ili9488_init_sequence));
+
+ // Configure the rotation (i.e. the ordering and direction of memory writes in GRAM)
+ const uint8_t madctl[] = {
+ [QP_ROTATION_0] = ILI9XXX_MADCTL_BGR | ILI9XXX_MADCTL_MY,
+ [QP_ROTATION_90] = ILI9XXX_MADCTL_BGR | ILI9XXX_MADCTL_MX | ILI9XXX_MADCTL_MV | ILI9XXX_MADCTL_MY,
+ [QP_ROTATION_180] = ILI9XXX_MADCTL_BGR | ILI9XXX_MADCTL_MX,
+ [QP_ROTATION_270] = ILI9XXX_MADCTL_BGR | ILI9XXX_MADCTL_MV,
+ };
+ qp_comms_command_databyte(device, ILI9XXX_SET_MEM_ACS_CTL, madctl[rotation]);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Driver vtable
+
+const struct tft_panel_dc_reset_painter_driver_vtable_t ili9488_driver_vtable = {
+ .base =
+ {
+ .init = qp_ili9488_init,
+ .power = qp_tft_panel_power,
+ .clear = qp_tft_panel_clear,
+ .flush = qp_tft_panel_flush,
+ .pixdata = qp_tft_panel_pixdata,
+ .viewport = qp_tft_panel_viewport,
+ .palette_convert = qp_tft_panel_palette_convert_rgb888,
+ .append_pixels = qp_tft_panel_append_pixels_rgb888,
+ },
+ .num_window_bytes = 2,
+ .swap_window_coords = false,
+ .opcodes =
+ {
+ .display_on = ILI9XXX_CMD_DISPLAY_ON,
+ .display_off = ILI9XXX_CMD_DISPLAY_OFF,
+ .set_column_address = ILI9XXX_SET_COL_ADDR,
+ .set_row_address = ILI9XXX_SET_PAGE_ADDR,
+ .enable_writes = ILI9XXX_SET_MEM,
+ },
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SPI
+
+#ifdef QUANTUM_PAINTER_ILI9488_SPI_ENABLE
+
+// Factory function for creating a handle to the ILI9488 device
+painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode) {
+ for (uint32_t i = 0; i < ILI9488_NUM_DEVICES; ++i) {
+ tft_panel_dc_reset_painter_device_t *driver = &ili9488_drivers[i];
+ if (!driver->base.driver_vtable) {
+ driver->base.driver_vtable = (const struct painter_driver_vtable_t *)&ili9488_driver_vtable;
+ driver->base.comms_vtable = (const struct painter_comms_vtable_t *)&spi_comms_with_dc_vtable;
+ driver->base.native_bits_per_pixel = 24; // RGB888
+ driver->base.panel_width = panel_width;
+ driver->base.panel_height = panel_height;
+ driver->base.rotation = QP_ROTATION_0;
+ driver->base.offset_x = 0;
+ driver->base.offset_y = 0;
+
+ // SPI and other pin configuration
+ driver->base.comms_config = &driver->spi_dc_reset_config;
+ driver->spi_dc_reset_config.spi_config.chip_select_pin = chip_select_pin;
+ driver->spi_dc_reset_config.spi_config.divisor = spi_divisor;
+ driver->spi_dc_reset_config.spi_config.lsb_first = false;
+ driver->spi_dc_reset_config.spi_config.mode = spi_mode;
+ driver->spi_dc_reset_config.dc_pin = dc_pin;
+ driver->spi_dc_reset_config.reset_pin = reset_pin;
+ return (painter_device_t)driver;
+ }
+ }
+ return NULL;
+}
+
+#endif // QUANTUM_PAINTER_ILI9488_SPI_ENABLE
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/drivers/painter/ili9xxx/qp_ili9488.h b/drivers/painter/ili9xxx/qp_ili9488.h
new file mode 100644
index 0000000000..21b8f03322
--- /dev/null
+++ b/drivers/painter/ili9xxx/qp_ili9488.h
@@ -0,0 +1,37 @@
+// Copyright 2021 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "gpio.h"
+#include "qp_internal.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Quantum Painter ILI9488 configurables (add to your keyboard's config.h)
+
+#ifndef ILI9488_NUM_DEVICES
+/**
+ * @def This controls the maximum number of ILI9488 devices that Quantum Painter can communicate with at any one time.
+ * Increasing this number allows for multiple displays to be used.
+ */
+# define ILI9488_NUM_DEVICES 1
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Quantum Painter ILI9488 device factories
+
+#ifdef QUANTUM_PAINTER_ILI9488_SPI_ENABLE
+/**
+ * Factory method for an ILI9488 SPI LCD device.
+ *
+ * @param panel_width[in] the width of the display panel
+ * @param panel_height[in] the height of the display panel
+ * @param chip_select_pin[in] the GPIO pin used for SPI chip select
+ * @param dc_pin[in] the GPIO pin used for D/C control
+ * @param reset_pin[in] the GPIO pin used for RST
+ * @param spi_divisor[in] the SPI divisor to use when communicating with the display
+ * @param spi_mode[in] the SPI mode to use when communicating with the display
+ * @return the device handle used with all drawing routines in Quantum Painter
+ */
+painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
+#endif // QUANTUM_PAINTER_ILI9488_SPI_ENABLE
diff --git a/drivers/painter/ili9xxx/qp_ili9xxx_opcodes.h b/drivers/painter/ili9xxx/qp_ili9xxx_opcodes.h
index 1fa395cb89..47bb703648 100644
--- a/drivers/painter/ili9xxx/qp_ili9xxx_opcodes.h
+++ b/drivers/painter/ili9xxx/qp_ili9xxx_opcodes.h
@@ -85,6 +85,7 @@
#define ILI9XXX_SET_NGAMMA 0xE1 // Set negative gamma
#define ILI9XXX_SET_DGAMMA_CTL_1 0xE2 // Set digital gamma ctl 1
#define ILI9XXX_SET_DGAMMA_CTL_2 0xE3 // Set digital gamma ctl 2
+#define ILI9XXX_SET_IMAGE_FUNCTION 0xE9 // Set image function
#define ILI9XXX_ENABLE_3_GAMMA 0xF2 // Enable 3 gamma
#define ILI9XXX_SET_IF_CTL 0xF6 // Set interface control
#define ILI9XXX_SET_PUMP_RATIO_CTL 0xF7 // Set pump ratio control
diff --git a/drivers/painter/ssd1351/qp_ssd1351.c b/drivers/painter/ssd1351/qp_ssd1351.c
index 970e7e67f3..7ce76bab6d 100644
--- a/drivers/painter/ssd1351/qp_ssd1351.c
+++ b/drivers/painter/ssd1351/qp_ssd1351.c
@@ -71,12 +71,11 @@ const struct tft_panel_dc_reset_painter_driver_vtable_t ssd1351_driver_vtable =
.flush = qp_tft_panel_flush,
.pixdata = qp_tft_panel_pixdata,
.viewport = qp_tft_panel_viewport,
- .palette_convert = qp_tft_panel_palette_convert,
- .append_pixels = qp_tft_panel_append_pixels,
+ .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped,
+ .append_pixels = qp_tft_panel_append_pixels_rgb565,
},
- .rgb888_to_native16bit = qp_rgb888_to_rgb565_swapped,
- .num_window_bytes = 1,
- .swap_window_coords = true,
+ .num_window_bytes = 1,
+ .swap_window_coords = true,
.opcodes =
{
.display_on = SSD1351_DISPLAYON,
diff --git a/drivers/painter/st77xx/qp_st7789.c b/drivers/painter/st77xx/qp_st7789.c
index d005ece050..49e8436c29 100644
--- a/drivers/painter/st77xx/qp_st7789.c
+++ b/drivers/painter/st77xx/qp_st7789.c
@@ -90,12 +90,11 @@ const struct tft_panel_dc_reset_painter_driver_vtable_t st7789_driver_vtable = {
.flush = qp_tft_panel_flush,
.pixdata = qp_tft_panel_pixdata,
.viewport = qp_tft_panel_viewport,
- .palette_convert = qp_tft_panel_palette_convert,
- .append_pixels = qp_tft_panel_append_pixels,
+ .palette_convert = qp_tft_panel_palette_convert_rgb565_swapped,
+ .append_pixels = qp_tft_panel_append_pixels_rgb565,
},
- .rgb888_to_native16bit = qp_rgb888_to_rgb565_swapped,
- .num_window_bytes = 2,
- .swap_window_coords = false,
+ .num_window_bytes = 2,
+ .swap_window_coords = false,
.opcodes =
{
.display_on = ST77XX_CMD_DISPLAY_ON,
diff --git a/drivers/painter/tft_panel/qp_tft_panel.c b/drivers/painter/tft_panel/qp_tft_panel.c
index 4d636c9509..ad83b6c792 100644
--- a/drivers/painter/tft_panel/qp_tft_panel.c
+++ b/drivers/painter/tft_panel/qp_tft_panel.c
@@ -10,29 +10,6 @@
#define BYTE_SWAP(x) (((((uint16_t)(x)) >> 8) & 0x00FF) | ((((uint16_t)(x)) << 8) & 0xFF00))
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Native pixel format conversion
-
-uint16_t qp_rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b) {
- uint16_t rgb565 = (((uint16_t)r) >> 3) << 11 | (((uint16_t)g) >> 2) << 5 | (((uint16_t)b) >> 3);
- return rgb565;
-}
-
-uint16_t qp_rgb888_to_rgb565_swapped(uint8_t r, uint8_t g, uint8_t b) {
- uint16_t rgb565 = (((uint16_t)r) >> 3) << 11 | (((uint16_t)g) >> 2) << 5 | (((uint16_t)b) >> 3);
- return BYTE_SWAP(rgb565);
-}
-
-uint16_t qp_rgb888_to_bgr565(uint8_t r, uint8_t g, uint8_t b) {
- uint16_t bgr565 = (((uint16_t)b) >> 3) << 11 | (((uint16_t)g) >> 2) << 5 | (((uint16_t)r) >> 3);
- return bgr565;
-}
-
-uint16_t qp_rgb888_to_bgr565_swapped(uint8_t r, uint8_t g, uint8_t b) {
- uint16_t bgr565 = (((uint16_t)b) >> 3) << 11 | (((uint16_t)g) >> 2) << 5 | (((uint16_t)r) >> 3);
- return BYTE_SWAP(bgr565);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Quantum Painter API implementations
// Power control
@@ -105,26 +82,49 @@ bool qp_tft_panel_viewport(painter_device_t device, uint16_t left, uint16_t top,
// Stream pixel data to the current write position in GRAM
bool qp_tft_panel_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count) {
- qp_comms_send(device, pixel_data, native_pixel_count * sizeof(uint16_t));
+ struct painter_driver_t *driver = (struct painter_driver_t *)device;
+ qp_comms_send(device, pixel_data, native_pixel_count * driver->native_bits_per_pixel / 8);
return true;
}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Convert supplied palette entries into their native equivalents
-bool qp_tft_panel_palette_convert(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) {
- struct painter_driver_t * driver = (struct painter_driver_t *)device;
- struct tft_panel_dc_reset_painter_driver_vtable_t *vtable = (struct tft_panel_dc_reset_painter_driver_vtable_t *)driver->driver_vtable;
+
+bool qp_tft_panel_palette_convert_rgb565_swapped(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) {
for (int16_t i = 0; i < palette_size; ++i) {
- RGB rgb = hsv_to_rgb_nocie((HSV){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v});
- palette[i].rgb565 = vtable->rgb888_to_native16bit(rgb.r, rgb.g, rgb.b);
+ RGB rgb = hsv_to_rgb_nocie((HSV){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v});
+ uint16_t rgb565 = (((uint16_t)rgb.r) >> 3) << 11 | (((uint16_t)rgb.g) >> 2) << 5 | (((uint16_t)rgb.b) >> 3);
+ palette[i].rgb565 = BYTE_SWAP(rgb565);
}
return true;
}
+bool qp_tft_panel_palette_convert_rgb888(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) {
+ for (int16_t i = 0; i < palette_size; ++i) {
+ RGB rgb = hsv_to_rgb_nocie((HSV){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v});
+ palette[i].rgb888.r = rgb.r;
+ palette[i].rgb888.g = rgb.g;
+ palette[i].rgb888.b = rgb.b;
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Append pixels to the target location, keyed by the pixel index
-bool qp_tft_panel_append_pixels(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices) {
+
+bool qp_tft_panel_append_pixels_rgb565(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices) {
uint16_t *buf = (uint16_t *)target_buffer;
for (uint32_t i = 0; i < pixel_count; ++i) {
buf[pixel_offset + i] = palette[palette_indices[i]].rgb565;
}
return true;
}
+
+bool qp_tft_panel_append_pixels_rgb888(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices) {
+ for (uint32_t i = 0; i < pixel_count; ++i) {
+ target_buffer[(pixel_offset + i) * 3 + 0] = palette[palette_indices[i]].rgb888.r;
+ target_buffer[(pixel_offset + i) * 3 + 1] = palette[palette_indices[i]].rgb888.g;
+ target_buffer[(pixel_offset + i) * 3 + 2] = palette[palette_indices[i]].rgb888.b;
+ }
+ return true;
+}
diff --git a/drivers/painter/tft_panel/qp_tft_panel.h b/drivers/painter/tft_panel/qp_tft_panel.h
index 6eddfc503d..3cb015891b 100644
--- a/drivers/painter/tft_panel/qp_tft_panel.h
+++ b/drivers/painter/tft_panel/qp_tft_panel.h
@@ -11,15 +11,10 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Common TFT panel implementation using D/C, and RST pins.
-typedef uint16_t (*rgb888_to_native_uint16_t)(uint8_t r, uint8_t g, uint8_t b);
-
// Driver vtable with extras
struct tft_panel_dc_reset_painter_driver_vtable_t {
struct painter_driver_vtable_t base; // must be first, so it can be cast to/from the painter_driver_vtable_t* type
- // Conversion function for palette entries
- rgb888_to_native_uint16_t rgb888_to_native16bit;
-
// Number of bytes for transmitting x/y coordinates
uint8_t num_window_bytes;
@@ -58,10 +53,9 @@ bool qp_tft_panel_clear(painter_device_t device);
bool qp_tft_panel_flush(painter_device_t device);
bool qp_tft_panel_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom);
bool qp_tft_panel_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count);
-bool qp_tft_panel_palette_convert(painter_device_t device, int16_t palette_size, qp_pixel_t *palette);
-bool qp_tft_panel_append_pixels(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices);
-uint16_t qp_rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b);
-uint16_t qp_rgb888_to_rgb565_swapped(uint8_t r, uint8_t g, uint8_t b);
-uint16_t qp_rgb888_to_bgr565(uint8_t r, uint8_t g, uint8_t b);
-uint16_t qp_rgb888_to_bgr565_swapped(uint8_t r, uint8_t g, uint8_t b);
+bool qp_tft_panel_palette_convert_rgb565_swapped(painter_device_t device, int16_t palette_size, qp_pixel_t *palette);
+bool qp_tft_panel_palette_convert_rgb888(painter_device_t device, int16_t palette_size, qp_pixel_t *palette);
+
+bool qp_tft_panel_append_pixels_rgb565(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices);
+bool qp_tft_panel_append_pixels_rgb888(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices);
diff --git a/drivers/ps2/ps2.h b/drivers/ps2/ps2.h
index f123192852..2465e16235 100644
--- a/drivers/ps2/ps2.h
+++ b/drivers/ps2/ps2.h
@@ -89,6 +89,7 @@ uint8_t ps2_host_send(uint8_t data);
uint8_t ps2_host_recv_response(void);
uint8_t ps2_host_recv(void);
void ps2_host_set_led(uint8_t usb_led);
+bool pbuf_has_data(void);
/*--------------------------------------------------------------------
* static functions
diff --git a/drivers/ps2/ps2_interrupt.c b/drivers/ps2/ps2_interrupt.c
index c49b4f8b75..c9a9f1e1ec 100644
--- a/drivers/ps2/ps2_interrupt.c
+++ b/drivers/ps2/ps2_interrupt.c
@@ -66,8 +66,8 @@ uint8_t ps2_error = PS2_ERR_NONE;
static inline uint8_t pbuf_dequeue(void);
static inline void pbuf_enqueue(uint8_t data);
-static inline bool pbuf_has_data(void);
static inline void pbuf_clear(void);
+bool pbuf_has_data(void);
#if defined(PROTOCOL_CHIBIOS)
void ps2_interrupt_service_routine(void);
@@ -309,7 +309,7 @@ static inline uint8_t pbuf_dequeue(void) {
return val;
}
-static inline bool pbuf_has_data(void) {
+bool pbuf_has_data(void) {
#if defined(__AVR__)
uint8_t sreg = SREG;
cli();
diff --git a/drivers/ps2/ps2_mouse.c b/drivers/ps2/ps2_mouse.c
index ccb0a929ae..66b48bb3c3 100644
--- a/drivers/ps2/ps2_mouse.c
+++ b/drivers/ps2/ps2_mouse.c
@@ -53,6 +53,7 @@ void ps2_mouse_init(void) {
ps2_mouse_set_remote_mode();
#else
ps2_mouse_enable_data_reporting();
+ ps2_mouse_set_stream_mode();
#endif
#ifdef PS2_MOUSE_ENABLE_SCROLLING
@@ -75,19 +76,33 @@ void ps2_mouse_task(void) {
extern int tp_buttons;
/* receives packet from mouse */
+#ifdef PS2_MOUSE_USE_REMOTE_MODE
uint8_t rcv;
rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
if (rcv == PS2_ACK) {
mouse_report.buttons = ps2_host_recv_response() | tp_buttons;
mouse_report.x = ps2_host_recv_response() * PS2_MOUSE_X_MULTIPLIER;
mouse_report.y = ps2_host_recv_response() * PS2_MOUSE_Y_MULTIPLIER;
-#ifdef PS2_MOUSE_ENABLE_SCROLLING
+# ifdef PS2_MOUSE_ENABLE_SCROLLING
mouse_report.v = -(ps2_host_recv_response() & PS2_MOUSE_SCROLL_MASK) * PS2_MOUSE_V_MULTIPLIER;
-#endif
+# endif
+ } else {
+ if (debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
+ return;
+ }
+#else
+ if (pbuf_has_data()) {
+ mouse_report.buttons = ps2_host_recv_response() | tp_buttons;
+ mouse_report.x = ps2_host_recv_response() * PS2_MOUSE_X_MULTIPLIER;
+ mouse_report.y = ps2_host_recv_response() * PS2_MOUSE_Y_MULTIPLIER;
+# ifdef PS2_MOUSE_ENABLE_SCROLLING
+ mouse_report.v = -(ps2_host_recv_response() & PS2_MOUSE_SCROLL_MASK) * PS2_MOUSE_V_MULTIPLIER;
+# endif
} else {
if (debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
return;
}
+#endif
/* if mouse moves or buttons state changes */
if (mouse_report.x || mouse_report.y || mouse_report.v || ((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) {
diff --git a/drivers/sensors/cirque_pinnacle.c b/drivers/sensors/cirque_pinnacle.c
index 2db7f916fe..c50d5a2525 100644
--- a/drivers/sensors/cirque_pinnacle.c
+++ b/drivers/sensors/cirque_pinnacle.c
@@ -1,52 +1,24 @@
// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
+// based on https://github.com/cirque-corp/Cirque_Pinnacle_1CA027/tree/master/Circular_Trackpad
+// with modifications and changes for QMK
+// refer to documentation: Gen2 and Gen3 (Pinnacle ASIC) at https://www.cirque.com/documentation
+
#include "cirque_pinnacle.h"
#include "print.h"
#include "debug.h"
#include "wait.h"
-
-// Registers for RAP
-// clang-format off
-#define FIRMWARE_ID 0x00
-#define FIRMWARE_VERSION_C 0x01
-#define STATUS_1 0x02
-#define SYSCONFIG_1 0x03
-#define FEEDCONFIG_1 0x04
-#define FEEDCONFIG_2 0x05
-#define CALIBRATION_CONFIG_1 0x07
-#define PS2_AU_CONTROL 0x08
-#define SAMPLE_RATE 0x09
-#define Z_IDLE_COUNT 0x0A
-#define Z_SCALER 0x0B
-#define SLEEP_INTERVAL 0x0C
-#define SLEEP_TIMER 0x0D
-#define PACKET_BYTE_0 0x12
-#define PACKET_BYTE_1 0x13
-#define PACKET_BYTE_2 0x14
-#define PACKET_BYTE_3 0x15
-#define PACKET_BYTE_4 0x16
-#define PACKET_BYTE_5 0x17
-
-#define ERA_VALUE 0x1B
-#define ERA_HIGH_BYTE 0x1C
-#define ERA_LOW_BYTE 0x1D
-#define ERA_CONTROL 0x1E
-
-// ADC-attenuation settings (held in BIT_7 and BIT_6)
-// 1X = most sensitive, 4X = least sensitive
-#define ADC_ATTENUATE_1X 0x00
-#define ADC_ATTENUATE_2X 0x40
-#define ADC_ATTENUATE_3X 0x80
-#define ADC_ATTENUATE_4X 0xC0
-
-// Register config values for this demo
-#define SYSCONFIG_1_VALUE 0x00
-#define FEEDCONFIG_1_VALUE 0x03 // 0x03 for absolute mode 0x01 for relative mode
-#define FEEDCONFIG_2_VALUE 0x1C // 0x1F for normal functionality 0x1E for intellimouse disabled
-#define Z_IDLE_COUNT_VALUE 0x05
-// clang-format on
+#include "timer.h"
+
+#ifndef CIRQUE_PINNACLE_ATTENUATION
+# ifdef CIRQUE_PINNACLE_CURVED_OVERLAY
+# define CIRQUE_PINNACLE_ATTENUATION EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X
+# else
+# define CIRQUE_PINNACLE_ATTENUATION EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_4X
+# endif
+#endif
bool touchpad_init;
-uint16_t scale_data = 1024;
+uint16_t scale_data = CIRQUE_PINNACLE_DEFAULT_SCALE;
void cirque_pinnacle_clear_flags(void);
void cirque_pinnacle_enable_feed(bool feedEnable);
@@ -103,45 +75,45 @@ void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResoluti
// Clears Status1 register flags (SW_CC and SW_DR)
void cirque_pinnacle_clear_flags() {
- RAP_Write(STATUS_1, 0x00);
+ RAP_Write(HOSTREG__STATUS1, HOSTREG__STATUS1_DEFVAL & ~(HOSTREG__STATUS1__COMMAND_COMPLETE | HOSTREG__STATUS1__DATA_READY));
wait_us(50);
}
// Enables/Disables the feed
void cirque_pinnacle_enable_feed(bool feedEnable) {
- uint8_t temp;
-
- RAP_ReadBytes(FEEDCONFIG_1, &temp, 1); // Store contents of FeedConfig1 register
+ uint8_t feedconfig1;
+ RAP_ReadBytes(HOSTREG__FEEDCONFIG1, &feedconfig1, 1);
if (feedEnable) {
- temp |= 0x01; // Set Feed Enable bit
- RAP_Write(0x04, temp);
+ feedconfig1 |= HOSTREG__FEEDCONFIG1__FEED_ENABLE;
} else {
- temp &= ~0x01; // Clear Feed Enable bit
- RAP_Write(0x04, temp);
+ feedconfig1 &= ~HOSTREG__FEEDCONFIG1__FEED_ENABLE;
}
+ RAP_Write(HOSTREG__FEEDCONFIG1, feedconfig1);
}
/* ERA (Extended Register Access) Functions */
// Reads <count> bytes from an extended register at <address> (16-bit address),
// stores values in <*data>
void ERA_ReadBytes(uint16_t address, uint8_t* data, uint16_t count) {
- uint8_t ERAControlValue = 0xFF;
+ uint8_t ERAControlValue = 0xFF;
+ uint16_t timeout_timer;
cirque_pinnacle_enable_feed(false); // Disable feed
- RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Send upper byte of ERA address
- RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Send lower byte of ERA address
+ RAP_Write(HOSTREG__EXT_REG_AXS_ADDR_HIGH, (uint8_t)(address >> 8)); // Send upper byte of ERA address
+ RAP_Write(HOSTREG__EXT_REG_AXS_ADDR_LOW, (uint8_t)(address & 0x00FF)); // Send lower byte of ERA address
for (uint16_t i = 0; i < count; i++) {
- RAP_Write(ERA_CONTROL, 0x05); // Signal ERA-read (auto-increment) to Pinnacle
+ RAP_Write(HOSTREG__EXT_REG_AXS_CTRL, HOSTREG__EREG_AXS__INC_ADDR_READ | HOSTREG__EREG_AXS__READ); // Signal ERA-read (auto-increment) to Pinnacle
// Wait for status register 0x1E to clear
+ timeout_timer = timer_read();
do {
- RAP_ReadBytes(ERA_CONTROL, &ERAControlValue, 1);
- } while (ERAControlValue != 0x00);
+ RAP_ReadBytes(HOSTREG__EXT_REG_AXS_CTRL, &ERAControlValue, 1);
+ } while ((ERAControlValue != 0x00) && (timer_elapsed(timeout_timer) <= CIRQUE_PINNACLE_TIMEOUT));
- RAP_ReadBytes(ERA_VALUE, data + i, 1);
+ RAP_ReadBytes(HOSTREG__EXT_REG_AXS_VALUE, data + i, 1);
cirque_pinnacle_clear_flags();
}
@@ -149,49 +121,83 @@ void ERA_ReadBytes(uint16_t address, uint8_t* data, uint16_t count) {
// Writes a byte, <data>, to an extended register at <address> (16-bit address)
void ERA_WriteByte(uint16_t address, uint8_t data) {
- uint8_t ERAControlValue = 0xFF;
+ uint8_t ERAControlValue = 0xFF;
+ uint16_t timeout_timer;
cirque_pinnacle_enable_feed(false); // Disable feed
- RAP_Write(ERA_VALUE, data); // Send data byte to be written
+ RAP_Write(HOSTREG__EXT_REG_AXS_VALUE, data); // Send data byte to be written
- RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Upper byte of ERA address
- RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Lower byte of ERA address
+ RAP_Write(HOSTREG__EXT_REG_AXS_ADDR_HIGH, (uint8_t)(address >> 8)); // Upper byte of ERA address
+ RAP_Write(HOSTREG__EXT_REG_AXS_ADDR_LOW, (uint8_t)(address & 0x00FF)); // Lower byte of ERA address
- RAP_Write(ERA_CONTROL, 0x02); // Signal an ERA-write to Pinnacle
+ RAP_Write(HOSTREG__EXT_REG_AXS_CTRL, HOSTREG__EREG_AXS__WRITE); // Signal an ERA-write to Pinnacle
// Wait for status register 0x1E to clear
+ timeout_timer = timer_read();
do {
- RAP_ReadBytes(ERA_CONTROL, &ERAControlValue, 1);
- } while (ERAControlValue != 0x00);
+ RAP_ReadBytes(HOSTREG__EXT_REG_AXS_CTRL, &ERAControlValue, 1);
+ } while ((ERAControlValue != 0x00) && (timer_elapsed(timeout_timer) <= CIRQUE_PINNACLE_TIMEOUT));
cirque_pinnacle_clear_flags();
}
void cirque_pinnacle_set_adc_attenuation(uint8_t adcGain) {
- uint8_t temp = 0x00;
+ uint8_t adcconfig = 0x00;
- ERA_ReadBytes(0x0187, &temp, 1);
- temp &= 0x3F; // clear top two bits
- temp |= adcGain;
- ERA_WriteByte(0x0187, temp);
- ERA_ReadBytes(0x0187, &temp, 1);
+ ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1);
+ adcconfig &= EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK;
+ adcconfig |= adcGain;
+ ERA_WriteByte(EXTREG__TRACK_ADCCONFIG, adcconfig);
+ ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1);
}
// Changes thresholds to improve detection of fingers
+// Not needed for flat overlay?
void cirque_pinnacle_tune_edge_sensitivity(void) {
- uint8_t temp = 0x00;
+ uint8_t widezmin = 0x00;
- ERA_ReadBytes(0x0149, &temp, 1);
- ERA_WriteByte(0x0149, 0x04);
- ERA_ReadBytes(0x0149, &temp, 1);
+ ERA_ReadBytes(EXTREG__XAXIS_WIDEZMIN, &widezmin, 1);
+ ERA_WriteByte(EXTREG__XAXIS_WIDEZMIN, 0x04); // magic number from Cirque sample code
+ ERA_ReadBytes(EXTREG__XAXIS_WIDEZMIN, &widezmin, 1);
- ERA_ReadBytes(0x0168, &temp, 1);
- ERA_WriteByte(0x0168, 0x03);
- ERA_ReadBytes(0x0168, &temp, 1);
+ ERA_ReadBytes(EXTREG__YAXIS_WIDEZMIN, &widezmin, 1);
+ ERA_WriteByte(EXTREG__YAXIS_WIDEZMIN, 0x03); // magic number from Cirque sample code
+ ERA_ReadBytes(EXTREG__YAXIS_WIDEZMIN, &widezmin, 1);
}
-/* Pinnacle-based TM040040 Functions */
+// Perform calibration
+void cirque_pinnacle_calibrate(void) {
+ uint8_t calconfig;
+ uint16_t timeout_timer;
+
+ RAP_ReadBytes(HOSTREG__CALCONFIG1, &calconfig, 1);
+ calconfig |= HOSTREG__CALCONFIG1__CALIBRATE;
+ RAP_Write(HOSTREG__CALCONFIG1, calconfig);
+
+ // Calibration takes ~100ms according to GT-AN-090624, doubling the timeout just to be safe
+ timeout_timer = timer_read();
+ do {
+ RAP_ReadBytes(HOSTREG__CALCONFIG1, &calconfig, 1);
+ } while ((calconfig & HOSTREG__CALCONFIG1__CALIBRATE) && (timer_elapsed(timeout_timer) <= 200));
+
+ cirque_pinnacle_clear_flags();
+}
+
+// Enable/disable cursor smoothing, smoothing is enabled by default
+void cirque_pinnacle_cursor_smoothing(bool enable) {
+ uint8_t feedconfig3;
+
+ RAP_ReadBytes(HOSTREG__FEEDCONFIG3, &feedconfig3, 1);
+ if (enable) {
+ feedconfig3 &= ~HOSTREG__FEEDCONFIG3__DISABLE_CROSS_RATE_SMOOTHING;
+ } else {
+ feedconfig3 |= HOSTREG__FEEDCONFIG3__DISABLE_CROSS_RATE_SMOOTHING;
+ }
+ RAP_Write(HOSTREG__FEEDCONFIG3, feedconfig3);
+}
+
+/* Pinnacle-based TM040040/TM035035/TM023023 Functions */
void cirque_pinnacle_init(void) {
#if defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
spi_init();
@@ -200,39 +206,71 @@ void cirque_pinnacle_init(void) {
#endif
touchpad_init = true;
+
// Host clears SW_CC flag
cirque_pinnacle_clear_flags();
- // Host configures bits of registers 0x03 and 0x05
- RAP_Write(SYSCONFIG_1, SYSCONFIG_1_VALUE);
- RAP_Write(FEEDCONFIG_2, FEEDCONFIG_2_VALUE);
+ // send a RESET command now, in case QMK had a soft-reset without a power cycle
+ RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1__RESET);
+ wait_ms(30); // Pinnacle needs 10-15ms to boot, so wait long enough before configuring
+ RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1_DEFVAL);
+ wait_us(50);
+
+ // FeedConfig2 (Feature flags for Relative Mode Only)
+ RAP_Write(HOSTREG__FEEDCONFIG2, HOSTREG__FEEDCONFIG2_DEFVAL);
- // Host enables preferred output mode (absolute)
- RAP_Write(FEEDCONFIG_1, FEEDCONFIG_1_VALUE);
+ // FeedConfig1 (Data Output Flags)
+ RAP_Write(HOSTREG__FEEDCONFIG1, CIRQUE_PINNACLE_POSITION_MODE ? HOSTREG__FEEDCONFIG1__DATA_TYPE__REL0_ABS1 : HOSTREG__FEEDCONFIG1_DEFVAL);
- // Host sets z-idle packet count to 5 (default is 30)
- RAP_Write(Z_IDLE_COUNT, Z_IDLE_COUNT_VALUE);
+ // Host sets z-idle packet count to 5 (default is 0x1E/30)
+ RAP_Write(HOSTREG__ZIDLE, 5);
- cirque_pinnacle_set_adc_attenuation(0xFF);
+ cirque_pinnacle_set_adc_attenuation(CIRQUE_PINNACLE_ATTENUATION);
+#ifdef CIRQUE_PINNACLE_CURVED_OVERLAY
cirque_pinnacle_tune_edge_sensitivity();
+#endif
+ // Force a calibration after setting ADC attenuation
+ cirque_pinnacle_calibrate();
+
cirque_pinnacle_enable_feed(true);
}
-// Reads XYZ data from Pinnacle registers 0x14 through 0x17
-// Stores result in pinnacle_data_t struct with xValue, yValue, and zValue members
pinnacle_data_t cirque_pinnacle_read_data(void) {
- uint8_t data[6] = {0};
- pinnacle_data_t result = {0};
- RAP_ReadBytes(PACKET_BYTE_0, data, 6);
+ uint8_t data_ready = 0;
+ uint8_t data[6] = {0};
+ pinnacle_data_t result = {0};
+
+ // Check if there is valid data available
+ RAP_ReadBytes(HOSTREG__STATUS1, &data_ready, 1);
+ if ((data_ready & HOSTREG__STATUS1__DATA_READY) == 0) {
+ // no data available yet
+ result.valid = false; // be explicit
+ return result;
+ }
- cirque_pinnacle_clear_flags();
+ // Read all data bytes
+ RAP_ReadBytes(HOSTREG__PACKETBYTE_0, data, 6);
- result.buttonFlags = data[0] & 0x3F;
- result.xValue = data[2] | ((data[4] & 0x0F) << 8);
- result.yValue = data[3] | ((data[4] & 0xF0) << 4);
- result.zValue = data[5] & 0x3F;
+ // Get ready for the next data sample
+ cirque_pinnacle_clear_flags();
- result.touchDown = (result.xValue != 0 || result.yValue != 0);
+#if CIRQUE_PINNACLE_POSITION_MODE
+ // Decode data for absolute mode
+ // Register 0x13 is unused in this mode (palm detection area)
+ result.buttonFlags = data[0] & 0x3F; // bit0 to bit5 are switch 0-5, only hardware button presses (from input pin on the Pinnacle chip)
+ result.xValue = data[2] | ((data[4] & 0x0F) << 8); // merge high and low bits for X
+ result.yValue = data[3] | ((data[4] & 0xF0) << 4); // merge high and low bits for Y
+ result.zValue = data[5] & 0x3F; // Z is only lower 6 bits, upper 2 bits are reserved/unused
+ result.touchDown = (result.xValue != 0 || result.yValue != 0); // (0,0) is a "magic coordinate" to indicate "finger touched down"
+#else
+ // Decode data for relative mode
+ // Registers 0x16 and 0x17 are unused in this mode
+ result.buttons = data[0] & 0x07; // bit0 = primary button, bit1 = secondary button, bit2 = auxilary button, if Taps enabled then also software-recognized taps are reported
+ result.xDelta = data[1];
+ result.yDelta = data[2];
+ result.wheelCount = data[3];
+#endif
+ result.valid = true;
return result;
}
diff --git a/drivers/sensors/cirque_pinnacle.h b/drivers/sensors/cirque_pinnacle.h
index c8cb360e03..1c9bf06fd3 100644
--- a/drivers/sensors/cirque_pinnacle.h
+++ b/drivers/sensors/cirque_pinnacle.h
@@ -2,26 +2,23 @@
#pragma once
+#include "cirque_pinnacle_regdefs.h"
#include <stdint.h>
#include <stdbool.h>
-// Convenient way to store and access measurements
-typedef struct {
- uint16_t xValue;
- uint16_t yValue;
- uint16_t zValue;
- uint8_t buttonFlags;
- bool touchDown;
-} pinnacle_data_t;
+#ifndef CIRQUE_PINNACLE_TIMEOUT
+# define CIRQUE_PINNACLE_TIMEOUT 20 // I2C timeout in milliseconds
+#endif
-void cirque_pinnacle_init(void);
-pinnacle_data_t cirque_pinnacle_read_data(void);
-void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution);
-uint16_t cirque_pinnacle_get_scale(void);
-void cirque_pinnacle_set_scale(uint16_t scale);
+#define CIRQUE_PINNACLE_ABSOLUTE_MODE 1
+#define CIRQUE_PINNACLE_RELATIVE_MODE 0
+#ifndef CIRQUE_PINNACLE_POSITION_MODE
+# define CIRQUE_PINNACLE_POSITION_MODE CIRQUE_PINNACLE_ABSOLUTE_MODE
+#endif
-#ifndef CIRQUE_PINNACLE_TIMEOUT
-# define CIRQUE_PINNACLE_TIMEOUT 20
+#define CIRQUE_PINNACLE_DEFAULT_SCALE 1024
+#ifndef CIRQUE_PINNACLE_DIAMETER_MM
+# define CIRQUE_PINNACLE_DIAMETER_MM 40
#endif
// Coordinate scaling values
@@ -43,12 +40,14 @@ void cirque_pinnacle_set_scale(uint16_t scale);
#ifndef CIRQUE_PINNACLE_Y_RANGE
# define CIRQUE_PINNACLE_Y_RANGE (CIRQUE_PINNACLE_Y_UPPER - CIRQUE_PINNACLE_Y_LOWER)
#endif
-
+#if !defined(POINTING_DEVICE_TASK_THROTTLE_MS)
+# define POINTING_DEVICE_TASK_THROTTLE_MS 10 // Cirque Pinnacle in normal operation produces data every 10ms. Advanced configuration for pen/stylus usage might require lower values.
+#endif
#if defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c)
# include "i2c_master.h"
// Cirque's 7-bit I2C Slave Address
# ifndef CIRQUE_PINNACLE_ADDR
-# define CIRQUE_PINNACLE_ADDR 0x2A
+# define CIRQUE_PINNACLE_ADDR I2C_ADDRESS_DEFAULT
# endif
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
# include "spi_master.h"
@@ -72,3 +71,32 @@ void cirque_pinnacle_set_scale(uint16_t scale);
# endif
# endif
#endif
+
+#define DIVIDE_UNSIGNED_ROUND(numerator, denominator) (((numerator) + ((denominator) / 2)) / (denominator))
+#define CIRQUE_PINNACLE_INCH_TO_PX(inch) (DIVIDE_UNSIGNED_ROUND((inch) * (uint32_t)CIRQUE_PINNACLE_DIAMETER_MM * 10, 254))
+#define CIRQUE_PINNACLE_PX_TO_INCH(px) (DIVIDE_UNSIGNED_ROUND((px) * (uint32_t)254, CIRQUE_PINNACLE_DIAMETER_MM * 10))
+
+// Convenient way to store and access measurements
+typedef struct {
+ bool valid; // true if valid data was read, false if no data was ready
+#if CIRQUE_PINNACLE_POSITION_MODE
+ uint16_t xValue;
+ uint16_t yValue;
+ uint16_t zValue;
+ uint8_t buttonFlags;
+ bool touchDown;
+#else
+ uint8_t xDelta;
+ uint8_t yDelta;
+ uint8_t wheelCount;
+ uint8_t buttons;
+#endif
+} pinnacle_data_t;
+
+void cirque_pinnacle_init(void);
+void cirque_pinnacle_calibrate(void);
+void cirque_pinnacle_cursor_smoothing(bool enable);
+pinnacle_data_t cirque_pinnacle_read_data(void);
+void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution);
+uint16_t cirque_pinnacle_get_scale(void);
+void cirque_pinnacle_set_scale(uint16_t scale);
diff --git a/drivers/sensors/cirque_pinnacle_gestures.c b/drivers/sensors/cirque_pinnacle_gestures.c
new file mode 100644
index 0000000000..70f16527ba
--- /dev/null
+++ b/drivers/sensors/cirque_pinnacle_gestures.c
@@ -0,0 +1,227 @@
+/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ * Copyright 2022 Daniel Kao <daniel.m.kao@gmail.com>
+ *
+ * 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 <stdlib.h>
+#include <lib/lib8tion/lib8tion.h>
+#include "cirque_pinnacle_gestures.h"
+#include "pointing_device.h"
+#include "timer.h"
+#include "wait.h"
+
+#if defined(CIRQUE_PINNACLE_TAP_ENABLE) || defined(CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE)
+static cirque_pinnacle_features_t features = {.tap_enable = true, .circular_scroll_enable = true};
+#endif
+
+#ifdef CIRQUE_PINNACLE_TAP_ENABLE
+static trackpad_tap_context_t tap;
+
+static report_mouse_t trackpad_tap(report_mouse_t mouse_report, pinnacle_data_t touchData) {
+ if (touchData.touchDown != tap.touchDown) {
+ tap.touchDown = touchData.touchDown;
+ if (!touchData.zValue) {
+ if (timer_elapsed(tap.timer) < CIRQUE_PINNACLE_TAPPING_TERM && tap.timer != 0) {
+ mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1);
+ pointing_device_set_report(mouse_report);
+ pointing_device_send();
+# if TAP_CODE_DELAY > 0
+ wait_ms(TAP_CODE_DELAY);
+# endif
+ mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
+ pointing_device_set_report(mouse_report);
+ pointing_device_send();
+ }
+ }
+ tap.timer = timer_read();
+ }
+ if (timer_elapsed(tap.timer) > (CIRQUE_PINNACLE_TOUCH_DEBOUNCE)) {
+ tap.timer = 0;
+ }
+
+ return mouse_report;
+}
+
+void cirque_pinnacle_enable_tap(bool enable) {
+ features.tap_enable = enable;
+}
+#endif
+
+#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE
+/* To set a trackpad exclusively as scroll wheel: outer_ring_pct = 100, trigger_px = 0, trigger_ang = 0 */
+static circular_scroll_context_t scroll = {.config = {.outer_ring_pct = 33,
+ .trigger_px = 16,
+ .trigger_ang = 9102, /* 50 degrees */
+ .wheel_clicks = 18}};
+
+static inline uint16_t atan2_16(int32_t dy, int32_t dx) {
+ if (dy == 0) {
+ if (dx >= 0) {
+ return 0;
+ } else {
+ return 32768;
+ }
+ }
+
+ int32_t abs_y = dy > 0 ? dy : -dy;
+ int16_t a;
+
+ if (dx >= 0) {
+ a = 8192 - (8192 * (dx - abs_y) / (dx + abs_y));
+ } else {
+ a = 24576 - (8192 * (dx + abs_y) / (abs_y - dx));
+ }
+
+ if (dy < 0) {
+ return -a; // negate if in quad III or IV
+ }
+ return a;
+}
+
+static circular_scroll_t circular_scroll(pinnacle_data_t touchData) {
+ circular_scroll_t report = {0, 0, false};
+ int8_t x, y, wheel_clicks;
+ uint8_t center = 256 / 2, mag;
+ int16_t ang, dot, det, opposite_side, adjacent_side;
+ uint16_t scale = cirque_pinnacle_get_scale();
+
+ if (touchData.zValue) {
+ /*
+ * Place origin at center of trackpad, treat coordinates as vectors.
+ * Scale to fixed int8_t size; angles are independent of resolution.
+ */
+ if (scale) {
+ x = (int8_t)((int32_t)touchData.xValue * 256 / scale - center);
+ y = (int8_t)((int32_t)touchData.yValue * 256 / scale - center);
+ } else {
+ x = 0;
+ y = 0;
+ }
+
+ /* Check if first touch */
+ if (!scroll.z) {
+ report.suppress_touch = false;
+ /* Check if touch falls within outer ring */
+ mag = sqrt16(x * x + y * y);
+ if (mag * 100 / center >= 100 - scroll.config.outer_ring_pct) {
+ scroll.state = SCROLL_DETECTING;
+ scroll.x = x;
+ scroll.y = y;
+ scroll.mag = mag;
+ /*
+ * Decide scroll axis:
+ * Vertical if started from righ half
+ * Horizontal if started from left half
+ * Flipped for left-handed
+ */
+# if defined(POINTING_DEVICE_ROTATION_90)
+ scroll.axis = y < 0;
+# elif defined(POINTING_DEVICE_ROTATION_180)
+ scroll.axis = x > 0;
+# elif defined(POINTING_DEVICE_ROTATION_270)
+ scroll.axis = y > 0;
+# else
+ scroll.axis = x < 0;
+# endif
+ }
+ } else if (scroll.state == SCROLL_DETECTING) {
+ report.suppress_touch = true;
+ /* Already detecting scroll, check movement from touchdown location */
+ mag = sqrt16((x - scroll.x) * (x - scroll.x) + (y - scroll.y) * (y - scroll.y));
+ if (mag >= scroll.config.trigger_px) {
+ /*
+ * Find angle of movement.
+ * 0 degrees here means movement towards center of circle
+ */
+ dot = scroll.x * x + scroll.y * y;
+ det = scroll.x * y - scroll.y * x;
+ opposite_side = abs(det); /* Based on scalar rejection */
+ adjacent_side = abs(scroll.mag * scroll.mag - abs(dot)); /* Based on scalar projection */
+ ang = (int16_t)atan2_16(opposite_side, adjacent_side);
+ if (ang < scroll.config.trigger_ang) {
+ /* Not a scroll, release coordinates */
+ report.suppress_touch = false;
+ scroll.state = NOT_SCROLL;
+ } else {
+ /* Scroll detected */
+ scroll.state = SCROLL_VALID;
+ }
+ }
+ }
+ if (scroll.state == SCROLL_VALID) {
+ report.suppress_touch = true;
+ dot = scroll.x * x + scroll.y * y;
+ det = scroll.x * y - scroll.y * x;
+ ang = (int16_t)atan2_16(det, dot);
+ wheel_clicks = ((int32_t)ang * scroll.config.wheel_clicks) / 65536;
+ if (wheel_clicks >= 1 || wheel_clicks <= -1) {
+ if (scroll.config.left_handed) {
+ if (scroll.axis == 0) {
+ report.h = -wheel_clicks;
+ } else {
+ report.v = wheel_clicks;
+ }
+ } else {
+ if (scroll.axis == 0) {
+ report.v = -wheel_clicks;
+ } else {
+ report.h = wheel_clicks;
+ }
+ }
+ scroll.x = x;
+ scroll.y = y;
+ }
+ }
+ }
+
+ scroll.z = touchData.zValue;
+ if (!scroll.z) scroll.state = SCROLL_UNINITIALIZED;
+
+ return report;
+}
+
+void cirque_pinnacle_enable_circular_scroll(bool enable) {
+ features.circular_scroll_enable = enable;
+}
+
+void cirque_pinnacle_configure_circular_scroll(uint8_t outer_ring_pct, uint8_t trigger_px, uint16_t trigger_ang, uint8_t wheel_clicks, bool left_handed) {
+ scroll.config.outer_ring_pct = outer_ring_pct;
+ scroll.config.trigger_px = trigger_px;
+ scroll.config.trigger_ang = trigger_ang;
+ scroll.config.wheel_clicks = wheel_clicks;
+ scroll.config.left_handed = left_handed;
+}
+#endif
+
+bool cirque_pinnacle_gestures(report_mouse_t* mouse_report, pinnacle_data_t touchData) {
+ bool suppress_mouse_update = false;
+
+#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE
+ circular_scroll_t scroll_report;
+ if (features.circular_scroll_enable) {
+ scroll_report = circular_scroll(touchData);
+ mouse_report->v = scroll_report.v;
+ mouse_report->h = scroll_report.h;
+ suppress_mouse_update = scroll_report.suppress_touch;
+ }
+#endif
+
+#ifdef CIRQUE_PINNACLE_TAP_ENABLE
+ if (features.tap_enable) {
+ *mouse_report = trackpad_tap(*mouse_report, touchData);
+ }
+#endif
+
+ return suppress_mouse_update;
+}
diff --git a/drivers/sensors/cirque_pinnacle_gestures.h b/drivers/sensors/cirque_pinnacle_gestures.h
new file mode 100644
index 0000000000..f39782b467
--- /dev/null
+++ b/drivers/sensors/cirque_pinnacle_gestures.h
@@ -0,0 +1,107 @@
+/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ * Copyright 2022 Daniel Kao <daniel.m.kao@gmail.com>
+ *
+ * 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 "cirque_pinnacle.h"
+#include "report.h"
+
+typedef struct {
+ bool tap_enable;
+ bool circular_scroll_enable;
+} cirque_pinnacle_features_t;
+
+#ifdef CIRQUE_PINNACLE_TAP_ENABLE
+# ifndef CIRQUE_PINNACLE_TAPPING_TERM
+# include "action.h"
+# include "action_tapping.h"
+# define CIRQUE_PINNACLE_TAPPING_TERM GET_TAPPING_TERM(KC_BTN1, &(keyrecord_t){})
+# endif
+# ifndef CIRQUE_PINNACLE_TOUCH_DEBOUNCE
+# define CIRQUE_PINNACLE_TOUCH_DEBOUNCE (CIRQUE_PINNACLE_TAPPING_TERM * 8)
+# endif
+
+typedef struct {
+ uint16_t timer;
+ bool touchDown;
+} trackpad_tap_context_t;
+
+/* Enable/disable tap gesture */
+void cirque_pinnacle_enable_tap(bool enable);
+#endif
+
+#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE
+typedef enum {
+ SCROLL_UNINITIALIZED,
+ SCROLL_DETECTING,
+ SCROLL_VALID,
+ NOT_SCROLL,
+} circular_scroll_status_t;
+
+typedef struct {
+ int8_t v;
+ int8_t h;
+ bool suppress_touch;
+} circular_scroll_t;
+
+typedef struct {
+ uint8_t outer_ring_pct; /* Width of outer ring, given as a percentage of the radius */
+ uint8_t trigger_px; /* Amount of movement before triggering scroll validation, in pixels 0~127 */
+ uint16_t trigger_ang; /* Angle required to validate scroll, in radians where pi = 32768 */
+ uint8_t wheel_clicks; /* How many clicks to report in a circle */
+ bool left_handed; /* Whether scrolling should be flipped for left handed use */
+} circular_scroll_config_t;
+
+typedef struct {
+ circular_scroll_config_t config;
+ circular_scroll_status_t state;
+ uint8_t mag;
+ int8_t x;
+ int8_t y;
+ uint16_t z;
+ bool axis;
+} circular_scroll_context_t;
+
+/* Enable/disable circular scroll gesture */
+void cirque_pinnacle_enable_circular_scroll(bool enable);
+
+/*
+ * Configure circular scroll gesture.
+ * Trackpad can be configured to act exclusively as a scroll wheel with outer_ring_pct = 0, trigger_px = 0, trigger_ang = 0.
+ * @param outer_ring_pct Width of outer ring from which to begin scroll validation, given as a percentage of the radius.
+ * @param trigger_px Amount of movement before triggering scroll validation. Expressed in pixels, trackpad coordinates are scaled to radius of 128 pixels for circular scroll.
+ * @param triger_ang Angle required to validate scroll, angle smaller than this will invalidate scroll. In radians where pi = 32768, 0 means movement towards center of trackpad, 16384 means movement perpendicular to center.
+ * @param wheel_clicks Number of scroll wheel clicks to report in a full rotation.
+ * @param left_handed Whether scrolling should be flipped for left-handed use.
+ */
+void cirque_pinnacle_configure_circular_scroll(uint8_t outer_ring_pct, uint8_t trigger_px, uint16_t trigger_ang, uint8_t wheel_clicks, bool left_handed);
+#endif
+
+#ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+/* Implementation in pointing_device_drivers.c */
+
+/* Enable/disable inertial cursor */
+void cirque_pinnacle_enable_cursor_glide(bool enable);
+
+/*
+ * Configure inertial cursor.
+ * @param trigger_px Movement required to trigger cursor glide, set this to non-zero if you have some amount of hover.
+ */
+void cirque_pinnacle_configure_cursor_glide(float trigger_px);
+#endif
+
+/* Process available gestures */
+bool cirque_pinnacle_gestures(report_mouse_t* mouse_report, pinnacle_data_t touchData);
diff --git a/drivers/sensors/cirque_pinnacle_i2c.c b/drivers/sensors/cirque_pinnacle_i2c.c
index 8a38f1dcea..b328dd9a7a 100644
--- a/drivers/sensors/cirque_pinnacle_i2c.c
+++ b/drivers/sensors/cirque_pinnacle_i2c.c
@@ -19,7 +19,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, NULL, 0, CIRQUE_PINNACLE_TIMEOUT);
if (i2c_readReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, data, count, CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
#ifdef CONSOLE_ENABLE
- dprintf("error right touchpad\n");
+ dprintf("error cirque_pinnacle i2c_readReg\n");
#endif
touchpad_init = false;
}
@@ -34,7 +34,7 @@ void RAP_Write(uint8_t address, uint8_t data) {
if (touchpad_init) {
if (i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
#ifdef CONSOLE_ENABLE
- dprintf("error right touchpad\n");
+ dprintf("error cirque_pinnacle i2c_writeReg\n");
#endif
touchpad_init = false;
}
diff --git a/drivers/sensors/cirque_pinnacle_regdefs.h b/drivers/sensors/cirque_pinnacle_regdefs.h
new file mode 100644
index 0000000000..993da1e757
--- /dev/null
+++ b/drivers/sensors/cirque_pinnacle_regdefs.h
@@ -0,0 +1,405 @@
+// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
+// based on https://github.com/cirque-corp/Cirque_Pinnacle_1CA027/tree/master/Additional_Examples
+// with modifications and changes for QMK
+// refer to documentation: Gen2 and Gen3 (Pinnacle ASIC) at https://www.cirque.com/gen2gen3-asic-details
+
+#pragma once
+
+// clang-format off
+
+#define HostReg__0 (0x00)
+#define HostReg__1 (0x01)
+#define HostReg__2 (0x02)
+#define HostReg__3 (0x03)
+#define HostReg__4 (0x04)
+#define HostReg__5 (0x05)
+#define HostReg__6 (0x06)
+#define HostReg__7 (0x07)
+#define HostReg__8 (0x08)
+#define HostReg__9 (0x09)
+#define HostReg__10 (0x0A)
+#define HostReg__11 (0x0B)
+#define HostReg__12 (0x0C)
+#define HostReg__13 (0x0D)
+#define HostReg__14 (0x0E)
+#define HostReg__15 (0x0F)
+#define HostReg__16 (0x10)
+#define HostReg__17 (0x11)
+#define HostReg__18 (0x12)
+#define HostReg__19 (0x13)
+#define HostReg__20 (0x14)
+#define HostReg__21 (0x15)
+#define HostReg__22 (0x16)
+#define HostReg__23 (0x17)
+#define HostReg__24 (0x18)
+#define HostReg__25 (0x19)
+#define HostReg__26 (0x1A)
+#define HostReg__27 (0x1B)
+#define HostReg__28 (0x1C)
+#define HostReg__29 (0x1D)
+#define HostReg__30 (0x1E)
+#define HostReg__31 (0x1F)
+
+// ---------------- Register Assignments -------------------------------------
+
+/*--------------------------------------------------------------------------*\
+ Chip ID / Version
+\*--------------------------------------------------------------------------*/
+// Chip ID Register
+#define HOSTREG__CHIPID HostReg__0
+
+// Chip Version Register
+#define HOSTREG__VERSION HostReg__1
+
+/*--------------------------------------------------------------------------*\
+ Status Register
+\*--------------------------------------------------------------------------*/
+// Status 1 Register -- MUST BE HOSTREG__2
+#define HOSTREG__STATUS1 HostReg__2
+# define HOSTREG__STATUS1__DATA_READY 0x04
+# define HOSTREG__STATUS1__COMMAND_COMPLETE 0x08
+#define HOSTREG__STATUS1_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ System Config Register
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__SYSCONFIG1 HostReg__3
+# define HOSTREG__SYSCONFIG1__RESET 0x01
+# define HOSTREG__SYSCONFIG1__STANDBY 0x02
+# define HOSTREG__SYSCONFIG1__AUTO_SLEEP 0x04
+# define HOSTREG__SYSCONFIG1__TRACK_DISABLE 0x08
+# define HOSTREG__SYSCONFIG1__ANYMEAS_ENABLE 0x10
+# define HOSTREG__SYSCONFIG1__GPIO_CTRL_ENABLE 0x20
+# define HOSTREG__SYSCONFIG1__WAKEUP_TOGGLE 0x40
+# define HOSTREG__SYSCONFIG1__FORCE_WAKEUP 0x80
+#define HOSTREG__SYSCONFIG1_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ Feed Config Registers
+\*--------------------------------------------------------------------------*/
+// Feed Config Register1
+#define HOSTREG__FEEDCONFIG1 HostReg__4
+# define HOSTREG__FEEDCONFIG1__FEED_ENABLE 0x01
+# define HOSTREG__FEEDCONFIG1__DATA_TYPE__REL0_ABS1 0x02
+# define HOSTREG__FEEDCONFIG1__FILTER_DISABLE 0x04
+# define HOSTREG__FEEDCONFIG1__X_AXIS_DISABLE 0x08
+# define HOSTREG__FEEDCONFIG1__Y_AXIS_DISABLE 0x10
+# define HOSTREG__FEEDCONFIG1__AXIS_FOR_Z__Y0_X1 0x20
+# define HOSTREG__FEEDCONFIG1__X_DATA_INVERT 0x40
+# define HOSTREG__FEEDCONFIG1__Y_DATA_INVERT 0x80
+#define HOSTREG__FEEDCONFIG1_DEFVAL 0x00
+
+// Feed Config Register2
+#define HOSTREG__FEEDCONFIG2 HostReg__5
+# define HOSTREG__FEEDCONFIG2__INTELLIMOUSE_MODE 0x01
+# define HOSTREG__FEEDCONFIG2__ALL_TAP_DISABLE 0x02
+# define HOSTREG__FEEDCONFIG2__SECONDARY_TAP_DISABLE 0x04
+# define HOSTREG__FEEDCONFIG2__SCROLL_DISABLE 0x08
+# define HOSTREG__FEEDCONFIG2__GLIDE_EXTEND_DISABLE 0x10
+# define HOSTREG__FEEDCONFIG2__PALM_BEFORE_Z_ENABLE 0x20
+# define HOSTREG__FEEDCONFIG2__BUTNS_46_SCROLL_5_MIDDLE 0x40
+# define HOSTREG__FEEDCONFIG2__SWAP_XY_RELATIVE 0x80
+#define HOSTREG__FEEDCONFIG2_DEFVAL 0x00
+
+// Feed Config Register3
+#define HOSTREG__FEEDCONFIG3 HostReg__6
+# define HOSTREG__FEEDCONFIG3__BTNS_456_TO_123_IN_REL 0x01
+# define HOSTREG__FEEDCONFIG3__DISABLE_CROSS_RATE_SMOOTHING 0x02
+# define HOSTREG__FEEDCONFIG3__DISABLE_PALM_NERD_MEAS 0x04
+# define HOSTREG__FEEDCONFIG3__DISABLE_NOISE_AVOIDANCE 0x08
+# define HOSTREG__FEEDCONFIG3__DISABLE_WRAP_LOCKOUT 0x10
+# define HOSTREG__FEEDCONFIG3__DISABLE_DYNAMIC_EMI_ADJUST 0x20
+# define HOSTREG__FEEDCONFIG3__DISABLE_HW_EMI_DETECT 0x40
+# define HOSTREG__FEEDCONFIG3__DISABLE_SW_EMI_DETECT 0x80
+#define HOSTREG__FEEDCONFIG3_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ Calibration Config
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__CALCONFIG1 HostReg__7
+# define HOSTREG__CALCONFIG1__CALIBRATE 0x01
+# define HOSTREG__CALCONFIG1__BACKGROUND_COMP_ENABLE 0x02
+# define HOSTREG__CALCONFIG1__NERD_COMP_ENABLE 0x04
+# define HOSTREG__CALCONFIG1__TRACK_ERROR_COMP_ENABLE 0x08
+# define HOSTREG__CALCONFIG1__TAP_COMP_ENABLE 0x10
+# define HOSTREG__CALCONFIG1__PALM_ERROR_COMP_ENABLE 0x20
+# define HOSTREG__CALCONFIG1__CALIBRATION_MATRIX_DISABLE 0x40
+# define HOSTREG__CALCONFIG1__FORCE_PRECALIBRATION_NOISE_CHECK 0x80
+#define HOSTREG__CALCONFIG1_DEFVAL (HOSTREG__CALCONFIG1__BACKGROUND_COMP_ENABLE | HOSTREG__CALCONFIG1__NERD_COMP_ENABLE | HOSTREG__CALCONFIG1__TRACK_ERROR_COMP_ENABLE | HOSTREG__CALCONFIG1__TAP_COMP_ENABLE | HOSTREG__CALCONFIG1__PALM_ERROR_COMP_ENABLE)
+
+/*--------------------------------------------------------------------------*\
+ PS2 Aux Control Register
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__PS2AUX_CTRL HostReg__8
+# define HOSTREG__PS2AUX_CTRL__CMD_PASSTHRU_ENABLE 0x01
+# define HOSTREG__PS2AUX_CTRL__SP_EXTENDED_MODE 0x02
+# define HOSTREG__PS2AUX_CTRL__GS_DISABLE 0x04
+# define HOSTREG__PS2AUX_CTRL__SP_DISABLE 0x08
+# define HOSTREG__PS2AUX_CTRL__GS_COORDINATE_DISABLE 0x10
+# define HOSTREG__PS2AUX_CTRL__SP_COORDINATE_DISABLE 0x20
+# define HOSTREG__PS2AUX_CTRL__DISABLE_AA00_DETECT 0x40
+# define HOSTREG__PS2AUX_CTRL__AUX_PRESENT 0x80
+#define HOSTREG__PR2AUX_CTRL_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ Sample Rate Value
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__SAMPLERATE HostReg__9
+# define HOSTREG__SAMPLERATE__10_SPS 0x0A
+# define HOSTREG__SAMPLERATE__20_SPS 0x14
+# define HOSTREG__SAMPLERATE__40_SPS 0x28
+# define HOSTREG__SAMPLERATE__60_SPS 0x3C
+# define HOSTREG__SAMPLERATE__80_SPS 0x50
+# define HOSTREG__SAMPLERATE__100_SPS 0x64
+# define HOSTREG__SAMPLERATE__200_SPS 0xC8 // 200sps not supported
+ // only for ps2 compatibility
+ // rate set to 100sps
+#define HOSTREG__SAMPLERATE_DEFVAL HOSTREG__SAMPLERATE__100_SPS
+
+/*--------------------------------------------------------------------------*\
+ Z Idle Value
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__ZIDLE HostReg__10
+#define HOSTREG__ZIDLE_DEFVAL 30 // 0x1E
+
+/*--------------------------------------------------------------------------*\
+ Z Scaler Value
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__ZSCALER HostReg__11
+#define HOSTREG__ZSCALER_DEFVAL 8 // 0x08
+
+/*--------------------------------------------------------------------------*\
+ Sleep Interval Value
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__SLEEP_INTERVAL HostReg__12
+#define HOSTREG__SLEEP_INTERVAL_DEFVAL 73 // 0x49
+
+/*--------------------------------------------------------------------------*\
+ Sleep Delay Value
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__SLEEP_DELAY HostReg__13
+#define HOSTREG__SLEEP_DELAY_DEFVAL 39 // 0x27
+
+/*--------------------------------------------------------------------------*\
+ Dynamic EMI Bad Channel Count Thresholds
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__DYNAMIC_EMI_ADJUST_THRESHOLD HostReg__14
+#define HOSTREG__DYNAMIC_EMI_ADJUST_THRESHOLD_DEFVAL 66 // 0x42
+
+/*--------------------------------------------------------------------------*\
+ Packet Registers
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__PACKETBYTE_0 HostReg__18
+#define HOSTREG__PACKETBYTE_1 HostReg__19
+#define HOSTREG__PACKETBYTE_2 HostReg__20
+#define HOSTREG__PACKETBYTE_3 HostReg__21
+#define HOSTREG__PACKETBYTE_4 HostReg__22
+#define HOSTREG__PACKETBYTE_5 HostReg__23
+
+/*--------------------------------------------------------------------------*\
+ Port A GPIO Control
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__PORTA_GPIO_CTRL HostReg__24
+#define HOSTREG__PORTA_GPIO_CTRL_DEFVAL 0xFF
+
+/*--------------------------------------------------------------------------*\
+ Port A GPIO Data
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__PORTA_GPIO_DATA HostReg__25
+#define HOSTREG__PORTA_GPIO_DATA_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ Port B GPIO Control And Data
+\*--------------------------------------------------------------------------*/
+
+#define HOSTREG__PORTB_GPIO_CTRL_DATA HostReg__26
+# define HOSTREG__PORTB_GPIO_DATA__PB0 0x01
+# define HOSTREG__PORTB_GPIO_DATA__PB1 0x02
+# define HOSTREG__PORTB_GPIO_DATA__PB2 0x04
+# define HOSTREG__PORTB_GPIO_CTRL__PB0 0x08
+# define HOSTREG__PORTB_GPIO_CTRL__PB1 0x10
+# define HOSTREG__PORTB_GPIO_CTRL__PB2 0x20
+# define HOSTREG__PORTB_GPIO_RSVD_0 0x40
+# define HOSTREG__PORTB_GPIO_READ1_WRITE0 0x80
+#define HOSTREG__PORTB_GPIO_CTRL_DATA_DEFVAL (HOSTREG__PORTB_GPIO_CTRL__PB0 | HOSTREG__PORTB_GPIO_CTRL__PB1 | HOSTREG__PORTB_GPIO_CTRL__PB2)
+
+/*--------------------------------------------------------------------------*\
+ Extended Register Access
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__EXT_REG_AXS_VALUE HostReg__27
+
+#define HOSTREG__EXT_REG_AXS_ADDR_HIGH HostReg__28
+#define HOSTREG__EXT_REG_AXS_ADDR_LOW HostReg__29
+
+#define HOSTREG__EXT_REG_AXS_CTRL HostReg__30
+# define HOSTREG__EREG_AXS__READ 0x01
+# define HOSTREG__EREG_AXS__WRITE 0x02
+# define HOSTREG__EREG_AXS__INC_ADDR_READ 0x04
+# define HOSTREG__EREG_AXS__INC_ADDR_WRITE 0x08
+# define HOSTREG__EREG_AXS__RSVD_3 0x10
+# define HOSTREG__EREG_AXS__RSVD_2 0x20
+# define HOSTREG__EREG_AXS__RSVD_1 0x40
+# define HOSTREG__EREG_AXS__RSVD_0 0x80
+
+#define HOSTREG__EXT_REG_AXS_VALUE_DEFVAL 0x00
+#define HOSTREG__EXT_REG_AXS_ADDR_HIGH_DEFVAL 0x00
+#define HOSTREG__EXT_REG_AXS_ADDR_LOW_DEFVAL 0x00
+#define HOSTREG__EXT_REG_AXS_CTRL_DEFVAL 0x00
+
+/*--------------------------------------------------------------------------*\
+ Product ID
+\*--------------------------------------------------------------------------*/
+#define HOSTREG__PRODUCT_ID HostReg__31
+
+
+
+//Some useful values
+#define I2C_ADDRESS_DEFAULT 0x2A
+#define FIRMWARE_ID 0x07
+#define FIRMWARE_VERSION 0x9D
+
+//Anymeas config options
+//First setting is HostReg 5. This sets toggle frequency (EF) and gain.
+//Gain is upper two bits (0xC0), frequency is lower 6 bits (0x3F)
+#define AnyMeas_AccumBits_ElecFreq HostReg__5
+# define ADCCNFG_ELEC_FREQ 0x3F /* Bit 4, 3, 2, 1, 0 */
+# define ADCCNFG_EF_0 0x02 // 500,000Hz
+# define ADCCNFG_EF_1 0x03 // 444,444Hz
+# define ADCCNFG_EF_2 0x04 // 400,000Hz
+# define ADCCNFG_EF_3 0x05 // 363,636Hz
+# define ADCCNFG_EF_4 0x06 // 333,333Hz
+# define ADCCNFG_EF_5 0x07 // 307,692Hz
+# define ADCCNFG_EF_6 0x09 // 267,000Hz
+# define ADCCNFG_EF_7 0x0B // 235,000Hz
+# define ADCCNFG_ACCUMBITSSELECT 0xC0 /* Bit 7, 6 */
+# define ADCCNFG_ACCBITS_17_14_0 0x00 //This is about 2x gain
+# define ADCCNFG_ACCBITS_17_15_1 0x40 //This is about 1.6x gain
+# define ADCCNFG_ACCBITS_17_2__80 0x80 //This is about 1.3x gain
+# define ADCCNFG_ACCBITS_17_2__C0 0xC0 //This is lowest gain
+//Note, all frequencies above are based on default 500ns aperture. If aperture is shorter the frequencies will be faster and if aperture is longer the frequencies will be slower.
+
+//Next is HostReg 6. This sets the sample length. There are four possible settings to bit length. All other settings are not normally used and should be a 0.
+#define AnyMeas_BitLength HostReg__6
+# define ADCCTRL_BIT_LENGTH 0x03 /* Bit 1, 0 */
+# define ADCCTRL_SAMPLES_32 0x00 //Note: this does not work.
+# define ADCCTRL_SAMPLES_128 0x01
+# define ADCCTRL_SAMPLES_256 0x02
+# define ADCCTRL_SAMPLES_512 0x03
+# define ADCCTRL_ENABLE 0x20 /* Bit 5 */
+# define ADCCTRL_INT_FLAG 0x40 /* Bit 6 */
+# define ADCCTRL_START_BUSY 0x80 /* Bit 7 */
+//The smaller the sample length the faster the measurement but the lower the SNR. For high SNR requirements 512 sample length is recommended. Alternatively, multiple 128 or 256 length measurements could be averaged.
+
+//Next is HostReg 7. This sets the sense mux. Pinnacle has 2 sense lines, Sense N and Sense P1. There is also a Sense P2 but it is not bonded out, it is only internal.
+//Signal on Sense N will be inverted from signal on Sense P1. Other than sign inversion, signal strength should be the same.
+#define AnyMeas_ADC_MuxControl HostReg__7
+# define ADCMUXCTRL_SENSEP1GATE 0x01 //Enables Sense P1. Can be combined with Sense N input or exclusivly Sense P1 alone.
+# define ADCMUXCTRL_SENSEP2GATE 0x02 //Not used.
+# define ADCMUXCTRL_SENSENGATE 0x04 //Enables Sense N. Can be combined with Sense P inputs or exclusivly Sense N alone.
+# define ADCMUXCTRL_REF0GATE 0x08 //This enables the RefCap0. This is a capacitor inside the chip that is roughly 0.25pF. It is also controlled with the toggle and polarity bits so those bits must be set properly as well in order to use it.
+# define ADCMUXCTRL_REF1GATE 0x10 //This enables the RefCap1. This is a capacitor inside the chip that is roughly 0.5pF. It is also controlled with the toggle and polarity bits so those bits must be set properly as well in order to use it.
+# define ADCMUXCTRL_OSCMEASEN 0x80 //this is a test mode for measuring the internal oscillator. It is for IC test only.
+
+//Next is HostReg 8. This contains various ADC config settings that are not likely to be used.
+#define AnyMeas_ADC_Config2 HostReg__8
+# define ADCCNFG2_ADC_CLK_SELECT 0x01 /* Bit 0 */ //If 0 use the standard 8Mhz clock. If 1 use a divide by 2, 4Mhz clock. Only used if extra slow toggle frequencies are required.
+# define ADCCNFG2_EMI_FLAG 0x02 /* Bit 1 */ //EMI flag threshold only used with internal FW. Not valid in anymeas mode.
+# define ADCCNFG2_EMI_FLAG_THRESHOLD_0 0x04 /* Bit 2 */ //EMI flag threshold only used with internal FW. Not valid in anymeas mode.
+# define ADCCNFG2_EMI_FLAG_THRESHOLD_1 0x08 /* Bit 3 */ //EMI flag threshold only used with internal FW. Not valid in anymeas mode.
+# define ADCCNFG2_DSX2_EXTEND 0x10 /* Bit 4 */ //extend one signal on the receive. Could also be helpful in situations where sensor cap is extremely high.
+# define ADCCNFG2_ETOGGLE_DELAY 0x20 /* Bit 5 */ //delay a bit before toggling electrodes. Could be helpful in situations where sensor cap is extremely high.
+
+//Next is HostReg 9. This sets the aperture length. Bottom 4 bits set the aperture width
+#define AnyMeas_ADC_AWidth HostReg__9
+# define ADCAWIDTH_AWIDTHMASK 0x0F
+# define ADCAWIDTH_APERTURE_OPEN 0x00 //does not work
+# define ADCAWIDTH_APERTURE_125NS 0x01 //does not work
+# define ADCAWIDTH_APERTURE_250NS 0x02
+# define ADCAWIDTH_APERTURE_375NS 0x03
+# define ADCAWIDTH_APERTURE_500NS 0x04
+# define ADCAWIDTH_APERTURE_625NS 0x05
+# define ADCAWIDTH_APERTURE_750NS 0x06
+# define ADCAWIDTH_APERTURE_875NS 0x07
+# define ADCAWIDTH_APERTURE_1000NS 0x08
+# define ADCAWIDTH_APERTURE_1125NS 0x09
+# define ADCAWIDTH_APERTURE_1250NS 0x0A
+# define ADCAWIDTH_APERTURE_1375NS 0x0B
+# define ADCAWIDTH_APERTURE_1500NS 0x0C
+# define ADCAWIDTH_APERTURE_1625NS 0x0D
+# define ADCAWIDTH_APERTURE_1750NS 0x0E
+# define ADCAWIDTH_APERTURE_1875NS 0x0F
+# define ADCAWIDTH_AWIDTHPLUSHALF 0x10
+# define ADCAWIDTH_AOPEN 0x20
+# define ADCAWIDTH_W2WAIT 0x40
+
+//next two registers give the high and low bytes to the 16 bit address where Pinnacle will pull the measurement data. Normally these addresses are within the base 32 registers.
+#define AnyMeas_pADCMeasInfoStart_High_Byte HostReg__10
+#define AnyMeas_pADCMeasInfoStart_Low_Byte HostReg__11
+
+//Next is the measurement index, this sets the measurement state machine to the start and should be a 0 at start.
+#define AnyMeas_MeasIndex HostReg__12
+# define ANYMEASSTATE_RESET_START 0x00
+# define ANYMEASSTATE_START_MEASUREMENT 0x01
+# define ANYMEASSTATE_WAIT_FOR_MEASUREMENT_AND_HOST 0x02
+
+//next is the state itself of the measurement, should always be 0.
+#define AnyMeas_State HostReg__13
+
+//next is the number of measurements. Use 0x80 to repeat the single measurement or repeat a number of measurements.
+//0x40 will turn the ADC off after measurements. This will result in longer startup time for a subsequent measurement, but lower idle power draw.
+#define AnyMeas_Control_NumMeas HostReg__14
+# define ANYMEAS_CONTROL__NUM_MEAS_MASK 0x3F
+# define ANYMEAS_CONTROL__ADC_POST_MEAS_PWR 0x40
+# define ANYMEAS_CONTROL__REPEAT 0x80
+
+//These are not used
+#define AnyMeas_pADCMeasInfo_High_Byte HostReg__15
+#define AnyMeas_pADCMeasInfo_Low_Byte HostReg__16
+
+//16 bit result of measurement will be found in these two registers.
+#define AnyMeas_Result_High_Byte HostReg__17
+#define AnyMeas_Result_Low_Byte HostReg__18
+
+// ---------------- Extended Register Assignments ----------------------------
+/*--------------------------------------------------------------------------*\
+ ADC Mux Control
+\*--------------------------------------------------------------------------*/
+#define EXTREG__ADCMUX_CTRL 0x00EB
+# define EXTREG__ADCMUX_CTRL__SNSP_ENABLE 0x01
+# define EXTREG__ADCMUX_CTRL__SNSN_ENABLE 0x04
+
+/*--------------------------------------------------------------------------*\
+ Timer Reload Registers
+\*--------------------------------------------------------------------------*/
+#define EXTREG__PACKET_TIMER_RELOAD 0x019F
+#define EXTREG__TRACK_TIMER_RELOAD 0x019E
+// These two registers should have matching content.
+# define EXTREG__TIMER_RELOAD__300_SPS 0x06
+# define EXTREG__TIMER_RELOAD__200_SPS 0x09
+# define EXTREG__TIMER_RELOAD__100_SPS 0x13
+
+/*--------------------------------------------------------------------------*\
+ Track ADC Config
+\*--------------------------------------------------------------------------*/
+#define EXTREG__TRACK_ADCCONFIG 0x0187
+// ADC-attenuation settings (held in BIT_7 and BIT_6)
+// 1X = most sensitive, 4X = least sensitive
+# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK 0x3F
+# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_1X 0x00
+# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X 0x40
+# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_3X 0x80
+# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_4X 0xC0
+#define EXTREG__TRACK_ADCCONFIG_DEFVAL 0x4E
+
+
+/*--------------------------------------------------------------------------*\
+ Tune Edge Sensitivity
+\*--------------------------------------------------------------------------*/
+// These registers are not detailed in any publically available documentation
+// Names inferred from debug prints in https://github.com/cirque-corp/Cirque_Pinnacle_1CA027/blob/master/Circular_Trackpad
+#define EXTREG__XAXIS_WIDEZMIN 0x0149
+#define EXTREG__YAXIS_WIDEZMIN 0x0168
+#define EXTREG__XAXIS_WIDEZMIN_DEFVAL 0x06
+#define EXTREG__YAXIS_WIDEZMIN_DEFVAL 0x05
+
+// clang-format on
diff --git a/drivers/sensors/cirque_pinnacle_spi.c b/drivers/sensors/cirque_pinnacle_spi.c
index 34c77df07b..bd980fc863 100644
--- a/drivers/sensors/cirque_pinnacle_spi.c
+++ b/drivers/sensors/cirque_pinnacle_spi.c
@@ -25,7 +25,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
}
} else {
#ifdef CONSOLE_ENABLE
- dprintf("error right touchpad\n");
+ dprintf("error cirque_pinnacle spi_start read\n");
#endif
touchpad_init = false;
}
@@ -43,7 +43,7 @@ void RAP_Write(uint8_t address, uint8_t data) {
spi_write(data);
} else {
#ifdef CONSOLE_ENABLE
- dprintf("error right touchpad\n");
+ dprintf("error cirque_pinnacle spi_start write\n");
#endif
touchpad_init = false;
}
diff --git a/drivers/sensors/pimoroni_trackball.c b/drivers/sensors/pimoroni_trackball.c
index 333e017a06..88a351316b 100644
--- a/drivers/sensors/pimoroni_trackball.c
+++ b/drivers/sensors/pimoroni_trackball.c
@@ -95,16 +95,3 @@ int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_di
uint16_t magnitude = (scale * offset * offset * precision) >> 7;
return isnegative ? -(int16_t)(magnitude) : (int16_t)(magnitude);
}
-
-void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset) {
- if (*offset > 127) {
- *mouse = 127;
- *offset -= 127;
- } else if (*offset < -127) {
- *mouse = -127;
- *offset += 127;
- } else {
- *mouse = *offset;
- *offset = 0;
- }
-}
diff --git a/drivers/sensors/pimoroni_trackball.h b/drivers/sensors/pimoroni_trackball.h
index e20ee748a7..749f381bbd 100644
--- a/drivers/sensors/pimoroni_trackball.h
+++ b/drivers/sensors/pimoroni_trackball.h
@@ -52,7 +52,6 @@ typedef struct {
void pimoroni_trackball_device_init(void);
void pimoroni_trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
-void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset);
uint16_t pimoroni_trackball_get_cpi(void);
void pimoroni_trackball_set_cpi(uint16_t cpi);
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
diff --git a/drivers/sensors/pmw3360.c b/drivers/sensors/pmw3360.c
index 5f4d17a3f0..2c6d91d588 100644
--- a/drivers/sensors/pmw3360.c
+++ b/drivers/sensors/pmw3360.c
@@ -1,291 +1,294 @@
-/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- * Copyright 2022 Ulrich Spörlein
- *
- * 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 "spi_master.h"
-#include "pmw3360.h"
-#include "wait.h"
-#include "debug.h"
-#include "print.h"
-#include "pmw3360_firmware.h"
-
-// Registers
-// clang-format off
-#define REG_Product_ID 0x00
-#define REG_Revision_ID 0x01
-#define REG_Motion 0x02
-#define REG_Delta_X_L 0x03
-#define REG_Delta_X_H 0x04
-#define REG_Delta_Y_L 0x05
-#define REG_Delta_Y_H 0x06
-#define REG_SQUAL 0x07
-#define REG_Raw_Data_Sum 0x08
-#define REG_Maximum_Raw_data 0x09
-#define REG_Minimum_Raw_data 0x0a
-#define REG_Shutter_Lower 0x0b
-#define REG_Shutter_Upper 0x0c
-#define REG_Control 0x0d
-#define REG_Config1 0x0f
-#define REG_Config2 0x10
-#define REG_Angle_Tune 0x11
-#define REG_Frame_Capture 0x12
-#define REG_SROM_Enable 0x13
-#define REG_Run_Downshift 0x14
-#define REG_Rest1_Rate_Lower 0x15
-#define REG_Rest1_Rate_Upper 0x16
-#define REG_Rest1_Downshift 0x17
-#define REG_Rest2_Rate_Lower 0x18
-#define REG_Rest2_Rate_Upper 0x19
-#define REG_Rest2_Downshift 0x1a
-#define REG_Rest3_Rate_Lower 0x1b
-#define REG_Rest3_Rate_Upper 0x1c
-#define REG_Observation 0x24
-#define REG_Data_Out_Lower 0x25
-#define REG_Data_Out_Upper 0x26
-#define REG_Raw_Data_Dump 0x29
-#define REG_SROM_ID 0x2a
-#define REG_Min_SQ_Run 0x2b
-#define REG_Raw_Data_Threshold 0x2c
-#define REG_Config5 0x2f
-#define REG_Power_Up_Reset 0x3a
-#define REG_Shutdown 0x3b
-#define REG_Inverse_Product_ID 0x3f
-#define REG_LiftCutoff_Tune3 0x41
-#define REG_Angle_Snap 0x42
-#define REG_LiftCutoff_Tune1 0x4a
-#define REG_Motion_Burst 0x50
-#define REG_LiftCutoff_Tune_Timeout 0x58
-#define REG_LiftCutoff_Tune_Min_Length 0x5a
-#define REG_SROM_Load_Burst 0x62
-#define REG_Lift_Config 0x63
-#define REG_Raw_Data_Burst 0x64
-#define REG_LiftCutoff_Tune2 0x65
-
-#define CPI_STEP 100
-// clang-format on
-
-// limits to 0--119, resulting in a CPI range of 100 -- 12000 (as only steps of 100 are possible).
-#ifndef MAX_CPI
-# define MAX_CPI 0x77
-#endif
-
-static const pin_t pins[] = PMW3360_CS_PINS;
-#define NUMBER_OF_SENSORS (sizeof(pins) / sizeof(pin_t))
-
-// per-sensor driver state
-static bool _inBurst[NUMBER_OF_SENSORS] = {0};
-
-#ifdef CONSOLE_ENABLE
-void print_byte(uint8_t byte) {
- dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0'));
-}
-#endif
-#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
-
-bool pmw3360_spi_start(int8_t index) {
- bool status = spi_start(pins[index], PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
- // tNCS-SCLK, 120ns
- wait_us(1);
- return status;
-}
-
-spi_status_t pmw3360_write(int8_t index, uint8_t reg_addr, uint8_t data) {
- pmw3360_spi_start(index);
-
- if (reg_addr != REG_Motion_Burst) {
- _inBurst[index] = false;
- }
-
- // send address of the register, with MSBit = 1 to indicate it's a write
- spi_status_t status = spi_write(reg_addr | 0x80);
- status = spi_write(data);
-
- // tSCLK-NCS for write operation is 35us
- wait_us(35);
- spi_stop();
-
- // tSWW/tSWR (=180us) minus tSCLK-NCS. Could be shortened, but it looks like a safe lower bound
- wait_us(145);
- return status;
-}
-
-uint8_t pmw3360_read(int8_t index, uint8_t reg_addr) {
- pmw3360_spi_start(index);
- // send adress of the register, with MSBit = 0 to indicate it's a read
- spi_write(reg_addr & 0x7f);
- // tSRAD (=160us)
- wait_us(160);
- uint8_t data = spi_read();
-
- // tSCLK-NCS for read operation is 120ns
- wait_us(1);
- spi_stop();
-
- // tSRW/tSRR (=20us) minus tSCLK-NCS
- wait_us(19);
- return data;
-}
-
-bool pmw3360_check_signature(int8_t index) {
- uint8_t pid = pmw3360_read(index, REG_Product_ID);
- uint8_t iv_pid = pmw3360_read(index, REG_Inverse_Product_ID);
- uint8_t SROM_ver = pmw3360_read(index, REG_SROM_ID);
- return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04
-}
-
-void pmw3360_upload_firmware(int8_t index) {
- // Datasheet claims we need to disable REST mode first, but during startup
- // it's already disabled and we're not turning it on ...
- // pmw3360_write(index, REG_Config2, 0x00); // disable REST mode
- pmw3360_write(index, REG_SROM_Enable, 0x1d);
-
- wait_ms(10);
-
- pmw3360_write(index, REG_SROM_Enable, 0x18);
-
- pmw3360_spi_start(index);
- spi_write(REG_SROM_Load_Burst | 0x80);
- wait_us(15);
-
- for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
- spi_write(pgm_read_byte(firmware_data + i));
-#ifndef PMW3360_FIRMWARE_UPLOAD_FAST
- wait_us(15);
-#endif
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2022 Ulrich Spörlein (@uqs)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "pmw33xx_common.h"
+#include "progmem.h"
+
+extern const size_t pmw33xx_number_of_sensors;
+
+uint16_t pmw33xx_get_cpi(uint8_t sensor) {
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return 0;
}
- wait_us(200);
- pmw3360_read(index, REG_SROM_ID);
- pmw3360_write(index, REG_Config2, 0x00);
+ uint8_t cpival = pmw33xx_read(sensor, REG_Config1);
+ return (uint16_t)((cpival + 1) & 0xFF) * PMW33XX_CPI_STEP;
}
-bool pmw3360_init(int8_t index) {
- if (index >= NUMBER_OF_SENSORS) {
- return false;
+void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) {
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return;
}
- spi_init();
- // power up, need to first drive NCS high then low.
- // the datasheet does not say for how long, 40us works well in practice.
- pmw3360_spi_start(index);
- wait_us(40);
- spi_stop();
- wait_us(40);
- pmw3360_write(index, REG_Power_Up_Reset, 0x5a);
- wait_ms(50);
-
- // read registers and discard
- pmw3360_read(index, REG_Motion);
- pmw3360_read(index, REG_Delta_X_L);
- pmw3360_read(index, REG_Delta_X_H);
- pmw3360_read(index, REG_Delta_Y_L);
- pmw3360_read(index, REG_Delta_Y_H);
-
- pmw3360_upload_firmware(index);
-
- spi_stop();
-
- wait_ms(10);
- pmw3360_set_cpi(PMW3360_CPI);
-
- wait_ms(1);
-
- pmw3360_write(index, REG_Config2, 0x00);
-
- pmw3360_write(index, REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -127, 127));
-
- pmw3360_write(index, REG_Lift_Config, PMW3360_LIFTOFF_DISTANCE);
-
- bool init_success = pmw3360_check_signature(index);
-#ifdef CONSOLE_ENABLE
- if (init_success) {
- dprintf("pmw3360 signature verified");
- } else {
- dprintf("pmw3360 signature verification failed!");
- }
-#endif
-
- return init_success;
+ uint8_t cpival = CONSTRAIN((cpi / PMW33XX_CPI_STEP) - 1, 0, (PMW33XX_CPI_MAX / PMW33XX_CPI_STEP) - 1U);
+ pmw33xx_write(sensor, REG_Config1, cpival);
}
-// Only support reading the value from sensor #0, no one is using this anyway.
-uint16_t pmw3360_get_cpi(void) {
- uint8_t cpival = pmw3360_read(0, REG_Config1);
- return (uint16_t)((cpival + 1) & 0xFF) * CPI_STEP;
-}
-
-// Write same CPI to all sensors.
-void pmw3360_set_cpi(uint16_t cpi) {
- uint8_t cpival = constrain((cpi / CPI_STEP) - 1, 0, MAX_CPI);
- for (size_t i = 0; i < NUMBER_OF_SENSORS; i++) {
- pmw3360_write(i, REG_Config1, cpival);
- }
-}
+// PID, Inverse PID, SROM version
+const uint8_t pmw33xx_firmware_signature[3] PROGMEM = {0x42, 0xBD, 0x04};
-report_pmw3360_t pmw3360_read_burst(int8_t index) {
- report_pmw3360_t report = {0};
- if (index >= NUMBER_OF_SENSORS) {
- return report;
- }
-
- if (!_inBurst[index]) {
-#ifdef CONSOLE_ENABLE
- dprintf("burst on for index %d", index);
-#endif
- pmw3360_write(index, REG_Motion_Burst, 0x00);
- _inBurst[index] = true;
- }
-
- pmw3360_spi_start(index);
- spi_write(REG_Motion_Burst);
- wait_us(35); // waits for tSRAD_MOTBR
-
- report.motion = spi_read();
- spi_read(); // skip Observation
- // delta registers
- report.dx = spi_read();
- report.mdx = spi_read();
- report.dy = spi_read();
- report.mdy = spi_read();
-
- if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
- _inBurst[index] = false;
- }
-
- spi_stop();
-
-#ifdef CONSOLE_ENABLE
- if (debug_mouse) {
- print_byte(report.motion);
- print_byte(report.dx);
- print_byte(report.mdx);
- print_byte(report.dy);
- print_byte(report.mdy);
- dprintf("\n");
- }
-#endif
-
- report.isMotion = (report.motion & 0x80) != 0;
- report.isOnSurface = (report.motion & 0x08) == 0;
- report.dx |= (report.mdx << 8);
- report.dx = report.dx * -1;
- report.dy |= (report.mdy << 8);
- report.dy = report.dy * -1;
-
- return report;
-}
+// Firmware Blob for PMW3360
+// clang-format off
+const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM = {
+ 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF,
+ 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5,
+ 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79,
+ 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E,
+ 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B,
+ 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4,
+ 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF,
+ 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE,
+ 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF,
+ 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89,
+ 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5,
+ 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66,
+ 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4,
+ 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18,
+ 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A,
+ 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB,
+ 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3,
+ 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05,
+ 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8,
+ 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23,
+ 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C,
+ 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A,
+ 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1,
+ 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6,
+ 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8,
+ 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76,
+ 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5,
+ 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD,
+ 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5,
+ 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF,
+ 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8,
+ 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08,
+ 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42,
+ 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A,
+ 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11,
+ 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80,
+ 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69,
+ 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8,
+ 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72,
+ 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97,
+ 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F,
+ 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC,
+ 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E,
+ 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE,
+ 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30,
+ 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71,
+ 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2,
+ 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68,
+ 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7,
+ 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3,
+ 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67,
+ 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF,
+ 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95,
+ 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A,
+ 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8,
+ 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77,
+ 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08,
+ 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31,
+ 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A,
+ 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF,
+ 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62,
+ 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC,
+ 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99,
+ 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8,
+ 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D,
+ 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78,
+ 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B,
+ 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85,
+ 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07,
+ 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9,
+ 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B,
+ 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26,
+ 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5,
+ 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F,
+ 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97,
+ 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE,
+ 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72,
+ 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D,
+ 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D,
+ 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26,
+ 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7,
+ 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1,
+ 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1,
+ 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF,
+ 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9,
+ 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2,
+ 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F,
+ 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D,
+ 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E,
+ 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75,
+ 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F,
+ 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8,
+ 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E,
+ 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED,
+ 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD,
+ 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8,
+ 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88,
+ 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57,
+ 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA,
+ 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2,
+ 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7,
+ 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99,
+ 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A,
+ 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D,
+ 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF,
+ 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17,
+ 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF,
+ 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A,
+ 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62,
+ 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA,
+ 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF,
+ 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66,
+ 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5,
+ 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5,
+ 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF,
+ 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69,
+ 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F,
+ 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79,
+ 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A,
+ 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA,
+ 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50,
+ 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E,
+ 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5,
+ 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2,
+ 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54,
+ 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61,
+ 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8,
+ 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A,
+ 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A,
+ 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23,
+ 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B,
+ 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB,
+ 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4,
+ 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81,
+ 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F,
+ 0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD,
+ 0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C,
+ 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19,
+ 0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4,
+ 0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6,
+ 0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49,
+ 0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11,
+ 0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44,
+ 0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1,
+ 0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C,
+ 0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A,
+ 0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08,
+ 0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58,
+ 0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE,
+ 0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B,
+ 0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF,
+ 0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65,
+ 0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67,
+ 0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C,
+ 0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7,
+ 0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3,
+ 0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33,
+ 0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A,
+ 0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D,
+ 0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4,
+ 0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E,
+ 0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96,
+ 0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68,
+ 0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84,
+ 0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC,
+ 0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80,
+ 0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9,
+ 0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B,
+ 0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45,
+ 0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40,
+ 0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97,
+ 0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D,
+ 0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C,
+ 0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E,
+ 0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76,
+ 0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7,
+ 0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73,
+ 0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF,
+ 0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6,
+ 0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8,
+ 0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F,
+ 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82,
+ 0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28,
+ 0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42,
+ 0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39,
+ 0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D,
+ 0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1,
+ 0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77,
+ 0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32,
+ 0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84,
+ 0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0,
+ 0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA,
+ 0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5,
+ 0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17,
+ 0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0,
+ 0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B,
+ 0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45,
+ 0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28,
+ 0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9,
+ 0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E,
+ 0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70,
+ 0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA,
+ 0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30,
+ 0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF,
+ 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51,
+ 0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3,
+ 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46,
+ 0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C,
+ 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12,
+ 0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC,
+ 0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED,
+ 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8,
+ 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76,
+ 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82,
+ 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B,
+ 0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98,
+ 0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA,
+ 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC,
+ 0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F,
+ 0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43,
+ 0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58,
+ 0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D,
+ 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49,
+ 0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE,
+ 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21,
+ 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16,
+ 0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6,
+ 0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0,
+ 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D,
+ 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0,
+ 0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2,
+ 0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4,
+ 0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22,
+ 0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9,
+ 0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA,
+ 0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C,
+ 0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3,
+ 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2,
+ 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85,
+ 0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59,
+ 0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC,
+ 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63,
+ 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1,
+ 0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC,
+ 0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58,
+ 0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E,
+ 0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19,
+ 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56,
+ 0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25,
+ 0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4,
+ 0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4,
+ 0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A,
+ 0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0,
+ 0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C,
+ 0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20,
+ 0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B
+};
diff --git a/drivers/sensors/pmw3360.h b/drivers/sensors/pmw3360.h
index 3aa8ed0ed8..8aa70bd427 100644
--- a/drivers/sensors/pmw3360.h
+++ b/drivers/sensors/pmw3360.h
@@ -1,79 +1,73 @@
-/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- *
- * 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/>.
- */
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2022 Ulrich Spörlein (@uqs)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
-#ifndef PMW3360_CPI
-# define PMW3360_CPI 1600
+#if !defined(PMW33XX_CPI)
+# define PMW33XX_CPI 1600U
#endif
-#ifndef PMW3360_CLOCK_SPEED
-# define PMW3360_CLOCK_SPEED 2000000
-#endif
-
-#ifndef PMW3360_SPI_LSBFIRST
-# define PMW3360_SPI_LSBFIRST false
-#endif
-
-#ifndef PMW3360_SPI_MODE
-# define PMW3360_SPI_MODE 3
-#endif
-
-#ifndef PMW3360_SPI_DIVISOR
-# ifdef __AVR__
-# define PMW3360_SPI_DIVISOR (F_CPU / PMW3360_CLOCK_SPEED)
-# else
-# define PMW3360_SPI_DIVISOR 64
-# endif
-#endif
-
-#ifndef PMW3360_LIFTOFF_DISTANCE
-# define PMW3360_LIFTOFF_DISTANCE 0x02
-#endif
-
-#ifndef ROTATIONAL_TRANSFORM_ANGLE
-# define ROTATIONAL_TRANSFORM_ANGLE 0x00
-#endif
-
-// Support single and plural spellings
-#ifndef PMW3360_CS_PINS
-# ifndef PMW3360_CS_PIN
-# error "No chip select pin defined -- missing PMW3360_CS_PIN or PMW3360_CS_PINS"
-# else
-# define PMW3360_CS_PINS \
- { PMW3360_CS_PIN }
-# endif
-#endif
+#define PMW33XX_CPI_STEP 100
+#define PMW33XX_CPI_MIN 100
+#define PMW33XX_CPI_MAX 12000
-typedef struct {
- int8_t motion;
- bool isMotion; // True if a motion is detected.
- bool isOnSurface; // True when a chip is on a surface
- int16_t dx; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
- int8_t mdx;
- int16_t dy; // displacement on y directions.
- int8_t mdy;
-} report_pmw3360_t;
+#define PMW33XX_FIRMWARE_LENGTH 4094
-bool pmw3360_init(int8_t index);
-uint16_t pmw3360_get_cpi(void);
-void pmw3360_set_cpi(uint16_t cpi);
-/* Reads and clears the current delta values on the sensor */
-report_pmw3360_t pmw3360_read_burst(int8_t index);
+// PMW3360 register addresses
+// clang-format off
+#define REG_Product_ID 0x00
+#define REG_Revision_ID 0x01
+#define REG_Motion 0x02
+#define REG_Delta_X_L 0x03
+#define REG_Delta_X_H 0x04
+#define REG_Delta_Y_L 0x05
+#define REG_Delta_Y_H 0x06
+#define REG_SQUAL 0x07
+#define REG_Raw_Data_Sum 0x08
+#define REG_Maximum_Raw_data 0x09
+#define REG_Minimum_Raw_data 0x0a
+#define REG_Shutter_Lower 0x0b
+#define REG_Shutter_Upper 0x0c
+#define REG_Control 0x0d
+#define REG_Config1 0x0f
+#define REG_Config2 0x10
+#define REG_Angle_Tune 0x11
+#define REG_Frame_Capture 0x12
+#define REG_SROM_Enable 0x13
+#define REG_Run_Downshift 0x14
+#define REG_Rest1_Rate_Lower 0x15
+#define REG_Rest1_Rate_Upper 0x16
+#define REG_Rest1_Downshift 0x17
+#define REG_Rest2_Rate_Lower 0x18
+#define REG_Rest2_Rate_Upper 0x19
+#define REG_Rest2_Downshift 0x1a
+#define REG_Rest3_Rate_Lower 0x1b
+#define REG_Rest3_Rate_Upper 0x1c
+#define REG_Observation 0x24
+#define REG_Data_Out_Lower 0x25
+#define REG_Data_Out_Upper 0x26
+#define REG_Raw_Data_Dump 0x29
+#define REG_SROM_ID 0x2a
+#define REG_Min_SQ_Run 0x2b
+#define REG_Raw_Data_Threshold 0x2c
+#define REG_Config5 0x2f
+#define REG_Power_Up_Reset 0x3a
+#define REG_Shutdown 0x3b
+#define REG_Inverse_Product_ID 0x3f
+#define REG_LiftCutoff_Tune3 0x41
+#define REG_Angle_Snap 0x42
+#define REG_LiftCutoff_Tune1 0x4a
+#define REG_Motion_Burst 0x50
+#define REG_LiftCutoff_Tune_Timeout 0x58
+#define REG_LiftCutoff_Tune_Min_Length 0x5a
+#define REG_SROM_Load_Burst 0x62
+#define REG_Lift_Config 0x63
+#define REG_Raw_Data_Burst 0x64
+#define REG_LiftCutoff_Tune2 0x65
+// clang-format on
diff --git a/drivers/sensors/pmw3360_firmware.h b/drivers/sensors/pmw3360_firmware.h
deleted file mode 100644
index ed9fda5a75..0000000000
--- a/drivers/sensors/pmw3360_firmware.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- *
- * 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 "progmem.h"
-
-// PID, Inverse PID, SROM version
-const uint8_t firmware_signature[] PROGMEM = {0x42, 0xBD, 0x04};
-
-#define FIRMWARE_LENGTH 4094
-
-// Firmware Blob foor PMW3360
-
-// clang-format off
-const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
- 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF,
- 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5,
- 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79,
- 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E,
- 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B,
- 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4,
- 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF,
- 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE,
- 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF,
- 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89,
- 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5,
- 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66,
- 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4,
- 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18,
- 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A,
- 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB,
- 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3,
- 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05,
- 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8,
- 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23,
- 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C,
- 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A,
- 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1,
- 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6,
- 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8,
- 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76,
- 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5,
- 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD,
- 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5,
- 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF,
- 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8,
- 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08,
- 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42,
- 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A,
- 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11,
- 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80,
- 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69,
- 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8,
- 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72,
- 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97,
- 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F,
- 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC,
- 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E,
- 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE,
- 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30,
- 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71,
- 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2,
- 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68,
- 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7,
- 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3,
- 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67,
- 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF,
- 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95,
- 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A,
- 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8,
- 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77,
- 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08,
- 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31,
- 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A,
- 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF,
- 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62,
- 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC,
- 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99,
- 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8,
- 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D,
- 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78,
- 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B,
- 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85,
- 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07,
- 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9,
- 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B,
- 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26,
- 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5,
- 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F,
- 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97,
- 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE,
- 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72,
- 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D,
- 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D,
- 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26,
- 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7,
- 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1,
- 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1,
- 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF,
- 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9,
- 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2,
- 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F,
- 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D,
- 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E,
- 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75,
- 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F,
- 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8,
- 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E,
- 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED,
- 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD,
- 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8,
- 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88,
- 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57,
- 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA,
- 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2,
- 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7,
- 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99,
- 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A,
- 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D,
- 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF,
- 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17,
- 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF,
- 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A,
- 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62,
- 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA,
- 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF,
- 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66,
- 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5,
- 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5,
- 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF,
- 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69,
- 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F,
- 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79,
- 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A,
- 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA,
- 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50,
- 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E,
- 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5,
- 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2,
- 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54,
- 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61,
- 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8,
- 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A,
- 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A,
- 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23,
- 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B,
- 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB,
- 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4,
- 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81,
- 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F,
- 0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD,
- 0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C,
- 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19,
- 0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4,
- 0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6,
- 0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49,
- 0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11,
- 0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44,
- 0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1,
- 0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C,
- 0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A,
- 0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08,
- 0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58,
- 0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE,
- 0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B,
- 0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF,
- 0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65,
- 0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67,
- 0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C,
- 0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7,
- 0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3,
- 0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33,
- 0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A,
- 0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D,
- 0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4,
- 0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E,
- 0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96,
- 0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68,
- 0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84,
- 0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC,
- 0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80,
- 0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9,
- 0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B,
- 0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45,
- 0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40,
- 0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97,
- 0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D,
- 0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C,
- 0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E,
- 0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76,
- 0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7,
- 0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73,
- 0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF,
- 0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6,
- 0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8,
- 0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F,
- 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82,
- 0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28,
- 0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42,
- 0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39,
- 0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D,
- 0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1,
- 0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77,
- 0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32,
- 0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84,
- 0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0,
- 0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA,
- 0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5,
- 0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17,
- 0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0,
- 0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B,
- 0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45,
- 0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28,
- 0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9,
- 0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E,
- 0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70,
- 0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA,
- 0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30,
- 0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF,
- 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51,
- 0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3,
- 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46,
- 0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C,
- 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12,
- 0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC,
- 0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED,
- 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8,
- 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76,
- 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82,
- 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B,
- 0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98,
- 0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA,
- 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC,
- 0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F,
- 0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43,
- 0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58,
- 0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D,
- 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49,
- 0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE,
- 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21,
- 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16,
- 0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6,
- 0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0,
- 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D,
- 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0,
- 0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2,
- 0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4,
- 0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22,
- 0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9,
- 0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA,
- 0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C,
- 0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3,
- 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2,
- 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85,
- 0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59,
- 0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC,
- 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63,
- 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1,
- 0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC,
- 0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58,
- 0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E,
- 0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19,
- 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56,
- 0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25,
- 0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4,
- 0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4,
- 0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A,
- 0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0,
- 0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C,
- 0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20,
- 0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B
-};
diff --git a/drivers/sensors/pmw3389.c b/drivers/sensors/pmw3389.c
index 828dafa134..cba94d6c65 100644
--- a/drivers/sensors/pmw3389.c
+++ b/drivers/sensors/pmw3389.c
@@ -1,294 +1,314 @@
-/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- *
- * 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/>.
- */
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
-#include "spi_master.h"
-#include "pmw3389.h"
-#include "wait.h"
-#include "debug.h"
-#include "print.h"
-#include "pmw3389_firmware.h"
+#include "pmw33xx_common.h"
+#include "progmem.h"
-// Registers
-// clang-format off
-#define REG_Product_ID 0x00
-#define REG_Revision_ID 0x01
-#define REG_Motion 0x02
-#define REG_Delta_X_L 0x03
-#define REG_Delta_X_H 0x04
-#define REG_Delta_Y_L 0x05
-#define REG_Delta_Y_H 0x06
-#define REG_SQUAL 0x07
-#define REG_RawData_Sum 0x08
-#define REG_Maximum_RawData 0x09
-#define REG_Minimum_RawData 0x0a
-#define REG_Shutter_Lower 0x0b
-#define REG_Shutter_Upper 0x0c
-#define REG_Ripple_Control 0x0d
-#define REG_Resolution_L 0x0e
-#define REG_Resolution_H 0x0f
-#define REG_Config2 0x10
-#define REG_Angle_Tune 0x11
-#define REG_Frame_Capture 0x12
-#define REG_SROM_Enable 0x13
-#define REG_Run_Downshift 0x14
-#define REG_Rest1_Rate_Lower 0x15
-#define REG_Rest1_Rate_Upper 0x16
-#define REG_Rest1_Downshift 0x17
-#define REG_Rest2_Rate_Lower 0x18
-#define REG_Rest2_Rate_Upper 0x19
-#define REG_Rest2_Downshift 0x1a
-#define REG_Rest3_Rate_Lower 0x1b
-#define REG_Rest3_Rate_Upper 0x1c
-#define REG_Observation 0x24
-#define REG_Data_Out_Lower 0x25
-#define REG_Data_Out_Upper 0x26
-#define REG_SROM_ID 0x2a
-#define REG_Min_SQ_Run 0x2b
-#define REG_RawData_Threshold 0x2c
-#define REG_Control2 0x2d
-#define REG_Config5_L 0x2e
-#define REG_Config5_H 0x2f
-#define REG_Power_Up_Reset 0X3a
-#define REG_Shutdown 0x3b
-#define REG_Inverse_Product_ID 0x3f
-#define REG_LiftCutoff_Cal3 0x41
-#define REG_Angle_Snap 0x42
-#define REG_LiftCutoff_Cal1 0x4a
-#define REG_Motion_Burst 0x50
-#define REG_SROM_Load_Burst 0x62
-#define REG_Lift_Config 0x63
-#define REG_RawData_Burst 0x64
-#define REG_LiftCutoff_Cal2 0x65
-#define REG_LiftCutoff_Cal_Timeout 0x71
-#define REG_LiftCutoff_Cal_Min_Length 0x72
-#define REG_PWM_Period_Cnt 0x73
-#define REG_PWM_Width_Cnt 0x74
-
-#define CPI_STEP 50
-// clang-format on
-
-// limits to 0--319, resulting in a CPI range of 50 -- 16000 (as only steps of 50 are possible).
-#ifndef MAX_CPI
-# define MAX_CPI 0x013f
-#endif
-
-bool _inBurst = false;
-
-#ifdef CONSOLE_ENABLE
-void print_byte(uint8_t byte) {
- dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0'));
-}
-#endif
-#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
-
-bool pmw3389_spi_start(void) {
- bool status = spi_start(PMW3389_CS_PIN, PMW3389_SPI_LSBFIRST, PMW3389_SPI_MODE, PMW3389_SPI_DIVISOR);
- // tNCS-SCLK, 120ns
- wait_us(1);
- return status;
-}
-
-spi_status_t pmw3389_write(uint8_t reg_addr, uint8_t data) {
- pmw3389_spi_start();
-
- if (reg_addr != REG_Motion_Burst) {
- _inBurst = false;
- }
-
- // send address of the register, with MSBit = 1 to indicate it's a write
- spi_status_t status = spi_write(reg_addr | 0x80);
- status = spi_write(data);
-
- // tSCLK-NCS for write operation is 35 us
- wait_us(35);
- spi_stop();
-
- // tSWW/tSWR (=180us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
- wait_us(145);
- return status;
-}
-
-uint8_t pmw3389_read(uint8_t reg_addr) {
- pmw3389_spi_start();
- // send adress of the register, with MSBit = 0 to indicate it's a read
- spi_write(reg_addr & 0x7f);
- // tSRAD (=160us)
- wait_us(160);
- uint8_t data = spi_read();
-
- // tSCLK-NCS, 120ns
- wait_us(1);
- spi_stop();
-
- // tSRW/tSRR (=20us) minus tSCLK-NCS
- wait_us(19);
- return data;
-}
-
-bool pmw3389_init(void) {
- setPinOutput(PMW3389_CS_PIN);
-
- spi_init();
- _inBurst = false;
-
- spi_stop();
- pmw3389_spi_start();
- spi_stop();
-
- pmw3389_write(REG_Shutdown, 0xb6); // Shutdown first
- wait_ms(300);
-
- pmw3389_spi_start();
- wait_us(40);
- spi_stop();
- wait_us(40);
-
- // power up, need to first drive NCS high then low, see above.
- pmw3389_write(REG_Power_Up_Reset, 0x5a);
- wait_ms(50);
-
- // read registers and discard
- pmw3389_read(REG_Motion);
- pmw3389_read(REG_Delta_X_L);
- pmw3389_read(REG_Delta_X_H);
- pmw3389_read(REG_Delta_Y_L);
- pmw3389_read(REG_Delta_Y_H);
-
- pmw3389_upload_firmware();
-
- spi_stop();
+extern const size_t pmw33xx_number_of_sensors;
- wait_ms(10);
- pmw3389_set_cpi(PMW3389_CPI);
-
- wait_ms(1);
-
- pmw3389_write(REG_Config2, 0x00);
-
- pmw3389_write(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -127, 127));
-
- pmw3389_write(REG_Lift_Config, PMW3389_LIFTOFF_DISTANCE);
-
- bool init_success = pmw3389_check_signature();
-#ifdef CONSOLE_ENABLE
- if (init_success) {
- dprintf("pmw3389 signature verified");
- } else {
- dprintf("pmw3389 signature verification failed!");
+uint16_t pmw33xx_get_cpi(uint8_t sensor) {
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return 0;
}
-#endif
-
- writePinLow(PMW3389_CS_PIN);
- return init_success;
+ uint16_t cpival = (pmw33xx_read(sensor, REG_Resolution_H) << 8) | pmw33xx_read(sensor, REG_Resolution_L);
+ return (uint16_t)((cpival + 1) & 0xFFFF) * PMW33XX_CPI_STEP;
}
-void pmw3389_upload_firmware(void) {
- // Datasheet claims we need to disable REST mode first, but during startup
- // it's already disabled and we're not turning it on ...
- // pmw3389_write(REG_Config2, 0x00); // disable REST mode
- pmw3389_write(REG_SROM_Enable, 0x1d);
-
- wait_ms(10);
-
- pmw3389_write(REG_SROM_Enable, 0x18);
-
- pmw3389_spi_start();
- spi_write(REG_SROM_Load_Burst | 0x80);
- wait_us(15);
-
- for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
- spi_write(pgm_read_byte(firmware_data + i));
-#ifndef PMW3389_FIRMWARE_UPLOAD_FAST
- wait_us(15);
-#endif
+void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) {
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return;
}
- wait_us(200);
-
- pmw3389_read(REG_SROM_ID);
- pmw3389_write(REG_Config2, 0x00);
-}
-
-bool pmw3389_check_signature(void) {
- uint8_t pid = pmw3389_read(REG_Product_ID);
- uint8_t iv_pid = pmw3389_read(REG_Inverse_Product_ID);
- uint8_t SROM_ver = pmw3389_read(REG_SROM_ID);
- return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04
-}
-uint16_t pmw3389_get_cpi(void) {
- uint16_t cpival = (pmw3389_read(REG_Resolution_H) << 8) | pmw3389_read(REG_Resolution_L);
- return (uint16_t)((cpival + 1) & 0xffff) * CPI_STEP;
-}
-
-void pmw3389_set_cpi(uint16_t cpi) {
- uint16_t cpival = constrain((cpi / CPI_STEP) - 1, 0, MAX_CPI);
+ uint16_t cpival = CONSTRAIN((cpi / PMW33XX_CPI_STEP) - 1, 0, (PMW33XX_CPI_MAX / PMW33XX_CPI_STEP) - 1U);
// Sets upper byte first for more consistent setting of cpi
- pmw3389_write(REG_Resolution_H, (cpival >> 8) & 0xff);
- pmw3389_write(REG_Resolution_L, cpival & 0xff);
+ pmw33xx_write(sensor, REG_Resolution_H, (cpival >> 8) & 0xFF);
+ pmw33xx_write(sensor, REG_Resolution_L, cpival & 0xFF);
}
-report_pmw3389_t pmw3389_read_burst(void) {
- report_pmw3389_t report = {0};
-
- if (!_inBurst) {
-#ifdef CONSOLE_ENABLE
- dprintf("burst on");
-#endif
- pmw3389_write(REG_Motion_Burst, 0x00);
- _inBurst = true;
- }
-
- pmw3389_spi_start();
- spi_write(REG_Motion_Burst);
- wait_us(35); // waits for tSRAD_MOTBR
-
- report.motion = spi_read();
- spi_read(); // skip Observation
- // delta registers
- report.dx = spi_read();
- report.mdx = spi_read();
- report.dy = spi_read();
- report.mdy = spi_read();
-
- if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
- _inBurst = false;
- }
-
- spi_stop();
-
-#ifdef CONSOLE_ENABLE
- if (debug_mouse) {
- print_byte(report.motion);
- print_byte(report.dx);
- print_byte(report.mdx);
- print_byte(report.dy);
- print_byte(report.mdy);
- dprintf("\n");
- }
-#endif
+// PID, Inverse PID, SROM version
+const uint8_t pmw33xx_firmware_signature[3] PROGMEM = {0x42, 0xBD, 0x04};
- report.isMotion = (report.motion & 0x80) != 0;
- report.isOnSurface = (report.motion & 0x08) == 0;
- report.dx |= (report.mdx << 8);
- report.dx = report.dx * -1;
- report.dy |= (report.mdy << 8);
- report.dy = report.dy * -1;
+// Firmware Blob for PMW3389
+// clang-format off
+const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM = {
+ 0x01, 0xe8, 0xba, 0x26, 0x0b, 0xb2, 0xbe, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0xa8, 0xb3,
+ 0xe4, 0x2b, 0xb5, 0xe8, 0x53, 0x07, 0x6d, 0x3b, 0xd1, 0x20, 0xc2, 0x06, 0x6f, 0x3d, 0xd9,
+ 0x11, 0xa0, 0xc2, 0xe7, 0x2d, 0xb9, 0xd1, 0x20, 0xa3, 0xa5, 0xc8, 0xf3, 0x64, 0x4a, 0xf7,
+ 0x4d, 0x18, 0x93, 0xa4, 0xca, 0xf7, 0x6c, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xfe, 0x7e, 0x7e,
+ 0x5f, 0x1d, 0x99, 0xb0, 0xc3, 0xe5, 0x29, 0xd3, 0x03, 0x65, 0x48, 0x12, 0x87, 0x6d, 0x58,
+ 0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xf2, 0x4f, 0xfd, 0x59, 0x11, 0x81, 0x61, 0x21, 0xc0, 0x02,
+ 0x86, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x55, 0x28, 0xb3, 0xe4, 0x4a, 0x16,
+ 0xab, 0xbf, 0xdd, 0x38, 0xf2, 0x66, 0x4e, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xc8,
+ 0x12, 0xa6, 0xaf, 0xdc, 0x3a, 0xd1, 0x41, 0x60, 0x75, 0x58, 0x24, 0x92, 0xd4, 0x72, 0x6c,
+ 0xe0, 0x2f, 0xfd, 0x23, 0x8d, 0x1c, 0x5b, 0xb2, 0x97, 0x36, 0x3d, 0x0b, 0xa2, 0x49, 0xb1,
+ 0x58, 0xf2, 0x1f, 0xc0, 0xcb, 0xf8, 0x41, 0x4f, 0xcd, 0x1e, 0x6b, 0x39, 0xa7, 0x2b, 0xe9,
+ 0x30, 0x16, 0x83, 0xd2, 0x0e, 0x47, 0x8f, 0xe3, 0xb1, 0xdf, 0xa2, 0x15, 0xdb, 0x5d, 0x30,
+ 0xc5, 0x1a, 0xab, 0x31, 0x99, 0xf3, 0xfa, 0xb2, 0x86, 0x69, 0xad, 0x7a, 0xe8, 0xa7, 0x18,
+ 0x6a, 0xcc, 0xc8, 0x65, 0x23, 0x87, 0xa8, 0x5f, 0xf5, 0x21, 0x59, 0x75, 0x09, 0x71, 0x45,
+ 0x55, 0x25, 0x4b, 0xda, 0xa1, 0xc3, 0xf7, 0x41, 0xab, 0x59, 0xd9, 0x74, 0x12, 0x55, 0x5f,
+ 0xbc, 0xaf, 0xd9, 0xfd, 0xb0, 0x1e, 0xa3, 0x0f, 0xff, 0xde, 0x11, 0x16, 0x6a, 0xae, 0x0e,
+ 0xe1, 0x5d, 0x3c, 0x10, 0x43, 0x9a, 0xa1, 0x0b, 0x24, 0x8f, 0x0d, 0x7f, 0x0b, 0x5e, 0x4c,
+ 0x42, 0xa4, 0x84, 0x2c, 0x40, 0xd0, 0x55, 0x39, 0xe6, 0x4b, 0xf8, 0x9b, 0x2f, 0xdc, 0x28,
+ 0xff, 0xfa, 0xb5, 0x85, 0x19, 0xe5, 0x28, 0xa1, 0x77, 0xaa, 0x73, 0xf3, 0x03, 0xc7, 0x62,
+ 0xa6, 0x91, 0x18, 0xc9, 0xb0, 0xcd, 0x05, 0xdc, 0xca, 0x81, 0x26, 0x1a, 0x47, 0x40, 0xda,
+ 0x36, 0x7d, 0x6a, 0x53, 0xc8, 0x5a, 0x77, 0x5d, 0x19, 0xa4, 0x1b, 0x23, 0x83, 0xd0, 0xb2,
+ 0xaa, 0x0e, 0xbf, 0x77, 0x4e, 0x3a, 0x3b, 0x59, 0x00, 0x31, 0x0d, 0x02, 0x1b, 0x88, 0x7a,
+ 0xd4, 0xbd, 0x9d, 0xcc, 0x58, 0x04, 0x69, 0xf6, 0x3b, 0xca, 0x42, 0xe2, 0xfd, 0xc3, 0x3d,
+ 0x39, 0xc5, 0xd0, 0x71, 0xe4, 0xc8, 0xb7, 0x3e, 0x3f, 0xc8, 0xe9, 0xca, 0xc9, 0x3f, 0x04,
+ 0x4e, 0x1b, 0x79, 0xca, 0xa5, 0x61, 0xc2, 0xed, 0x1d, 0xa6, 0xda, 0x5a, 0xe9, 0x7f, 0x65,
+ 0x8c, 0xbe, 0x12, 0x6e, 0xa4, 0x5b, 0x33, 0x2f, 0x84, 0x28, 0x9c, 0x1c, 0x88, 0x2d, 0xff,
+ 0x07, 0xbf, 0xa6, 0xd7, 0x5a, 0x88, 0x86, 0xb0, 0x3f, 0xf6, 0x31, 0x5b, 0x11, 0x6d, 0xf5,
+ 0x58, 0xeb, 0x58, 0x02, 0x9e, 0xb5, 0x9a, 0xb1, 0xff, 0x25, 0x9d, 0x8b, 0x4f, 0xb6, 0x0a,
+ 0xf9, 0xea, 0x3e, 0x3f, 0x21, 0x09, 0x65, 0x21, 0x22, 0xfe, 0x3d, 0x4e, 0x11, 0x5b, 0x9e,
+ 0x5a, 0x59, 0x8b, 0xdd, 0xd8, 0xce, 0xd6, 0xd9, 0x59, 0xd2, 0x1e, 0xfd, 0xef, 0x0d, 0x1b,
+ 0xd9, 0x61, 0x7f, 0xd7, 0x2d, 0xad, 0x62, 0x09, 0xe5, 0x22, 0x63, 0xea, 0xc7, 0x31, 0xd9,
+ 0xa1, 0x38, 0x80, 0x5c, 0xa7, 0x32, 0x82, 0xec, 0x1b, 0xa2, 0x49, 0x5a, 0x06, 0xd2, 0x7c,
+ 0xc9, 0x96, 0x57, 0xbb, 0x17, 0x75, 0xfc, 0x7a, 0x8f, 0x0d, 0x77, 0xb5, 0x7a, 0x8e, 0x3e,
+ 0xf4, 0xba, 0x2f, 0x69, 0x13, 0x26, 0xd6, 0xd9, 0x21, 0x60, 0x2f, 0x21, 0x3e, 0x87, 0xee,
+ 0xfd, 0x87, 0x16, 0x0d, 0xc8, 0x08, 0x00, 0x25, 0x71, 0xac, 0x2c, 0x03, 0x2a, 0x37, 0x2d,
+ 0xb3, 0x34, 0x09, 0x91, 0xe3, 0x06, 0x2c, 0x38, 0x37, 0x95, 0x3b, 0x17, 0x7a, 0xaf, 0xac,
+ 0x99, 0x55, 0xab, 0x41, 0x39, 0x5f, 0x8e, 0xa6, 0x43, 0x80, 0x03, 0x88, 0x6f, 0x7d, 0xbd,
+ 0x5a, 0xb4, 0x2b, 0x32, 0x23, 0x5a, 0xa9, 0x31, 0x32, 0x39, 0x4c, 0x5b, 0xf4, 0x6b, 0xaf,
+ 0x66, 0x6f, 0x3c, 0x8e, 0x2d, 0x82, 0x97, 0x9f, 0x4a, 0x01, 0xdc, 0x99, 0x98, 0x00, 0xec,
+ 0x38, 0x7a, 0x79, 0x70, 0xa6, 0x85, 0xd6, 0x21, 0x63, 0x0d, 0x45, 0x9a, 0x2e, 0x5e, 0xa7,
+ 0xb1, 0xea, 0x66, 0x6a, 0xbc, 0x62, 0x2d, 0x7b, 0x7d, 0x85, 0xea, 0x95, 0x2f, 0xc0, 0xe8,
+ 0x6f, 0x35, 0xa0, 0x3a, 0x02, 0x25, 0xbc, 0xb2, 0x5f, 0x5c, 0x43, 0x96, 0xcc, 0x26, 0xd2,
+ 0x16, 0xb4, 0x96, 0x73, 0xd7, 0x13, 0xc7, 0xae, 0x53, 0x15, 0x31, 0x89, 0x68, 0x66, 0x6d,
+ 0x2c, 0x92, 0x1f, 0xcc, 0x5b, 0xa7, 0x8f, 0x5d, 0xbb, 0xc9, 0xdb, 0xe8, 0x3b, 0x9d, 0x61,
+ 0x74, 0x8b, 0x05, 0xa1, 0x58, 0x52, 0x68, 0xee, 0x3d, 0x39, 0x79, 0xa0, 0x9b, 0xdd, 0xe1,
+ 0x55, 0xc9, 0x60, 0xeb, 0xad, 0xb8, 0x5b, 0xc2, 0x5a, 0xb5, 0x2c, 0x18, 0x55, 0xa9, 0x50,
+ 0xc3, 0xf6, 0x72, 0x5f, 0xcc, 0xe2, 0xf4, 0x55, 0xb5, 0xd6, 0xb5, 0x4a, 0x99, 0xa5, 0x28,
+ 0x74, 0x97, 0x18, 0xe8, 0xc0, 0x84, 0x89, 0x50, 0x03, 0x86, 0x4d, 0x1a, 0xb7, 0x09, 0x90,
+ 0xa2, 0x01, 0x04, 0xbb, 0x73, 0x62, 0xcb, 0x97, 0x22, 0x70, 0x5d, 0x52, 0x41, 0x8e, 0xd9,
+ 0x90, 0x15, 0xaa, 0xab, 0x0a, 0x31, 0x65, 0xb4, 0xda, 0xd0, 0xee, 0x24, 0xc9, 0x41, 0x91,
+ 0x1e, 0xbc, 0x46, 0x70, 0x40, 0x9d, 0xda, 0x0e, 0x2a, 0xe4, 0xb2, 0x4c, 0x9f, 0xf2, 0xfc,
+ 0xf3, 0x84, 0x17, 0x44, 0x1e, 0xd7, 0xca, 0x23, 0x1f, 0x3f, 0x5a, 0x22, 0x3d, 0xaf, 0x9b,
+ 0x2d, 0xfc, 0x41, 0xad, 0x26, 0xb4, 0x45, 0x67, 0x0b, 0x80, 0x0e, 0xf9, 0x61, 0x37, 0xec,
+ 0x3b, 0xf4, 0x4b, 0x14, 0xdf, 0x5a, 0x0c, 0x3a, 0x50, 0x0b, 0x14, 0x0c, 0x72, 0xae, 0xc6,
+ 0xc5, 0xec, 0x35, 0x53, 0x2d, 0x59, 0xed, 0x91, 0x74, 0xe2, 0xc4, 0xc8, 0xf2, 0x25, 0x6b,
+ 0x97, 0x6f, 0xc9, 0x76, 0xce, 0xa9, 0xb1, 0x99, 0x8f, 0x5a, 0x92, 0x3b, 0xc4, 0x8d, 0x54,
+ 0x50, 0x40, 0x72, 0xd6, 0x90, 0x83, 0xfc, 0xe5, 0x49, 0x8b, 0x17, 0xf5, 0xfd, 0x6b, 0x8d,
+ 0x32, 0x02, 0xe9, 0x0a, 0xfe, 0xbf, 0x00, 0x6b, 0xa3, 0xad, 0x5f, 0x09, 0x4b, 0x97, 0x2b,
+ 0x00, 0x58, 0x65, 0x2e, 0x07, 0x49, 0x0a, 0x3b, 0x6b, 0x2e, 0x50, 0x6c, 0x1d, 0xac, 0xb7,
+ 0x6a, 0x26, 0xd8, 0x13, 0xa4, 0xca, 0x16, 0xae, 0xab, 0x93, 0xb9, 0x1c, 0x1c, 0xb4, 0x47,
+ 0x6a, 0x38, 0x36, 0x17, 0x27, 0xc9, 0x7f, 0xc7, 0x64, 0xcb, 0x89, 0x58, 0xc5, 0x61, 0xc2,
+ 0xc6, 0xea, 0x15, 0x0b, 0x34, 0x0c, 0x5d, 0x61, 0x76, 0x6e, 0x2b, 0x62, 0x40, 0x92, 0xa3,
+ 0x6c, 0xef, 0xf4, 0xe4, 0xc3, 0xa1, 0xa8, 0xf5, 0x94, 0x79, 0x0d, 0xd1, 0x3d, 0xcb, 0x3d,
+ 0x40, 0xb6, 0xd0, 0xf0, 0x10, 0x54, 0xd8, 0x47, 0x25, 0x51, 0xc5, 0x41, 0x79, 0x00, 0xe5,
+ 0xa0, 0x72, 0xde, 0xbb, 0x3b, 0x62, 0x17, 0xf6, 0xbc, 0x5d, 0x00, 0x76, 0x2e, 0xa7, 0x3b,
+ 0xb6, 0xf1, 0x98, 0x72, 0x59, 0x2a, 0x73, 0xb0, 0x21, 0xd6, 0x49, 0xe0, 0xc0, 0xd5, 0xeb,
+ 0x02, 0x7d, 0x4b, 0x41, 0x28, 0x70, 0x2d, 0xec, 0x2b, 0x71, 0x1f, 0x0b, 0xb9, 0x71, 0x63,
+ 0x06, 0xe6, 0xbc, 0x60, 0xbb, 0xf4, 0x9a, 0x62, 0x43, 0x09, 0x18, 0x4e, 0x93, 0x06, 0x4d,
+ 0x76, 0xfa, 0x7f, 0xbd, 0x02, 0xe4, 0x50, 0x91, 0x12, 0xe5, 0x86, 0xff, 0x64, 0x1e, 0xaf,
+ 0x7e, 0xb3, 0xb2, 0xde, 0x89, 0xc1, 0xa2, 0x6f, 0x40, 0x7b, 0x41, 0x51, 0x63, 0xea, 0x25,
+ 0xd1, 0x97, 0x57, 0x92, 0xa8, 0x45, 0xa1, 0xa5, 0x45, 0x21, 0x43, 0x7f, 0x83, 0x15, 0x29,
+ 0xd0, 0x30, 0x53, 0x32, 0xb4, 0x5a, 0x17, 0x96, 0xbc, 0xc2, 0x68, 0xa9, 0xb7, 0xaf, 0xac,
+ 0xdf, 0xf1, 0xe3, 0x89, 0xba, 0x24, 0x79, 0x54, 0xc6, 0x14, 0x07, 0x1c, 0x1e, 0x0d, 0x3a,
+ 0x6b, 0xe5, 0x3d, 0x4e, 0x10, 0x60, 0x96, 0xec, 0x6c, 0xda, 0x47, 0xae, 0x03, 0x25, 0x39,
+ 0x1d, 0x74, 0xc8, 0xac, 0x6a, 0xf2, 0x6b, 0x05, 0x2a, 0x9a, 0xe7, 0xe8, 0x92, 0xd6, 0xc2,
+ 0x6d, 0xfa, 0xe8, 0xa7, 0x9d, 0x5f, 0x48, 0xc9, 0x75, 0xf1, 0x66, 0x6a, 0xdb, 0x5d, 0x9a,
+ 0xcd, 0x27, 0xdd, 0xb9, 0x24, 0x04, 0x9c, 0x18, 0xc2, 0x6d, 0x0c, 0x91, 0x34, 0x48, 0x42,
+ 0x6f, 0xe9, 0x59, 0x70, 0xc4, 0x7e, 0x81, 0x0e, 0x32, 0x0a, 0x93, 0x48, 0xb0, 0xc0, 0x15,
+ 0x9e, 0x05, 0xac, 0x36, 0x16, 0xcb, 0x59, 0x65, 0xa0, 0x83, 0xdf, 0x3e, 0xda, 0xfb, 0x1d,
+ 0x1a, 0xdb, 0x65, 0xec, 0x9a, 0xc6, 0xc3, 0x8e, 0x3c, 0x45, 0xfd, 0xc8, 0xf5, 0x1c, 0x6a,
+ 0x67, 0x0d, 0x8f, 0x99, 0x7d, 0x30, 0x21, 0x8c, 0xea, 0x22, 0x87, 0x65, 0xc9, 0xb2, 0x4c,
+ 0xe4, 0x1b, 0x46, 0xba, 0x54, 0xbd, 0x7c, 0xca, 0xd5, 0x8f, 0x5b, 0xa5, 0x01, 0x04, 0xd8,
+ 0x0a, 0x16, 0xbf, 0xb9, 0x50, 0x2e, 0x37, 0x2f, 0x64, 0xf3, 0x70, 0x11, 0x02, 0x05, 0x31,
+ 0x9b, 0xa0, 0xb2, 0x01, 0x5e, 0x4f, 0x19, 0xc9, 0xd4, 0xea, 0xa1, 0x79, 0x54, 0x53, 0xa7,
+ 0xde, 0x2f, 0x49, 0xd3, 0xd1, 0x63, 0xb5, 0x03, 0x15, 0x4e, 0xbf, 0x04, 0xb3, 0x26, 0x8b,
+ 0x20, 0xb2, 0x45, 0xcf, 0xcd, 0x5b, 0x82, 0x32, 0x88, 0x61, 0xa7, 0xa8, 0xb2, 0xa0, 0x72,
+ 0x96, 0xc0, 0xdb, 0x2b, 0xe2, 0x5f, 0xba, 0xe3, 0xf5, 0x8a, 0xde, 0xf1, 0x18, 0x01, 0x16,
+ 0x40, 0xd9, 0x86, 0x12, 0x09, 0x18, 0x1b, 0x05, 0x0c, 0xb1, 0xb5, 0x47, 0xe2, 0x43, 0xab,
+ 0xfe, 0x92, 0x63, 0x7e, 0x95, 0x2b, 0xf0, 0xaf, 0xe1, 0xf1, 0xc3, 0x4a, 0xff, 0x2b, 0x09,
+ 0xbb, 0x4a, 0x0e, 0x9a, 0xc4, 0xd8, 0x64, 0x7d, 0x83, 0xa0, 0x4f, 0x44, 0xdb, 0xc4, 0xa8,
+ 0x58, 0xef, 0xfc, 0x9e, 0x77, 0xf9, 0xa6, 0x8f, 0x58, 0x8b, 0x12, 0xf4, 0xe9, 0x81, 0x12,
+ 0x47, 0x51, 0x41, 0x83, 0xef, 0xf6, 0x73, 0xbc, 0x8e, 0x0f, 0x4c, 0x8f, 0x4e, 0x69, 0x90,
+ 0x77, 0x29, 0x5d, 0x92, 0xb0, 0x6d, 0x06, 0x67, 0x29, 0x60, 0xbd, 0x4b, 0x17, 0xc8, 0x89,
+ 0x69, 0x28, 0x29, 0xd6, 0x78, 0xcb, 0x11, 0x4c, 0xba, 0x8b, 0x68, 0xae, 0x7e, 0x9f, 0xef,
+ 0x95, 0xda, 0xe2, 0x9e, 0x7f, 0xe9, 0x55, 0xe5, 0xe1, 0xe2, 0xb7, 0xe6, 0x5f, 0xbb, 0x2c,
+ 0xa2, 0xe6, 0xee, 0xc7, 0x0a, 0x60, 0xa9, 0xd1, 0x80, 0xdf, 0x7f, 0xd6, 0x97, 0xab, 0x1d,
+ 0x22, 0x25, 0xfc, 0x79, 0x23, 0xe0, 0xae, 0xc5, 0xef, 0x16, 0xa4, 0xa1, 0x0f, 0x92, 0xa9,
+ 0xc7, 0xe3, 0x3a, 0x55, 0xdf, 0x62, 0x49, 0xd9, 0xf5, 0x84, 0x49, 0xc5, 0x90, 0x34, 0xd3,
+ 0xe1, 0xac, 0x99, 0x21, 0xb1, 0x02, 0x76, 0x4a, 0xfa, 0xd4, 0xbb, 0xa4, 0x9c, 0xa2, 0xe2,
+ 0xcb, 0x3d, 0x3b, 0x14, 0x75, 0x60, 0xd1, 0x02, 0xb4, 0xa3, 0xb4, 0x72, 0x06, 0xf9, 0x19,
+ 0x9c, 0xe2, 0xe4, 0xa7, 0x0f, 0x25, 0x88, 0xc6, 0x86, 0xd6, 0x8c, 0x74, 0x4e, 0x6e, 0xfc,
+ 0xa8, 0x48, 0x9e, 0xa7, 0x9d, 0x1a, 0x4b, 0x37, 0x09, 0xc8, 0xb0, 0x10, 0xbe, 0x6f, 0xfe,
+ 0xa3, 0xc4, 0x7a, 0xb5, 0x3d, 0xe8, 0x30, 0xf1, 0x0d, 0xa0, 0xb2, 0x44, 0xfc, 0x9b, 0x8c,
+ 0xf8, 0x61, 0xed, 0x81, 0xd1, 0x62, 0x11, 0xb4, 0xe1, 0xd5, 0x39, 0x52, 0x89, 0xd3, 0xa8,
+ 0x49, 0x31, 0xdf, 0xb6, 0xf9, 0x91, 0xf4, 0x1c, 0x9d, 0x09, 0x95, 0x40, 0x56, 0xe7, 0xe3,
+ 0xcd, 0x5c, 0x92, 0xc1, 0x1d, 0x6b, 0xe9, 0x78, 0x6f, 0x8e, 0x94, 0x42, 0x66, 0xa2, 0xaa,
+ 0xd3, 0xc8, 0x2e, 0xe3, 0xf6, 0x07, 0x72, 0x0b, 0x6b, 0x1e, 0x7b, 0xb9, 0x7c, 0xe0, 0xa0,
+ 0xbc, 0xd9, 0x25, 0xdf, 0x87, 0xa8, 0x5f, 0x9c, 0xcc, 0xf0, 0xdb, 0x42, 0x8e, 0x07, 0x31,
+ 0x13, 0x01, 0x66, 0x32, 0xd1, 0xb8, 0xd6, 0xe3, 0x5e, 0x12, 0x76, 0x61, 0xd3, 0x38, 0x89,
+ 0xe6, 0x17, 0x6f, 0xa5, 0xf2, 0x71, 0x0e, 0xa5, 0xe2, 0x88, 0x30, 0xbb, 0xbe, 0x8a, 0xea,
+ 0xc7, 0x62, 0xc4, 0xcf, 0xb8, 0xcd, 0x33, 0x8d, 0x3d, 0x3e, 0xb5, 0x60, 0x3a, 0x03, 0x92,
+ 0xe4, 0x6d, 0x1b, 0xe0, 0xb4, 0x84, 0x08, 0x55, 0x88, 0xa7, 0x3a, 0xb9, 0x3d, 0x43, 0xc3,
+ 0xc0, 0xfa, 0x07, 0x6a, 0xca, 0x94, 0xad, 0x99, 0x55, 0xf1, 0xf1, 0xc0, 0x23, 0x87, 0x1d,
+ 0x3d, 0x1c, 0xd1, 0x66, 0xa0, 0x57, 0x10, 0x52, 0xa2, 0x7f, 0xbe, 0xf9, 0x88, 0xb6, 0x02,
+ 0xbf, 0x08, 0x23, 0xa9, 0x0c, 0x63, 0x17, 0x2a, 0xae, 0xf5, 0xf7, 0xb7, 0x21, 0x83, 0x92,
+ 0x31, 0x23, 0x0d, 0x20, 0xc3, 0xc2, 0x05, 0x21, 0x62, 0x8e, 0x45, 0xe8, 0x14, 0xc1, 0xda,
+ 0x75, 0xb8, 0xf8, 0x92, 0x01, 0xd0, 0x5d, 0x18, 0x9f, 0x99, 0x11, 0x19, 0xf5, 0x35, 0xe8,
+ 0x7f, 0x20, 0x88, 0x8c, 0x05, 0x75, 0xf5, 0xd7, 0x40, 0x17, 0xbb, 0x1e, 0x36, 0x52, 0xd9,
+ 0xa4, 0x9c, 0xc2, 0x9d, 0x42, 0x81, 0xd8, 0xc7, 0x8a, 0xe7, 0x4c, 0x81, 0xe0, 0xb7, 0x57,
+ 0xed, 0x48, 0x8b, 0xf0, 0x97, 0x15, 0x61, 0xd9, 0x2c, 0x7c, 0x45, 0xaf, 0xc2, 0xcd, 0xfc,
+ 0xaa, 0x13, 0xad, 0x59, 0xcc, 0xb2, 0xb2, 0x6e, 0xdd, 0x63, 0x9c, 0x32, 0x0f, 0xec, 0x83,
+ 0xbe, 0x78, 0xac, 0x91, 0x44, 0x1a, 0x1f, 0xea, 0xfd, 0x5d, 0x8e, 0xb4, 0xc0, 0x84, 0xd4,
+ 0xac, 0xb4, 0x87, 0x5f, 0xac, 0xef, 0xdf, 0xcd, 0x12, 0x56, 0xc8, 0xcd, 0xfe, 0xc5, 0xda,
+ 0xd3, 0xc1, 0x69, 0xf3, 0x61, 0x05, 0xea, 0x25, 0xe2, 0x12, 0x05, 0x8f, 0x39, 0x08, 0x08,
+ 0x7c, 0x37, 0xb6, 0x7e, 0x5b, 0xd8, 0xb1, 0x0e, 0xf2, 0xdb, 0x4b, 0xf1, 0xad, 0x90, 0x01,
+ 0x57, 0xcd, 0xa0, 0xb4, 0x52, 0xe8, 0xf3, 0xd7, 0x8a, 0xbd, 0x4f, 0x9f, 0x21, 0x40, 0x72,
+ 0xa4, 0xfc, 0x0b, 0x01, 0x2b, 0x2f, 0xb6, 0x4c, 0x95, 0x2d, 0x35, 0x33, 0x41, 0x6b, 0xa0,
+ 0x93, 0xe7, 0x2c, 0xf2, 0xd3, 0x72, 0x8b, 0xf4, 0x4f, 0x15, 0x3c, 0xaf, 0xd6, 0x12, 0xde,
+ 0x3f, 0x83, 0x3f, 0xff, 0xf8, 0x7f, 0xf6, 0xcc, 0xa6, 0x7f, 0xc9, 0x9a, 0x6e, 0x1f, 0xc1,
+ 0x0c, 0xfb, 0xee, 0x9c, 0xe7, 0xaf, 0xc9, 0x26, 0x54, 0xef, 0xb0, 0x39, 0xef, 0xb2, 0xe9,
+ 0x23, 0xc4, 0xef, 0xd1, 0xa1, 0xa4, 0x25, 0x24, 0x6f, 0x8d, 0x6a, 0xe5, 0x8a, 0x32, 0x3a,
+ 0xaf, 0xfc, 0xda, 0xce, 0x18, 0x25, 0x42, 0x07, 0x4d, 0x45, 0x8b, 0xdf, 0x85, 0xcf, 0x55,
+ 0xb2, 0x24, 0xfe, 0x9c, 0x69, 0x74, 0xa7, 0x6e, 0xa0, 0xce, 0xc0, 0x39, 0xf4, 0x86, 0xc6,
+ 0x8d, 0xae, 0xb9, 0x48, 0x64, 0x13, 0x0b, 0x40, 0x81, 0xa2, 0xc9, 0xa8, 0x85, 0x51, 0xee,
+ 0x9f, 0xcf, 0xa2, 0x8c, 0x19, 0x52, 0x48, 0xe2, 0xc1, 0xa8, 0x58, 0xb4, 0x10, 0x24, 0x06,
+ 0x58, 0x51, 0xfc, 0xb9, 0x12, 0xec, 0xfd, 0x73, 0xb4, 0x6d, 0x84, 0xfa, 0x06, 0x8b, 0x05,
+ 0x0b, 0x2d, 0xd6, 0xd6, 0x1f, 0x29, 0x82, 0x9f, 0x19, 0x12, 0x1e, 0xb2, 0x04, 0x8f, 0x7f,
+ 0x4d, 0xbd, 0x30, 0x2e, 0xe3, 0xe0, 0x88, 0x29, 0xc5, 0x93, 0xd6, 0x6c, 0x1f, 0x29, 0x45,
+ 0x91, 0xa7, 0x58, 0xcd, 0x05, 0x17, 0xd6, 0x6d, 0xb3, 0xca, 0x66, 0xcc, 0x3c, 0x4a, 0x74,
+ 0xfd, 0x08, 0x10, 0xa6, 0x99, 0x92, 0x10, 0xd2, 0x85, 0xab, 0x6e, 0x1d, 0x0e, 0x8b, 0x26,
+ 0x46, 0xd1, 0x6c, 0x84, 0xc0, 0x26, 0x43, 0x59, 0x68, 0xf0, 0x13, 0x1d, 0xfb, 0xe3, 0xd1,
+ 0xd2, 0xb4, 0x71, 0x9e, 0xf2, 0x59, 0x6a, 0x33, 0x29, 0x79, 0xd2, 0xd7, 0x26, 0xf1, 0xae,
+ 0x78, 0x9e, 0x1f, 0x0f, 0x3f, 0xe3, 0xe8, 0xd0, 0x27, 0x78, 0x77, 0xf6, 0xac, 0x9c, 0x56,
+ 0x39, 0x73, 0x8a, 0x6b, 0x2f, 0x34, 0x78, 0xb1, 0x11, 0xdb, 0xa4, 0x5c, 0x80, 0x01, 0x71,
+ 0x6a, 0xc2, 0xd1, 0x2e, 0x5e, 0x76, 0x28, 0x70, 0x93, 0xae, 0x3e, 0x78, 0xb0, 0x1f, 0x0f,
+ 0xda, 0xbf, 0xfb, 0x8a, 0x67, 0x65, 0x4f, 0x91, 0xed, 0x49, 0x75, 0x78, 0x62, 0xa2, 0x93,
+ 0xb5, 0x70, 0x7f, 0x4d, 0x08, 0x4e, 0x79, 0x61, 0xa8, 0x5f, 0x7f, 0xb4, 0x65, 0x9f, 0x91,
+ 0x54, 0x3a, 0xe8, 0x50, 0x33, 0xd3, 0xd5, 0x8a, 0x7c, 0xf3, 0x9e, 0x8b, 0x77, 0x7b, 0xc6,
+ 0xc6, 0x0c, 0x45, 0x95, 0x1f, 0xb0, 0xd0, 0x0b, 0x27, 0x4a, 0xfd, 0xc7, 0xf7, 0x0d, 0x5a,
+ 0x43, 0xc9, 0x7d, 0x35, 0xb0, 0x7d, 0xc4, 0x9c, 0x57, 0x1e, 0x76, 0x0d, 0xf1, 0x95, 0x30,
+ 0x71, 0xcc, 0xb3, 0x66, 0x3b, 0x63, 0xa8, 0x6c, 0xa3, 0x43, 0xa0, 0x24, 0xcc, 0xb7, 0x53,
+ 0xfe, 0xfe, 0xbc, 0x6e, 0x60, 0x89, 0xaf, 0x16, 0x21, 0xc8, 0x91, 0x6a, 0x89, 0xce, 0x80,
+ 0x2c, 0xf1, 0x59, 0xce, 0xc3, 0x60, 0x61, 0x3b, 0x0b, 0x19, 0xfe, 0x99, 0xac, 0x65, 0x90,
+ 0x15, 0x12, 0x05, 0xac, 0x7e, 0xff, 0x98, 0x7b, 0x66, 0x64, 0x0e, 0x4b, 0x5b, 0xaa, 0x8d,
+ 0x3b, 0xd2, 0x56, 0xcf, 0x99, 0x39, 0xee, 0x22, 0x81, 0xd0, 0x60, 0x06, 0x66, 0x20, 0x81,
+ 0x48, 0x3c, 0x6f, 0x3a, 0x77, 0xba, 0xcb, 0x52, 0xac, 0x79, 0x56, 0xaf, 0xe9, 0x16, 0x17,
+ 0x0a, 0xa3, 0x82, 0x08, 0xd5, 0x3c, 0x97, 0xcb, 0x09, 0xff, 0x7f, 0xf9, 0x4f, 0x60, 0x05,
+ 0xb9, 0x53, 0x26, 0xaa, 0xb8, 0x50, 0xaa, 0x19, 0x25, 0xae, 0x5f, 0xea, 0x8a, 0xd0, 0x89,
+ 0x12, 0x80, 0x43, 0x50, 0x24, 0x12, 0x21, 0x14, 0xcd, 0x77, 0xeb, 0x21, 0xcc, 0x5c, 0x09,
+ 0x64, 0xf3, 0xc7, 0xcb, 0xc5, 0x4b, 0xc3, 0xe7, 0xed, 0xe7, 0x86, 0x2c, 0x1d, 0x8e, 0x19,
+ 0x52, 0x9b, 0x2a, 0x0c, 0x18, 0x72, 0x0b, 0x1e, 0x1b, 0xb0, 0x0f, 0x42, 0x99, 0x04, 0xae,
+ 0xd5, 0xb7, 0x89, 0x1a, 0xb9, 0x4f, 0xd6, 0xaf, 0xf3, 0xc9, 0x93, 0x6f, 0xb0, 0x60, 0x83,
+ 0x6e, 0x6b, 0xd1, 0x5f, 0x3f, 0x1a, 0x83, 0x1e, 0x24, 0x00, 0x87, 0xb5, 0x3e, 0xdb, 0xf9,
+ 0x4d, 0xa7, 0x16, 0x2e, 0x19, 0x5b, 0x8f, 0x1b, 0x0d, 0x47, 0x72, 0x42, 0xe9, 0x0a, 0x11,
+ 0x08, 0x2d, 0x88, 0x1c, 0xbc, 0xc7, 0xb4, 0xbe, 0x29, 0x4d, 0x03, 0x5e, 0xec, 0xdf, 0xf3,
+ 0x3d, 0x2f, 0xe8, 0x1d, 0x9a, 0xd2, 0xd1, 0xab, 0x41, 0x3d, 0x87, 0x11, 0x45, 0xb0, 0x0d,
+ 0x46, 0xf5, 0xe8, 0x95, 0x62, 0x1c, 0x68, 0xf7, 0xa6, 0x5b, 0x39, 0x4e, 0xbf, 0x47, 0xba,
+ 0x5d, 0x7f, 0xb7, 0x6a, 0xf4, 0xba, 0x1d, 0x69, 0xf6, 0xa4, 0xe7, 0xe4, 0x6b, 0x3b, 0x0d,
+ 0x23, 0x16, 0x4a, 0xb2, 0x68, 0xf0, 0xb2, 0x0d, 0x09, 0x17, 0x6a, 0x63, 0x8c, 0x83, 0xd3,
+ 0xbd, 0x05, 0xc9, 0xf6, 0xf0, 0xa1, 0x31, 0x0b, 0x2c, 0xac, 0x83, 0xac, 0x80, 0x34, 0x32,
+ 0xb4, 0xec, 0xd0, 0xbc, 0x54, 0x82, 0x9a, 0xc8, 0xf6, 0xa0, 0x7d, 0xc6, 0x79, 0x73, 0xf4,
+ 0x20, 0x99, 0xf3, 0xb4, 0x01, 0xde, 0x91, 0x27, 0xf2, 0xc0, 0xdc, 0x81, 0x00, 0x4e, 0x7e,
+ 0x07, 0x99, 0xc8, 0x3a, 0x51, 0xbc, 0x38, 0xd6, 0x8a, 0xa2, 0xde, 0x3b, 0x6a, 0x8c, 0x1a,
+ 0x7c, 0x81, 0x0f, 0x3a, 0x1f, 0xe4, 0x05, 0x7b, 0x20, 0x35, 0x6b, 0xa5, 0x6a, 0xa7, 0xe7,
+ 0xbc, 0x9c, 0x20, 0xec, 0x00, 0x15, 0xe2, 0x51, 0xaf, 0x77, 0xeb, 0x29, 0x3c, 0x7d, 0x2e,
+ 0x00, 0x5c, 0x81, 0x21, 0xfa, 0x35, 0x6f, 0x40, 0xef, 0xfb, 0xd1, 0x3f, 0xcc, 0x9d, 0x55,
+ 0x53, 0xfb, 0x5a, 0xa5, 0x56, 0x89, 0x0b, 0x52, 0xeb, 0x57, 0x73, 0x4f, 0x1b, 0x67, 0x24,
+ 0xcb, 0xb8, 0x6a, 0x10, 0x69, 0xd6, 0xfb, 0x52, 0x40, 0xff, 0x20, 0xa5, 0xf3, 0x72, 0xe1,
+ 0x3d, 0xa4, 0x8c, 0x81, 0x66, 0x16, 0x0d, 0x5d, 0xad, 0xa8, 0x50, 0x25, 0x78, 0x31, 0x77,
+ 0x0c, 0x57, 0xe4, 0xe9, 0x15, 0x2d, 0xdb, 0x07, 0x87, 0xc8, 0xb0, 0x43, 0xde, 0xfc, 0xfe,
+ 0xa9, 0xeb, 0xf5, 0xb0, 0xd3, 0x7b, 0xe9, 0x1f, 0x6e, 0xca, 0xe4, 0x03, 0x95, 0xc5, 0xd1,
+ 0x59, 0x72, 0x63, 0xf0, 0x86, 0x54, 0xe8, 0x16, 0x62, 0x0b, 0x35, 0x29, 0xc2, 0x68, 0xd0,
+ 0xd6, 0x3e, 0x90, 0x60, 0x57, 0x1d, 0xc9, 0xed, 0x3f, 0xed, 0xb0, 0x2f, 0x7e, 0x97, 0x02,
+ 0x51, 0xec, 0xee, 0x6f, 0x82, 0x74, 0x76, 0x7f, 0xfb, 0xd6, 0xc4, 0xc3, 0xdd, 0xe8, 0xb1,
+ 0x60, 0xfc, 0xc6, 0xb9, 0x0d, 0x6a, 0x33, 0x78, 0xc6, 0xc1, 0xbf, 0x86, 0x2c, 0x50, 0xcc,
+ 0x9a, 0x70, 0x8e, 0x7b, 0xec, 0xab, 0x95, 0xac, 0x53, 0xa0, 0x4b, 0x07, 0x88, 0xaf, 0x42,
+ 0xed, 0x19, 0x8d, 0xf6, 0x32, 0x17, 0x48, 0x47, 0x1d, 0x41, 0x6f, 0xfe, 0x2e, 0xa7, 0x8f,
+ 0x4b, 0xa0, 0x51, 0xf3, 0xbf, 0x02, 0x0a, 0x48, 0x58, 0xf7, 0xa1, 0x6d, 0xea, 0xa5, 0x13,
+ 0x5a, 0x5b, 0xea, 0x0c, 0x9e, 0x52, 0x4f, 0x9e, 0xb9, 0x71, 0x7f, 0x23, 0x83, 0xda, 0x1b,
+ 0x86, 0x9a, 0x41, 0x29, 0xda, 0x70, 0xe7, 0x64, 0xa1, 0x7b, 0xd5, 0x0a, 0x22, 0x0d, 0x5c,
+ 0x40, 0xc4, 0x81, 0x07, 0x25, 0x35, 0x4a, 0x1c, 0x10, 0xdb, 0x45, 0x0a, 0xff, 0x36, 0xd4,
+ 0xe0, 0xeb, 0x5f, 0x68, 0xd6, 0x67, 0xc6, 0xd0, 0x8b, 0x76, 0x1a, 0x7d, 0x59, 0x42, 0xa1,
+ 0xcb, 0x96, 0x4d, 0x84, 0x09, 0x9a, 0x3d, 0xe0, 0x52, 0x85, 0x6e, 0x48, 0x90, 0x85, 0x2a,
+ 0x63, 0xb2, 0x69, 0xd2, 0x00, 0x43, 0x31, 0x37, 0xb3, 0x52, 0xaf, 0x62, 0xfa, 0xc1, 0xe0,
+ 0x03, 0xfb, 0x62, 0xaa, 0x88, 0xc9, 0xb2, 0x2c, 0xd5, 0xa8, 0xf5, 0xa5, 0x4c, 0x12, 0x59,
+ 0x4e, 0x06, 0x5e, 0x9b, 0x15, 0x66, 0x11, 0xb2, 0x27, 0x92, 0xdc, 0x98, 0x59, 0xde, 0xdf,
+ 0xfa, 0x9a, 0x32, 0x2e, 0xc0, 0x5d, 0x3c, 0x33, 0x41, 0x6d, 0xaf, 0xb2, 0x25, 0x23, 0x14,
+ 0xa5, 0x7b, 0xc7, 0x9b, 0x68, 0xf3, 0xda, 0xeb, 0xe3, 0xa9, 0xe2, 0x6f, 0x0e, 0x1d, 0x1c,
+ 0xba, 0x55, 0xb6, 0x34, 0x6a, 0x93, 0x1f, 0x1f, 0xb8, 0x34, 0xc8, 0x84, 0x08, 0xb1, 0x6b,
+ 0x6a, 0x28, 0x74, 0x74, 0xe5, 0xeb, 0x75, 0xe9, 0x7c, 0xd8, 0xba, 0xd8, 0x42, 0xa5, 0xee,
+ 0x1f, 0x80, 0xd9, 0x96, 0xb2, 0x2e, 0xe7, 0xbf, 0xba, 0xeb, 0xd1, 0x69, 0xbb, 0x8f, 0xfd,
+ 0x5a, 0x63, 0x8f, 0x39, 0x7f, 0xdf, 0x1d, 0x37, 0xd2, 0x18, 0x35, 0x9d, 0xb6, 0xcc, 0xe4,
+ 0x27, 0x81, 0x89, 0x38, 0x38, 0x68, 0x33, 0xe7, 0x78, 0xd8, 0x76, 0xf5, 0xee, 0xd0, 0x4a,
+ 0x07, 0x69, 0x19, 0x7a, 0xad, 0x18, 0xb1, 0x94, 0x61, 0x45, 0x53, 0xa2, 0x48, 0xda, 0x96,
+ 0x4a, 0xf9, 0xee, 0x94, 0x2a, 0x1f, 0x6e, 0x18, 0x3c, 0x92, 0x46, 0xd1, 0x1a, 0x28, 0x18,
+ 0x32, 0x1f, 0x3a, 0x45, 0xbe, 0x04, 0x35, 0x92, 0xe5, 0xa3, 0xcb, 0xb5, 0x2e, 0x32, 0x43,
+ 0xac, 0x65, 0x17, 0x89, 0x99, 0x15, 0x03, 0x9e, 0xb1, 0x23, 0x2f, 0xed, 0x76, 0x4d, 0xd8,
+ 0xac, 0x21, 0x40, 0xc4, 0x99, 0x4e, 0x65, 0x71, 0x2c, 0xb3, 0x45, 0xab, 0xfb, 0xe7, 0x72,
+ 0x39, 0x56, 0x30, 0x6d, 0xfb, 0x74, 0xeb, 0x99, 0xf3, 0xcd, 0x57, 0x5c, 0x78, 0x75, 0xe9,
+ 0x8d, 0xc3, 0xa2, 0xfb, 0x5d, 0xe0, 0x90, 0xc5, 0x55, 0xad, 0x91, 0x53, 0x4e, 0x9e, 0xbd,
+ 0x8c, 0x49, 0xa4, 0xa4, 0x69, 0x10, 0x0c, 0xc5, 0x76, 0xe9, 0x25, 0x86, 0x8d, 0x66, 0x23,
+ 0xa8, 0xdb, 0x5c, 0xe8, 0xd9, 0x30, 0xe1, 0x15, 0x7b, 0xc0, 0x99, 0x0f, 0x03, 0xec, 0xaa,
+ 0x12, 0xef, 0xce, 0xd4, 0xea, 0x55, 0x5c, 0x08, 0x86, 0xf4, 0xf4, 0xb0, 0x83, 0x42, 0x95,
+ 0x37, 0xb6, 0x38, 0xe0, 0x2b, 0x54, 0x89, 0xbd, 0x4e, 0x20, 0x9d, 0x3f, 0xc3, 0x4b, 0xb7,
+ 0xec, 0xfa, 0x5a, 0x14, 0x03, 0xcb, 0x64, 0xc8, 0x34, 0x4a, 0x4b, 0x6e, 0xf8, 0x6e, 0x56,
+ 0xf6, 0xdd, 0x5f, 0xa1, 0x24, 0xe2, 0xd4, 0xd0, 0x82, 0x64, 0x1f, 0x8e, 0x9b, 0xfa, 0xb4,
+ 0xcb, 0xdb, 0x0a, 0xe8, 0x15, 0xfc, 0x15, 0xab, 0x4b, 0x18, 0xbf, 0xd4, 0x42, 0x14, 0x48,
+ 0x82, 0x85, 0xdd, 0xeb, 0x49, 0x1b, 0x0b, 0x0b, 0x05, 0xe9, 0xb4, 0xa1, 0x33, 0x0a, 0x5d,
+ 0x0e, 0x6c, 0x4b, 0xc0, 0xd6, 0x6c, 0x7c, 0xfb, 0x69, 0x0b, 0x53, 0x19, 0xe4, 0xf3, 0x35,
+ 0xfc, 0xbe, 0xa1, 0x34, 0x02, 0x09, 0x4f, 0x74, 0x86, 0x92, 0xcd, 0x5d, 0x1a, 0xc1, 0x27,
+ 0x0c, 0xf2, 0xc5, 0xcf, 0xdd, 0x23, 0x93, 0x02, 0xbd, 0x41, 0x5e, 0x42, 0xf0, 0xa0, 0x9d,
+ 0x0c, 0x72, 0xc8, 0xec, 0x32, 0x0a, 0x8a, 0xfd, 0x3d, 0x5a, 0x41, 0x27, 0x0c, 0x88, 0x59,
+ 0xad, 0x94, 0x2e, 0xef, 0x5d, 0x8f, 0xc7, 0xdf, 0x66, 0xe4, 0xdd, 0x56, 0x6c, 0x7b, 0xca,
+ 0x55, 0x81, 0xae, 0xae, 0x5c, 0x1b, 0x1a, 0xab, 0xae, 0x99, 0x8d, 0xcc, 0x42, 0x97, 0x59,
+ 0xf4, 0x14, 0x3f, 0x75, 0xc6, 0xd1, 0x88, 0xba, 0xaa, 0x84, 0x4a, 0xd0, 0x34, 0x08, 0x3b,
+ 0x7d, 0xdb, 0x15, 0x06, 0xb0, 0x5c, 0xbd, 0x40, 0xf5, 0xa8, 0xec, 0xae, 0x36, 0x40, 0xdd,
+ 0x90, 0x1c, 0x3e, 0x0d, 0x7e, 0x73, 0xc7, 0xc2, 0xc5, 0x6a, 0xff, 0x52, 0x05, 0x7f, 0xbe,
+ 0xd0, 0x92, 0xfd, 0xb3, 0x6f, 0xff, 0x5d, 0xb7, 0x97, 0x64, 0x73, 0x7b, 0xca, 0xd1, 0x98,
+ 0x24, 0x6b, 0x0b, 0x01, 0x68, 0xdd, 0x27, 0x85, 0x85, 0xb5, 0x83, 0xc1, 0xe0, 0x50, 0x64,
+ 0xc7, 0xaf, 0xf1, 0xc6, 0x4d, 0xb1, 0xef, 0xc9, 0xb4, 0x0a, 0x6d, 0x65, 0xf3, 0x47, 0xcc,
+ 0xa3, 0x02, 0x21, 0x0c, 0xbe, 0x22, 0x29, 0x05, 0xcf, 0x5f, 0xe8, 0x94, 0x6c, 0xe5, 0xdc,
+ 0xc4, 0xdf, 0xbe, 0x3e, 0xa8, 0xb4, 0x18, 0xb0, 0x99, 0xb8, 0x6f, 0xff, 0x5d, 0xb9, 0xfd,
+ 0x3b, 0x5d, 0x16, 0xbf, 0x3e, 0xd8, 0xb3, 0xd8, 0x08, 0x34, 0xf6, 0x47, 0x35, 0x5b, 0x72,
+ 0x1a, 0x33, 0xad, 0x52, 0x5d, 0xb8, 0xd0, 0x77, 0xc6, 0xab, 0xba, 0x55, 0x09, 0x5f, 0x02,
+ 0xf8, 0xd4, 0x5f, 0x53, 0x06, 0x91, 0xcd, 0x74, 0x42, 0xae, 0x54, 0x91, 0x81, 0x62, 0x13,
+ 0x6f, 0xd8, 0xa9, 0x77, 0xc3, 0x6c, 0xcb, 0xf1, 0x29, 0x5a, 0xcc, 0xda, 0x35, 0xbd, 0x52,
+ 0x23, 0xbe, 0x59, 0xeb, 0x12, 0x6d, 0xb7, 0x53, 0xee, 0xfc, 0xb4, 0x1b, 0x13, 0x5e, 0xba,
+ 0x16, 0x7c, 0xc5, 0xf3, 0xe3, 0x6d, 0x07, 0x78, 0xf5, 0x2b, 0x21, 0x05, 0x88, 0x4c, 0xc0,
+ 0xa1, 0xe3, 0x36, 0x10, 0xf8, 0x1b, 0xd8, 0x17, 0xfb, 0x6a, 0x4e, 0xd8, 0xb3, 0x47, 0x2d,
+ 0x99, 0xbd, 0xbb, 0x5d, 0x37, 0x7d, 0xba, 0xf1, 0xe1, 0x7c, 0xc0, 0xc5, 0x54, 0x62, 0x7f,
+ 0xcf, 0x5a, 0x4a, 0x93, 0xcc, 0xf1, 0x1b, 0x34, 0xc8, 0xa6, 0x05, 0x4c, 0x55, 0x8b, 0x54,
+ 0x84, 0xd5, 0x77, 0xeb, 0xc0, 0x6d, 0x3a, 0x29, 0xbd, 0x75, 0x61, 0x09, 0x9a, 0x2c, 0xbb,
+ 0xf7, 0x18, 0x79, 0x34, 0x90, 0x24, 0xa5, 0x81, 0x70, 0x87, 0xc5, 0x02, 0x7c, 0xba, 0xd4,
+ 0x5e, 0x14, 0x8e, 0xe4, 0xed, 0xa2, 0x61, 0x6a, 0xb9, 0x6e, 0xb5, 0x4a, 0xb9, 0x01, 0x46,
+ 0xf4, 0xcf, 0xbc, 0x09, 0x2f, 0x27, 0x4b, 0xbd, 0x86, 0x7a, 0x10, 0xe1, 0xd4, 0xc8, 0xd9,
+ 0x20, 0x8d, 0x8a, 0x63, 0x00, 0x63, 0x44, 0xeb, 0x54, 0x0b, 0x75, 0x49, 0x10, 0xa2, 0xa7,
+ 0xad, 0xb9, 0xd1, 0x01, 0x80, 0x63, 0x25, 0xc8, 0x12, 0xa6, 0xce, 0x1e, 0xbe, 0xfe, 0x7e,
+ 0x5f, 0x3c, 0xdb, 0x34, 0xea, 0x37, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x8c, 0x9a, 0xb6,
+ 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x1b, 0xb4, 0xea, 0x56,
+ 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xd6, 0x2e, 0xde, 0x1f, 0x9d,
+ 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x66, 0x4e, 0x1e, 0x9f, 0x9d, 0xb8, 0xf2, 0x47,
+ 0x0c, 0x9a, 0xb6, 0xee, 0x3f, 0xfc, 0x7a, 0x57, 0x0d, 0x79, 0x70, 0x62, 0x27, 0xad, 0xb9,
+ 0xd1, 0x01, 0x61, 0x40, 0x02, 0x67, 0x2d, 0xd8, 0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xd7, 0x2c,
+ 0xbb, 0xf4, 0x4b, 0xf5, 0x49, 0xf1, 0x60, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x01,
+ 0x80, 0x63, 0x25, 0xa9, 0xb1, 0xe0, 0x42, 0xe7, 0x4c, 0x1a, 0x97, 0xac, 0xbb, 0xf4, 0x6a,
+ 0x37, 0xcd, 0x18, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0xa8, 0xd2, 0x07, 0x6d, 0x58, 0x32,
+ 0xe6, 0x4e, 0x1e, 0x9f, 0xbc, 0xfa, 0x57, 0x0d, 0x79, 0x51, 0x20, 0xc2, 0x06, 0x6f, 0x5c,
+ 0x1b, 0x95, 0xa8, 0xb3, 0xc5, 0xe9, 0x31, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93,
+ 0x85, 0x69, 0x31, 0xc1, 0xe1, 0x21, 0xc0, 0xe3, 0x44, 0x0a, 0x77, 0x6c, 0x5a, 0x17, 0x8d,
+ 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x17, 0xac, 0xbb, 0xf4, 0x4b, 0x14,
+ 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xb3, 0xc5, 0xe9, 0x31, 0xc1, 0x00, 0x82, 0x67, 0x4c,
+ 0xfb, 0x55, 0x28, 0xd2, 0x26, 0xaf, 0xbd, 0xd9, 0x11, 0x81, 0x61, 0x21, 0xa1, 0xa1, 0xc0,
+ 0x02, 0x86, 0x6f, 0x5c, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xdd,
+ 0x19, 0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x7c, 0x5b, 0x15, 0x89, 0x90, 0x83, 0x84, 0x6b, 0x54,
+ 0x0b, 0x75, 0x68, 0x52, 0x07, 0x6d, 0x58, 0x32, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0xed, 0x58,
+ 0x32, 0xe6, 0x4e, 0xff, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xdd, 0x38, 0xd3, 0x05, 0x88, 0x92,
+ 0xa6, 0xaf, 0xdc, 0x1b, 0xb4, 0xcb, 0xf5, 0x68, 0x52, 0x07, 0x8c, 0x7b, 0x55, 0x09, 0x90,
+ 0x83, 0x84, 0x6b, 0x54, 0x2a, 0xb7, 0xec, 0x3b, 0xd5, 0x09, 0x90, 0xa2, 0xc6, 0x0e, 0x7f,
+ 0x7c, 0x7a, 0x57, 0x0d, 0x98, 0xb2, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0x0c, 0x7b, 0x74, 0x4b,
+ 0x14, 0x8b, 0x94, 0xaa, 0xb7, 0xcd, 0x18, 0x93, 0xa4, 0xca, 0x16, 0xae, 0xbf, 0xdd, 0x19,
+ 0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x63, 0x44, 0xeb, 0x35, 0xc9,
+ 0x10, 0x83, 0x65, 0x48, 0x12, 0xa6, 0xce, 0x1e, 0x9f, 0xbc, 0xdb, 0x15, 0x89, 0x71, 0x60,
+ 0x23, 0xc4, 0xeb, 0x54, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xcf, 0x81, 0x10, 0xac, 0x74
+};
- return report;
-}
+// clang-format off
diff --git a/drivers/sensors/pmw3389.h b/drivers/sensors/pmw3389.h
index db4a763fe3..fafd1e2046 100644
--- a/drivers/sensors/pmw3389.h
+++ b/drivers/sensors/pmw3389.h
@@ -1,76 +1,77 @@
-/* Copyright 2021 Alabastard (@Alabastard-64)
- * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- *
- * 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/>.
- */
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
-#ifndef PMW3389_CPI
-# define PMW3389_CPI 2000
+#if !defined(PMW33XX_CPI)
+# define PMW33XX_CPI 2000
#endif
-#ifndef PMW3389_CLOCK_SPEED
-# define PMW3389_CLOCK_SPEED 2000000
-#endif
-
-#ifndef PMW3389_SPI_LSBFIRST
-# define PMW3389_SPI_LSBFIRST false
-#endif
-
-#ifndef PMW3389_SPI_MODE
-# define PMW3389_SPI_MODE 3
-#endif
-
-#ifndef PMW3389_SPI_DIVISOR
-# ifdef __AVR__
-# define PMW3389_SPI_DIVISOR (F_CPU / PMW3389_CLOCK_SPEED)
-# else
-# define PMW3389_SPI_DIVISOR 64
-# endif
-#endif
-
-#ifndef PMW3389_LIFTOFF_DISTANCE
-# define PMW3389_LIFTOFF_DISTANCE 0x02
-#endif
-
-#ifndef ROTATIONAL_TRANSFORM_ANGLE
-# define ROTATIONAL_TRANSFORM_ANGLE 0x00
-#endif
-
-#ifndef PMW3389_CS_PIN
-# error "No chip select pin defined -- missing PMW3389_CS_PIN"
-#endif
+#define PMW33XX_CPI_STEP 50
+#define PMW33XX_CPI_MIN 50
+#define PMW33XX_CPI_MAX 16000
-typedef struct {
- int8_t motion;
- bool isMotion; // True if a motion is detected.
- bool isOnSurface; // True when a chip is on a surface
- int16_t dx; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
- int8_t mdx;
- int16_t dy; // displacement on y directions.
- int8_t mdy;
-} report_pmw3389_t;
+#define PMW33XX_FIRMWARE_LENGTH 4094
-bool pmw3389_init(void);
-void pmw3389_upload_firmware(void);
-bool pmw3389_check_signature(void);
-uint16_t pmw3389_get_cpi(void);
-void pmw3389_set_cpi(uint16_t cpi);
-/* Reads and clears the current delta values on the sensor */
-report_pmw3389_t pmw3389_read_burst(void);
+// PMW3389 register addresses
+// clang-format off
+#define REG_Product_ID 0x00
+#define REG_Revision_ID 0x01
+#define REG_Motion 0x02
+#define REG_Delta_X_L 0x03
+#define REG_Delta_X_H 0x04
+#define REG_Delta_Y_L 0x05
+#define REG_Delta_Y_H 0x06
+#define REG_SQUAL 0x07
+#define REG_RawData_Sum 0x08
+#define REG_Maximum_RawData 0x09
+#define REG_Minimum_RawData 0x0a
+#define REG_Shutter_Lower 0x0b
+#define REG_Shutter_Upper 0x0c
+#define REG_Ripple_Control 0x0d
+#define REG_Resolution_L 0x0e
+#define REG_Resolution_H 0x0f
+#define REG_Config2 0x10
+#define REG_Angle_Tune 0x11
+#define REG_Frame_Capture 0x12
+#define REG_SROM_Enable 0x13
+#define REG_Run_Downshift 0x14
+#define REG_Rest1_Rate_Lower 0x15
+#define REG_Rest1_Rate_Upper 0x16
+#define REG_Rest1_Downshift 0x17
+#define REG_Rest2_Rate_Lower 0x18
+#define REG_Rest2_Rate_Upper 0x19
+#define REG_Rest2_Downshift 0x1a
+#define REG_Rest3_Rate_Lower 0x1b
+#define REG_Rest3_Rate_Upper 0x1c
+#define REG_Observation 0x24
+#define REG_Data_Out_Lower 0x25
+#define REG_Data_Out_Upper 0x26
+#define REG_SROM_ID 0x2a
+#define REG_Min_SQ_Run 0x2b
+#define REG_RawData_Threshold 0x2c
+#define REG_Control2 0x2d
+#define REG_Config5_L 0x2e
+#define REG_Config5_H 0x2f
+#define REG_Power_Up_Reset 0X3a
+#define REG_Shutdown 0x3b
+#define REG_Inverse_Product_ID 0x3f
+#define REG_LiftCutoff_Cal3 0x41
+#define REG_Angle_Snap 0x42
+#define REG_LiftCutoff_Cal1 0x4a
+#define REG_Motion_Burst 0x50
+#define REG_SROM_Load_Burst 0x62
+#define REG_Lift_Config 0x63
+#define REG_RawData_Burst 0x64
+#define REG_LiftCutoff_Cal2 0x65
+#define REG_LiftCutoff_Cal_Timeout 0x71
+#define REG_LiftCutoff_Cal_Min_Length 0x72
+#define REG_PWM_Period_Cnt 0x73
+#define REG_PWM_Width_Cnt 0x74
+// clang-format on
diff --git a/drivers/sensors/pmw3389_firmware.h b/drivers/sensors/pmw3389_firmware.h
deleted file mode 100644
index cd9638b605..0000000000
--- a/drivers/sensors/pmw3389_firmware.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
- * Copyright 2019 Sunjun Kim
- * Copyright 2020 Ploopy Corporation
- *
- * 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 "progmem.h"
-
-// PID, Inverse PID, SROM version
-const uint8_t firmware_signature[] PROGMEM = {0x42, 0xBD, 0x04};
-
-#define FIRMWARE_LENGTH 4094
-
-// Firmware Blob for PMW3389
-
-// clang-format off
-const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
- 0x01, 0xe8, 0xba, 0x26, 0x0b, 0xb2, 0xbe, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0xa8, 0xb3,
- 0xe4, 0x2b, 0xb5, 0xe8, 0x53, 0x07, 0x6d, 0x3b, 0xd1, 0x20, 0xc2, 0x06, 0x6f, 0x3d, 0xd9,
- 0x11, 0xa0, 0xc2, 0xe7, 0x2d, 0xb9, 0xd1, 0x20, 0xa3, 0xa5, 0xc8, 0xf3, 0x64, 0x4a, 0xf7,
- 0x4d, 0x18, 0x93, 0xa4, 0xca, 0xf7, 0x6c, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xfe, 0x7e, 0x7e,
- 0x5f, 0x1d, 0x99, 0xb0, 0xc3, 0xe5, 0x29, 0xd3, 0x03, 0x65, 0x48, 0x12, 0x87, 0x6d, 0x58,
- 0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xf2, 0x4f, 0xfd, 0x59, 0x11, 0x81, 0x61, 0x21, 0xc0, 0x02,
- 0x86, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x55, 0x28, 0xb3, 0xe4, 0x4a, 0x16,
- 0xab, 0xbf, 0xdd, 0x38, 0xf2, 0x66, 0x4e, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xc8,
- 0x12, 0xa6, 0xaf, 0xdc, 0x3a, 0xd1, 0x41, 0x60, 0x75, 0x58, 0x24, 0x92, 0xd4, 0x72, 0x6c,
- 0xe0, 0x2f, 0xfd, 0x23, 0x8d, 0x1c, 0x5b, 0xb2, 0x97, 0x36, 0x3d, 0x0b, 0xa2, 0x49, 0xb1,
- 0x58, 0xf2, 0x1f, 0xc0, 0xcb, 0xf8, 0x41, 0x4f, 0xcd, 0x1e, 0x6b, 0x39, 0xa7, 0x2b, 0xe9,
- 0x30, 0x16, 0x83, 0xd2, 0x0e, 0x47, 0x8f, 0xe3, 0xb1, 0xdf, 0xa2, 0x15, 0xdb, 0x5d, 0x30,
- 0xc5, 0x1a, 0xab, 0x31, 0x99, 0xf3, 0xfa, 0xb2, 0x86, 0x69, 0xad, 0x7a, 0xe8, 0xa7, 0x18,
- 0x6a, 0xcc, 0xc8, 0x65, 0x23, 0x87, 0xa8, 0x5f, 0xf5, 0x21, 0x59, 0x75, 0x09, 0x71, 0x45,
- 0x55, 0x25, 0x4b, 0xda, 0xa1, 0xc3, 0xf7, 0x41, 0xab, 0x59, 0xd9, 0x74, 0x12, 0x55, 0x5f,
- 0xbc, 0xaf, 0xd9, 0xfd, 0xb0, 0x1e, 0xa3, 0x0f, 0xff, 0xde, 0x11, 0x16, 0x6a, 0xae, 0x0e,
- 0xe1, 0x5d, 0x3c, 0x10, 0x43, 0x9a, 0xa1, 0x0b, 0x24, 0x8f, 0x0d, 0x7f, 0x0b, 0x5e, 0x4c,
- 0x42, 0xa4, 0x84, 0x2c, 0x40, 0xd0, 0x55, 0x39, 0xe6, 0x4b, 0xf8, 0x9b, 0x2f, 0xdc, 0x28,
- 0xff, 0xfa, 0xb5, 0x85, 0x19, 0xe5, 0x28, 0xa1, 0x77, 0xaa, 0x73, 0xf3, 0x03, 0xc7, 0x62,
- 0xa6, 0x91, 0x18, 0xc9, 0xb0, 0xcd, 0x05, 0xdc, 0xca, 0x81, 0x26, 0x1a, 0x47, 0x40, 0xda,
- 0x36, 0x7d, 0x6a, 0x53, 0xc8, 0x5a, 0x77, 0x5d, 0x19, 0xa4, 0x1b, 0x23, 0x83, 0xd0, 0xb2,
- 0xaa, 0x0e, 0xbf, 0x77, 0x4e, 0x3a, 0x3b, 0x59, 0x00, 0x31, 0x0d, 0x02, 0x1b, 0x88, 0x7a,
- 0xd4, 0xbd, 0x9d, 0xcc, 0x58, 0x04, 0x69, 0xf6, 0x3b, 0xca, 0x42, 0xe2, 0xfd, 0xc3, 0x3d,
- 0x39, 0xc5, 0xd0, 0x71, 0xe4, 0xc8, 0xb7, 0x3e, 0x3f, 0xc8, 0xe9, 0xca, 0xc9, 0x3f, 0x04,
- 0x4e, 0x1b, 0x79, 0xca, 0xa5, 0x61, 0xc2, 0xed, 0x1d, 0xa6, 0xda, 0x5a, 0xe9, 0x7f, 0x65,
- 0x8c, 0xbe, 0x12, 0x6e, 0xa4, 0x5b, 0x33, 0x2f, 0x84, 0x28, 0x9c, 0x1c, 0x88, 0x2d, 0xff,
- 0x07, 0xbf, 0xa6, 0xd7, 0x5a, 0x88, 0x86, 0xb0, 0x3f, 0xf6, 0x31, 0x5b, 0x11, 0x6d, 0xf5,
- 0x58, 0xeb, 0x58, 0x02, 0x9e, 0xb5, 0x9a, 0xb1, 0xff, 0x25, 0x9d, 0x8b, 0x4f, 0xb6, 0x0a,
- 0xf9, 0xea, 0x3e, 0x3f, 0x21, 0x09, 0x65, 0x21, 0x22, 0xfe, 0x3d, 0x4e, 0x11, 0x5b, 0x9e,
- 0x5a, 0x59, 0x8b, 0xdd, 0xd8, 0xce, 0xd6, 0xd9, 0x59, 0xd2, 0x1e, 0xfd, 0xef, 0x0d, 0x1b,
- 0xd9, 0x61, 0x7f, 0xd7, 0x2d, 0xad, 0x62, 0x09, 0xe5, 0x22, 0x63, 0xea, 0xc7, 0x31, 0xd9,
- 0xa1, 0x38, 0x80, 0x5c, 0xa7, 0x32, 0x82, 0xec, 0x1b, 0xa2, 0x49, 0x5a, 0x06, 0xd2, 0x7c,
- 0xc9, 0x96, 0x57, 0xbb, 0x17, 0x75, 0xfc, 0x7a, 0x8f, 0x0d, 0x77, 0xb5, 0x7a, 0x8e, 0x3e,
- 0xf4, 0xba, 0x2f, 0x69, 0x13, 0x26, 0xd6, 0xd9, 0x21, 0x60, 0x2f, 0x21, 0x3e, 0x87, 0xee,
- 0xfd, 0x87, 0x16, 0x0d, 0xc8, 0x08, 0x00, 0x25, 0x71, 0xac, 0x2c, 0x03, 0x2a, 0x37, 0x2d,
- 0xb3, 0x34, 0x09, 0x91, 0xe3, 0x06, 0x2c, 0x38, 0x37, 0x95, 0x3b, 0x17, 0x7a, 0xaf, 0xac,
- 0x99, 0x55, 0xab, 0x41, 0x39, 0x5f, 0x8e, 0xa6, 0x43, 0x80, 0x03, 0x88, 0x6f, 0x7d, 0xbd,
- 0x5a, 0xb4, 0x2b, 0x32, 0x23, 0x5a, 0xa9, 0x31, 0x32, 0x39, 0x4c, 0x5b, 0xf4, 0x6b, 0xaf,
- 0x66, 0x6f, 0x3c, 0x8e, 0x2d, 0x82, 0x97, 0x9f, 0x4a, 0x01, 0xdc, 0x99, 0x98, 0x00, 0xec,
- 0x38, 0x7a, 0x79, 0x70, 0xa6, 0x85, 0xd6, 0x21, 0x63, 0x0d, 0x45, 0x9a, 0x2e, 0x5e, 0xa7,
- 0xb1, 0xea, 0x66, 0x6a, 0xbc, 0x62, 0x2d, 0x7b, 0x7d, 0x85, 0xea, 0x95, 0x2f, 0xc0, 0xe8,
- 0x6f, 0x35, 0xa0, 0x3a, 0x02, 0x25, 0xbc, 0xb2, 0x5f, 0x5c, 0x43, 0x96, 0xcc, 0x26, 0xd2,
- 0x16, 0xb4, 0x96, 0x73, 0xd7, 0x13, 0xc7, 0xae, 0x53, 0x15, 0x31, 0x89, 0x68, 0x66, 0x6d,
- 0x2c, 0x92, 0x1f, 0xcc, 0x5b, 0xa7, 0x8f, 0x5d, 0xbb, 0xc9, 0xdb, 0xe8, 0x3b, 0x9d, 0x61,
- 0x74, 0x8b, 0x05, 0xa1, 0x58, 0x52, 0x68, 0xee, 0x3d, 0x39, 0x79, 0xa0, 0x9b, 0xdd, 0xe1,
- 0x55, 0xc9, 0x60, 0xeb, 0xad, 0xb8, 0x5b, 0xc2, 0x5a, 0xb5, 0x2c, 0x18, 0x55, 0xa9, 0x50,
- 0xc3, 0xf6, 0x72, 0x5f, 0xcc, 0xe2, 0xf4, 0x55, 0xb5, 0xd6, 0xb5, 0x4a, 0x99, 0xa5, 0x28,
- 0x74, 0x97, 0x18, 0xe8, 0xc0, 0x84, 0x89, 0x50, 0x03, 0x86, 0x4d, 0x1a, 0xb7, 0x09, 0x90,
- 0xa2, 0x01, 0x04, 0xbb, 0x73, 0x62, 0xcb, 0x97, 0x22, 0x70, 0x5d, 0x52, 0x41, 0x8e, 0xd9,
- 0x90, 0x15, 0xaa, 0xab, 0x0a, 0x31, 0x65, 0xb4, 0xda, 0xd0, 0xee, 0x24, 0xc9, 0x41, 0x91,
- 0x1e, 0xbc, 0x46, 0x70, 0x40, 0x9d, 0xda, 0x0e, 0x2a, 0xe4, 0xb2, 0x4c, 0x9f, 0xf2, 0xfc,
- 0xf3, 0x84, 0x17, 0x44, 0x1e, 0xd7, 0xca, 0x23, 0x1f, 0x3f, 0x5a, 0x22, 0x3d, 0xaf, 0x9b,
- 0x2d, 0xfc, 0x41, 0xad, 0x26, 0xb4, 0x45, 0x67, 0x0b, 0x80, 0x0e, 0xf9, 0x61, 0x37, 0xec,
- 0x3b, 0xf4, 0x4b, 0x14, 0xdf, 0x5a, 0x0c, 0x3a, 0x50, 0x0b, 0x14, 0x0c, 0x72, 0xae, 0xc6,
- 0xc5, 0xec, 0x35, 0x53, 0x2d, 0x59, 0xed, 0x91, 0x74, 0xe2, 0xc4, 0xc8, 0xf2, 0x25, 0x6b,
- 0x97, 0x6f, 0xc9, 0x76, 0xce, 0xa9, 0xb1, 0x99, 0x8f, 0x5a, 0x92, 0x3b, 0xc4, 0x8d, 0x54,
- 0x50, 0x40, 0x72, 0xd6, 0x90, 0x83, 0xfc, 0xe5, 0x49, 0x8b, 0x17, 0xf5, 0xfd, 0x6b, 0x8d,
- 0x32, 0x02, 0xe9, 0x0a, 0xfe, 0xbf, 0x00, 0x6b, 0xa3, 0xad, 0x5f, 0x09, 0x4b, 0x97, 0x2b,
- 0x00, 0x58, 0x65, 0x2e, 0x07, 0x49, 0x0a, 0x3b, 0x6b, 0x2e, 0x50, 0x6c, 0x1d, 0xac, 0xb7,
- 0x6a, 0x26, 0xd8, 0x13, 0xa4, 0xca, 0x16, 0xae, 0xab, 0x93, 0xb9, 0x1c, 0x1c, 0xb4, 0x47,
- 0x6a, 0x38, 0x36, 0x17, 0x27, 0xc9, 0x7f, 0xc7, 0x64, 0xcb, 0x89, 0x58, 0xc5, 0x61, 0xc2,
- 0xc6, 0xea, 0x15, 0x0b, 0x34, 0x0c, 0x5d, 0x61, 0x76, 0x6e, 0x2b, 0x62, 0x40, 0x92, 0xa3,
- 0x6c, 0xef, 0xf4, 0xe4, 0xc3, 0xa1, 0xa8, 0xf5, 0x94, 0x79, 0x0d, 0xd1, 0x3d, 0xcb, 0x3d,
- 0x40, 0xb6, 0xd0, 0xf0, 0x10, 0x54, 0xd8, 0x47, 0x25, 0x51, 0xc5, 0x41, 0x79, 0x00, 0xe5,
- 0xa0, 0x72, 0xde, 0xbb, 0x3b, 0x62, 0x17, 0xf6, 0xbc, 0x5d, 0x00, 0x76, 0x2e, 0xa7, 0x3b,
- 0xb6, 0xf1, 0x98, 0x72, 0x59, 0x2a, 0x73, 0xb0, 0x21, 0xd6, 0x49, 0xe0, 0xc0, 0xd5, 0xeb,
- 0x02, 0x7d, 0x4b, 0x41, 0x28, 0x70, 0x2d, 0xec, 0x2b, 0x71, 0x1f, 0x0b, 0xb9, 0x71, 0x63,
- 0x06, 0xe6, 0xbc, 0x60, 0xbb, 0xf4, 0x9a, 0x62, 0x43, 0x09, 0x18, 0x4e, 0x93, 0x06, 0x4d,
- 0x76, 0xfa, 0x7f, 0xbd, 0x02, 0xe4, 0x50, 0x91, 0x12, 0xe5, 0x86, 0xff, 0x64, 0x1e, 0xaf,
- 0x7e, 0xb3, 0xb2, 0xde, 0x89, 0xc1, 0xa2, 0x6f, 0x40, 0x7b, 0x41, 0x51, 0x63, 0xea, 0x25,
- 0xd1, 0x97, 0x57, 0x92, 0xa8, 0x45, 0xa1, 0xa5, 0x45, 0x21, 0x43, 0x7f, 0x83, 0x15, 0x29,
- 0xd0, 0x30, 0x53, 0x32, 0xb4, 0x5a, 0x17, 0x96, 0xbc, 0xc2, 0x68, 0xa9, 0xb7, 0xaf, 0xac,
- 0xdf, 0xf1, 0xe3, 0x89, 0xba, 0x24, 0x79, 0x54, 0xc6, 0x14, 0x07, 0x1c, 0x1e, 0x0d, 0x3a,
- 0x6b, 0xe5, 0x3d, 0x4e, 0x10, 0x60, 0x96, 0xec, 0x6c, 0xda, 0x47, 0xae, 0x03, 0x25, 0x39,
- 0x1d, 0x74, 0xc8, 0xac, 0x6a, 0xf2, 0x6b, 0x05, 0x2a, 0x9a, 0xe7, 0xe8, 0x92, 0xd6, 0xc2,
- 0x6d, 0xfa, 0xe8, 0xa7, 0x9d, 0x5f, 0x48, 0xc9, 0x75, 0xf1, 0x66, 0x6a, 0xdb, 0x5d, 0x9a,
- 0xcd, 0x27, 0xdd, 0xb9, 0x24, 0x04, 0x9c, 0x18, 0xc2, 0x6d, 0x0c, 0x91, 0x34, 0x48, 0x42,
- 0x6f, 0xe9, 0x59, 0x70, 0xc4, 0x7e, 0x81, 0x0e, 0x32, 0x0a, 0x93, 0x48, 0xb0, 0xc0, 0x15,
- 0x9e, 0x05, 0xac, 0x36, 0x16, 0xcb, 0x59, 0x65, 0xa0, 0x83, 0xdf, 0x3e, 0xda, 0xfb, 0x1d,
- 0x1a, 0xdb, 0x65, 0xec, 0x9a, 0xc6, 0xc3, 0x8e, 0x3c, 0x45, 0xfd, 0xc8, 0xf5, 0x1c, 0x6a,
- 0x67, 0x0d, 0x8f, 0x99, 0x7d, 0x30, 0x21, 0x8c, 0xea, 0x22, 0x87, 0x65, 0xc9, 0xb2, 0x4c,
- 0xe4, 0x1b, 0x46, 0xba, 0x54, 0xbd, 0x7c, 0xca, 0xd5, 0x8f, 0x5b, 0xa5, 0x01, 0x04, 0xd8,
- 0x0a, 0x16, 0xbf, 0xb9, 0x50, 0x2e, 0x37, 0x2f, 0x64, 0xf3, 0x70, 0x11, 0x02, 0x05, 0x31,
- 0x9b, 0xa0, 0xb2, 0x01, 0x5e, 0x4f, 0x19, 0xc9, 0xd4, 0xea, 0xa1, 0x79, 0x54, 0x53, 0xa7,
- 0xde, 0x2f, 0x49, 0xd3, 0xd1, 0x63, 0xb5, 0x03, 0x15, 0x4e, 0xbf, 0x04, 0xb3, 0x26, 0x8b,
- 0x20, 0xb2, 0x45, 0xcf, 0xcd, 0x5b, 0x82, 0x32, 0x88, 0x61, 0xa7, 0xa8, 0xb2, 0xa0, 0x72,
- 0x96, 0xc0, 0xdb, 0x2b, 0xe2, 0x5f, 0xba, 0xe3, 0xf5, 0x8a, 0xde, 0xf1, 0x18, 0x01, 0x16,
- 0x40, 0xd9, 0x86, 0x12, 0x09, 0x18, 0x1b, 0x05, 0x0c, 0xb1, 0xb5, 0x47, 0xe2, 0x43, 0xab,
- 0xfe, 0x92, 0x63, 0x7e, 0x95, 0x2b, 0xf0, 0xaf, 0xe1, 0xf1, 0xc3, 0x4a, 0xff, 0x2b, 0x09,
- 0xbb, 0x4a, 0x0e, 0x9a, 0xc4, 0xd8, 0x64, 0x7d, 0x83, 0xa0, 0x4f, 0x44, 0xdb, 0xc4, 0xa8,
- 0x58, 0xef, 0xfc, 0x9e, 0x77, 0xf9, 0xa6, 0x8f, 0x58, 0x8b, 0x12, 0xf4, 0xe9, 0x81, 0x12,
- 0x47, 0x51, 0x41, 0x83, 0xef, 0xf6, 0x73, 0xbc, 0x8e, 0x0f, 0x4c, 0x8f, 0x4e, 0x69, 0x90,
- 0x77, 0x29, 0x5d, 0x92, 0xb0, 0x6d, 0x06, 0x67, 0x29, 0x60, 0xbd, 0x4b, 0x17, 0xc8, 0x89,
- 0x69, 0x28, 0x29, 0xd6, 0x78, 0xcb, 0x11, 0x4c, 0xba, 0x8b, 0x68, 0xae, 0x7e, 0x9f, 0xef,
- 0x95, 0xda, 0xe2, 0x9e, 0x7f, 0xe9, 0x55, 0xe5, 0xe1, 0xe2, 0xb7, 0xe6, 0x5f, 0xbb, 0x2c,
- 0xa2, 0xe6, 0xee, 0xc7, 0x0a, 0x60, 0xa9, 0xd1, 0x80, 0xdf, 0x7f, 0xd6, 0x97, 0xab, 0x1d,
- 0x22, 0x25, 0xfc, 0x79, 0x23, 0xe0, 0xae, 0xc5, 0xef, 0x16, 0xa4, 0xa1, 0x0f, 0x92, 0xa9,
- 0xc7, 0xe3, 0x3a, 0x55, 0xdf, 0x62, 0x49, 0xd9, 0xf5, 0x84, 0x49, 0xc5, 0x90, 0x34, 0xd3,
- 0xe1, 0xac, 0x99, 0x21, 0xb1, 0x02, 0x76, 0x4a, 0xfa, 0xd4, 0xbb, 0xa4, 0x9c, 0xa2, 0xe2,
- 0xcb, 0x3d, 0x3b, 0x14, 0x75, 0x60, 0xd1, 0x02, 0xb4, 0xa3, 0xb4, 0x72, 0x06, 0xf9, 0x19,
- 0x9c, 0xe2, 0xe4, 0xa7, 0x0f, 0x25, 0x88, 0xc6, 0x86, 0xd6, 0x8c, 0x74, 0x4e, 0x6e, 0xfc,
- 0xa8, 0x48, 0x9e, 0xa7, 0x9d, 0x1a, 0x4b, 0x37, 0x09, 0xc8, 0xb0, 0x10, 0xbe, 0x6f, 0xfe,
- 0xa3, 0xc4, 0x7a, 0xb5, 0x3d, 0xe8, 0x30, 0xf1, 0x0d, 0xa0, 0xb2, 0x44, 0xfc, 0x9b, 0x8c,
- 0xf8, 0x61, 0xed, 0x81, 0xd1, 0x62, 0x11, 0xb4, 0xe1, 0xd5, 0x39, 0x52, 0x89, 0xd3, 0xa8,
- 0x49, 0x31, 0xdf, 0xb6, 0xf9, 0x91, 0xf4, 0x1c, 0x9d, 0x09, 0x95, 0x40, 0x56, 0xe7, 0xe3,
- 0xcd, 0x5c, 0x92, 0xc1, 0x1d, 0x6b, 0xe9, 0x78, 0x6f, 0x8e, 0x94, 0x42, 0x66, 0xa2, 0xaa,
- 0xd3, 0xc8, 0x2e, 0xe3, 0xf6, 0x07, 0x72, 0x0b, 0x6b, 0x1e, 0x7b, 0xb9, 0x7c, 0xe0, 0xa0,
- 0xbc, 0xd9, 0x25, 0xdf, 0x87, 0xa8, 0x5f, 0x9c, 0xcc, 0xf0, 0xdb, 0x42, 0x8e, 0x07, 0x31,
- 0x13, 0x01, 0x66, 0x32, 0xd1, 0xb8, 0xd6, 0xe3, 0x5e, 0x12, 0x76, 0x61, 0xd3, 0x38, 0x89,
- 0xe6, 0x17, 0x6f, 0xa5, 0xf2, 0x71, 0x0e, 0xa5, 0xe2, 0x88, 0x30, 0xbb, 0xbe, 0x8a, 0xea,
- 0xc7, 0x62, 0xc4, 0xcf, 0xb8, 0xcd, 0x33, 0x8d, 0x3d, 0x3e, 0xb5, 0x60, 0x3a, 0x03, 0x92,
- 0xe4, 0x6d, 0x1b, 0xe0, 0xb4, 0x84, 0x08, 0x55, 0x88, 0xa7, 0x3a, 0xb9, 0x3d, 0x43, 0xc3,
- 0xc0, 0xfa, 0x07, 0x6a, 0xca, 0x94, 0xad, 0x99, 0x55, 0xf1, 0xf1, 0xc0, 0x23, 0x87, 0x1d,
- 0x3d, 0x1c, 0xd1, 0x66, 0xa0, 0x57, 0x10, 0x52, 0xa2, 0x7f, 0xbe, 0xf9, 0x88, 0xb6, 0x02,
- 0xbf, 0x08, 0x23, 0xa9, 0x0c, 0x63, 0x17, 0x2a, 0xae, 0xf5, 0xf7, 0xb7, 0x21, 0x83, 0x92,
- 0x31, 0x23, 0x0d, 0x20, 0xc3, 0xc2, 0x05, 0x21, 0x62, 0x8e, 0x45, 0xe8, 0x14, 0xc1, 0xda,
- 0x75, 0xb8, 0xf8, 0x92, 0x01, 0xd0, 0x5d, 0x18, 0x9f, 0x99, 0x11, 0x19, 0xf5, 0x35, 0xe8,
- 0x7f, 0x20, 0x88, 0x8c, 0x05, 0x75, 0xf5, 0xd7, 0x40, 0x17, 0xbb, 0x1e, 0x36, 0x52, 0xd9,
- 0xa4, 0x9c, 0xc2, 0x9d, 0x42, 0x81, 0xd8, 0xc7, 0x8a, 0xe7, 0x4c, 0x81, 0xe0, 0xb7, 0x57,
- 0xed, 0x48, 0x8b, 0xf0, 0x97, 0x15, 0x61, 0xd9, 0x2c, 0x7c, 0x45, 0xaf, 0xc2, 0xcd, 0xfc,
- 0xaa, 0x13, 0xad, 0x59, 0xcc, 0xb2, 0xb2, 0x6e, 0xdd, 0x63, 0x9c, 0x32, 0x0f, 0xec, 0x83,
- 0xbe, 0x78, 0xac, 0x91, 0x44, 0x1a, 0x1f, 0xea, 0xfd, 0x5d, 0x8e, 0xb4, 0xc0, 0x84, 0xd4,
- 0xac, 0xb4, 0x87, 0x5f, 0xac, 0xef, 0xdf, 0xcd, 0x12, 0x56, 0xc8, 0xcd, 0xfe, 0xc5, 0xda,
- 0xd3, 0xc1, 0x69, 0xf3, 0x61, 0x05, 0xea, 0x25, 0xe2, 0x12, 0x05, 0x8f, 0x39, 0x08, 0x08,
- 0x7c, 0x37, 0xb6, 0x7e, 0x5b, 0xd8, 0xb1, 0x0e, 0xf2, 0xdb, 0x4b, 0xf1, 0xad, 0x90, 0x01,
- 0x57, 0xcd, 0xa0, 0xb4, 0x52, 0xe8, 0xf3, 0xd7, 0x8a, 0xbd, 0x4f, 0x9f, 0x21, 0x40, 0x72,
- 0xa4, 0xfc, 0x0b, 0x01, 0x2b, 0x2f, 0xb6, 0x4c, 0x95, 0x2d, 0x35, 0x33, 0x41, 0x6b, 0xa0,
- 0x93, 0xe7, 0x2c, 0xf2, 0xd3, 0x72, 0x8b, 0xf4, 0x4f, 0x15, 0x3c, 0xaf, 0xd6, 0x12, 0xde,
- 0x3f, 0x83, 0x3f, 0xff, 0xf8, 0x7f, 0xf6, 0xcc, 0xa6, 0x7f, 0xc9, 0x9a, 0x6e, 0x1f, 0xc1,
- 0x0c, 0xfb, 0xee, 0x9c, 0xe7, 0xaf, 0xc9, 0x26, 0x54, 0xef, 0xb0, 0x39, 0xef, 0xb2, 0xe9,
- 0x23, 0xc4, 0xef, 0xd1, 0xa1, 0xa4, 0x25, 0x24, 0x6f, 0x8d, 0x6a, 0xe5, 0x8a, 0x32, 0x3a,
- 0xaf, 0xfc, 0xda, 0xce, 0x18, 0x25, 0x42, 0x07, 0x4d, 0x45, 0x8b, 0xdf, 0x85, 0xcf, 0x55,
- 0xb2, 0x24, 0xfe, 0x9c, 0x69, 0x74, 0xa7, 0x6e, 0xa0, 0xce, 0xc0, 0x39, 0xf4, 0x86, 0xc6,
- 0x8d, 0xae, 0xb9, 0x48, 0x64, 0x13, 0x0b, 0x40, 0x81, 0xa2, 0xc9, 0xa8, 0x85, 0x51, 0xee,
- 0x9f, 0xcf, 0xa2, 0x8c, 0x19, 0x52, 0x48, 0xe2, 0xc1, 0xa8, 0x58, 0xb4, 0x10, 0x24, 0x06,
- 0x58, 0x51, 0xfc, 0xb9, 0x12, 0xec, 0xfd, 0x73, 0xb4, 0x6d, 0x84, 0xfa, 0x06, 0x8b, 0x05,
- 0x0b, 0x2d, 0xd6, 0xd6, 0x1f, 0x29, 0x82, 0x9f, 0x19, 0x12, 0x1e, 0xb2, 0x04, 0x8f, 0x7f,
- 0x4d, 0xbd, 0x30, 0x2e, 0xe3, 0xe0, 0x88, 0x29, 0xc5, 0x93, 0xd6, 0x6c, 0x1f, 0x29, 0x45,
- 0x91, 0xa7, 0x58, 0xcd, 0x05, 0x17, 0xd6, 0x6d, 0xb3, 0xca, 0x66, 0xcc, 0x3c, 0x4a, 0x74,
- 0xfd, 0x08, 0x10, 0xa6, 0x99, 0x92, 0x10, 0xd2, 0x85, 0xab, 0x6e, 0x1d, 0x0e, 0x8b, 0x26,
- 0x46, 0xd1, 0x6c, 0x84, 0xc0, 0x26, 0x43, 0x59, 0x68, 0xf0, 0x13, 0x1d, 0xfb, 0xe3, 0xd1,
- 0xd2, 0xb4, 0x71, 0x9e, 0xf2, 0x59, 0x6a, 0x33, 0x29, 0x79, 0xd2, 0xd7, 0x26, 0xf1, 0xae,
- 0x78, 0x9e, 0x1f, 0x0f, 0x3f, 0xe3, 0xe8, 0xd0, 0x27, 0x78, 0x77, 0xf6, 0xac, 0x9c, 0x56,
- 0x39, 0x73, 0x8a, 0x6b, 0x2f, 0x34, 0x78, 0xb1, 0x11, 0xdb, 0xa4, 0x5c, 0x80, 0x01, 0x71,
- 0x6a, 0xc2, 0xd1, 0x2e, 0x5e, 0x76, 0x28, 0x70, 0x93, 0xae, 0x3e, 0x78, 0xb0, 0x1f, 0x0f,
- 0xda, 0xbf, 0xfb, 0x8a, 0x67, 0x65, 0x4f, 0x91, 0xed, 0x49, 0x75, 0x78, 0x62, 0xa2, 0x93,
- 0xb5, 0x70, 0x7f, 0x4d, 0x08, 0x4e, 0x79, 0x61, 0xa8, 0x5f, 0x7f, 0xb4, 0x65, 0x9f, 0x91,
- 0x54, 0x3a, 0xe8, 0x50, 0x33, 0xd3, 0xd5, 0x8a, 0x7c, 0xf3, 0x9e, 0x8b, 0x77, 0x7b, 0xc6,
- 0xc6, 0x0c, 0x45, 0x95, 0x1f, 0xb0, 0xd0, 0x0b, 0x27, 0x4a, 0xfd, 0xc7, 0xf7, 0x0d, 0x5a,
- 0x43, 0xc9, 0x7d, 0x35, 0xb0, 0x7d, 0xc4, 0x9c, 0x57, 0x1e, 0x76, 0x0d, 0xf1, 0x95, 0x30,
- 0x71, 0xcc, 0xb3, 0x66, 0x3b, 0x63, 0xa8, 0x6c, 0xa3, 0x43, 0xa0, 0x24, 0xcc, 0xb7, 0x53,
- 0xfe, 0xfe, 0xbc, 0x6e, 0x60, 0x89, 0xaf, 0x16, 0x21, 0xc8, 0x91, 0x6a, 0x89, 0xce, 0x80,
- 0x2c, 0xf1, 0x59, 0xce, 0xc3, 0x60, 0x61, 0x3b, 0x0b, 0x19, 0xfe, 0x99, 0xac, 0x65, 0x90,
- 0x15, 0x12, 0x05, 0xac, 0x7e, 0xff, 0x98, 0x7b, 0x66, 0x64, 0x0e, 0x4b, 0x5b, 0xaa, 0x8d,
- 0x3b, 0xd2, 0x56, 0xcf, 0x99, 0x39, 0xee, 0x22, 0x81, 0xd0, 0x60, 0x06, 0x66, 0x20, 0x81,
- 0x48, 0x3c, 0x6f, 0x3a, 0x77, 0xba, 0xcb, 0x52, 0xac, 0x79, 0x56, 0xaf, 0xe9, 0x16, 0x17,
- 0x0a, 0xa3, 0x82, 0x08, 0xd5, 0x3c, 0x97, 0xcb, 0x09, 0xff, 0x7f, 0xf9, 0x4f, 0x60, 0x05,
- 0xb9, 0x53, 0x26, 0xaa, 0xb8, 0x50, 0xaa, 0x19, 0x25, 0xae, 0x5f, 0xea, 0x8a, 0xd0, 0x89,
- 0x12, 0x80, 0x43, 0x50, 0x24, 0x12, 0x21, 0x14, 0xcd, 0x77, 0xeb, 0x21, 0xcc, 0x5c, 0x09,
- 0x64, 0xf3, 0xc7, 0xcb, 0xc5, 0x4b, 0xc3, 0xe7, 0xed, 0xe7, 0x86, 0x2c, 0x1d, 0x8e, 0x19,
- 0x52, 0x9b, 0x2a, 0x0c, 0x18, 0x72, 0x0b, 0x1e, 0x1b, 0xb0, 0x0f, 0x42, 0x99, 0x04, 0xae,
- 0xd5, 0xb7, 0x89, 0x1a, 0xb9, 0x4f, 0xd6, 0xaf, 0xf3, 0xc9, 0x93, 0x6f, 0xb0, 0x60, 0x83,
- 0x6e, 0x6b, 0xd1, 0x5f, 0x3f, 0x1a, 0x83, 0x1e, 0x24, 0x00, 0x87, 0xb5, 0x3e, 0xdb, 0xf9,
- 0x4d, 0xa7, 0x16, 0x2e, 0x19, 0x5b, 0x8f, 0x1b, 0x0d, 0x47, 0x72, 0x42, 0xe9, 0x0a, 0x11,
- 0x08, 0x2d, 0x88, 0x1c, 0xbc, 0xc7, 0xb4, 0xbe, 0x29, 0x4d, 0x03, 0x5e, 0xec, 0xdf, 0xf3,
- 0x3d, 0x2f, 0xe8, 0x1d, 0x9a, 0xd2, 0xd1, 0xab, 0x41, 0x3d, 0x87, 0x11, 0x45, 0xb0, 0x0d,
- 0x46, 0xf5, 0xe8, 0x95, 0x62, 0x1c, 0x68, 0xf7, 0xa6, 0x5b, 0x39, 0x4e, 0xbf, 0x47, 0xba,
- 0x5d, 0x7f, 0xb7, 0x6a, 0xf4, 0xba, 0x1d, 0x69, 0xf6, 0xa4, 0xe7, 0xe4, 0x6b, 0x3b, 0x0d,
- 0x23, 0x16, 0x4a, 0xb2, 0x68, 0xf0, 0xb2, 0x0d, 0x09, 0x17, 0x6a, 0x63, 0x8c, 0x83, 0xd3,
- 0xbd, 0x05, 0xc9, 0xf6, 0xf0, 0xa1, 0x31, 0x0b, 0x2c, 0xac, 0x83, 0xac, 0x80, 0x34, 0x32,
- 0xb4, 0xec, 0xd0, 0xbc, 0x54, 0x82, 0x9a, 0xc8, 0xf6, 0xa0, 0x7d, 0xc6, 0x79, 0x73, 0xf4,
- 0x20, 0x99, 0xf3, 0xb4, 0x01, 0xde, 0x91, 0x27, 0xf2, 0xc0, 0xdc, 0x81, 0x00, 0x4e, 0x7e,
- 0x07, 0x99, 0xc8, 0x3a, 0x51, 0xbc, 0x38, 0xd6, 0x8a, 0xa2, 0xde, 0x3b, 0x6a, 0x8c, 0x1a,
- 0x7c, 0x81, 0x0f, 0x3a, 0x1f, 0xe4, 0x05, 0x7b, 0x20, 0x35, 0x6b, 0xa5, 0x6a, 0xa7, 0xe7,
- 0xbc, 0x9c, 0x20, 0xec, 0x00, 0x15, 0xe2, 0x51, 0xaf, 0x77, 0xeb, 0x29, 0x3c, 0x7d, 0x2e,
- 0x00, 0x5c, 0x81, 0x21, 0xfa, 0x35, 0x6f, 0x40, 0xef, 0xfb, 0xd1, 0x3f, 0xcc, 0x9d, 0x55,
- 0x53, 0xfb, 0x5a, 0xa5, 0x56, 0x89, 0x0b, 0x52, 0xeb, 0x57, 0x73, 0x4f, 0x1b, 0x67, 0x24,
- 0xcb, 0xb8, 0x6a, 0x10, 0x69, 0xd6, 0xfb, 0x52, 0x40, 0xff, 0x20, 0xa5, 0xf3, 0x72, 0xe1,
- 0x3d, 0xa4, 0x8c, 0x81, 0x66, 0x16, 0x0d, 0x5d, 0xad, 0xa8, 0x50, 0x25, 0x78, 0x31, 0x77,
- 0x0c, 0x57, 0xe4, 0xe9, 0x15, 0x2d, 0xdb, 0x07, 0x87, 0xc8, 0xb0, 0x43, 0xde, 0xfc, 0xfe,
- 0xa9, 0xeb, 0xf5, 0xb0, 0xd3, 0x7b, 0xe9, 0x1f, 0x6e, 0xca, 0xe4, 0x03, 0x95, 0xc5, 0xd1,
- 0x59, 0x72, 0x63, 0xf0, 0x86, 0x54, 0xe8, 0x16, 0x62, 0x0b, 0x35, 0x29, 0xc2, 0x68, 0xd0,
- 0xd6, 0x3e, 0x90, 0x60, 0x57, 0x1d, 0xc9, 0xed, 0x3f, 0xed, 0xb0, 0x2f, 0x7e, 0x97, 0x02,
- 0x51, 0xec, 0xee, 0x6f, 0x82, 0x74, 0x76, 0x7f, 0xfb, 0xd6, 0xc4, 0xc3, 0xdd, 0xe8, 0xb1,
- 0x60, 0xfc, 0xc6, 0xb9, 0x0d, 0x6a, 0x33, 0x78, 0xc6, 0xc1, 0xbf, 0x86, 0x2c, 0x50, 0xcc,
- 0x9a, 0x70, 0x8e, 0x7b, 0xec, 0xab, 0x95, 0xac, 0x53, 0xa0, 0x4b, 0x07, 0x88, 0xaf, 0x42,
- 0xed, 0x19, 0x8d, 0xf6, 0x32, 0x17, 0x48, 0x47, 0x1d, 0x41, 0x6f, 0xfe, 0x2e, 0xa7, 0x8f,
- 0x4b, 0xa0, 0x51, 0xf3, 0xbf, 0x02, 0x0a, 0x48, 0x58, 0xf7, 0xa1, 0x6d, 0xea, 0xa5, 0x13,
- 0x5a, 0x5b, 0xea, 0x0c, 0x9e, 0x52, 0x4f, 0x9e, 0xb9, 0x71, 0x7f, 0x23, 0x83, 0xda, 0x1b,
- 0x86, 0x9a, 0x41, 0x29, 0xda, 0x70, 0xe7, 0x64, 0xa1, 0x7b, 0xd5, 0x0a, 0x22, 0x0d, 0x5c,
- 0x40, 0xc4, 0x81, 0x07, 0x25, 0x35, 0x4a, 0x1c, 0x10, 0xdb, 0x45, 0x0a, 0xff, 0x36, 0xd4,
- 0xe0, 0xeb, 0x5f, 0x68, 0xd6, 0x67, 0xc6, 0xd0, 0x8b, 0x76, 0x1a, 0x7d, 0x59, 0x42, 0xa1,
- 0xcb, 0x96, 0x4d, 0x84, 0x09, 0x9a, 0x3d, 0xe0, 0x52, 0x85, 0x6e, 0x48, 0x90, 0x85, 0x2a,
- 0x63, 0xb2, 0x69, 0xd2, 0x00, 0x43, 0x31, 0x37, 0xb3, 0x52, 0xaf, 0x62, 0xfa, 0xc1, 0xe0,
- 0x03, 0xfb, 0x62, 0xaa, 0x88, 0xc9, 0xb2, 0x2c, 0xd5, 0xa8, 0xf5, 0xa5, 0x4c, 0x12, 0x59,
- 0x4e, 0x06, 0x5e, 0x9b, 0x15, 0x66, 0x11, 0xb2, 0x27, 0x92, 0xdc, 0x98, 0x59, 0xde, 0xdf,
- 0xfa, 0x9a, 0x32, 0x2e, 0xc0, 0x5d, 0x3c, 0x33, 0x41, 0x6d, 0xaf, 0xb2, 0x25, 0x23, 0x14,
- 0xa5, 0x7b, 0xc7, 0x9b, 0x68, 0xf3, 0xda, 0xeb, 0xe3, 0xa9, 0xe2, 0x6f, 0x0e, 0x1d, 0x1c,
- 0xba, 0x55, 0xb6, 0x34, 0x6a, 0x93, 0x1f, 0x1f, 0xb8, 0x34, 0xc8, 0x84, 0x08, 0xb1, 0x6b,
- 0x6a, 0x28, 0x74, 0x74, 0xe5, 0xeb, 0x75, 0xe9, 0x7c, 0xd8, 0xba, 0xd8, 0x42, 0xa5, 0xee,
- 0x1f, 0x80, 0xd9, 0x96, 0xb2, 0x2e, 0xe7, 0xbf, 0xba, 0xeb, 0xd1, 0x69, 0xbb, 0x8f, 0xfd,
- 0x5a, 0x63, 0x8f, 0x39, 0x7f, 0xdf, 0x1d, 0x37, 0xd2, 0x18, 0x35, 0x9d, 0xb6, 0xcc, 0xe4,
- 0x27, 0x81, 0x89, 0x38, 0x38, 0x68, 0x33, 0xe7, 0x78, 0xd8, 0x76, 0xf5, 0xee, 0xd0, 0x4a,
- 0x07, 0x69, 0x19, 0x7a, 0xad, 0x18, 0xb1, 0x94, 0x61, 0x45, 0x53, 0xa2, 0x48, 0xda, 0x96,
- 0x4a, 0xf9, 0xee, 0x94, 0x2a, 0x1f, 0x6e, 0x18, 0x3c, 0x92, 0x46, 0xd1, 0x1a, 0x28, 0x18,
- 0x32, 0x1f, 0x3a, 0x45, 0xbe, 0x04, 0x35, 0x92, 0xe5, 0xa3, 0xcb, 0xb5, 0x2e, 0x32, 0x43,
- 0xac, 0x65, 0x17, 0x89, 0x99, 0x15, 0x03, 0x9e, 0xb1, 0x23, 0x2f, 0xed, 0x76, 0x4d, 0xd8,
- 0xac, 0x21, 0x40, 0xc4, 0x99, 0x4e, 0x65, 0x71, 0x2c, 0xb3, 0x45, 0xab, 0xfb, 0xe7, 0x72,
- 0x39, 0x56, 0x30, 0x6d, 0xfb, 0x74, 0xeb, 0x99, 0xf3, 0xcd, 0x57, 0x5c, 0x78, 0x75, 0xe9,
- 0x8d, 0xc3, 0xa2, 0xfb, 0x5d, 0xe0, 0x90, 0xc5, 0x55, 0xad, 0x91, 0x53, 0x4e, 0x9e, 0xbd,
- 0x8c, 0x49, 0xa4, 0xa4, 0x69, 0x10, 0x0c, 0xc5, 0x76, 0xe9, 0x25, 0x86, 0x8d, 0x66, 0x23,
- 0xa8, 0xdb, 0x5c, 0xe8, 0xd9, 0x30, 0xe1, 0x15, 0x7b, 0xc0, 0x99, 0x0f, 0x03, 0xec, 0xaa,
- 0x12, 0xef, 0xce, 0xd4, 0xea, 0x55, 0x5c, 0x08, 0x86, 0xf4, 0xf4, 0xb0, 0x83, 0x42, 0x95,
- 0x37, 0xb6, 0x38, 0xe0, 0x2b, 0x54, 0x89, 0xbd, 0x4e, 0x20, 0x9d, 0x3f, 0xc3, 0x4b, 0xb7,
- 0xec, 0xfa, 0x5a, 0x14, 0x03, 0xcb, 0x64, 0xc8, 0x34, 0x4a, 0x4b, 0x6e, 0xf8, 0x6e, 0x56,
- 0xf6, 0xdd, 0x5f, 0xa1, 0x24, 0xe2, 0xd4, 0xd0, 0x82, 0x64, 0x1f, 0x8e, 0x9b, 0xfa, 0xb4,
- 0xcb, 0xdb, 0x0a, 0xe8, 0x15, 0xfc, 0x15, 0xab, 0x4b, 0x18, 0xbf, 0xd4, 0x42, 0x14, 0x48,
- 0x82, 0x85, 0xdd, 0xeb, 0x49, 0x1b, 0x0b, 0x0b, 0x05, 0xe9, 0xb4, 0xa1, 0x33, 0x0a, 0x5d,
- 0x0e, 0x6c, 0x4b, 0xc0, 0xd6, 0x6c, 0x7c, 0xfb, 0x69, 0x0b, 0x53, 0x19, 0xe4, 0xf3, 0x35,
- 0xfc, 0xbe, 0xa1, 0x34, 0x02, 0x09, 0x4f, 0x74, 0x86, 0x92, 0xcd, 0x5d, 0x1a, 0xc1, 0x27,
- 0x0c, 0xf2, 0xc5, 0xcf, 0xdd, 0x23, 0x93, 0x02, 0xbd, 0x41, 0x5e, 0x42, 0xf0, 0xa0, 0x9d,
- 0x0c, 0x72, 0xc8, 0xec, 0x32, 0x0a, 0x8a, 0xfd, 0x3d, 0x5a, 0x41, 0x27, 0x0c, 0x88, 0x59,
- 0xad, 0x94, 0x2e, 0xef, 0x5d, 0x8f, 0xc7, 0xdf, 0x66, 0xe4, 0xdd, 0x56, 0x6c, 0x7b, 0xca,
- 0x55, 0x81, 0xae, 0xae, 0x5c, 0x1b, 0x1a, 0xab, 0xae, 0x99, 0x8d, 0xcc, 0x42, 0x97, 0x59,
- 0xf4, 0x14, 0x3f, 0x75, 0xc6, 0xd1, 0x88, 0xba, 0xaa, 0x84, 0x4a, 0xd0, 0x34, 0x08, 0x3b,
- 0x7d, 0xdb, 0x15, 0x06, 0xb0, 0x5c, 0xbd, 0x40, 0xf5, 0xa8, 0xec, 0xae, 0x36, 0x40, 0xdd,
- 0x90, 0x1c, 0x3e, 0x0d, 0x7e, 0x73, 0xc7, 0xc2, 0xc5, 0x6a, 0xff, 0x52, 0x05, 0x7f, 0xbe,
- 0xd0, 0x92, 0xfd, 0xb3, 0x6f, 0xff, 0x5d, 0xb7, 0x97, 0x64, 0x73, 0x7b, 0xca, 0xd1, 0x98,
- 0x24, 0x6b, 0x0b, 0x01, 0x68, 0xdd, 0x27, 0x85, 0x85, 0xb5, 0x83, 0xc1, 0xe0, 0x50, 0x64,
- 0xc7, 0xaf, 0xf1, 0xc6, 0x4d, 0xb1, 0xef, 0xc9, 0xb4, 0x0a, 0x6d, 0x65, 0xf3, 0x47, 0xcc,
- 0xa3, 0x02, 0x21, 0x0c, 0xbe, 0x22, 0x29, 0x05, 0xcf, 0x5f, 0xe8, 0x94, 0x6c, 0xe5, 0xdc,
- 0xc4, 0xdf, 0xbe, 0x3e, 0xa8, 0xb4, 0x18, 0xb0, 0x99, 0xb8, 0x6f, 0xff, 0x5d, 0xb9, 0xfd,
- 0x3b, 0x5d, 0x16, 0xbf, 0x3e, 0xd8, 0xb3, 0xd8, 0x08, 0x34, 0xf6, 0x47, 0x35, 0x5b, 0x72,
- 0x1a, 0x33, 0xad, 0x52, 0x5d, 0xb8, 0xd0, 0x77, 0xc6, 0xab, 0xba, 0x55, 0x09, 0x5f, 0x02,
- 0xf8, 0xd4, 0x5f, 0x53, 0x06, 0x91, 0xcd, 0x74, 0x42, 0xae, 0x54, 0x91, 0x81, 0x62, 0x13,
- 0x6f, 0xd8, 0xa9, 0x77, 0xc3, 0x6c, 0xcb, 0xf1, 0x29, 0x5a, 0xcc, 0xda, 0x35, 0xbd, 0x52,
- 0x23, 0xbe, 0x59, 0xeb, 0x12, 0x6d, 0xb7, 0x53, 0xee, 0xfc, 0xb4, 0x1b, 0x13, 0x5e, 0xba,
- 0x16, 0x7c, 0xc5, 0xf3, 0xe3, 0x6d, 0x07, 0x78, 0xf5, 0x2b, 0x21, 0x05, 0x88, 0x4c, 0xc0,
- 0xa1, 0xe3, 0x36, 0x10, 0xf8, 0x1b, 0xd8, 0x17, 0xfb, 0x6a, 0x4e, 0xd8, 0xb3, 0x47, 0x2d,
- 0x99, 0xbd, 0xbb, 0x5d, 0x37, 0x7d, 0xba, 0xf1, 0xe1, 0x7c, 0xc0, 0xc5, 0x54, 0x62, 0x7f,
- 0xcf, 0x5a, 0x4a, 0x93, 0xcc, 0xf1, 0x1b, 0x34, 0xc8, 0xa6, 0x05, 0x4c, 0x55, 0x8b, 0x54,
- 0x84, 0xd5, 0x77, 0xeb, 0xc0, 0x6d, 0x3a, 0x29, 0xbd, 0x75, 0x61, 0x09, 0x9a, 0x2c, 0xbb,
- 0xf7, 0x18, 0x79, 0x34, 0x90, 0x24, 0xa5, 0x81, 0x70, 0x87, 0xc5, 0x02, 0x7c, 0xba, 0xd4,
- 0x5e, 0x14, 0x8e, 0xe4, 0xed, 0xa2, 0x61, 0x6a, 0xb9, 0x6e, 0xb5, 0x4a, 0xb9, 0x01, 0x46,
- 0xf4, 0xcf, 0xbc, 0x09, 0x2f, 0x27, 0x4b, 0xbd, 0x86, 0x7a, 0x10, 0xe1, 0xd4, 0xc8, 0xd9,
- 0x20, 0x8d, 0x8a, 0x63, 0x00, 0x63, 0x44, 0xeb, 0x54, 0x0b, 0x75, 0x49, 0x10, 0xa2, 0xa7,
- 0xad, 0xb9, 0xd1, 0x01, 0x80, 0x63, 0x25, 0xc8, 0x12, 0xa6, 0xce, 0x1e, 0xbe, 0xfe, 0x7e,
- 0x5f, 0x3c, 0xdb, 0x34, 0xea, 0x37, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x8c, 0x9a, 0xb6,
- 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x1b, 0xb4, 0xea, 0x56,
- 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xd6, 0x2e, 0xde, 0x1f, 0x9d,
- 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x66, 0x4e, 0x1e, 0x9f, 0x9d, 0xb8, 0xf2, 0x47,
- 0x0c, 0x9a, 0xb6, 0xee, 0x3f, 0xfc, 0x7a, 0x57, 0x0d, 0x79, 0x70, 0x62, 0x27, 0xad, 0xb9,
- 0xd1, 0x01, 0x61, 0x40, 0x02, 0x67, 0x2d, 0xd8, 0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xd7, 0x2c,
- 0xbb, 0xf4, 0x4b, 0xf5, 0x49, 0xf1, 0x60, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x01,
- 0x80, 0x63, 0x25, 0xa9, 0xb1, 0xe0, 0x42, 0xe7, 0x4c, 0x1a, 0x97, 0xac, 0xbb, 0xf4, 0x6a,
- 0x37, 0xcd, 0x18, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0xa8, 0xd2, 0x07, 0x6d, 0x58, 0x32,
- 0xe6, 0x4e, 0x1e, 0x9f, 0xbc, 0xfa, 0x57, 0x0d, 0x79, 0x51, 0x20, 0xc2, 0x06, 0x6f, 0x5c,
- 0x1b, 0x95, 0xa8, 0xb3, 0xc5, 0xe9, 0x31, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93,
- 0x85, 0x69, 0x31, 0xc1, 0xe1, 0x21, 0xc0, 0xe3, 0x44, 0x0a, 0x77, 0x6c, 0x5a, 0x17, 0x8d,
- 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x17, 0xac, 0xbb, 0xf4, 0x4b, 0x14,
- 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xb3, 0xc5, 0xe9, 0x31, 0xc1, 0x00, 0x82, 0x67, 0x4c,
- 0xfb, 0x55, 0x28, 0xd2, 0x26, 0xaf, 0xbd, 0xd9, 0x11, 0x81, 0x61, 0x21, 0xa1, 0xa1, 0xc0,
- 0x02, 0x86, 0x6f, 0x5c, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xdd,
- 0x19, 0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x7c, 0x5b, 0x15, 0x89, 0x90, 0x83, 0x84, 0x6b, 0x54,
- 0x0b, 0x75, 0x68, 0x52, 0x07, 0x6d, 0x58, 0x32, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0xed, 0x58,
- 0x32, 0xe6, 0x4e, 0xff, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xdd, 0x38, 0xd3, 0x05, 0x88, 0x92,
- 0xa6, 0xaf, 0xdc, 0x1b, 0xb4, 0xcb, 0xf5, 0x68, 0x52, 0x07, 0x8c, 0x7b, 0x55, 0x09, 0x90,
- 0x83, 0x84, 0x6b, 0x54, 0x2a, 0xb7, 0xec, 0x3b, 0xd5, 0x09, 0x90, 0xa2, 0xc6, 0x0e, 0x7f,
- 0x7c, 0x7a, 0x57, 0x0d, 0x98, 0xb2, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0x0c, 0x7b, 0x74, 0x4b,
- 0x14, 0x8b, 0x94, 0xaa, 0xb7, 0xcd, 0x18, 0x93, 0xa4, 0xca, 0x16, 0xae, 0xbf, 0xdd, 0x19,
- 0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x63, 0x44, 0xeb, 0x35, 0xc9,
- 0x10, 0x83, 0x65, 0x48, 0x12, 0xa6, 0xce, 0x1e, 0x9f, 0xbc, 0xdb, 0x15, 0x89, 0x71, 0x60,
- 0x23, 0xc4, 0xeb, 0x54, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xcf, 0x81, 0x10, 0xac, 0x74
-};
-
-// clang-format off
diff --git a/drivers/sensors/pmw33xx_common.c b/drivers/sensors/pmw33xx_common.c
new file mode 100644
index 0000000000..13164cb150
--- /dev/null
+++ b/drivers/sensors/pmw33xx_common.c
@@ -0,0 +1,219 @@
+// Copyright 2022 Daniel Kao (dkao)
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2022 Ulrich Spörlein (@uqs)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "debug.h"
+#include "pmw33xx_common.h"
+#include "print.h"
+#include "string.h"
+#include "wait.h"
+#include "spi_master.h"
+#include "progmem.h"
+
+extern const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM;
+extern const uint8_t pmw33xx_firmware_signature[3] PROGMEM;
+
+static const pin_t cs_pins[] = PMW33XX_CS_PINS;
+static bool in_burst[sizeof(cs_pins) / sizeof(pin_t)] = {0};
+
+const size_t pmw33xx_number_of_sensors = sizeof(cs_pins) / sizeof(pin_t);
+
+bool __attribute__((cold)) pmw33xx_upload_firmware(uint8_t sensor);
+bool __attribute__((cold)) pmw33xx_check_signature(uint8_t sensor);
+
+void pmw33xx_set_cpi_all_sensors(uint16_t cpi) {
+ for (uint8_t sensor = 0; sensor < pmw33xx_number_of_sensors; sensor++) {
+ pmw33xx_set_cpi(sensor, cpi);
+ }
+}
+
+bool pmw33xx_spi_start(uint8_t sensor) {
+ if (!spi_start(cs_pins[sensor], false, 3, PMW33XX_SPI_DIVISOR)) {
+ spi_stop();
+ return false;
+ }
+ // tNCS-SCLK, 10ns
+ wait_us(1);
+ return true;
+}
+
+bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data) {
+ if (!pmw33xx_spi_start(sensor)) {
+ return false;
+ }
+
+ if (reg_addr != REG_Motion_Burst) {
+ in_burst[sensor] = false;
+ }
+
+ // send address of the register, with MSBit = 1 to indicate it's a write
+ uint8_t command[2] = {reg_addr | 0x80, data};
+ if (spi_transmit(command, sizeof(command)) != SPI_STATUS_SUCCESS) {
+ return false;
+ }
+
+ // tSCLK-NCS for write operation is 35us
+ wait_us(35);
+ spi_stop();
+
+ // tSWW/tSWR (=18us) minus tSCLK-NCS. Could be shortened, but it looks like
+ // a safe lower bound
+ wait_us(145);
+ return true;
+}
+
+uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr) {
+ if (!pmw33xx_spi_start(sensor)) {
+ return 0;
+ }
+
+ // send adress of the register, with MSBit = 0 to indicate it's a read
+ spi_write(reg_addr & 0x7f);
+ // tSRAD (=160us)
+ wait_us(160);
+ uint8_t data = spi_read();
+
+ // tSCLK-NCS, 120ns
+ wait_us(1);
+ spi_stop();
+
+ // tSRW/tSRR (=20us) mins tSCLK-NCS
+ wait_us(19);
+ return data;
+}
+
+bool pmw33xx_check_signature(uint8_t sensor) {
+ uint8_t signature_dump[3] = {
+ pmw33xx_read(sensor, REG_Product_ID),
+ pmw33xx_read(sensor, REG_Inverse_Product_ID),
+ pmw33xx_read(sensor, REG_SROM_ID),
+ };
+
+ return memcmp(pmw33xx_firmware_signature, signature_dump, sizeof(signature_dump)) == 0;
+}
+
+bool pmw33xx_upload_firmware(uint8_t sensor) {
+ // Datasheet claims we need to disable REST mode first, but during startup
+ // it's already disabled and we're not turning it on ...
+ // pmw33xx_write(REG_Config2, 0x00); // disable REST mode
+ if (!pmw33xx_write(sensor, REG_SROM_Enable, 0x1d)) {
+ return false;
+ }
+ wait_ms(10);
+ pmw33xx_write(sensor, REG_SROM_Enable, 0x18);
+
+ if (!pmw33xx_spi_start(sensor)) {
+ return false;
+ }
+
+ spi_write(REG_SROM_Load_Burst | 0x80);
+ wait_us(15);
+
+ for (size_t i = 0; i < PMW33XX_FIRMWARE_LENGTH; i++) {
+ spi_write(pgm_read_byte(pmw33xx_firmware_data + i));
+ wait_us(15);
+ }
+ wait_us(200);
+
+ pmw33xx_read(sensor, REG_SROM_ID);
+ pmw33xx_write(sensor, REG_Config2, 0x00);
+
+ return true;
+}
+
+bool pmw33xx_init(uint8_t sensor) {
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return false;
+ }
+ spi_init();
+
+ // power up, need to first drive NCS high then low. the datasheet does not
+ // say for how long, 40us works well in practice.
+ if (!pmw33xx_spi_start(sensor)) {
+ return false;
+ }
+ wait_us(40);
+ spi_stop();
+ wait_us(40);
+
+ if (!pmw33xx_write(sensor, REG_Power_Up_Reset, 0x5a)) {
+ return false;
+ }
+ wait_ms(50);
+
+ // read registers and discard
+ pmw33xx_read(sensor, REG_Motion);
+ pmw33xx_read(sensor, REG_Delta_X_L);
+ pmw33xx_read(sensor, REG_Delta_X_H);
+ pmw33xx_read(sensor, REG_Delta_Y_L);
+ pmw33xx_read(sensor, REG_Delta_Y_H);
+
+ if (!pmw33xx_upload_firmware(sensor)) {
+ dprintf("PMW33XX (%d): firmware upload failed!\n", sensor);
+ return false;
+ }
+
+ spi_stop();
+
+ wait_ms(10);
+ pmw33xx_set_cpi(sensor, PMW33XX_CPI);
+
+ wait_ms(1);
+
+ pmw33xx_write(sensor, REG_Config2, 0x00);
+ pmw33xx_write(sensor, REG_Angle_Tune, CONSTRAIN(ROTATIONAL_TRANSFORM_ANGLE, -127, 127));
+ pmw33xx_write(sensor, REG_Lift_Config, PMW33XX_LIFTOFF_DISTANCE);
+
+ if (!pmw33xx_check_signature(sensor)) {
+ dprintf("PMW33XX (%d): firmware signature verification failed!\n", sensor);
+ return false;
+ }
+
+ return true;
+}
+
+pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor) {
+ pmw33xx_report_t report = {0};
+
+ if (sensor >= pmw33xx_number_of_sensors) {
+ return report;
+ }
+
+ if (!in_burst[sensor]) {
+ dprintf("PMW33XX (%d): burst\n", sensor);
+ if (!pmw33xx_write(sensor, REG_Motion_Burst, 0x00)) {
+ return report;
+ }
+ in_burst[sensor] = true;
+ }
+
+ if (!pmw33xx_spi_start(sensor)) {
+ return report;
+ }
+
+ spi_write(REG_Motion_Burst);
+ wait_us(35); // waits for tSRAD_MOTBR
+
+ spi_receive((uint8_t*)&report, sizeof(report));
+
+ // panic recovery, sometimes burst mode works weird.
+ if (report.motion.w & 0b111) {
+ in_burst[sensor] = false;
+ }
+
+ spi_stop();
+
+ if (debug_config.mouse) {
+ dprintf("PMW33XX (%d): motion: 0x%x dx: %i dy: %i\n", sensor, report.motion.w, report.delta_x, report.delta_y);
+ }
+
+ report.delta_x *= -1;
+ report.delta_y *= -1;
+
+ return report;
+}
diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h
new file mode 100644
index 0000000000..87e8b34d5c
--- /dev/null
+++ b/drivers/sensors/pmw33xx_common.h
@@ -0,0 +1,150 @@
+// Copyright 2022 Daniel Kao (dkao)
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2022 Ulrich Spörlein (@uqs)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include "spi_master.h"
+#include "util.h"
+
+#if defined(POINTING_DEVICE_DRIVER_pmw3360)
+# include "pmw3360.h"
+#elif defined(POINTING_DEVICE_DRIVER_pmw3389)
+# include "pmw3389.h"
+#endif
+
+typedef struct __attribute__((packed)) {
+ union {
+ struct {
+ bool capture_from_raw_data : 1; // FRAME_RData_1st
+ uint8_t operation_mode : 2; // OP_MODE
+ bool is_lifted : 1; // Lift_stat
+ bool raw_data_grab_is_raw_data : 1; // RData_1st
+ uint8_t _reserved : 2; // 1 + Reserved
+ bool is_motion : 1; // MOT
+ } b;
+ uint8_t w;
+ } motion;
+ uint8_t observation;
+ int16_t delta_x; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
+ int16_t delta_y; // displacement on y directions.
+} pmw33xx_report_t;
+
+_Static_assert(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size");
+_Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size");
+
+#if !defined(PMW33XX_CLOCK_SPEED)
+# define PMW33XX_CLOCK_SPEED 2000000
+#endif
+
+#if !defined(PMW33XX_SPI_DIVISOR)
+# ifdef __AVR__
+# define PMW33XX_SPI_DIVISOR (F_CPU / PMW33XX_CLOCK_SPEED)
+# else
+# define PMW33XX_SPI_DIVISOR 64
+# endif
+#endif
+
+#if !defined(PMW33XX_LIFTOFF_DISTANCE)
+# define PMW33XX_LIFTOFF_DISTANCE 0x02
+#endif
+
+#if !defined(ROTATIONAL_TRANSFORM_ANGLE)
+# define ROTATIONAL_TRANSFORM_ANGLE 0x00
+#endif
+
+#if ROTATIONAL_TRANSFORM_ANGLE > 127 || ROTATIONAL_TRANSFORM_ANGLE < (-127)
+# error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 127 for all PMW33XX sensors.
+#endif
+
+// Support single and plural spellings
+#ifndef PMW33XX_CS_PINS
+# ifndef PMW33XX_CS_PIN
+# error "No chip select pin defined -- missing PMW33XX_CS_PIN or PMW33XX_CS_PINS"
+# else
+# define PMW33XX_CS_PINS \
+ { PMW33XX_CS_PIN }
+# endif
+#endif
+
+#if PMW33XX_CPI > PMW33XX_CPI_MAX || PMW33XX_CPI < PMW33XX_CPI_MIN || (PMW33XX_CPI % PMW33XX_CPI_STEP) != 0U
+# pragma message "PMW33XX_CPI has to be in the range of " STR(PMW33XX_CPI_MAX) "-" STR(PMW33XX_CPI_MIN) " in increments of " STR(PMW33XX_CPI_STEP) ". But it is " STR(PMW33XX_CPI) "."
+# error Use correct PMW33XX_CPI value.
+#endif
+
+#define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
+
+/**
+ * @brief Initializes the given sensor so it is in a working state and ready to
+ * be polled for data.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return true Initialization was a success
+ * @return false Initialization failed, do not proceed operation
+ */
+bool __attribute__((cold)) pmw33xx_init(uint8_t sensor);
+
+/**
+ * @brief Gets the currently set CPI value from the sensor. CPI is often
+ * refereed to as the sensors sensitivity.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return uint16_t Current CPI value of the sensor
+ */
+uint16_t pmw33xx_get_cpi(uint8_t sensor);
+
+/**
+ * @brief Sets the given CPI value for the given PMW33XX sensor. CIP is often
+ * refereed to as the sensors sensitivity. Values outside of the allow range are
+ * constrained into legal values.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param cpi CPI value to set, legal range depends on the PMW sensor type
+ */
+void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi);
+
+/**
+ * @brief Sets the given CPI value to all registered PMW33XX sensors. CPI is
+ * often refereed to as the sensors sensitivity. Values outside of the allow
+ * range are constrained into legal values.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param cpi CPI value to set, legal range depends on the PMW sensor type
+ */
+void pmw33xx_set_cpi_all_sensors(uint16_t cpi);
+
+/**
+ * @brief Reads and clears the current delta, and motion register values on the
+ * given sensor.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return pmw33xx_report_t Current values of the sensor, if errors occurred all
+ * fields are set to zero
+ */
+pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor);
+
+/**
+ * @brief Read one byte of data from the given register on the sensor
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param reg_addr Register address to read from
+ * @return uint8_t
+ */
+uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr);
+
+/**
+ * @brief Writes one byte of data to the given register on the sensor
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param reg_addr Registers address to write to
+ * @param data Data to write to the register
+ * @return true Write was a success
+ * @return false Write failed, do not proceed operation
+ */
+bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data);
diff --git a/drivers/serial.h b/drivers/serial.h
index 0cfdbd9959..fb91b136e7 100644
--- a/drivers/serial.h
+++ b/drivers/serial.h
@@ -27,3 +27,13 @@ void soft_serial_initiator_init(void);
void soft_serial_target_init(void);
bool soft_serial_transaction(int sstd_index);
+
+#ifdef SERIAL_DEBUG
+# include <debug.h>
+# include <print.h>
+# define serial_dprintf(...) dprintf(__VA_ARGS__)
+#else
+# define serial_dprintf(...) \
+ do { \
+ } while (0)
+#endif
diff --git a/drivers/wear_leveling/wear_leveling_flash_spi.c b/drivers/wear_leveling/wear_leveling_flash_spi.c
new file mode 100644
index 0000000000..6191f8bf09
--- /dev/null
+++ b/drivers/wear_leveling/wear_leveling_flash_spi.c
@@ -0,0 +1,101 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <stdbool.h>
+#include <hal.h>
+#include "util.h"
+#include "timer.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+
+#ifndef WEAR_LEVELING_EXTERNAL_FLASH_BULK_COUNT
+# define WEAR_LEVELING_EXTERNAL_FLASH_BULK_COUNT 32
+#endif // WEAR_LEVELING_EXTERNAL_FLASH_BULK_COUNT
+
+bool backing_store_init(void) {
+ bs_dprintf("Init\n");
+ flash_init();
+ return true;
+}
+
+bool backing_store_unlock(void) {
+ bs_dprintf("Unlock\n");
+ // No-op -- handled by the flash driver as it is.
+ return true;
+}
+
+bool backing_store_erase(void) {
+#ifdef WEAR_LEVELING_DEBUG_OUTPUT
+ uint32_t start = timer_read32();
+#endif
+
+ bool ret = true;
+ for (int i = 0; i < (WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT); ++i) {
+ flash_status_t status = flash_erase_block(((WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET) + i) * (EXTERNAL_FLASH_BLOCK_SIZE));
+ if (status != FLASH_STATUS_SUCCESS) {
+ ret = false;
+ break;
+ }
+ }
+
+ bs_dprintf("Backing store erase took %ldms to complete\n", ((long)(timer_read32() - start)));
+ return ret;
+}
+
+bool backing_store_write(uint32_t address, backing_store_int_t value) {
+ return backing_store_write_bulk(address, &value, 1);
+}
+
+bool backing_store_lock(void) {
+ bs_dprintf("Lock \n");
+ // No-op -- handled by the flash driver as it is.
+ return true;
+}
+
+bool backing_store_read(uint32_t address, backing_store_int_t *value) {
+ return backing_store_read_bulk(address, value, 1);
+}
+
+bool backing_store_read_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ bs_dprintf("Read ");
+ uint32_t offset = (WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET) * (EXTERNAL_FLASH_BLOCK_SIZE) + address;
+ flash_status_t status = flash_read_block(offset, values, sizeof(backing_store_int_t) * item_count);
+ if (status == FLASH_STATUS_SUCCESS) {
+ for (size_t i = 0; i < item_count; ++i) {
+ values[i] = ~values[i];
+ }
+ wl_dump(offset, values, sizeof(backing_store_int_t) * item_count);
+ }
+ return status == FLASH_STATUS_SUCCESS;
+}
+
+bool backing_store_write_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ uint32_t offset = (WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET) * (EXTERNAL_FLASH_BLOCK_SIZE) + address;
+ size_t index = 0;
+ backing_store_int_t temp[WEAR_LEVELING_EXTERNAL_FLASH_BULK_COUNT];
+ do {
+ // Copy out the block of data we want to transmit first
+ size_t this_loop = MIN(item_count, WEAR_LEVELING_EXTERNAL_FLASH_BULK_COUNT);
+ for (size_t i = 0; i < this_loop; ++i) {
+ temp[i] = values[index + i];
+ }
+
+ bs_dprintf("Write ");
+ wl_dump(offset, temp, sizeof(backing_store_int_t) * this_loop);
+
+ // Take the complement instead
+ for (size_t i = 0; i < this_loop; ++i) {
+ temp[i] = ~temp[i];
+ }
+
+ // Write out the block
+ if (flash_write_block(offset, temp, sizeof(backing_store_int_t) * this_loop) != FLASH_STATUS_SUCCESS) {
+ return false;
+ }
+
+ offset += this_loop * sizeof(backing_store_int_t);
+ index += this_loop;
+ item_count -= this_loop;
+ } while (item_count > 0);
+
+ return true;
+}
diff --git a/drivers/wear_leveling/wear_leveling_flash_spi_config.h b/drivers/wear_leveling/wear_leveling_flash_spi_config.h
new file mode 100644
index 0000000000..394370daa3
--- /dev/null
+++ b/drivers/wear_leveling/wear_leveling_flash_spi_config.h
@@ -0,0 +1,34 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#ifndef __ASSEMBLER__
+# include <stdlib.h>
+# include <stdint.h>
+# include "flash_spi.h"
+#endif
+
+// Use 1 block -- check the config for the SPI flash to determine how big it is
+#ifndef WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT
+# define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT 1
+#endif // WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT
+
+// Start at the first block of the external flash
+#ifndef WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET
+# define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET 0
+#endif // WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET
+
+// 8-byte writes by default
+#ifndef BACKING_STORE_WRITE_SIZE
+# define BACKING_STORE_WRITE_SIZE 8
+#endif
+
+// The space allocated by the block
+#ifndef WEAR_LEVELING_BACKING_SIZE
+# define WEAR_LEVELING_BACKING_SIZE ((EXTERNAL_FLASH_BLOCK_SIZE) * (WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT))
+#endif // WEAR_LEVELING_BACKING_SIZE
+
+// Use half of the backing size for logical EEPROM
+#ifndef WEAR_LEVELING_LOGICAL_SIZE
+# define WEAR_LEVELING_LOGICAL_SIZE ((WEAR_LEVELING_BACKING_SIZE) / 2)
+#endif // WEAR_LEVELING_LOGICAL_SIZE
diff --git a/keyboards/1k/keymaps/tap_dance/config.h b/keyboards/1k/keymaps/tap_dance/config.h
index 5df7869537..bd0163e447 100644
--- a/keyboards/1k/keymaps/tap_dance/config.h
+++ b/keyboards/1k/keymaps/tap_dance/config.h
@@ -4,3 +4,4 @@
#pragma once
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
diff --git a/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/config.h b/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/config.h
index c835440076..161b46c814 100644
--- a/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/config.h
+++ b/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/config.h
@@ -3,6 +3,7 @@
/* tap dance stuff*/
#undef TAPPING_TERM
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
#define TAPPING_TOGGLE 2
@@ -12,4 +13,4 @@
#define EXAMPLESTRING4 "tapdance_4"
#undef RGBLED_NUM
-#define RGBLED_NUM 16 \ No newline at end of file
+#define RGBLED_NUM 16
diff --git a/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/keymap.c b/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/keymap.c
index 6b7b36cbb2..eeca552657 100644
--- a/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/keymap.c
+++ b/keyboards/1upkeyboards/sweet16/keymaps/ridingintraffic/keymap.c
@@ -196,7 +196,7 @@ void matrix_scan_user(void) {
}
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _TAPLAND:
rgblight_setrgb(0, 16, 0); //green
break;
diff --git a/keyboards/40percentclub/gherkin/keymaps/itsaferbie/keymap.c b/keyboards/40percentclub/gherkin/keymaps/itsaferbie/keymap.c
index 950b6e86b9..32c074c88f 100644
--- a/keyboards/40percentclub/gherkin/keymaps/itsaferbie/keymap.c
+++ b/keyboards/40percentclub/gherkin/keymaps/itsaferbie/keymap.c
@@ -105,7 +105,7 @@ void matrix_scan_user(void) {
#ifdef RGBLIGHT_ENABLE
static uint8_t old_layer = 255;
- uint8_t new_layer = biton32(layer_state);
+ uint8_t new_layer = get_highest_layer(layer_state);
// Color of the Icons.
if (old_layer != new_layer) {
diff --git a/keyboards/40percentclub/half_n_half/keymaps/Boy_314/keymap.c b/keyboards/40percentclub/half_n_half/keymaps/Boy_314/keymap.c
index 2eef3dc48b..bd467482fe 100644
--- a/keyboards/40percentclub/half_n_half/keymaps/Boy_314/keymap.c
+++ b/keyboards/40percentclub/half_n_half/keymaps/Boy_314/keymap.c
@@ -128,10 +128,10 @@ void tap_dance_choose_layer_reset (qk_tap_dance_state_t *state, void *user_data)
layer_off(_RAISE);
break;
case 3:
- if (biton32(default_layer_state) == _DVORAK) {
+ if (get_highest_layer(default_layer_state) == _DVORAK) {
set_single_persistent_default_layer(_QWERTY);
}
- else if (biton32(default_layer_state) == _QWERTY) {
+ else if (get_highest_layer(default_layer_state) == _QWERTY) {
set_single_persistent_default_layer(_DVORAK);
}
break;
diff --git a/keyboards/40percentclub/mf68/keymaps/delivrance/rules.mk b/keyboards/40percentclub/mf68/keymaps/delivrance/rules.mk
index 5ac2ce5ccb..3d056cb71b 100644
--- a/keyboards/40percentclub/mf68/keymaps/delivrance/rules.mk
+++ b/keyboards/40percentclub/mf68/keymaps/delivrance/rules.mk
@@ -1,6 +1,5 @@
BACKLIGHT_DRIVER = custom
NKRO_ENABLE = yes
-TERMINAL_ENABLE = yes
DYNAMIC_MACRO_ENABLE = yes
# Use RAM (fake EEPROM, transient) instead of real EEPROM
diff --git a/keyboards/adafruit/macropad/config.h b/keyboards/adafruit/macropad/config.h
new file mode 100644
index 0000000000..8d7298e09c
--- /dev/null
+++ b/keyboards/adafruit/macropad/config.h
@@ -0,0 +1,137 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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 "config_common.h"
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 3
+
+#define VENDOR_ID 0x239A
+#define PRODUCT_ID 0x0108
+#define DEVICE_VER 0x0001
+#define MANUFACTURER Adafruit
+#define PRODUCT Macropad RP2040
+
+/* Keyboard Matrix Assignments */
+// clang-format off
+#define DIRECT_PINS { \
+ { NO_PIN, NO_PIN, GP0 }, \
+ { GP1, GP2, GP3 }, \
+ { GP4, GP5, GP6 }, \
+ { GP7, GP8, GP9 }, \
+ { GP10, GP11, GP12 } \
+}
+// clang-format on
+
+/* OLED SPI Defines */
+#define OLED_DISPLAY_128X64
+#define OLED_IC OLED_IC_SH1106
+
+/* OLED SPI Pins */
+#define OLED_DC_PIN GP24
+#define OLED_CS_PIN GP22
+#define OLED_RST_PIN GP23
+
+/* Shift OLED columns by 2 pixels */
+#define OLED_COLUMN_OFFSET 2
+
+/* Divisor for OLED */
+#define OLED_SPI_DIVISOR 4
+
+/* ChibiOS SPI definitions */
+#define SPI_DRIVER SPID1
+#define SPI_SCK_PIN GP26
+#define SPI_MOSI_PIN GP27
+#define SPI_MISO_PIN GP28
+
+/* Encoders */
+#define ENCODERS_PAD_A { GP18 }
+#define ENCODERS_PAD_B { GP17 }
+
+#define DEBOUNCE 5
+
+/* Bootmagic lite */
+/* (Press the Encoder button while plugging the keyboard to enter the bootloader) */
+#define BOOTMAGIC_LITE_ROW 0
+#define BOOTMAGIC_LITE_COLUMN 2
+
+/* Double tap the side button to enter bootloader */
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP13
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
+
+/* Audio (Unsupported for now)*/
+// #define AUDIO_PIN GP16
+// #define SPEAKER_SHUTDOWN GP14
+
+#ifdef RGB_MATRIX_ENABLE
+
+ /* RGB Defines */
+# define RGB_DI_PIN GP19
+# define DRIVER_LED_TOTAL 12
+# define RGBLED_NUM 12
+
+ /* Enable Framebuffer and keypress effects */
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+# define RGB_MATRIX_KEYPRESSES
+
+# define ENABLE_RGB_MATRIX_ALPHAS_MODS
+# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
+# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
+# define ENABLE_RGB_MATRIX_BREATHING
+# define ENABLE_RGB_MATRIX_BAND_SAT
+# define ENABLE_RGB_MATRIX_BAND_VAL
+# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
+# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
+# define ENABLE_RGB_MATRIX_CYCLE_ALL
+# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
+# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
+# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
+# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
+# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
+# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
+# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
+# define ENABLE_RGB_MATRIX_DUAL_BEACON
+# define ENABLE_RGB_MATRIX_RAINBOW_BEACON
+# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
+# define ENABLE_RGB_MATRIX_RAINDROPS
+# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
+# define ENABLE_RGB_MATRIX_HUE_BREATHING
+# define ENABLE_RGB_MATRIX_HUE_PENDULUM
+# define ENABLE_RGB_MATRIX_HUE_WAVE
+# define ENABLE_RGB_MATRIX_PIXEL_RAIN
+# define ENABLE_RGB_MATRIX_PIXEL_FLOW
+# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
+# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+# define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
+# define ENABLE_RGB_MATRIX_SPLASH
+# define ENABLE_RGB_MATRIX_MULTISPLASH
+# define ENABLE_RGB_MATRIX_SOLID_SPLASH
+# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
+#endif
diff --git a/keyboards/adafruit/macropad/halconf.h b/keyboards/adafruit/macropad/halconf.h
new file mode 100644
index 0000000000..6cd66fd520
--- /dev/null
+++ b/keyboards/adafruit/macropad/halconf.h
@@ -0,0 +1,28 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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_next <halconf.h>
+
+#undef HAL_USE_SPI
+#define HAL_USE_SPI TRUE
+
+#undef SPI_USE_WAIT
+#define SPI_USE_WAIT TRUE
+
+#undef SPI_SELECT_MODE
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
diff --git a/keyboards/adafruit/macropad/info.json b/keyboards/adafruit/macropad/info.json
new file mode 100644
index 0000000000..ffa31780a9
--- /dev/null
+++ b/keyboards/adafruit/macropad/info.json
@@ -0,0 +1,24 @@
+{
+ "keyboard_name": "Adafruit Macropad RP2040",
+ "url": "https://learn.adafruit.com/adafruit-macropad-rp2040",
+ "maintainer": "Jpe230",
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label":"Mute", "x":2, "y":0},
+ {"label":"Enter", "x":0, "y":1},
+ {"label":"KC_0", "x":1, "y":1},
+ {"label":"BackSpace", "x":2, "y":1},
+ {"label":"KC_7", "x":0, "y":2},
+ {"label":"KC_8", "x":1, "y":2},
+ {"label":"KC_9", "x":2, "y":2},
+ {"label":"KC_4", "x":0, "y":3},
+ {"label":"KC_5", "x":1, "y":3},
+ {"label":"KC_6", "x":2, "y":3},
+ {"label":"KC_1", "x":0, "y":4},
+ {"label":"KC_2", "x":1, "y":4},
+ {"label":"KC_3", "x":2, "y":4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/adafruit/macropad/keymaps/default/keymap.c b/keyboards/adafruit/macropad/keymaps/default/keymap.c
new file mode 100644
index 0000000000..26c6b4ccf2
--- /dev/null
+++ b/keyboards/adafruit/macropad/keymaps/default/keymap.c
@@ -0,0 +1,114 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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 QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ KC_MUTE,
+ KC_ENT, KC_0, KC_BSPC,
+ KC_7, KC_8, KC_9,
+ KC_4, KC_5, KC_6,
+ KC_1, KC_2, KC_3
+ )
+};
+
+#ifdef ENCODER_MAP_ENABLE
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
+ [0] = { ENCODER_CCW_CW(KC_VOLU, KC_VOLD) },
+};
+#endif
+
+
+#ifdef OLED_ENABLE
+static void render_qmk_logo(void) {
+ static const char PROGMEM qmk_logo[] = {
+ 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,
+ 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f,
+ 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x83, 0x83, 0x83, 0x83, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe,
+ 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, 0x83, 0x83, 0x83, 0x03,
+ 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,
+ 0x81, 0x83, 0x83, 0x83, 0x83, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, 0x83, 0x83, 0x83, 0x81,
+ 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,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x07, 0x1f, 0x3f, 0x7f, 0x7e, 0xf8, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff,
+ 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7f, 0x3f, 0x1f, 0x07, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+ 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,
+ 0xc0, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff,
+ 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0,
+ 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xfc, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
+ 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
+ };
+
+ oled_write_raw_P(qmk_logo, sizeof(qmk_logo));
+}
+
+bool oled_task_user(void) {
+ render_qmk_logo();
+ return true;
+}
+
+#endif
+
diff --git a/keyboards/adafruit/macropad/lib/oled_driver_spi.h b/keyboards/adafruit/macropad/lib/oled_driver_spi.h
new file mode 100644
index 0000000000..c8a2cd7d9a
--- /dev/null
+++ b/keyboards/adafruit/macropad/lib/oled_driver_spi.h
@@ -0,0 +1,29 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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 OLED_DC_PIN
+# error "The OLED driver in SPI needs a D/C pin defined"
+#endif
+#ifndef OLED_CS_PIN
+# error "The OLED driver in SPI needs a CS pin defined"
+#endif
+#ifndef OLED_SPI_MODE
+# define OLED_SPI_MODE 3
+#endif
+#ifndef OLED_SPI_DIVISOR
+# define OLED_SPI_DIVISOR 2
+#endif
diff --git a/keyboards/adafruit/macropad/lib/ssd1306_sh1106.c b/keyboards/adafruit/macropad/lib/ssd1306_sh1106.c
new file mode 100644
index 0000000000..dc1289fdb1
--- /dev/null
+++ b/keyboards/adafruit/macropad/lib/ssd1306_sh1106.c
@@ -0,0 +1,827 @@
+/*
+Copyright 2019 Ryan Caltabiano <https://github.com/XScorpion2>
+Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+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 "oled_driver.h"
+#include "oled_driver_spi.h"
+
+#include "spi_master.h"
+
+#include <quantum.h>
+#include OLED_FONT_H
+#include "timer.h"
+#include "print.h"
+
+#include <string.h>
+
+#include "progmem.h"
+
+#include "keyboard.h"
+
+// Used commands from spec sheet: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
+// for SH1106: https://www.velleman.eu/downloads/29/infosheets/sh1106_datasheet.pdf
+
+// Fundamental Commands
+#define CONTRAST 0x81
+#define DISPLAY_ALL_ON 0xA5
+#define DISPLAY_ALL_ON_RESUME 0xA4
+#define NORMAL_DISPLAY 0xA6
+#define INVERT_DISPLAY 0xA7
+#define DISPLAY_ON 0xAF
+#define DISPLAY_OFF 0xAE
+#define NOP 0xE3
+
+// Scrolling Commands
+#define ACTIVATE_SCROLL 0x2F
+#define DEACTIVATE_SCROLL 0x2E
+#define SCROLL_RIGHT 0x26
+#define SCROLL_LEFT 0x27
+#define SCROLL_RIGHT_UP 0x29
+#define SCROLL_LEFT_UP 0x2A
+
+// Addressing Setting Commands
+#define MEMORY_MODE 0x20
+#define COLUMN_ADDR 0x21
+#define PAGE_ADDR 0x22
+#define PAM_SETCOLUMN_LSB 0x00
+#define PAM_SETCOLUMN_MSB 0x10
+#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
+
+// Hardware Configuration Commands
+#define DISPLAY_START_LINE 0x40
+#define SEGMENT_REMAP 0xA0
+#define SEGMENT_REMAP_INV 0xA1
+#define MULTIPLEX_RATIO 0xA8
+#define COM_SCAN_INC 0xC0
+#define COM_SCAN_DEC 0xC8
+#define DISPLAY_OFFSET 0xD3
+#define COM_PINS 0xDA
+#define COM_PINS_SEQ 0x02
+#define COM_PINS_ALT 0x12
+#define COM_PINS_SEQ_LR 0x22
+#define COM_PINS_ALT_LR 0x32
+
+// Timing & Driving Commands
+#define DISPLAY_CLOCK 0xD5
+#define PRE_CHARGE_PERIOD 0xD9
+#define VCOM_DETECT 0xDB
+
+// Advance Graphic Commands
+#define FADE_BLINK 0x23
+#define ENABLE_FADE 0x20
+#define ENABLE_BLINK 0x30
+
+// Charge Pump Commands
+#define CHARGE_PUMP 0x8D
+
+// Misc defines
+#ifndef OLED_BLOCK_COUNT
+# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8)
+#endif
+#ifndef OLED_BLOCK_SIZE
+# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)
+#endif
+
+#define OLED_ALL_BLOCKS_MASK (((((OLED_BLOCK_TYPE)1 << (OLED_BLOCK_COUNT - 1)) - 1) << 1) | 1)
+
+#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])
+
+// spi defines
+#define OLED_STATUS_SUCCESS SPI_STATUS_SUCCESS
+
+void oled_spi_init(void) {
+ spi_init();
+
+ setPinOutput(OLED_CS_PIN);
+ writePinHigh(OLED_CS_PIN);
+
+ setPinOutput(OLED_DC_PIN);
+ writePinLow(OLED_DC_PIN);
+}
+
+void oled_spi_start(void) {
+ spi_start(OLED_CS_PIN, false, OLED_SPI_MODE, OLED_SPI_DIVISOR);
+}
+
+void oled_spi_stop(void) {
+ spi_stop();
+}
+
+// Transmit/Write Funcs.
+bool oled_cmd(const uint8_t *data, uint16_t size) {
+ oled_spi_start();
+ // Command Mode
+ writePinLow(OLED_DC_PIN);
+ // Send the commands
+ if(spi_transmit(data, size) != OLED_STATUS_SUCCESS){
+ oled_spi_stop();
+ return false;
+ }
+ oled_spi_stop();
+ return true;
+}
+
+bool oled_cmd_p(const uint8_t *data, uint16_t size) {
+ return oled_cmd(data, size);
+}
+
+bool oled_write_reg(const uint8_t *data, uint16_t size)
+{
+ oled_spi_start();
+ // Command Mode
+ writePinHigh(OLED_DC_PIN);
+ // Send the commands
+ if(spi_transmit(data, size) != OLED_STATUS_SUCCESS){
+ oled_spi_stop();
+ return false;
+ }
+ oled_spi_stop();
+ return true;
+}
+
+#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
+
+// Display buffer's is the same as the OLED memory layout
+// this is so we don't end up with rounding errors with
+// parts of the display unusable or don't get cleared correctly
+// and also allows for drawing & inverting
+uint8_t oled_buffer[OLED_MATRIX_SIZE];
+uint8_t * oled_cursor;
+OLED_BLOCK_TYPE oled_dirty = 0;
+bool oled_initialized = false;
+bool oled_active = false;
+bool oled_scrolling = false;
+bool oled_inverted = false;
+uint8_t oled_brightness = OLED_BRIGHTNESS;
+oled_rotation_t oled_rotation = 0;
+uint8_t oled_rotation_width = 0;
+uint8_t oled_scroll_speed = 0; // this holds the speed after being remapped to ssd1306 internal values
+uint8_t oled_scroll_start = 0;
+uint8_t oled_scroll_end = 7;
+#if OLED_TIMEOUT > 0
+uint32_t oled_timeout;
+#endif
+#if OLED_SCROLL_TIMEOUT > 0
+uint32_t oled_scroll_timeout;
+#endif
+#if OLED_UPDATE_INTERVAL > 0
+uint16_t oled_update_timeout;
+#endif
+
+// Flips the rendering bits for a character at the current cursor position
+static void InvertCharacter(uint8_t *cursor) {
+ const uint8_t *end = cursor + OLED_FONT_WIDTH;
+ while (cursor < end) {
+ *cursor = ~(*cursor);
+ cursor++;
+ }
+}
+
+bool oled_init(oled_rotation_t rotation) {
+ oled_rotation = oled_init_user(oled_init_kb(rotation));
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+ oled_rotation_width = OLED_DISPLAY_WIDTH;
+ } else {
+ oled_rotation_width = OLED_DISPLAY_HEIGHT;
+ }
+
+ oled_spi_init();
+
+#ifdef OLED_RST_PIN
+ /* Reset device */
+ setPinOutput(OLED_RST_PIN);
+ writePinLow(OLED_RST_PIN);
+ wait_ms(20);
+ writePinHigh(OLED_RST_PIN);
+ wait_ms(20);
+#endif
+
+ static const uint8_t PROGMEM display_setup1[] = {
+ DISPLAY_OFF,
+ DISPLAY_CLOCK,
+ 0x80,
+ MULTIPLEX_RATIO,
+ OLED_DISPLAY_HEIGHT - 1,
+ DISPLAY_OFFSET,
+ 0x00,
+ DISPLAY_START_LINE | 0x00,
+ CHARGE_PUMP,
+ 0x14,
+#if (OLED_IC != OLED_IC_SH1106)
+ // MEMORY_MODE is unsupported on SH1106 (Page Addressing only)
+ MEMORY_MODE,
+ 0x00, // Horizontal addressing mode
+#endif
+ };
+
+ if (!oled_cmd_p(display_setup1, ARRAY_SIZE(display_setup1))) {
+ print("oled_init cmd set 1 failed\n");
+ return false;
+ }
+
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_180)) {
+ static const uint8_t PROGMEM display_normal[] = {SEGMENT_REMAP_INV, COM_SCAN_DEC};
+ if (!oled_cmd_p(display_normal, ARRAY_SIZE(display_normal))) {
+ print("oled_init cmd normal rotation failed\n");
+ return false;
+ }
+ } else {
+ static const uint8_t PROGMEM display_flipped[] = {SEGMENT_REMAP, COM_SCAN_INC};
+ if (!oled_cmd_p(display_flipped, ARRAY_SIZE(display_flipped))) {
+ print("display_flipped failed\n");
+ return false;
+ }
+ }
+
+ static const uint8_t PROGMEM display_setup2[] = {COM_PINS, OLED_COM_PINS, CONTRAST, OLED_BRIGHTNESS, PRE_CHARGE_PERIOD, 0xF1, VCOM_DETECT, 0x20, DISPLAY_ALL_ON_RESUME, NORMAL_DISPLAY, DEACTIVATE_SCROLL, DISPLAY_ON};
+ if (!oled_cmd_p(display_setup2, ARRAY_SIZE(display_setup2))) {
+ print("display_setup2 failed\n");
+ return false;
+ }
+
+#if OLED_TIMEOUT > 0
+ oled_timeout = timer_read32() + OLED_TIMEOUT;
+#endif
+#if OLED_SCROLL_TIMEOUT > 0
+ oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT;
+#endif
+
+ oled_clear();
+ oled_initialized = true;
+ oled_active = true;
+ oled_scrolling = false;
+ return true;
+}
+
+__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
+ return rotation;
+}
+__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+ return rotation;
+}
+
+void oled_clear(void) {
+ memset(oled_buffer, 0, sizeof(oled_buffer));
+ oled_cursor = &oled_buffer[0];
+ oled_dirty = OLED_ALL_BLOCKS_MASK;
+}
+
+static void calc_bounds(uint8_t update_start, uint8_t *cmd_array) {
+ // Calculate commands to set memory addressing bounds.
+ uint8_t start_page = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH;
+ uint8_t start_column = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH;
+#if (OLED_IC == OLED_IC_SH1106)
+ // Commands for Page Addressing Mode. Sets starting page and column; has no end bound.
+ // Column value must be split into high and low nybble and sent as two commands.
+ cmd_array[0] = PAM_PAGE_ADDR | start_page;
+ cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f);
+ cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f);
+ cmd_array[3] = NOP;
+ cmd_array[4] = NOP;
+ cmd_array[5] = NOP;
+#else
+ // Commands for use in Horizontal Addressing mode.
+ cmd_array[1] = start_column;
+ cmd_array[4] = start_page;
+ cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) % OLED_DISPLAY_WIDTH + cmd_array[1];
+ cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) / OLED_DISPLAY_WIDTH - 1;
+#endif
+}
+
+static void calc_bounds_90(uint8_t update_start, uint8_t *cmd_array) {
+ cmd_array[1] = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_HEIGHT * 8;
+ cmd_array[4] = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_HEIGHT;
+ cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) / OLED_DISPLAY_HEIGHT * 8 - 1 + cmd_array[1];
+ ;
+ cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) % OLED_DISPLAY_HEIGHT / 8;
+}
+
+uint8_t crot(uint8_t a, int8_t n) {
+ const uint8_t mask = 0x7;
+ n &= mask;
+ return a << n | a >> (-n & mask);
+}
+
+static void rotate_90(const uint8_t *src, uint8_t *dest) {
+ for (uint8_t i = 0, shift = 7; i < 8; ++i, --shift) {
+ uint8_t selector = (1 << i);
+ for (uint8_t j = 0; j < 8; ++j) {
+ dest[i] |= crot(src[j] & selector, shift - (int8_t)j);
+ }
+ }
+}
+
+void oled_render(void) {
+ if (!oled_initialized) {
+ return;
+ }
+
+ // Do we have work to do?
+ oled_dirty &= OLED_ALL_BLOCKS_MASK;
+ if (!oled_dirty || oled_scrolling) {
+ return;
+ }
+
+ // Find first dirty block
+ uint8_t update_start = 0;
+ while (!(oled_dirty & ((OLED_BLOCK_TYPE)1 << update_start))) {
+ ++update_start;
+ }
+
+ // Set column & page position
+ static uint8_t display_start[] = {COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1};
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+ calc_bounds(update_start, display_start);
+ } else {
+ calc_bounds_90(update_start, display_start);
+ }
+
+ // Send column & page position
+ if (!oled_cmd(display_start, ARRAY_SIZE(display_start))) {
+ print("oled_render offset command failed\n");
+ return;
+ }
+
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+ // Send render data chunk as is
+ if (!oled_write_reg(&oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE)) {
+ print("oled_render data failed\n");
+ return;
+ }
+ } else {
+ // Rotate the render chunks
+ const static uint8_t source_map[] = OLED_SOURCE_MAP;
+ const static uint8_t target_map[] = OLED_TARGET_MAP;
+
+ static uint8_t temp_buffer[OLED_BLOCK_SIZE];
+ memset(temp_buffer, 0, sizeof(temp_buffer));
+ for (uint8_t i = 0; i < sizeof(source_map); ++i) {
+ rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]);
+ }
+
+ // Send render data chunk after rotating
+ if (!oled_write_reg(temp_buffer, OLED_BLOCK_SIZE)) {
+ print("oled_render90 data failed\n");
+ return;
+ }
+ }
+
+ // Turn on display if it is off
+ oled_on();
+
+ // Clear dirty flag
+ oled_dirty &= ~((OLED_BLOCK_TYPE)1 << update_start);
+}
+
+void oled_set_cursor(uint8_t col, uint8_t line) {
+ uint16_t index = line * oled_rotation_width + col * OLED_FONT_WIDTH;
+
+ // Out of bounds?
+ if (index >= OLED_MATRIX_SIZE) {
+ index = 0;
+ }
+
+ oled_cursor = &oled_buffer[index];
+}
+
+void oled_advance_page(bool clearPageRemainder) {
+ uint16_t index = oled_cursor - &oled_buffer[0];
+ uint8_t remaining = oled_rotation_width - (index % oled_rotation_width);
+
+ if (clearPageRemainder) {
+ // Remaining Char count
+ remaining = remaining / OLED_FONT_WIDTH;
+
+ // Write empty character until next line
+ while (remaining--)
+ oled_write_char(' ', false);
+ } else {
+ // Next page index out of bounds?
+ if (index + remaining >= OLED_MATRIX_SIZE) {
+ index = 0;
+ remaining = 0;
+ }
+
+ oled_cursor = &oled_buffer[index + remaining];
+ }
+}
+
+void oled_advance_char(void) {
+ uint16_t nextIndex = oled_cursor - &oled_buffer[0] + OLED_FONT_WIDTH;
+ uint8_t remainingSpace = oled_rotation_width - (nextIndex % oled_rotation_width);
+
+ // Do we have enough space on the current line for the next character
+ if (remainingSpace < OLED_FONT_WIDTH) {
+ nextIndex += remainingSpace;
+ }
+
+ // Did we go out of bounds
+ if (nextIndex >= OLED_MATRIX_SIZE) {
+ nextIndex = 0;
+ }
+
+ // Update cursor position
+ oled_cursor = &oled_buffer[nextIndex];
+}
+
+// Main handler that writes character data to the display buffer
+void oled_write_char(const char data, bool invert) {
+ // Advance to the next line if newline
+ if (data == '\n') {
+ // Old source wrote ' ' until end of line...
+ oled_advance_page(true);
+ return;
+ }
+
+ if (data == '\r') {
+ oled_advance_page(false);
+ return;
+ }
+
+ // copy the current render buffer to check for dirty after
+ static uint8_t oled_temp_buffer[OLED_FONT_WIDTH];
+ memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH);
+
+ _Static_assert(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array");
+
+ // set the reder buffer data
+ uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
+ if (cast_data < OLED_FONT_START || cast_data > OLED_FONT_END) {
+ memset(oled_cursor, 0x00, OLED_FONT_WIDTH);
+ } else {
+ const uint8_t *glyph = &font[(cast_data - OLED_FONT_START) * OLED_FONT_WIDTH];
+ memcpy_P(oled_cursor, glyph, OLED_FONT_WIDTH);
+ }
+
+ // Invert if needed
+ if (invert) {
+ InvertCharacter(oled_cursor);
+ }
+
+ // Dirty check
+ if (memcmp(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH)) {
+ uint16_t index = oled_cursor - &oled_buffer[0];
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
+ // Edgecase check if the written data spans the 2 chunks
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << ((index + OLED_FONT_WIDTH - 1) / OLED_BLOCK_SIZE));
+ }
+
+ // Finally move to the next char
+ oled_advance_char();
+}
+
+void oled_write(const char *data, bool invert) {
+ const char *end = data + strlen(data);
+ while (data < end) {
+ oled_write_char(*data, invert);
+ data++;
+ }
+}
+
+void oled_write_ln(const char *data, bool invert) {
+ oled_write(data, invert);
+ oled_advance_page(true);
+}
+
+void oled_pan(bool left) {
+ uint16_t i = 0;
+ for (uint16_t y = 0; y < OLED_DISPLAY_HEIGHT / 8; y++) {
+ if (left) {
+ for (uint16_t x = 0; x < OLED_DISPLAY_WIDTH - 1; x++) {
+ i = y * OLED_DISPLAY_WIDTH + x;
+ oled_buffer[i] = oled_buffer[i + 1];
+ }
+ } else {
+ for (uint16_t x = OLED_DISPLAY_WIDTH - 1; x > 0; x--) {
+ i = y * OLED_DISPLAY_WIDTH + x;
+ oled_buffer[i] = oled_buffer[i - 1];
+ }
+ }
+ }
+ oled_dirty = OLED_ALL_BLOCKS_MASK;
+}
+
+oled_buffer_reader_t oled_read_raw(uint16_t start_index) {
+ if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE;
+ oled_buffer_reader_t ret_reader;
+ ret_reader.current_element = &oled_buffer[start_index];
+ ret_reader.remaining_element_count = OLED_MATRIX_SIZE - start_index;
+ return ret_reader;
+}
+
+void oled_write_raw_byte(const char data, uint16_t index) {
+ if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE;
+ if (oled_buffer[index] == data) return;
+ oled_buffer[index] = data;
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
+}
+
+void oled_write_raw(const char *data, uint16_t size) {
+ uint16_t cursor_start_index = oled_cursor - &oled_buffer[0];
+ if ((size + cursor_start_index) > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE - cursor_start_index;
+ for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
+ uint8_t c = *data++;
+ if (oled_buffer[i] == c) continue;
+ oled_buffer[i] = c;
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
+ }
+}
+
+void oled_write_pixel(uint8_t x, uint8_t y, bool on) {
+ if (x >= oled_rotation_width) {
+ return;
+ }
+ uint16_t index = x + (y / 8) * oled_rotation_width;
+ if (index >= OLED_MATRIX_SIZE) {
+ return;
+ }
+ uint8_t data = oled_buffer[index];
+ if (on) {
+ data |= (1 << (y % 8));
+ } else {
+ data &= ~(1 << (y % 8));
+ }
+ if (oled_buffer[index] != data) {
+ oled_buffer[index] = data;
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
+ }
+}
+
+#if defined(__AVR__)
+void oled_write_P(const char *data, bool invert) {
+ uint8_t c = pgm_read_byte(data);
+ while (c != 0) {
+ oled_write_char(c, invert);
+ c = pgm_read_byte(++data);
+ }
+}
+
+void oled_write_ln_P(const char *data, bool invert) {
+ oled_write_P(data, invert);
+ oled_advance_page(true);
+}
+
+void oled_write_raw_P(const char *data, uint16_t size) {
+ uint16_t cursor_start_index = oled_cursor - &oled_buffer[0];
+ if ((size + cursor_start_index) > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE - cursor_start_index;
+ for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
+ uint8_t c = pgm_read_byte(data++);
+ if (oled_buffer[i] == c) continue;
+ oled_buffer[i] = c;
+ oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
+ }
+}
+#endif // defined(__AVR__)
+
+bool oled_on(void) {
+ if (!oled_initialized) {
+ return oled_active;
+ }
+
+#if OLED_TIMEOUT > 0
+ oled_timeout = timer_read32() + OLED_TIMEOUT;
+#endif
+
+ static const uint8_t PROGMEM display_on[] =
+#ifdef OLED_FADE_OUT
+ {FADE_BLINK, 0x00};
+#else
+ {DISPLAY_ON};
+#endif
+
+ if (!oled_active) {
+ if (!oled_cmd_p(display_on, ARRAY_SIZE(display_on))) {
+ print("oled_on cmd failed\n");
+ return oled_active;
+ }
+ oled_active = true;
+ }
+ return oled_active;
+}
+
+bool oled_off(void) {
+ if (!oled_initialized) {
+ return !oled_active;
+ }
+
+ static const uint8_t PROGMEM display_off[] =
+#ifdef OLED_FADE_OUT
+ {FADE_BLINK, ENABLE_FADE | OLED_FADE_OUT_INTERVAL};
+#else
+ {DISPLAY_OFF};
+#endif
+
+ if (oled_active) {
+ if (!oled_cmd_p(display_off, ARRAY_SIZE(display_off))) {
+ print("oled_off cmd failed\n");
+ return oled_active;
+ }
+ oled_active = false;
+ }
+ return !oled_active;
+}
+
+bool is_oled_on(void) {
+ return oled_active;
+}
+
+uint8_t oled_set_brightness(uint8_t level) {
+ if (!oled_initialized) {
+ return oled_brightness;
+ }
+
+ uint8_t set_contrast[] = { CONTRAST, level};
+ if (oled_brightness != level) {
+ if (!oled_cmd(set_contrast, ARRAY_SIZE(set_contrast))) {
+ print("set_brightness cmd failed\n");
+ return oled_brightness;
+ }
+ oled_brightness = level;
+ }
+ return oled_brightness;
+}
+
+uint8_t oled_get_brightness(void) {
+ return oled_brightness;
+}
+
+// Set the specific 8 lines rows of the screen to scroll.
+// 0 is the default for start, and 7 for end, which is the entire
+// height of the screen. For 128x32 screens, rows 4-7 are not used.
+void oled_scroll_set_area(uint8_t start_line, uint8_t end_line) {
+ oled_scroll_start = start_line;
+ oled_scroll_end = end_line;
+}
+
+void oled_scroll_set_speed(uint8_t speed) {
+ // Sets the speed for scrolling... does not take effect
+ // until scrolling is either started or restarted
+ // the ssd1306 supports 8 speeds
+ // FrameRate2 speed = 7
+ // FrameRate3 speed = 4
+ // FrameRate4 speed = 5
+ // FrameRate5 speed = 0
+ // FrameRate25 speed = 6
+ // FrameRate64 speed = 1
+ // FrameRate128 speed = 2
+ // FrameRate256 speed = 3
+ // for ease of use these are remaped here to be in order
+ static const uint8_t scroll_remap[8] = {7, 4, 5, 0, 6, 1, 2, 3};
+ oled_scroll_speed = scroll_remap[speed];
+}
+
+bool oled_scroll_right(void) {
+ if (!oled_initialized) {
+ return oled_scrolling;
+ }
+
+ // Dont enable scrolling if we need to update the display
+ // This prevents scrolling of bad data from starting the scroll too early after init
+ if (!oled_dirty && !oled_scrolling) {
+ uint8_t display_scroll_right[] = {SCROLL_RIGHT, 0x00, oled_scroll_start, oled_scroll_speed, oled_scroll_end, 0x00, 0xFF, ACTIVATE_SCROLL};
+ if (!oled_cmd(display_scroll_right, ARRAY_SIZE(display_scroll_right))) {
+ print("oled_scroll_right cmd failed\n");
+ return oled_scrolling;
+ }
+ oled_scrolling = true;
+ }
+ return oled_scrolling;
+}
+
+bool oled_scroll_left(void) {
+ if (!oled_initialized) {
+ return oled_scrolling;
+ }
+
+ // Dont enable scrolling if we need to update the display
+ // This prevents scrolling of bad data from starting the scroll too early after init
+ if (!oled_dirty && !oled_scrolling) {
+ uint8_t display_scroll_left[] = {SCROLL_LEFT, 0x00, oled_scroll_start, oled_scroll_speed, oled_scroll_end, 0x00, 0xFF, ACTIVATE_SCROLL};
+ if (!oled_cmd(display_scroll_left, ARRAY_SIZE(display_scroll_left))) {
+ print("oled_scroll_left cmd failed\n");
+ return oled_scrolling;
+ }
+ oled_scrolling = true;
+ }
+ return oled_scrolling;
+}
+
+bool oled_scroll_off(void) {
+ if (!oled_initialized) {
+ return !oled_scrolling;
+ }
+
+ if (oled_scrolling) {
+ static const uint8_t PROGMEM display_scroll_off[] = {DEACTIVATE_SCROLL};
+ if (!oled_cmd_p(display_scroll_off, ARRAY_SIZE(display_scroll_off))) {
+ print("oled_scroll_off cmd failed\n");
+ return oled_scrolling;
+ }
+ oled_scrolling = false;
+ oled_dirty = OLED_ALL_BLOCKS_MASK;
+ }
+ return !oled_scrolling;
+}
+
+bool is_oled_scrolling(void) {
+ return oled_scrolling;
+}
+
+bool oled_invert(bool invert) {
+ if (!oled_initialized) {
+ return oled_inverted;
+ }
+
+ if (invert && !oled_inverted) {
+ static const uint8_t PROGMEM display_inverted[] = {INVERT_DISPLAY};
+ if (!oled_cmd_p(display_inverted, ARRAY_SIZE(display_inverted))) {
+ print("oled_invert cmd failed\n");
+ return oled_inverted;
+ }
+ oled_inverted = true;
+ } else if (!invert && oled_inverted) {
+ static const uint8_t PROGMEM display_normal[] = {NORMAL_DISPLAY};
+ if (!oled_cmd_p(display_normal, ARRAY_SIZE(display_normal))) {
+ print("oled_invert cmd failed\n");
+ return oled_inverted;
+ }
+ oled_inverted = false;
+ }
+
+ return oled_inverted;
+}
+
+uint8_t oled_max_chars(void) {
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+ return OLED_DISPLAY_WIDTH / OLED_FONT_WIDTH;
+ }
+ return OLED_DISPLAY_HEIGHT / OLED_FONT_WIDTH;
+}
+
+uint8_t oled_max_lines(void) {
+ if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+ return OLED_DISPLAY_HEIGHT / OLED_FONT_HEIGHT;
+ }
+ return OLED_DISPLAY_WIDTH / OLED_FONT_HEIGHT;
+}
+
+void oled_task(void) {
+ if (!oled_initialized) {
+ return;
+ }
+
+#if OLED_UPDATE_INTERVAL > 0
+ if (timer_elapsed(oled_update_timeout) >= OLED_UPDATE_INTERVAL) {
+ oled_update_timeout = timer_read();
+ oled_set_cursor(0, 0);
+ oled_task_kb();
+ }
+#else
+ oled_set_cursor(0, 0);
+ oled_task_kb();
+#endif
+
+#if OLED_SCROLL_TIMEOUT > 0
+ if (oled_dirty && oled_scrolling) {
+ oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT;
+ oled_scroll_off();
+ }
+#endif
+
+ // Smart render system, no need to check for dirty
+ oled_render();
+
+ // Display timeout check
+#if OLED_TIMEOUT > 0
+ if (oled_active && timer_expired32(timer_read32(), oled_timeout)) {
+ oled_off();
+ }
+#endif
+
+#if OLED_SCROLL_TIMEOUT > 0
+ if (!oled_scrolling && timer_expired32(timer_read32(), oled_scroll_timeout)) {
+# ifdef OLED_SCROLL_TIMEOUT_RIGHT
+ oled_scroll_right();
+# else
+ oled_scroll_left();
+# endif
+ }
+#endif
+}
+
+__attribute__((weak)) bool oled_task_kb(void) {
+ return oled_task_user();
+}
+__attribute__((weak)) bool oled_task_user(void) {
+ return true;
+}
diff --git a/keyboards/adafruit/macropad/macropad.c b/keyboards/adafruit/macropad/macropad.c
new file mode 100644
index 0000000000..a82a2dabb1
--- /dev/null
+++ b/keyboards/adafruit/macropad/macropad.c
@@ -0,0 +1,56 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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 "macropad.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+#define NA NO_LED
+
+/* RGB Positioning */
+led_config_t g_led_config = { {
+ { NA, NA, NA },
+ { 0, 1, 2 },
+ { 3, 4, 5 },
+ { 6, 7, 8 },
+ { 9, 10, 11 }
+}, {
+ { 0, 0 }, { 112, 0 }, { 224, 0},
+ { 0, 21 }, { 112, 21 }, { 224, 21},
+ { 0, 42 }, { 112, 42 }, { 224, 42},
+ { 0, 64 }, { 112, 64 }, { 224, 64}
+}, {
+ 4, 4, 4,
+ 4, 4, 4,
+ 4, 4, 4,
+ 4, 4, 4
+} };
+
+#endif
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_kb(uint8_t index, bool clockwise) {
+ if (!encoder_update_user(index, clockwise)) { return false; }
+ if (index == 0) {
+ if (clockwise) {
+ tap_code_delay(KC_VOLU, 10);
+ } else {
+ tap_code_delay(KC_VOLD, 10);
+ }
+ }
+ return true;
+}
+#endif
diff --git a/keyboards/boardsource/holiday/spooky/spooky.h b/keyboards/adafruit/macropad/macropad.h
index 42127b8f44..6e2e3524b7 100644
--- a/keyboards/boardsource/holiday/spooky/spooky.h
+++ b/keyboards/adafruit/macropad/macropad.h
@@ -1,4 +1,4 @@
-/* Copyright 2020 boardsource
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
*
* 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
@@ -18,18 +18,21 @@
#include "quantum.h"
-/* This is a shortcut to help you visually see your layout.
- *
- * The first section contains all of the arguments representing the physical
- * layout of the board and position of the keys.
- *
- * The second converts the arguments into a two-dimensional array which
- * represents the switch matrix.
- */
-#define LAYOUT_ortho_2x3( \
- k00, k01, k02, \
- k10, k11, k12 \
-) { \
- { k00, k01, k02 }, \
- { k10, k11, k12 } \
-}
+#define ___ KC_NO
+
+// clang-format off
+ #define LAYOUT( \
+ K02, \
+ K10, K11, K12, \
+ K20, K21, K22, \
+ K30, K31, K32, \
+ K40, K41, K42 \
+ ) \
+ { \
+ { ___, ___, K02 }, \
+ { K10, K11, K12 }, \
+ { K20, K21, K22 }, \
+ { K30, K31, K32 }, \
+ { K40, K41, K42 } \
+ }
+// clang-format on
diff --git a/keyboards/adafruit/macropad/mcuconf.h b/keyboards/adafruit/macropad/mcuconf.h
new file mode 100644
index 0000000000..198a2eea69
--- /dev/null
+++ b/keyboards/adafruit/macropad/mcuconf.h
@@ -0,0 +1,22 @@
+/* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
+ *
+ * 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_next <mcuconf.h>
+
+#undef RP_SPI_USE_SPI1
+#define RP_SPI_USE_SPI1 TRUE
diff --git a/keyboards/adafruit/macropad/readme.md b/keyboards/adafruit/macropad/readme.md
new file mode 100644
index 0000000000..fe7375b336
--- /dev/null
+++ b/keyboards/adafruit/macropad/readme.md
@@ -0,0 +1,37 @@
+# Adafruit MacroPad RP2040
+
+![AdafruitMacropad](https://i.imgur.com/dSBSwcJh.jpeg)
+
+A RP2040-powered Macropad with a 3x4 layout.
+
+- Keyboard Maintainer: [Jpe230](https://github.com/jpe230/)
+- Hardware Supported: Adafruit MacroPad RP2040
+- Hardware Availability: [Barebones kit](https://www.adafruit.com/product/5100) [Starter Kit](https://www.adafruit.com/product/5128)
+
+Make example for this board (after setting up your build environment):
+
+```sh
+qmk compile -kb adafruit/macropad -km default
+```
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Features
+
+- Raspberry Pi RP2040 Chip + 8MB Flash memory - Dual-core Cortex M0+ at ~130MHz with 264KB of RAM.
+- 3x4 Mechanical key switch sockets - accepts any Cherry MX-compatible switches. Individually tied to GPIO pins (not matrix wired)
+- One NeoPixel RGB LED per switch, on north side.
+- Rotary encoder, 20 detents per rotation, with push-switch on GPIO pin. Push switch is also used for entering bootloader mode when held down on power-up or reset.
+- 128x64 SH1106 Monochrome OLED display - On high-speed hardware SPI port for quick updates.
+- 8mm Speaker/Buzzer - With Class D amplifier and RC filter, can be used to make simple beeps and sounds effects. (Unsupported for now)
+- STEMMA QT Connector - Allows adding any I2C sensors/displays/devices with plug-and-play cables.
+- Reset button - On the side, for quick restarting, press it twice to enter bootloader.
+- Four M3 mounting bosses - Make custom enclosures easily.
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the rotary encoder push-button on power-up or reset.
+* **Physical reset button**: Press twice the button on the side while the board is connected.
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available.
diff --git a/keyboards/adafruit/macropad/rules.mk b/keyboards/adafruit/macropad/rules.mk
new file mode 100644
index 0000000000..3636424a71
--- /dev/null
+++ b/keyboards/adafruit/macropad/rules.mk
@@ -0,0 +1,26 @@
+# MCU name
+MCU = RP2040
+# Bootloader selection
+BOOTLOADER = rp2040
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Enable N-Key Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+AUDIO_ENABLE = no # Audio output
+# AUDIO_DRIVER = pwm_software
+ENCODER_ENABLE = yes
+RGB_MATRIX_ENABLE = yes
+RGB_MATRIX_DRIVER = WS2812
+WS2812_DRIVER = vendor
+OLED_ENABLE = yes
+OLED_DRIVER = custom
+# Project specific files
+SRC += lib/ssd1306_sh1106.c
+QUANTUM_LIB_SRC += spi_master.c
diff --git a/keyboards/aidansmithdotdev/fine40/config.h b/keyboards/aidansmithdotdev/fine40/config.h
new file mode 100644
index 0000000000..43ac1e5dda
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/config.h
@@ -0,0 +1,12 @@
+// Copyright 2022 Aidan Smith (@Aidan-OS)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "config_common.h"
+
+#define ENCODER_RESOLUTION 2
+#define ENCODERS_PAD_A { D5 }
+#define ENCODERS_PAD_B { B7 }
+
+#define OLED_DISPLAY_128X64 //Comment this out to change the screen size
diff --git a/keyboards/aidansmithdotdev/fine40/fine40.c b/keyboards/aidansmithdotdev/fine40/fine40.c
new file mode 100644
index 0000000000..cc4024136e
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/fine40.c
@@ -0,0 +1,85 @@
+// Copyright 2022 Aidan Smith (@Aidan-OS)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "fine40.h"
+
+enum keyboard_layers {
+ _MAIN,
+ _RIGHT,
+ _LEFT,
+ _TAB,
+};
+
+#ifdef OLED_ENABLE
+//static void render_logo(void) {
+// static const char PROGMEM raw_logo[] = {
+// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,192,224,224,240,240,248,248,248,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,248,248,248,240,240,224,224,192,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,224,224,224,192, 0, 0, 0, 0, 96,240,240, 96, 0, 0, 0, 0, 0, 0,240,240,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0, 0, 0,128,192,224,240,248,252,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 15, 7, 7, 7, 15,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,252,248,240,224,192,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,240,254,255,127,115,127,127,255,252,224, 0,255,255,255,254, 48,254,254,255,199,135,255,255,255, 0,224,247,255,191,191,255,255,254, 0,254,255,255,255, 7,255,255,254,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0,192,248,254,255,255,255,255,255,255,255,255,255,127, 31, 15, 7, 3, 1,192,224,240,251,255,255,255,255,255, 0, 0, 0, 0, 0,255,255,255,255,255,255,241,225,192, 1, 3, 7, 15, 31,127,255,255,255,255,255,255,255,255,255,254,248,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3,128,128,128,128, 0, 1, 3, 3, 1, 1, 3, 3, 1, 0, 0, 1, 1, 3, 3, 3, 3,129,192,128, 1, 3, 3, 3, 3, 1, 1, 0,129,195,195,193, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255, 7, 0, 0, 0,240,252,255,255,255,255,255,255,255,255,255,255,255,254,252,254,255,255,255,255,255,255,255,255,255,255,255,252,240, 0, 0, 0, 7,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 63, 63,127,123,243,247,231,193, 0,252,252,252, 28, 60,252,252,252, 28,252,252,248,224, 0,255,255,255, 0,255,255,255,255, 28, 28, 0,255,255,255,255, 28,252,252,248,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,240, 0, 0, 0, 7, 31,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,127, 31, 7, 0, 0, 0,240,255,255,255,255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 15, 15, 14, 15, 7, 7, 3, 0, 15, 15, 15, 0, 0, 15, 15, 15, 0, 7, 15, 15, 7, 0, 15, 15, 15, 0, 1, 7, 7, 15, 14, 14, 6, 7, 7, 7, 7, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 1, 15, 63,255,255,255,255,255,255,255,255,255,255,254,248,240,224,192,128,129, 3, 7, 15, 15, 31, 31, 31, 63, 63, 63, 63, 63, 31, 31, 31, 15, 15, 7, 3,129,128,192,224,240,248,254,255,255,255,255,255,255,255,255,255,255, 63, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,192,224,224,224,252,254,254, 0, 0,128,192,224,224,224,224,192,128, 96,224,224,224, 0, 0,224,224,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 15, 31, 63,127,255,255,255,255,255,255,255,255,255,255,254,254,254,254,254,252,252,252,252,252,252,252,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,120,120, 48, 31, 63, 63,120,112,127,127, 63, 0, 6, 31, 63, 63,127,119,119, 63, 55, 0, 3, 15, 63,127,127, 63, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 7, 7, 15, 15, 15, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 15, 15, 15, 7, 7, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// };
+// oled_write_raw_P(raw_logo, sizeof(raw_logo));
+//}
+
+static void render_mochi(void)
+{
+ static const char PROGMEM mochi_logo[] = {
+ 0, 0, 0, 0, 0,224,240,240,240,192,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,224,240,240,240,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252,252,252,252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,248,248,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,192,224,240,240,240,224, 0, 0, 0, 0, 0, 0,128,192,224,240,240,240,240,240,240,224,224,192, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,224,255,255,255, 15, 63,255,254,248,224, 0, 0, 0, 0,224,248,254,255, 31, 31,255,255,255,128, 0, 0, 0,128,224,240,248,252, 60, 28, 28, 30, 28, 60,124,248,248,240,192, 0, 0, 0,128,224,240,248,252, 60, 60, 28, 30, 28, 28, 60, 28, 0, 0, 0,255,255,255,255, 28, 28, 28, 28, 60,124,252,248,240,192, 0, 0, 0, 0,252,252,252,252, 0, 0, 0, 0, 0,192,224,248,252, 63, 31, 7, 3,255,255,255,255, 0, 0, 0, 0,224,254,255,255, 15, 1, 0, 0, 0, 0, 1, 15,255,255,255,248, 0, 0, 0,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 3, 15, 63,255,252,252,255, 63, 15, 3, 0, 0, 0,255,255,255,255, 0, 0, 0, 63,255,255,255,224,128, 0, 0, 0, 0,128,192,255,255,255,127, 4, 0, 0, 63,255,255,255,224,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 60, 63, 63, 63, 61, 60, 60, 60, 60, 60,255,255,255,255, 60, 60, 0, 0, 7,127,255,255,248,128, 0, 0, 0, 0,128,240,255,255,127, 31, 0, 0, 0,
+ 0, 0, 0, 0, 15, 15, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 15, 15, 15, 0, 0, 0, 0, 0, 1, 3, 7, 7, 15, 15, 15, 15, 15, 7, 7, 3, 1, 0, 0, 0, 0, 0, 0, 3, 3, 7, 7, 15, 15, 15, 15, 15, 15, 7, 0, 0, 0, 15, 15, 15, 7, 0, 0, 0, 0, 0, 0, 7, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 7, 0, 0, 0, 0, 0, 0, 1, 3, 7, 7, 15, 15, 15, 15, 7, 7, 3, 1, 0, 0, 0, 0, 0,
+ };
+
+ oled_write_raw_P(mochi_logo, sizeof(mochi_logo));
+}
+
+
+oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
+ return OLED_ROTATION_180; // flips the display 180 degrees
+}
+bool oled_task_kb(void) {
+ if (!oled_task_user()) {
+ return false;
+ }
+ render_mochi();
+ oled_set_cursor(0, 4);
+ oled_write_P(PSTR("Layer: "), false);
+
+ switch(get_highest_layer(layer_state))
+ {
+ case _MAIN:
+ oled_write_ln_P(PSTR("Main"), false);
+ break;
+ case _LEFT:
+ oled_write_ln_P(PSTR("Left"), false);
+ break;
+ case _RIGHT:
+ oled_write_ln_P(PSTR("Right"), false);
+ break;
+ case _TAB:
+ oled_write_ln_P(PSTR("Tab"), false);
+ break;
+ }
+
+ //render_logo();
+ return(true);
+}
+#endif
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_kb(uint8_t index, bool clockwise) {
+ if (!encoder_update_user(index, clockwise)) {
+ return false;
+ }
+ // Volume control
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ return false;
+}
+#endif \ No newline at end of file
diff --git a/keyboards/aidansmithdotdev/fine40/fine40.h b/keyboards/aidansmithdotdev/fine40/fine40.h
new file mode 100644
index 0000000000..dd675cf3ad
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/fine40.h
@@ -0,0 +1,3 @@
+// Copyright 2022 Aidan Smith (@Aidan-OS)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "quantum.h" \ No newline at end of file
diff --git a/keyboards/aidansmithdotdev/fine40/info.json b/keyboards/aidansmithdotdev/fine40/info.json
new file mode 100644
index 0000000000..c2e1afd84c
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/info.json
@@ -0,0 +1,231 @@
+{
+ "manufacturer": "Aidan Smith",
+ "keyboard_name": "aidansmithdotdev/fine40",
+ "maintainer": "Aidan-OS",
+ "bootloader": "atmel-dfu",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "command": false,
+ "console": false,
+ "extrakey": true,
+ "mousekey": true,
+ "encoder": true,
+ "oled": true,
+ "nkro": true
+ },
+ "matrix_pins": {
+ "cols": [ "B3", "E6", "B1", "D7", "F7", "C6" ],
+ "rows": [ "F5", "F6", "B2", "B5", "F4", "D4", "B4", "B6" ]
+ },
+ "processor": "atmega32u4",
+ "url": "https://aidansmith.dev",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x4564",
+ "vid": "0xA059"
+ },
+ "layouts": {
+ "LAYOUT_2u_single_space": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 1], "x": 1, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0 },
+ { "matrix": [0, 5], "x": 5, "y": 0 },
+ { "matrix": [4, 5], "x": 6, "y": 0 },
+ { "matrix": [4, 4], "x": 7, "y": 0 },
+ { "matrix": [4, 3], "x": 8, "y": 0 },
+ { "matrix": [4, 2], "x": 9, "y": 0 },
+ { "matrix": [4, 1], "x": 10, "y": 0 },
+ { "matrix": [4, 0], "x": 11, "y": 0, "w": 1.5 },
+ { "matrix": [1, 0], "x": 0, "y": 1, "w": 1.25 },
+ { "matrix": [1, 1], "x": 1.25, "y": 1 },
+ { "matrix": [1, 2], "x": 2.25, "y": 1 },
+ { "matrix": [1, 3], "x": 3.25, "y": 1 },
+ { "matrix": [1, 4], "x": 4.25, "y": 1 },
+ { "matrix": [1, 5], "x": 5.25, "y": 1 },
+ { "matrix": [5, 5], "x": 6.25, "y": 1 },
+ { "matrix": [5, 4], "x": 7.25, "y": 1 },
+ { "matrix": [5, 3], "x": 8.25, "y": 1 },
+ { "matrix": [5, 2], "x": 9.25, "y": 1 },
+ { "matrix": [5, 1], "x": 10.25, "y": 1 },
+ { "matrix": [5, 0], "x": 11.25, "y": 1, "w": 1.25 },
+ { "matrix": [2, 0], "x": 0, "y": 2, "w": 1.5 },
+ { "matrix": [2, 1], "x": 1.5, "y": 2 },
+ { "matrix": [2, 2], "x": 2.5, "y": 2 },
+ { "matrix": [2, 3], "x": 3.5, "y": 2 },
+ { "matrix": [2, 4], "x": 4.5, "y": 2 },
+ { "matrix": [2, 5], "x": 5.5, "y": 2 },
+ { "matrix": [6, 5], "x": 6.5, "y": 2 },
+ { "matrix": [6, 4], "x": 7.5, "y": 2 },
+ { "matrix": [6, 3], "x": 8.5, "y": 2 },
+ { "matrix": [6, 2], "x": 9.5, "y": 2 },
+ { "matrix": [6, 1], "x": 10.5, "y": 2 },
+ { "matrix": [6, 0], "x": 11.5, "y": 2 },
+ { "matrix": [3, 0], "x": 0, "y": 3 },
+ { "matrix": [3, 1], "x": 1, "y": 3 },
+ { "matrix": [3, 2], "x": 2, "y": 3 },
+ { "matrix": [3, 3], "x": 3, "y": 3 },
+ { "matrix": [3, 4], "x": 4, "y": 3, "w": 1.25 },
+ { "matrix": [3, 5], "x": 5.25, "y": 3, "w": 2 },
+ { "matrix": [7, 5], "x": 7.25, "y": 3, "w": 1.25 },
+ { "matrix": [7, 4], "x": 8.5, "y": 3 },
+ { "matrix": [7, 3], "x": 9.5, "y": 3 },
+ { "matrix": [7, 2], "x": 10.5, "y": 3 },
+ { "matrix": [7, 1], "x": 11.5, "y": 3 },
+ { "matrix": [7, 0], "x": 13, "y": 3 }
+ ]
+ },
+ "LAYOUT_2u_split_space": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 1], "x": 1, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0 },
+ { "matrix": [0, 5], "x": 5, "y": 0 },
+ { "matrix": [4, 5], "x": 6, "y": 0 },
+ { "matrix": [4, 4], "x": 7, "y": 0 },
+ { "matrix": [4, 3], "x": 8, "y": 0 },
+ { "matrix": [4, 2], "x": 9, "y": 0 },
+ { "matrix": [4, 1], "x": 10, "y": 0 },
+ { "matrix": [4, 0], "x": 11, "y": 0, "w": 1.5 },
+ { "matrix": [1, 0], "x": 0, "y": 1, "w": 1.25 },
+ { "matrix": [1, 1], "x": 1.25, "y": 1 },
+ { "matrix": [1, 2], "x": 2.25, "y": 1 },
+ { "matrix": [1, 3], "x": 3.25, "y": 1 },
+ { "matrix": [1, 4], "x": 4.25, "y": 1 },
+ { "matrix": [1, 5], "x": 5.25, "y": 1 },
+ { "matrix": [5, 5], "x": 6.25, "y": 1 },
+ { "matrix": [5, 4], "x": 7.25, "y": 1 },
+ { "matrix": [5, 3], "x": 8.25, "y": 1 },
+ { "matrix": [5, 2], "x": 9.25, "y": 1 },
+ { "matrix": [5, 1], "x": 10.25, "y": 1 },
+ { "matrix": [5, 0], "x": 11.25, "y": 1, "w": 1.25 },
+ { "matrix": [2, 0], "x": 0, "y": 2, "w": 1.5 },
+ { "matrix": [2, 1], "x": 1.5, "y": 2 },
+ { "matrix": [2, 2], "x": 2.5, "y": 2 },
+ { "matrix": [2, 3], "x": 3.5, "y": 2 },
+ { "matrix": [2, 4], "x": 4.5, "y": 2 },
+ { "matrix": [2, 5], "x": 5.5, "y": 2 },
+ { "matrix": [6, 5], "x": 6.5, "y": 2 },
+ { "matrix": [6, 4], "x": 7.5, "y": 2 },
+ { "matrix": [6, 3], "x": 8.5, "y": 2 },
+ { "matrix": [6, 2], "x": 9.5, "y": 2 },
+ { "matrix": [6, 1], "x": 10.5, "y": 2 },
+ { "matrix": [6, 0], "x": 11.5, "y": 2 },
+ { "matrix": [3, 0], "x": 0, "y": 3 },
+ { "matrix": [3, 1], "x": 1, "y": 3 },
+ { "matrix": [3, 2], "x": 2, "y": 3 },
+ { "matrix": [3, 3], "x": 3, "y": 3, "w": 1.25 },
+ { "matrix": [3, 4], "x": 4.25, "y": 3, "w": 2 },
+ { "matrix": [7, 5], "x": 6.25, "y": 3, "w": 2 },
+ { "matrix": [7, 4], "x": 8.25, "y": 3, "w": 1.25 },
+ { "matrix": [7, 3], "x": 9.5, "y": 3 },
+ { "matrix": [7, 2], "x": 10.5, "y": 3 },
+ { "matrix": [7, 1], "x": 11.5, "y": 3 },
+ { "matrix": [7, 0], "x": 13, "y": 3 }
+ ]
+ },
+ "LAYOUT_225u_split_space": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 1], "x": 1, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0 },
+ { "matrix": [0, 5], "x": 5, "y": 0 },
+ { "matrix": [4, 5], "x": 6, "y": 0 },
+ { "matrix": [4, 4], "x": 7, "y": 0 },
+ { "matrix": [4, 3], "x": 8, "y": 0 },
+ { "matrix": [4, 2], "x": 9, "y": 0 },
+ { "matrix": [4, 1], "x": 10, "y": 0 },
+ { "matrix": [4, 0], "x": 11, "y": 0, "w": 1.5 },
+ { "matrix": [1, 0], "x": 0, "y": 1, "w": 1.25 },
+ { "matrix": [1, 1], "x": 1.25, "y": 1 },
+ { "matrix": [1, 2], "x": 2.25, "y": 1 },
+ { "matrix": [1, 3], "x": 3.25, "y": 1 },
+ { "matrix": [1, 4], "x": 4.25, "y": 1 },
+ { "matrix": [1, 5], "x": 5.25, "y": 1 },
+ { "matrix": [5, 5], "x": 6.25, "y": 1 },
+ { "matrix": [5, 4], "x": 7.25, "y": 1 },
+ { "matrix": [5, 3], "x": 8.25, "y": 1 },
+ { "matrix": [5, 2], "x": 9.25, "y": 1 },
+ { "matrix": [5, 1], "x": 10.25, "y": 1 },
+ { "matrix": [5, 0], "x": 11.25, "y": 1, "w": 1.25 },
+ { "matrix": [2, 0], "x": 0, "y": 2, "w": 1.5 },
+ { "matrix": [2, 1], "x": 1.5, "y": 2 },
+ { "matrix": [2, 2], "x": 2.5, "y": 2 },
+ { "matrix": [2, 3], "x": 3.5, "y": 2 },
+ { "matrix": [2, 4], "x": 4.5, "y": 2 },
+ { "matrix": [2, 5], "x": 5.5, "y": 2 },
+ { "matrix": [6, 5], "x": 6.5, "y": 2 },
+ { "matrix": [6, 4], "x": 7.5, "y": 2 },
+ { "matrix": [6, 3], "x": 8.5, "y": 2 },
+ { "matrix": [6, 2], "x": 9.5, "y": 2 },
+ { "matrix": [6, 1], "x": 10.5, "y": 2 },
+ { "matrix": [6, 0], "x": 11.5, "y": 2 },
+ { "matrix": [3, 0], "x": 0, "y": 3 },
+ { "matrix": [3, 1], "x": 1, "y": 3 },
+ { "matrix": [3, 2], "x": 2, "y": 3 },
+ { "matrix": [3, 3], "x": 3, "y": 3 },
+ { "matrix": [3, 4], "x": 4, "y": 3, "w": 2.25 },
+ { "matrix": [7, 5], "x": 6.25, "y": 3, "w": 2.25 },
+ { "matrix": [7, 4], "x": 8.5, "y": 3 },
+ { "matrix": [7, 3], "x": 9.5, "y": 3 },
+ { "matrix": [7, 2], "x": 10.5, "y": 3 },
+ { "matrix": [7, 1], "x": 11.5, "y": 3 },
+ { "matrix": [7, 0], "x": 13, "y": 3 }
+ ]
+ },
+ "LAYOUT_7u_space": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 1], "x": 1, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0 },
+ { "matrix": [0, 5], "x": 5, "y": 0 },
+ { "matrix": [4, 5], "x": 6, "y": 0 },
+ { "matrix": [4, 4], "x": 7, "y": 0 },
+ { "matrix": [4, 3], "x": 8, "y": 0 },
+ { "matrix": [4, 2], "x": 9, "y": 0 },
+ { "matrix": [4, 1], "x": 10, "y": 0 },
+ { "matrix": [4, 0], "x": 11, "y": 0, "w": 1.5 },
+ { "matrix": [1, 0], "x": 0, "y": 1, "w": 1.25 },
+ { "matrix": [1, 1], "x": 1.25, "y": 1 },
+ { "matrix": [1, 2], "x": 2.25, "y": 1 },
+ { "matrix": [1, 3], "x": 3.25, "y": 1 },
+ { "matrix": [1, 4], "x": 4.25, "y": 1 },
+ { "matrix": [1, 5], "x": 5.25, "y": 1 },
+ { "matrix": [5, 5], "x": 6.25, "y": 1 },
+ { "matrix": [5, 4], "x": 7.25, "y": 1 },
+ { "matrix": [5, 3], "x": 8.25, "y": 1 },
+ { "matrix": [5, 2], "x": 9.25, "y": 1 },
+ { "matrix": [5, 1], "x": 10.25, "y": 1 },
+ { "matrix": [5, 0], "x": 11.25, "y": 1, "w": 1.25 },
+ { "matrix": [2, 0], "x": 0, "y": 2, "w": 1.5 },
+ { "matrix": [2, 1], "x": 1.5, "y": 2 },
+ { "matrix": [2, 2], "x": 2.5, "y": 2 },
+ { "matrix": [2, 3], "x": 3.5, "y": 2 },
+ { "matrix": [2, 4], "x": 4.5, "y": 2 },
+ { "matrix": [2, 5], "x": 5.5, "y": 2 },
+ { "matrix": [6, 5], "x": 6.5, "y": 2 },
+ { "matrix": [6, 4], "x": 7.5, "y": 2 },
+ { "matrix": [6, 3], "x": 8.5, "y": 2 },
+ { "matrix": [6, 2], "x": 9.5, "y": 2 },
+ { "matrix": [6, 1], "x": 10.5, "y": 2 },
+ { "matrix": [6, 0], "x": 11.5, "y": 2 },
+ { "matrix": [3, 0], "x": 0, "y": 3, "w": 1.25 },
+ { "matrix": [3, 1], "x": 1.25, "y": 3, "w": 1.25 },
+ { "matrix": [3, 5], "x": 2.5, "y": 3, "w": 7 },
+ { "matrix": [7, 3], "x": 9.5, "y": 3 },
+ { "matrix": [7, 2], "x": 10.5, "y": 3 },
+ { "matrix": [7, 1], "x": 11.5, "y": 3 },
+ { "matrix": [7, 0], "x": 13, "y": 3 }
+ ]
+ }
+ }
+}
diff --git a/keyboards/aidansmithdotdev/fine40/keymaps/default/keymap.c b/keyboards/aidansmithdotdev/fine40/keymaps/default/keymap.c
new file mode 100644
index 0000000000..37085b7c90
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/keymaps/default/keymap.c
@@ -0,0 +1,43 @@
+// Copyright 2022 Aidan Smith (@Aidan-OS)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+
+enum keyboard_layers {
+ _MAIN,
+ _RIGHT,
+ _LEFT,
+ _TAB,
+};
+
+#define LT3_TAB LT(_TAB, KC_TAB)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_MAIN] = LAYOUT_2u_single_space(
+ KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_BSPC ,
+ LT3_TAB , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_QUOT ,
+ KC_LSFT , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_ENT ,
+ KC_LCTL , KC_RALT , KC_LGUI , KC_BSLS , MO(_LEFT) , KC_SPC , MO(_RIGHT) , KC_LEFT , KC_DOWN , KC_UP , KC_RIGHT , KC_MPLY
+),
+
+[_LEFT] = LAYOUT_2u_single_space( /* LEFT */
+ KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_DELETE ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_UNDERSCORE , KC_PLUS , KC_LEFT_CURLY_BRACE , KC_RIGHT_CURLY_BRACE , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_HOME , KC_PGDN , KC_PGUP , KC_END , _______
+),
+
+[_RIGHT] = LAYOUT_2u_single_space( /* RIGHT */
+ KC_TILDE , KC_EXCLAIM , KC_AT , KC_HASH , KC_DOLLAR , KC_PERCENT , KC_CIRCUMFLEX , KC_AMPERSAND , KC_ASTERISK , KC_LEFT_PAREN , KC_RIGHT_PAREN , KC_DELETE ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MINS , KC_EQL , KC_LBRC , KC_RBRC , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_LT , KC_GT , _______ , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MUTE , KC_VOLD , KC_VOLU , KC_MPLY , _______
+),
+
+[_TAB] = LAYOUT_2u_single_space( /* Tab */
+ KC_ESC , RESET , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ,
+ _______ , KC_F11 , KC_F12 , KC_F13 , KC_F14 , KC_F15 , KC_F16 , KC_F17 , KC_F18 , KC_F19 , KC_F20 , _______ ,
+ _______ , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MS_L , KC_MS_D , KC_MS_U , KC_MS_R , _______
+),
+};
diff --git a/keyboards/aidansmithdotdev/fine40/keymaps/via/keymap.c b/keyboards/aidansmithdotdev/fine40/keymaps/via/keymap.c
new file mode 100644
index 0000000000..37085b7c90
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/keymaps/via/keymap.c
@@ -0,0 +1,43 @@
+// Copyright 2022 Aidan Smith (@Aidan-OS)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+
+enum keyboard_layers {
+ _MAIN,
+ _RIGHT,
+ _LEFT,
+ _TAB,
+};
+
+#define LT3_TAB LT(_TAB, KC_TAB)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_MAIN] = LAYOUT_2u_single_space(
+ KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_BSPC ,
+ LT3_TAB , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_QUOT ,
+ KC_LSFT , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_ENT ,
+ KC_LCTL , KC_RALT , KC_LGUI , KC_BSLS , MO(_LEFT) , KC_SPC , MO(_RIGHT) , KC_LEFT , KC_DOWN , KC_UP , KC_RIGHT , KC_MPLY
+),
+
+[_LEFT] = LAYOUT_2u_single_space( /* LEFT */
+ KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_DELETE ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_UNDERSCORE , KC_PLUS , KC_LEFT_CURLY_BRACE , KC_RIGHT_CURLY_BRACE , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_HOME , KC_PGDN , KC_PGUP , KC_END , _______
+),
+
+[_RIGHT] = LAYOUT_2u_single_space( /* RIGHT */
+ KC_TILDE , KC_EXCLAIM , KC_AT , KC_HASH , KC_DOLLAR , KC_PERCENT , KC_CIRCUMFLEX , KC_AMPERSAND , KC_ASTERISK , KC_LEFT_PAREN , KC_RIGHT_PAREN , KC_DELETE ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MINS , KC_EQL , KC_LBRC , KC_RBRC , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_LT , KC_GT , _______ , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MUTE , KC_VOLD , KC_VOLU , KC_MPLY , _______
+),
+
+[_TAB] = LAYOUT_2u_single_space( /* Tab */
+ KC_ESC , RESET , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ,
+ _______ , KC_F11 , KC_F12 , KC_F13 , KC_F14 , KC_F15 , KC_F16 , KC_F17 , KC_F18 , KC_F19 , KC_F20 , _______ ,
+ _______ , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , _______ ,
+ _______ , _______ , _______ , _______ , _______ , _______ , _______ , KC_MS_L , KC_MS_D , KC_MS_U , KC_MS_R , _______
+),
+};
diff --git a/keyboards/aidansmithdotdev/fine40/keymaps/via/rules.mk b/keyboards/aidansmithdotdev/fine40/keymaps/via/rules.mk
new file mode 100644
index 0000000000..036bd6d1c3
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes \ No newline at end of file
diff --git a/keyboards/aidansmithdotdev/fine40/readme.md b/keyboards/aidansmithdotdev/fine40/readme.md
new file mode 100644
index 0000000000..ad3eba7c5c
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/readme.md
@@ -0,0 +1,27 @@
+# Fine!40 PCB (For Mochi40)
+
+![aidansmithdotdev/fine40](https://i.imgur.com/2JMorvxh.png)
+
+The PCB for the Mochi40, a spiritual successor to the unreleased Whimsy recreated from scratch and made completely open source! With an OLED, Rotary Encoder, and headers for both the Elite-C and Nice!Nano, this board gives you all you could want in a 40%.
+
+* Keyboard Maintainer: [Aidan Smith](https://github.com/Aidan-OS)
+* Hardware Supported: Fine!40
+* Hardware Availability: https://github.com/Aidan-OS/Mochi40
+
+Make example for this keyboard (after setting up your build environment):
+
+ make aidansmithdotdev/fine40:default
+
+Flashing example for this keyboard:
+
+ make aidansmithdotdev/fine40:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (top left key) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
+* **Keycode in layout**: Press the key mapped to `RESET` if it is available
diff --git a/keyboards/aidansmithdotdev/fine40/rules.mk b/keyboards/aidansmithdotdev/fine40/rules.mk
new file mode 100644
index 0000000000..2e3ef9fb84
--- /dev/null
+++ b/keyboards/aidansmithdotdev/fine40/rules.mk
@@ -0,0 +1 @@
+OLED_DRIVER = SSD1306
diff --git a/keyboards/annepro2/c15/config.h b/keyboards/annepro2/c15/config.h
index ff92aeea8e..2ebb962efb 100644
--- a/keyboards/annepro2/c15/config.h
+++ b/keyboards/annepro2/c15/config.h
@@ -49,3 +49,21 @@
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD
+
+// SPI configuration
+#define SPI_DRIVER SPID1
+#define SPI_SCK_PIN A0
+#define SPI_MOSI_PIN A1
+#define SPI_MISO_PIN A2
+
+// Flash configuration
+#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN B6
+#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 16
+#define EXTERNAL_FLASH_PAGE_SIZE 256
+#define EXTERNAL_FLASH_SECTOR_SIZE 4096
+#define EXTERNAL_FLASH_BLOCK_SIZE 4096
+#define EXTERNAL_FLASH_SIZE (256 * 1024) // 2M-bit flash size
+
+// Wear-leveling driver configuration
+#define WEAR_LEVELING_LOGICAL_SIZE 1024
+#define WEAR_LEVELING_BACKING_SIZE (WEAR_LEVELING_LOGICAL_SIZE * 2)
diff --git a/keyboards/annepro2/c15/rules.mk b/keyboards/annepro2/c15/rules.mk
index 2c518b6339..302aeecbe6 100644
--- a/keyboards/annepro2/c15/rules.mk
+++ b/keyboards/annepro2/c15/rules.mk
@@ -26,6 +26,10 @@ BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
+# Wear-levelling driver
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = spi_flash
+
# Custom RGB matrix handling
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = custom
diff --git a/keyboards/annepro2/c18/config.h b/keyboards/annepro2/c18/config.h
index 82a406a157..5e4978048b 100644
--- a/keyboards/annepro2/c18/config.h
+++ b/keyboards/annepro2/c18/config.h
@@ -47,3 +47,21 @@
// Obins stock firmware has something similar to this already enabled, but disabled by default in QMK
#define PERMISSIVE_HOLD
+
+// SPI configuration
+#define SPI_DRIVER SPID1
+#define SPI_SCK_PIN A0
+#define SPI_MOSI_PIN A1
+#define SPI_MISO_PIN A2
+
+// Flash configuration
+#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN A3
+#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 16
+#define EXTERNAL_FLASH_PAGE_SIZE 256
+#define EXTERNAL_FLASH_SECTOR_SIZE 4096
+#define EXTERNAL_FLASH_BLOCK_SIZE 4096
+#define EXTERNAL_FLASH_SIZE (256 * 1024) // 2M-bit flash size
+
+// Wear-leveling driver configuration
+#define WEAR_LEVELING_LOGICAL_SIZE 1024
+#define WEAR_LEVELING_BACKING_SIZE (WEAR_LEVELING_LOGICAL_SIZE * 2)
diff --git a/keyboards/annepro2/c18/rules.mk b/keyboards/annepro2/c18/rules.mk
index 60c2e08648..b1c7208f8b 100644
--- a/keyboards/annepro2/c18/rules.mk
+++ b/keyboards/annepro2/c18/rules.mk
@@ -26,6 +26,10 @@ BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
+# Wear-levelling driver
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = spi_flash
+
# Custom RGB matrix handling
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = custom
diff --git a/keyboards/annepro2/halconf.h b/keyboards/annepro2/halconf.h
index 686b91a7fb..dcb04eab1b 100644
--- a/keyboards/annepro2/halconf.h
+++ b/keyboards/annepro2/halconf.h
@@ -25,4 +25,8 @@
#define SERIAL_USB_BUFFERS_SIZE 256
+#define HAL_USE_SPI TRUE
+#define SPI_USE_WAIT TRUE
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+
#include_next <halconf.h>
diff --git a/keyboards/annepro2/mcuconf.h b/keyboards/annepro2/mcuconf.h
index 8265fe6eb9..9e39bd9681 100644
--- a/keyboards/annepro2/mcuconf.h
+++ b/keyboards/annepro2/mcuconf.h
@@ -60,3 +60,11 @@
#define HT32_USB_USE_USB0 TRUE
#define HT32_USB_USB0_IRQ_PRIORITY 5
+
+/*
+ * SPI driver setting
+ */
+
+#define HT32_SPI_USE_SPI1 TRUE
+#define HT32_SPI1_IRQ_PRIORITY 9
+
diff --git a/keyboards/bandominedoni/keymaps/led/keymap.c b/keyboards/bandominedoni/keymaps/led/keymap.c
index 305756b5b1..4a88d33872 100644
--- a/keyboards/bandominedoni/keymaps/led/keymap.c
+++ b/keyboards/bandominedoni/keymaps/led/keymap.c
@@ -180,7 +180,7 @@ void keyboard_post_init_user(void) {
#ifdef RGB_MATRIX_ENABLE
void rgb_matrix_indicators_user(void) {
if (rgb_matrix_is_enabled()) { // turn the lights on when it is enabled.
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _CLOSE:
// rgb_matrix_set_color(pgm_read_byte(&convert_led_location2number[11]), RGB_RED); // RGB_TOG <- too heavy.
diff --git a/keyboards/bandominedoni/keymaps/via/keymap.c b/keyboards/bandominedoni/keymaps/via/keymap.c
index ad6833d692..342ed1d40c 100644
--- a/keyboards/bandominedoni/keymaps/via/keymap.c
+++ b/keyboards/bandominedoni/keymaps/via/keymap.c
@@ -118,7 +118,7 @@ void keyboard_post_init_user(void) {
#ifdef RGB_MATRIX_ENABLE
void rgb_matrix_indicators_user(void) {
if (rgb_matrix_is_enabled()) { // turn the lights on when it is enabled.
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _CLOSE:
// rgb_matrix_set_color(pgm_read_byte(&convert_led_location2number[11]), RGB_RED); // RGB_TOG <- too heavy.
diff --git a/keyboards/basekeys/slice/rev1/keymaps/2moons/keymap.c b/keyboards/basekeys/slice/rev1/keymaps/2moons/keymap.c
index 26ca151089..1292f2d2ed 100644
--- a/keyboards/basekeys/slice/rev1/keymaps/2moons/keymap.c
+++ b/keyboards/basekeys/slice/rev1/keymaps/2moons/keymap.c
@@ -46,8 +46,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/basekeys/slice/rev1_rgb/keymaps/2moons_rgb/keymap.c b/keyboards/basekeys/slice/rev1_rgb/keymaps/2moons_rgb/keymap.c
index 05de0e42d0..7e82c7b7d2 100644
--- a/keyboards/basekeys/slice/rev1_rgb/keymaps/2moons_rgb/keymap.c
+++ b/keyboards/basekeys/slice/rev1_rgb/keymaps/2moons_rgb/keymap.c
@@ -39,8 +39,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/bastardkb/charybdis/3x5/config.h b/keyboards/bastardkb/charybdis/3x5/config.h
index 89b896bc35..b12603fade 100644
--- a/keyboards/bastardkb/charybdis/3x5/config.h
+++ b/keyboards/bastardkb/charybdis/3x5/config.h
@@ -58,8 +58,8 @@
/* Set 0 if debouncing isn't needed. */
#define DEBOUNCE 5
-/* PMW3360 settings. */
-#define PMW3360_CS_PIN B0
+/* PMW33XX settings. */
+#define PMW33XX_CS_PIN B0
// Trackball angle adjustment.
#define ROTATIONAL_TRANSFORM_ANGLE -25
diff --git a/keyboards/bastardkb/charybdis/3x5/keymaps/drashna/config.h b/keyboards/bastardkb/charybdis/3x5/keymaps/drashna/config.h
index 0f08aee9ef..39204a3667 100644
--- a/keyboards/bastardkb/charybdis/3x5/keymaps/drashna/config.h
+++ b/keyboards/bastardkb/charybdis/3x5/keymaps/drashna/config.h
@@ -98,10 +98,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #define EXTERNAL_EEPROM_ADDRESS_SIZE 2
/* pmw3360 config */
-#undef PMW3360_CS_PIN
-#define PMW3360_CS_PIN B0
-#define PMW3360_SPI_MODE 3
-#define PMW3360_SPI_DIVISOR 64
+#undef PMW33XX_CS_PIN
+#define PMW33XX_CS_PIN B0
#define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
#define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400
diff --git a/keyboards/bastardkb/charybdis/4x6/config.h b/keyboards/bastardkb/charybdis/4x6/config.h
index 423f12fdbe..6760129ef8 100644
--- a/keyboards/bastardkb/charybdis/4x6/config.h
+++ b/keyboards/bastardkb/charybdis/4x6/config.h
@@ -60,8 +60,8 @@
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
-/* PMW3360 settings. */
-#define PMW3360_CS_PIN B0
+/* PMW33XX settings. */
+#define PMW33XX_CS_PIN B0
#define RGB_DI_PIN D3
#define RGBLED_NUM 56
diff --git a/keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h b/keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h
index 2b6e11ec61..63e67aa6d8 100644
--- a/keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h
+++ b/keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h
@@ -87,11 +87,9 @@
#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN A4
#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 64
-#undef PMW3360_CS_PIN
-#define PMW3360_CS_PIN A15 // b14
-#define PMW3360_CS_MODE 3
-#define PMW3360_CS_DIVISOR 64
-#define PMW3360_LIFTOFF_DISTANCE 0b1111
+#undef PMW33XX_CS_PIN
+#define PMW33XX_CS_PIN A15 // b14
+#define PMW33XX_LIFTOFF_DISTANCE 0b1111
#undef ROTATIONAL_TRANSFORM_ANGLE
#define ROTATIONAL_TRANSFORM_ANGLE -65
diff --git a/keyboards/bastardkb/charybdis/charybdis.c b/keyboards/bastardkb/charybdis/charybdis.c
index f94682ba41..29603042b2 100644
--- a/keyboards/bastardkb/charybdis/charybdis.c
+++ b/keyboards/bastardkb/charybdis/charybdis.c
@@ -18,6 +18,8 @@
*/
#include "charybdis.h"
+#include "transactions.h"
+#include <string.h>
#ifdef CONSOLE_ENABLE
# include "print.h"
@@ -160,10 +162,8 @@ void charybdis_set_pointer_dragscroll_enabled(bool enable) {
maybe_update_pointing_device_cpi(&g_charybdis_config);
}
-void pointing_device_init_kb(void) { maybe_update_pointing_device_cpi(&g_charybdis_config); }
-
# ifndef CONSTRAIN_HID
-# define CONSTRAIN_HID(value) ((value) < -127 ? -127 : ((value) > 127 ? 127 : (value)))
+# define CONSTRAIN_HID(value) ((value) < XY_REPORT_MIN ? XY_REPORT_MIN : ((value) > XY_REPORT_MAX ? XY_REPORT_MAX : (value)))
# endif // !CONSTRAIN_HID
/**
@@ -340,4 +340,49 @@ void matrix_init_kb(void) {
read_charybdis_config_from_eeprom(&g_charybdis_config);
matrix_init_user();
}
+
+# ifdef CHARYBDIS_CONFIG_SYNC
+void charybdis_config_sync_handler(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
+ if (initiator2target_buffer_size == sizeof(g_charybdis_config)) {
+ memcpy(&g_charybdis_config, initiator2target_buffer, sizeof(g_charybdis_config));
+ }
+}
+# endif
+
+void keyboard_post_init_kb(void) {
+ maybe_update_pointing_device_cpi(&g_charybdis_config);
+# ifdef CHARYBDIS_CONFIG_SYNC
+ transaction_register_rpc(RPC_ID_KB_CONFIG_SYNC, charybdis_config_sync_handler);
+# endif
+ keyboard_post_init_user();
+}
+
+# ifdef CHARYBDIS_CONFIG_SYNC
+void housekeeping_task_kb(void) {
+ if (is_keyboard_master()) {
+ // Keep track of the last state, so that we can tell if we need to propagate to slave
+ static charybdis_config_t last_charybdis_config = {0};
+ static uint32_t last_sync = 0;
+ bool needs_sync = false;
+
+ // Check if the state values are different
+ if (memcmp(&g_charybdis_config, &last_charybdis_config, sizeof(g_charybdis_config))) {
+ needs_sync = true;
+ memcpy(&last_charybdis_config, &g_charybdis_config, sizeof(g_charybdis_config));
+ }
+ // Send to slave every 500ms regardless of state change
+ if (timer_elapsed32(last_sync) > 500) {
+ needs_sync = true;
+ }
+
+ // Perform the sync if requested
+ if (needs_sync) {
+ if (transaction_rpc_send(RPC_ID_KB_CONFIG_SYNC, sizeof(g_charybdis_config), &g_charybdis_config)) {
+ last_sync = timer_read32();
+ }
+ }
+ }
+ // no need for user function, is called already
+}
+# endif // CHARYBDIS_CONFIG_SYNC
#endif // POINTING_DEVICE_ENABLE
diff --git a/keyboards/bastardkb/charybdis/post_config.h b/keyboards/bastardkb/charybdis/post_config.h
index 540751f6c6..b769722b64 100644
--- a/keyboards/bastardkb/charybdis/post_config.h
+++ b/keyboards/bastardkb/charybdis/post_config.h
@@ -20,6 +20,11 @@
#pragma once
+// Enable syncing of charybdis config
+#ifdef CHARYBDIS_CONFIG_SYNC
+# define SPLIT_TRANSACTION_IDS_KB RPC_ID_KB_CONFIG_SYNC
+#endif
+
/* Mouse config. */
#ifndef MOUSEKEY_MOVE_DELTA
diff --git a/keyboards/bastardkb/charybdis/readme.md b/keyboards/bastardkb/charybdis/readme.md
index 461f33117c..d786abf36e 100644
--- a/keyboards/bastardkb/charybdis/readme.md
+++ b/keyboards/bastardkb/charybdis/readme.md
@@ -176,3 +176,23 @@ To disable the custom keycodes, and reduce binary size, simply add a definition
```c
#define NO_CHARYBDIS_KEYCODES
```
+
+### Configuration Syncing
+
+If you want/need to enable syncing of the charybdis config, such as to read the sniping or drag scroll modes on the other half (such as for displaying the status via rgb matrix, or added on screens, or what not), you can enabled this. To do so, add this to your `config.h`:
+
+```c
+#define CHARYBDIS_CONFIG_SYNC
+```
+
+Note that you will need to reflash both sides when enabling this.
+
+### Enable Large Mouse Reports
+
+By default, the X and Y motion for the pointing device/mouse reports is -127 to 127. You can definitely hit the limit for that with the sensors. You can enable support for -32767 to 32767 by adding this to your `config.h`:
+
+```c
+#define MOUSE_EXTENDED_REPORT
+```
+
+Note that you will need to reflash both sides when enabling this.
diff --git a/keyboards/bbrfkr/dynamis/config.h b/keyboards/bbrfkr/dynamis/config.h
index 0c11416612..abf4058e7b 100644
--- a/keyboards/bbrfkr/dynamis/config.h
+++ b/keyboards/bbrfkr/dynamis/config.h
@@ -52,5 +52,5 @@
#define ENCODERS_PAD_A { B7 }
#define ENCODERS_PAD_B { E6 }
-#define PMW3360_CS_PIN SPI_SS_PIN
+#define PMW33XX_CS_PIN SPI_SS_PIN
#define POINTING_DEVICE_INVERT_Y
diff --git a/keyboards/biacco42/ergo42/keymaps/hdbx/keymap.c b/keyboards/biacco42/ergo42/keymaps/hdbx/keymap.c
index bb3b6fac48..58f01bb322 100644
--- a/keyboards/biacco42/ergo42/keymaps/hdbx/keymap.c
+++ b/keyboards/biacco42/ergo42/keymaps/hdbx/keymap.c
@@ -134,7 +134,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
// RGB Underglow使用時ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼æ¯Žã®ã‚«ãƒ©ãƒ¼åˆ‡ã‚Šæ›¿ãˆ
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
@@ -148,7 +148,7 @@ void matrix_init_user(void) {
layer_state_t layer_state_set_user(layer_state_t state) {
state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
#ifdef RGBLIGHT_ENABLE
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
rgblight_setrgb_chartreuse(); // RAISE:シャルトリューズ
break;
diff --git a/keyboards/boardsource/holiday/spooky/config.h b/keyboards/boardsource/holiday/spooky/config.h
deleted file mode 100644
index 87d63b0d9e..0000000000
--- a/keyboards/boardsource/holiday/spooky/config.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Copyright 2020 boardsource
-
-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 "config_common.h"
-
-/* USB Device descriptor parameter */
-#define VENDOR_ID 0x4273
-#define PRODUCT_ID 0x1031
-#define DEVICE_VER 0x0001
-#define MANUFACTURER Boardsource
-#define PRODUCT spooky
-
-/* key matrix size */
-#define MATRIX_ROWS 2
-#define MATRIX_COLS 3
-
-#define DIRECT_PINS { {E6,B4,B5}, {B3,B2,B6}}
-
-#define RGB_DI_PIN D3
-#define RGBLIGHT_ANIMATIONS
-#ifdef RGBLIGHT_ENABLE
-#define RGBLED_NUM 5 // Number of LEDs
-#endif
-
-
-//#define BACKLIGHT_PIN B7
-//#define BACKLIGHT_LEVELS 3
-//#define BACKLIGHT_BREATHING
-
-//#define RGB_DI_PIN E2
-//#ifdef RGB_DI_PIN
-//# define RGBLED_NUM 16
-//# define RGBLIGHT_HUE_STEP 8
-//# define RGBLIGHT_SAT_STEP 8
-//# define RGBLIGHT_VAL_STEP 8
-//# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
-//# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
-/*== all animations enable ==*/
-//# define RGBLIGHT_ANIMATIONS
-/*== or choose animations ==*/
-//# define RGBLIGHT_EFFECT_BREATHING
-//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
-//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
-//# define RGBLIGHT_EFFECT_SNAKE
-//# define RGBLIGHT_EFFECT_KNIGHT
-//# define RGBLIGHT_EFFECT_CHRISTMAS
-//# define RGBLIGHT_EFFECT_STATIC_GRADIENT
-//# define RGBLIGHT_EFFECT_RGB_TEST
-//# define RGBLIGHT_EFFECT_ALTERNATING
-/*== customize breathing effect ==*/
-/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
-//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
-/*==== use exp() and sin() ====*/
-//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
-//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
-//#endif
-
-/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
-#define DEBOUNCE 5
-
-/* define if matrix has ghost (lacks anti-ghosting diodes) */
-//#define MATRIX_HAS_GHOST
-
-/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
-#define LOCKING_SUPPORT_ENABLE
-/* Locking resynchronize hack */
-#define LOCKING_RESYNC_ENABLE
-
-/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
- * This is useful for the Windows task manager shortcut (ctrl+shift+esc).
- */
-//#define GRAVE_ESC_CTRL_OVERRIDE
-
-/*
- * Force NKRO
- *
- * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
- * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
- * makefile for this to work.)
- *
- * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
- * until the next keyboard reset.
- *
- * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
- * fully operational during normal computer usage.
- *
- * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
- * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
- * bootmagic, NKRO mode will always be enabled until it is toggled again during a
- * power-up.
- *
- */
-//#define FORCE_NKRO
-
-/*
- * Feature disable options
- * These options are also useful to firmware size reduction.
- */
-
-/* disable debug print */
-//#define NO_DEBUG
-
-/* disable print */
-//#define NO_PRINT
-
-/* disable action features */
-//#define NO_ACTION_LAYER
-//#define NO_ACTION_TAPPING
-//#define NO_ACTION_ONESHOT
-
-/* Bootmagic Lite key configuration */
-//#define BOOTMAGIC_LITE_ROW 0
-//#define BOOTMAGIC_LITE_COLUMN 0
diff --git a/keyboards/boardsource/holiday/spooky/info.json b/keyboards/boardsource/holiday/spooky/info.json
index c942b2af11..56be9f7d26 100644
--- a/keyboards/boardsource/holiday/spooky/info.json
+++ b/keyboards/boardsource/holiday/spooky/info.json
@@ -1,18 +1,46 @@
{
- "keyboard_name": "spooky",
- "url": "https://boardsource.xyz/store/5f783f6da2c1b43e37ca0795",
- "maintainer": "boardsource",
- "layouts": {
- "LAYOUT_ortho_2x3": {
- "layout": [
- { "label": "k00", "x": 0, "y": 0 },
- { "label": "k01", "x": 1, "y": 0 },
- { "label": "k02", "x": 2, "y": 0 },
-
- { "label": "k10", "x": 0, "y": 1 },
- { "label": "k11", "x": 1, "y": 1 },
- { "label": "k12", "x": 2, "y": 1 }
- ]
- }
+ "manufacturer": "Boardsource",
+ "keyboard_name": "Spooky",
+ "maintainer": "waffle87",
+ "development_board": "promicro",
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true,
+ "rgblight": true
+ },
+ "matrix_pins": {
+ "direct": [
+ ["E6", "B4", "B5"],
+ ["B3", "B2", "B6"]
+ ]
+ },
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x1031",
+ "vid": "0x4273"
+ },
+ "rgblight": {
+ "led_count": 5,
+ "pin": "D3",
+ "sleep": true,
+ "animations": {
+ "all": true
}
+ },
+ "community_layouts": [
+ "ortho_2x3"
+ ],
+ "layouts": {
+ "LAYOUT_ortho_2x3": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 1], "x": 1, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [1, 0], "x": 0, "y": 1 },
+ { "matrix": [1, 1], "x": 1, "y": 1 },
+ { "matrix": [1, 2], "x": 2, "y": 1 }
+ ]
+ }
+ }
}
diff --git a/keyboards/boardsource/holiday/spooky/keymaps/default/keymap.c b/keyboards/boardsource/holiday/spooky/keymaps/default/keymap.c
index 63fbb1b94c..96c21f53f3 100644
--- a/keyboards/boardsource/holiday/spooky/keymaps/default/keymap.c
+++ b/keyboards/boardsource/holiday/spooky/keymaps/default/keymap.c
@@ -1,4 +1,4 @@
-/* Copyright 2020 boardsource
+/* Copyright 2022 boardsource
*
* 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
@@ -15,15 +15,9 @@
*/
#include QMK_KEYBOARD_H
-// Defines names for use in layer keycodes and the keymap
-enum layer_names {
- _BASE,
-};
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* Base */
- [_BASE] = LAYOUT_ortho_2x3(
+ [0] = LAYOUT_ortho_2x3(
KC_F1, KC_F2, KC_F3,
KC_F4, KC_F5, KC_F6
- ),
- };
+ )
+};
diff --git a/keyboards/boardsource/holiday/spooky/keymaps/rip_mx/keymap.c b/keyboards/boardsource/holiday/spooky/keymaps/rip_mx/keymap.c
index eb56d11735..0afc136854 100644
--- a/keyboards/boardsource/holiday/spooky/keymaps/rip_mx/keymap.c
+++ b/keyboards/boardsource/holiday/spooky/keymaps/rip_mx/keymap.c
@@ -1,4 +1,4 @@
-/* Copyright 2020 boardsource
+/* Copyright 2022 boardsource
*
* 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
@@ -15,17 +15,11 @@
*/
#include QMK_KEYBOARD_H
-// Defines names for use in layer keycodes and the keymap
-enum layer_names {
- _BASE,
-};
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* Base */
- [_BASE] = LAYOUT_ortho_2x3(
+ [0] = LAYOUT_ortho_2x3(
RGB_TOG, KC_VOLU, KC_F2,
RGB_MOD, KC_VOLD, KC_F1
- ),
+ )
};
#ifdef OLED_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
@@ -34,46 +28,44 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
static void render_RIP(void) {
static const char PROGMEM my_logo[] = {
-0xff, 0xff, 0x07, 0x1e, 0x70, 0xc0, 0x00, 0x00, 0xe0, 0x78, 0x1e, 0x07, 0xff, 0xfe, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x06, 0x1c, 0xb8, 0xf0, 0xe0, 0xb8, 0x1c, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3e, 0x66, 0x63, 0x63, 0x43, 0x43, 0xc3, 0xc2, 0x82,
-0x00, 0x00, 0x00, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0xc0, 0xf0, 0x30, 0xf0, 0x80, 0x00, 0x00, 0xc0,
-0xf0, 0x10, 0x00, 0x00, 0x00, 0xf3, 0xf3, 0x00, 0x00, 0x10, 0x18, 0xfe, 0x18, 0x10, 0x10, 0x10,
-0x00, 0x00, 0xc0, 0xe0, 0x30, 0x10, 0x18, 0x18, 0x18, 0x10, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff,
-0x30, 0x10, 0x18, 0x18, 0x18, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x90, 0x90, 0x98,
-0x98, 0x98, 0xb0, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x98, 0x98, 0x18, 0x18, 0x10, 0x00,
-0x1f, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00,
-0x00, 0x10, 0x1c, 0x0e, 0x07, 0x01, 0x00, 0x00, 0x01, 0x07, 0x0e, 0x1c, 0x18, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x18, 0x18, 0x10, 0x10, 0x18, 0x18, 0x0d, 0x0f,
-0x03, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x1e, 0x1e, 0x07, 0x00, 0x00, 0x01, 0x0f, 0x1c, 0x1e, 0x07,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x03, 0x0f, 0x0c, 0x18, 0x10, 0x10, 0x10, 0x18, 0x08, 0x00, 0x00, 0x00, 0x1f, 0x1f,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x18, 0x10,
-0x10, 0x10, 0x18, 0x18, 0x08, 0x00, 0x00, 0x08, 0x18, 0x10, 0x11, 0x11, 0x11, 0x19, 0x0f, 0x0e,
-0x00, 0x30, 0x30, 0x10, 0x10, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xf0,
-0x30, 0x10, 0x18, 0x18, 0x10, 0x70, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb0, 0x10, 0x18,
-0x18, 0x10, 0x30, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x70, 0x10, 0x18, 0x18, 0x10, 0x30,
-0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x18, 0x18, 0x18,
-0x10, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf0, 0x30, 0x10, 0x18, 0x10, 0x30, 0xf0,
-0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x18, 0x18, 0x10, 0x30, 0xf0, 0xe0, 0x00, 0x00,
-0x00, 0x00, 0xc0, 0xe0, 0x30, 0x10, 0x18, 0x18, 0x10, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc7,
-0xc4, 0x8c, 0x8c, 0xcc, 0xc4, 0x77, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x38, 0x7d, 0xc7, 0xc3, 0x82,
-0x82, 0xc3, 0xc7, 0x7d, 0x7c, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x70, 0xc0, 0x80, 0x80, 0xc0, 0xc0,
-0x7f, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xd8, 0xcc,
-0xc6, 0xc3, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x70, 0xc0, 0xc0, 0x80, 0xc0, 0xc0, 0x70,
-0x3f, 0x0f, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xd8, 0xcc, 0xcc, 0xc7, 0xc3, 0xc1, 0x00, 0x00,
-0x00, 0x00, 0x3f, 0x7f, 0xe0, 0xc0, 0x80, 0x80, 0xc0, 0x60, 0x7f, 0x1f, 0x00, 0x00, 0x00, 0x00
- };
-
+ 0xff, 0xff, 0x07, 0x1e, 0x70, 0xc0, 0x00, 0x00, 0xe0, 0x78, 0x1e, 0x07, 0xff, 0xfe, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x06, 0x1c, 0xb8, 0xf0, 0xe0, 0xb8, 0x1c, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3e, 0x66, 0x63, 0x63, 0x43, 0x43, 0xc3, 0xc2, 0x82,
+ 0x00, 0x00, 0x00, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0xc0, 0xf0, 0x30, 0xf0, 0x80, 0x00, 0x00, 0xc0,
+ 0xf0, 0x10, 0x00, 0x00, 0x00, 0xf3, 0xf3, 0x00, 0x00, 0x10, 0x18, 0xfe, 0x18, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x10, 0x18, 0x18, 0x18, 0x10, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x30, 0x10, 0x18, 0x18, 0x18, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x90, 0x90, 0x98,
+ 0x98, 0x98, 0xb0, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x98, 0x98, 0x18, 0x18, 0x10, 0x00,
+ 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00,
+ 0x00, 0x10, 0x1c, 0x0e, 0x07, 0x01, 0x00, 0x00, 0x01, 0x07, 0x0e, 0x1c, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x18, 0x18, 0x10, 0x10, 0x18, 0x18, 0x0d, 0x0f,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x1e, 0x1e, 0x07, 0x00, 0x00, 0x01, 0x0f, 0x1c, 0x1e, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x03, 0x0f, 0x0c, 0x18, 0x10, 0x10, 0x10, 0x18, 0x08, 0x00, 0x00, 0x00, 0x1f, 0x1f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x18, 0x10,
+ 0x10, 0x10, 0x18, 0x18, 0x08, 0x00, 0x00, 0x08, 0x18, 0x10, 0x11, 0x11, 0x11, 0x19, 0x0f, 0x0e,
+ 0x00, 0x30, 0x30, 0x10, 0x10, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xf0,
+ 0x30, 0x10, 0x18, 0x18, 0x10, 0x70, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb0, 0x10, 0x18,
+ 0x18, 0x10, 0x30, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x70, 0x10, 0x18, 0x18, 0x10, 0x30,
+ 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x18, 0x18, 0x18,
+ 0x10, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf0, 0x30, 0x10, 0x18, 0x10, 0x30, 0xf0,
+ 0xe0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x18, 0x18, 0x10, 0x30, 0xf0, 0xe0, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x10, 0x18, 0x18, 0x10, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc7,
+ 0xc4, 0x8c, 0x8c, 0xcc, 0xc4, 0x77, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x38, 0x7d, 0xc7, 0xc3, 0x82,
+ 0x82, 0xc3, 0xc7, 0x7d, 0x7c, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x70, 0xc0, 0x80, 0x80, 0xc0, 0xc0,
+ 0x7f, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xd8, 0xcc,
+ 0xc6, 0xc3, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0x3f, 0x70, 0xc0, 0xc0, 0x80, 0xc0, 0xc0, 0x70,
+ 0x3f, 0x0f, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xd8, 0xcc, 0xcc, 0xc7, 0xc3, 0xc1, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x7f, 0xe0, 0xc0, 0x80, 0x80, 0xc0, 0x60, 0x7f, 0x1f, 0x00, 0x00, 0x00, 0x00
+ };
oled_write_raw_P(my_logo, sizeof(my_logo));
}
bool oled_task_user(void) {
render_RIP();
- return false;
- }
-
+ return false;
+}
#endif
diff --git a/keyboards/boardsource/holiday/spooky/keymaps/rip_my_wallet/keymap.c b/keyboards/boardsource/holiday/spooky/keymaps/rip_my_wallet/keymap.c
index f8cac50875..1ddad75827 100644
--- a/keyboards/boardsource/holiday/spooky/keymaps/rip_my_wallet/keymap.c
+++ b/keyboards/boardsource/holiday/spooky/keymaps/rip_my_wallet/keymap.c
@@ -1,4 +1,4 @@
-/* Copyright 2020 boardsource
+/* Copyright 2022 boardsource
*
* 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
@@ -15,18 +15,13 @@
*/
#include QMK_KEYBOARD_H
-// Defines names for use in layer keycodes and the keymap
-enum layer_names {
- _BASE,
-};
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* Base */
- [_BASE] = LAYOUT_ortho_2x3(
+ [0] = LAYOUT_ortho_2x3(
RGB_TOG, KC_1, KC_2,
RGB_MOD, KC_3,KC_4
- ),
+ )
};
+
#ifdef OLED_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
return OLED_ROTATION_180;
@@ -34,46 +29,44 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
static void render_RIP(void) {
static const char PROGMEM my_logo[] = {
-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, 0xf0, 0x08, 0x04,
-0x04, 0x7c, 0xfc, 0xf0, 0x00, 0x00, 0x40, 0x20, 0xf0, 0x7c, 0x06, 0x00, 0x41, 0xc0, 0x00, 0x00,
-0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0xc0, 0x00,
-0x00, 0x00, 0xe0, 0x60, 0x00, 0x80, 0x40, 0x20, 0x20, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x3c, 0x02,
-0x01, 0xc1, 0xf8, 0x0e, 0x00, 0x01, 0xc0, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x50, 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, 0x10, 0x10, 0x00, 0x08,
-0x03, 0x00, 0x00, 0x0f, 0x06, 0x01, 0x00, 0x1e, 0x1f, 0x10, 0x00, 0x00, 0x1e, 0x1f, 0x08, 0xc0,
-0x3e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x11, 0x08, 0x04, 0x1e, 0x11, 0x00,
-0x08, 0x06, 0x01, 0x00, 0x1e, 0x19, 0x08, 0x00, 0x1e, 0x0b, 0x08, 0x00, 0x1f, 0x1b, 0x08, 0x00,
-0x18, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x19, 0x08, 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, 0x0c,
-0x84, 0x84, 0x84, 0xcc, 0x38, 0x00, 0x00, 0x00, 0xf0, 0x18, 0x04, 0x05, 0x0f, 0x79, 0xe1, 0x00,
-0x00, 0x00, 0xc0, 0x78, 0x0c, 0x00, 0x00, 0x0c, 0x84, 0x84, 0xcc, 0xf8, 0x30, 0x00, 0x00, 0xe0,
-0xf8, 0x0c, 0x04, 0x04, 0x0c, 0xf8, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x00, 0x00, 0x08, 0x0c,
-0x04, 0x04, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xf0, 0x18, 0x0c, 0x04, 0x0c, 0x18, 0xf0, 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, 0x10,
-0x10, 0x10, 0x10, 0x19, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x18, 0x10, 0x10, 0x18, 0x0f, 0x07, 0x00,
-0x20, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x1d, 0x0f, 0x00, 0x00, 0x03,
-0x0f, 0x18, 0x10, 0x10, 0x18, 0x0f, 0x00, 0x00, 0x38, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x18, 0x1c,
-0x16, 0x13, 0x10, 0x10, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x10, 0x10, 0x10, 0x0c, 0x07, 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, 0xf0, 0x08, 0x04,
+ 0x04, 0x7c, 0xfc, 0xf0, 0x00, 0x00, 0x40, 0x20, 0xf0, 0x7c, 0x06, 0x00, 0x41, 0xc0, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0xc0, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x00, 0x80, 0x40, 0x20, 0x20, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x3c, 0x02,
+ 0x01, 0xc1, 0xf8, 0x0e, 0x00, 0x01, 0xc0, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x50, 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, 0x10, 0x10, 0x00, 0x08,
+ 0x03, 0x00, 0x00, 0x0f, 0x06, 0x01, 0x00, 0x1e, 0x1f, 0x10, 0x00, 0x00, 0x1e, 0x1f, 0x08, 0xc0,
+ 0x3e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x11, 0x08, 0x04, 0x1e, 0x11, 0x00,
+ 0x08, 0x06, 0x01, 0x00, 0x1e, 0x19, 0x08, 0x00, 0x1e, 0x0b, 0x08, 0x00, 0x1f, 0x1b, 0x08, 0x00,
+ 0x18, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x19, 0x08, 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, 0x0c,
+ 0x84, 0x84, 0x84, 0xcc, 0x38, 0x00, 0x00, 0x00, 0xf0, 0x18, 0x04, 0x05, 0x0f, 0x79, 0xe1, 0x00,
+ 0x00, 0x00, 0xc0, 0x78, 0x0c, 0x00, 0x00, 0x0c, 0x84, 0x84, 0xcc, 0xf8, 0x30, 0x00, 0x00, 0xe0,
+ 0xf8, 0x0c, 0x04, 0x04, 0x0c, 0xf8, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x00, 0x00, 0x08, 0x0c,
+ 0x04, 0x04, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xf0, 0x18, 0x0c, 0x04, 0x0c, 0x18, 0xf0, 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, 0x10,
+ 0x10, 0x10, 0x10, 0x19, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x18, 0x10, 0x10, 0x18, 0x0f, 0x07, 0x00,
+ 0x20, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x1d, 0x0f, 0x00, 0x00, 0x03,
+ 0x0f, 0x18, 0x10, 0x10, 0x18, 0x0f, 0x00, 0x00, 0x38, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x18, 0x1c,
+ 0x16, 0x13, 0x10, 0x10, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x10, 0x10, 0x10, 0x0c, 0x07, 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
};
-
oled_write_raw_P(my_logo, sizeof(my_logo));
}
bool oled_task_user(void) {
render_RIP();
- return false;
- }
-
+ return false;
+}
#endif
diff --git a/keyboards/boardsource/holiday/spooky/rules.mk b/keyboards/boardsource/holiday/spooky/rules.mk
index ce35761cc9..6e7633bfe0 100644
--- a/keyboards/boardsource/holiday/spooky/rules.mk
+++ b/keyboards/boardsource/holiday/spooky/rules.mk
@@ -1,20 +1 @@
-# MCU name
-MCU = atmega32u4
-
-# Bootloader selection
-BOOTLOADER = caterina
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = no # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
-AUDIO_ENABLE = no # Audio output
-
-LAYOUTS = ortho_2x3
+# This file intentionally left blank
diff --git a/keyboards/boardsource/lulu/config.h b/keyboards/boardsource/lulu/config.h
index 8cd240179e..f96a228429 100644
--- a/keyboards/boardsource/lulu/config.h
+++ b/keyboards/boardsource/lulu/config.h
@@ -2,46 +2,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
-
#include "config_common.h"
-
-#define VENDOR_ID 0x4273
-#define PRODUCT_ID 0x7685
-#define DEVICE_VER 0x0000
-#define MANUFACTURER Boardsource
-#define PRODUCT lulu
-
-#define MATRIX_ROWS 10
-#define MATRIX_COLS 6
-#define MATRIX_ROW_PINS {C6, D7, E6, B4, B5}
-
-// wiring of each half
-#define MATRIX_COL_PINS {F6, F7, B1, B3, B2, B6}
-#define USE_SERIAL
-#define SOFT_SERIAL_PIN D2
-#define SPLIT_USB_DETECT
#define RGB_DI_PIN D3
-
-#define ENCODERS_PAD_A { F0 }
-#define ENCODERS_PAD_B { F1 }
-#define ENCODERS_PAD_A_RIGHT { F0 }
-#define ENCODERS_PAD_B_RIGHT { F1 }
-
-/* Set 0 if debouncing isn't needed */
-#define DEBOUNCE 5
-#define DIODE_DIRECTION COL2ROW
-#ifdef RGB_MATRIX_ENABLE
- #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150
- #define RGBLED_NUM 70 // Number of LEDs
- #define DRIVER_LED_TOTAL RGBLED_NUM
- #define RGB_MATRIX_SPLIT { 35, 35 }
- #define SPLIT_TRANSPORT_MIRROR
- #define RGBLIGHT_LIMIT_VAL 150
- #define ENABLE_RGB_MATRIX_ALPHAS_MODS
- #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
- #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
- #define ENABLE_RGB_MATRIX_BREATHING
- #define ENABLE_RGB_MATRIX_BAND_SAT
- #define ENABLE_RGB_MATRIX_BAND_VAL
-#endif
-
+#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150
+#define DRIVER_LED_TOTAL 70
+#define RGB_MATRIX_SPLIT { 35, 35 }
+#define ENABLE_RGB_MATRIX_ALPHAS_MODS
+#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
+#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
+#define ENABLE_RGB_MATRIX_BREATHING
+#define ENABLE_RGB_MATRIX_BAND_SAT
+#define ENABLE_RGB_MATRIX_BAND_VAL
diff --git a/keyboards/boardsource/lulu/info.json b/keyboards/boardsource/lulu/info.json
index 156a7cea98..5ee5c59c1a 100644
--- a/keyboards/boardsource/lulu/info.json
+++ b/keyboards/boardsource/lulu/info.json
@@ -1,16 +1,177 @@
{
- "keyboard_name": "Lulu",
- "url": "https://boardsource.xyz/store/61d0b772319a1f3cc53ba2fb",
- "maintainer": "boardsource",
- "layouts": {
- "LAYOUT": {
- "layout": [
- {"x":0, "y":0.5}, {"x":1, "y":0.375}, {"x":2, "y":0.125}, {"x":3, "y":0}, {"x":4, "y":0.125}, {"x":5, "y":0.25}, {"x":10.5, "y":0.25}, {"x":11.5, "y":0.125}, {"x":12.5, "y":0}, {"x":13.5, "y":0.125}, {"x":14.5, "y":0.375}, {"x":15.5, "y":0.5},
- {"x":0, "y":1.5}, {"x":1, "y":1.375}, {"x":2, "y":1.125}, {"x":3, "y":1}, {"x":4, "y":1.125}, {"x":5, "y":1.25}, {"x":10.5, "y":1.25}, {"x":11.5, "y":1.125}, {"x":12.5, "y":1}, {"x":13.5, "y":1.125}, {"x":14.5, "y":1.375}, {"x":15.5, "y":1.5},
- {"x":0, "y":2.5}, {"x":1, "y":2.375}, {"x":2, "y":2.125}, {"x":3, "y":2}, {"x":4, "y":2.125}, {"x":5, "y":2.25}, {"x":10.5, "y":2.25}, {"x":11.5, "y":2.125}, {"x":12.5, "y":2}, {"x":13.5, "y":2.125}, {"x":14.5, "y":2.375}, {"x":15.5, "y":2.5},
- {"x":0, "y":3.5}, {"x":1, "y":3.375}, {"x":2, "y":3.125}, {"x":3, "y":3}, {"x":4, "y":3.125}, {"x":5, "y":3.25}, {"x":6, "y":2.75}, {"x":9.5, "y":2.75}, {"x":10.5, "y":3.25}, {"x":11.5, "y":3.125}, {"x":12.5, "y":3}, {"x":13.5, "y":3.125}, {"x":14.5, "y":3.375}, {"x":15.5, "y":3.5},
- {"x":2.5, "y":4.125}, {"x":3.5, "y":4.15}, {"x":4.5, "y":4.25}, {"x":6, "y":4.25, "h":1.5}, {"x":9.5, "y":4.25, "h":1.5}, {"x":11, "y":4.25}, {"x":12, "y":4.15}, {"x":13, "y":4.15}
- ]
- }
+ "manufacturer": "Boardsource",
+ "keyboard_name": "lulu",
+ "maintainer": "waffle87",
+ "bootloader": "atmel-dfu",
+ "diode_direction": "COL2ROW",
+ "build": {
+ "lto": true
+ },
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true,
+ "rgb_matrix": true,
+ "oled": true
+ },
+ "matrix_pins": {
+ "cols": ["F6", "F7", "B1", "B3", "B2", "B6"],
+ "rows": ["C6", "D7", "E6", "B4", "B5"]
+ },
+ "processor": "atmega32u4",
+ "url": "https://boardsource.xyz/projects/60de24d6847112054777bbdd",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x7685",
+ "vid": "0x4273"
+ },
+ "split": {
+ "enabled": true,
+ "soft_serial_pin": "D2"
+ },
+ "encoder": {
+ "enabled": true,
+ "rotary": [
+ { "pin_a": "F0", "pin_b": "F1" }
+ ]
+ },
+ "rgb_matrix": {
+ "layout": [
+ { "flags": 2, "x": 86, "y": 55 },
+ { "flags": 2, "x": 51, "y": 55 },
+ { "flags": 2, "x": 17, "y": 40 },
+ { "flags": 2, "x": 17, "y": 10 },
+ { "flags": 2, "x": 51, "y": 10 },
+ { "flags": 2, "x": 86, "y": 10 },
+ { "flags": 2, "x": 137, "y": 55 },
+ { "flags": 2, "x": 172, "y": 55 },
+ { "flags": 2, "x": 206, "y": 40 },
+ { "flags": 2, "x": 206, "y": 10 },
+ { "flags": 2, "x": 172, "y": 10 },
+ { "flags": 2, "x": 137, "y": 10 },
+ { "flags": 1, "matrix": [0, 0], "x": 0, "y": 0 },
+ { "flags": 4, "matrix": [0, 1], "x": 17, "y": 0 },
+ { "flags": 4, "matrix": [0, 2], "x": 34, "y": 0 },
+ { "flags": 4, "matrix": [0, 3], "x": 51, "y": 0 },
+ { "flags": 4, "matrix": [0, 4], "x": 68, "y": 0 },
+ { "flags": 4, "matrix": [0, 5], "x": 86, "y": 0 },
+ { "flags": 4, "matrix": [5, 5], "x": 137, "y": 0 },
+ { "flags": 4, "matrix": [5, 4], "x": 155, "y": 0 },
+ { "flags": 4, "matrix": [5, 3], "x": 172, "y": 0 },
+ { "flags": 4, "matrix": [5, 2], "x": 189, "y": 0 },
+ { "flags": 4, "matrix": [5, 1], "x": 206, "y": 0 },
+ { "flags": 1, "matrix": [5, 0], "x": 224, "y": 0 },
+ { "flags": 1, "matrix": [1, 0], "x": 0, "y": 16 },
+ { "flags": 4, "matrix": [1, 1], "x": 17, "y": 16 },
+ { "flags": 4, "matrix": [1, 2], "x": 34, "y": 16 },
+ { "flags": 4, "matrix": [1, 3], "x": 51, "y": 16 },
+ { "flags": 4, "matrix": [1, 4], "x": 68, "y": 16 },
+ { "flags": 4, "matrix": [1, 5], "x": 86, "y": 16 },
+ { "flags": 4, "matrix": [6, 5], "x": 137, "y": 16 },
+ { "flags": 4, "matrix": [6, 4], "x": 155, "y": 16 },
+ { "flags": 4, "matrix": [6, 3], "x": 172, "y": 16 },
+ { "flags": 4, "matrix": [6, 2], "x": 189, "y": 16 },
+ { "flags": 4, "matrix": [6, 1], "x": 206, "y": 16 },
+ { "flags": 1, "matrix": [6, 4], "x": 224, "y": 16 },
+ { "flags": 1, "matrix": [2, 0], "x": 0, "y": 32 },
+ { "flags": 4, "matrix": [2, 1], "x": 17, "y": 32 },
+ { "flags": 4, "matrix": [2, 2], "x": 34, "y": 32 },
+ { "flags": 4, "matrix": [2, 3], "x": 51, "y": 32 },
+ { "flags": 4, "matrix": [2, 4], "x": 68, "y": 32 },
+ { "flags": 4, "matrix": [2, 5], "x": 86, "y": 32 },
+ { "flags": 4, "matrix": [7, 5], "x": 137, "y": 32 },
+ { "flags": 4, "matrix": [7, 4], "x": 155, "y": 32 },
+ { "flags": 4, "matrix": [7, 3], "x": 172, "y": 32 },
+ { "flags": 4, "matrix": [7, 2], "x": 189, "y": 32 },
+ { "flags": 4, "matrix": [7, 1], "x": 206, "y": 32 },
+ { "flags": 1, "matrix": [7, 4], "x": 224, "y": 32 },
+ { "flags": 1, "matrix": [3, 0], "x": 0, "y": 48 },
+ { "flags": 4, "matrix": [3, 1], "x": 17, "y": 48 },
+ { "flags": 4, "matrix": [3, 2], "x": 34, "y": 48 },
+ { "flags": 4, "matrix": [3, 3], "x": 51, "y": 48 },
+ { "flags": 4, "matrix": [3, 4], "x": 68, "y": 48 },
+ { "flags": 4, "matrix": [3, 5], "x": 86, "y": 48 },
+ { "flags": 4, "matrix": [4, 5], "x": 103, "y": 48 },
+ { "flags": 4, "matrix": [9, 5], "x": 120, "y": 48 },
+ { "flags": 4, "matrix": [8, 5], "x": 137, "y": 48 },
+ { "flags": 4, "matrix": [8, 4], "x": 155, "y": 48 },
+ { "flags": 4, "matrix": [8, 3], "x": 172, "y": 48 },
+ { "flags": 4, "matrix": [8, 2], "x": 189, "y": 48 },
+ { "flags": 4, "matrix": [8, 1], "x": 206, "y": 48 },
+ { "flags": 1, "matrix": [8, 4], "x": 224, "y": 48 },
+ { "flags": 1, "matrix": [4, 1], "x": 34, "y": 64 },
+ { "flags": 1, "matrix": [4, 2], "x": 51, "y": 64 },
+ { "flags": 1, "matrix": [4, 3], "x": 68, "y": 64 },
+ { "flags": 1, "matrix": [4, 4], "x": 86, "y": 64 },
+ { "flags": 1, "matrix": [9, 4], "x": 137, "y": 64 },
+ { "flags": 1, "matrix": [9, 3], "x": 155, "y": 64 },
+ { "flags": 1, "matrix": [9, 2], "x": 172, "y": 64 },
+ { "flags": 1, "matrix": [9, 1], "x": 189, "y": 64 }
+ ]
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0.5 },
+ { "matrix": [0, 1], "x": 1, "y": 0.375 },
+ { "matrix": [0, 2], "x": 2, "y": 0.125 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0.125 },
+ { "matrix": [0, 5], "x": 5, "y": 0.25 },
+ { "matrix": [5, 5], "x": 10.5, "y": 0.25 },
+ { "matrix": [5, 4], "x": 11.5, "y": 0.125 },
+ { "matrix": [5, 3], "x": 12.5, "y": 0 },
+ { "matrix": [5, 2], "x": 13.5, "y": 0.125 },
+ { "matrix": [5, 1], "x": 14.5, "y": 0.375 },
+ { "matrix": [5, 0], "x": 15.5, "y": 0.5 },
+ { "matrix": [1, 0], "x": 0, "y": 1.5 },
+ { "matrix": [1, 1], "x": 1, "y": 1.375 },
+ { "matrix": [1, 2], "x": 2, "y": 1.125 },
+ { "matrix": [1, 3], "x": 3, "y": 1 },
+ { "matrix": [1, 4], "x": 4, "y": 1.125 },
+ { "matrix": [1, 5], "x": 5, "y": 1.25 },
+ { "matrix": [6, 5], "x": 10.5, "y": 1.25 },
+ { "matrix": [6, 4], "x": 11.5, "y": 1.125 },
+ { "matrix": [6, 3], "x": 12.5, "y": 1 },
+ { "matrix": [6, 2], "x": 13.5, "y": 1.125 },
+ { "matrix": [6, 1], "x": 14.5, "y": 1.375 },
+ { "matrix": [6, 0], "x": 15.5, "y": 1.5 },
+ { "matrix": [2, 0], "x": 0, "y": 2.5 },
+ { "matrix": [2, 1], "x": 1, "y": 2.375 },
+ { "matrix": [2, 2], "x": 2, "y": 2.125 },
+ { "matrix": [2, 3], "x": 3, "y": 2 },
+ { "matrix": [2, 4], "x": 4, "y": 2.125 },
+ { "matrix": [2, 5], "x": 5, "y": 2.25 },
+ { "matrix": [7, 5], "x": 10.5, "y": 2.25 },
+ { "matrix": [7, 4], "x": 11.5, "y": 2.125 },
+ { "matrix": [7, 3], "x": 12.5, "y": 2 },
+ { "matrix": [7, 2], "x": 13.5, "y": 2.125 },
+ { "matrix": [7, 1], "x": 14.5, "y": 2.375 },
+ { "matrix": [7, 0], "x": 15.5, "y": 2.5 },
+ { "matrix": [3, 0], "x": 0, "y": 3.5 },
+ { "matrix": [3, 1], "x": 1, "y": 3.375 },
+ { "matrix": [3, 2], "x": 2, "y": 3.125 },
+ { "matrix": [3, 3], "x": 3, "y": 3 },
+ { "matrix": [3, 4], "x": 4, "y": 3.125 },
+ { "matrix": [3, 5], "x": 5, "y": 3.25 },
+ { "matrix": [4, 5], "x": 6, "y": 2.75 },
+ { "matrix": [9, 5], "x": 9.5, "y": 2.75 },
+ { "matrix": [8, 5], "x": 10.5, "y": 3.25 },
+ { "matrix": [8, 4], "x": 11.5, "y": 3.125 },
+ { "matrix": [8, 3], "x": 12.5, "y": 3 },
+ { "matrix": [8, 2], "x": 13.5, "y": 3.125 },
+ { "matrix": [8, 1], "x": 14.5, "y": 3.375 },
+ { "matrix": [8, 0], "x": 15.5, "y": 3.5 },
+ { "matrix": [4, 1], "x": 2.5, "y": 4.125 },
+ { "matrix": [4, 2], "x": 3.5, "y": 4.15 },
+ { "matrix": [4, 3], "x": 4.5, "y": 4.25 },
+ { "matrix": [4, 4], "h": 1.5, "x": 6, "y": 4.25 },
+ { "matrix": [9, 4], "h": 1.5, "x": 9.5, "y": 4.25 },
+ { "matrix": [9, 3], "x": 11, "y": 4.25 },
+ { "matrix": [9, 2], "x": 12, "y": 4.15 },
+ { "matrix": [9, 1], "x": 13, "y": 4.15 }
+ ]
}
+ }
}
diff --git a/keyboards/boardsource/lulu/keymaps/default/keymap.c b/keyboards/boardsource/lulu/keymaps/default/keymap.c
index 8624b51b6a..cbee1401ed 100644
--- a/keyboards/boardsource/lulu/keymaps/default/keymap.c
+++ b/keyboards/boardsource/lulu/keymaps/default/keymap.c
@@ -106,24 +106,3 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
layer_state_t layer_state_set_user(layer_state_t state) {
return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
}
-
-#ifdef ENCODER_ENABLE
-bool encoder_update_user(uint8_t index, bool clockwise) {
- if (index == 0) {
- // Volume control
- if (clockwise) {
- tap_code(KC_VOLU);
- } else {
- tap_code(KC_VOLD);
- }
- } else if (index == 1) {
- // Page up/Page down
- if (clockwise) {
- tap_code(KC_PGDN);
- } else {
- tap_code(KC_PGUP);
- }
- }
- return false;
-}
-#endif
diff --git a/keyboards/boardsource/lulu/keymaps/via/keymap.c b/keyboards/boardsource/lulu/keymaps/via/keymap.c
index 912ea38559..de635a6128 100644
--- a/keyboards/boardsource/lulu/keymaps/via/keymap.c
+++ b/keyboards/boardsource/lulu/keymaps/via/keymap.c
@@ -102,4 +102,3 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______
)
};
-
diff --git a/keyboards/boardsource/lulu/lulu.c b/keyboards/boardsource/lulu/lulu.c
index 7a25fce50c..be6d565a32 100644
--- a/keyboards/boardsource/lulu/lulu.c
+++ b/keyboards/boardsource/lulu/lulu.c
@@ -1,267 +1,237 @@
// Copyright 2022 Cole Smith <cole@boadsource.xyz>
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "encoder.h"
-#include "lulu.h"
-#ifdef RGB_MATRIX_ENABLE
-
-led_config_t g_led_config = { {
- {11,10, 9, 8, 7, 6},
- {17,16,15,14,13,12},
- {23,22,21,20,19,18},
- {29,28,27,26,25,24},
- {NO_LED,34,33,32,31,30},
- {41,42,43,44,45,46},
- {47,48,49,50,51,52},
- {53,54,55,56,57,58},
- {59,60,61,62,63,64},
- {NO_LED,65,66,67,68,69}
-},{
-
- {86,55},{51,55},{17,40},{17,10},{51,10},{86,10},
- {0,0}, {17,0}, {34,0}, {51,0}, {68,0}, {86,0},
- {0,16},{17,16},{34,16},{51,16},{68,16},{86,16},
- {0,32},{17,32},{34,32},{51,32},{68,32},{86,32},
- {0,48},{17,48},{34,48},{51,48},{68,48},{86,48},{103,48},
- {34,64},{51,64},{68,64},{86,64},
-
-
- {137,55},{172,55},{206,40},{206,10},{172,10},{137,10},
- {137,0}, {155,0}, {172,0}, {189,0}, {206,0}, {224,0},
- {137,16},{155,16},{172,16},{189,16},{206,16},{224,16},
- {137,32},{155,32},{172,32},{189,32},{206,32},{224,32},
- {137,48},{155,48},{172,48},{189,48},{155,48},{137,48},{120,48},
- {172,64},{189,64},{155,64},{137,64}
-},{2,2,2,2,2,2,
- 4,4,4,4,4,1,
- 1,4,4,4,4,4,
- 4,4,4,4,4,1,
- 1,4,4,4,4,4,
- 1,4,1,1,1,
- 2,2,2,2,2,2,
- 4,4,4,4,4,1,
- 1,4,4,4,4,4,
- 4,4,4,4,4,1,
- 1,4,4,4,4,4,
- 1,4,1,1,1
-}};
-
+#ifdef ENCODER_ENABLE
+bool encoder_update_kb(uint8_t index, bool clockwise) {
+ if (!encoder_update_user(index, clockwise)) { return false; }
+ if (index == 0) {
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ } else if (index == 1) {
+ if (clockwise) {
+ tap_code(KC_PGDN);
+ } else {
+ tap_code(KC_PGUP);
+ }
+ }
+ return true;
+}
#endif
-
-
#ifdef OLED_ENABLE
oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
if (!is_keyboard_master()) {
- return OLED_ROTATION_180; // flips the display 180 degrees if offhand
+ return OLED_ROTATION_180;
}
return rotation;
}
void render_layer1_logo(void){
- static const char PROGMEM layer_logo[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
-0x03, 0x02, 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, 0xf0,
-0xfc, 0x0e, 0x07, 0x03, 0x01, 0x01, 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
-0xf0, 0xf0, 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, 0x01,
-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, 0xf8, 0xf0, 0x60,
-0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
-0x07, 0x0f, 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, 0x0f, 0x0f, 0x00,
-0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
-};
- oled_write_raw_P(layer_logo, sizeof(layer_logo));
+ static const char PROGMEM layer_logo[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
+ 0x03, 0x02, 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, 0xf0,
+ 0xfc, 0x0e, 0x07, 0x03, 0x01, 0x01, 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
+ 0xf0, 0xf0, 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, 0x01,
+ 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, 0xf8, 0xf0, 0x60,
+ 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
+ 0x07, 0x0f, 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, 0x0f, 0x0f, 0x00,
+ 0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ oled_write_raw_P(layer_logo, sizeof(layer_logo));
}
+
void render_layer2_logo(void){
- static const char PROGMEM layer_logo[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x00, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
-0x03, 0x02, 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, 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
-0xf0, 0xf0, 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, 0x0f,
-0x3f, 0x70, 0xe0, 0xc0, 0x80, 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, 0xf8, 0xf0, 0x60,
-0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
-0x07, 0x0f, 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, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00,
-0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+ static const char PROGMEM layer_logo[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x00, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
+ 0x03, 0x02, 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, 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
+ 0xf0, 0xf0, 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, 0x0f,
+ 0x3f, 0x70, 0xe0, 0xc0, 0x80, 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, 0xf8, 0xf0, 0x60,
+ 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
+ 0x07, 0x0f, 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, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00,
+ 0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
oled_write_raw_P(layer_logo, sizeof(layer_logo));
}
+
void render_layer3_logo(void){
- static const char PROGMEM layer_logo[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x00, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
-0x03, 0x02, 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, 0x80, 0xc0,
-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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
-0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0x70, 0x38, 0x1f, 0x07,
-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, 0xf8, 0xf0, 0x60,
-0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
-0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x0f, 0x0f, 0x00,
-0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+ static const char PROGMEM layer_logo[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 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, 0x00, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
+ 0x03, 0x02, 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, 0x80, 0xc0,
+ 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
+ 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0x70, 0x38, 0x1f, 0x07,
+ 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, 0xf8, 0xf0, 0x60,
+ 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
+ 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x0f, 0x0f, 0x00,
+ 0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
oled_write_raw_P(layer_logo, sizeof(layer_logo));
}
+
void render_layer4_logo(void){
- static const char PROGMEM layer_logo[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 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, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
-0x03, 0x02, 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, 0x01, 0x01, 0x03, 0x07, 0x0e, 0xfc, 0xf0,
-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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
-0xf0, 0xf0, 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, 0x01,
-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, 0xf8, 0xf0, 0x60,
-0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
-0x07, 0x0f, 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, 0x0f, 0x0f, 0x00,
-0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+ static const char PROGMEM layer_logo[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x18, 0x30, 0x60, 0xe0, 0xc0, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 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, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc8, 0xf8, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x0f, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
+ 0x03, 0x02, 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, 0x01, 0x01, 0x03, 0x07, 0x0e, 0xfc, 0xf0,
+ 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, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, 0x00,
+ 0xf0, 0xf0, 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, 0x01,
+ 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, 0xf8, 0xf0, 0x60,
+ 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x01, 0x03, 0x07,
+ 0x07, 0x0f, 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, 0x0f, 0x0f, 0x00,
+ 0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
oled_write_raw_P(layer_logo, sizeof(layer_logo));
}
void render_logo(void) {
static const char PROGMEM logo[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 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, 0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x60,
-0x60, 0x60, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x00, 0xe0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 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, 0xf0, 0xfc, 0x1e, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x80, 0xc0,
-0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0e, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
-0xe0, 0xc0, 0x80, 0x80, 0xc0, 0xc0, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x00, 0x1f, 0xff, 0xff, 0xc0, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, 0xff, 0x7f, 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, 0x07, 0x1f, 0x78, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x01,
-0x01, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xe0, 0x78, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 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, 0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x60,
+ 0x60, 0x60, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0xe0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 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, 0xf0, 0xfc, 0x1e, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x80, 0xc0,
+ 0x80, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0e, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
+ 0xe0, 0xc0, 0x80, 0x80, 0xc0, 0xc0, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x1f, 0xff, 0xff, 0xc0, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, 0xff, 0x7f, 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, 0x07, 0x1f, 0x78, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xe0, 0x78, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 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, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
oled_write_raw_P(logo, sizeof(logo));
}
-enum Layers{
- _QWERTY,
- _RAISE,
- _LOWER,
- _ADJUST
-};
void process_layer_state(void) {
switch (get_highest_layer(layer_state)) {
- case _QWERTY:
+ case 0:
render_layer1_logo();
break;
- case _LOWER:
+ case 1:
render_layer2_logo();
break;
- case _RAISE:
+ case 2:
render_layer3_logo();
break;
- case _ADJUST:
+ case 3:
render_layer4_logo();
break;
}
@@ -277,4 +247,3 @@ bool oled_task_kb(void) {
return false;
}
#endif
-
diff --git a/keyboards/boardsource/lulu/lulu.h b/keyboards/boardsource/lulu/lulu.h
deleted file mode 100644
index bda65f63e0..0000000000
--- a/keyboards/boardsource/lulu/lulu.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2022 Cole Smith <cole@boadsource.xyz>
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "quantum.h"
-#include "split_util.h"
-#define has_usb() is_keyboard_master()
-#define is_master is_keyboard_master()
-#define LAYOUT( \
- L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
- L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
- L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
- L30, L31, L32, L33, L34, L35, L45, R40, R30, R31, R32, R33, R34, R35, \
- L41, L42, L43, L44, R41, R42, R43, R44 \
- ) \
- { \
- { L00, L01, L02, L03, L04, L05 }, \
- { L10, L11, L12, L13, L14, L15 }, \
- { L20, L21, L22, L23, L24, L25 }, \
- { L30, L31, L32, L33, L34, L35 }, \
- { KC_NO, L41, L42, L43, L44, L45 }, \
- { R05, R04, R03, R02, R01, R00 }, \
- { R15, R14, R13, R12, R11, R10 }, \
- { R25, R24, R23, R22, R21, R20 }, \
- { R35, R34, R33, R32, R31, R30 }, \
- { KC_NO, R44, R43, R42, R41, R40 } \
- }
-
diff --git a/keyboards/boardsource/lulu/rules.mk b/keyboards/boardsource/lulu/rules.mk
index 06d206cb55..32afd21635 100644
--- a/keyboards/boardsource/lulu/rules.mk
+++ b/keyboards/boardsource/lulu/rules.mk
@@ -1,26 +1 @@
-# MCU name
-MCU = atmega32u4
-
-# Bootloader selection
-BOOTLOADER = atmel-dfu
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = yes # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
-AUDIO_ENABLE = no # Audio output
-SPLIT_KEYBOARD = yes
-RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = WS2812
-RGB_MATRIX_SUPPORTED = yes
-OLED_ENABLE = yes
-OLED_DRIVER = SSD1306
-LTO_ENABLE = yes
-ENCODER_ENABLE = yes
diff --git a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/config.h b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/config.h
index 4bc6d2c3c0..e45034f9a8 100644
--- a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/config.h
+++ b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/config.h
@@ -2,6 +2,7 @@
// place overrides here
#define TAPPING_TERM 200
+#define TAPPING_TERM_PER_KEY
#define LEADER_TIMEOUT 800
#define DISABLE_SPACE_CADET_ROLLOVER
diff --git a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/keymap.c b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/keymap.c
index dd2098d945..6db177c183 100644
--- a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/keymap.c
+++ b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/keymap.c
@@ -52,17 +52,33 @@ qk_tap_dance_action_t tap_dance_actions[] = {
// Tap once for CTRL, twice for Caps Lock
[TD_CTCPS] = ACTION_TAP_DANCE_DOUBLE(KC_LCTL, KC_CAPS),
[COPA] = ACTION_TAP_DANCE_DOUBLE(LCTL(KC_C), LCTL(KC_V)),
- [EMOJIS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleEmojis, NULL, NULL, 800),
- [ANIMAL] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleAnimals, NULL, NULL, 800),
- //[SYMBOLS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleSymbols, NULL, NULL, 800),
- [FOODS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleFoods, NULL, NULL, 800),
- [ETC] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleEtc, NULL, NULL, 800),
- //[VEHICLES] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleVehicles, NULL, NULL, 800),
- //[SUPPLEMENT] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleSupplement, NULL, NULL, 800),
- [ALLS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(cycleAll, NULL, NULL, 800)
+ [EMOJIS] = ACTION_TAP_DANCE_FN_ADVANCED(cycleEmojis, NULL, NULL),
+ [ANIMAL] = ACTION_TAP_DANCE_FN_ADVANCED(cycleAnimals, NULL, NULL),
+ //[SYMBOLS] = ACTION_TAP_DANCE_FN_ADVANCED(cycleSymbols, NULL, NULL),
+ [FOODS] = ACTION_TAP_DANCE_FN_ADVANCED(cycleFoods, NULL, NULL),
+ [ETC] = ACTION_TAP_DANCE_FN_ADVANCED(cycleEtc, NULL, NULL),
+ //[VEHICLES] = ACTION_TAP_DANCE_FN_ADVANCED(cycleVehicles, NULL, NULL),
+ //[SUPPLEMENT] = ACTION_TAP_DANCE_FN_ADVANCED(cycleSupplement, NULL, NULL),
+ [ALLS] = ACTION_TAP_DANCE_FN_ADVANCED(cycleAll, NULL, NULL)
// Other declarations would go here, separated by commas, if you have them
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(EMOJIS):
+ case TD(ANIMAL):
+ //case TD(SYMBOLS):
+ case TD(FOODS):
+ case TD(ETC):
+ //case TD(VEHICLES):
+ //case TD(SUPPLEMENT):
+ case TD(ALLS):
+ return 800;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
// macros
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch(id) {
diff --git a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/variableTapDance.md b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/variableTapDance.md
index b2e5041393..c3fce50f2a 100644
--- a/keyboards/bpiphany/frosty_flake/keymaps/nikchi/variableTapDance.md
+++ b/keyboards/bpiphany/frosty_flake/keymaps/nikchi/variableTapDance.md
@@ -3,7 +3,4 @@ Tap Dance is constrained normally by `TAPPING_TERM` defined in your keyboard's c
-- `ACTION_TAP_DANCE_FN_ADVANCED_TIME(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, tap_specific_tapping_term)` : This works the same as `ACTION_TAP_DANCE_FN_ADVANCED` just with the extra `tap_specific_tapping_term` arguement at the end. This way you can set a specific tap dance to have a longer or shorter tap in between your taps, giving you more, or less, time in between each tap.
-
-
-`tap_specific_tapping_term` should be the same type and range of values that one would put into the `TAPPING_TERM` definition in the config.h file.
+- Implementing `uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record)`, you can set a specific tap dance to have a longer or shorter tap in between your taps, giving you more, or less, time in between each tap. The return value should be the same type and range of values that one would put into the `TAPPING_TERM` definition in the config.h file.
diff --git a/keyboards/bpiphany/kitten_paw/keymaps/ickerwx/keymap.c b/keyboards/bpiphany/kitten_paw/keymaps/ickerwx/keymap.c
index cc4d0bca63..4553d4e0e3 100644
--- a/keyboards/bpiphany/kitten_paw/keymaps/ickerwx/keymap.c
+++ b/keyboards/bpiphany/kitten_paw/keymaps/ickerwx/keymap.c
@@ -89,7 +89,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void) {
uint8_t layer;
- layer = biton32(layer_state);
+ layer = get_highest_layer(layer_state);
if (current_layer_global != layer) {
current_layer_global = layer;
@@ -132,7 +132,7 @@ void tap_helper(keyrecord_t *record, uint16_t orig_mod, uint16_t macro_mod, uint
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
uint8_t layer;
- layer = biton32(layer_state);
+ layer = get_highest_layer(layer_state);
if (layer == PROG2) {
if (keycode >= KC_A && keycode <= KC_EXSEL && \
!( // do not send LSFT + these keycodes, they are needed for emulating the US layout
diff --git a/keyboards/bpiphany/pegasushoof/keymaps/blowrak/keymap.c b/keyboards/bpiphany/pegasushoof/keymaps/blowrak/keymap.c
index 7884462021..dc55cdf9fd 100644
--- a/keyboards/bpiphany/pegasushoof/keymaps/blowrak/keymap.c
+++ b/keyboards/bpiphany/pegasushoof/keymaps/blowrak/keymap.c
@@ -77,7 +77,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void)
{
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case KM_BLOWRAK:
ph_caps_led_on();
diff --git a/keyboards/cannonkeys/ortho75/ortho75.c b/keyboards/cannonkeys/ortho75/ortho75.c
index 7c722d7156..58b7396a1b 100644
--- a/keyboards/cannonkeys/ortho75/ortho75.c
+++ b/keyboards/cannonkeys/ortho75/ortho75.c
@@ -5,47 +5,48 @@
uint8_t layer = 0;
-uint32_t layer_state_set_kb(uint32_t state) {
- state = layer_state_set_user(state);
- layer = biton32(state);
- return state;
+layer_state_t layer_state_set_kb(layer_state_t state) {
+ state = layer_state_set_user(state);
+ layer = get_highest_layer(state);
+ return state;
}
bool encoder_update_kb(uint8_t index, bool clockwise) {
if (!encoder_update_user(index, clockwise)) return false;
- uint16_t mapped_code = 0;
- if (index == 0) {
- if (clockwise) {
- switch(layer){
- case 0:
- default:
- mapped_code = KC_VOLU;
- break;
- case 1:
- mapped_code = KC_MEDIA_NEXT_TRACK;
- break;
- case 2:
- mapped_code = KC_PGDN;
- break;
+ uint16_t mapped_code = 0;
+ if (index == 0) {
+ if (clockwise) {
+ switch (layer) {
+ case 0:
+ default:
+ mapped_code = KC_VOLU;
+ break;
+ case 1:
+ mapped_code = KC_MEDIA_NEXT_TRACK;
+ break;
+ case 2:
+ mapped_code = KC_PGDN;
+ break;
+ }
+ } else {
+ switch (layer) {
+ case 0:
+ default:
+ mapped_code = KC_VOLD;
+ break;
+ case 1:
+ mapped_code = KC_MEDIA_PREV_TRACK;
+ break;
+ case 2:
+ mapped_code = KC_PGUP;
+ break;
+ }
}
- } else {
- switch(layer){
- case 0:
- default:
- mapped_code = KC_VOLD;
- break;
- case 1:
- mapped_code = KC_MEDIA_PREV_TRACK;
- break;
- case 2:
- mapped_code = KC_PGUP;
- break;
+ uint16_t held_keycode_timer = timer_read();
+ register_code(mapped_code);
+ while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY) { /* no-op */
}
+ unregister_code(mapped_code);
}
- uint16_t held_keycode_timer = timer_read();
- register_code(mapped_code);
- while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
- unregister_code(mapped_code);
- }
- return true;
+ return true;
}
diff --git a/keyboards/cannonkeys/satisfaction75/satisfaction75.c b/keyboards/cannonkeys/satisfaction75/satisfaction75.c
index bd7eaf1885..9435377839 100644
--- a/keyboards/cannonkeys/satisfaction75/satisfaction75.c
+++ b/keyboards/cannonkeys/satisfaction75/satisfaction75.c
@@ -240,7 +240,7 @@ void read_host_led_state(void) {
layer_state_t layer_state_set_kb(layer_state_t state) {
state = layer_state_set_user(state);
- layer = biton32(state);
+ layer = get_highest_layer(state);
oled_request_wakeup();
return state;
}
diff --git a/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c b/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
index fff8b65bd7..1e8465387c 100644
--- a/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
+++ b/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
@@ -145,7 +145,7 @@ static char* get_time(void) {
hour = 12;
}
- static char time_str[8] = "";
+ static char time_str[11] = "";
sprintf(time_str, "%02d:%02d%s", hour, minute, is_pm ? "pm" : "am");
return time_str;
@@ -162,7 +162,7 @@ static char* get_date(void) {
day = day_config;
}
- static char date_str[11] = "";
+ static char date_str[15] = "";
sprintf(date_str, "%04d-%02d-%02d", year, month, day);
return date_str;
diff --git a/keyboards/ckeys/handwire_101/keymaps/default/keymap.c b/keyboards/ckeys/handwire_101/keymaps/default/keymap.c
index 3bb1a2c009..3f5ebc8655 100755
--- a/keyboards/ckeys/handwire_101/keymaps/default/keymap.c
+++ b/keyboards/ckeys/handwire_101/keymaps/default/keymap.c
@@ -134,10 +134,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `--------=======------------------------'
*/
[_TERMINAL] = LAYOUT_ortho_4x4(
- _______, TERM_ABOUT, _______, _______,
- TERM_OFF, TERM_PRINT, _______, _______,
- _______, TERM_FLUSH, _______, _______,
- TERM_ON, TERM_HELP , _______, _______
+ _______, TERM_ABOUT, _______, _______,
+ _______, TERM_PRINT, _______, _______,
+ _______, TERM_FLUSH, _______, _______,
+ _______, TERM_HELP , _______, _______
),
/* ADMIN
* ,-----------------------------------------.
diff --git a/keyboards/ckeys/handwire_101/rules.mk b/keyboards/ckeys/handwire_101/rules.mk
index 8fa32bcee5..3131bb405a 100755
--- a/keyboards/ckeys/handwire_101/rules.mk
+++ b/keyboards/ckeys/handwire_101/rules.mk
@@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
-TERMINAL_ENABLE = yes
NKRO_ENABLE = yes # Enable N-Key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
AUDIO_ENABLE = no # Audio output
diff --git a/keyboards/ckeys/washington/keymaps/default/keymap.c b/keyboards/ckeys/washington/keymaps/default/keymap.c
index 95e0f3ab59..9ce0181fe4 100644
--- a/keyboards/ckeys/washington/keymaps/default/keymap.c
+++ b/keyboards/ckeys/washington/keymaps/default/keymap.c
@@ -40,7 +40,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
bool encoder_update_user(uint8_t index, bool clockwise) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _BASE:
if (clockwise) {
tap_code(KC_VOLU);
@@ -62,7 +62,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
bool oled_task_user(void) {
// Host Keyboard Layer Status
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _BASE:
oled_write_P(PSTR("Default\n"), false);
break;
diff --git a/keyboards/clueboard/66/keymaps/magicmonty/keymap.c b/keyboards/clueboard/66/keymaps/magicmonty/keymap.c
index 56d4c47071..7b7d2bdce0 100644
--- a/keyboards/clueboard/66/keymaps/magicmonty/keymap.c
+++ b/keyboards/clueboard/66/keymaps/magicmonty/keymap.c
@@ -199,7 +199,7 @@ void matrix_scan_user(void) {
if (!rgblight_config.enable || rgblight_config.mode != 1) { return; }
- uint32_t layer = layer_state;
+ layer_state_t layer = layer_state;
uint8_t val = rgblight_config.val;
if (layer & (1<<_FL)) {
diff --git a/keyboards/contra/keymaps/default/keymap.c b/keyboards/contra/keymaps/default/keymap.c
index 6c05ebebff..1a365c9a6d 100644
--- a/keyboards/contra/keymaps/default/keymap.c
+++ b/keyboards/contra/keymaps/default/keymap.c
@@ -163,7 +163,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = LAYOUT_planck_mit(
_______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
diff --git a/keyboards/crkbd/keymaps/dsanchezseco/keymap.c b/keyboards/crkbd/keymaps/dsanchezseco/keymap.c
index 6ef428a11f..ab84e5c580 100644
--- a/keyboards/crkbd/keymaps/dsanchezseco/keymap.c
+++ b/keyboards/crkbd/keymaps/dsanchezseco/keymap.c
@@ -84,7 +84,7 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
const char *read_logo(void);
bool oled_task_user(void){
- switch (biton32(layer_state)){
+ switch (get_highest_layer(layer_state)){
case _DVORAK:
oled_write_ln_P(PSTR("DVRK"), false);
break;
diff --git a/keyboards/crkbd/keymaps/edvorakjp/keymap.c b/keyboards/crkbd/keymaps/edvorakjp/keymap.c
index 5e56da61a9..f3b801da68 100644
--- a/keyboards/crkbd/keymaps/edvorakjp/keymap.c
+++ b/keyboards/crkbd/keymaps/edvorakjp/keymap.c
@@ -54,9 +54,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format on
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
-uint32_t layer_state_set_keymap(uint32_t state) {
+layer_state_t layer_state_set_keymap(layer_state_t state) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case L_EDVORAKJP_LOWER:
rgblight_sethsv_noeeprom_red();
break;
diff --git a/keyboards/crkbd/keymaps/edvorakjp/oled.c b/keyboards/crkbd/keymaps/edvorakjp/oled.c
index e5ff029565..cd75f8e277 100644
--- a/keyboards/crkbd/keymaps/edvorakjp/oled.c
+++ b/keyboards/crkbd/keymaps/edvorakjp/oled.c
@@ -9,7 +9,7 @@ void render_layer_state(void) {
char layer_name[17];
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case L_EDVORAKJP_BASE:
oled_write_ln_P(PSTR("Default"), false);
break;
diff --git a/keyboards/crkbd/keymaps/jarred/keymap.c b/keyboards/crkbd/keymaps/jarred/keymap.c
index b938636c2a..3784eff2b8 100644
--- a/keyboards/crkbd/keymaps/jarred/keymap.c
+++ b/keyboards/crkbd/keymaps/jarred/keymap.c
@@ -84,7 +84,7 @@ const char *read_keylogs(void);
char matrix_line_str[24];
const char *read_layer_state(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
strcpy(matrix_line_str, "Layer: ");
diff --git a/keyboards/delikeeb/vaneela/keymaps/default/keymap.c b/keyboards/delikeeb/vaneela/keymaps/default/keymap.c
index b1d7401b9d..57df91cd4d 100644
--- a/keyboards/delikeeb/vaneela/keymaps/default/keymap.c
+++ b/keyboards/delikeeb/vaneela/keymaps/default/keymap.c
@@ -106,7 +106,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_FN] = LAYOUT_ortho_5x12(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,TERM_ON, TERM_OFF, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, _______, _______, _______, AG_NORM, AG_SWAP, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/delikeeb/vaneela/keymaps/via/keymap.c b/keyboards/delikeeb/vaneela/keymaps/via/keymap.c
index 65194b84d3..4bfee3daf5 100644
--- a/keyboards/delikeeb/vaneela/keymaps/via/keymap.c
+++ b/keyboards/delikeeb/vaneela/keymaps/via/keymap.c
@@ -105,7 +105,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_FN] = LAYOUT_ortho_5x12(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,TERM_ON, TERM_OFF, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL,
_______, _______, _______, _______, _______, AG_NORM, AG_SWAP, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/dichotomy/keymaps/default/keymap.c b/keyboards/dichotomy/keymaps/default/keymap.c
index b8c7ef4274..80fc4d89bc 100755
--- a/keyboards/dichotomy/keymaps/default/keymap.c
+++ b/keyboards/dichotomy/keymaps/default/keymap.c
@@ -109,7 +109,7 @@ report_mouse_t currentReport = {};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
//uint8_t layer;
- //layer = biton32(layer_state); // get the current layer //Or don't, I didn't use it.
+ //layer = get_highest_layer(layer_state); // get the current layer //Or don't, I didn't use it.
bool returnVal = true; //this is to determine if more key processing is needed.
//custom layer handling for tri_layer,
@@ -437,7 +437,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
};
void matrix_scan_user(void) {
- //uint8_t layer = biton32(layer_state);
+ //uint8_t layer = get_highest_layer(layer_state);
for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
if ((timer_elapsed(special_timers[i]) >= CUSTOM_LONGPRESS) && (!special_key_states[i]) && special_key_pressed[i]){
switch (i + SAFE_RANGE){
diff --git a/keyboards/dm9records/plaid/keymaps/default/keymap.c b/keyboards/dm9records/plaid/keymaps/default/keymap.c
index f11b744066..d96c250609 100644
--- a/keyboards/dm9records/plaid/keymaps/default/keymap.c
+++ b/keyboards/dm9records/plaid/keymaps/default/keymap.c
@@ -195,7 +195,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = LAYOUT_plaid_grid(
QK_BOOT,LED_1, LED_2, LED_3, LED_4, LED_5,LED_6, LED_7, LED_8, LED_9, LED_0,KC_DEL ,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
diff --git a/keyboards/dm9records/plaid/keymaps/thehalfdeafchef/keymap.c b/keyboards/dm9records/plaid/keymaps/thehalfdeafchef/keymap.c
index 6dcabb160e..e617d0dd5f 100644
--- a/keyboards/dm9records/plaid/keymaps/thehalfdeafchef/keymap.c
+++ b/keyboards/dm9records/plaid/keymaps/thehalfdeafchef/keymap.c
@@ -129,7 +129,7 @@ layer_state_t layer_state_set_user(layer_state_t state) { return update_tri_laye
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _LOWER:
diff --git a/keyboards/doio/kb16/keymaps/default/keymap.c b/keyboards/doio/kb16/keymaps/default/keymap.c
index 0d229c753b..df72bbe15a 100644
--- a/keyboards/doio/kb16/keymaps/default/keymap.c
+++ b/keyboards/doio/kb16/keymaps/default/keymap.c
@@ -133,5 +133,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef ENCODER_MAP_ENABLE
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[_BASE] = { ENCODER_CCW_CW(KC_MPRV, KC_MNXT), ENCODER_CCW_CW(KC_PGDN, KC_PGUP), ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
+ [_FN] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
+ [_FN1] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
+ [_FN2] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
};
#endif
diff --git a/keyboards/doppelganger/doppelganger.c b/keyboards/doppelganger/doppelganger.c
index 04d19480da..304d764028 100644
--- a/keyboards/doppelganger/doppelganger.c
+++ b/keyboards/doppelganger/doppelganger.c
@@ -15,25 +15,31 @@
*/
#include "doppelganger.h"
-void keyboard_pre_init_kb (void) {
- setPinOutput(C6);
- setPinOutput(B0);
+void keyboard_pre_init_kb(void) {
+ setPinOutput(C6);
+ setPinOutput(B0);
}
bool led_update_kb(led_t led_state) {
- bool res = led_update_user(led_state);
- if(res) {
- // writePin sets the pin high for 1 and low for 0.
- // In this example the pins are inverted, setting
- // it low/0 turns it on, and high/1 turns the LED off.
- // This behavior depends on whether the LED is between the pin
- // and VCC or the pin and GND.
- writePin(C6, !led_state.caps_lock);
- }
- return res;
+ bool res = led_update_user(led_state);
+ if (res) {
+ // writePin sets the pin high for 1 and low for 0.
+ // In this example the pins are inverted, setting
+ // it low/0 turns it on, and high/1 turns the LED off.
+ // This behavior depends on whether the LED is between the pin
+ // and VCC or the pin and GND.
+ writePin(C6, !led_state.caps_lock);
+ }
+ return res;
}
__attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) {
- writePin(B0, !(state & (1UL << 1)));
- return state;
+ writePin(B0, !(state & (1UL << 1)));
+ return state;
+}
+
+// Override core logic as we reuse SPLIT_HAND_PIN within matrix pins
+bool is_keyboard_left(void) {
+ setPinInput(SPLIT_HAND_PIN);
+ return readPin(SPLIT_HAND_PIN);
}
diff --git a/keyboards/duck/lightsaver/keymaps/rasmus/keymap.c b/keyboards/duck/lightsaver/keymaps/rasmus/keymap.c
index 70dc17bb13..65f128a26b 100644
--- a/keyboards/duck/lightsaver/keymaps/rasmus/keymap.c
+++ b/keyboards/duck/lightsaver/keymaps/rasmus/keymap.c
@@ -34,8 +34,8 @@ enum {
//Tap Dance Definitions
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_F1_GAME] = ACTION_TAP_DANCE_DUAL_ROLE(KC_F1, GAME),
- [TD_CAPS_FN] = ACTION_TAP_DANCE_DUAL_ROLE(KC_CAPS, 5)
+ [TD_F1_GAME] = ACTION_TAP_DANCE_LAYER_MOVE(KC_F1, GAME),
+ [TD_CAPS_FN] = ACTION_TAP_DANCE_LAYER_MOVE(KC_CAPS, 5)
};
enum macro_id {
diff --git a/keyboards/dz60/keymaps/iso_split-spacebar/keymap.c b/keyboards/dz60/keymaps/iso_split-spacebar/keymap.c
index a9e811f9a4..d3956ce3f0 100644
--- a/keyboards/dz60/keymaps/iso_split-spacebar/keymap.c
+++ b/keyboards/dz60/keymaps/iso_split-spacebar/keymap.c
@@ -4,12 +4,12 @@
// thanks to atlacat, hailbreno, itsaferbie and weeheavy...
// and special thanks to AGausmann and drashna for the layer-activated RGB underglow
-// https://www.reddit.com/r/olkb/comments/6t1vdu/update_layeractivated_rgb_underglow/
+// https://www.reddit.com/r/olkb/comments/6t1vdu/update_layeractivated_rgb_underglow/
// https://github.com/AGausmann/qmk_firmware/blob/agausmann-v3.x/keyboards/nyquist/keymaps/agausmann/keymap.c
#include QMK_KEYBOARD_H
-/*
+/*
* Each layer gets a name for readability.
* The underscores don't mean anything - you can
* have a layer called STUFF or any other name.
@@ -23,8 +23,8 @@
#define NL 2 // Numpad Layer
#define RL 3 // RGB Layer
-/*
-* Let's give an easier name to the RGB modes
+/*
+* Let's give an easier name to the RGB modes
* and assign the ones we want to the different layer
* these will then be used by the function below
*
@@ -49,10 +49,10 @@
//
#define RGB_RL_MODE rgblight_mode_noeeprom(22) //rgb mode for RL layer
#define RGB_RL_LIGHT rgblight_sethsv_noeeprom_red() //rgb light for RL layer
-
+
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-
+
/* Keymap BL: Base Layer (Default Layer)
*
* ,-----------------------------------------------------------.
@@ -140,7 +140,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, RGB_STA, RGB_BRE, RGB_RAI, RGB_SWI, _______, _______, RGB_SNA, RGB_KNI, RGB_GRA, RGB_XMS, _______, _______, _______,
_______, BL_DEC, BL_TOGG, BL_INC, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, MO(FL), _______, _______, _______, TO(BL), _______),
-
+
};
@@ -175,25 +175,25 @@ void matrix_scan_user(void) {
#ifdef RGBLIGHT_ENABLE
static uint8_t old_layer = 1;
- uint8_t new_layer = biton32(layer_state);
+ uint8_t new_layer = get_highest_layer(layer_state);
if (old_layer != new_layer) {
switch (new_layer) {
case BL:
RGB_BL_MODE;
- RGB_BL_LIGHT;
+ RGB_BL_LIGHT;
break;
case FL:
RGB_FL_MODE;
- RGB_FL_LIGHT;
+ RGB_FL_LIGHT;
break;
case NL:
- RGB_NL_MODE;
- RGB_NL_LIGHT;
+ RGB_NL_MODE;
+ RGB_NL_LIGHT;
break;
case RL:
- RGB_RL_MODE;
- RGB_RL_LIGHT;
+ RGB_RL_MODE;
+ RGB_RL_LIGHT;
break;
}
diff --git a/keyboards/dz60/keymaps/marianas/customLogic.c b/keyboards/dz60/keymaps/marianas/customLogic.c
index f22bd882e9..03ba92fe92 100644
--- a/keyboards/dz60/keymaps/marianas/customLogic.c
+++ b/keyboards/dz60/keymaps/marianas/customLogic.c
@@ -11,7 +11,7 @@ static int16_t fnTimer = 0;
layer_state_t layer_state_set_user(layer_state_t state)
{
- switch (biton32(state))
+ switch (get_highest_layer(state))
{
case QWERTY:
rgblight_mode(9);
diff --git a/keyboards/dz60/keymaps/xtonhasvim/keymap.c b/keyboards/dz60/keymaps/xtonhasvim/keymap.c
index 9a482686d8..49bc20b576 100644
--- a/keyboards/dz60/keymaps/xtonhasvim/keymap.c
+++ b/keyboards/dz60/keymaps/xtonhasvim/keymap.c
@@ -73,7 +73,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
static uint32_t last_state = 0;
if(last_state != state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _CMD:
user_led_on();
break;
@@ -85,5 +85,3 @@ layer_state_t layer_state_set_user(layer_state_t state) {
}
return state;
}
-
-
diff --git a/keyboards/dztech/dz60rgb/keymaps/matthewrobo/keymap.c b/keyboards/dztech/dz60rgb/keymaps/matthewrobo/keymap.c
index a12358c8d9..287496e17f 100644
--- a/keyboards/dztech/dz60rgb/keymaps/matthewrobo/keymap.c
+++ b/keyboards/dztech/dz60rgb/keymaps/matthewrobo/keymap.c
@@ -96,7 +96,7 @@ void rgb_matrix_indicators_user(void)
uint8_t this_led = host_keyboard_leds();
if (!g_suspend_state && rgb_matrix_config.enable) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _NAV:
if (this_led & (1 << USB_LED_NUM_LOCK)) {
rgb_matrix_set_color(13, 0xFF, 0x00, 0x00);
diff --git a/keyboards/dztech/dz60rgb/keymaps/mekanist/keymap.c b/keyboards/dztech/dz60rgb/keymaps/mekanist/keymap.c
index a7c6360568..6af35cf779 100644
--- a/keyboards/dztech/dz60rgb/keymaps/mekanist/keymap.c
+++ b/keyboards/dztech/dz60rgb/keymaps/mekanist/keymap.c
@@ -62,7 +62,7 @@ void rgb_matrix_indicators_user(void)
uint8_t this_led = host_keyboard_leds();
if (!g_suspend_state && rgb_matrix_config.enable) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _LAYER1:
rgb_matrix_layer_helper(0xFF, 0x00, 0x00); break;
@@ -78,7 +78,7 @@ void rgb_matrix_indicators_user(void)
rgb_matrix_set_color(40, 0xFF, 0xFF, 0xFF);
}
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _LAYER3:
if (this_led & (1 << USB_LED_NUM_LOCK)) {
rgb_matrix_set_color(13, 0xFF, 0x00, 0x00);
diff --git a/keyboards/dztech/dz60rgb/keymaps/perseid/keymap.c b/keyboards/dztech/dz60rgb/keymaps/perseid/keymap.c
index c13fcc1d35..daef7b271d 100644
--- a/keyboards/dztech/dz60rgb/keymaps/perseid/keymap.c
+++ b/keyboards/dztech/dz60rgb/keymaps/perseid/keymap.c
@@ -37,7 +37,7 @@ void rgb_matrix_layer_helper (uint8_t red, uint8_t green, uint8_t blue) {
void rgb_matrix_indicators_user(void)
{
if (!g_suspend_state) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _QWERTY:
rgb_matrix_layer_helper(0x00, 0x0F, 0xFF); break;
@@ -46,7 +46,7 @@ void rgb_matrix_indicators_user(void)
}
}
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _FNM:
rgb_matrix_set_color(0, 0x00, 0xFF, 0x00);
rgb_matrix_set_color(1, 0x00, 0x00, 0x00);
diff --git a/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c b/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c
index 8bd6069107..817c0fd2ff 100644
--- a/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c
+++ b/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c
@@ -238,5 +238,5 @@ void rgb_matrix_indicators_user(void) {
}
// Show Selected Layer
- rgb_matrix_set_color(layers_leds_map[biton32(layer_state)], MAIN_COLOR[0], MAIN_COLOR[1], MAIN_COLOR[2]);
-} \ No newline at end of file
+ rgb_matrix_set_color(layers_leds_map[get_highest_layer(layer_state)], MAIN_COLOR[0], MAIN_COLOR[1], MAIN_COLOR[2]);
+}
diff --git a/keyboards/dztech/dz65rgb/keymaps/drootz/keymap.c b/keyboards/dztech/dz65rgb/keymaps/drootz/keymap.c
index c313f467e3..2ebbddcef7 100644
--- a/keyboards/dztech/dz65rgb/keymaps/drootz/keymap.c
+++ b/keyboards/dztech/dz65rgb/keymaps/drootz/keymap.c
@@ -1,20 +1,20 @@
#include QMK_KEYBOARD_H
/**************** SOME GLOBALS *********************/
-
+
bool onMac = false;
bool isLeader = false;
bool isBlinking = false;
bool isRecording = false;
bool isPlaying = false;
-const float led_dim_ratio = 0.50;
-static uint16_t blink_cycle_timer,
- blink_fade_in_timer,
- blink_fade_out_timer,
+const float led_dim_ratio = 0.50;
+static uint16_t blink_cycle_timer,
+ blink_fade_in_timer,
+ blink_fade_out_timer,
macro_one_play_timer,
macro_two_play_timer,
macro_play_blink_timer = 2000;
-static uint8_t fade_in_step_counter,
+static uint8_t fade_in_step_counter,
fade_out_step_counter,
blink_hsv_value;
@@ -26,13 +26,13 @@ Function to set color with hsv arguments
- "val_ratio" is used to adjust brightness ratio
*/
void rgb_matrix_set_color_hsv(uint8_t led, uint16_t hue, uint16_t sat, uint16_t val, float val_ratio) {
- const uint8_t h = hue <= 255 ? hue : rgb_matrix_config.hsv.h;
+ const uint8_t h = hue <= 255 ? hue : rgb_matrix_config.hsv.h;
const uint8_t s = sat <= 255 ? sat : rgb_matrix_config.hsv.s;
const uint8_t v = val <= 255 ? val * val_ratio : rgb_matrix_config.hsv.v * val_ratio;
HSV hsv_in = {h, s, v};
RGB rgb_out = hsv_to_rgb(hsv_in);
rgb_matrix_set_color(led, rgb_out.r, rgb_out.g, rgb_out.b);
-}
+}
void reset_blink_cycle(void) {
blink_cycle_timer = timer_read();
@@ -110,31 +110,31 @@ const layers_leds_map[] = {
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_MAIN] = LAYOUT_65_ansi(
- KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS,
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
- KC_LEAD, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_DEL,
+ KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
+ KC_LEAD, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_DEL,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[_MAC] = LAYOUT_65_ansi(
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_LALT, KC_LGUI, KC_TRNS, KC_TRNS, MO(_FN), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
),
[_FN] = LAYOUT_65_ansi(
- DYN_REC_STOP, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_NO,
- KC_TRNS, KC_MUTE, KC_VOLU, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_SAD, RGB_SAI, DYN_MACRO_PLAY2, DYN_REC_START2,
- KC_TRNS, KC_BRID, KC_VOLD, KC_BRIU, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_HUD, RGB_HUI, DYN_MACRO_PLAY1, DYN_REC_START1,
- KC_TRNS, TO(_MAIN), TO(_MAC), KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_SPD, RGB_SPI, KC_TRNS, RGB_VAI, KC_NO,
+ DYN_REC_STOP, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_NO,
+ KC_TRNS, KC_MUTE, KC_VOLU, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_SAD, RGB_SAI, DYN_MACRO_PLAY2, DYN_REC_START2,
+ KC_TRNS, KC_BRID, KC_VOLD, KC_BRIU, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_HUD, RGB_HUI, DYN_MACRO_PLAY1, DYN_REC_START1,
+ KC_TRNS, TO(_MAIN), TO(_MAC), KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_SPD, RGB_SPI, KC_TRNS, RGB_VAI, KC_NO,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_RMOD, RGB_VAD, RGB_MOD
),
-};
+};
//**************** MATRIX SCANS *********************//
-void rgb_matrix_indicators_user(void) {
+void rgb_matrix_indicators_user(void) {
#ifdef RGB_MATRIX_ENABLE
@@ -144,7 +144,7 @@ void rgb_matrix_indicators_user(void) {
/* CapsLock LED indicator */
if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) {
rgb_matrix_set_color_hsv(30, 999, 0, led_constant_val, 0.75); // WHITE
- }
+ }
/* Current layer LED indicator */
rgb_matrix_set_color_hsv(layers_leds_map[get_highest_layer(layer_state)], 999, 0, led_constant_val, led_dim_ratio); // WHITE
@@ -155,7 +155,7 @@ void rgb_matrix_indicators_user(void) {
rgb_matrix_set_color_hsv(30, 999, 999, 999, 1); // CONFIG
} else {
rgb_matrix_set_color_hsv(14, 999, 999, 999, led_dim_ratio); // CONFIG
- }
+ }
/* Blinking LED indicator when recording Dynamic Macro */
if (isRecording && isBlinking) {
@@ -174,7 +174,7 @@ void rgb_matrix_indicators_user(void) {
}
}
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _FN:
/* Dynamic Macro LED indicator */
if (isRecording) {
@@ -188,12 +188,12 @@ void rgb_matrix_indicators_user(void) {
/* Layer LED indicators */
rgb_matrix_set_color_hsv(45, 999, 0, led_constant_val, led_dim_ratio); /* WHITE Layer _MAIN */
rgb_matrix_set_color_hsv(46, 999, 0, led_constant_val, led_dim_ratio); /* WHITE Layer _MAC */
- break;
+ break;
}
#endif /* RGB_MATRIX */
}
-
+
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
bool pressed = record->event.pressed;
if (pressed) {
@@ -202,12 +202,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
onMac = true;
break;
case TO(_MAIN):
- onMac = false;
+ onMac = false;
break;
}
}
return true;
-}
+}
//**************** LEADER *********************//
@@ -244,7 +244,7 @@ const uint8_t french_accent_index[3] = {
[_ACUTE] = 2
};
-/*
+/*
This represent unicode decimal values
Each index will be mapped to numpad keycode to out put the correct sequence
All codes in this array should be of size 3
@@ -272,8 +272,8 @@ const uint8_t french_decimal_unicodes[5][3][2] = { /*[Letter][Accent][Case]*/
}
},{
{
- 140, // î
- 206 // ÃŽ
+ 140, // î
+ 206 // ÃŽ
}
},{
{
@@ -306,7 +306,7 @@ This is designed and work on an English language keyboard setting on both Window
=> accept french_letter and french_accent enum's as argument
*/
void send_french_accent(uint8_t letter, uint8_t accent) {
-
+
bool isCaps;
uint8_t decimal_unicode_in;
uint8_t decimal_unicode_size = 3;
@@ -330,7 +330,7 @@ void send_french_accent(uint8_t letter, uint8_t accent) {
};
/*
- Function to tap the correct keycodes in sequence for the
+ Function to tap the correct keycodes in sequence for the
"Windows Alt Code" requested, aka Decimal Unicodes
*/
void tap_win_alt_code(void) {
@@ -341,7 +341,7 @@ void send_french_accent(uint8_t letter, uint8_t accent) {
tap_code(numpad_key_map[decimal_unicode_out[i]]);
}
}
-
+
isCaps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK) ? true : false;
if (onMac) {
@@ -372,7 +372,7 @@ void send_french_accent(uint8_t letter, uint8_t accent) {
/*Couple functions used to output the same macro on two different sequences*/
-/* (|) */
+/* (|) */
void ldrkey_send_paranthesis_wrap_ini(void) {
SEND_STRING("()" SS_TAP(X_LEFT));
}
@@ -382,7 +382,7 @@ void ldrkey_send_paranthesis_wrap_word(void) {
onMac ? SEND_STRING(SS_LALT(SS_TAP(X_LEFT)) "(" SS_LALT(SS_TAP(X_RIGHT)) ")") : SEND_STRING(SS_LCTL(SS_TAP(X_LEFT)) "(" SS_LCTL(SS_TAP(X_RIGHT)) ")");
}
-/* (selection) */
+/* (selection) */
void ldrkey_send_paranthesis_wrap_selection(void) {
onMac ? SEND_STRING(SS_LGUI(SS_TAP(X_X)) "()" SS_TAP(X_LEFT) SS_LGUI(SS_TAP(X_V)) SS_TAP(X_RIGHT)) : SEND_STRING(SS_LCTL(SS_TAP(X_X)) "()" SS_TAP(X_LEFT) SS_LCTL(SS_TAP(X_V)) SS_TAP(X_RIGHT));
}
@@ -419,9 +419,9 @@ void ldrkey_send_curlybrace_wrap_selection(void) {
LEADER_EXTERNS();
-void matrix_scan_user(void)
+void matrix_scan_user(void)
{
- LEADER_DICTIONARY()
+ LEADER_DICTIONARY()
{
leading = false;
leader_end();
@@ -476,49 +476,49 @@ void matrix_scan_user(void)
tap_code(KC_CAPS);
}
/* ± => LdrKey > = > - */
- SEQ_TWO_KEYS(KC_EQL, KC_MINS) {
- onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_EQL)))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P1) SS_UP(X_LALT));
+ SEQ_TWO_KEYS(KC_EQL, KC_MINS) {
+ onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_EQL)))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P1) SS_UP(X_LALT));
}
/* ≤ => LdrKey > - > = */
- SEQ_TWO_KEYS(KC_MINS, KC_EQL) {
- onMac ? SEND_STRING(SS_LALT(SS_TAP(X_COMM))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P3) SS_UP(X_LALT));
+ SEQ_TWO_KEYS(KC_MINS, KC_EQL) {
+ onMac ? SEND_STRING(SS_LALT(SS_TAP(X_COMM))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P3) SS_UP(X_LALT));
}
/* ≥ => LdrKey > = > = */
- SEQ_TWO_KEYS(KC_EQL, KC_EQL) {
- onMac ? SEND_STRING(SS_LALT(SS_TAP(X_DOT))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P2) SS_UP(X_LALT));
+ SEQ_TWO_KEYS(KC_EQL, KC_EQL) {
+ onMac ? SEND_STRING(SS_LALT(SS_TAP(X_DOT))) : SEND_STRING(SS_DOWN(X_LALT) SS_TAP(X_P2) SS_TAP(X_P4) SS_TAP(X_P2) SS_UP(X_LALT));
}
/* <= => LdrKey > , > , */
- SEQ_TWO_KEYS(KC_COMM, KC_COMM) {
- SEND_STRING(SS_LSFT(SS_TAP(X_COMM)) SS_TAP(X_SPC) SS_TAP(X_EQL) SS_TAP(X_LEFT) SS_TAP(X_BSPC) SS_TAP(X_RIGHT));
+ SEQ_TWO_KEYS(KC_COMM, KC_COMM) {
+ SEND_STRING(SS_LSFT(SS_TAP(X_COMM)) SS_TAP(X_SPC) SS_TAP(X_EQL) SS_TAP(X_LEFT) SS_TAP(X_BSPC) SS_TAP(X_RIGHT));
}
/* => => LdrKey > . > . */
- SEQ_TWO_KEYS(KC_DOT, KC_DOT) {
- SEND_STRING("=>");
+ SEQ_TWO_KEYS(KC_DOT, KC_DOT) {
+ SEND_STRING("=>");
}
/* ", " => LdrKey > " " */
- SEQ_ONE_KEY(KC_SPC) {
- SEND_STRING(", ");
+ SEQ_ONE_KEY(KC_SPC) {
+ SEND_STRING(", ");
}
/* ". " => LdrKey > " " > " " */
- SEQ_TWO_KEYS(KC_SPC, KC_SPC) {
- SEND_STRING(". ");
+ SEQ_TWO_KEYS(KC_SPC, KC_SPC) {
+ SEND_STRING(". ");
}
/* Backward delete current word (on cursor) */
- SEQ_TWO_KEYS(KC_BSPC, KC_BSPC) {
- onMac ? SEND_STRING(SS_LALT(SS_TAP(X_RIGHT)) SS_LALT(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC)) : SEND_STRING(SS_LCTL(SS_TAP(X_RIGHT)) SS_LCTL(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC));
+ SEQ_TWO_KEYS(KC_BSPC, KC_BSPC) {
+ onMac ? SEND_STRING(SS_LALT(SS_TAP(X_RIGHT)) SS_LALT(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC)) : SEND_STRING(SS_LCTL(SS_TAP(X_RIGHT)) SS_LCTL(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC));
}
/* Previous word delete */
- SEQ_ONE_KEY(KC_BSPC) {
- onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC)) : SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC));
+ SEQ_ONE_KEY(KC_BSPC) {
+ onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC)) : SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_LEFT))) SS_TAP(X_BSPC));
}
/* Forward delete current word (on cursor) */
- SEQ_TWO_KEYS(KC_DEL, KC_DEL) {
+ SEQ_TWO_KEYS(KC_DEL, KC_DEL) {
- onMac ? SEND_STRING(SS_LALT(SS_TAP(X_LEFT)) SS_LALT(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL)) : SEND_STRING(SS_LCTL(SS_TAP(X_LEFT)) SS_LCTL(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL));
+ onMac ? SEND_STRING(SS_LALT(SS_TAP(X_LEFT)) SS_LALT(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL)) : SEND_STRING(SS_LCTL(SS_TAP(X_LEFT)) SS_LCTL(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL));
}
/* Next word delete */
- SEQ_ONE_KEY(KC_DEL) {
- onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL)): SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL));
+ SEQ_ONE_KEY(KC_DEL) {
+ onMac ? SEND_STRING(SS_LALT(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL)): SEND_STRING(SS_LCTL(SS_LSFT(SS_TAP(X_RIGHT))) SS_TAP(X_DEL));
}
/* ` => LdrKey > Escape */
SEQ_ONE_KEY(KC_GESC) {
@@ -548,7 +548,7 @@ void matrix_scan_user(void)
SEQ_ONE_KEY(KC_Q) {
onMac ? SEND_STRING(SS_LGUI(SS_TAP(X_Q))) : SEND_STRING(SS_LALT(SS_TAP(X_F4)));
}
- /* " => LdrKey > ' */
+ /* " => LdrKey > ' */
SEQ_ONE_KEY(KC_QUOT) {
SEND_STRING("\"");
}
@@ -657,48 +657,48 @@ void matrix_scan_user(void)
ldrkey_send_curlybrace_wrap_selection();
}
/* Select everything on this line before cursor => LdrKey > Left */
- SEQ_ONE_KEY(KC_LEFT) {
+ SEQ_ONE_KEY(KC_LEFT) {
onMac ? SEND_STRING(SS_LSFT(SS_LGUI(SS_TAP(X_LEFT)))) : SEND_STRING(SS_LSFT(SS_TAP(X_HOME)));
}
/* Select everything on this line after cursor => LdrKey > Right */
- SEQ_ONE_KEY(KC_RIGHT) {
+ SEQ_ONE_KEY(KC_RIGHT) {
onMac ? SEND_STRING(SS_LSFT(SS_LGUI(SS_TAP(X_RIGHT)))) : SEND_STRING(SS_LSFT(SS_TAP(X_END)));
}
/* Select everything on this line before cursor and bring on previous line => LdrKey > Left > Left */
- SEQ_TWO_KEYS(KC_LEFT, KC_LEFT) {
- onMac ? SEND_STRING(SS_LSFT(SS_TAP(X_UP) SS_LGUI(SS_TAP(X_RIGHT)))) : SEND_STRING(SS_LSFT(SS_TAP(X_UP) SS_TAP(X_END)));
+ SEQ_TWO_KEYS(KC_LEFT, KC_LEFT) {
+ onMac ? SEND_STRING(SS_LSFT(SS_TAP(X_UP) SS_LGUI(SS_TAP(X_RIGHT)))) : SEND_STRING(SS_LSFT(SS_TAP(X_UP) SS_TAP(X_END)));
}
/* Select everything on this line => LdrKey > Right > Left */
- SEQ_TWO_KEYS(KC_RIGHT, KC_LEFT) {
- onMac ? SEND_STRING(SS_LGUI(SS_TAP(X_RIGHT) SS_LSFT(SS_LGUI(SS_TAP(X_LEFT))))) : SEND_STRING(SS_TAP(X_END) SS_LSFT(SS_TAP(X_HOME)));
+ SEQ_TWO_KEYS(KC_RIGHT, KC_LEFT) {
+ onMac ? SEND_STRING(SS_LGUI(SS_TAP(X_RIGHT) SS_LSFT(SS_LGUI(SS_TAP(X_LEFT))))) : SEND_STRING(SS_TAP(X_END) SS_LSFT(SS_TAP(X_HOME)));
}
/* Select 1x Page Up on the page before the cursor => LdrKey > Up */
- SEQ_ONE_KEY(KC_UP) {
+ SEQ_ONE_KEY(KC_UP) {
SEND_STRING(SS_LSFT(SS_TAP(X_PGUP)));
}
/* Select 1x Page Down on the page after the cursor => LdrKey > Down */
- SEQ_ONE_KEY(KC_DOWN) {
- SEND_STRING(SS_LSFT(SS_TAP(X_PGDN)));
+ SEQ_ONE_KEY(KC_DOWN) {
+ SEND_STRING(SS_LSFT(SS_TAP(X_PGDN)));
}
/* Select everything on the page before the cursor => LdrKey > Up > Up */
- SEQ_TWO_KEYS(KC_UP, KC_UP) {
+ SEQ_TWO_KEYS(KC_UP, KC_UP) {
onMac ? SEND_STRING(SS_LSFT(SS_LGUI(SS_TAP(X_UP)))) : SEND_STRING(SS_LSFT(SS_LCTL(SS_TAP(X_HOME))));
}
/* Select everything on the page after the cursor => LdrKey > Down > Down */
- SEQ_TWO_KEYS(KC_DOWN, KC_DOWN) {
+ SEQ_TWO_KEYS(KC_DOWN, KC_DOWN) {
onMac ? SEND_STRING(SS_LSFT(SS_LGUI(SS_TAP(X_DOWN)))) : SEND_STRING(SS_LSFT(SS_LCTL(SS_TAP(X_END))));
}
/* HELPER => spit out the url of the layout description page on github */
- SEQ_FIVE_KEYS(KC_GESC, KC_GESC, KC_GESC, KC_GESC, KC_GESC) {
+ SEQ_FIVE_KEYS(KC_GESC, KC_GESC, KC_GESC, KC_GESC, KC_GESC) {
SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/keyboards/dztech/dz65rgb/keymaps/drootz");
}
/* google.ca => LdrKey > G > G */
- SEQ_TWO_KEYS(KC_G, KC_G) {
- SEND_STRING("https://google.ca" SS_TAP(X_ENT));
+ SEQ_TWO_KEYS(KC_G, KC_G) {
+ SEND_STRING("https://google.ca" SS_TAP(X_ENT));
}
/* @gmail => LdrKey > M > L > T */
- SEQ_THREE_KEYS(KC_M, KC_L, KC_T) {
- SEND_STRING("mailto." SS_TAP(X_D) SS_TAP(X_A) SS_TAP(X_N) SS_TAP(X_I) SS_TAP(X_E) SS_TAP(X_L) SS_TAP(X_R) SS_TAP(X_A) SS_TAP(X_C) SS_TAP(X_I) SS_TAP(X_N) SS_TAP(X_E) "@gmail.com");
+ SEQ_THREE_KEYS(KC_M, KC_L, KC_T) {
+ SEND_STRING("mailto." SS_TAP(X_D) SS_TAP(X_A) SS_TAP(X_N) SS_TAP(X_I) SS_TAP(X_E) SS_TAP(X_L) SS_TAP(X_R) SS_TAP(X_A) SS_TAP(X_C) SS_TAP(X_I) SS_TAP(X_N) SS_TAP(X_E) "@gmail.com");
}
/* Show Desktop => LdrKey > D */
SEQ_ONE_KEY(KC_D) {
diff --git a/keyboards/dztech/dz65rgb/keymaps/matthewrobo/keymap.c b/keyboards/dztech/dz65rgb/keymaps/matthewrobo/keymap.c
index 00915a9b4f..0c7bfbbb48 100644
--- a/keyboards/dztech/dz65rgb/keymaps/matthewrobo/keymap.c
+++ b/keyboards/dztech/dz65rgb/keymaps/matthewrobo/keymap.c
@@ -91,7 +91,7 @@ void rgb_matrix_indicators_user(void)
uint8_t this_led = host_keyboard_leds();
if (!g_suspend_state && rgb_matrix_config.enable) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _NAV:
if (IS_LED_ON(this_led, USB_LED_NUM_LOCK)) {
rgb_matrix_set_color(17, 0xFF, 0x00, 0x00);
diff --git a/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c b/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c
index a5b107baae..91798ab188 100755
--- a/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c
@@ -190,7 +190,7 @@ static bool is_macro1_recording = false;
// The current set of active layers (as a bitmask).
// There is a global 'layer_state' variable but it is set after the call
// to layer_state_set_user().
-static uint32_t current_layer_state = 0;
+static layer_state_t current_layer_state = 0;
layer_state_t layer_state_set_user(layer_state_t state);
// Method called at the end of the tap dance on the TAP_MACRO key. That key is
diff --git a/keyboards/ergodox_ez/keymaps/blakedietz/keymap.c b/keyboards/ergodox_ez/keymaps/blakedietz/keymap.c
index 5c08d30727..67c50eb129 100644
--- a/keyboards/ergodox_ez/keymaps/blakedietz/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/blakedietz/keymap.c
@@ -200,7 +200,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -262,4 +262,3 @@ void matrix_scan_user(void) {
// }
// return true;
//}
-
diff --git a/keyboards/ergodox_ez/keymaps/bpruitt-goddard/keymap.c b/keyboards/ergodox_ez/keymaps/bpruitt-goddard/keymap.c
index 229ece0d74..eff7f111b4 100644
--- a/keyboards/ergodox_ez/keymaps/bpruitt-goddard/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/bpruitt-goddard/keymap.c
@@ -98,7 +98,7 @@ static bool is_macro1_recording = false;
// The current set of active layers (as a bitmask).
// There is a global 'layer_state' variable but it is set after the call
// to layer_state_set_user().
-static uint32_t current_layer_state = 0;
+static layer_state_t current_layer_state = 0;
layer_state_t layer_state_set_user(layer_state_t state);
// Method called at the end of the tap dance on the TAP_MACRO key. That key is
diff --git a/keyboards/ergodox_ez/keymaps/default_osx/keymap.c b/keyboards/ergodox_ez/keymaps/default_osx/keymap.c
index 73b1077b83..3ab66078fe 100644
--- a/keyboards/ergodox_ez/keymaps/default_osx/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/default_osx/keymap.c
@@ -141,7 +141,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/dvorak_42_key/keymap.c b/keyboards/ergodox_ez/keymaps/dvorak_42_key/keymap.c
index fab2977356..ff9ae77bdd 100644
--- a/keyboards/ergodox_ez/keymaps/dvorak_42_key/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/dvorak_42_key/keymap.c
@@ -725,7 +725,7 @@ void led_set_user(uint8_t usb_led) {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_2_off();
diff --git a/keyboards/ergodox_ez/keymaps/hacker_dvorak/config.h b/keyboards/ergodox_ez/keymaps/hacker_dvorak/config.h
index da20820787..c35963d842 100644
--- a/keyboards/ergodox_ez/keymaps/hacker_dvorak/config.h
+++ b/keyboards/ergodox_ez/keymaps/hacker_dvorak/config.h
@@ -7,6 +7,7 @@
#undef TAPPING_TERM
#define TAPPING_TERM 175
+#define TAPPING_TERM_PER_KEY
#undef DEBOUNCE
#define DEBOUNCE 15
diff --git a/keyboards/ergodox_ez/keymaps/hacker_dvorak/tap_dance/tap_dance_actions.c b/keyboards/ergodox_ez/keymaps/hacker_dvorak/tap_dance/tap_dance_actions.c
index 59e3e2b0dc..1d5e1cee00 100644
--- a/keyboards/ergodox_ez/keymaps/hacker_dvorak/tap_dance/tap_dance_actions.c
+++ b/keyboards/ergodox_ez/keymaps/hacker_dvorak/tap_dance/tap_dance_actions.c
@@ -13,14 +13,32 @@ qk_tap_dance_action_t tap_dance_actions[] = {
[RPRN_RBRC] = ACTION_TAP_DANCE_DOUBLE(KC_RPRN, KC_RBRC),
[LCBR_LABK] = ACTION_TAP_DANCE_DOUBLE(KC_LCBR, KC_LABK),
[RCBR_RABK] = ACTION_TAP_DANCE_DOUBLE(KC_RCBR, KC_RABK),
- [SCLN_COLN] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, scln_coln_finished, scln_coln_reset, DANCING_TERM),
- [QUOT_DQUO] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, quot_dquot_finished, quot_dquot_reset, DANCING_TERM),
- [DOT_COMM] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, dot_comm_finished, dot_comm_reset, DANCING_TERM),
- [NONE_LEAD] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, none_lead_finished, none_lead_reset, DANCING_TERM),
- [U_ARR_GUI] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, u_arrows_gui_finished, u_arrows_gui_reset, DANCING_TERM),
- [H_MOU_GUI] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, h_mouse_gui_finished, h_mouse_gui_reset, DANCING_TERM),
- [J_MED_MEH] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, j_media_meh_finished, j_media_meh_reset, DANCING_TERM),
- [W_MED_MEH] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, w_media_meh_finished, w_media_meh_reset, DANCING_TERM),
- [K_NUM_HYP] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, k_numpad_hyper_finished, k_numpad_hyper_reset, DANCING_TERM),
- [M_CHO_HYP] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, m_chords_hyper_finished, m_chords_hyper_reset, DANCING_TERM),
+ [SCLN_COLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, scln_coln_finished, scln_coln_reset),
+ [QUOT_DQUO] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, quot_dquot_finished, quot_dquot_reset),
+ [DOT_COMM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dot_comm_finished, dot_comm_reset),
+ [NONE_LEAD] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, none_lead_finished, none_lead_reset),
+ [U_ARR_GUI] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, u_arrows_gui_finished, u_arrows_gui_reset),
+ [H_MOU_GUI] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, h_mouse_gui_finished, h_mouse_gui_reset),
+ [J_MED_MEH] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, j_media_meh_finished, j_media_meh_reset),
+ [W_MED_MEH] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, w_media_meh_finished, w_media_meh_reset),
+ [K_NUM_HYP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, k_numpad_hyper_finished, k_numpad_hyper_reset),
+ [M_CHO_HYP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, m_chords_hyper_finished, m_chords_hyper_reset),
};
+
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(SCLN_COLN):
+ case TD(QUOT_DQUO):
+ case TD(DOT_COMM):
+ case TD(NONE_LEAD):
+ case TD(U_ARR_GUI):
+ case TD(H_MOU_GUI):
+ case TD(J_MED_MEH):
+ case TD(W_MED_MEH):
+ case TD(K_NUM_HYP):
+ case TD(M_CHO_HYP):
+ return DANCING_TERM;
+ default:
+ return TAPPING_TERM;
+ }
+}
diff --git a/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c b/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
index fd022681b0..ed407def79 100644
--- a/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
+++ b/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
@@ -1,6 +1,6 @@
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
switch (layer) {
case DVORAK:
diff --git a/keyboards/ergodox_ez/keymaps/heartrobotninja/keymap.c b/keyboards/ergodox_ez/keymaps/heartrobotninja/keymap.c
index b6edc17532..91884c8e76 100644
--- a/keyboards/ergodox_ez/keymaps/heartrobotninja/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/heartrobotninja/keymap.c
@@ -370,7 +370,7 @@ LEADER_EXTERNS();
void matrix_scan_user(void)
{
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (keyboard_report->mods & MOD_BIT(KC_LSFT) ||
((get_oneshot_mods() & MOD_BIT(KC_LSFT)) &&
@@ -677,4 +677,4 @@ void matrix_init_user(void)
wait_ms(1000);
rgblight_effect_knight(50);
-} \ No newline at end of file
+}
diff --git a/keyboards/ergodox_ez/keymaps/kou/keymap.c b/keyboards/ergodox_ez/keymaps/kou/keymap.c
index c8d0a6b5dd..01427c2d2d 100644
--- a/keyboards/ergodox_ez/keymaps/kou/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/kou/keymap.c
@@ -284,7 +284,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/lukaus/keymap.c b/keyboards/ergodox_ez/keymaps/lukaus/keymap.c
index 5d797beb18..542e123db3 100644
--- a/keyboards/ergodox_ez/keymaps/lukaus/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/lukaus/keymap.c
@@ -813,7 +813,7 @@ case RU_7:
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
// ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/matrixman/keymap.c b/keyboards/ergodox_ez/keymaps/matrixman/keymap.c
index 10b6567cdb..bb6ba5ae34 100644
--- a/keyboards/ergodox_ez/keymaps/matrixman/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/matrixman/keymap.c
@@ -165,7 +165,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/nathanvercaemert/keymap.c b/keyboards/ergodox_ez/keymaps/nathanvercaemert/keymap.c
index e31391a674..a3c2176951 100644
--- a/keyboards/ergodox_ez/keymaps/nathanvercaemert/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/nathanvercaemert/keymap.c
@@ -218,7 +218,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
@@ -431,4 +431,3 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
return true;
}
-
diff --git a/keyboards/ergodox_ez/keymaps/nfriend/keymap.c b/keyboards/ergodox_ez/keymaps/nfriend/keymap.c
index 1d12093bab..ba578dd1c5 100644
--- a/keyboards/ergodox_ez/keymaps/nfriend/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/nfriend/keymap.c
@@ -1057,7 +1057,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/profet_80/keymap.c b/keyboards/ergodox_ez/keymaps/profet_80/keymap.c
index 85455fa9d9..6f602e828e 100644
--- a/keyboards/ergodox_ez/keymaps/profet_80/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/profet_80/keymap.c
@@ -157,7 +157,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/pvinis/keymap.c b/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
index 024cefd270..c69621ab98 100644
--- a/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
@@ -245,11 +245,11 @@ void keyboard_post_init_user_keymap(void) {
}
// light up leds based on the layer
-uint32_t layer_state_set_user_keymap(uint32_t state) {
+layer_state_t layer_state_set_user_keymap(layer_state_t state) {
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case LR_SYSCTL:
ergodox_right_led_3_on(); // blue
break;
@@ -306,7 +306,7 @@ uint32_t layer_state_set_user_keymap(uint32_t state) {
// SYSCTL on first tap, MOUSE ON second tap
// void layers_dance_finished(qk_tap_dance_state_t *state, void *user_data) {
-// uint8_t layer = biton32(layer_state);
+// uint8_t layer = get_highest_layer(layer_state);
// switch(state->count) {
// case 1:
diff --git a/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c b/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
index 3e607edb39..595f3b4ee1 100644
--- a/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
@@ -228,7 +228,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case SYMB:
ergodox_right_led_1_on();
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
@@ -268,4 +268,3 @@ layer_state_t layer_state_set_user(layer_state_t state) {
}
return state;
}
-
diff --git a/keyboards/ergodox_ez/keymaps/rishka/keymap.c b/keyboards/ergodox_ez/keymaps/rishka/keymap.c
index 102803e512..0d6ac9fe95 100644
--- a/keyboards/ergodox_ez/keymaps/rishka/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/rishka/keymap.c
@@ -138,7 +138,7 @@ void keyboard_post_init_user(void) {
};
// Runs whenever there is a layer state change.
-uint32_t layer_state_set_user(layer_state_t state) {
+layer_state_t layer_state_set_user(layer_state_t state) {
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/keyboards/ergodox_ez/keymaps/skug/keymap.c b/keyboards/ergodox_ez/keymaps/skug/keymap.c
index 1446ea7466..04aa6a99fd 100644
--- a/keyboards/ergodox_ez/keymaps/skug/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/skug/keymap.c
@@ -228,7 +228,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/smurmann/keymap.c b/keyboards/ergodox_ez/keymaps/smurmann/keymap.c
index 42ac13775f..c8ddc23a8b 100644
--- a/keyboards/ergodox_ez/keymaps/smurmann/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/smurmann/keymap.c
@@ -139,7 +139,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if(layer == 1)
{
@@ -157,7 +157,7 @@ void matrix_scan_user(void) {
}
if(keyboard_report->mods & MOD_BIT(KC_LSFT))
- {
+ {
ergodox_right_led_1_set (LED_BRIGHTNESS_HI);
ergodox_right_led_1_on ();
} else {
@@ -182,7 +182,7 @@ void matrix_scan_user(void) {
}
if(keyboard_report->mods & MOD_BIT(KC_LCTRL))
- {
+ {
ergodox_right_led_3_set (LED_BRIGHTNESS_HI);
ergodox_right_led_3_on ();
} else {
@@ -195,7 +195,7 @@ void matrix_scan_user(void) {
};
void led_set_user(uint8_t usb_led){
- if (usb_led & (1 << USB_LED_CAPS_LOCK))
+ if (usb_led & (1 << USB_LED_CAPS_LOCK))
{
capsOn = true;
}else {
diff --git a/keyboards/ergodox_ez/keymaps/steno/keymap.c b/keyboards/ergodox_ez/keymaps/steno/keymap.c
index 080d3f6cef..96218bbe99 100644
--- a/keyboards/ergodox_ez/keymaps/steno/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/steno/keymap.c
@@ -228,7 +228,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/testing/keymap.c b/keyboards/ergodox_ez/keymaps/testing/keymap.c
index 5c1fc4af28..3aee63ddf1 100644
--- a/keyboards/ergodox_ez/keymaps/testing/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/testing/keymap.c
@@ -62,7 +62,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/keymaps/vim/keymap.c b/keyboards/ergodox_ez/keymaps/vim/keymap.c
index 948f2b4794..c1c037ef23 100644
--- a/keyboards/ergodox_ez/keymaps/vim/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/vim/keymap.c
@@ -330,7 +330,7 @@ void matrix_init_user(void) {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ergodox_ez/util/compile_keymap.py b/keyboards/ergodox_ez/util/compile_keymap.py
index b447ecaf5c..310512c920 100755
--- a/keyboards/ergodox_ez/util/compile_keymap.py
+++ b/keyboards/ergodox_ez/util/compile_keymap.py
@@ -27,29 +27,34 @@ PY2 = sys.version_info.major == 2
if PY2:
chr = unichr
-
KEYBOARD_LAYOUTS = {
# These map positions in the parsed layout to
# positions in the KEYMAP MATRIX
'ergodox_ez': [
- [ 0, 1, 2, 3, 4, 5, 6], [38, 39, 40, 41, 42, 43, 44],
- [ 7, 8, 9, 10, 11, 12, 13], [45, 46, 47, 48, 49, 50, 51],
- [14, 15, 16, 17, 18, 19 ], [ 52, 53, 54, 55, 56, 57],
- [20, 21, 22, 23, 24, 25, 26], [58, 59, 60, 61, 62, 63, 64],
- [27, 28, 29, 30, 31 ], [ 65, 66, 67, 68, 69],
- [ 32, 33], [70, 71 ],
- [ 34], [72 ],
- [ 35, 36, 37], [73, 74, 75 ],
+ [0, 1, 2, 3, 4, 5, 6],
+ [38, 39, 40, 41, 42, 43, 44],
+ [7, 8, 9, 10, 11, 12, 13],
+ [45, 46, 47, 48, 49, 50, 51],
+ [14, 15, 16, 17, 18, 19],
+ [52, 53, 54, 55, 56, 57],
+ [20, 21, 22, 23, 24, 25, 26],
+ [58, 59, 60, 61, 62, 63, 64],
+ [27, 28, 29, 30, 31],
+ [65, 66, 67, 68, 69],
+ [32, 33],
+ [70, 71],
+ [34],
+ [72],
+ [35, 36, 37],
+ [73, 74, 75],
]
}
-ROW_INDENTS = {
- 'ergodox_ez': [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 5, 0, 6, 0, 4, 0]
-}
+ROW_INDENTS = {'ergodox_ez': [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 5, 0, 6, 0, 4, 0]}
BLANK_LAYOUTS = [
-# Compact Layout
-"""
+ # Compact Layout
+ """
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
@@ -70,8 +75,8 @@ BLANK_LAYOUTS = [
'-----------------' '-----------------'
""",
-# Wide Layout
-"""
+ # Wide Layout
+ """
.---------------------------------------------. .---------------------------------------------.
| | | | | | | | ! | | | | | | |
!-------+-----+-----+-----+-----+-------------! !-------+-----+-----+-----+-----+-----+-------!
@@ -93,26 +98,22 @@ BLANK_LAYOUTS = [
""",
]
-
DEFAULT_CONFIG = {
- "keymaps_includes": [
- "keymap_common.h",
- ],
+ "keymaps_includes": ["keymap_common.h",],
'filler': "-+.'!:x",
'separator': "|",
'default_key_prefix': ["KC_"],
}
-
SECTIONS = [
'layout_config',
'layers',
]
-
# Markdown Parsing
-ONELINE_COMMENT_RE = re.compile(r"""
+ONELINE_COMMENT_RE = re.compile(
+ r"""
^ # comment must be at the start of the line
\s* # arbitrary whitespace
// # start of the comment
@@ -121,22 +122,26 @@ ONELINE_COMMENT_RE = re.compile(r"""
""", re.MULTILINE | re.VERBOSE
)
-INLINE_COMMENT_RE = re.compile(r"""
+INLINE_COMMENT_RE = re.compile(
+ r"""
([\,\"\[\]\{\}\d]) # anythig that might end a expression
\s+ # comment must be preceded by whitespace
// # start of the comment
\s # and succeded by whitespace
(?:[^\"\]\}\{\[]*) # the comment (except things which might be json)
$ # until the end of line
-""", re.MULTILINE | re.VERBOSE)
+""", re.MULTILINE | re.VERBOSE
+)
-TRAILING_COMMA_RE = re.compile(r"""
+TRAILING_COMMA_RE = re.compile(
+ r"""
, # the comma
(?:\s*) # arbitrary whitespace
$ # only works if the trailing comma is followed by newline
(\s*) # arbitrary whitespace
([\]\}]) # end of an array or object
-""", re.MULTILINE | re.VERBOSE)
+""", re.MULTILINE | re.VERBOSE
+)
def loads(raw_data):
@@ -178,9 +183,7 @@ def parse_config(path):
def end_section():
if section['start_line'] >= 0:
if section['name'] == 'layout_config':
- config.update(loads("\n".join(
- section['code_lines']
- )))
+ config.update(loads("\n".join(section['code_lines'])))
elif section['sub_name'].startswith('layer'):
layer_name = section['sub_name']
config['layer_lines'][layer_name] = section['code_lines']
@@ -215,6 +218,7 @@ def parse_config(path):
assert 'layout' in config
return config
+
# header file parsing
IF0_RE = re.compile(r"""
@@ -224,7 +228,6 @@ IF0_RE = re.compile(r"""
#endif
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
COMMENT_RE = re.compile(r"""
/\*
.*?
@@ -244,6 +247,7 @@ def regex_partial(re_str_fmt, flags):
def partial(*args, **kwargs):
re_str = re_str_fmt.format(*args, **kwargs)
return re.compile(re_str, flags)
+
return partial
@@ -256,7 +260,6 @@ KEYDEF_REP = regex_partial(r"""
) # capture group end
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
ENUM_RE = re.compile(r"""
(
enum
@@ -268,7 +271,6 @@ ENUM_RE = re.compile(r"""
) # capture group end
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
ENUM_KEY_REP = regex_partial(r"""
(
{} # the prefixes
@@ -309,14 +311,13 @@ def parse_valid_keys(config, out_path):
include_path = os.path.join(dirpath, include)
if os.path.exists(include_path):
header_data = read_header_file(include_path)
- valid_keycodes.update(
- parse_keydefs(config, header_data)
- )
+ valid_keycodes.update(parse_keydefs(config, header_data))
return valid_keycodes
# Keymap Parsing
+
def iter_raw_codes(layer_lines, filler, separator):
filler_re = re.compile("[" + filler + " ]")
for line in layer_lines:
@@ -346,28 +347,21 @@ LAYER_CHANGE_RE = re.compile(r"""
(DF|TG|MO)\(\d+\)
""", re.VERBOSE)
-
MACRO_RE = re.compile(r"""
M\(\w+\)
""", re.VERBOSE)
-
UNICODE_RE = re.compile(r"""
U[0-9A-F]{4}
""", re.VERBOSE)
-
NON_CODE = re.compile(r"""
^[^A-Z0-9_]$
""", re.VERBOSE)
def parse_uni_code(raw_code):
- macro_id = "UC_" + (
- unicodedata.name(raw_code)
- .replace(" ", "_")
- .replace("-", "_")
- )
+ macro_id = "UC_" + (unicodedata.name(raw_code).replace(" ", "_").replace("-", "_"))
code = "M({})".format(macro_id)
uc_hex = "{:04X}".format(ord(raw_code))
return code, macro_id, uc_hex
@@ -407,19 +401,13 @@ def parse_code(raw_code, key_prefixes, valid_keycodes):
def parse_keymap(config, key_indexes, layer_lines, valid_keycodes):
keymap = {}
- raw_codes = list(iter_raw_codes(
- layer_lines, config['filler'], config['separator']
- ))
+ raw_codes = list(iter_raw_codes(layer_lines, config['filler'], config['separator']))
indexed_codes = iter_indexed_codes(raw_codes, key_indexes)
key_prefixes = config['key_prefixes']
for raw_code, key_index, row_index in indexed_codes:
- code, macro_id, uc_hex = parse_code(
- raw_code, key_prefixes, valid_keycodes
- )
+ code, macro_id, uc_hex = parse_code(raw_code, key_prefixes, valid_keycodes)
# TODO: line numbers for invalid codes
- err_msg = "Could not parse key '{}' on row {}".format(
- raw_code, row_index
- )
+ err_msg = "Could not parse key '{}' on row {}".format(raw_code, row_index)
assert code is not None, err_msg
# print(repr(raw_code), repr(code), macro_id, uc_hex)
if macro_id:
@@ -432,17 +420,14 @@ def parse_keymap(config, key_indexes, layer_lines, valid_keycodes):
def parse_keymaps(config, valid_keycodes):
keymaps = collections.OrderedDict()
- key_indexes = config.get(
- 'key_indexes', KEYBOARD_LAYOUTS[config['layout']]
- )
+ key_indexes = config.get('key_indexes', KEYBOARD_LAYOUTS[config['layout']])
# TODO: maybe validate key_indexes
for layer_name, layer_lines, in config['layer_lines'].items():
- keymaps[layer_name] = parse_keymap(
- config, key_indexes, layer_lines, valid_keycodes
- )
+ keymaps[layer_name] = parse_keymap(config, key_indexes, layer_lines, valid_keycodes)
return keymaps
+
# keymap.c output
USERCODE = """
@@ -453,7 +438,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -572,7 +557,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {{
}};
"""
-
UNICODE_MACRO_TEMPLATE = """
case {macro_id}:
unicode_action_function(0x{hi:02x}, 0x{lo:02x});
@@ -584,9 +568,7 @@ def unicode_macro_cases(config):
for macro_id, uc_hex in config['unicode_macros'].items():
hi = int(uc_hex, 16) >> 8
lo = int(uc_hex, 16) & 0xFF
- yield UNICODE_MACRO_TEMPLATE.format(
- macro_id=macro_id, hi=hi, lo=lo
- )
+ yield UNICODE_MACRO_TEMPLATE.format(macro_id=macro_id, hi=hi, lo=lo)
def iter_keymap_lines(keymap, row_indents=None):
diff --git a/keyboards/ergoslab/keymaps/default/keymap.c b/keyboards/ergoslab/keymaps/default/keymap.c
index 59415618a8..093d586eba 100644
--- a/keyboards/ergoslab/keymaps/default/keymap.c
+++ b/keyboards/ergoslab/keymaps/default/keymap.c
@@ -51,7 +51,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef RGBLIGHT_ENABLE
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
switch (layer) {
case BASE:
rgblight_sethsv(HSV_ERGOSLAB_ORANGE);
diff --git a/keyboards/exclusive/e65/keymaps/masterzen/keymap.c b/keyboards/exclusive/e65/keymaps/masterzen/keymap.c
index 156832de4e..898a294f7e 100644
--- a/keyboards/exclusive/e65/keymaps/masterzen/keymap.c
+++ b/keyboards/exclusive/e65/keymaps/masterzen/keymap.c
@@ -102,7 +102,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
edit = false;
}
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _ADJUST:
temp_config.mode = rgblight_get_mode();
rgblight_mode_noeeprom(1);
diff --git a/keyboards/exclusive/e7v1/keymaps/masterzen/keymap.c b/keyboards/exclusive/e7v1/keymaps/masterzen/keymap.c
index 6987e84021..2793cffe93 100644
--- a/keyboards/exclusive/e7v1/keymaps/masterzen/keymap.c
+++ b/keyboards/exclusive/e7v1/keymaps/masterzen/keymap.c
@@ -121,7 +121,7 @@ layer_state_t layer_state_set_user(layer_state_t state)
edit = false;
}
- switch (biton32(state))
+ switch (get_highest_layer(state))
{
case _ADJUST:
mode = rgblight_get_mode();
diff --git a/keyboards/flehrad/bigswitch/keymaps/333fred/config.h b/keyboards/flehrad/bigswitch/keymaps/333fred/config.h
index 3273cc8db4..6e9219115c 100644
--- a/keyboards/flehrad/bigswitch/keymaps/333fred/config.h
+++ b/keyboards/flehrad/bigswitch/keymaps/333fred/config.h
@@ -24,3 +24,4 @@
// Long tapping term on the big switch, because it takes so long to press
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
diff --git a/keyboards/fractal/keymaps/default/keymap.c b/keyboards/fractal/keymaps/default/keymap.c
index 6b0a8cc18c..ded4890d8c 100644
--- a/keyboards/fractal/keymaps/default/keymap.c
+++ b/keyboards/fractal/keymaps/default/keymap.c
@@ -158,7 +158,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_ortho_5x12(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/gboards/gergo/keymaps/colemak/keymap.c b/keyboards/gboards/gergo/keymaps/colemak/keymap.c
index b2e79114f2..35b1e0b653 100644
--- a/keyboards/gboards/gergo/keymaps/colemak/keymap.c
+++ b/keyboards/gboards/gergo/keymaps/colemak/keymap.c
@@ -146,8 +146,8 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- //uint8_t layer = biton32(layer_state);
- biton32(layer_state);
+ //uint8_t layer = get_highest_layer(layer_state);
+ get_highest_layer(layer_state);
};
@@ -171,4 +171,3 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
return true;
};
-
diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h b/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h
index f66c334b85..e2c27583fa 100644
--- a/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h
+++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h
@@ -27,3 +27,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define COMBO_ALLOW_ACTION_KEYS
#define COMBO_VARIABLE_LEN
+
+#define TAPPING_TERM_PER_KEY
diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c b/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c
index e3b8944814..8b832cbac8 100644
--- a/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c
+++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c
@@ -199,5 +199,14 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
}
qk_tap_dance_action_t tap_dance_actions[] = {
- [GAME] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275)
+ [GAME] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset)
};
+
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
+ return 275;
+ default:
+ return TAPPING_TERM;
+ }
+}
diff --git a/keyboards/gh60/revc/keymaps/dbroqua/keymap.c b/keyboards/gh60/revc/keymaps/dbroqua/keymap.c
index 964f40f1c0..ffb87ef009 100644
--- a/keyboards/gh60/revc/keymaps/dbroqua/keymap.c
+++ b/keyboards/gh60/revc/keymaps/dbroqua/keymap.c
@@ -101,7 +101,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
void matrix_scan_user(void) {
- uint32_t layer = layer_state;
+ layer_state_t layer = layer_state;
if (layer & (1<<1)) {
gh60_fn_led_on();
@@ -120,4 +120,4 @@ void matrix_scan_user(void) {
} else {
gh60_esc_led_off();
}
-}; \ No newline at end of file
+};
diff --git a/keyboards/gh60/revc/keymaps/default/keymap.c b/keyboards/gh60/revc/keymaps/default/keymap.c
index a8fd4f3c22..4ebc71ff4b 100644
--- a/keyboards/gh60/revc/keymaps/default/keymap.c
+++ b/keyboards/gh60/revc/keymaps/default/keymap.c
@@ -31,7 +31,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void) {
//Layer LED indicators
- uint32_t layer = layer_state;
+ layer_state_t layer = layer_state;
if (layer & (1<<1)) {
gh60_wasd_leds_on();
diff --git a/keyboards/gh60/revc/keymaps/robotmaxtron/keymap.c b/keyboards/gh60/revc/keymaps/robotmaxtron/keymap.c
index b84e7564fc..77bf54de63 100644
--- a/keyboards/gh60/revc/keymaps/robotmaxtron/keymap.c
+++ b/keyboards/gh60/revc/keymaps/robotmaxtron/keymap.c
@@ -97,7 +97,7 @@ void matrix_scan_user(void) {
// Layer LED indicators
// ESC led on when in function layer, WASD cluster leds enabled when on arrow cluster
- uint32_t layer = layer_state;
+ layer_state_t layer = layer_state;
if (layer & (1<<1)) {
gh60_wasd_leds_on();
} else {
diff --git a/keyboards/gh60/satan/keymaps/addcninblue/keymap.c b/keyboards/gh60/satan/keymaps/addcninblue/keymap.c
index 5012fee56b..2b1a417fb5 100644
--- a/keyboards/gh60/satan/keymaps/addcninblue/keymap.c
+++ b/keyboards/gh60/satan/keymaps/addcninblue/keymap.c
@@ -177,7 +177,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (old_layer != layer) {
switch (layer) {
diff --git a/keyboards/glenpickle/chimera_ergo/keymaps/default/keymap.c b/keyboards/glenpickle/chimera_ergo/keymaps/default/keymap.c
index 51ab0e92cd..dd7e32f7dc 100644
--- a/keyboards/glenpickle/chimera_ergo/keymaps/default/keymap.c
+++ b/keyboards/glenpickle/chimera_ergo/keymaps/default/keymap.c
@@ -131,7 +131,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
diff --git a/keyboards/glenpickle/chimera_ls/keymaps/default/keymap.c b/keyboards/glenpickle/chimera_ls/keymaps/default/keymap.c
index 0affeef389..1ae70e6245 100644
--- a/keyboards/glenpickle/chimera_ls/keymaps/default/keymap.c
+++ b/keyboards/glenpickle/chimera_ls/keymaps/default/keymap.c
@@ -158,7 +158,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
diff --git a/keyboards/glenpickle/chimera_ortho/keymaps/default/keymap.c b/keyboards/glenpickle/chimera_ortho/keymaps/default/keymap.c
index 6a676493dd..bc783f540c 100644
--- a/keyboards/glenpickle/chimera_ortho/keymaps/default/keymap.c
+++ b/keyboards/glenpickle/chimera_ortho/keymaps/default/keymap.c
@@ -151,7 +151,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/ansi.c b/keyboards/gmmk/gmmk2/p96/ansi/ansi.c
new file mode 100644
index 0000000000..455a598982
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/ansi.c
@@ -0,0 +1,332 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "ansi.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
+/* Refer to IS31 manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, CS1_SW1, CS2_SW1, CS3_SW1}, // 0, k00, Esc
+ {0, CS1_SW2, CS2_SW2, CS3_SW2}, // 1, k10, F1
+ {0, CS1_SW3, CS2_SW3, CS3_SW3}, // 2, k20, F2
+ {0, CS1_SW4, CS2_SW4, CS3_SW4}, // 3, k30, F3
+ {0, CS1_SW5, CS2_SW5, CS3_SW5}, // 4, k40, F4
+ {0, CS1_SW6, CS2_SW6, CS3_SW6}, // 5, k50, F5
+ {0, CS1_SW7, CS2_SW7, CS3_SW7}, // 6, k60, F6
+ {0, CS1_SW8, CS2_SW8, CS3_SW8}, // 7, k70, F7
+ {0, CS1_SW9, CS2_SW9, CS3_SW9}, // 8, k80, F8
+ {0, CS1_SW10, CS2_SW10, CS3_SW10}, // 9, k90, F9
+ {0, CS1_SW11, CS2_SW11, CS3_SW11}, // 10, ka0, F10
+ {0, CS1_SW12, CS2_SW12, CS3_SW12}, // 11, kb0, F11
+ {1, CS1_SW1, CS2_SW1, CS3_SW1}, // 12, kc0, F12
+ {1, CS4_SW2, CS5_SW2, CS6_SW2}, // 13, kd0, Printscreen
+ {1, CS4_SW3, CS5_SW3, CS6_SW3}, // 14, k06, Delete
+ {1, CS1_SW2, CS2_SW2, CS3_SW2}, // 15, k16, Insert
+ {1, CS4_SW4, CS5_SW4, CS6_SW4}, // 16, k26, Page Up
+ {1, CS4_SW7, CS5_SW7, CS6_SW7}, // 17, k36, Page Down
+
+ {0, CS4_SW1, CS5_SW1, CS6_SW1}, // 18, k01, `
+ {0, CS4_SW2, CS5_SW2, CS6_SW2}, // 19, k11, 1
+ {0, CS4_SW3, CS5_SW3, CS6_SW3}, // 20, k21, 2
+ {0, CS4_SW4, CS5_SW4, CS6_SW4}, // 21, k31, 3
+ {0, CS4_SW5, CS5_SW5, CS6_SW5}, // 22, k41, 4
+ {0, CS4_SW6, CS5_SW6, CS6_SW6}, // 23, k51, 5
+ {0, CS4_SW7, CS5_SW7, CS6_SW7}, // 24, k61, 6
+ {0, CS4_SW8, CS5_SW8, CS6_SW8}, // 25, k71, 7
+ {0, CS4_SW9, CS5_SW9, CS6_SW9}, // 26, k81, 8
+ {0, CS4_SW10, CS5_SW10, CS6_SW10}, // 27, k91, 9
+ {0, CS4_SW11, CS5_SW11, CS6_SW11}, // 28, ka1, 0
+ {0, CS4_SW12, CS5_SW12, CS6_SW12}, // 29, kb1, -
+ {1, CS1_SW5, CS2_SW5, CS3_SW5}, // 30, kc1, =
+ {1, CS1_SW7, CS2_SW7, CS3_SW7}, // 31, kd1, Backspace
+ {1, CS7_SW1, CS8_SW1, CS9_SW1}, // 32, k46, Num Lock
+ {1, CS7_SW2, CS8_SW2, CS9_SW2}, // 33, k56, Num /
+ {1, CS7_SW3, CS8_SW3, CS9_SW3}, // 34, k66, Num *
+ {1, CS7_SW4, CS8_SW4, CS9_SW4}, // 35, k76, Num -
+
+ {0, CS7_SW1, CS8_SW1, CS9_SW1}, // 36, k02, Tab
+ {0, CS7_SW2, CS8_SW2, CS9_SW2}, // 37, k12, Q
+ {0, CS7_SW3, CS8_SW3, CS9_SW3}, // 38, k22, W
+ {0, CS7_SW4, CS8_SW4, CS9_SW4}, // 39, k32, E
+ {0, CS7_SW5, CS8_SW5, CS9_SW5}, // 40, k42, R
+ {0, CS7_SW6, CS8_SW6, CS9_SW6}, // 41, k52, T
+ {0, CS7_SW7, CS8_SW7, CS9_SW7}, // 42, k62, Y
+ {0, CS7_SW8, CS8_SW8, CS9_SW8}, // 43, k72, U
+ {0, CS7_SW9, CS8_SW9, CS9_SW9}, // 44, k82, I
+ {0, CS7_SW10, CS8_SW10, CS9_SW10}, // 45, k92, O
+ {0, CS7_SW11, CS8_SW11, CS9_SW11}, // 46, ka2, P
+ {0, CS7_SW12, CS8_SW12, CS9_SW12}, // 47, kb2, [
+ {1, CS1_SW8, CS2_SW8, CS3_SW8}, // 48, kc2, ]
+ {1, CS1_SW9, CS2_SW9, CS3_SW9}, // 49, kd3, "\\"
+ {1, CS7_SW5, CS8_SW5, CS9_SW5}, // 50, k86, Num 7
+ {1, CS7_SW6, CS8_SW6, CS9_SW6}, // 51, k96, Num 8
+ {1, CS7_SW7, CS8_SW7, CS9_SW7}, // 52, ka6, Num 9
+ {1, CS7_SW8, CS8_SW8, CS9_SW8}, // 53, kb6, Num +
+
+ {0, CS10_SW1, CS11_SW1, CS12_SW1}, // 54, k03, Caps Lock
+ {0, CS10_SW2, CS11_SW2, CS12_SW2}, // 55, k13, A
+ {0, CS10_SW3, CS11_SW3, CS12_SW3}, // 56, k23, S
+ {0, CS10_SW4, CS11_SW4, CS12_SW4}, // 57, k33, D
+ {0, CS10_SW5, CS11_SW5, CS12_SW5}, // 58, k43, F
+ {0, CS10_SW6, CS11_SW6, CS12_SW6}, // 59, k53, G
+ {0, CS10_SW7, CS11_SW7, CS12_SW7}, // 60, k63, H
+ {0, CS10_SW8, CS11_SW8, CS12_SW8}, // 61, k73, J
+ {0, CS10_SW9, CS11_SW9, CS12_SW9}, // 62, k83, K
+ {0, CS10_SW10, CS11_SW10, CS12_SW10}, // 63, k93, L
+ {0, CS10_SW11, CS11_SW11, CS12_SW11}, // 64, ka3, ;
+ {0, CS10_SW12, CS11_SW12, CS12_SW12}, // 65, kb3, '
+ {1, CS1_SW11, CS2_SW11, CS3_SW11}, // 66, kc3, Enter
+ {1, CS7_SW9, CS8_SW9, CS9_SW9}, // 67, ka7, Num 4
+ {1, CS7_SW10, CS8_SW10, CS9_SW10}, // 68, kb7, Num 5
+ {1, CS7_SW11, CS8_SW11, CS9_SW11}, // 69, kc7, Num 6
+
+ {0, CS13_SW1, CS14_SW1, CS15_SW1}, // 70, k04, Shift_L
+ {0, CS13_SW2, CS14_SW2, CS15_SW2}, // 71, k24, Z
+ {0, CS13_SW3, CS14_SW3, CS15_SW3}, // 72, k34, X
+ {0, CS13_SW4, CS14_SW4, CS15_SW4}, // 73, k44, C
+ {0, CS13_SW5, CS14_SW5, CS15_SW5}, // 74, k54, V
+ {0, CS13_SW6, CS14_SW6, CS15_SW6}, // 75, k64, B
+ {0, CS13_SW7, CS14_SW7, CS15_SW7}, // 76, k74, N
+ {0, CS13_SW8, CS14_SW8, CS15_SW8}, // 77, k84, M
+ {0, CS13_SW9, CS14_SW9, CS15_SW9}, // 78, k94, ,
+ {0, CS13_SW10, CS14_SW10, CS15_SW10}, // 79, ka4, .
+ {0, CS13_SW11, CS14_SW11, CS15_SW11}, // 80, kb4, /
+ {1, CS4_SW8, CS5_SW8, CS6_SW8}, // 81, kd4, Shift_R
+ {1, CS4_SW9, CS5_SW9, CS6_SW9}, // 82, k17, Up
+ {1, CS10_SW1, CS11_SW1, CS12_SW1}, // 83, k67, Num 1
+ {1, CS10_SW2, CS11_SW2, CS12_SW2}, // 84, k77, Num 2
+ {1, CS10_SW3, CS11_SW3, CS12_SW3}, // 85, k87, Num 3
+ {1, CS10_SW4, CS11_SW4, CS12_SW4}, // 86, k97, Enter_R
+
+ {0, CS16_SW1, CS17_SW1, CS18_SW1}, // 87, k05, Ctrl_L
+ {0, CS16_SW2, CS17_SW2, CS18_SW2}, // 88, k15, Win_L
+ {0, CS16_SW3, CS17_SW3, CS18_SW3}, // 89, k25, Alt_L
+ {0, CS16_SW6, CS17_SW6, CS18_SW6}, // 90, k65, Space
+ {0, CS16_SW9, CS17_SW9, CS18_SW9}, // 91, k95, Alt_R
+ {0, CS16_SW10, CS17_SW10, CS18_SW10}, // 92, ka5, FN
+ {0, CS16_SW12, CS17_SW12, CS18_SW12}, // 93, kc5, Ctrl_R
+ {1, CS4_SW10, CS5_SW10, CS6_SW10}, // 94, k07, Left
+ {1, CS4_SW11, CS5_SW11, CS6_SW11}, // 95, k27, Down
+ {1, CS10_SW5, CS11_SW5, CS12_SW5}, // 96, k37, Right
+ {1, CS10_SW6, CS11_SW6, CS12_SW6}, // 97, k47, Num 0
+ {1, CS10_SW7, CS11_SW7, CS12_SW7}, // 98, k57, Num .
+
+ {1, CS13_SW1, CS14_SW1, CS15_SW1}, // 101, LED 1
+ {1, CS13_SW2, CS14_SW2, CS15_SW2}, // 102, LED 2
+ {1, CS13_SW3, CS14_SW3, CS15_SW3}, // 103, LED 3
+ {1, CS13_SW4, CS14_SW4, CS15_SW4}, // 104, LED 4
+ {1, CS13_SW5, CS14_SW5, CS15_SW5}, // 105, LED 5
+ {1, CS13_SW6, CS14_SW6, CS15_SW6}, // 106, LED 6
+ {1, CS13_SW7, CS14_SW7, CS15_SW7}, // 107, LED 7
+ {1, CS13_SW8, CS14_SW8, CS15_SW8}, // 108, LED 8
+ {1, CS13_SW9, CS14_SW9, CS15_SW9}, // 109, LED 9
+ {1, CS13_SW10, CS14_SW10, CS15_SW10}, // 110, LED 10
+ {1, CS16_SW1, CS17_SW1, CS18_SW1}, // 111, LED 11
+ {1, CS16_SW2, CS17_SW2, CS18_SW2}, // 112, LED 12
+ {1, CS16_SW3, CS17_SW3, CS18_SW3}, // 113, LED 13
+ {1, CS16_SW4, CS17_SW4, CS18_SW4}, // 114, LED 14
+ {1, CS16_SW5, CS17_SW5, CS18_SW5}, // 115, LED 15
+ {1, CS16_SW6, CS17_SW6, CS18_SW6}, // 116, LED 16
+ {1, CS16_SW7, CS17_SW7, CS18_SW7}, // 117, LED 17
+ {1, CS16_SW8, CS17_SW8, CS18_SW8}, // 118, LED 18
+ {1, CS16_SW9, CS17_SW9, CS18_SW9}, // 119, LED 19
+ {1, CS16_SW10, CS17_SW10, CS18_SW10} // 120, LED 20
+};
+
+#define __ NO_LED
+
+led_config_t g_led_config = {{
+ { 0, 18, 36, 54, 70, 87, 14, 94},
+ { 1, 19, 37, 55, __, 88, 15, 82},
+ { 2, 20, 38, 56, 71, 89, 16, 95},
+ { 3, 21, 39, 57, 72, __, 17, 96},
+ { 4, 22, 40, 58, 73, __, 32, 97},
+ { 5, 23, 41, 59, 74, __, 33, 98},
+ { 6, 24, 42, 60, 75, 90, 34, 83},
+ { 7, 25, 43, 61, 76, __, 35, 84},
+ { 8, 26, 44, 62, 77, __, 50, 85},
+ { 9, 27, 45, 63, 78, 91, 51, 86},
+ {10, 28, 46, 64, 79, 92, 52, 67},
+ {11, 29, 47, 65, 80, __, 53, 68},
+ {12, 30, 48, __, __, 93, __, 69},
+ {13, 31, 49, 66, 81, __, __, __}
+}, {
+ { 11, 0}, // 0, k00, Esc
+ { 22, 0}, // 1, k10, F1
+ { 33, 0}, // 2, k20, F2
+ { 44, 0}, // 3, k30, F3
+ { 55, 0}, // 4, k40, F4
+ { 66, 0}, // 5, k50, F5
+ { 77, 0}, // 6, k60, F6
+ { 88, 0}, // 7, k70, F7
+ { 99, 0}, // 8, k80, F8
+ { 110, 0}, // 9, k90, F9
+ { 121, 0}, // 10, ka0, F10
+ { 132, 0}, // 11, kb0, F11
+ { 143, 0}, // 12, kc0, F12
+ { 154, 0}, // 13, kd0, Printscreen
+ { 165, 0}, // 14, k06, Delete
+ { 176, 0}, // 15, k16, Insert
+ { 187, 0}, // 16, k26, Page Up
+ { 198, 0}, // 17, k36, Page Down
+
+ { 11, 11}, // 18, k01, `
+ { 22, 11}, // 19, k11, 1
+ { 33, 11}, // 20, k21, 2
+ { 44, 11}, // 21, k31, 3
+ { 55, 11}, // 22, k41, 4
+ { 66, 11}, // 23, k51, 5
+ { 77, 11}, // 24, k61, 6
+ { 88, 11}, // 25, k71, 7
+ { 99, 11}, // 26, k81, 8
+ { 110, 11}, // 27, k91, 9
+ { 121, 11}, // 28, ka1, 0
+ { 132, 11}, // 29, kb1, -
+ { 143, 11}, // 30, kc1, =
+ { 154, 11}, // 31, kd1, Backspace
+ { 165, 11}, // 32, k46, Num Lock
+ { 176, 11}, // 33, k56, Num /
+ { 187, 11}, // 34, k66, Num *
+ { 198, 11}, // 35, k76, Num -
+
+ { 11, 22}, // 36, k02, Tab
+ { 22, 22}, // 37, k12, Q
+ { 33, 22}, // 38, k22, W
+ { 44, 22}, // 39, k32, E
+ { 55, 22}, // 40, k42, R
+ { 66, 22}, // 41, k52, T
+ { 77, 22}, // 42, k62, Y
+ { 88, 22}, // 43, k72, U
+ { 99, 22}, // 44, k82, I
+ { 110, 22}, // 45, k92, O
+ { 121, 22}, // 46, ka2, P
+ { 132, 22}, // 47, kb2, [
+ { 143, 22}, // 48, kc2, ]
+ { 154, 22}, // 49, kd3, "\\"
+ { 165, 22}, // 50, k86, Num 7
+ { 176, 22}, // 51, k96, Num 8
+ { 187, 22}, // 52, ka6, Num 9
+ { 198, 22}, // 53, kb6, Num +
+
+ { 11, 33}, // 54, k03, Caps Lock
+ { 22, 33}, // 55, k13, A
+ { 33, 33}, // 56, k23, S
+ { 44, 33}, // 57, k33, D
+ { 55, 33}, // 58, k43, F
+ { 66, 33}, // 59, k53, G
+ { 77, 33}, // 60, k63, H
+ { 88, 33}, // 61, k73, J
+ { 99, 33}, // 62, k83, K
+ { 110, 33}, // 63, k93, L
+ { 121, 33}, // 64, ka3, ;
+ { 132, 33}, // 65, kb3, '
+ { 154, 33}, // 66, kc3, Enter
+ { 165, 33}, // 67, ka7, Num 4
+ { 176, 33}, // 68, kb7, Num 5
+ { 187, 33}, // 69, kc7, Num 6
+
+ { 11, 44}, // 70, k04, Shift_L
+ { 33, 44}, // 71, k24, Z
+ { 44, 44}, // 72, k34, X
+ { 55, 44}, // 73, k44, C
+ { 66, 44}, // 74, k54, V
+ { 77, 44}, // 75, k64, B
+ { 88, 44}, // 76, k74, N
+ { 99, 44}, // 77, k84, M
+ { 110, 44}, // 78, k94, ,
+ { 121, 44}, // 79, ka4, .
+ { 132, 44}, // 80, kb4, /
+ { 143, 44}, // 81, kd4, Shift_R
+ { 154, 44}, // 82, k17, Up
+ { 165, 44}, // 83, k67, Num 1
+ { 176, 44}, // 84, k77, Num 2
+ { 187, 44}, // 85, k87, Num 3
+ { 198, 44}, // 86, k97, Enter_R
+
+ { 11, 55}, // 87, k05, Ctrl_L
+ { 22, 55}, // 88, k15, Win_L
+ { 33, 55}, // 89, k25, Alt_L
+ { 77, 55}, // 90, k65, Space
+ { 110, 55}, // 91, k95, Alt_R
+ { 121, 55}, // 92, ka5, FN
+ { 132, 55}, // 93, kc5, Ctrl_R
+ { 143, 55}, // 94, k07, Left
+ { 154, 55}, // 95, k27, Down
+ { 165, 55}, // 96, k37, Right
+ { 176, 55}, // 97, k47, Num 0
+ { 187, 55}, // 98, k57, Num .
+
+ { 0, 0}, // 101, LED 1
+ { 0, 6}, // 102, LED 2
+ { 0, 12}, // 103, LED 3
+ { 0, 18}, // 104, LED 4
+ { 0, 24}, // 105, LED 5
+ { 0, 30}, // 106, LED 6
+ { 0, 36}, // 107, LED 7
+ { 0, 42}, // 108, LED 8
+ { 0, 48}, // 109, LED 9
+ { 0, 54}, // 110, LED 10
+ { 209, 0}, // 111, LED 11
+ { 209, 6}, // 112, LED 12
+ { 209, 12}, // 113, LED 13
+ { 209, 18}, // 114, LED 14
+ { 209, 24}, // 115, LED 15
+ { 209, 30}, // 116, LED 16
+ { 209, 36}, // 117, LED 17
+ { 209, 42}, // 118, LED 18
+ { 209, 48}, // 119, LED 19
+ { 209, 54} // 120, LED 20
+}, {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+} };
+#endif
+
+#ifdef EEPROM_ENABLE
+
+#include "spi_master.h"
+
+void spi_init(void) {
+ static bool is_initialised = false;
+ if (!is_initialised) {
+ is_initialised = true;
+
+ // Try releasing special pins for a short time
+ setPinInput(SPI_SCK_PIN);
+ setPinInput(SPI_MOSI_PIN);
+ setPinInput(SPI_MISO_PIN);
+
+ chThdSleepMilliseconds(10);
+
+ palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST | PAL_WB32_CURRENT_LEVEL3);
+ palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ }
+}
+
+#endif
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/ansi.h b/keyboards/gmmk/gmmk2/p96/ansi/ansi.h
new file mode 100644
index 0000000000..d449a198df
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/ansi.h
@@ -0,0 +1,54 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "quantum.h"
+
+#define ___ KC_NO
+
+// ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Prt Del Ins PgUp PgDn
+// ` 1 2 3 4 5 6 7 8 9 0 - = BSpc Num / * -
+// Tab Q W E R T Y U I O P [ ] \\ 7 8 9 +
+// Caps A S D F G H J K L ; ' Enter 4 5 6 +
+// Sh_L Z X C V B N M , . / Sh_R Up 1 2 3 Enter
+// Ct_L Win_L Alt_L SPACE Alt_R FN Ct_R Left Down Right 0 . Enter
+
+// clang-format off
+#define LAYOUT( \
+ k00, k10, k20, k30, k40, k50, k60, k70, k80, k90, ka0, kb0, kc0, kd0, k06, k16, k26, k36,\
+ k01, k11, k21, k31, k41, k51, k61, k71, k81, k91, ka1, kb1, kc1, kd1, k46, k56, k66, k76,\
+ k02, k12, k22, k32, k42, k52, k62, k72, k82, k92, ka2, kb2, kc2, kd2, k86, k96, ka6, kb6,\
+ k03, k13, k23, k33, k43, k53, k63, k73, k83, k93, ka3, kb3, kd3, ka7, kb7, kc7, \
+ k04, k24, k34, k44, k54, k64, k74, k84, k94, ka4, kb4, kd4, k17, k67, k77, k87, k97,\
+ k05, k15, k25, k65, k95, ka5, kc5, k07, k27, k37, k47, k57 \
+)\
+{\
+ { k00, k01, k02, k03, k04, k05, k06, k07},\
+ { k10, k11, k12, k13, ___, k15, k16, k17},\
+ { k20, k21, k22, k23, k24, k25, k26, k27},\
+ { k30, k31, k32, k33, k34, ___, k36, k37},\
+ { k40, k41, k42, k43, k44, ___, k46, k47},\
+ { k50, k51, k52, k53, k54, ___, k56, k57},\
+ { k60, k61, k62, k63, k64, k65, k66, k67},\
+ { k70, k71, k72, k73, k74, ___, k76, k77},\
+ { k80, k81, k82, k83, k84, ___, k86, k87},\
+ { k90, k91, k92, k93, k94, k95, k96, k97},\
+ { ka0, ka1, ka2, ka3, ka4, ka5, ka6, ka7},\
+ { kb0, kb1, kb2, kb3, kb4, ___, kb6, kb7},\
+ { kc0, kc1, kc2, ___, ___, kc5, ___, kc7},\
+ { kd0, kd1, kd2, kd3, kd4, ___, ___, ___} \
+}
diff --git a/quantum/process_keycode/process_terminal_nop.h b/keyboards/gmmk/gmmk2/p96/ansi/config.h
index 36e25320c5..9f386a4211 100644
--- a/quantum/process_keycode/process_terminal_nop.h
+++ b/keyboards/gmmk/gmmk2/p96/ansi/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2017 Jack Humbert
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
*
* 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
@@ -16,7 +16,6 @@
#pragma once
-#include "quantum.h"
+#include "config_common.h"
-#define TERM_ON KC_NO
-#define TERM_OFF KC_NO
+#define PRODUCT_ID 0x504B
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/info.json b/keyboards/gmmk/gmmk2/p96/ansi/info.json
new file mode 100644
index 0000000000..1fe1530e4e
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/info.json
@@ -0,0 +1,119 @@
+{
+ "keyboard_name": "GMMK V2 96 ANSI",
+ "url": "http://www.pcgamingrace.com",
+ "maintainer": "GloriousThrall",
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ { "label": "ESC", "x": 0, "y": 0 },
+
+ { "label": "F1", "x": 1.25, "y": 0 },
+ { "label": "F2", "x": 2.25, "y": 0 },
+ { "label": "F3", "x": 3.25, "y": 0 },
+ { "label": "F4", "x": 4.25, "y": 0 },
+
+ { "label": "F5", "x": 5.5, "y": 0 },
+ { "label": "F6", "x": 6.5, "y": 0 },
+ { "label": "F7", "x": 7.5, "y": 0 },
+ { "label": "F8", "x": 8.5, "y": 0 },
+
+ { "label": "F9", "x": 9.75, "y": 0 },
+ { "label": "F10", "x": 10.75, "y": 0 },
+ { "label": "F11", "x": 11.75, "y": 0 },
+ { "label": "F12", "x": 12.75, "y": 0 },
+
+ { "label": "Printscreen", "x": 14, "y": 0 },
+ { "label": "Delete", "x": 15.5, "y": 0 },
+ { "label": "Insert", "x": 16.5, "y": 0 },
+ { "label": "Page Up", "x": 17.5, "y": 0 },
+ { "label": "Page Down", "x": 18.5, "y": 0 },
+
+ { "label": "`", "x": 0, "y": 1 },
+ { "label": "1", "x": 1, "y": 1 },
+ { "label": "2", "x": 2, "y": 1 },
+ { "label": "3", "x": 3, "y": 1 },
+ { "label": "4", "x": 4, "y": 1 },
+ { "label": "5", "x": 5, "y": 1 },
+ { "label": "6", "x": 6, "y": 1 },
+ { "label": "7", "x": 7, "y": 1 },
+ { "label": "8", "x": 8, "y": 1 },
+ { "label": "9", "x": 9, "y": 1 },
+ { "label": "0", "x": 10, "y": 1 },
+ { "label": "-", "x": 11, "y": 1 },
+ { "label": "=", "x": 12, "y": 1 },
+ { "label": "Backspace", "x": 13, "y": 1, "w": 2},
+ { "label": "Num Lock", "x": 15.5, "y": 1 },
+ { "label": "/", "x": 16.5, "y": 1 },
+ { "label": "*", "x": 17.5, "y": 1 },
+ { "label": "-", "x": 18.5, "y": 1 },
+
+ { "label": "Tab", "x": 0, "y": 2, "w": 1.5},
+ { "label": "Q", "x": 1.5, "y": 2 },
+ { "label": "W", "x": 2.5, "y": 2 },
+ { "label": "E", "x": 3.5, "y": 2 },
+ { "label": "R", "x": 4.5, "y": 2 },
+ { "label": "T", "x": 5.5, "y": 2 },
+ { "label": "Y", "x": 6.5, "y": 2 },
+ { "label": "U", "x": 7.5, "y": 2 },
+ { "label": "I", "x": 8.5, "y": 2 },
+ { "label": "O", "x": 9.5, "y": 2 },
+ { "label": "P", "x": 10.5, "y": 2 },
+ { "label": "[", "x": 11.5, "y": 2 },
+ { "label": "]", "x": 12.5, "y": 2 },
+ { "label": "\\", "x": 13.5, "y": 2 , "w": 1.25},
+ { "label": "7", "x": 15.5, "y": 2 },
+ { "label": "8", "x": 16.5, "y": 2 },
+ { "label": "9", "x": 17.5, "y": 2, "w": 1.5},
+ { "label": "+", "x": 18.5, "y": 2 ,"h":2},
+
+ { "label": "Caps Lock", "x": 0, "y": 3, "w": 1.75},
+ { "label": "A", "x": 1.75, "y": 3 },
+ { "label": "S", "x": 2.75, "y": 3 },
+ { "label": "D", "x": 3.75, "y": 3 },
+ { "label": "F", "x": 4.75, "y": 3 },
+ { "label": "G", "x": 5.75, "y": 3 },
+ { "label": "H", "x": 6.75, "y": 3 },
+ { "label": "J", "x": 7.75, "y": 3 },
+ { "label": "K", "x": 8.75, "y": 3 },
+ { "label": "L", "x": 9.75, "y": 3 },
+ { "label": ";", "x": 10.75, "y": 3 },
+ { "label": "'", "x": 11.75, "y": 3 },
+ { "label": "Enter", "x": 12.75, "y": 3, "w": 2.25 },
+ { "label": "4", "x": 15.5, "y": 3 },
+ { "label": "5", "x": 16.5, "y": 3 },
+ { "label": "6", "x": 17.5, "y": 3 },
+
+ { "label": "Shift", "x": 0, "y": 4, "w": 2.25},
+ { "label": "Z", "x": 2.25, "y": 4 },
+ { "label": "X", "x": 3.25, "y": 4 },
+ { "label": "C", "x": 4.25, "y": 4 },
+ { "label": "V", "x": 5.25, "y": 4 },
+ { "label": "B", "x": 6.25, "y": 4 },
+ { "label": "N", "x": 7.25, "y": 4 },
+ { "label": "M", "x": 8.25, "y": 4 },
+ { "label": ",", "x": 9.25, "y": 4 },
+ { "label": ".", "x": 10.25, "y": 4 },
+ { "label": "/", "x": 11.25, "y": 4 },
+ { "label": "Shift", "x": 12.25, "y": 4, "w": 1.75},
+ { "label": "Up", "x": 14.25, "y": 4 },
+ { "label": "1", "x": 15.5, "y": 4 },
+ { "label": "2", "x": 16.5, "y": 4 },
+ { "label": "3", "x": 17.5, "y": 4 },
+ { "label": "Enter", "x": 18.5, "y": 4 ,"h":2},
+
+ { "label": "Ctrl", "x": 0, "y": 5, "w": 1.25},
+ { "label": "Win", "x": 1.25, "y": 5, "w": 1.25},
+ { "label": "Alt", "x": 2.5, "y": 5, "w": 1.25},
+ { "label": "Space", "x": 3.75, "y": 5, "w": 6.25},
+ { "label": "Alt", "x": 10, "y": 5 },
+ { "label": "FN", "x": 11, "y": 5 },
+ { "label": "Ctrl", "x": 12, "y": 5 },
+ { "label": "Left", "x": 13.25, "y": 5 },
+ { "label": "Down", "x": 14.25, "y": 5 },
+ { "label": "Right", "x": 15.25, "y": 5 },
+ { "label": "0", "x": 16.5, "y": 5 },
+ { "label": ".", "x": 17.5, "y": 5 }
+ ]
+ }
+ }
+}
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/keymap.c b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/keymap.c
new file mode 100644
index 0000000000..7ea51338aa
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/keymap.c
@@ -0,0 +1,46 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 QMK_KEYBOARD_H
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+enum custom_layers {
+ _BL,
+ _FL,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap _BL: Base Layer (Default Layer)
+ */
+[_BL] = LAYOUT(
+ KC_GESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+
+ /* Keymap _FL: Function Layer
+ */
+[_FL] = LAYOUT(
+ RESET, KC_MYCM, KC_WHOM, KC_CALC, KC_MSEL, KC_MPRV, KC_MRWD, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLU, KC_VOLD, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_HUI, RGB_HUD, RGB_SPD, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, _______, _______, _______, _______,
+ _______, UC_M_WI, _______, _______, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_MOD, _______, _______)
+};
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/readme.md b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/readme.md
new file mode 100644
index 0000000000..fd8536d5de
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/default/readme.md
@@ -0,0 +1 @@
+# ANSI GMMKV2 96% Layout
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/config.h b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/config.h
new file mode 100644
index 0000000000..8fe214e8a7
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/config.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "config_common.h"
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
+#define STM32_USB_USE_OTG1 TRUE
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/keymap.c b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/keymap.c
new file mode 100644
index 0000000000..c61740193e
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/keymap.c
@@ -0,0 +1,53 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 QMK_KEYBOARD_H
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+enum custom_layers {
+ _BL,
+ _FL,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap _BL: Base Layer (Default Layer)
+ */
+[_BL] = LAYOUT(
+ KC_GESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+
+ /* Keymap _FL: Function Layer
+ */
+[_FL] = LAYOUT(
+ RESET, KC_MYCM, KC_WHOM, KC_CALC, KC_MSEL, KC_MPRV, KC_MRWD, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLU, KC_VOLD, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_HUI, RGB_HUD, RGB_SPD, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, _______, _______, _______, _______,
+ _______, UC_M_WI, _______, _______, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_MOD, _______, _______),
+[2] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+};
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/rules.mk b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/readme.md b/keyboards/gmmk/gmmk2/p96/ansi/readme.md
new file mode 100644
index 0000000000..0d01979bb3
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/readme.md
@@ -0,0 +1,23 @@
+# GMMK V2 96% (ANSI)
+
+A keyboard made and sold by Glorious LLC. Equipped with the WestBerry G7 ARM Cortex-M4 microcontroller
+
+* Keyboard Maintainer: [GloriousThrall](https://github.com/GloriousThrall)
+* Hardware Supported: GMMK V2
+* Hardware Availability: [GloriousPCGaming.com](https://www.pcgamingrace.com)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make gmmk/gmmk2/p96/ansi:default
+
+Flashing example for this keyboard:
+
+ make gmmk/gmmk2/p96/ansi:default:flash
+
+To reset the board into bootloader mode, do one of the following:
+
+* Hold the Reset switch mounted on the surface of the PCB while connecting the USB cable (remove the spacebar key and press and hold the pin on the right side)
+* Hold the Escape key while connecting the USB cable (also erases persistent settings)
+* Fn+Backslash will reset the board to bootloader mode if you have flashed the default QMK keymap
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/gmmk/gmmk2/p96/ansi/rules.mk b/keyboards/gmmk/gmmk2/p96/ansi/rules.mk
new file mode 100644
index 0000000000..ba78129495
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/ansi/rules.mk
@@ -0,0 +1,22 @@
+# MCU name
+MCU = WB32F3G71
+
+# Bootloader selection
+BOOTLOADER = wb32-dfu
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite.
+MOUSEKEY_ENABLE = yes # Mouse keys.
+EXTRAKEY_ENABLE = yes # Audio control and System control.
+CONSOLE_ENABLE = no # Console for debug.
+COMMAND_ENABLE = no # Commands for debug and configuration.
+NKRO_ENABLE = yes # Enable NKRO Rollover.
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality.
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow.
+AUDIO_ENABLE = no # Audio output.
+RGB_MATRIX_ENABLE = yes # Enable RGB matrix effects.
+RGB_MATRIX_DRIVER = AW20216 # Enable RGB matrix effects.
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = spi_flash
diff --git a/keyboards/gmmk/gmmk2/p96/config.h b/keyboards/gmmk/gmmk2/p96/config.h
new file mode 100644
index 0000000000..1b3a92dd53
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/config.h
@@ -0,0 +1,130 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "config_common.h"
+
+/* USB Device descriptor parameter */
+#define DEVICE_VER 0x0001
+#define VENDOR_ID 0x320F
+#define MANUFACTURER Glorious
+
+#define PRODUCT GMMK 2 96
+
+/* key matrix size */
+#define MATRIX_ROWS 14
+#define MATRIX_COLS 8
+
+#define MATRIX_ROW_PINS \
+ { B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13 }
+#define MATRIX_COL_PINS \
+ { A0, A1, A2, A3, A4, A8, A9, A10 }
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION COL2ROW
+
+/* Hold ESC on start up to clear EEPROM and boot into bootloader mode */
+#define BOOTMAGIC_LITE_ROW 0
+#define BOOTMAGIC_LITE_COLUMN 0
+
+#define TAP_CODE_DELAY 10
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+#define RGB_DISABLE_WHEN_USB_SUSPENDED
+
+/* External spi flash */
+#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN B14
+#define WEAR_LEVELING_BACKING_SIZE 2048
+
+/* SPI Config for LED Driver */
+#define SPI_DRIVER SPIDQ
+#define SPI_SCK_PIN A5
+#define SPI_MOSI_PIN A7
+#define SPI_MISO_PIN A6
+
+#define DRIVER_1_CS A15
+#define DRIVER_2_CS B15
+#define DRIVER_1_EN C13
+#define DRIVER_2_EN C13
+
+#define DRIVER_COUNT 2
+#define DRIVER_1_LED_TOTAL 66
+#define DRIVER_2_LED_TOTAL 54
+#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
+
+// RGB Matrix Animation modes. Explicitly enabled
+// For full list of effects, see:
+// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
+#define ENABLE_RGB_MATRIX_ALPHAS_MODS
+#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
+#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
+#define ENABLE_RGB_MATRIX_BREATHING
+#define ENABLE_RGB_MATRIX_BAND_SAT
+#define ENABLE_RGB_MATRIX_BAND_VAL
+#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
+#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
+#define ENABLE_RGB_MATRIX_CYCLE_ALL
+#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
+#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
+#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
+#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
+#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
+#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
+#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
+#define ENABLE_RGB_MATRIX_DUAL_BEACON
+#define ENABLE_RGB_MATRIX_RAINBOW_BEACON
+#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
+#define ENABLE_RGB_MATRIX_RAINDROPS
+#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
+#define ENABLE_RGB_MATRIX_HUE_BREATHING
+#define ENABLE_RGB_MATRIX_HUE_PENDULUM
+#define ENABLE_RGB_MATRIX_HUE_WAVE
+#define ENABLE_RGB_MATRIX_PIXEL_RAIN
+#define ENABLE_RGB_MATRIX_PIXEL_FLOW
+#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
+// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
+#define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+#define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
+#define ENABLE_RGB_MATRIX_SPLASH
+#define ENABLE_RGB_MATRIX_MULTISPLASH
+#define ENABLE_RGB_MATRIX_SOLID_SPLASH
+#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
+
+
+/* Send up to 4 key press events per scan */
+#define QMK_KEYS_PER_SCAN 4
+
+/* Set debounce time to 5ms */
+#define DEBOUNCE 5
+
+/* Force NKRO on boot up regardless of the setting saved in the EEPROM (uncomment to enable it) */
+// #define FORCE_NKRO
diff --git a/keyboards/gmmk/gmmk2/p96/halconf.h b/keyboards/gmmk/gmmk2/p96/halconf.h
new file mode 100644
index 0000000000..293d182917
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/halconf.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd
+ *
+ * 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/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/wb_support/gmmk2/halconf.h -r platforms/chibios/boards/common/configs/halconf.h`
+ */
+
+#pragma once
+
+#define HAL_USE_SPI TRUE
+#define SPI_USE_WAIT TRUE
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+
+#include_next <halconf.h>
+
diff --git a/keyboards/gmmk/gmmk2/p96/iso/config.h b/keyboards/gmmk/gmmk2/p96/iso/config.h
new file mode 100644
index 0000000000..97a391b09c
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/config.h
@@ -0,0 +1,21 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "config_common.h"
+
+#define PRODUCT_ID 0x505A
diff --git a/keyboards/gmmk/gmmk2/p96/iso/info.json b/keyboards/gmmk/gmmk2/p96/iso/info.json
new file mode 100644
index 0000000000..96e9f1312b
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/info.json
@@ -0,0 +1,120 @@
+{
+ "keyboard_name": "GMMK V2 96 ISO",
+ "url": "http://www.pcgamingrace.com",
+ "maintainer": "GloriousThrall",
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ { "label": "ESC", "x": 0, "y": 0 },
+
+ { "label": "F1", "x": 1.25, "y": 0 },
+ { "label": "F2", "x": 2.25, "y": 0 },
+ { "label": "F3", "x": 3.25, "y": 0 },
+ { "label": "F4", "x": 4.25, "y": 0 },
+
+ { "label": "F5", "x": 5.5, "y": 0 },
+ { "label": "F6", "x": 6.5, "y": 0 },
+ { "label": "F7", "x": 7.5, "y": 0 },
+ { "label": "F8", "x": 8.5, "y": 0 },
+
+ { "label": "F9", "x": 9.75, "y": 0 },
+ { "label": "F10", "x": 10.75, "y": 0 },
+ { "label": "F11", "x": 11.75, "y": 0 },
+ { "label": "F12", "x": 12.75, "y": 0 },
+
+ { "label": "Printscreen", "x": 14, "y": 0 },
+ { "label": "Delete", "x": 15.5, "y": 0 },
+ { "label": "Insert", "x": 16.5, "y": 0 },
+ { "label": "Page Up", "x": 17.5, "y": 0 },
+ { "label": "Page Down", "x": 18.5, "y": 0 },
+
+ { "label": "`", "x": 0, "y": 1 },
+ { "label": "1", "x": 1, "y": 1 },
+ { "label": "2", "x": 2, "y": 1 },
+ { "label": "3", "x": 3, "y": 1 },
+ { "label": "4", "x": 4, "y": 1 },
+ { "label": "5", "x": 5, "y": 1 },
+ { "label": "6", "x": 6, "y": 1 },
+ { "label": "7", "x": 7, "y": 1 },
+ { "label": "8", "x": 8, "y": 1 },
+ { "label": "9", "x": 9, "y": 1 },
+ { "label": "0", "x": 10, "y": 1 },
+ { "label": "-", "x": 11, "y": 1 },
+ { "label": "=", "x": 12, "y": 1 },
+ { "label": "Backspace", "x": 13, "y": 1, "w": 2},
+ { "label": "Num Lock", "x": 15.5, "y": 1 },
+ { "label": "/", "x": 16.5, "y": 1 },
+ { "label": "*", "x": 17.5, "y": 1 },
+ { "label": "-", "x": 18.5, "y": 1 },
+
+ { "label": "Tab", "x": 0, "y": 2, "w": 1.5},
+ { "label": "Q", "x": 1.5, "y": 2 },
+ { "label": "W", "x": 2.5, "y": 2 },
+ { "label": "E", "x": 3.5, "y": 2 },
+ { "label": "R", "x": 4.5, "y": 2 },
+ { "label": "T", "x": 5.5, "y": 2 },
+ { "label": "Y", "x": 6.5, "y": 2 },
+ { "label": "U", "x": 7.5, "y": 2 },
+ { "label": "I", "x": 8.5, "y": 2 },
+ { "label": "O", "x": 9.5, "y": 2 },
+ { "label": "P", "x": 10.5, "y": 2 },
+ { "label": "[", "x": 11.5, "y": 2 },
+ { "label": "]", "x": 12.5, "y": 2 },
+ { "label": "Enter", "x": 13.5, "y": 2 ,"h":2, "w": 1.25},
+ { "label": "7", "x": 15.5, "y": 2 },
+ { "label": "8", "x": 16.5, "y": 2 },
+ { "label": "9", "x": 17.5, "y": 2, "w": 1.5},
+ { "label": "+", "x": 18.5, "y": 2 ,"h":2},
+
+ { "label": "Caps Lock", "x": 0, "y": 3, "w": 1.75},
+ { "label": "A", "x": 1.75, "y": 3 },
+ { "label": "S", "x": 2.75, "y": 3 },
+ { "label": "D", "x": 3.75, "y": 3 },
+ { "label": "F", "x": 4.75, "y": 3 },
+ { "label": "G", "x": 5.75, "y": 3 },
+ { "label": "H", "x": 6.75, "y": 3 },
+ { "label": "J", "x": 7.75, "y": 3 },
+ { "label": "K", "x": 8.75, "y": 3 },
+ { "label": "L", "x": 9.75, "y": 3 },
+ { "label": ";", "x": 10.75, "y": 3 },
+ { "label": "'", "x": 11.75, "y": 3 },
+ { "label": "#", "x": 12.75, "y": 3 },
+ { "label": "4", "x": 15.5, "y": 3 },
+ { "label": "5", "x": 16.5, "y": 3 },
+ { "label": "6", "x": 17.5, "y": 3 },
+
+ { "label": "Shift", "x": 0, "y": 4, "w": 1.25},
+ { "label": "\\", "x": 1.25, "y": 4 },
+ { "label": "Z", "x": 2.25, "y": 4 },
+ { "label": "X", "x": 3.25, "y": 4 },
+ { "label": "C", "x": 4.25, "y": 4 },
+ { "label": "V", "x": 5.25, "y": 4 },
+ { "label": "B", "x": 6.25, "y": 4 },
+ { "label": "N", "x": 7.25, "y": 4 },
+ { "label": "M", "x": 8.25, "y": 4 },
+ { "label": ",", "x": 9.25, "y": 4 },
+ { "label": ".", "x": 10.25, "y": 4 },
+ { "label": "/", "x": 11.25, "y": 4 },
+ { "label": "Shift", "x": 12.25, "y": 4, "w": 1.75},
+ { "label": "Up", "x": 14.25, "y": 4 },
+ { "label": "1", "x": 15.5, "y": 4 },
+ { "label": "2", "x": 16.5, "y": 4 },
+ { "label": "3", "x": 17.5, "y": 4 },
+ { "label": "Enter", "x": 18.5, "y": 4 ,"h":2},
+
+ { "label": "Ctrl", "x": 0, "y": 5, "w": 1.25},
+ { "label": "Win", "x": 1.25, "y": 5, "w": 1.25},
+ { "label": "Alt", "x": 2.5, "y": 5, "w": 1.25},
+ { "label": "Space", "x": 3.75, "y": 5, "w": 6.25},
+ { "label": "Alt", "x": 10, "y": 5 },
+ { "label": "FN", "x": 11, "y": 5 },
+ { "label": "Ctrl", "x": 12, "y": 5 },
+ { "label": "Left", "x": 13.25, "y": 5 },
+ { "label": "Down", "x": 14.25, "y": 5 },
+ { "label": "Right", "x": 15.25, "y": 5 },
+ { "label": "0", "x": 16.5, "y": 5 },
+ { "label": ".", "x": 17.5, "y": 5 }
+ ]
+ }
+ }
+}
diff --git a/keyboards/gmmk/gmmk2/p96/iso/iso.c b/keyboards/gmmk/gmmk2/p96/iso/iso.c
new file mode 100644
index 0000000000..e1fee18079
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/iso.c
@@ -0,0 +1,328 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "iso.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
+/* Refer to IS31 manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, CS1_SW1, CS2_SW1, CS3_SW1}, // 0, k00, Esc
+ {0, CS1_SW2, CS2_SW2, CS3_SW2}, // 1, k10, F1
+ {0, CS1_SW3, CS2_SW3, CS3_SW3}, // 2, k20, F2
+ {0, CS1_SW4, CS2_SW4, CS3_SW4}, // 3, k30, F3
+ {0, CS1_SW5, CS2_SW5, CS3_SW5}, // 4, k40, F4
+ {0, CS1_SW6, CS2_SW6, CS3_SW6}, // 5, k50, F5
+ {0, CS1_SW7, CS2_SW7, CS3_SW7}, // 6, k60, F6
+ {0, CS1_SW8, CS2_SW8, CS3_SW8}, // 7, k70, F7
+ {0, CS1_SW9, CS2_SW9, CS3_SW9}, // 8, k80, F8
+ {0, CS1_SW10, CS2_SW10, CS3_SW10}, // 9, k90, F9
+ {0, CS1_SW11, CS2_SW11, CS3_SW11}, // 10, ka0, F10
+ {0, CS1_SW12, CS2_SW12, CS3_SW12}, // 11, kb0, F11
+ {1, CS1_SW1, CS2_SW1, CS3_SW1}, // 12, kc0, F12
+ {1, CS4_SW2, CS5_SW2, CS6_SW2}, // 13, kd0, Printscreen
+ {1, CS4_SW3, CS5_SW3, CS6_SW3}, // 14, k06, Delete
+ {1, CS1_SW2, CS2_SW2, CS3_SW2}, // 15, k16, Insert
+ {1, CS4_SW4, CS5_SW4, CS6_SW4}, // 16, k26, Page Up
+ {1, CS4_SW7, CS5_SW7, CS6_SW7}, // 17, k36, Page Down
+
+ {0, CS4_SW1, CS5_SW1, CS6_SW1}, // 18, k01, `
+ {0, CS4_SW2, CS5_SW2, CS6_SW2}, // 19, k11, 1
+ {0, CS4_SW3, CS5_SW3, CS6_SW3}, // 20, k21, 2
+ {0, CS4_SW4, CS5_SW4, CS6_SW4}, // 21, k31, 3
+ {0, CS4_SW5, CS5_SW5, CS6_SW5}, // 22, k41, 4
+ {0, CS4_SW6, CS5_SW6, CS6_SW6}, // 23, k51, 5
+ {0, CS4_SW7, CS5_SW7, CS6_SW7}, // 24, k61, 6
+ {0, CS4_SW8, CS5_SW8, CS6_SW8}, // 25, k71, 7
+ {0, CS4_SW9, CS5_SW9, CS6_SW9}, // 26, k81, 8
+ {0, CS4_SW10, CS5_SW10, CS6_SW10}, // 27, k91, 9
+ {0, CS4_SW11, CS5_SW11, CS6_SW11}, // 28, ka1, 0
+ {0, CS4_SW12, CS5_SW12, CS6_SW12}, // 29, kb1, -
+ {1, CS1_SW5, CS2_SW5, CS3_SW5}, // 30, kc1, =
+ {1, CS1_SW7, CS2_SW7, CS3_SW7}, // 31, kd1, Backspace
+ {1, CS7_SW1, CS8_SW1, CS9_SW1}, // 32, k46, Num Lock
+ {1, CS7_SW2, CS8_SW2, CS9_SW2}, // 33, k56, Num /
+ {1, CS7_SW3, CS8_SW3, CS9_SW3}, // 34, k66, Num *
+ {1, CS7_SW4, CS8_SW4, CS9_SW4}, // 35, k76, Num -
+
+ {0, CS7_SW1, CS8_SW1, CS9_SW1}, // 36, k02, Tab
+ {0, CS7_SW2, CS8_SW2, CS9_SW2}, // 37, k12, Q
+ {0, CS7_SW3, CS8_SW3, CS9_SW3}, // 38, k22, W
+ {0, CS7_SW4, CS8_SW4, CS9_SW4}, // 39, k32, E
+ {0, CS7_SW5, CS8_SW5, CS9_SW5}, // 40, k42, R
+ {0, CS7_SW6, CS8_SW6, CS9_SW6}, // 41, k52, T
+ {0, CS7_SW7, CS8_SW7, CS9_SW7}, // 42, k62, Y
+ {0, CS7_SW8, CS8_SW8, CS9_SW8}, // 43, k72, U
+ {0, CS7_SW9, CS8_SW9, CS9_SW9}, // 44, k82, I
+ {0, CS7_SW10, CS8_SW10, CS9_SW10}, // 45, k92, O
+ {0, CS7_SW11, CS8_SW11, CS9_SW11}, // 46, ka2, P
+ {0, CS7_SW12, CS8_SW12, CS9_SW12}, // 47, kb2, [
+ {1, CS1_SW8, CS2_SW8, CS3_SW8}, // 48, kc2, ]
+ {1, CS1_SW11, CS2_SW11, CS3_SW11}, // 49, kd3, Enter
+ {1, CS7_SW5, CS8_SW5, CS9_SW5}, // 50, k86, Num 7
+ {1, CS7_SW6, CS8_SW6, CS9_SW6}, // 51, k96, Num 8
+ {1, CS7_SW7, CS8_SW7, CS9_SW7}, // 52, ka6, Num 9
+ {1, CS7_SW8, CS8_SW8, CS9_SW8}, // 53, kb6, Num +
+
+ {0, CS10_SW1, CS11_SW1, CS12_SW1}, // 54, k03, Caps Lock
+ {0, CS10_SW2, CS11_SW2, CS12_SW2}, // 55, k13, A
+ {0, CS10_SW3, CS11_SW3, CS12_SW3}, // 56, k23, S
+ {0, CS10_SW4, CS11_SW4, CS12_SW4}, // 57, k33, D
+ {0, CS10_SW5, CS11_SW5, CS12_SW5}, // 58, k43, F
+ {0, CS10_SW6, CS11_SW6, CS12_SW6}, // 59, k53, G
+ {0, CS10_SW7, CS11_SW7, CS12_SW7}, // 60, k63, H
+ {0, CS10_SW8, CS11_SW8, CS12_SW8}, // 61, k73, J
+ {0, CS10_SW9, CS11_SW9, CS12_SW9}, // 62, k83, K
+ {0, CS10_SW10, CS11_SW10, CS12_SW10}, // 63, k93, L
+ {0, CS10_SW11, CS11_SW11, CS12_SW11}, // 64, ka3, ;
+ {0, CS10_SW12, CS11_SW12, CS12_SW12}, // 65, kb3, '
+ {1, CS1_SW10, CS2_SW10, CS3_SW10}, // 66, kc3, #
+ {1, CS7_SW9, CS8_SW9, CS9_SW9}, // 67, ka7, Num 4
+ {1, CS7_SW10, CS8_SW10, CS9_SW10}, // 68, kb7, Num 5
+ {1, CS7_SW11, CS8_SW11, CS9_SW11}, // 69, kc7, Num 6
+
+ {0, CS13_SW1, CS14_SW1, CS15_SW1}, // 70, k04, Shift_L
+ {0, CS13_SW12, CS14_SW12, CS15_SW12}, // 71, k14, "\\"
+ {0, CS13_SW2, CS14_SW2, CS15_SW2}, // 72, k24, Z
+ {0, CS13_SW3, CS14_SW3, CS15_SW3}, // 73, k34, X
+ {0, CS13_SW4, CS14_SW4, CS15_SW4}, // 74, k44, C
+ {0, CS13_SW5, CS14_SW5, CS15_SW5}, // 75, k54, V
+ {0, CS13_SW6, CS14_SW6, CS15_SW6}, // 76, k64, B
+ {0, CS13_SW7, CS14_SW7, CS15_SW7}, // 77, k74, N
+ {0, CS13_SW8, CS14_SW8, CS15_SW8}, // 78, k84, M
+ {0, CS13_SW9, CS14_SW9, CS15_SW9}, // 79, k94, ,
+ {0, CS13_SW10, CS14_SW10, CS15_SW10}, // 80, ka4, .
+ {0, CS13_SW11, CS14_SW11, CS15_SW11}, // 81, kb4, /
+ {1, CS4_SW8, CS5_SW8, CS6_SW8}, // 82, kd4, Shift_R
+ {1, CS4_SW9, CS5_SW9, CS6_SW9}, // 83, k17, Up
+ {1, CS10_SW1, CS11_SW1, CS12_SW1}, // 84, k67, Num 1
+ {1, CS10_SW2, CS11_SW2, CS12_SW2}, // 85, k77, Num 2
+ {1, CS10_SW3, CS11_SW3, CS12_SW3}, // 86, k87, Num 3
+ {1, CS10_SW4, CS11_SW4, CS12_SW4}, // 87, k97, Enter_R
+
+ {0, CS16_SW1, CS17_SW1, CS18_SW1}, // 88, k05, Ctrl_L
+ {0, CS16_SW2, CS17_SW2, CS18_SW2}, // 89, k15, Win_L
+ {0, CS16_SW3, CS17_SW3, CS18_SW3}, // 90, k25, Alt_L
+ {0, CS16_SW6, CS17_SW6, CS18_SW6}, // 91, k65, Space
+ {0, CS16_SW9, CS17_SW9, CS18_SW9}, // 92, k95, Alt_R
+ {0, CS16_SW10, CS17_SW10, CS18_SW10}, // 93, ka5, FN
+ {0, CS16_SW12, CS17_SW12, CS18_SW12}, // 94, kc5, Ctrl_R
+ {1, CS4_SW10, CS5_SW10, CS6_SW10}, // 95, k07, Left
+ {1, CS4_SW11, CS5_SW11, CS6_SW11}, // 96, k27, Down
+ {1, CS10_SW5, CS11_SW5, CS12_SW5}, // 97, k37, Right
+ {1, CS10_SW6, CS11_SW6, CS12_SW6}, // 98, k47, Num 0
+ {1, CS10_SW7, CS11_SW7, CS12_SW7}, // 99, k57, Num .
+
+ {1, CS13_SW1, CS14_SW1, CS15_SW1}, // 101, LED 1
+ {1, CS13_SW2, CS14_SW2, CS15_SW2}, // 102, LED 2
+ {1, CS13_SW3, CS14_SW3, CS15_SW3}, // 103, LED 3
+ {1, CS13_SW4, CS14_SW4, CS15_SW4}, // 104, LED 4
+ {1, CS13_SW5, CS14_SW5, CS15_SW5}, // 105, LED 5
+ {1, CS13_SW6, CS14_SW6, CS15_SW6}, // 106, LED 6
+ {1, CS13_SW7, CS14_SW7, CS15_SW7}, // 107, LED 7
+ {1, CS13_SW8, CS14_SW8, CS15_SW8}, // 108, LED 8
+ {1, CS13_SW9, CS14_SW9, CS15_SW9}, // 109, LED 9
+ {1, CS13_SW10, CS14_SW10, CS15_SW10}, // 110, LED 10
+ {1, CS16_SW1, CS17_SW1, CS18_SW1}, // 111, LED 11
+ {1, CS16_SW2, CS17_SW2, CS18_SW2}, // 112, LED 12
+ {1, CS16_SW3, CS17_SW3, CS18_SW3}, // 113, LED 13
+ {1, CS16_SW4, CS17_SW4, CS18_SW4}, // 114, LED 14
+ {1, CS16_SW5, CS17_SW5, CS18_SW5}, // 115, LED 15
+ {1, CS16_SW6, CS17_SW6, CS18_SW6}, // 116, LED 16
+ {1, CS16_SW7, CS17_SW7, CS18_SW7}, // 117, LED 17
+ {1, CS16_SW8, CS17_SW8, CS18_SW8}, // 118, LED 18
+ {1, CS16_SW9, CS17_SW9, CS18_SW9}, // 119, LED 19
+ {1, CS16_SW10, CS17_SW10, CS18_SW10} // 120, LED 20
+};
+
+#define __ NO_LED
+
+led_config_t g_led_config = {{
+ { 0, 18, 36, 54, 70, 88, 14, 95},
+ { 1, 19, 37, 55, 71, 89, 15, 83},
+ { 2, 20, 38, 56, 72, 90, 16, 96},
+ { 3, 21, 39, 57, 73, __, 17, 97},
+ { 4, 22, 40, 58, 74, __, 32, 98},
+ { 5, 23, 41, 59, 75, __, 33, 99},
+ { 6, 24, 42, 60, 76, 91, 34, 84},
+ { 7, 25, 43, 61, 77, __, 35, 85},
+ { 8, 26, 44, 62, 78, __, 50, 86},
+ { 9, 27, 45, 63, 79, 92, 51, 87},
+ {10, 28, 46, 64, 80, 93, 52, 67},
+ {11, 29, 47, 65, 81, __, 53, 68},
+ {12, 30, 48, 66, __, 94, __, 69},
+ {13, 31, __, 49, 82, __, __, __}
+}, {
+ { 11, 0}, // 0, k00, Esc
+ { 22, 0}, // 1, k10, F1
+ { 33, 0}, // 2, k20, F2
+ { 44, 0}, // 3, k30, F3
+ { 55, 0}, // 4, k40, F4
+ { 66, 0}, // 5, k50, F5
+ { 77, 0}, // 6, k60, F6
+ { 88, 0}, // 7, k70, F7
+ { 99, 0}, // 8, k80, F8
+ { 110, 0}, // 9, k90, F9
+ { 121, 0}, // 10, ka0, F10
+ { 132, 0}, // 11, kb0, F11
+ { 143, 0}, // 12, kc0, F12
+ { 154, 0}, // 13, kd0, Printscreen
+ { 165, 0}, // 14, k06, Delete
+ { 176, 0}, // 15, k16, Insert
+ { 187, 0}, // 16, k26, Page Up
+ { 198, 0}, // 17, k36, Page Down
+ { 11, 11}, // 18, k01, `
+ { 22, 11}, // 19, k11, 1
+ { 33, 11}, // 20, k21, 2
+ { 44, 11}, // 21, k31, 3
+ { 55, 11}, // 22, k41, 4
+ { 66, 11}, // 23, k51, 5
+ { 77, 11}, // 24, k61, 6
+ { 88, 11}, // 25, k71, 7
+ { 99, 11}, // 26, k81, 8
+ { 110, 11}, // 27, k91, 9
+ { 121, 11}, // 28, ka1, 0
+ { 132, 11}, // 29, kb1, -
+ { 143, 11}, // 30, kc1, =
+ { 154, 11}, // 31, kd1, Backspace
+ { 165, 11}, // 32, k46, Num Lock
+ { 176, 11}, // 33, k56, Num /
+ { 187, 11}, // 34, k66, Num *
+ { 198, 11}, // 35, k76, Num -
+ { 11, 22}, // 36, k02, Tab
+ { 22, 22}, // 37, k12, Q
+ { 33, 22}, // 38, k22, W
+ { 44, 22}, // 39, k32, E
+ { 55, 22}, // 40, k42, R
+ { 66, 22}, // 41, k52, T
+ { 77, 22}, // 42, k62, Y
+ { 88, 22}, // 43, k72, U
+ { 99, 22}, // 44, k82, I
+ { 110, 22}, // 45, k92, O
+ { 121, 22}, // 46, ka2, P
+ { 132, 22}, // 47, kb2, [
+ { 143, 22}, // 48, kc2, ]
+ { 154, 22}, // 49, kd3, Enter
+ { 165, 22}, // 50, k86, Num 7
+ { 176, 22}, // 51, k96, Num 8
+ { 187, 22}, // 52, ka6, Num 9
+ { 198, 22}, // 53, kb6, Num +
+ { 11, 33}, // 54, k03, Caps Lock
+ { 22, 33}, // 55, k13, A
+ { 33, 33}, // 56, k23, S
+ { 44, 33}, // 57, k33, D
+ { 55, 33}, // 58, k43, F
+ { 66, 33}, // 59, k53, G
+ { 77, 33}, // 60, k63, H
+ { 88, 33}, // 61, k73, J
+ { 99, 33}, // 62, k83, K
+ { 110, 33}, // 63, k93, L
+ { 121, 33}, // 64, ka3, ;
+ { 132, 33}, // 65, kb3, '
+ { 143, 33}, // 66, kc3, #
+ { 165, 33}, // 67, ka7, Num 4
+ { 176, 33}, // 68, kb7, Num 5
+ { 187, 33}, // 69, kc7, Num 6
+ { 11, 44}, // 70, k04, Shift_L
+ { 22, 44}, // 71, k14, "\\"
+ { 33, 44}, // 72, k24, Z
+ { 44, 44}, // 73, k34, X
+ { 55, 44}, // 74, k44, C
+ { 66, 44}, // 75, k54, V
+ { 77, 44}, // 76, k64, B
+ { 88, 44}, // 77, k74, N
+ { 99, 44}, // 78, k84, M
+ { 110, 44}, // 79, k94, ,
+ { 121, 44}, // 80, ka4, .
+ { 132, 44}, // 81, kb4, /
+ { 143, 44}, // 82, kd4, Shift_R
+ { 154, 44}, // 83, k17, Up
+ { 165, 44}, // 84, k67, Num 1
+ { 176, 44}, // 85, k77, Num 2
+ { 187, 44}, // 86, k87, Num 3
+ { 198, 44}, // 87, k97, Enter_R
+ { 11, 55}, // 88, k05, Ctrl_L
+ { 22, 55}, // 89, k15, Win_L
+ { 33, 55}, // 90, k25, Alt_L
+ { 77, 55}, // 91, k65, Space
+ { 110, 55}, // 92, k95, Alt_R
+ { 121, 55}, // 93, ka5, FN
+ { 132, 55}, // 94, kc5, Ctrl_R
+ { 143, 55}, // 95, k07, Left
+ { 154, 55}, // 96, k27, Down
+ { 165, 55}, // 97, k37, Right
+ { 176, 55}, // 98, k47, Num 0
+ { 187, 55}, // 99, k57, Num .
+ { 0, 0}, // 101, LED 1
+ { 0, 6}, // 102, LED 2
+ { 0, 12}, // 103, LED 3
+ { 0, 18}, // 104, LED 4
+ { 0, 24}, // 105, LED 5
+ { 0, 30}, // 106, LED 6
+ { 0, 36}, // 107, LED 7
+ { 0, 42}, // 108, LED 8
+ { 0, 48}, // 109, LED 9
+ { 0, 54}, // 110, LED 10
+ { 209, 0}, // 111, LED 11
+ { 209, 6}, // 112, LED 12
+ { 209, 12}, // 113, LED 13
+ { 209, 18}, // 114, LED 14
+ { 209, 24}, // 115, LED 15
+ { 209, 30}, // 116, LED 16
+ { 209, 36}, // 117, LED 17
+ { 209, 42}, // 118, LED 18
+ { 209, 48}, // 119, LED 19
+ { 209, 54} // 120, LED 20
+}, {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+} };
+#endif
+
+#ifdef EEPROM_ENABLE
+
+#include "spi_master.h"
+
+void spi_init(void) {
+ static bool is_initialised = false;
+ if (!is_initialised) {
+ is_initialised = true;
+
+ // Try releasing special pins for a short time
+ setPinInput(SPI_SCK_PIN);
+ setPinInput(SPI_MOSI_PIN);
+ setPinInput(SPI_MISO_PIN);
+
+ chThdSleepMilliseconds(10);
+
+ palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST | PAL_WB32_CURRENT_LEVEL3);
+ palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ }
+}
+
+#endif
diff --git a/keyboards/gmmk/gmmk2/p96/iso/iso.h b/keyboards/gmmk/gmmk2/p96/iso/iso.h
new file mode 100644
index 0000000000..f575befdc1
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/iso.h
@@ -0,0 +1,54 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "quantum.h"
+
+#define ___ KC_NO
+
+// ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 Prt Del Ins PgUp PgDn
+// ` 1 2 3 4 5 6 7 8 9 0 - = BSpc Num / * -
+// Tab Q W E R T Y U I O P [ ] Enter 7 8 9 +
+// Caps A S D F G H J K L ; ' # Enter 4 5 6 +
+// Sh_L \ Z X C V B N M , . / Sh_R Up 1 2 3 Enter
+// Ct_L Win_L Alt_L SPACE Alt_R FN Ct_R Left Down Right 0 . Enter
+
+// clang-format off
+#define LAYOUT( \
+ k00, k10, k20, k30, k40, k50, k60, k70, k80, k90, ka0, kb0, kc0, kd0, k06, k16, k26, k36,\
+ k01, k11, k21, k31, k41, k51, k61, k71, k81, k91, ka1, kb1, kc1, kd1, k46, k56, k66, k76,\
+ k02, k12, k22, k32, k42, k52, k62, k72, k82, k92, ka2, kb2, kc2, kd3, k86, k96, ka6, kb6,\
+ k03, k13, k23, k33, k43, k53, k63, k73, k83, k93, ka3, kb3, kc3, ka7, kb7, kc7, \
+ k04, k14, k24, k34, k44, k54, k64, k74, k84, k94, ka4, kb4, kd4, k17, k67, k77, k87, k97,\
+ k05, k15, k25, k65, k95, ka5, kc5, k07, k27, k37, k47, k57 \
+)\
+{\
+ { k00, k01, k02, k03, k04, k05, k06, k07},\
+ { k10, k11, k12, k13, k14, k15, k16, k17},\
+ { k20, k21, k22, k23, k24, k25, k26, k27},\
+ { k30, k31, k32, k33, k34, ___, k36, k37},\
+ { k40, k41, k42, k43, k44, ___, k46, k47},\
+ { k50, k51, k52, k53, k54, ___, k56, k57},\
+ { k60, k61, k62, k63, k64, k65, k66, k67},\
+ { k70, k71, k72, k73, k74, ___, k76, k77},\
+ { k80, k81, k82, k83, k84, ___, k86, k87},\
+ { k90, k91, k92, k93, k94, k95, k96, k97},\
+ { ka0, ka1, ka2, ka3, ka4, ka5, ka6, ka7},\
+ { kb0, kb1, kb2, kb3, kb4, ___, kb6, kb7},\
+ { kc0, kc1, kc2, kc3, ___, kc5, ___, kc7},\
+ { kd0, kd1, ___, kd3, kd4, ___, ___, ___} \
+}
diff --git a/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/keymap.c b/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/keymap.c
new file mode 100644
index 0000000000..1b41235e3c
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/keymap.c
@@ -0,0 +1,44 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 QMK_KEYBOARD_H
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+#define _BL 0
+#define _FL 1
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap _BL: Base Layer (Default Layer)
+ */
+[_BL] = LAYOUT(
+ KC_GESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_ENT, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+
+ /* Keymap _FL: Function Layer
+ */
+[_FL] = LAYOUT(
+ RESET, KC_MYCM, KC_WHOM, KC_CALC, KC_MSEL, KC_MPRV, KC_MRWD, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLU, KC_VOLD, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, RGB_SAI, RGB_SAD, RGB_SPD, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, _______, _______, _______, _______,
+ _______, UC_M_WI, _______, _______, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_MOD, _______, _______)
+};
diff --git a/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/readme.md b/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/readme.md
new file mode 100644
index 0000000000..b83b40941d
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/keymaps/default/readme.md
@@ -0,0 +1 @@
+# ISO GMMKV2 96% Layout
diff --git a/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/config.h b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/config.h
new file mode 100644
index 0000000000..8fe214e8a7
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/config.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "config_common.h"
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
+#define STM32_USB_USE_OTG1 TRUE
diff --git a/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/keymap.c b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/keymap.c
new file mode 100644
index 0000000000..0656566cf7
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/keymap.c
@@ -0,0 +1,51 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 QMK_KEYBOARD_H
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+#define _BL 0
+#define _FL 1
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap _BL: Base Layer (Default Layer)
+ */
+[_BL] = LAYOUT(
+ KC_GESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_ENT, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+
+ /* Keymap _FL: Function Layer
+ */
+[_FL] = LAYOUT(
+ RESET, KC_MYCM, KC_WHOM, KC_CALC, KC_MSEL, KC_MPRV, KC_MRWD, KC_MPLY, KC_MSTP, KC_MUTE, KC_VOLU, KC_VOLD, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, RGB_SAI, RGB_SAD, RGB_SPD, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, _______, _______, _______, _______,
+ _______, UC_M_WI, _______, _______, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_MOD, _______, _______),
+[2] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+};
diff --git a/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/rules.mk b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/gmmk/gmmk2/p96/iso/readme.md b/keyboards/gmmk/gmmk2/p96/iso/readme.md
new file mode 100644
index 0000000000..88a9211973
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/readme.md
@@ -0,0 +1,23 @@
+# GMMK V2 96% (ISO)
+
+A keyboard made and sold by Glorious LLC. Equipped with the WestBerry G7 ARM Cortex-M4 microcontroller
+
+* Keyboard Maintainer: [GloriousThrall](https://github.com/GloriousThrall)
+* Hardware Supported: GMMK V2
+* Hardware Availability: [GloriousPCGaming.com](https://www.pcgamingrace.com)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make gmmk/gmmk2/p96/iso:default
+
+Flashing example for this keyboard:
+
+ make gmmk/gmmk2/p96/iso:default:flash
+
+To reset the board into bootloader mode, do one of the following:
+
+* Hold the Reset switch mounted on the surface of the PCB while connecting the USB cable (remove the spacebar key and press and hold the pin on the right side)
+* Hold the Escape key while connecting the USB cable (also erases persistent settings)
+* Fn+Backslash will reset the board to bootloader mode if you have flashed the default QMK keymap
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/gmmk/gmmk2/p96/iso/rules.mk b/keyboards/gmmk/gmmk2/p96/iso/rules.mk
new file mode 100644
index 0000000000..ba78129495
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/iso/rules.mk
@@ -0,0 +1,22 @@
+# MCU name
+MCU = WB32F3G71
+
+# Bootloader selection
+BOOTLOADER = wb32-dfu
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite.
+MOUSEKEY_ENABLE = yes # Mouse keys.
+EXTRAKEY_ENABLE = yes # Audio control and System control.
+CONSOLE_ENABLE = no # Console for debug.
+COMMAND_ENABLE = no # Commands for debug and configuration.
+NKRO_ENABLE = yes # Enable NKRO Rollover.
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality.
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow.
+AUDIO_ENABLE = no # Audio output.
+RGB_MATRIX_ENABLE = yes # Enable RGB matrix effects.
+RGB_MATRIX_DRIVER = AW20216 # Enable RGB matrix effects.
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = spi_flash
diff --git a/keyboards/gmmk/gmmk2/p96/mcuconf.h b/keyboards/gmmk/gmmk2/p96/mcuconf.h
new file mode 100644
index 0000000000..c58ff986b1
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/mcuconf.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd
+ *
+ * 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/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/wb_support/gmmk2/mcuconf.h -r platforms/chibios/GENERIC_WB32_F3G71XX/configs/mcuconf.h`
+ */
+
+#pragma once
+
+#include_next <mcuconf.h>
+
+#undef WB32_SPI_USE_QSPI
+#define WB32_SPI_USE_QSPI TRUE
+
+#undef WB32_SPI_USE_SPIM2
+#define WB32_SPI_USE_SPIM2 TRUE
diff --git a/keyboards/gmmk/gmmk2/p96/p96.c b/keyboards/gmmk/gmmk2/p96/p96.c
new file mode 100644
index 0000000000..47edcfe1ad
--- /dev/null
+++ b/keyboards/gmmk/gmmk2/p96/p96.c
@@ -0,0 +1,17 @@
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
+ *
+ * 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 "p96.h"
diff --git a/quantum/process_keycode/process_terminal.h b/keyboards/gmmk/gmmk2/p96/p96.h
index 0159131e5b..e7b37d6816 100644
--- a/quantum/process_keycode/process_terminal.h
+++ b/keyboards/gmmk/gmmk2/p96/p96.h
@@ -1,4 +1,4 @@
-/* Copyright 2017 Jack Humbert
+/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>
*
* 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
@@ -18,7 +18,8 @@
#include "quantum.h"
-extern const char keycode_to_ascii_lut[58];
-extern const char shifted_keycode_to_ascii_lut[58];
-extern const char terminal_prompt[8];
-bool process_terminal(uint16_t keycode, keyrecord_t *record);
+#if defined(KEYBOARD_gmmk_gmmk2_p96_ansi)
+# include "ansi/ansi.h"
+#elif defined(KEYBOARD_gmmk_gmmk2_p96_iso)
+# include "iso/iso.h"
+#endif // GMMK V2 revisions
diff --git a/keyboards/gon/nerdtkl/keymaps/gam3cat/keymap.c b/keyboards/gon/nerdtkl/keymaps/gam3cat/keymap.c
index c4294c812e..bda83bb5da 100644
--- a/keyboards/gon/nerdtkl/keymaps/gam3cat/keymap.c
+++ b/keyboards/gon/nerdtkl/keymaps/gam3cat/keymap.c
@@ -241,7 +241,7 @@ void matrix_scan_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _BL:
custom_backlight_level(0);
break;
diff --git a/keyboards/handwired/ergocheap/config.h b/keyboards/handwired/ergocheap/config.h
index 26905e8cb3..00b9616e3e 100644
--- a/keyboards/handwired/ergocheap/config.h
+++ b/keyboards/handwired/ergocheap/config.h
@@ -47,6 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
/*
* Feature disable options
diff --git a/keyboards/handwired/frenchdev/keymaps/default/keymap.c b/keyboards/handwired/frenchdev/keymaps/default/keymap.c
index 2d917b412e..11463a0162 100644
--- a/keyboards/handwired/frenchdev/keymaps/default/keymap.c
+++ b/keyboards/handwired/frenchdev/keymaps/default/keymap.c
@@ -209,7 +209,7 @@ void press_underscore(void) {
uint8_t old_layer=_BASE;
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
frenchdev_led_1_off();
frenchdev_led_2_off();
diff --git a/keyboards/handwired/hillside/0_1/0_1.c b/keyboards/handwired/hillside/0_1/0_1.c
deleted file mode 100644
index ee096f18a7..0000000000
--- a/keyboards/handwired/hillside/0_1/0_1.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2021 Michael McCoyd (@mmccoyd)
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "0_1.h"
diff --git a/keyboards/handwired/hillside/0_1/keymaps/default/keymap.json b/keyboards/handwired/hillside/0_1/keymaps/default/keymap.json
deleted file mode 100644
index 5c672f8b8b..0000000000
--- a/keyboards/handwired/hillside/0_1/keymaps/default/keymap.json
+++ /dev/null
@@ -1,101 +0,0 @@
-{ "version": 1,
- "notes": "",
- "documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n",
- "keyboard": "handwired/hillside/0_1",
- "keymap": "default",
- "layout": "LAYOUT",
- "layers": [
- ["KC_TAB" , "KC_Q" , "KC_W" , "KC_E" , "KC_R" , "KC_T",
- "KC_Y" , "KC_U" , "KC_I" , "KC_O" , "KC_P" , "KC_BSPC",
-
- "KC_CAPS", "KC_A" , "KC_S" , "KC_D" , "KC_F" , "KC_G",
- "KC_H" , "KC_J" , "KC_K" , "KC_L" , "KC_SCLN" , "KC_ENT",
-
- "KC_LSFT", "KC_Z" , "KC_X" , "KC_C" , "KC_V" , "KC_B" , "KC_GRV",
- "KC_ESC" , "KC_N" , "KC_M" , "KC_COMM" , "KC_DOT" , "KC_SLSH" , "KC_RSFT",
-
- "KC_LCTL", "KC_LGUI" , "KC_LALT" , "MO(5)" , "MO(3)",
- "MO(4)" , "KC_SPC" , "KC_LALT" , "KC_RGUI" , "KC_QUOT"
-
- ],
- ["KC_TAB" , "KC_QUOT" , "KC_COMM" , "KC_DOT" , "KC_P" , "KC_Y",
- "KC_F" , "KC_G" , "KC_C" , "KC_R" , "KC_L" , "KC_BSPC",
-
- "KC_CAPS", "KC_A" , "KC_O" , "KC_E" , "KC_U" , "KC_I",
- "KC_D" , "KC_H" , "KC_T" , "KC_N" , "KC_S" , "KC_ENT",
-
- "KC_LSFT", "KC_SCLN" , "KC_Q" , "KC_J" , "KC_K" , "KC_X" , "KC_GRV",
- "KC_ESC" , "KC_B" , "KC_M" , "KC_W" , "KC_V" , "KC_Z" , "KC_RSFT",
-
- "KC_LCTL", "KC_LGUI" , "KC_LALT" , "MO(5)" , "MO(3)",
- "MO(4)" , "KC_SPC" , "KC_LALT" , "KC_RGUI" , "KC_SLSH"
-
- ],
- ["KC_TAB" , "KC_Q" , "KC_W" , "KC_F" , "KC_P" , "KC_B",
- "KC_J" , "KC_L" , "KC_U" , "KC_Y" , "KC_SCLN" , "KC_BSPC",
-
- "KC_CAPS", "KC_A" , "KC_R" , "KC_S" , "KC_T" , "KC_G",
- "KC_M" , "KC_N" , "KC_E" , "KC_I" , "KC_O" , "KC_ENT",
-
- "KC_LSFT", "KC_Z" , "KC_X" , "KC_C" , "KC_D" , "KC_V" , "KC_GRV",
- "KC_ESC" , "KC_K" , "KC_H" , "KC_COMM" , "KC_DOT" , "KC_SLSH" , "KC_RSFT",
-
- "KC_LCTL", "KC_LGUI" , "KC_LALT" , "MO(5)" , "MO(3)",
- "MO(4)" , "KC_SPC" , "KC_LALT" , "KC_RGUI" , "KC_QUOT"
-
- ],
- ["KC_NO" , "KC_INS" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_VOLU",
- "KC_PGUP", "KC_HOME" , "KC_NO" , "KC_END" , "KC_NO" , "KC_DEL",
-
- "KC_NO" , "KC_LGUI" , "KC_LALT" , "KC_LCTL" , "KC_LSFT" , "KC_VOLD",
- "KC_PGDN", "KC_LEFT" , "KC_UP" , "KC_RGHT" , "KC_NO" , "KC_TRNS",
-
- "KC_LSFT", "LCTL(KC_Z)" , "LCTL(KC_X)" , "LCTL(KC_C)", "LCTL(KC_V)" , "LCTL(KC_Y)", "KC_MUTE",
- "KC_ESC" , "OSM(MOD_RALT)", "LCTL(KC_LEFT)", "KC_DOWN" , "LCTL(KC_RGHT)", "KC_APP" , "KC_TRNS",
-
- "KC_TRNS", "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
- "MO(6)" , "KC_BSPC" , "KC_TRNS" , "KC_TRNS" , "KC_RCTL"
-
- ],
- ["KC_F11" , "KC_EXLM" , "KC_AT" , "KC_HASH" , "KC_DLR" , "KC_PERC",
- "KC_CIRC", "KC_AMPR" , "KC_ASTR" , "KC_LPRN" , "KC_RPRN" , "KC_TRNS",
-
- "KC_F12" , "KC_F1" , "KC_F2" , "KC_F3" , "KC_F4" , "KC_F5",
- "KC_PIPE", "KC_LSFT" , "KC_LCTL" , "KC_LALT" , "KC_LGUI" , "KC_TRNS",
-
- "KC_LSFT", "KC_F6" , "KC_F7" , "KC_F8" , "KC_F9" , "KC_F10" , "KC_PSCR",
- "KC_ESC" , "KC_BSLS" , "KC_LBRC" , "KC_RBRC" , "KC_LCBR" , "KC_RCBR" , "KC_TRNS",
-
- "KC_TRNS", "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "MO(6)",
- "KC_TRNS", "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_RCTL"
-
- ],
- ["KC_TAB" , "KC_MINS" , "KC_PLUS" , "KC_EQL" , "KC_SLSH" , "KC_ASTR",
- "KC_COMM", "KC_7" , "KC_8" , "KC_9" , "KC_NO" , "KC_TRNS",
-
- "KC_NO" , "KC_LGUI" , "KC_LALT" , "KC_LCTL" , "KC_LSFT" , "KC_NO",
- "KC_0" , "KC_1" , "KC_2" , "KC_3" , "KC_UNDS" , "KC_TRNS",
-
- "KC_TRNS", "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO",
- "KC_NO" , "KC_DOT" , "KC_4" , "KC_5" , "KC_6" , "KC_NO" , "KC_TRNS",
-
- "KC_TRNS", "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_NO",
- "KC_NO" , "KC_BSPC" , "KC_TRNS" , "KC_TRNS" , "KC_RCTL"
-
- ],
- ["KC_NO" , "DF(0)" , "DF(1)" , "DF(2)" , "AG_SWAP" , "AG_NORM",
- "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO",
-
- "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "CL_SWAP" , "CL_NORM",
- "RGB_MOD", "RGB_VAI" , "RGB_HUI" , "RGB_SAI" , "KC_NO" , "KC_NO",
-
- "QK_BOOT", "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO",
- "RGB_TOG", "RGB_RMOD" , "RGB_VAD" , "RGB_HUD" , "RGB_SAD" , "KC_NO" , "KC_NO",
-
- "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_TRNS",
- "KC_TRNS", "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO"
-
- ]
- ],
- "author": "@mmccoyd"
-}
diff --git a/keyboards/handwired/hillside/0_1/keymaps/default/readme.md b/keyboards/handwired/hillside/0_1/keymaps/default/readme.md
deleted file mode 100644
index 1890d5808c..0000000000
--- a/keyboards/handwired/hillside/0_1/keymaps/default/readme.md
+++ /dev/null
@@ -1,212 +0,0 @@
-# Default Keymap
-
-This default keymap follows many of the norms seen in non-programmable keyboards
- to ease initial use of the Hillside keyboard.
-It is a starting point for you to tweak over time to better suit _your_ preferences.
-You can easily customize it with the
- [QMK configurator](https://config.qmk.fm/#/hillside/0_1/LAYOUT)
- or with the [via firmware](https://caniusevia.com).
-
-Some of its key features are:
-- A mostly standard base layer with letters, some symbols, shift, modifier and delete keys
- in the expected places for non-programmable keyboards.
-- QWERTY, Colemak-DH and Dvorak options for the letter and symbol layout.
-- Comfortable modifier and function or symbol combinations on the non-base layers
- using modifiers on the home row of the navigation/edit, symbol/function and number-pad layers.
-- Word navigation and cut/copy/paste keys on the navigation layer.
-- A slightly optimized number pad with the more frequently used numbers on the home row.
-
-We've deliberately omitted some features:
-- Combos: because the online configuration tools do not handle them
- and because they would add to the initial learning curve,
- as helpful to a keymap as a light sprinkling of combos can be.
-- Multi-function mod-tap keys, auto shift capitalization and auto-exit modes such as CAPWORD or NUMWORD:
- as they may be too large a step for someone new to programmable keyboards.
-
-## Base Layer
-
-```
-| TAB | Q | W | E | R | T |---------------------------| Y | U | I | O | P | BKSPC |
-| CAPS | A | S | D | F | G |---------------------------| H | J | K | L | ; | ENTER |
-| SHIFT | Z | X | C | V | B | ~ |---------------| ESC | N | M | , | . | / | SHIFT |
---------------|CTRL |-----| GUI | ALT | Num | Nav |---| Sym |SPACE| ALT | GUI |-----| ' |--------------
-```
-
-The base layer provides a very standard key layout:
-
-- Return, Tab, backspace and shift keys in the outer columns.
-- Alt/option and win/command keys on both thumbs, with the location swappable for windows or mac.
-- A space key on the right thumb.
-
-The differences from a standard layout are:
-
-- There are three additional "shift" keys
- to access the navigation/editing, symbol/function, and number layers.
-- Esc and `~ are above the thumbs.
-- The Menu and AltGr keys are on a layer.
-
-The default layout is QWERTY with alternatives of Dvorak and Colemak-DH
-and the alt/option and win/command key locations are swappable for windows or mac.
-
-<details>
-<summary>Details of Dvorak and Colemak-DH</summary>
-The Dvorak and Colemak-DH base layers
- have identical non-alpha and non-symbol keys as the QWERTY base layer.
-In the Dvorak layout, the symbol key in the bottom row is the "/?" symbols
- so that the same 12 symbols are taken care of on the base layer.
-
-```
-Dvorak
-| TAB | ' | , | . | P | Y |---------------------------| F | G | C | R | L | BKSPC |
-| CAPS | A | O | E | U | I |---------------------------| D | H | T | N | S | ENTER |
-| SHIFT | ; | Q | J | K | X | ~ |---------------| ESC | B | M | W | V | Z | SHIFT |
---------------|CTRL |-----| GUI | ALT | Num | Nav |---| Sym |SPACE| ALT | GUI |-----| / |--------------
-
-Colemak-DH
-| TAB | Q | W | F | P | B |---------------------------| J | L | U | Y | ; | BKSPC |
-| CAPS | A | R | S | T | G |---------------------------| M | N | E | I | O | ENTER |
-| SHIFT | Z | X | C | D | V | ~ |---------------| ESC | K | H | , | . | / | SHIFT |
---------------|CTRL |-----| GUI | ALT | Num | Nav |---| Sym |SPACE| ALT | GUI |-----| ' |--------------
-```
-</details>
-
-## Navigation, Editing and Media Layer
-
-```
-| | INS | | | |VOL+ |---------------------------|PG_UP|HOME | | END| | DEL |
-| | GUI | ALT |CTRL |SHIFT|VOL- |---------------------------|PG_DN|LEFT | UP |RIGHT| | ENTER |
-| SHIFT |UNDO | CUT |COPY |PASTE|REDO |MUTE |---------------| ESC |RALT |WORDL|DOWN |WORDR|MENU | SHIFT |
---------------|CTRL |-----| GUI | ALT | Num | *** |---| Adj |BSPC | ALT | GUI |-----|CTRL |--------------
-```
-Holding down the Nav key accesses a navigation and editing layer:
-
-- Navigation arrows are on and below the right home row in a cross pattern.
- This feels more natural for a column stagger keyboard than an inverted T.
- The keys below that move left or right by a word.
- Home, end, and page up/down are beside them.
-- Modifiers in the left home row make it easier to use the arrows
- to select text with the shift key or move between desktops or tabs.
-- Editing keys appear on the lower left.
- The edit keys, modifiers and arrows make it easy to move text around without leaving the layer.
-- Delete is in the upper right, and a backspace key is on the thumb.
-- The base layer modifiers and escape are in the same spots as on the base layer,
- and a right-hand control key is added.
-- Media volume and play keys are on the left, accessible with one hand.
-- Menu and AltGr keys fill out the layer.
-- A few keys do nothing and are available for more user-specific needs.
-
-## Symbol and Function Layer
-
-```
-| F11 | ! | @ | # | $ | % |---------------------------| ^ | & | * | ( | ) | BSPC |
-| F12 | F1 | F2 | F3 | F4 | F5 |---------------------------| | |SHIFT|CTRL | ALT | GUI | ENTER |
-| SHIFT | F6 | F7 | F8 | F9 | F10 |PRTSC|---------------| ESC | \ | [ | ] | { | } | SHIFT |
---------------|CTRL |-----| GUI | ALT | Num | Adj |---| *** |SPACE| ALT | GUI |-----|CTRL |--------------
-```
-Holding down the Sym key accesses a layer of symbol and function keys:
-
-- The symbols usually found on the number keys are in the top row.
- If desired, you can use these positions for other things,
- as the symbols are also accessible from the number pad layer with the shift key.
-- Several more symbols appear on the right.
-- The function keys are on the left, beginning with two rows of five.
-- A row of modifiers in the home row allows the comfortable creation of any modifier and function key combination.
-- The base layer modifier and escape keys are still available, as is a right-hand control key.
-
-## Number Pad and Algebraic Layer
-```
-| TAB | - | + | = | / | * |---------------------------| . | 7 | 8 | 9 | | BSPC |
-| | GUI | ALT |CTRL |SHIFT| |---------------------------| 0 | 1 | 2 | 3 | _ | ENTER |
-| SHIFT | | | | | | |---------------| ESC | , | 4 | 5 | 6 | | SHIFT |
---------------|CTRL |-----| GUI | ALT | *** | |---| |BSPC | ALT | GUI |-----|CTRL |--------------
-```
-Holding down the Num key accesses a number pad and arithmetic symbols:
-
-- The number pad has the lowest numbers swapped into the home row as these are the most commonly used.
-- A row of modifiers in the home row allows the comfortable creation of any modifier and number combination.
-- Symbols commonly used with numbers fill out the layer
- and can be combined with the home row mods or the existing base layer modifiers on the right hand.
-- Several keys remain unused and await more user-specific needs.
-
-
-## Adjust Layer
-```
-| |QWERT|DVORK|COLMK|AG_SWAP|AG_NORM|-----------------------| | | | | | |
-| | | | |CTR_S|CTR_N|---------------------------|MOD+ |BRI+ |HUE+ |SAT+ | | |
-| QK_BOOT | | | | | | |--------------|RGBTOG|MOD- |BRI- |HUE- |SAT- | | |
---------------| |-----| | | | *** |---| *** | | | |-----| |--------------
-```
-Simultaneously holding down the Nav and Sym keys enables keys to adjust various keyboard settings:
-
-- The base layer can be set to QWERTY, Colemak-DH or Dvorak,
- but the keyboard reverts to QWERTY each time it is plugged in.
-- Alt/option and GUI/command can be swapped for mac users or restored to the windows norm.
- This setting persists over power loss.
-- The backlight LEDs can be enabled, disabled, and controlled.
- These settings also persist over power loss.
-
-
-## Make it Yours
-
-If you are coming from a traditional keyboard,
- with a row-staggered layout and a large set of physical keys,
- learning to use a column staggered (ergo) and layer-based keyboard,
- which uses layers instead of finger reaches to access numbers, symbols and functions,
- will be an adjustment for your muscle memory and your mental keyboard map.
-This default layout tries to simplify that adjustment by keeping things in the expected spots when possible.
-
-Yet this layout is only a decent compromise and is not optimal for each user.
-
-The online configurator makes it easy to tweak this layout to your needs.
-You can add additional layers or completely switch around what these do.
-
-Some changes you might consider making:
-- Put some of your most-used key combinations on the unused keys on the navigation layer.
-- If you are on a mac, switch the editing and word navigation keys from ctrl-x to cmd-x.
-- Change the shift keys to one-shot shift keys,
- where pressing and releasing them shifts the next key pressed.
- That is much easier on your hands than holding them down.
- Yet, they can still be held as usual if desired.
-- Instead of holding down the thumb key to keep the symbol layer active,
- you could use a one-shot layer key.
- One-shot modifiers are likely less stress on your hands and may even be faster.
- You would still be able to hold it down instead.
-- Instead of holding down the key for the number pad layer,
- you could make it a layer toggle, like caps lock is a capitalization toggle key.
-
-Here are some other keymaps for inspiration and ideas:
-- The [Ferris default](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/keymaps/default) uses more advanced features as it has far fewer keys to work with.
-- The [Miryoku](https://github.com/manna-harbour/miryoku/tree/master/docs/reference) keymap ensures that all modifiers are comfortably available with each character key.
-- The [Kyria default](https://github.com/qmk/qmk_firmware/tree/master/keyboards/splitkb/kyria/keymaps/default) has different keymap choices and a couple more keys.
-
-A good metaphor is to think of your keymap as a bonsai tree that you tweak slightly over time
- in response to ideas of how it might serve you better.
-
-
-## Why no keymap.c
-
-Via and the online configurator provide straightforward visual ways to work with a simple layout,
- and both use a .json keymap format.
-So this default ```keymap.json``` was created with the online configurator
- and formatted for easier reading and editing.
-
-If you wish, you can edit the ```keymap.json``` directly in a text editor, optionally use the below ```json2hill.py``` to restore the spacing, and then compile and flash it.
-
-Or, you can use the graphical configurator to edit the keymap. To do that:
-
-- Open the [QMK configurator](https://config.qmk.fm/#/handwired/hillside/LAYOUT)
-- Using the green up arrow button, load the keymap from ```qmk_firmware/keyboards/handwired/hillside/keymaps/default/keymap.json```
-- Make the changes you wish to the layout
-- Save the keymap using the green down arrow button.
-- Copy those changes back into your QMK repository and reformat for easy reading using the format script:
-```
-./keyboards/handwired/hillside/0_1/keymaps/json2hill.py --input <Your download directory>/default.json > ./keyboards/handwired/hillside/0_1/keymaps/default/keymap.json
-```
- You may need to make that script executable with ```chmod +x```. After your keymap is safely copied and formated, you may want to remove the keymap from your download directory so later downloads will automatically receive the same file name.
-
-After either method of editing, compile and flash the keymap as usual.
-
-You can combine a .json based keymap with more advanced features specified in .c files
- with a bit more complexity.
-For example, see
-[pierrec83's Kyria map](https://github.com/qmk/qmk_firmware/tree/master/keyboards/splitkb/kyria/keymaps/pierrec83).
diff --git a/keyboards/handwired/hillside/48/48.c b/keyboards/handwired/hillside/48/48.c
new file mode 100644
index 0000000000..a1d2c2f6e4
--- /dev/null
+++ b/keyboards/handwired/hillside/48/48.c
@@ -0,0 +1,4 @@
+// Copyright 2022 Michael McCoyd (@mmccoyd)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "48.h"
diff --git a/keyboards/handwired/hillside/0_1/0_1.h b/keyboards/handwired/hillside/48/48.h
index 0aeefdf630..65e1aaee30 100644
--- a/keyboards/handwired/hillside/0_1/0_1.h
+++ b/keyboards/handwired/hillside/48/48.h
@@ -1,4 +1,4 @@
-// Copyright 2021 Michael McCoyd (@mmccoyd)
+// Copyright 2022 Michael McCoyd (@mmccoyd)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/keyboards/handwired/hillside/0_1/config.h b/keyboards/handwired/hillside/48/config.h
index c83b23d0e8..c83b23d0e8 100644
--- a/keyboards/handwired/hillside/0_1/config.h
+++ b/keyboards/handwired/hillside/48/config.h
diff --git a/keyboards/handwired/hillside/0_1/info.json b/keyboards/handwired/hillside/48/info.json
index 7e128d5191..2325c2d8d3 100644
--- a/keyboards/handwired/hillside/0_1/info.json
+++ b/keyboards/handwired/hillside/48/info.json
@@ -2,7 +2,7 @@
"manufacturer": "mmccoyd",
"maintainer": "mmccoyd",
- "keyboard_name": "Hillside",
+ "keyboard_name": "Hillside48",
"url": "http://github.com/mmccoyd/hillside/",
"tags": ["split", "column stagger", "choc v1", "choc spaced" ],
@@ -44,7 +44,7 @@
"LAYOUT": {
"layout": [
- {"label": "Tab", "x": 0, "y": 0.93},
+ {"label": "`", "x": 0, "y": 0.93},
{"label": "Q", "x": 1, "y": 0.93},
{"label": "W", "x": 2, "y": 0.31},
{"label": "E", "x": 3, "y": 0},
@@ -59,7 +59,7 @@
{"label": "Backspace", "x": 14.5, "y": 0.93},
- {"label": "Ctrl", "x": 0, "y": 1.93},
+ {"label": "Tab", "x": 0, "y": 1.93},
{"label": "A", "x": 1, "y": 1.93},
{"label": "S", "x": 2, "y": 1.31},
{"label": "D", "x": 3, "y": 1},
@@ -71,7 +71,7 @@
{"label": "K", "x": 11.5, "y": 1},
{"label": "L", "x": 12.5, "y": 1.31},
{"label": ";", "x": 13.5, "y": 1.93},
- {"label": "'", "x": 14.5, "y": 1.93},
+ {"label": "Enter", "x": 14.5, "y": 1.93},
{"label": "Shift", "x": 0, "y": 2.93},
@@ -80,9 +80,9 @@
{"label": "C", "x": 3, "y": 2},
{"label": "V", "x": 4, "y": 2.28},
{"label": "B", "x": 5, "y": 2.42},
- {"label": "`", "x": 6, "y": 2.78},
+ {"label": "Esc", "x": 6, "y": 2.78},
- {"label": "Esc", "x": 8.5, "y": 2.78},
+ {"label": "Caps", "x": 8.5, "y": 2.78},
{"label": "N", "x": 9.5, "y": 2.42},
{"label": "M", "x": 10.5, "y": 2.28},
{"label": ",", "x": 11.5, "y": 2},
@@ -91,18 +91,18 @@
{"label": "Shift", "x": 14.5, "y": 2.93},
- {"label": "Enter", "x": 2, "y": 3.31},
+ {"label": "Ctrl", "x": 2, "y": 3.31},
{"label": "Gui", "x": 3.5, "y": 3.28},
{"label": "Alt", "x": 4.5, "y": 3.42},
- {"label": "Num", "x": 5.5, "y": 3.78},
- {"label": "Nav", "x": 6.5, "y": 4.14},
+ {"label": "Sym", "x": 5.5, "y": 3.78},
+ {"label": "Shift", "x": 6.5, "y": 4.14},
- {"label": "Sym", "x": 8, "y": 4.14},
+ {"label": "Nav", "x": 8, "y": 4.14},
{"label": "Space", "x": 9, "y": 3.78},
{"label": "Alt", "x": 10, "y": 3.42},
{"label": "Gui", "x": 11, "y": 3.28},
- {"label": "App", "x": 12.5, "y": 3.31}
+ {"label": "'", "x": 12.5, "y": 3.31}
]
}
}
diff --git a/keyboards/handwired/hillside/48/keymaps/default/config.h b/keyboards/handwired/hillside/48/keymaps/default/config.h
new file mode 100644
index 0000000000..1f71d42e67
--- /dev/null
+++ b/keyboards/handwired/hillside/48/keymaps/default/config.h
@@ -0,0 +1,9 @@
+// Copyright 2022 Michael McCoyd (@mmccoyd)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+// Some boards have issues detecting handedness using the vbus voltage,
+// such as Elite-C v3, but not v3.1 on, and apparently some ProMicro boards.
+// For those boards, use usb detection instead.
+// #define SPLIT_USB_DETECT
diff --git a/keyboards/handwired/hillside/48/keymaps/default/keymap.json b/keyboards/handwired/hillside/48/keymaps/default/keymap.json
new file mode 100644
index 0000000000..364ab726a0
--- /dev/null
+++ b/keyboards/handwired/hillside/48/keymaps/default/keymap.json
@@ -0,0 +1,88 @@
+{ "version": 1,
+ "notes": "",
+ "documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n",
+ "keyboard": "handwired/hillside/48",
+ "keymap": "default",
+ "layout": "LAYOUT",
+ "layers": [
+ ["KC_GRV" , "KC_Q" , "KC_W" , "KC_E" , "KC_R" , "KC_T",
+ "KC_Y" , "KC_U" , "KC_I" , "KC_O" , "KC_P" , "KC_BSPC",
+
+ "KC_TAB" , "KC_A" , "KC_S" , "KC_D" , "KC_F" , "KC_G",
+ "KC_H" , "KC_J" , "KC_K" , "KC_L" , "KC_SCLN" , "KC_ENT",
+
+ "KC_LSFT" , "KC_Z" , "KC_X" , "KC_C" , "KC_V" , "KC_B" , "KC_ESC",
+ "CAPS_WORD" , "KC_N" , "KC_M" , "KC_COMM", "KC_DOT" , "KC_SLSH" , "KC_RSFT",
+
+ "KC_LCTL" , "KC_LGUI" , "KC_LALT", "MO(3)" , "OSM(MOD_LSFT)",
+ "MO(4)" , "KC_SPC" , "KC_LALT", "KC_RGUI", "KC_QUOT"
+
+ ],
+ ["KC_GRV" , "KC_QUOT" , "KC_COMM", "KC_DOT" , "KC_P" , "KC_Y",
+ "KC_F" , "KC_G" , "KC_C" , "KC_R" , "KC_L" , "KC_BSPC",
+
+ "KC_TAB" , "KC_A" , "KC_O" , "KC_E" , "KC_U" , "KC_I",
+ "KC_D" , "KC_H" , "KC_T" , "KC_N" , "KC_S" , "KC_ENT",
+
+ "KC_LSFT" , "KC_SCLN" , "KC_Q" , "KC_J" , "KC_K" , "KC_X" , "KC_ESC",
+ "CAPS_WORD" , "KC_B" , "KC_M" , "KC_W" , "KC_V" , "KC_Z" , "KC_RSFT",
+
+ "KC_LCTL" , "KC_LGUI" , "KC_LALT", "MO(3)" , "OSM(MOD_LSFT)",
+ "MO(4)" , "KC_SPC" , "KC_LALT", "KC_RGUI", "KC_SLSH"
+
+ ],
+ ["KC_GRV" , "KC_Q" , "KC_W" , "KC_F" , "KC_P" , "KC_B",
+ "KC_J" , "KC_L" , "KC_U" , "KC_Y" , "KC_SCLN" , "KC_BSPC",
+
+ "KC_TAB" , "KC_A" , "KC_R" , "KC_S" , "KC_T" , "KC_G",
+ "KC_M" , "KC_N" , "KC_E" , "KC_I" , "KC_O" , "KC_ENT",
+
+ "KC_LSFT" , "KC_Z" , "KC_X" , "KC_C" , "KC_D" , "KC_V" , "KC_ESC",
+ "CAPS_WORD" , "KC_K" , "KC_H" , "KC_COMM", "KC_DOT" , "KC_SLSH" , "KC_RSFT",
+
+ "KC_LCTL" , "KC_LGUI" , "KC_LALT", "MO(3)" , "OSM(MOD_LSFT)",
+ "MO(4)" , "KC_SPC" , "KC_LALT", "KC_RGUI", "KC_QUOT"
+
+ ],
+ ["KC_HOME" , "KC_EXLM" , "KC_AT" , "KC_HASH", "KC_DLR" , "KC_PERC",
+ "KC_CIRC" , "KC_AMPR" , "KC_ASTR", "KC_LPRN", "KC_RPRN" , "KC_DEL",
+
+ "KC_END" , "KC_LGUI" , "KC_LALT", "KC_LCTL", "KC_LSFT" , "KC_INS",
+ "KC_LBRC" , "KC_RBRC" , "KC_MINS", "KC_EQL" , "KC_BSLS" , "KC_TRNS",
+
+ "KC_LSFT" , "KC_NO" , "KC_VOLD", "KC_MUTE", "KC_VOLU" , "KC_MPLY" , "OSM(MOD_RALT)",
+ "KC_APP" , "KC_LCBR" , "KC_RCBR", "KC_UNDS", "KC_PLUS" , "KC_PIPE" , "KC_TRNS",
+
+ "KC_TRNS" , "KC_TRNS" , "KC_TRNS", "KC_TRNS", "OSM(MOD_LSFT)",
+ "MO(5)" , "KC_TRNS" , "KC_TRNS", "KC_TRNS", "KC_RCTL"
+
+ ],
+ ["LCTL(KC_X)", "KC_1" , "KC_2" , "KC_3" , "KC_4" , "KC_5",
+ "KC_6" , "KC_7" , "KC_8" , "KC_9" , "KC_0" , "KC_BSPC",
+
+ "LCTL(KC_C)", "KC_LEFT" , "KC_DOWN", "KC_UP" , "KC_RGHT" , "LCTL(KC_V)",
+ "KC_PGUP" , "KC_RSFT" , "KC_RCTL", "KC_LALT", "KC_RGUI" , "KC_PGDN",
+
+ "KC_LSFT" , "KC_F1" , "KC_F2" , "KC_F3" , "KC_F4" , "KC_F5" , "LCTL(KC_Z)",
+ "LCTL(KC_Y)", "KC_F6" , "KC_F7" , "KC_F8" , "KC_F9" , "KC_F10" , "KC_TRNS",
+
+ "KC_TRNS" , "KC_TRNS" , "KC_TRNS", "MO(5)" , "KC_TRNS",
+ "KC_TRNS" , "KC_TRNS" , "KC_TRNS", "KC_TRNS", "KC_RCTL"
+
+ ],
+ ["KC_NO" , "DF(0)" , "DF(1)" , "DF(2)" , "AG_SWAP" , "CG_SWAP",
+ "KC_NO" , "KC_F11" , "KC_F12" , "KC_PSCR", "KC_NO" , "KC_NO",
+
+ "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO" , "AG_NORM" , "CG_NORM",
+ "RGB_MOD" , "RGB_VAI" , "RGB_HUI", "RGB_SAI", "KC_NO" , "KC_NO",
+
+ "KC_NO" , "KC_LGUI" , "KC_LALT", "KC_LCTL", "KC_LSFT" , "KC_NO" , "KC_NO",
+ "RGB_TOG" , "RGB_RMOD", "RGB_VAD", "RGB_HUD", "RGB_SAD" , "KC_NO" , "QK_BOOT",
+
+ "KC_NO" , "KC_NO" , "KC_NO" , "KC_TRNS", "KC_NO",
+ "KC_TRNS" , "KC_NO" , "KC_NO" , "KC_NO" , "KC_NO"
+
+ ]
+ ],
+ "author": "@mmccoyd"
+}
diff --git a/keyboards/handwired/hillside/48/keymaps/default/readme.md b/keyboards/handwired/hillside/48/keymaps/default/readme.md
new file mode 100644
index 0000000000..9bf294eff0
--- /dev/null
+++ b/keyboards/handwired/hillside/48/keymaps/default/readme.md
@@ -0,0 +1,159 @@
+# Default Keymap
+
+For easier initial use, this keymap follows the layout of more standard keyboards where possible. It is a starting point for you to tweak over time to suit your preferences better. You can easily customize it with the [QMK configurator](https://config.qmk.fm/#/handwired/hillside/48/LAYOUT).
+
+Some of its key features are:
+- Numbers and symbols along the top row of their layers for familiarity.
+- Comfortable combination of modifier and function or symbol on the non-base layers
+ using modifiers on the home row of the symbol and number/function layers.
+- A layer with both navigation and editing keys allows document editing without leaving the layer.
+- QWERTY, Colemak-DH and Dvorak base layer options.
+
+## Base Layer
+
+```
+| ` | Q | W | E | R | T |---------------------------| Y | U | I | O | P | BKSPC |
+| TAB | A | S | D | F | G |---------------------------| H | J | K | L | ; | ENTER |
+| SHIFT | Z | X | C | V | B | ESC |---------------|CAPS | N | M | , | . | / | SHIFT |
+--------------|CTRL |-----| GUI | ALT | Sym |SHIFT|---| Nav |SPACE| ALT | GUI |-----| ' |--------------
+```
+
+The base layer provides a very standard key layout with five differences:
+
+- Numbers, functions and most symbols are accessed with number and symbol shift keys.
+- Escape is on the left thumb.
+- The left thumb has a shift key that affects the next key pressed. So to get 'A', press and release the thumb shift key, press 'a'. You can also hold the key down, and it will work like a standard shift key. There are still standard shift keys at either end of the keyboard.
+- The right upper thumb turns on a mode that capitalizes all letters until something other than a letter, digit, dash, underscore, delete or backspace is typed. The caps word mode also times out after five seconds of no key presses.
+- The Menu and AltGr keys are on a layer.
+
+The default layout is QWERTY with alternatives of Dvorak and Colemak-DH, and the alt/option and the win/command key locations are swappable for windows or mac.
+
+
+<details>
+<summary>Details of Dvorak and Colemak-DH</summary>
+The Dvorak and Colemak-DH base layers
+ have identical non-alpha and non-symbol keys as the QWERTY base layer.
+
+```
+Dvorak
+| ` | ' | , | . | P | Y |---------------------------| F | G | C | R | L | BKSPC |
+| TAB | A | O | E | U | I |---------------------------| D | H | T | N | S | ENTER |
+| SHIFT | ; | Q | J | K | X | ESC |---------------|CAPS | B | M | W | V | Z | SHIFT |
+--------------|CTRL |-----| GUI | ALT | Sym |SHIFT|---| Nav |SPACE| ALT | GUI |-----| / |--------------
+
+Colemak-DH
+| ` | Q | W | F | P | B |---------------------------| J | L | U | Y | ; | BKSPC |
+| TAB | A | R | S | T | G |---------------------------| M | N | E | I | O | ENTER |
+| SHIFT | Z | X | C | D | V | ESC |---------------|CAPS | K | H | , | . | / | SHIFT |
+--------------|CTRL |-----| GUI | ALT | Sym |SHIFT|---| Nav |SPACE| ALT | GUI |-----| ' |--------------
+```
+</details>
+
+## Symbol and Media Layer
+
+```
+| HOME | ! | @ | # | $ | % |---------------------------| ^ | & | * | ( | ) | DEL |
+| END | GUI | ALT |CTRL |SHIFT| INS |---------------------------| [ | ] | - | = | \ | ENTER |
+| SHIFT | |VOL- |MUTE |VOL+ |PLAY |OSM ALT |------------|MENU | { | } | _ | + | | | SHIFT |
+--------------|CTRL |-----| GUI | ALT | *** |SHIFT|---| Adj |SPACE| ALT | GUI |-----|CTRL |--------------
+```
+Holding down the SYM key accesses the symbol layer:
+
+- The symbols not present on the base layer are along the top row and right side, similar to a full-size keyboard.
+- Duplicates of the modifier keys are along the left home keys. This allows a very comfortable combination of any set of modifiers plus a key on the right side of the board.
+- Forward delete is on the upper right, taking backspace's place.
+- The Windows OS application menu key is on the upper right thumb.
+- The AltGr key affects the next key pressed so that it can combine with a key on any layer. It changes the meaning of the next key pressed after the AltGr key is pressed and released. For example, to do AltGr-h: press SYM, press and release AltGr, release SYM, press and release h.
+
+## Navigation, Editing, Number and Function Layer
+
+```
+| CUT | 1 | 2 | 3 | 4 | 5 |---------------------------| 6 | 7 | 8 | 9 | 0 | BSPC |
+| COPY |LEFT |DOWN | UP |RIGHT|PASTE|---------------------------|PG_UP|SHIFT|CTRL | ALT | GUI | PG_DN |
+| SHIFT | F1 | F2 | F3 | F4 | F5 |UNDO |---------------|REDO | F6 | F7 | F8 | F9 | F10 | SHIFT |
+--------------|CTRL |-----| GUI | ALT | Adj |SHIFT|---| *** |SPACE| ALT | GUI |-----|CTRL |--------------
+```
+Holding down the Nav/Edit key accesses the navigation, editing, number and function layer:
+
+- Numbers are along the top row, and function keys are on the bottom row.
+- The arrow keys on the left can be combined with the home row modifiers on the right to easily move around and select text, which can then be cut, copied and pasted.
+
+
+## Adjust Layer
+```
+| |QWERT|DVORK|COLMK|AG_SWAP|CTR_SWAP|----------------------| | F11 | F12 |PR_SCR| | |
+| | | | |AG_NORM|CTR_NORM|----------------------|MOD+ |BRI+ |HUE+ |SAT+ | | |
+| | GUI | ALT |CTRL |SHIFT| | |--------------|RGBTOG|MOD- |BRI- |HUE- |SAT- | | BOOT |
+--------------| |-----| | | *** | |---| *** | | | |-----| |--------------
+```
+Simultaneously holding down the Sym and Nav/Edit keys enables keys to adjust keyboard settings:
+
+- The base layer can be set to QWERTY, Colemak-DH or Dvorak, although the keyboard reverts to QWERTY each time it is plugged in.
+- Alt/option and GUI/command can be swapped for mac users or restored to the windows norm.
+- The backlight LEDs can be enabled, disabled, and controlled.
+- BOOT allows loading new firmware, such as for keymap changes.
+- The remaining Fn keys are here with modifiers to use with them.
+
+## Make it Yours
+
+If you are coming from a traditional keyboard,
+ with a row-staggered layout and a large set of physical keys,
+ learning to use a column staggered (ergo) and layer-based keyboard,
+ which uses layers instead of finger reaches to access numbers, symbols and functions,
+ will be an adjustment for your muscle memory and your mental keyboard map.
+This default layout tries to simplify that adjustment by keeping things in the expected spots when possible.
+
+Yet this layout is only a decent compromise and is not optimal for each user.
+The online configurator makes it easy to tweak this layout to your needs.
+You can add additional layers or completely switch around what these do.
+
+A good metaphor is to think of your keymap as a bonsai tree that you tweak slightly over time
+ in response to ideas of how it might serve you better.
+
+Some changes you might consider making:
+- If you are on a mac, switch the editing keys from ctrl-x to cmd-x.
+- Change the shift keys to one-shot shift keys,
+ where pressing and releasing them shifts the next key pressed.
+ That is much easier on your hands than holding them down.
+ Yet, they can still be held as usual if desired.
+- Instead of holding down the thumb key to keep the symbol layer active,
+ you could use a one-shot layer key.
+ One-shot modifiers are likely less stress on your hands and may even be faster.
+ You would still be able to hold it down instead.
+
+Here are some other keymaps for inspiration and ideas:
+- The [Ferris default](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/keymaps/default) uses more advanced features as it has far fewer keys.
+- The [Miryoku](https://github.com/manna-harbour/miryoku/tree/master/docs/reference) keymap ensures that all modifiers are comfortably available with each character key.
+- The [Kyria default](https://github.com/qmk/qmk_firmware/tree/master/keyboards/splitkb/kyria/keymaps/default) has different keymap choices and a couple more keys.
+
+
+
+## Why no keymap.c
+
+The online configurator provides a straightforward visual way to work with a simple layout
+ and uses a .json keymap format.
+So this default ```keymap.json``` was created with the online configurator
+ and formatted for easier reading and editing.
+
+If you wish, you can edit the ```keymap.json``` directly in a text editor, optionally use the below ```json2hill48.py``` to restore the spacing, and then compile and flash it.
+
+Or, you can use the graphical configurator to edit the keymap. To do that:
+
+- Open the [QMK configurator](https://config.qmk.fm/#/handwired/hillside/48/LAYOUT)
+- Using the green up arrow button, load the keymap from ```qmk_firmware/keyboards/handwired/hillside/48/keymaps/default/keymap.json```
+- Make the changes you wish to the layout
+- Save the keymap using the green down arrow button.
+- Copy those changes back into your QMK repository and reformat for easy reading using the format script:
+```
+./keyboards/handwired/hillside/48/keymaps/json2hill48.py \
+ --input <Your download directory>/default.json \
+ > ./keyboards/handwired/hillside/48/keymaps/default/keymap.json
+```
+ You may need to make that script executable with ```chmod +x```. After your keymap is safely copied and formatted, you may want to remove the keymap from your download directory so later downloads will automatically receive the same file name.
+
+After either method of editing, compile and flash the keymap as usual.
+
+You can combine a .json based keymap with more advanced features specified in .c files
+ with a bit more complexity.
+For example, see
+[pierrec83's Kyria map](https://github.com/qmk/qmk_firmware/tree/master/keyboards/splitkb/kyria/keymaps/pierrec83). \ No newline at end of file
diff --git a/keyboards/handwired/hillside/48/keymaps/default/rules.mk b/keyboards/handwired/hillside/48/keymaps/default/rules.mk
new file mode 100644
index 0000000000..4711d2ff74
--- /dev/null
+++ b/keyboards/handwired/hillside/48/keymaps/default/rules.mk
@@ -0,0 +1 @@
+CAPS_WORD_ENABLE = yes
diff --git a/keyboards/handwired/hillside/0_1/keymaps/json2hill.py b/keyboards/handwired/hillside/48/keymaps/json2hill48.py
index a9971c0d78..c4fb5b1037 100755
--- a/keyboards/handwired/hillside/0_1/keymaps/json2hill.py
+++ b/keyboards/handwired/hillside/48/keymaps/json2hill48.py
@@ -1,9 +1,9 @@
#!/usr/bin/env python3
-# Copyright 2020-2021 Pierre Viseu Chevalier, Michael McCoyd (@pierrechevalier83, @mmccoyd)
+# Copyright 2020-2022 Pierre Viseu Chevalier, Michael McCoyd (@pierrechevalier83, @mmccoyd)
# SPDX-License-Identifier: GPL-2.0-or-later
-"""Pretty print keymap json in more readable row/side organized format."""
+"""Pretty print keymap json in more readable row/side organized format, based on ROW_SIZES."""
import argparse
import json
@@ -28,14 +28,20 @@ For example, for one layer:
],
"""
-indent_level=4 # number of spaces of initial indent per output line
+# The structure of the keymap. Tuples describing row sizes.
+# (<Keys upto and including (one-indexed) keycount x> <are in half rows of y>)
+ROW_SIZES = [(24, 6),
+ (38, 7),
+ (48, 5),
+ ]
+
+###
+### Below here should not need to changed for different keyboards
+###
-# The structure of the keymap
-# [[Endpoint of sides with identical widths, side width, mapping to column],...]
-KEYS_TO_COL = [[24, 6, lambda n: n % 6],
- [38, 7, lambda n: (n - 24) % 7],
- [48, 5, lambda n: (n - 38) % 5]]
-LAST_KEY = KEYS_TO_COL[-1][0] - 1
+LAST_KEY = ROW_SIZES[-1][0] - 1
+
+indent_level=4 # number of spaces of initial indent per output line
def parse_cli():
parser = argparse.ArgumentParser(description='Hillside keymap formatter')
@@ -54,12 +60,15 @@ class Column(NamedTuple):
def get_col(key_index):
"""Return Column for key_index."""
- for keys, num_cols, col_fn in KEYS_TO_COL:
- if key_index < keys:
- col_num = col_fn(key_index)
- return Column(col_num,
+ index_prior = 0 # index of last key in rows of the prior size
+ for keys_upto, num_cols in ROW_SIZES: # For row sizes from top
+ if key_index < keys_upto: # Find range key_index is in
+ col_num = (key_index - index_prior) % num_cols
+ return Column(col_num, # Return column plus side and row ends flags
ends_side=col_num == num_cols - 1,
- ends_row=(keys - 1 - key_index) % (2 * num_cols) == 0)
+ ends_row=(keys_upto - 1 - key_index) %
+ (2 * num_cols) == 0)
+ index_prior = keys_upto # Big O: row ranges * keys, but range is small
def format_layers(layers):
formatted = indent_level * " " + "\"layers\": [\n"
@@ -133,4 +142,5 @@ def main():
keymap_json = json.loads(args.input.read())
print(format_keymap(keymap_json))
-main()
+if __name__ == "__main__":
+ main()
diff --git a/keyboards/handwired/hillside/0_1/keymaps/via/keymap.json b/keyboards/handwired/hillside/48/keymaps/via/keymap.json
index a015f0241c..b4848a72ee 100644
--- a/keyboards/handwired/hillside/0_1/keymaps/via/keymap.json
+++ b/keyboards/handwired/hillside/48/keymaps/via/keymap.json
@@ -1,6 +1,6 @@
{ "version": 1,
"notes": "",
- "keyboard": "handwired/hillside/0_1",
+ "keyboard": "handwired/hillside/48",
"keymap": "via",
"layout": "LAYOUT",
"layers": [
diff --git a/keyboards/handwired/hillside/0_1/readme.md b/keyboards/handwired/hillside/48/readme.md
index f1ff0f8506..ec6dffc0f2 100644
--- a/keyboards/handwired/hillside/0_1/readme.md
+++ b/keyboards/handwired/hillside/48/readme.md
@@ -2,7 +2,7 @@
![hillside](https://imgur.com/XW0rX13.png)
-[Hillside](https://github.com/mmccoyd/hillside)
+[Hillside 48](https://github.com/mmccoyd/hillside)
is a split ergonomic keyboard
with 3x6+4+2 choc-spaced keys with aggressive column stagger,
a longer thumb arc and a breakoff outer-pinky column.
@@ -13,11 +13,11 @@
Make example for this keyboard (after setting up your build environment):
- make handwired/hillside/0_1:default
+ make handwired/hillside/48:default
Flashing example for this keyboard:
- make handwired/hillside/0_1:default:flash
+ make handwired/hillside/48:default:flash
## Bootloader
diff --git a/keyboards/handwired/hillside/0_1/rules.mk b/keyboards/handwired/hillside/48/rules.mk
index 2501147ea8..2501147ea8 100644
--- a/keyboards/handwired/hillside/0_1/rules.mk
+++ b/keyboards/handwired/hillside/48/rules.mk
diff --git a/keyboards/handwired/kbod/keymaps/default/keymap.c b/keyboards/handwired/kbod/keymaps/default/keymap.c
index 333f8a769f..0ffc3e9d97 100644
--- a/keyboards/handwired/kbod/keymaps/default/keymap.c
+++ b/keyboards/handwired/kbod/keymaps/default/keymap.c
@@ -89,7 +89,7 @@ void matrix_init_user(void) {
}
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (layer) {
PORTC |= _BV(PC7);
} else {
diff --git a/keyboards/handwired/onekey/config.h b/keyboards/handwired/onekey/config.h
index f491d4d393..88c15806ce 100644
--- a/keyboards/handwired/onekey/config.h
+++ b/keyboards/handwired/onekey/config.h
@@ -42,6 +42,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LOCKING_RESYNC_ENABLE
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
/*
* Feature disable options
diff --git a/keyboards/handwired/onekey/elite_c/config.h b/keyboards/handwired/onekey/elite_c/config.h
index f495a1c38b..a3f63983fe 100644
--- a/keyboards/handwired/onekey/elite_c/config.h
+++ b/keyboards/handwired/onekey/elite_c/config.h
@@ -30,3 +30,6 @@
#define RGB_CI_PIN B1
#define ADC_PIN F6
+
+#define QMK_WAITING_TEST_BUSY_PIN F6
+#define QMK_WAITING_TEST_YIELD_PIN F7
diff --git a/keyboards/handwired/onekey/keymaps/chibios_waiting_test/config.h b/keyboards/handwired/onekey/keymaps/chibios_waiting_test/config.h
new file mode 100644
index 0000000000..0c75fa3044
--- /dev/null
+++ b/keyboards/handwired/onekey/keymaps/chibios_waiting_test/config.h
@@ -0,0 +1,12 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#if !defined(QMK_WAITING_TEST_BUSY_PIN)
+# define QMK_WAITING_TEST_BUSY_PIN A8
+#endif
+
+#if !defined(QMK_WAITING_TEST_YIELD_PIN)
+# define QMK_WAITING_TEST_YIELD_PIN A9
+#endif
diff --git a/keyboards/handwired/onekey/keymaps/chibios_waiting_test/keymap.c b/keyboards/handwired/onekey/keymaps/chibios_waiting_test/keymap.c
new file mode 100644
index 0000000000..ecf67d3b3c
--- /dev/null
+++ b/keyboards/handwired/onekey/keymaps/chibios_waiting_test/keymap.c
@@ -0,0 +1,47 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(KC_A)};
+
+#if defined(__AVR__)
+# pragma message "AVR uses polled waiting by default, running theses tests will not show any difference"
+static inline void chThdSleepMicroseconds(uint32_t us) {
+ wait_us(us);
+}
+#endif
+
+void keyboard_post_init_user(void) {
+ setPinOutput(QMK_WAITING_TEST_BUSY_PIN);
+ setPinOutput(QMK_WAITING_TEST_YIELD_PIN);
+}
+
+static inline void wait_us_polling_with_strobe(uint32_t us) {
+ writePinHigh(QMK_WAITING_TEST_BUSY_PIN);
+ wait_us(us);
+ writePinLow(QMK_WAITING_TEST_BUSY_PIN);
+}
+
+static inline void wait_us_yield_with_strobe(uint32_t us) {
+ writePinHigh(QMK_WAITING_TEST_YIELD_PIN);
+ chThdSleepMicroseconds(us);
+ writePinLow(QMK_WAITING_TEST_YIELD_PIN);
+}
+
+static const uint32_t waiting_values[] = {0, 1, 5, 10, 25, 50, 100, 150, 200, 500, 1000};
+
+void housekeeping_task_user(void) {
+ static uint32_t last_bench = 0;
+ if (timer_elapsed32(last_bench) > 500) {
+ for (int i = 0; i < (sizeof(waiting_values) / sizeof(waiting_values[0])); i++) {
+ wait_us_polling_with_strobe(waiting_values[i]);
+ wait_us(10);
+ }
+ for (int i = 0; i < (sizeof(waiting_values) / sizeof(waiting_values[0])); i++) {
+ wait_us_yield_with_strobe(waiting_values[i]);
+ wait_us(10);
+ }
+ last_bench = timer_read32();
+ }
+}
diff --git a/keyboards/handwired/onekey/onekey.c b/keyboards/handwired/onekey/onekey.c
index cbd67012ce..a29f9ea6d0 100644
--- a/keyboards/handwired/onekey/onekey.c
+++ b/keyboards/handwired/onekey/onekey.c
@@ -1 +1,12 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
#include "onekey.h"
+
+void keyboard_post_init_kb(void) {
+ debug_enable = true;
+ debug_matrix = true;
+ debug_keyboard = true;
+ debug_mouse = true;
+ keyboard_post_init_user();
+}
diff --git a/keyboards/handwired/onekey/promicro/config.h b/keyboards/handwired/onekey/promicro/config.h
index 9c8961d5ca..b9ab046eae 100644
--- a/keyboards/handwired/onekey/promicro/config.h
+++ b/keyboards/handwired/onekey/promicro/config.h
@@ -30,3 +30,6 @@
#define RGB_CI_PIN B1
#define ADC_PIN F6
+
+#define QMK_WAITING_TEST_BUSY_PIN F6
+#define QMK_WAITING_TEST_YIELD_PIN F7
diff --git a/keyboards/handwired/onekey/rp2040/config.h b/keyboards/handwired/onekey/rp2040/config.h
new file mode 100644
index 0000000000..f4e45a8981
--- /dev/null
+++ b/keyboards/handwired/onekey/rp2040/config.h
@@ -0,0 +1,22 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "config_common.h"
+
+#define PRODUCT Onekey Raspberry Pi RP2040
+#define MATRIX_COL_PINS \
+ { GP4 }
+#define MATRIX_ROW_PINS \
+ { GP5 }
+#define DEBUG_MATRIX_SCAN_RATE
+
+#define QMK_WAITING_TEST_BUSY_PIN GP8
+#define QMK_WAITING_TEST_YIELD_PIN GP9
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP25
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
+
+#define RGB_DI_PIN A1
diff --git a/keyboards/handwired/onekey/rp2040/readme.md b/keyboards/handwired/onekey/rp2040/readme.md
new file mode 100644
index 0000000000..9014479f8d
--- /dev/null
+++ b/keyboards/handwired/onekey/rp2040/readme.md
@@ -0,0 +1,12 @@
+# Raspberry Pi 2040 onekey
+
+To trigger keypress, short together pins *GP4* and *GP5*.
+
+Double-tap reset to enter bootloader mode. Copy the built uf2 file to the device by dragging the file to the new USB disk.
+
+## Supported Hardware
+
+* Raspberry Pi Pico
+* SparkFun Pro Micro - RP2040
+* Adafruit KB2040 - RP2040 Kee Boar
+* ...and many more RP2040 based development boards
diff --git a/keyboards/handwired/onekey/rp2040/rules.mk b/keyboards/handwired/onekey/rp2040/rules.mk
new file mode 100644
index 0000000000..646402d0bb
--- /dev/null
+++ b/keyboards/handwired/onekey/rp2040/rules.mk
@@ -0,0 +1,3 @@
+# MCU name
+MCU = RP2040
+BOOTLOADER = rp2040
diff --git a/keyboards/handwired/onekey/teensy_2/config.h b/keyboards/handwired/onekey/teensy_2/config.h
index b83262ef05..437c597f29 100644
--- a/keyboards/handwired/onekey/teensy_2/config.h
+++ b/keyboards/handwired/onekey/teensy_2/config.h
@@ -29,3 +29,6 @@
#define RGB_DI_PIN F6
#define ADC_PIN F6
+
+#define QMK_WAITING_TEST_BUSY_PIN F6
+#define QMK_WAITING_TEST_YIELD_PIN F7
diff --git a/keyboards/handwired/onekey/teensy_2pp/config.h b/keyboards/handwired/onekey/teensy_2pp/config.h
index 886ad70cbf..691dddfd1a 100644
--- a/keyboards/handwired/onekey/teensy_2pp/config.h
+++ b/keyboards/handwired/onekey/teensy_2pp/config.h
@@ -29,3 +29,6 @@
#define RGB_DI_PIN F6
#define ADC_PIN F6
+
+#define QMK_WAITING_TEST_BUSY_PIN F6
+#define QMK_WAITING_TEST_YIELD_PIN F7
diff --git a/keyboards/handwired/onekey/teensy_35/chconf.h b/keyboards/handwired/onekey/teensy_35/chconf.h
new file mode 100644
index 0000000000..ee8312c526
--- /dev/null
+++ b/keyboards/handwired/onekey/teensy_35/chconf.h
@@ -0,0 +1,28 @@
+/* Copyright 2020 QMK
+ *
+ * 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/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/handwired/onekey/teensy_35/chconf.h -r platforms/chibios/common/configs/chconf.h`
+ */
+
+#pragma once
+
+#define CH_CFG_ST_TIMEDELTA 0
+
+#define CH_CFG_TIME_QUANTUM 20
+
+#include_next <chconf.h>
diff --git a/keyboards/handwired/onekey/teensy_35/config.h b/keyboards/handwired/onekey/teensy_35/config.h
new file mode 100644
index 0000000000..a5f2c945c4
--- /dev/null
+++ b/keyboards/handwired/onekey/teensy_35/config.h
@@ -0,0 +1,32 @@
+/* Copyright 2019
+ *
+ * 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
+
+// TODO: including this causes "error: expected identifier before '(' token" errors
+//#include "config_common.h"
+
+#define PRODUCT Onekey Teensy 3.5
+
+#define MATRIX_COL_PINS { D5 } // 20/A6
+#define MATRIX_ROW_PINS { B2 } // 19/A5
+#define UNUSED_PINS
+
+// i2c_master defines
+#define I2C1_SCL_PIN B0 // 16/A2 on pinout
+#define I2C1_SDA_PIN B1 // 17/A3 on pinout
+#define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
+#define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
diff --git a/keyboards/handwired/onekey/teensy_35/halconf.h b/keyboards/handwired/onekey/teensy_35/halconf.h
new file mode 100644
index 0000000000..6ac756d0f2
--- /dev/null
+++ b/keyboards/handwired/onekey/teensy_35/halconf.h
@@ -0,0 +1,28 @@
+/* Copyright 2020 QMK
+ *
+ * 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/>.
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/handwired/onekey/teensy_35/halconf.h -r platforms/chibios/common/configs/halconf.h`
+ */
+
+#pragma once
+
+#define HAL_USE_SERIAL TRUE
+
+#define SERIAL_USB_BUFFERS_SIZE 256
+
+#include_next <halconf.h>
diff --git a/keyboards/handwired/onekey/teensy_35/mcuconf.h b/keyboards/handwired/onekey/teensy_35/mcuconf.h
new file mode 100644
index 0000000000..dc508eee7d
--- /dev/null
+++ b/keyboards/handwired/onekey/teensy_35/mcuconf.h
@@ -0,0 +1,50 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+#define K60x_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+
+/* Select the MCU clocking mode below by enabling the appropriate block. */
+
+/* PEE mode - 120MHz system clock driven by external crystal. */
+#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
+#define KINETIS_PLLCLK_FREQUENCY 120000000UL // 120 MHz (RUN)
+#define KINETIS_SYSCLK_FREQUENCY KINETIS_PLLCLK_FREQUENCY
+#define KINETIS_BUSCLK_FREQUENCY 60000000UL
+#define KINETIS_FLASHCLK_FREQUENCY 24000000UL // 24 MHz (RUN)
+
+#define KINETIS_CLKDIV1_OUTDIV1 1 // -> 0
+#define KINETIS_CLKDIV1_OUTDIV2 2 // -> 1
+#define KINETIS_CLKDIV1_OUTDIV4 5 // -> 4
+
+/*
+ * SERIAL driver system settings.
+ */
+#define KINETIS_SERIAL_USE_UART0 TRUE
+
+/*
+ * USB driver settings
+ */
+#define KINETIS_USB_USE_USB0 TRUE
+#define KINETIS_USB_USB0_IRQ_PRIORITY 5
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/handwired/onekey/teensy_35/rules.mk b/keyboards/handwired/onekey/teensy_35/rules.mk
new file mode 100644
index 0000000000..8ebefd03f5
--- /dev/null
+++ b/keyboards/handwired/onekey/teensy_35/rules.mk
@@ -0,0 +1,8 @@
+# MCU name
+MCU = MK64FX512
+
+# Bootloader selection
+BOOTLOADER = halfkay
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/handwired/ortho5x14/keymaps/2u/keymap.c b/keyboards/handwired/ortho5x14/keymaps/2u/keymap.c
index 70a96fac9d..d785825332 100644
--- a/keyboards/handwired/ortho5x14/keymaps/2u/keymap.c
+++ b/keyboards/handwired/ortho5x14/keymaps/2u/keymap.c
@@ -343,9 +343,9 @@ qk_tap_dance_action_t tap_dance_actions[] = {
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_HOME),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(KC_PGDN, KC_END),
- [TD_Q_LrALT] = ACTION_TAP_DANCE_DUAL_ROLE(KC_Q, _ALT),
- [TD_R_LrKey] = ACTION_TAP_DANCE_DUAL_ROLE(KC_R, _RAISE),
- [TD_T_LrMS] = ACTION_TAP_DANCE_DUAL_ROLE(KC_T, _MOUSE),
+ [TD_Q_LrALT] = ACTION_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
+ [TD_R_LrKey] = ACTION_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
+ [TD_T_LrMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
[TD_SHIFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lshift_finished, lshift_reset),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(KC_SPACE, KC_ENT),
diff --git a/keyboards/handwired/ortho5x14/keymaps/split1/keymap.c b/keyboards/handwired/ortho5x14/keymaps/split1/keymap.c
index b152503aaf..3734510f8c 100644
--- a/keyboards/handwired/ortho5x14/keymaps/split1/keymap.c
+++ b/keyboards/handwired/ortho5x14/keymaps/split1/keymap.c
@@ -279,9 +279,9 @@ qk_tap_dance_action_t tap_dance_actions[] = {
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_HOME),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_END),
- [TD_Q_LrALT] = ACTION_TAP_DANCE_DUAL_ROLE(KC_Q, _ALT),
- [TD_R_LrKey] = ACTION_TAP_DANCE_DUAL_ROLE(KC_R, _RAISE),
- [TD_T_LrMS] = ACTION_TAP_DANCE_DUAL_ROLE(KC_T, _MOUSE),
+ [TD_Q_LrALT] = ACTION_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
+ [TD_R_LrKey] = ACTION_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
+ [TD_T_LrMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
[TD_SHIFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lshift_finished, lshift_reset),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(KC_SPACE, KC_ENT),
diff --git a/keyboards/handwired/ortho_brass/keymaps/default/keymap.c b/keyboards/handwired/ortho_brass/keymaps/default/keymap.c
index 948a7bd1bc..f32529b6a7 100644
--- a/keyboards/handwired/ortho_brass/keymaps/default/keymap.c
+++ b/keyboards/handwired/ortho_brass/keymaps/default/keymap.c
@@ -162,7 +162,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = LAYOUT_ortho_4x12_1x2uC(
_______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
diff --git a/keyboards/handwired/prime_exl/keymaps/via/keymap.c b/keyboards/handwired/prime_exl/keymaps/via/keymap.c
index 0e6802996d..b5b616d55b 100644
--- a/keyboards/handwired/prime_exl/keymaps/via/keymap.c
+++ b/keyboards/handwired/prime_exl/keymaps/via/keymap.c
@@ -87,7 +87,7 @@ void led_set_user(uint8_t usb_led) {
//function for layer indicator LED
layer_state_t layer_state_set_user(layer_state_t state)
{
- if (biton32(state) == 1) {
+ if (get_highest_layer(state) == 1) {
writePinHigh(C6);
} else {
writePinLow(C6);
diff --git a/keyboards/handwired/promethium/keymaps/default/keymap.c b/keyboards/handwired/promethium/keymaps/default/keymap.c
index 1903b2f9ba..77f83361e6 100644
--- a/keyboards/handwired/promethium/keymaps/default/keymap.c
+++ b/keyboards/handwired/promethium/keymaps/default/keymap.c
@@ -529,7 +529,7 @@ void led_reset(void) {
}
void led_set_default_layer_indicator(void) {
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
rgbsps_set(LED_IND_QWERTY, THEME_COLOR_QWERTY);
rgbsps_set(LED_IND_ALT, COLOR_BLANK);
@@ -553,7 +553,7 @@ void led_set_layer_indicator(void) {
rgbsps_set(LED_IND_GREEK, COLOR_BLANK);
rgbsps_set(LED_IND_EMOJI, COLOR_BLANK);
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (oldlayer == layer) {
return;
}
@@ -1014,7 +1014,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
lshift = keyboard_report->mods & MOD_BIT(KC_LSFT);
rshift = keyboard_report->mods & MOD_BIT(KC_RSFT);
- layer = biton32(layer_state);
+ layer = get_highest_layer(layer_state);
#ifdef DOUBLESPACE_LAYER_ENABLE
// double-space: send space immediately if any other key depressed before space is released
diff --git a/keyboards/handwired/promethium/keymaps/priyadi/config.h b/keyboards/handwired/promethium/keymaps/priyadi/config.h
index 0630fd43e3..1e5e8906ed 100644
--- a/keyboards/handwired/promethium/keymaps/priyadi/config.h
+++ b/keyboards/handwired/promethium/keymaps/priyadi/config.h
@@ -2,12 +2,6 @@
#define PRIYADI_PROMETHIUM
-/* bootmagic salt key */
-#define BOOTMAGIC_KEY_SALT KC_ESC
-
-/* skip bootmagic and eeconfig */
-#define BOOTMAGIC_KEY_SKIP KC_SPACE
-
#define RGBSPS_ENABLE
#define RGBSPS_DEMO_ENABLE
diff --git a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c
index 94b505aa2c..faa096ce08 100644
--- a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c
+++ b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c
@@ -532,7 +532,7 @@ void led_reset(void) {
}
void led_set_default_layer_indicator(void) {
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
rgbsps_set(LED_IND_QWERTY, THEME_COLOR_QWERTY);
rgbsps_set(LED_IND_ALT, COLOR_BLANK);
@@ -556,7 +556,7 @@ void led_set_layer_indicator(void) {
rgbsps_set(LED_IND_GREEK, COLOR_BLANK);
rgbsps_set(LED_IND_EMOJI, COLOR_BLANK);
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (oldlayer == layer) {
return;
}
@@ -989,7 +989,7 @@ void process_doublespace(bool pressed, bool *isactive, bool *otheractive, bool *
}
#endif
-uint32_t layer_state_set_kb(uint32_t state)
+layer_state_t layer_state_set_kb(layer_state_t state)
{
// turn on punc layer if both fun & num are on
if ((state & ((1UL<<_NUM) | (1UL<<_FUN))) == ((1UL<<_NUM) | (1UL<<_FUN))) {
@@ -1017,7 +1017,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
lshift = keyboard_report->mods & MOD_BIT(KC_LSFT);
rshift = keyboard_report->mods & MOD_BIT(KC_RSFT);
- layer = biton32(layer_state);
+ layer = get_highest_layer(layer_state);
#ifdef DOUBLESPACE_LAYER_ENABLE
// double-space: send space immediately if any other key depressed before space is released
diff --git a/keyboards/handwired/riblee_f401/keymaps/default/keymap.c b/keyboards/handwired/riblee_f401/keymaps/default/keymap.c
index 6892c0fb49..bee4de5ede 100644
--- a/keyboards/handwired/riblee_f401/keymaps/default/keymap.c
+++ b/keyboards/handwired/riblee_f401/keymaps/default/keymap.c
@@ -158,7 +158,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_ortho_5x12(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, _______, _______, _______, _______, _______, NK_TOGG, LCG_SWP, LCG_NRM, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/handwired/riblee_f411/keymaps/default/keymap.c b/keyboards/handwired/riblee_f411/keymaps/default/keymap.c
index 2e9485d6b9..ff7e1117b8 100644
--- a/keyboards/handwired/riblee_f411/keymaps/default/keymap.c
+++ b/keyboards/handwired/riblee_f411/keymaps/default/keymap.c
@@ -158,7 +158,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_ortho_5x12(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, _______, _______, _______, _______, _______, NK_TOGG, LCG_SWP, LCG_NRM, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/handwired/rs60/keymaps/default/keymap.c b/keyboards/handwired/rs60/keymaps/default/keymap.c
index 6b311a7ebb..6d5dc4a32a 100644
--- a/keyboards/handwired/rs60/keymaps/default/keymap.c
+++ b/keyboards/handwired/rs60/keymaps/default/keymap.c
@@ -155,7 +155,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_ortho_5x12(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, _______, _______, _______, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/handwired/terminus_mini/keymaps/default/keymap.c b/keyboards/handwired/terminus_mini/keymaps/default/keymap.c
index 8062aa711f..8d0631072f 100644
--- a/keyboards/handwired/terminus_mini/keymaps/default/keymap.c
+++ b/keyboards/handwired/terminus_mini/keymaps/default/keymap.c
@@ -193,7 +193,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT(
- _______, _______, _______, _______, _______, QK_BOOT, _______, TERM_ON, TERM_OFF, _______, _______, KC_DEL,
+ _______, _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, KC_DEL,
_______, _______, _______, _______, _______, _______, _______, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/handwired/tractyl_manuform/4x6_right/config.h b/keyboards/handwired/tractyl_manuform/4x6_right/config.h
index ab46bc5276..5bfb17ee31 100644
--- a/keyboards/handwired/tractyl_manuform/4x6_right/config.h
+++ b/keyboards/handwired/tractyl_manuform/4x6_right/config.h
@@ -85,7 +85,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
-/* PMW3360 Settings */
-#define PMW3360_CS_PIN B0
+/* PMW33XX Settings */
+#define PMW33XX_CS_PIN B0
#define POINTING_DEVICE_RIGHT
diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h
index d8d36e824c..ab72957b5c 100644
--- a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h
+++ b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h
@@ -47,5 +47,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ENCODERS_PAD_B \
{ C7 }
-/* PMW3360 Settings */
-#define PMW3360_CS_PIN B6
+/* PMW33XX Settings */
+#define PMW33XX_CS_PIN B6
diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h
index f9a44587b0..809acdcd94 100644
--- a/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h
+++ b/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h
@@ -99,6 +99,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #define DEBUG_EEPROM_OUTPUT
/* pmw3360 config */
-#define PMW3360_CS_PIN B9
-#define PMW3360_SPI_MODE 3
-#define PMW3360_SPI_DIVISOR 8
+#define PMW33XX_CS_PIN B9
+#define PMW33XX_SPI_DIVISOR 8
diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h
index 5f0350810c..0eb5b2a217 100644
--- a/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h
+++ b/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h
@@ -102,7 +102,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 64
/* pmw3360 config */
-#define PMW3360_CS_PIN B0
-#define PMW3360_SPI_MODE 3
-#define PMW3360_SPI_DIVISOR 64
-#define PMW3360_FIRMWARE_UPLOAD_FAST
+#define PMW33XX_CS_PIN B0
diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h
index 442d474920..6eb3186332 100644
--- a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h
+++ b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h
@@ -51,5 +51,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ENCODERS_PAD_B \
{ D4 }
-/* PMW3360 Settings */
-#define PMW3360_CS_PIN B0
+/* PMW33XX Settings */
+#define PMW33XX_CS_PIN B0
diff --git a/keyboards/handwired/tractyl_manuform/tractyl_manuform.c b/keyboards/handwired/tractyl_manuform/tractyl_manuform.c
index 0ae49b6397..d3e2e02975 100644
--- a/keyboards/handwired/tractyl_manuform/tractyl_manuform.c
+++ b/keyboards/handwired/tractyl_manuform/tractyl_manuform.c
@@ -159,10 +159,8 @@ void charybdis_set_pointer_dragscroll_enabled(bool enable) {
maybe_update_pointing_device_cpi(&g_charybdis_config);
}
-void pointing_device_init_kb(void) { maybe_update_pointing_device_cpi(&g_charybdis_config); }
-
# ifndef CONSTRAIN_HID
-# define CONSTRAIN_HID(value) ((value) < -127 ? -127 : ((value) > 127 ? 127 : (value)))
+# define CONSTRAIN_HID(value) ((value) < XY_REPORT_MIN ? XY_REPORT_MIN : ((value) > XY_REPORT_MAX ? XY_REPORT_MAX : (value)))
# endif // !CONSTRAIN_HID
/**
@@ -249,17 +247,17 @@ static bool has_shift_mod(void) {
*/
__attribute__((unused)) static void debug_charybdis_config_to_console(charybdis_config_t* config) {
# ifdef CONSOLE_ENABLE
- dprintf("(charybdis) process_record_kb: config = {\n"
- "\traw = 0x%04X,\n"
- "\t{\n"
- "\t\tis_dragscroll_enabled=%b\n"
- "\t\tis_sniping_enabled=%b\n"
- "\t\tdefault_dpi=0x%02X (%ld)\n"
- "\t\tsniping_dpi=0x%01X (%ld)\n"
- "\t}\n"
- "}\n",
- config->raw, config->is_dragscroll_enabled, config->is_sniping_enabled, config->pointer_default_dpi, get_pointer_default_dpi(config), config->pointer_sniping_dpi, get_pointer_sniping_dpi(config));
-# endif // CONSOLE_ENABLE
+ IGNORE_FORMAT_WARNING(dprintf("(charybdis) process_record_kb: config = {\n"
+ "\traw = 0x%04X,\n"
+ "\t{\n"
+ "\t\tis_dragscroll_enabled=%b\n"
+ "\t\tis_sniping_enabled=%b\n"
+ "\t\tdefault_dpi=0x%02X (%ld)\n"
+ "\t\tsniping_dpi=0x%01X (%ld)\n"
+ "\t}\n"
+ "}\n",
+ config->raw, config->is_dragscroll_enabled, config->is_sniping_enabled, config->pointer_default_dpi, get_pointer_default_dpi(config), config->pointer_sniping_dpi, get_pointer_sniping_dpi(config)));
+# endif // CONSOLE_ENABLE
}
bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
@@ -339,6 +337,7 @@ void charybdis_config_sync_handler(uint8_t initiator2target_buffer_size, const v
}
void keyboard_post_init_kb(void) {
+ maybe_update_pointing_device_cpi(&g_charybdis_config);
transaction_register_rpc(RPC_ID_KB_CONFIG_SYNC, charybdis_config_sync_handler);
keyboard_post_init_user();
diff --git a/keyboards/handwired/traveller/keymaps/default/keymap.c b/keyboards/handwired/traveller/keymaps/default/keymap.c
index 288acbe108..2cd57db35f 100644
--- a/keyboards/handwired/traveller/keymaps/default/keymap.c
+++ b/keyboards/handwired/traveller/keymaps/default/keymap.c
@@ -219,7 +219,7 @@ void LayerLEDSet(uint8_t layr) {
uint8_t old_layer = _QW;
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (old_layer != layer) {
LayerLEDSet(layer);
diff --git a/keyboards/handwired/tritium_numpad/keymaps/blu/keymap.c b/keyboards/handwired/tritium_numpad/keymaps/blu/keymap.c
index b618675295..50bbf232b5 100644
--- a/keyboards/handwired/tritium_numpad/keymaps/blu/keymap.c
+++ b/keyboards/handwired/tritium_numpad/keymaps/blu/keymap.c
@@ -9,7 +9,7 @@ void keyboard_pre_init_user(void)
layer_state_t layer_state_set_user(layer_state_t state)
{
// Switch layer LED accordingly
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case 0:
writePinHigh(B0);
break;
diff --git a/keyboards/handwired/uthol/rev3/config.h b/keyboards/handwired/uthol/rev3/config.h
index 90880998b7..84ca3f0cc6 100644
--- a/keyboards/handwired/uthol/rev3/config.h
+++ b/keyboards/handwired/uthol/rev3/config.h
@@ -57,6 +57,7 @@
#define LOCKING_RESYNC_ENABLE
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
// RGB Stuff
#define RGB_DI_PIN B0
diff --git a/keyboards/helix/pico/keymaps/mtei/config.h b/keyboards/helix/pico/keymaps/mtei/config.h
index 1a4dc2c842..a633105ff9 100644
--- a/keyboards/helix/pico/keymaps/mtei/config.h
+++ b/keyboards/helix/pico/keymaps/mtei/config.h
@@ -13,8 +13,6 @@
#undef TAPPING_TERM
#define TAPPING_TERM 300
#define PERMISSIVE_HOLD
-/* when TAPPING_TERM >= 500 same effect PERMISSIVE_HOLD.
- see tmk_core/common/action_tapping.c */
// If you need more program area, try select and reduce rgblight modes to use.
diff --git a/keyboards/helix/pico/keymaps/mtei/keymap.c b/keyboards/helix/pico/keymaps/mtei/keymap.c
index b703ca376d..f641829292 100644
--- a/keyboards/helix/pico/keymaps/mtei/keymap.c
+++ b/keyboards/helix/pico/keymaps/mtei/keymap.c
@@ -242,7 +242,7 @@ float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
static int current_default_layer;
-uint32_t default_layer_state_set_kb(uint32_t state) {
+layer_state_t default_layer_state_set_kb(layer_state_t state) {
// 1<<_QWERTY - 1 == 1 - 1 == _QWERTY (=0)
// 1<<_COLEMAK - 1 == 2 - 1 == _COLEMAK (=1)
current_default_layer = state - 1;
diff --git a/keyboards/helix/rev2/keymaps/default/oled_display.c b/keyboards/helix/rev2/keymaps/default/oled_display.c
index ad5558869f..384356bd14 100644
--- a/keyboards/helix/rev2/keymaps/default/oled_display.c
+++ b/keyboards/helix/rev2/keymaps/default/oled_display.c
@@ -86,7 +86,7 @@ static void render_layer_status(void) {
break;
default:
oled_write_P(PSTR("Undef-"), false);
- snprintf(buf,sizeof(buf), "%ld", layer_state);
+ snprintf(buf,sizeof(buf), "%u", layer_state);
oled_write(buf, false);
}
oled_write_P(PSTR("\n"), false);
diff --git a/keyboards/helix/rev2/keymaps/edvorakjp/keymap.c b/keyboards/helix/rev2/keymaps/edvorakjp/keymap.c
index 5de00cb14c..80d0392ffb 100644
--- a/keyboards/helix/rev2/keymaps/edvorakjp/keymap.c
+++ b/keyboards/helix/rev2/keymaps/edvorakjp/keymap.c
@@ -5,9 +5,9 @@
// keymaps definitions are moved to keymap_Xrows.c.
#ifdef RGBLIGHT_ENABLE
-uint32_t layer_state_set_keymap(uint32_t state) {
+layer_state_t layer_state_set_keymap(layer_state_t state) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case L_EDVORAKJP_LOWER:
rgblight_sethsv_noeeprom_red();
break;
diff --git a/keyboards/helix/rev2/keymaps/edvorakjp/oled.c b/keyboards/helix/rev2/keymaps/edvorakjp/oled.c
index 207aebc423..14e3e5533b 100644
--- a/keyboards/helix/rev2/keymaps/edvorakjp/oled.c
+++ b/keyboards/helix/rev2/keymaps/edvorakjp/oled.c
@@ -19,7 +19,7 @@ void render_layer_state(void) {
char layer_name[17];
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case L_EDVORAKJP_BASE:
oled_write_ln_P(PSTR("Default"), false);
break;
diff --git a/keyboards/helix/rev2/keymaps/five_rows/config.h b/keyboards/helix/rev2/keymaps/five_rows/config.h
index 4aae9b5cac..43f14aaf2c 100644
--- a/keyboards/helix/rev2/keymaps/five_rows/config.h
+++ b/keyboards/helix/rev2/keymaps/five_rows/config.h
@@ -6,8 +6,6 @@
#undef TAPPING_TERM
#define TAPPING_TERM 300
#define PERMISSIVE_HOLD
-/* when TAPPING_TERM >= 500 same effect PERMISSIVE_HOLD.
- see tmk_core/common/action_tapping.c */
#undef OLED_UPDATE_INTERVAL
#ifdef DEBUG_MATRIX_SCAN_RATE
diff --git a/keyboards/helix/rev2/keymaps/five_rows/keymap.c b/keyboards/helix/rev2/keymaps/five_rows/keymap.c
index d992425de7..4d9dc16a9e 100644
--- a/keyboards/helix/rev2/keymaps/five_rows/keymap.c
+++ b/keyboards/helix/rev2/keymaps/five_rows/keymap.c
@@ -379,8 +379,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
int current_default_layer;
-uint32_t default_layer_state_set_user(uint32_t state) {
- current_default_layer = biton32(state);
+layer_state_t default_layer_state_set_user(layer_state_t state) {
+ current_default_layer = get_highest_layer(state);
return state;
}
diff --git a/keyboards/helix/rev3_5rows/keymaps/five_rows/config.h b/keyboards/helix/rev3_5rows/keymaps/five_rows/config.h
index ab679d14b9..a6fd32c613 100644
--- a/keyboards/helix/rev3_5rows/keymaps/five_rows/config.h
+++ b/keyboards/helix/rev3_5rows/keymaps/five_rows/config.h
@@ -6,8 +6,6 @@
#undef TAPPING_TERM
#define TAPPING_TERM 300
#define PERMISSIVE_HOLD
-/* when TAPPING_TERM >= 500 same effect PERMISSIVE_HOLD.
- see tmk_core/common/action_tapping.c */
#undef OLED_UPDATE_INTERVAL
#ifdef DEBUG_MATRIX_SCAN_RATE
diff --git a/keyboards/helix/rev3_5rows/keymaps/five_rows/keymap.c b/keyboards/helix/rev3_5rows/keymaps/five_rows/keymap.c
index d992425de7..4d9dc16a9e 100644
--- a/keyboards/helix/rev3_5rows/keymaps/five_rows/keymap.c
+++ b/keyboards/helix/rev3_5rows/keymaps/five_rows/keymap.c
@@ -379,8 +379,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
int current_default_layer;
-uint32_t default_layer_state_set_user(uint32_t state) {
- current_default_layer = biton32(state);
+layer_state_t default_layer_state_set_user(layer_state_t state) {
+ current_default_layer = get_highest_layer(state);
return state;
}
diff --git a/keyboards/hineybush/h87a/keymaps/gam3cat/keymap.c b/keyboards/hineybush/h87a/keymaps/gam3cat/keymap.c
index d59438f6b3..d505d5171d 100644
--- a/keyboards/hineybush/h87a/keymaps/gam3cat/keymap.c
+++ b/keyboards/hineybush/h87a/keymaps/gam3cat/keymap.c
@@ -245,7 +245,7 @@ void matrix_scan_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _BL:
custom_backlight_level(0);
rgblight_sethsv_noeeprom(180,100,255);
diff --git a/keyboards/hotdox/keymaps/default/keymap.c b/keyboards/hotdox/keymaps/default/keymap.c
index fe07e6f91d..eb4692a4c2 100644
--- a/keyboards/hotdox/keymaps/default/keymap.c
+++ b/keyboards/hotdox/keymaps/default/keymap.c
@@ -163,7 +163,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/keyboards/hotdox/keymaps/eozaki/keymap.c b/keyboards/hotdox/keymaps/eozaki/keymap.c
index 3516f20303..d4b8f491fd 100644
--- a/keyboards/hotdox/keymaps/eozaki/keymap.c
+++ b/keyboards/hotdox/keymaps/eozaki/keymap.c
@@ -170,7 +170,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/hotdox/keymaps/kloki/keymap.c b/keyboards/hotdox/keymaps/kloki/keymap.c
index f858effd54..2550b68978 100644
--- a/keyboards/hotdox/keymaps/kloki/keymap.c
+++ b/keyboards/hotdox/keymaps/kloki/keymap.c
@@ -189,7 +189,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/idobao/id67/config.h b/keyboards/idobao/id67/config.h
index f94606c9e7..59e34654b5 100644
--- a/keyboards/idobao/id67/config.h
+++ b/keyboards/idobao/id67/config.h
@@ -1,49 +1,12 @@
-/* Copyright 2021 Tybera
- * Copyright 2021 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Tybera (@tybera)
+// Copyright 2021 Werther (@thewerther)
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "config_common.h"
-/* USB Device descriptor parameter */
-#define VENDOR_ID 0x6964 /* "id" */
-#define PRODUCT_ID 0x0067
-#define DEVICE_VER 0x0002
-#define MANUFACTURER IDOBAO
-#define PRODUCT ID67
-
-/* key matrix size */
-#define MATRIX_ROWS 5
-#define MATRIX_COLS 15
-
-/*
- * Keyboard Matrix Assignments
- *
- * Change this to how you wired your keyboard
- * COLS: AVR pins used for columns, left to right
- * ROWS: AVR pins used for rows, top to bottom
- * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
- * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
- *
- */
-#define MATRIX_ROW_PINS { B0, B1, B2, B3, F7 }
-#define MATRIX_COL_PINS { C7, F6, F5, F4, F1, B7, D5, D1, D2, D3, D4, D0, D6, D7, B4 }
-
-#define DIODE_DIRECTION COL2ROW
#define RGB_DI_PIN F0
// RGB Matrix config
@@ -51,60 +14,73 @@
#ifndef ID67_DISABLE_UNDERGLOW
#define DRIVER_LED_TOTAL 77
#else
- #define DRIVER_LED_TOTAL 67
+ #define DRIVER_LED_TOTAL (77 - 10)
#endif
#define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
- #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150 // limits maximum brightness of LEDs to x out of 255. If not defined maximum brightness is set to 255
+ #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180 // limits maximum brightness of LEDs to x out of 255. If not defined maximum brightness is set to 255
#define RGB_MATRIX_KEYPRESSES
- #define ENABLE_RGB_MATRIX_ALPHAS_MODS // Static dual hue, speed is hue for secondary hue
- #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN // Static gradient top to bottom, speed controls how much gradient changes
- #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT // Static gradient left to right, speed controls how much gradient changes
- #define ENABLE_RGB_MATRIX_BREATHING // Single hue brightness cycling animation
- #define ENABLE_RGB_MATRIX_BAND_SAT // Single hue band fading saturation scrolling left to right
- #define ENABLE_RGB_MATRIX_BAND_VAL // Single hue band fading brightness scrolling left to right
- #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT // Single hue 3 blade spinning pinwheel fades saturation
- #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL // Single hue 3 blade spinning pinwheel fades brightness
- #define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT // Single hue spinning spiral fades saturation
- #define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL // Single hue spinning spiral fades brightness
- #define ENABLE_RGB_MATRIX_CYCLE_ALL // Full keyboard solid hue cycling through full gradient
- #define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT // Full gradient scrolling left to right
- #define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN // Full gradient scrolling top to bottom
- #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN // Full gradient scrolling out to in
- #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL // Full dual gradients scrolling out to in
- #define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON // Full gradient Chevron shaped scrolling left to right
- #define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL // Full gradient spinning pinwheel around center of keyboard
- #define ENABLE_RGB_MATRIX_CYCLE_SPIRAL // Full gradient spinning spiral around center of keyboard
- #define ENABLE_RGB_MATRIX_DUAL_BEACON // Full gradient spinning around center of keyboard
- #define ENABLE_RGB_MATRIX_RAINBOW_BEACON // Full tighter gradient spinning around center of keyboard
- #define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS // Full dual gradients spinning two halfs of keyboard
- #define ENABLE_RGB_MATRIX_RAINDROPS // Randomly changes a single key's hue
- #define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS // Randomly changes a single key's hue and saturation
- #define ENABLE_RGB_MATRIX_HUE_BREATHING // Hue shifts up a slight amount at the same time, then shifts back
- #define ENABLE_RGB_MATRIX_HUE_PENDULUM // Hue shifts up a slight amount in a wave to the right, then back to the left
- #define ENABLE_RGB_MATRIX_HUE_WAVE // Hue shifts up a slight amount and then back down in a wave to the right
+ #define ENABLE_RGB_MATRIX_SOLID_COLOR // Static single color
+ #define ENABLE_RGB_MATRIX_ALPHAS_MODS // Static dual hue, speed is hue for secondary hue
+ #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN // Static gradient top to bottom, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT // Static gradient left to right, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_BREATHING // Single hue brightness cycling animation
+ #define ENABLE_RGB_MATRIX_BAND_SAT // Single hue band fading saturation scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_VAL // Single hue band fading brightness scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT // Single hue 3 blade spinning pinwheel fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL // Single hue 3 blade spinning pinwheel fades brightness
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT // Single hue spinning spiral fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL // Single hue spinning spiral fades brightness
+ #define ENABLE_RGB_MATRIX_CYCLE_ALL // Full keyboard solid hue cycling through full gradient
+ #define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT // Full gradient scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN // Full gradient scrolling top to bottom
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN // Full gradient scrolling out to in
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL // Full dual gradients scrolling out to in
+ #define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON // Full gradient Chevron shaped scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL // Full gradient spinning pinwheel around center of keyboard
+ #define ENABLE_RGB_MATRIX_CYCLE_SPIRAL // Full gradient spinning spiral around center of keyboard
+ #define ENABLE_RGB_MATRIX_DUAL_BEACON // Full gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_BEACON // Full tighter gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS // Full dual gradients spinning two halfs of keyboard
+ #define ENABLE_RGB_MATRIX_RAINDROPS // Randomly changes a single key's hue
+ #define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS // Randomly changes a single key's hue and saturation
+ #define ENABLE_RGB_MATRIX_HUE_BREATHING // Hue shifts up a slight amount at the same time, then shifts back
+ #define ENABLE_RGB_MATRIX_HUE_PENDULUM // Hue shifts up a slight amount in a wave to the right, then back to the left
+ #define ENABLE_RGB_MATRIX_HUE_WAVE // Hue shifts up a slight amount and then back down in a wave to the right
- // don't need `#if`, animation modes themselves check defines
- // #if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
+ /* RGB_MATRIX_FRAMEBUFFER_EFFECTS -- don't enable */
// #define ENABLE_RGB_MATRIX_TYPING_HEATMAP
// #define ENABLE_RGB_MATRIX_DIGITAL_RAIN
- // #endif // #if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
- // don't need `#if`, animation modes themselves check defines
- // #if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
- #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE// Pulses keys hit to hue & value then fades value out
- #define ENABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue, pulses keys hit to shifted hue then fades to current hue
+ /* RGB_MATRIX_KEYPRESSES || RGB_MATRIX_KEYRELEASES */
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE // Pulses keys hit to hue & value then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue, pulses keys hit to shifted hue then fades to current hue
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out
#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out
- #define ENABLE_RGB_MATRIX_SPLASH // Full gradient & value pulse away from a single key hit then fades value out
- #define ENABLE_RGB_MATRIX_MULTISPLASH // Full gradient & value pulse away from multiple key hits then fades value out
- #define ENABLE_RGB_MATRIX_SOLID_SPLASH // Hue & value pulse away from a single key hit then fades value out
- #define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH // Hue & value pulse away from multiple key hits then fades value out
- // #endif // #if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
-#endif // #if defined(RGB_MATRIX_ENABLE)
+ #define ENABLE_RGB_MATRIX_SPLASH // Full gradient & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_MULTISPLASH // Full gradient & value pulse away from multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_SPLASH // Hue & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH // Hue & value pulse away from multiple key hits then fades value out
+#endif // RGB_MATRIX_ENABLE
+
+/* -----------------------
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ * ----------------------- */
+
+/* disable debug print */
+// #define NO_DEBUG
+
+/* disable print */
+// #define NO_PRINT
+
+/* disable action features */
+// #define NO_ACTION_LAYER
+// #define NO_ACTION_TAPPING
+// #define NO_ACTION_ONESHOT
diff --git a/keyboards/idobao/id67/id67.c b/keyboards/idobao/id67/id67.c
index 155cc74087..17bcd9a943 100644
--- a/keyboards/idobao/id67/id67.c
+++ b/keyboards/idobao/id67/id67.c
@@ -1,19 +1,7 @@
-/* Copyright 2021 Tybera
- * Copyright 2021 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Tybera (@tybera)
+// Copyright 2021 Werther (@thewerther)
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include "id67.h"
@@ -25,6 +13,23 @@
* These "LED Index to *" arrays are in that reversed order!
* i.e., Space row on top, listed right to left */
led_config_t g_led_config = { {
+ /* Under- / Per-Key
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │66 │65 │64 │63 │62 │61 │60 │59 │58 │57 │56 │55 │54 │ 53 │52 │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ 51 │50 │49 │48 │47 │46 │45 │44 │43 │42 │41 │40 │39 │ 38 │37 │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ 36 │35 │34 │33 │32 │31 │30 │29 │28 │27 │26 │25 │ 24 │23 │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ 22 │21 │20 │19 │18 │17 │16 │15 │14 │13 │12 │ 11 │10 │ 9 │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ 8 │ 7 │ 6 │ 5 │ 4 │ 3 │ │ 2 │ 1 │ 0 │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ *
+ * Bottom Side (as seen from top orientation)
+ * 67 68 69 70 71
+ * 76 75 74 73 72
+ */
// Key Matrix to LED Index
{66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52},
{51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37},
@@ -34,63 +39,30 @@ led_config_t g_led_config = { {
}, {
// LED Index to Physical Position
// based on: https://gist.github.com/vinorodrigues/07fd735683856b2a06c7c52b9b3878cb
- {224, 64}, {209, 64}, {194, 64}, {170, 64}, {151, 64}, {95, 64}, {39, 64}, {21, 64}, {2, 64},
- {224, 48}, {209, 48}, {189, 48}, {168, 48}, {153, 48}, {138, 48}, {123, 48}, {108, 48}, {93, 48}, {78, 48}, {63, 48}, {49, 48}, {34, 48}, {9, 48},
- {224, 32}, {200, 32}, {175, 32}, {161, 32}, {146, 32}, {131, 32}, {116, 32}, {101, 32}, {86, 32}, {71, 32}, {56, 32}, {41, 32}, {26, 32}, {6, 32},
- {224, 16}, {205, 16}, {187, 16}, {172, 16}, {157, 16}, {142, 16}, {127, 16}, {112, 16}, {97, 16}, {82, 16}, {67, 16}, {52, 16}, {37, 16}, {22, 16}, {4, 16},
- {224, 0}, {202, 0}, {179, 0}, {164, 0}, {149, 0}, {134, 0}, {119, 0}, {105, 0}, {90, 0}, {75, 0}, {60, 0}, {45, 0}, {30, 0}, {15, 0}, {0, 0}
- #ifndef ID67_DISABLE_UNDERGLOW
+ // **NB: In reverse order**
+ {224,64 }, {209,64 }, {194,64 }, {170,64 }, {151,64 }, { 95,64 }, { 39,64 }, { 21,64 }, { 2,64 },
+ {224,48 }, {209,48 }, {189,48 }, {168,48 }, {153,48 }, {138,48 }, {123,48 }, {108,48 }, { 93,48 }, { 78,48 }, { 63,48 }, { 49,48 }, { 34,48 }, { 9,48 },
+ {224,32 }, {200,32 }, {175,32 }, {161,32 }, {146,32 }, {131,32 }, {116,32 }, {101,32 }, { 86,32 }, { 71,32 }, { 56,32 }, { 41,32 }, { 26,32 }, { 6,32 },
+ {224,16 }, {205,16 }, {187,16 }, {172,16 }, {157,16 }, {142,16 }, {127,16 }, {112,16 }, { 97,16 }, { 82,16 }, { 67,16 }, { 52,16 }, { 37,16 }, { 22,16 }, { 4,16 },
+ {224,0 }, {202,0 }, {179,0 }, {164,0 }, {149,0 }, {134,0 }, {119,0 }, {105,0 }, { 90,0 }, { 75,0 }, { 60,0 }, { 45,0 }, { 30,0 }, { 15,0 }, { 0,0 }
// underglow LEDs
+ #ifndef ID67_DISABLE_UNDERGLOW
, {0, 0}, {56, 0}, {112, 0}, {168, 0}, {224, 0},
{224, 64}, {168, 64}, {112, 64}, {56, 64}, {0, 64}
#endif
}, {
// LED Index to Flag
- 4, 4, 4, 1, 1, 4, 1, 1, 1, // first row
- 1, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, // second row
+ // **NB: In reverse order**
+ 1, 1, 1, 1, 1, 4, 1, 1, 1, // fifth/bottom row
+ 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, // fourth row
1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, // third row
- 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, // fourth row
- 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 // fifth row
+ 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, // second row
+ 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 // first/top row
// underglow LEDs
#ifndef ID67_DISABLE_UNDERGLOW
- , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+ , 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2
#endif
} };
-#endif // #ifdef RGB_MATRIX_ENABLE
-
-
-/* Use `#define ID67_CAPS_LOCK_KEY_INDEX 36` in `keymaps/yourkeymap/config.h`
- * if you want to enable Caps-Lock LED mode */
-#if defined(RGB_MATRIX_ENABLE) && defined(ID67_CAPS_LOCK_KEY_INDEX)
-
-#define ID67_CAPS_LOCK_MAX_BRIGHTNESS 0xFF
-#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
- #undef ID67_CAPS_LOCK_MAX_BRIGHTNESS
- #define ID67_CAPS_LOCK_MAX_BRIGHTNESS RGB_MATRIX_MAXIMUM_BRIGHTNESS
-#endif
-
-#define ID67_CAPS_LOCK_VAL_STEP 8
-#ifdef RGB_MATRIX_VAL_STEP
- #undef ID67_CAPS_LOCK_VAL_STEP
- #define ID67_CAPS_LOCK_VAL_STEP RGB_MATRIX_VAL_STEP
-#endif
-
-/* This function is defined as weak, so if you create your own in keymap then
- * that will compile, not this */
-__attribute__((weak))
-void rgb_matrix_indicators_user(void) {
- if (host_keyboard_led_state().caps_lock) {
- uint8_t b = rgb_matrix_get_val();
- if (b < ID67_CAPS_LOCK_VAL_STEP) {
- b = ID67_CAPS_LOCK_VAL_STEP;
- } else if (b < (ID67_CAPS_LOCK_MAX_BRIGHTNESS - ID67_CAPS_LOCK_VAL_STEP)) {
- b += ID67_CAPS_LOCK_VAL_STEP; // one step more than current brightness
- } else {
- b = ID67_CAPS_LOCK_MAX_BRIGHTNESS;
- }
- rgb_matrix_set_color(ID67_CAPS_LOCK_KEY_INDEX, b, b, b); // white, with the adjusted brightness
- }
-}
-
-#endif // #ifdef ID67_CAPS_LOCK_KEY_INDEX
+#endif // RGB_MATRIX_ENABLE
diff --git a/keyboards/idobao/id67/id67.h b/keyboards/idobao/id67/id67.h
index a8eead92a0..cd5ab8de09 100644
--- a/keyboards/idobao/id67/id67.h
+++ b/keyboards/idobao/id67/id67.h
@@ -1,36 +1,8 @@
-/* Copyright 2021 Tybera
- * Copyright 2021 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Tybera (@tybera)
+// Copyright 2021 Werther (@thewerther)
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
-
-#define ___ KC_NO
-
-#define LAYOUT_65_ansi_blocker( \
- K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \
- K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
- K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
- K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
- K40, K41, K43, K46, K4A, K4B, K4C, K4D, K4E \
-) { \
- { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
- { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
- { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, ___, K2D, K2E }, \
- { K30, ___, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
- { K40, K41, ___, K43, ___, ___, K46, ___, ___, ___, K4A, K4B, K4C, K4D, K4E }, \
-}
diff --git a/keyboards/idobao/id67/info.json b/keyboards/idobao/id67/info.json
index 545cd863d8..5d70e19cd8 100644
--- a/keyboards/idobao/id67/info.json
+++ b/keyboards/idobao/id67/info.json
@@ -1,84 +1,105 @@
{
+ "manufacturer": "IDOBAO",
"keyboard_name": "ID67",
- "url": "https://idobao.net",
"maintainer": "thewerther",
- "layout_aliases": {
- "LAYOUT": "LAYOUT_65_ansi_blocker"
+ "bootloader": "atmel-dfu",
+ "diode_direction": "COL2ROW",
+ "debounce": 5,
+ "features": {
+ "bootmagic": true,
+ "mousekey": true,
+ "extrakey": true,
+ "command": false,
+ "console": false,
+ "nkro": true,
+ "backlight": false,
+ "rgblight": false
+ },
+ "matrix_pins": {
+ "cols": ["C7", "F6", "F5", "F4", "F1", "B7", "D5", "D1", "D2", "D3", "D4", "D0", "D6", "D7", "B4"],
+ "rows": ["B0", "B1", "B2", "B3", "F7"]
+ },
+ "processor": "atmega32u4",
+ "url": "https://idobao.net/search?type=product&q=ID67*",
+ "usb": {
+ "vid": "0x6964",
+ "pid": "0x0267",
+ "device_version": "2.0.0"
},
"layouts": {
"LAYOUT_65_ansi_blocker": {
"layout": [
- {"label":"K00 (B0,C7)", "x":0, "y":0},
- {"label":"K01 (B0,F6)", "x":1, "y":0},
- {"label":"K02 (B0,F5)", "x":2, "y":0},
- {"label":"K03 (B0,F4)", "x":3, "y":0},
- {"label":"K04 (B0,F1)", "x":4, "y":0},
- {"label":"K05 (B0,B7)", "x":5, "y":0},
- {"label":"K06 (B0,D5)", "x":6, "y":0},
- {"label":"K07 (B0,D1)", "x":7, "y":0},
- {"label":"K08 (B0,D2)", "x":8, "y":0},
- {"label":"K09 (B0,D3)", "x":9, "y":0},
- {"label":"K0A (B0,D4)", "x":10, "y":0},
- {"label":"K0B (B0,D0)", "x":11, "y":0},
- {"label":"K0C (B0,D6)", "x":12, "y":0},
- {"label":"K0D (B0,D7)", "x":13, "y":0, "w":2},
- {"label":"K0E (B0,B4)", "x":15, "y":0},
+ { "matrix": [0, 0], "x":0, "y":0 },
+ { "matrix": [0, 1], "x":1, "y":0 },
+ { "matrix": [0, 2], "x":2, "y":0 },
+ { "matrix": [0, 3], "x":3, "y":0 },
+ { "matrix": [0, 4], "x":4, "y":0 },
+ { "matrix": [0, 5], "x":5, "y":0 },
+ { "matrix": [0, 6], "x":6, "y":0 },
+ { "matrix": [0, 7], "x":7, "y":0 },
+ { "matrix": [0, 8], "x":8, "y":0 },
+ { "matrix": [0, 9], "x":9, "y":0 },
+ { "matrix": [0, 10], "x":10, "y":0 },
+ { "matrix": [0, 11], "x":11, "y":0 },
+ { "matrix": [0, 12], "x":12, "y":0 },
+ { "matrix": [0, 13], "x":13, "y":0, "w":2 },
+ { "matrix": [0, 14], "x":15, "y":0 },
- {"label":"K10 (B1,C7)", "x":0, "y":1, "w":1.5},
- {"label":"K11 (B1,F6)", "x":1.5, "y":1},
- {"label":"K12 (B1,F5)", "x":2.5, "y":1},
- {"label":"K13 (B1,F4)", "x":3.5, "y":1},
- {"label":"K14 (B1,F1)", "x":4.5, "y":1},
- {"label":"K15 (B1,B7)", "x":5.5, "y":1},
- {"label":"K16 (B1,D5)", "x":6.5, "y":1},
- {"label":"K17 (B1,D1)", "x":7.5, "y":1},
- {"label":"K18 (B1,D2)", "x":8.5, "y":1},
- {"label":"K19 (B1,D3)", "x":9.5, "y":1},
- {"label":"K1A (B1,D4)", "x":10.5, "y":1},
- {"label":"K1B (B1,D0)", "x":11.5, "y":1},
- {"label":"K1C (B1,D6)", "x":12.5, "y":1},
- {"label":"K1D (B1,D7)", "x":13.5, "y":1, "w":1.5},
- {"label":"K1E (B1,B4)", "x":15, "y":1},
+ { "matrix": [1, 0], "x":0, "y":1, "w":1.5 },
+ { "matrix": [1, 1], "x":1.5, "y":1 },
+ { "matrix": [1, 2], "x":2.5, "y":1 },
+ { "matrix": [1, 3], "x":3.5, "y":1 },
+ { "matrix": [1, 4], "x":4.5, "y":1 },
+ { "matrix": [1, 5], "x":5.5, "y":1 },
+ { "matrix": [1, 6], "x":6.5, "y":1 },
+ { "matrix": [1, 7], "x":7.5, "y":1 },
+ { "matrix": [1, 8], "x":8.5, "y":1 },
+ { "matrix": [1, 9], "x":9.5, "y":1 },
+ { "matrix": [1, 10], "x":10.5, "y":1 },
+ { "matrix": [1, 11], "x":11.5, "y":1 },
+ { "matrix": [1, 12], "x":12.5, "y":1 },
+ { "matrix": [1, 13], "x":13.5, "y":1, "w":1.5 },
+ { "matrix": [1, 14], "x":15, "y":1 },
- {"label":"K20 (B2,C7)", "x":0, "y":2, "w":1.75},
- {"label":"K21 (B2,F6)", "x":1.75, "y":2},
- {"label":"K22 (B2,F5)", "x":2.75, "y":2},
- {"label":"K23 (B2,F4)", "x":3.75, "y":2},
- {"label":"K24 (B2,F1)", "x":4.75, "y":2},
- {"label":"K25 (B2,B7)", "x":5.75, "y":2},
- {"label":"K26 (B2,D5)", "x":6.75, "y":2},
- {"label":"K27 (B2,D1)", "x":7.75, "y":2},
- {"label":"K28 (B2,D2)", "x":8.75, "y":2},
- {"label":"K29 (B2,D3)", "x":9.75, "y":2},
- {"label":"K2A (B2,D4)", "x":10.75, "y":2},
- {"label":"K2B (B2,D0)", "x":11.75, "y":2},
- {"label":"K2D (B2,D7)", "x":12.75, "y":2, "w":2.25},
- {"label":"K2E (B2,B4)", "x":15, "y":2},
+ { "matrix": [2, 0], "x":0, "y":2, "w":1.75 },
+ { "matrix": [2, 1], "x":1.75, "y":2 },
+ { "matrix": [2, 2], "x":2.75, "y":2 },
+ { "matrix": [2, 3], "x":3.75, "y":2 },
+ { "matrix": [2, 4], "x":4.75, "y":2 },
+ { "matrix": [2, 5], "x":5.75, "y":2 },
+ { "matrix": [2, 6], "x":6.75, "y":2 },
+ { "matrix": [2, 7], "x":7.75, "y":2 },
+ { "matrix": [2, 8], "x":8.75, "y":2 },
+ { "matrix": [2, 9], "x":9.75, "y":2 },
+ { "matrix": [2, 10], "x":10.75, "y":2 },
+ { "matrix": [2, 11], "x":11.75, "y":2 },
+ { "matrix": [2, 13], "x":12.75, "y":2, "w":2.25 },
+ { "matrix": [2, 14], "x":15, "y":2 },
- {"label":"K30 (B3,C7)", "x":0, "y":3, "w":2.25},
- {"label":"K32 (B3,F5)", "x":2.25, "y":3},
- {"label":"K33 (B3,F4)", "x":3.25, "y":3},
- {"label":"K34 (B3,F1)", "x":4.25, "y":3},
- {"label":"K35 (B3,B7)", "x":5.25, "y":3},
- {"label":"K36 (B3,D5)", "x":6.25, "y":3},
- {"label":"K37 (B3,D1)", "x":7.25, "y":3},
- {"label":"K38 (B3,D2)", "x":8.25, "y":3},
- {"label":"K39 (B3,D3)", "x":9.25, "y":3},
- {"label":"K3A (B3,D4)", "x":10.25, "y":3},
- {"label":"K3B (B3,D0)", "x":11.25, "y":3},
- {"label":"K3C (B3,D6)", "x":12.25, "y":3, "w":1.75},
- {"label":"K3D (B3,D7)", "x":14, "y":3},
- {"label":"K3E (B3,B4)", "x":15, "y":3},
+ { "matrix": [3, 0], "x":0, "y":3, "w":2.25 },
+ { "matrix": [3, 2], "x":2.25, "y":3 },
+ { "matrix": [3, 3], "x":3.25, "y":3 },
+ { "matrix": [3, 4], "x":4.25, "y":3 },
+ { "matrix": [3, 5], "x":5.25, "y":3 },
+ { "matrix": [3, 6], "x":6.25, "y":3 },
+ { "matrix": [3, 7], "x":7.25, "y":3 },
+ { "matrix": [3, 8], "x":8.25, "y":3 },
+ { "matrix": [3, 9], "x":9.25, "y":3 },
+ { "matrix": [3, 10], "x":10.25, "y":3 },
+ { "matrix": [3, 11], "x":11.25, "y":3 },
+ { "matrix": [3, 12], "x":12.25, "y":3, "w":1.75 },
+ { "matrix": [3, 13], "x":14, "y":3 },
+ { "matrix": [3, 14], "x":15, "y":3 },
- {"label":"K40 (F7,C7)", "x":0, "y":4, "w":1.25},
- {"label":"K41 (F7,F6)", "x":1.25, "y":4, "w":1.25},
- {"label":"K43 (F7,F4)", "x":2.5, "y":4, "w":1.25},
- {"label":"K46 (F7,D5)", "x":3.75, "y":4, "w":6.25},
- {"label":"K4A (F7,D4)", "x":10, "y":4, "w":1.25},
- {"label":"K4B (F7,D0)", "x":11.25, "y":4, "w":1.25},
- {"label":"K4C (F7,D6)", "x":13, "y":4},
- {"label":"K4D (F7,D7)", "x":14, "y":4},
- {"label":"K4E (F7,B4)", "x":15, "y":4}
+ { "matrix": [4, 0], "x":0, "y":4, "w":1.25 },
+ { "matrix": [4, 1], "x":1.25, "y":4, "w":1.25 },
+ { "matrix": [4, 3], "x":2.5, "y":4, "w":1.25 },
+ { "matrix": [4, 6], "x":3.75, "y":4, "w":6.25 },
+ { "matrix": [4, 10], "x":10, "y":4, "w":1.25 },
+ { "matrix": [4, 11], "x":11.25, "y":4, "w":1.25 },
+ { "matrix": [4, 12], "x":13, "y":4 },
+ { "matrix": [4, 13], "x":14, "y":4 },
+ { "matrix": [4, 14], "x":15, "y":4 }
]
}
}
diff --git a/keyboards/idobao/id67/keymaps/default/keymap.c b/keyboards/idobao/id67/keymaps/default/keymap.c
index 54b39ad4a7..55e6fd88cd 100644
--- a/keyboards/idobao/id67/keymaps/default/keymap.c
+++ b/keyboards/idobao/id67/keymaps/default/keymap.c
@@ -1,23 +1,22 @@
-/* Copyright 2021 Tybera
- * Copyright 2022 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Tybera (@tybera)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Backspc│ ~ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PUp│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shft │Up │PDn│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │Ctrl│Win │Alt │ │Fn1 │Ctrl│ │Lf │Dn │Rt │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[0] = LAYOUT_65_ansi_blocker(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_TILD,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
@@ -25,12 +24,25 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │Tog│Up │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │Lf │Dn │Rt │ │ │ │ │ │Ins│Hom│PUp│ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │RST│Sp+│Sp-│ │Vl-│Mut│Vl+│Del│End│PDn│ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[1] = LAYOUT_65_ansi_blocker(
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______,
_______, RGB_TOG, KC_UP, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______,
_______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, KC_INS, KC_HOME, KC_PGUP, _______, _______,
- _______, QK_BOOT, RGB_SPI, RGB_SPD, _______, KC_VOLD, KC_MUTE, KC_VOLU, _______, KC_DEL, KC_END, KC_PGDN, _______, _______,
+ _______, QK_BOOT, RGB_SPI, RGB_SPD, _______, KC_VOLD, KC_MUTE, KC_VOLU, KC_DEL, KC_END, KC_PGDN, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
-
+ )
};
diff --git a/keyboards/idobao/id67/keymaps/idobao/keymap.c b/keyboards/idobao/id67/keymaps/idobao/keymap.c
new file mode 100644
index 0000000000..55ff6e5730
--- /dev/null
+++ b/keyboards/idobao/id67/keymaps/idobao/keymap.c
@@ -0,0 +1,341 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// Copyright 2022 IDOBAO (@idobaokb)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* ------------------------------------------------------------------
+ * This is the IDOBAO factory default keymap ;)
+ * ------------------------------------------------------------------ */
+
+#include QMK_KEYBOARD_H
+#include "version.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_disable_perkey:1;
+ #ifndef ID67_DISABLE_UNDERGLOW
+ bool rgb_disable_underglow:1;
+ #endif // ID67_DISABLE_UNDERGLOW
+ };
+} user_config_t;
+
+#endif // RGB_MATRIX_ENABLE
+
+enum {
+ KC_MCON = USER00, // macOS Open Mission Control
+ KC_LPAD, // macOS Open Launchpad
+ #ifdef RGB_MATRIX_ENABLE
+ RGB_TPK, // Toggle Per-Key
+ #ifndef ID67_DISABLE_UNDERGLOW
+ RGB_TUG, // Toggle Underglow
+ #endif // ID67_DISABLE_UNDERGLOW
+ #endif //RGB_MATRIX_ENABLE
+ KB_VRSN = USER09 // debug, type version
+};
+
+#ifndef RGB_MATRIX_ENABLE
+ #define RGB_TPK _______
+ #define RGB_TUG _______
+#else
+ #ifdef ID67_DISABLE_UNDERGLOW
+ #define RGB_TUG _______
+ #endif // ID67_DISABLE_UNDERGLOW
+#endif // RGB_MATRIX_ENABLE
+
+enum macos_consumer_usages {
+ _AC_SHOW_ALL_WINDOWS = 0x29F, // mapped to KC_MCON
+ _AC_SHOW_ALL_APPS = 0x2A0 // mapped to KC_LPAD
+};
+
+/* Special Keys */
+#define SK_LT1C LT(1, KC_CAPS) // Layer Tap 1, i.e., Tap = Caps Lock, Hold = Layer 1
+#define SK_LT2A LT(2, KC_APP) // Layer Tap 2, i.e., Tap = Menu, Hold = Layer 2
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Backspc│ ~ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │*Caps*│ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PUp│ *Caps* => `LT(1, KC_CAPS)`
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shft │Up │PDn│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │Ctrl│Win │Alt │ │Fn1 │*Mn*│ │Lf │Dn │Rt │ *Mn* => `LT(2, KC_APP)`
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
+ [0] = LAYOUT_65_ansi_blocker(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_TILD,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
+ SK_LT1C, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), SK_LT2A, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │Tog│Up │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│ │TUG│TPK│ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │Lf │Dn │Rt │ │ │ │ │ │Ins│Hom│PUp│ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │RST│Sp+│Sp-│ │Vl-│Mut│Vl+│Del│End│PDn│ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
+ [1] = LAYOUT_65_ansi_blocker(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______,
+ _______, RGB_TOG, KC_UP, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, RGB_TUG, RGB_TPK, _______, _______,
+ KC_CAPS, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, KC_INS, KC_HOME, KC_PGUP, _______, _______,
+ _______, QK_BOOT, RGB_SPI, RGB_SPD, KB_VRSN, KC_VOLD, KC_MUTE, KC_VOLU, KC_DEL, KC_END, KC_PGDN, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
+ [2] = LAYOUT_65_ansi_blocker(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ [3] = LAYOUT_65_ansi_blocker(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
+
+#ifdef RGB_MATRIX_ENABLE
+
+/*
+ * RGB Stuff
+ */
+
+#define ID67_CAPS_LOCK_KEY_INDEX 36 // position of Caps Lock key
+
+#define ID67_CAPS_LOCK_MAX_BRIGHTNESS 0xFF
+#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
+ #undef ID67_CAPS_LOCK_MAX_BRIGHTNESS
+ #define ID67_CAPS_LOCK_MAX_BRIGHTNESS RGB_MATRIX_MAXIMUM_BRIGHTNESS
+#endif
+
+#define ID67_CAPS_LOCK_VAL_STEP 8
+#ifdef RGB_MATRIX_VAL_STEP
+ #undef ID67_CAPS_LOCK_VAL_STEP
+ #define ID67_CAPS_LOCK_VAL_STEP RGB_MATRIX_VAL_STEP
+#endif
+
+user_config_t user_config;
+
+void id67_update_rgb_mode(void) {
+ uint8_t flags = LED_FLAG_ALL;
+
+ if (user_config.rgb_disable_perkey
+ #ifndef ID67_DISABLE_UNDERGLOW
+ && user_config.rgb_disable_underglow
+ #endif // ID67_DISABLE_UNDERGLOW
+ ) {
+ flags = 0; // All OFF Condition
+ } else {
+ if (user_config.rgb_disable_perkey) {
+ #ifndef ID67_DISABLE_UNDERGLOW
+ flags = LED_FLAG_UNDERGLOW | 0xF0;
+ #else
+ flags = 0xF0;
+ #endif // ID67_DISABLE_UNDERGLOW
+ }
+ #ifndef ID67_DISABLE_UNDERGLOW
+ if (user_config.rgb_disable_underglow) {
+ flags = LED_FLAG_MODIFIER | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR | 0xF0;
+ }
+ #endif // ID67_DISABLE_UNDERGLOW
+ }
+
+ if (flags == 0) {
+ rgb_matrix_set_flags(0);
+ rgb_matrix_set_color_all(HSV_OFF);
+ } else {
+ rgb_matrix_set_flags(flags);
+ rgb_matrix_enable_noeeprom();
+ }
+
+ eeconfig_update_kb(user_config.raw); // write back to EEPROM
+}
+
+void id67_get_rgb_mode(void) {
+ user_config.raw = eeconfig_read_kb(); // read config from EEPROM
+ id67_update_rgb_mode();
+}
+
+void keyboard_post_init_user(void) {
+ id67_get_rgb_mode();
+}
+
+void eeconfig_init_user(void) {
+ // EEPROM is getting reset!
+ user_config.raw = 0;
+ id67_update_rgb_mode();
+}
+
+void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
+ // Caps Lock key stuff
+
+ if (host_keyboard_led_state().caps_lock) {
+ uint8_t v = rgb_matrix_get_val();
+ if (v < ID67_CAPS_LOCK_VAL_STEP) {
+ v = ID67_CAPS_LOCK_VAL_STEP;
+ } else if (v < (ID67_CAPS_LOCK_MAX_BRIGHTNESS - ID67_CAPS_LOCK_VAL_STEP)) {
+ if (!user_config.rgb_disable_perkey) {
+ v += ID67_CAPS_LOCK_VAL_STEP; // inc. by one more step than current brightness
+ } // else leave as current brightness
+ } else {
+ v = ID67_CAPS_LOCK_MAX_BRIGHTNESS;
+ }
+ rgb_matrix_set_color(ID67_CAPS_LOCK_KEY_INDEX, v, v, v); // white, brightness adjusted
+ } else if (user_config.rgb_disable_perkey) {
+ rgb_matrix_set_color(ID67_CAPS_LOCK_KEY_INDEX, HSV_OFF); // off
+ }
+}
+
+#endif // RGB_MATRIX_ENABLE
+
+/*
+ * Extra keys and RGB Toggle handler
+ */
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+
+ switch (keycode) {
+
+ // handle RGB toggle key - this ensures caps lock always works
+ #ifdef RGB_MATRIX_ENABLE
+
+ case QK_BOOT:
+ if (record->event.pressed) {
+ rgb_matrix_set_color_all(RGB_MATRIX_MAXIMUM_BRIGHTNESS, 0, 0); // All red
+ rgb_matrix_driver.flush();
+ }
+ return true;
+
+ case RGB_TOG:
+ /* roll through the LED modes
+ * | Level | Per-key | Underglow |
+ * |-------------|---------|-----------|
+ * | 0 (default) | on | on |
+ * | 1 | OFF | on |
+ * | 2 | on | OFF |
+ * | 3 | OFF | OFF |
+ *
+ * for ID67_DISABLE_UNDERGLOW
+ * | Level | Per-key |
+ * |-------------|---------|
+ * | 0 (default) | on |
+ * | 1 | OFF |
+ */
+ if (record->event.pressed) {
+ if ((!user_config.rgb_disable_perkey)
+ #ifndef ID67_DISABLE_UNDERGLOW
+ && (!user_config.rgb_disable_underglow)
+ #endif // ID67_DISABLE_UNDERGLOW
+ ) {
+ user_config.rgb_disable_perkey = 1;
+
+ #ifndef ID67_DISABLE_UNDERGLOW
+
+ } else if (user_config.rgb_disable_perkey && (!user_config.rgb_disable_underglow)) {
+ user_config.rgb_disable_perkey = 0;
+ user_config.rgb_disable_underglow = 1;
+
+ } else if ((!user_config.rgb_disable_perkey) && user_config.rgb_disable_underglow) {
+ user_config.rgb_disable_perkey = 1;
+
+ #endif // ID67_DISABLE_UNDERGLOW
+
+ } else {
+ user_config.rgb_disable_perkey = 0;
+ #ifndef ID67_DISABLE_UNDERGLOW
+ user_config.rgb_disable_underglow = 0;
+ #endif // ID67_DISABLE_UNDERGLOW
+ }
+
+ id67_update_rgb_mode();
+ }
+ return false;
+
+ case RGB_TPK:
+ if (record->event.pressed) {
+ user_config.rgb_disable_perkey ^= 1;
+ id67_update_rgb_mode();
+ }
+ return false;
+
+ #ifndef ID67_DISABLE_UNDERGLOW
+
+ case RGB_TUG:
+ if (record->event.pressed) {
+ user_config.rgb_disable_underglow ^= 1;
+ id67_update_rgb_mode();
+ }
+ return false;
+
+ #endif // ID67_DISABLE_UNDERGLOW
+
+ case EE_CLR:
+ if (!record->event.pressed) { // on release
+ id67_get_rgb_mode();
+ }
+ return true; // let this one pass on
+
+ #endif // RGB_MATRIX_ENABLE
+
+ // print firmware version
+ case KB_VRSN:
+ if (!get_mods()) {
+ if (!record->event.pressed) {
+ SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " (v" QMK_VERSION ")");
+ }
+ }
+ return false;
+
+ // @see: https://github.com/qmk/qmk_firmware/issues/10111#issuecomment-752300353
+ case KC_MCON:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_WINDOWS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case KC_LPAD:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_APPS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ default:
+ return true; /* Process all other keycodes normally */
+ }
+}
diff --git a/keyboards/idobao/id80/v3/keymaps/via/rules.mk b/keyboards/idobao/id67/keymaps/idobao/rules.mk
index ca9fed0e6b..ca9fed0e6b 100644
--- a/keyboards/idobao/id80/v3/keymaps/via/rules.mk
+++ b/keyboards/idobao/id67/keymaps/idobao/rules.mk
diff --git a/keyboards/idobao/id67/keymaps/thewerther/config.h b/keyboards/idobao/id67/keymaps/thewerther/config.h
index a63a92b171..4cd526feea 100644
--- a/keyboards/idobao/id67/keymaps/thewerther/config.h
+++ b/keyboards/idobao/id67/keymaps/thewerther/config.h
@@ -1,23 +1,11 @@
-/* Copyright 2021 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Werther (@thewerther)
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define DRIVER_LED_UNDERGLOW 10
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
#if defined(RGB_MATRIX_ENABLE)
#undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
diff --git a/keyboards/idobao/id67/keymaps/thewerther/keymap.c b/keyboards/idobao/id67/keymaps/thewerther/keymap.c
index 8af720755f..ef37b210f5 100644
--- a/keyboards/idobao/id67/keymaps/thewerther/keymap.c
+++ b/keyboards/idobao/id67/keymaps/thewerther/keymap.c
@@ -1,19 +1,5 @@
-/* Copyright 2021 Tybera
- * Copyright 2021 thewerther
- *
- * 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/>.
- */
+// Copyright 2021 Werther (@thewerther)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
@@ -36,14 +22,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_MPLY, KC_MPRV, KC_MNXT, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME,
- _______, RESET, RGB_SPI, RGB_SPD, _______, KC_VOLD, KC_MUTE, KC_VOLU, _______, _______, _______, _______, _______, KC_END,
+ _______, QK_BOOT, RGB_SPI, RGB_SPD, _______, KC_VOLD, KC_MUTE, KC_VOLU, _______, _______, _______, _______, _______, KC_END,
_______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
void matrix_scan_user(void) {
-# if defined(RGB_MATRIX_ENABLE)
+ #if defined(RGB_MATRIX_ENABLE)
int current_effect = rgb_matrix_get_mode();
if (current_effect >= RGB_MATRIX_SOLID_REACTIVE_SIMPLE && current_effect <= RGB_MATRIX_SOLID_MULTISPLASH) {
// set all underglow leds to current color
@@ -52,6 +38,5 @@ void matrix_scan_user(void) {
rgb_matrix_set_color(i, current_color.r, current_color.g, current_color.b);
}
}
-# endif
+ #endif
}
-
diff --git a/keyboards/idobao/id67/keymaps/via/keymap.c b/keyboards/idobao/id67/keymaps/via/keymap.c
index ff0bfff745..0014fb3bbf 100644
--- a/keyboards/idobao/id67/keymaps/via/keymap.c
+++ b/keyboards/idobao/id67/keymaps/via/keymap.c
@@ -1,22 +1,22 @@
-/* Copyright 2021 Tybera
- *
- * 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/>.
- */
+// Copyright 2021 Tybera (@tybera)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Backspc│ ~ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PUp│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shft │Up │PDn│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │Ctrl│Win │Alt │ │Fn1 │Ctrl│ │Lf │Dn │Rt │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[0] = LAYOUT_65_ansi_blocker(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_TILD,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
@@ -24,13 +24,41 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │Tog│Up │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │Lf │Dn │Rt │ │ │ │ │ │Ins│Hom│PUp│ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │RST│Sp+│Sp-│ │Vl-│Mut│Vl+│Del│End│PDn│ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[1] = LAYOUT_65_ansi_blocker(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______,
_______, RGB_TOG, KC_UP, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______,
_______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, KC_INS, KC_HOME, KC_PGUP, _______, _______,
- _______, QK_BOOT, BL_DEC, BL_TOGG, BL_INC, KC_VOLD, KC_MUTE, KC_VOLU, _______, KC_DEL, KC_END, KC_PGDN, _______, _______,
+ _______, QK_BOOT, RGB_SPI, RGB_SPD, _______, KC_VOLD, KC_MUTE, KC_VOLU, KC_DEL, KC_END, KC_PGDN, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[2] = LAYOUT_65_ansi_blocker(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
@@ -38,11 +66,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
),
+
[3] = LAYOUT_65_ansi_blocker(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
+ )
};
diff --git a/keyboards/idobao/id67/keymaps/vinorodrigues/config.h b/keyboards/idobao/id67/keymaps/vinorodrigues/config.h
index 92b3ec0658..f7ada65953 100644
--- a/keyboards/idobao/id67/keymaps/vinorodrigues/config.h
+++ b/keyboards/idobao/id67/keymaps/vinorodrigues/config.h
@@ -1,26 +1,14 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* IDOBAO ID67 Keymap for a ID67 Bestype, built for Mac use
- * Copyright (C) 2022 Vino Rodrigues
- *
- * 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 3 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
-#if defined(RGB_MATRIX_ENABLE)
- #define VIA_QMK_RGBLIGHT_ENABLE
- #define ID67_DISABLE_UNDERGLOW // personal choice, I use a ID67 Bestype
+#ifdef RGB_MATRIX_ENABLE
+ #define ID67_DISABLE_UNDERGLOW
#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
#undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
diff --git a/keyboards/idobao/id67/keymaps/vinorodrigues/keymap.c b/keyboards/idobao/id67/keymaps/vinorodrigues/keymap.c
index c62db2c724..1bf6971730 100644
--- a/keyboards/idobao/id67/keymaps/vinorodrigues/keymap.c
+++ b/keyboards/idobao/id67/keymaps/vinorodrigues/keymap.c
@@ -1,19 +1,8 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*
* IDOBAO ID67 Keymap for a ID67 Bestype, built for Mac use
- * Copyright (C) 2022 Vino Rodrigues
- *
- * 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 3 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 <https://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
@@ -44,30 +33,85 @@ enum macos_consumer_usages {
#endif
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Backspc│ ~ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │*Caps*│ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │PUp│ *Caps* => `LT(1, KC_CAPS)`
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shft │Up │PDn│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │Ctrl│Opt │Comm│ │Fn1 │Fn2 │ │Lf │Dn │Rt │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[_BASE] = LAYOUT_65_ansi_blocker(
KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_GRAVE, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLASH, KC_DELETE, \
LT1_C_L, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, \
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, FN_MO13, FN_MO23, KC_LEFT, KC_DOWN, KC_RIGHT),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │ ~ │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│ ERASE │F13│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │ │Up │ │ │ │ │ │ │ │PSc│Hom│End│Eject│Ins│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ Caps │Lf │Dn │Rt │ │ │ │ │ │ │PUp│PDn│ enter │Hom│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shft │ │ │ │ │ │ │ │ │Ins│Del│Shift │ │End│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ctrl│opt │comm│ │ │Fn3 │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[_FN1] = LAYOUT_65_ansi_blocker(
KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_ERAS, KC_F13, \
_______, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PSCR, KC_HOME, KC_END, KC_EJCT, KC_INS, \
KC_CAPS, KC_LEFT, KC_DOWN, KC_RIGHT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGUP, KC_PGDN, KC_PENT, KC_HOME, \
KC_RSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_DELETE, KC_LSFT, _______, KC_END, \
KC_RCTL, KC_RALT, KC_RGUI, _______, _______, _______, _______, _______, _______),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │Esc│SB-│SB+│mMC│mLP│Br-│Br+│Prv│Ply│Nxt│Mut│Vl-│Vl+│ out │F14│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tog │Mod│ │ │ │ │ │ │ │ │ │ │ │ │PSc│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │mod│ │ │ │ │ │ │ │ │Hu+│Sa+│ │SLk│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │ │ │ │ │ │ │ │ │Hu-│Sa-│ │Br+│Pau│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ │Fn3 │ │ │Sp-│Br-│Sp+│
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[_FN2] = LAYOUT_65_ansi_blocker(
KC_ESC, KC_BRID, KC_BRIU, KC_MCON, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_OUT, KC_F14, \
RGB_TOG, RGB_MOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PSCR, \
XXXXXXX, RGB_RMOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_HUI, RGB_SAI, XXXXXXX, KC_SLCK, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_HUD, RGB_SAD, XXXXXXX, RGB_VAI, KC_PAUS, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_SPD, RGB_VAD, RGB_SPI),
+
+ /*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───â”
+ * │RST│M01│M02│M03│M04│M05│M06│M07│M08│M09│M10│M11│M12│ Power │F15│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │Sleep│ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ Debug │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ │ │ │ │Ver│ │ │ │ │ │ │ │M00│ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤
+ * │ │ │ │ Wake │ │ │ │M13│M14│M15│
+ * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘
+ */
[_FN3] = LAYOUT_65_ansi_blocker(
- RESET, MACRO01, MACRO02, MACRO03, MACRO04, MACRO05, MACRO06, MACRO07, MACRO08, MACRO09, MACRO10, MACRO11, MACRO12, KC_POWER, KC_F15, \
+ QK_BOOT, MACRO01, MACRO02, MACRO03, MACRO04, MACRO05, MACRO06, MACRO07, MACRO08, MACRO09, MACRO10, MACRO11, MACRO12, KC_POWER, KC_F15, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_SLEP, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, DEBUG, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KB_VRSN, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MACRO00, XXXXXXX, \
- XXXXXXX, XXXXXXX, XXXXXXX, KC_WAKE, XXXXXXX, XXXXXXX, MACRO13, MACRO14, MACRO15),
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_WAKE, XXXXXXX, XXXXXXX, MACRO13, MACRO14, MACRO15)
};
#ifdef RGB_MATRIX_ENABLE
@@ -248,12 +292,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case KC_MCON:
if (record->event.pressed) {
host_consumer_send(_AC_SHOW_ALL_WINDOWS);
+ } else {
+ host_consumer_send(0);
}
return false;
case KC_LPAD:
if (record->event.pressed) {
host_consumer_send(_AC_SHOW_ALL_APPS);
+ } else {
+ host_consumer_send(0);
}
return false;
diff --git a/keyboards/idobao/id67/keymaps/vinorodrigues/rules.mk b/keyboards/idobao/id67/keymaps/vinorodrigues/rules.mk
index 24f7bdab9c..cf6371fda0 100644
--- a/keyboards/idobao/id67/keymaps/vinorodrigues/rules.mk
+++ b/keyboards/idobao/id67/keymaps/vinorodrigues/rules.mk
@@ -1,5 +1,3 @@
LTO_ENABLE = yes
VIA_ENABLE = yes
-
-KEY_LOCK_ENABLE = no # Enable KC_LOCK support
-NKRO_ENABLE = no # N-Key Rollover must be OFF for mac keys to work
+NKRO_ENABLE = no # N-Key Rollover must be OFF for mac keys to work
diff --git a/keyboards/idobao/id67/post_rules.mk b/keyboards/idobao/id67/post_rules.mk
index 5eecdef4ce..32832a65b2 100644
--- a/keyboards/idobao/id67/post_rules.mk
+++ b/keyboards/idobao/id67/post_rules.mk
@@ -2,13 +2,7 @@
# this enables switching off thoes LEDs
# Usage: `make idobao/id67:default UNDERGLOW=off`
-ifeq ($(findstring off,$(UNDERGLOW)), off)
- $(info ** UNDERGLOW OFF)
- OPT_DEFS += -DID67_DISABLE_UNDERGLOW
-else ifeq ($(findstring no,$(UNDERGLOW)), no)
- $(info ** NO UNDERGLOW)
- OPT_DEFS += -DID67_DISABLE_UNDERGLOW
-else ifeq ($(findstring 0,$(UNDERGLOW)), 0)
- $(info ** Nil UNDERGLOW)
+UNDERGLOW ?= yes
+ifneq ($(strip $(UNDERGLOW)), yes)
OPT_DEFS += -DID67_DISABLE_UNDERGLOW
endif
diff --git a/keyboards/idobao/id67/readme.md b/keyboards/idobao/id67/readme.md
index b69e2e60b1..c2d59eedeb 100644
--- a/keyboards/idobao/id67/readme.md
+++ b/keyboards/idobao/id67/readme.md
@@ -1,25 +1,32 @@
# IDOBAO ID67
-![id67](https://idobao.github.io/assets/img/idobao-id67.png)
+![id67](https://i.imgur.com/XiEnksS.png)
A 65% hotswap keyboard from IDOBAO.
## ANSI support:
-* Keyboard Maintainer: Tybera *(fmr.)*, [thewerther](https://github.com/thewerther) *(curr.)*
-* Hardware Supported: IDOBAO ID67, ID67V2, ID67 Crystal & ID67 Bestype
-* Hardware Availability: IDOBAO website:
+* Keyboard Maintainer:
+ - [Tybera](https://github.com/tybera) *(fmr.)*
+ - [Werther](https://github.com/thewerther) *(curr.)*
+ - [Vino Rodrigues](https://github.com/vinorodrigues) *(curr.)*
+* Hardware Supported:
+ - **IDOBAO ID67**
+ - **ID67v2**
+ - **ID67 Crystal**
+ - **ID67 Bestype**
+* Hardware Availability: [IDOBAO.net](https://idobao.net/search?type=product&q=ID67*):
* [ID67](https://www.idobao.net/products/idobao-id67-65-hot-swappable-mechanical-keyboard-kit-1)
- * [ID67V2](https://idobao.net/products/idobao-id67v2-65-hot-swappable-mechanical-keyboard-kit)
+ * [ID67v2](https://idobao.net/products/idobao-id67v2-65-hot-swappable-mechanical-keyboard-kit)
* [ID67 Crystal](https://idobao.net/products/idobao-id67-crystal-keyboard-kit-gasket-mount-version)
* [ID67 Bestype](https://idobao.net/products/idobao-id67-bestype-keyboard-kit-aluminum-with-brass-weight)
-## Layout
+## ANSI Layout
-![ID67 layout](https://idobao.github.io/kle/idobao-id67.png)
+![ID67 Layout](https://idobao.github.io/kle/idobao-id67.png)
-## Compiling and flashing
+## Compiling and Flashing
Make example for this keyboard (after setting up your build environment):
diff --git a/keyboards/idobao/id67/rules.mk b/keyboards/idobao/id67/rules.mk
index 729e1ca67c..ce58b87be5 100644
--- a/keyboards/idobao/id67/rules.mk
+++ b/keyboards/idobao/id67/rules.mk
@@ -1,21 +1,5 @@
-# MCU name
-MCU = atmega32u4
-
-# Bootloader selection
-BOOTLOADER = atmel-dfu
-
# Build Options
# change yes to no to disable
#
-BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = no # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
-AUDIO_ENABLE = no # Audio output
RGB_MATRIX_ENABLE = yes # Enable RGB Matrix feature
RGB_MATRIX_DRIVER = WS2812 # ID67 uses WS2812 driver
-LAYOUTS = 65_ansi_blocker
diff --git a/keyboards/idobao/id80/v3/ansi/ansi.c b/keyboards/idobao/id80/v3/ansi/ansi.c
new file mode 100644
index 0000000000..2b298924cf
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/ansi.c
@@ -0,0 +1,76 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ansi.h"
+
+#define __ NO_LED
+
+#ifdef RGB_MATRIX_ENABLE
+
+/* Per-key LED's
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │79 ││78 │77 │76 │75 ││74 │73 │72 │71 ││70 │69 │68 │67 ││66 ││65 │
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │64 │63 │62 │61 │60 │59 │58 │57 │56 │55 │54 │53 │52 │ 51 ││50 │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ 49 │48 │47 │46 │45 │44 │43 │42 │41 │40 │39 │38 │37 │ 36 ││35 │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ 34 │33 │32 │31 │30 │29 │28 │27 │26 │25 │24 │23 │ 22 │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ 21 │20 │19 │18 │17 │16 │15 │14 │13 │12 │11 │ 10 │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ 9 │
+ * │ 8 │ 7 │ 6 │ 5 │ 4 │ 3 │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ 2 │ 1 │ 0 │
+ * └───┴───┴───┘
+ * Underglow (as seen from top)
+ * ┌────┬────┬────┬────┬────┬────â”
+ * │ 80 │ 81 │ 82 │ 83 │ 84 │ 85 │
+ * ├────┼────┴────┴────┴────┼────┤
+ * │ 93 │ │ 86 │
+ * ├────┼────┬────┬────┬────┼────┤
+ * │ 92 │ 91 │ 90 │ 89 │ 88 │ 87 │
+ * └────┴────┴────┴────┴────┴────┘
+ */
+
+led_config_t g_led_config = { {
+ // Key Matrix to LED Index
+ /* Generated with: https://xelus.netlify.app/guides/KLE_to_RGB_parser */
+ { 8, 21, 34, 49, 64, 79, __, __, __, __, __ },
+ { 7, __, 33, 48, 63, 78, __, __, __, __, __ },
+ { 6, 20, 32, 47, 62, 77, __, __, 35, 50, 65 },
+ { 0, 19, 31, 46, 61, 76, 9, __, 36, __, 67 },
+ { 1, 18, 30, 45, 60, 75, 10, 22, 37, 52, 68 },
+ { 2, 17, 29, 44, 59, 74, 11, 23, 38, 53, 69 },
+ { 5, 16, 28, 43, 58, 73, __, __, __, 51, 66 },
+ { 3, 15, 27, 42, 57, 72, 12, 24, 39, 54, 70 },
+ { 4, 14, 26, 41, 56, 71, 13, 25, 40, 55, __ },
+}, {
+ /* NB: Reversed order */
+ // per-key
+ {224,64 }, {209,64 }, {195,64 }, {173,61 }, {151,61 }, { 94,61 }, { 39,61 }, { 20,61 }, { 2,61 },
+ {209,52 }, {185,49 }, {165,49 }, {151,49 }, {136,49 }, {121,49 }, {106,49 }, { 92,49 }, { 77,49 }, { 62,49 }, { 48,49 }, { 33,49 }, { 9,49 },
+ {196,38 }, {173,38 }, {158,38 }, {143,38 }, {129,38 }, {114,38 }, { 99,38 }, { 84,38 }, { 70,38 }, { 55,38 }, { 40,38 }, { 26,38 }, { 6,38 },
+ {224,26 }, {202,26 }, {184,26 }, {169,26 }, {154,26 }, {140,26 }, {125,26 }, {110,26 }, { 95,26 }, { 81,26 }, { 66,26 }, { 51,26 }, { 37,26 }, { 22,26 }, { 4,26 },
+ {224,15 }, {198,15 }, {176,15 }, {162,15 }, {147,15 }, {132,15 }, {118,15 }, {103,15 }, { 88,15 }, { 73,15 }, { 59,15 }, { 44,15 }, { 29,15 }, { 15,15 }, { 0,15 },
+ {224,0 }, {206,0 }, {187,0 }, {173,0 }, {158,0 }, {143,0 }, {125,0 }, {110,0 }, { 95,0 }, { 81,0 }, { 62,0 }, { 48,0 }, { 33,0 }, { 18,0 }, { 0,0 },
+ // underglow
+ { 0,0 }, { 45,0 }, { 90,0 }, {134,0 }, {179,0 }, {224,0 },
+ {224,32 },
+ {224,64 }, {179,64 }, {134,64 }, { 90,64 }, { 45,64 }, { 0,64 },
+ { 0,32 }
+}, {
+ /* NB: Reversed order */
+ 4, 4, 4, 4, 4, 1, 4, 4, 4,
+ 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ //
+ 2, 2, 2, 2, 2, 2,
+ 2,
+ 2, 2, 2, 2, 2, 2,
+ 2
+} };
+
+#endif
diff --git a/keyboards/idobao/id80/v3/ansi/ansi.h b/keyboards/idobao/id80/v3/ansi/ansi.h
new file mode 100644
index 0000000000..d9bef6d021
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/ansi.h
@@ -0,0 +1,6 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "quantum.h"
diff --git a/keyboards/idobao/id80/v3/ansi/config.h b/keyboards/idobao/id80/v3/ansi/config.h
new file mode 100644
index 0000000000..1b99fd7908
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/config.h
@@ -0,0 +1,97 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "config_common.h"
+
+/* --------------------------------
+ * Bootmagic Lite key configuration
+ * use the Esc key
+ * -------------------------------- */
+
+#define BOOTMAGIC_LITE_ROW 0
+#define BOOTMAGIC_LITE_COLUMN 5
+
+/* ----------------
+ * RGB Matrix stuff
+ * ---------------- */
+
+#define RGB_DI_PIN E2
+
+// RGB Matrix config
+#if defined(RGB_DI_PIN) && defined(RGB_MATRIX_ENABLE)
+
+ #define DRIVER_LED_TOTAL 94
+
+ #define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
+ #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180 // limits maximum brightness of LEDs to x out of 255. If not defined maximum brightness is set to 255
+
+ #define RGB_MATRIX_KEYPRESSES
+
+ #define ENABLE_RGB_MATRIX_SOLID_COLOR // Static single color
+ #define ENABLE_RGB_MATRIX_ALPHAS_MODS // Static dual hue, speed is hue for secondary hue
+ #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN // Static gradient top to bottom, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT // Static gradient left to right, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_BREATHING // Single hue brightness cycling animation
+ #define ENABLE_RGB_MATRIX_BAND_SAT // Single hue band fading saturation scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_VAL // Single hue band fading brightness scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT // Single hue 3 blade spinning pinwheel fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL // Single hue 3 blade spinning pinwheel fades brightness
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT // Single hue spinning spiral fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL // Single hue spinning spiral fades brightness
+ #define ENABLE_RGB_MATRIX_CYCLE_ALL // Full keyboard solid hue cycling through full gradient
+ #define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT // Full gradient scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN // Full gradient scrolling top to bottom
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN // Full gradient scrolling out to in
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL // Full dual gradients scrolling out to in
+ #define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON // Full gradient Chevron shaped scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL // Full gradient spinning pinwheel around center of keyboard
+ #define ENABLE_RGB_MATRIX_CYCLE_SPIRAL // Full gradient spinning spiral around center of keyboard
+ #define ENABLE_RGB_MATRIX_DUAL_BEACON // Full gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_BEACON // Full tighter gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS // Full dual gradients spinning two halfs of keyboard
+ #define ENABLE_RGB_MATRIX_RAINDROPS // Randomly changes a single key's hue
+ #define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS // Randomly changes a single key's hue and saturation
+ #define ENABLE_RGB_MATRIX_HUE_BREATHING // Hue shifts up a slight amount at the same time, then shifts back
+ #define ENABLE_RGB_MATRIX_HUE_PENDULUM // Hue shifts up a slight amount in a wave to the right, then back to the left
+ #define ENABLE_RGB_MATRIX_HUE_WAVE // Hue shifts up a slight amount and then back down in a wave to the right
+
+ /* don't need `#if`, animation modes themselves check defines
+ * #if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) */
+ // #define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+ // #define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+ /* #endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS */
+
+ /* don't need `#if`, animation modes themselves check defines
+ * #if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES) */
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE // Pulses keys hit to hue & value then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue, pulses keys hit to shifted hue then fades to current hue
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SPLASH // Full gradient & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_MULTISPLASH // Full gradient & value pulse away from multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_SPLASH // Hue & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH // Hue & value pulse away from multiple key hits then fades value out
+ /* #endif // RGB_MATRIX_KEYPRESSES | RGB_MATRIX_KEYRELEASES */
+#endif // RGB_MATRIX_ENABLE
+
+/* -----------------------
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ * ----------------------- */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
diff --git a/keyboards/idobao/id80/v3/ansi/info.json b/keyboards/idobao/id80/v3/ansi/info.json
new file mode 100644
index 0000000000..c7768130e1
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/info.json
@@ -0,0 +1,121 @@
+{
+ "manufacturer": "IDOBAO",
+ "keyboard_name": "IDOBAO ID80v3",
+ "maintainer": "vinorodrigues",
+ "bootloader": "atmel-dfu",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "mousekey": true,
+ "extrakey": true,
+ "console": false,
+ "command": false,
+ "nkro": true,
+ "backlight": false,
+ "rgblight": false
+ },
+ "matrix_pins": {
+ "cols": ["B7", "B3", "B2", "B1", "B0", "E6", "F1", "F4", "F5", "F6", "F7"],
+ "rows": ["D0", "D1", "D2", "D3", "D5", "D4", "D6", "D7", "B4"]
+ },
+ "processor": "atmega32u4",
+ "url": "https://idobao.net/search?type=product&q=id80*",
+ "usb": {
+ "vid": "0x6964",
+ "pid": "0x0380",
+ "device_version": "3.0.0"
+ },
+ "layouts": {
+ "LAYOUT_80_ansi": {
+ "layout": [
+ { "matrix": [0, 5], "x": 0, "y": 0 },
+ { "matrix": [1, 5], "x": 1.25, "y": 0 },
+ { "matrix": [2, 5], "x": 2.25, "y": 0 },
+ { "matrix": [3, 5], "x": 3.25, "y": 0 },
+ { "matrix": [4, 5], "x": 4.25, "y": 0 },
+ { "matrix": [5, 5], "x": 5.5, "y": 0 },
+ { "matrix": [6, 5], "x": 6.5, "y": 0 },
+ { "matrix": [7, 5], "x": 7.5, "y": 0 },
+ { "matrix": [8, 5], "x": 8.5, "y": 0 },
+ { "matrix": [7, 10], "x": 9.75, "y": 0 },
+ { "matrix": [5, 10], "x": 10.75, "y": 0 },
+ { "matrix": [4, 10], "x": 11.75, "y": 0 },
+ { "matrix": [3, 10], "x": 12.75, "y": 0 },
+ { "matrix": [6, 10], "x": 14, "y": 0 },
+ { "matrix": [2, 10], "x": 15.25, "y": 0 },
+
+ { "matrix": [0, 4], "x": 0, "y": 1.25 },
+ { "matrix": [1, 4], "x": 1, "y": 1.25 },
+ { "matrix": [2, 4], "x": 2, "y": 1.25 },
+ { "matrix": [3, 4], "x": 3, "y": 1.25 },
+ { "matrix": [4, 4], "x": 4, "y": 1.25 },
+ { "matrix": [5, 4], "x": 5, "y": 1.25 },
+ { "matrix": [6, 4], "x": 6, "y": 1.25 },
+ { "matrix": [7, 4], "x": 7, "y": 1.25 },
+ { "matrix": [8, 4], "x": 8, "y": 1.25 },
+ { "matrix": [8, 9], "x": 9, "y": 1.25 },
+ { "matrix": [7, 9], "x": 10, "y": 1.25 },
+ { "matrix": [5, 9], "x": 11, "y": 1.25 },
+ { "matrix": [4, 9], "x": 12, "y": 1.25 },
+ { "matrix": [6, 9], "x": 13, "y": 1.25, "w": 2 },
+ { "matrix": [2, 9], "x": 15.25, "y": 1.25 },
+
+ { "matrix": [0, 3], "x":0, "y":2.25, "w":1.5},
+ { "matrix": [1, 3], "x":1.5, "y":2.25},
+ { "matrix": [2, 3], "x":2.5, "y":2.25},
+ { "matrix": [3, 3], "x":3.5, "y":2.25},
+ { "matrix": [4, 3], "x":4.5, "y":2.25},
+ { "matrix": [5, 3], "x":5.5, "y":2.25},
+ { "matrix": [6, 3], "x":6.5, "y":2.25},
+ { "matrix": [7, 3], "x":7.5, "y":2.25},
+ { "matrix": [8, 3], "x":8.5, "y":2.25},
+ { "matrix": [8, 8], "x":9.5, "y":2.25},
+ { "matrix": [7, 8], "x":10.5, "y":2.25},
+ { "matrix": [5, 8], "x":11.5, "y":2.25},
+ { "matrix": [4, 8], "x":12.5, "y":2.25},
+ { "matrix": [3, 8], "x":13.5, "y":2.25, "w":1.5},
+ { "matrix": [2, 8], "x":15.25, "y":2.25},
+
+ { "matrix": [0, 2], "x":0, "y":3.25, "w":1.75},
+ { "matrix": [1, 2], "x":1.75, "y":3.25},
+ { "matrix": [2, 2], "x":2.75, "y":3.25},
+ { "matrix": [3, 2], "x":3.75, "y":3.25},
+ { "matrix": [4, 2], "x":4.75, "y":3.25},
+ { "matrix": [5, 2], "x":5.75, "y":3.25},
+ { "matrix": [6, 2], "x":6.75, "y":3.25},
+ { "matrix": [7, 2], "x":7.75, "y":3.25},
+ { "matrix": [8, 2], "x":8.75, "y":3.25},
+ { "matrix": [8, 7], "x":9.75, "y":3.25},
+ { "matrix": [7, 7], "x":10.75, "y":3.25},
+ { "matrix": [5, 7], "x":11.75, "y":3.25},
+ { "matrix": [4, 7], "x":12.75, "y":3.25, "w":2.25},
+
+ { "matrix": [0, 1], "x":0, "y":4.25, "w":2.25},
+ { "matrix": [2, 1], "x":2.25, "y":4.25},
+ { "matrix": [3, 1], "x":3.25, "y":4.25},
+ { "matrix": [4, 1], "x":4.25, "y":4.25},
+ { "matrix": [5, 1], "x":5.25, "y":4.25},
+ { "matrix": [6, 1], "x":6.25, "y":4.25},
+ { "matrix": [7, 1], "x":7.25, "y":4.25},
+ { "matrix": [8, 1], "x":8.25, "y":4.25},
+ { "matrix": [8, 6], "x":9.25, "y":4.25},
+ { "matrix": [7, 6], "x":10.25, "y":4.25},
+ { "matrix": [5, 6], "x":11.25, "y":4.25},
+ { "matrix": [4, 6], "x":12.25, "y":4.25, "w":1.75},
+
+ { "matrix": [3, 6], "x":14.25, "y":4.5},
+
+ { "matrix": [0, 0], "x":0, "y":5.25, "w":1.25},
+ { "matrix": [1, 0], "x":1.25, "y":5.25, "w":1.25},
+ { "matrix": [2, 0], "x":2.5, "y":5.25, "w":1.25},
+ { "matrix": [6, 0], "y":5.25, "w":6.25},
+ { "matrix": [8, 0], "x":10, "y":5.25, "w":1.5},
+ { "matrix": [7, 0], "x":11.5, "y":5.25, "w":1.5},
+
+ { "matrix": [5, 0], "x":13.25, "y":5.5},
+ { "matrix": [4, 0], "x":14.25, "y":5.5},
+ { "matrix": [3, 0], "x":15.25, "y":5.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/idobao/id80/v3/ansi/keymaps/default/keymap.c b/keyboards/idobao/id80/v3/ansi/keymaps/default/keymap.c
new file mode 100644
index 0000000000..127647c664
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/keymaps/default/keymap.c
@@ -0,0 +1,56 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Esc││F1 │F2 │F3 │F4 ││F5 │F6 │F7 │F8 ││F9 │F10│F11│F12││Fn1││Ins│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │`~ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │-_ │=+ │Backspc││Hom│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │[{ │]} │ \| ││Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │;: │'" │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │,< │.> │/? │Shift │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ ↑ │
+ * │Ctrl│Win │Alt │ Space │ Alt │Ctrl │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ ↠│ ↓ │ → │
+ * └───┴───┴───┘
+ */
+ [0] = LAYOUT_80_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MO(1), KC_INS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Rst││ │ │ │ ││ │ │ │ ││ │PSc│SLk│Pau││ ││Mut│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││Vl+│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ │Tog│ │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│Sp+│Sp-│ │ ││Vl-│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ │ │ │mod│ │ │NKR│ │ │ │ │ │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│PUp│
+ * │ │ │ │ │ │ │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│Hom│PDn│End│
+ * └───┴───┴───┘
+ */
+ [1] = LAYOUT_80_ansi(
+ QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_MUTE,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU,
+ _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, _______, _______, KC_VOLD,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, RGB_RMOD, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP,
+ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+ )
+};
diff --git a/keyboards/idobao/id80/v3/ansi/keymaps/idobao/keymap.c b/keyboards/idobao/id80/v3/ansi/keymaps/idobao/keymap.c
new file mode 100644
index 0000000000..e0d786e5e2
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/keymaps/idobao/keymap.c
@@ -0,0 +1,315 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// Copyright 2022 IDOBAO (@idobaokb)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* ------------------------------------------------------------------
+ * This is the IDOBAO factory default keymap ;)
+ * ------------------------------------------------------------------ */
+
+#include QMK_KEYBOARD_H
+#include "version.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_disable_perkey:1;
+ bool rgb_disable_underglow:1;
+ };
+} user_config_t;
+
+#endif // RGB_MATRIX_ENABLE
+
+enum {
+ _BASE = 0,
+ _FN1,
+ _FN2,
+ _FN3
+};
+
+enum {
+ KC_MCON = USER00, // macOS Open Mission Control
+ KC_LPAD, // macOS Open Launchpad
+ #ifdef RGB_MATRIX_ENABLE
+ RGB_TPK, // Toggle Per-Key
+ RGB_TUG, // Toggle Underglow
+ #endif // RGB_MATRIX_ENABLE
+ KB_VRSN = USER09 // debug, type version
+};
+
+#ifndef RGB_MATRIX_ENABLE
+ #define RGB_TPK _______
+ #define RGB_TUG _______
+#endif // RGB_MATRIX_ENABLE
+
+enum macos_consumer_usages {
+ _AC_SHOW_ALL_WINDOWS = 0x29F, // mapped to KC_MCON
+ _AC_SHOW_ALL_APPS = 0x2A0 // mapped to KC_LPAD
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Esc││F1 │F2 │F3 │F4 ││F5 │F6 │F7 │F8 ││F9 │F10│F11│F12││Fn1││Ins│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │`~ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │-_ │=+ │Backspc││Hom│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │[{ │]} │ \| ││Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │;: │'" │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │,< │.> │/? │Shift │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ ↑ │
+ * │Ctrl│Win │Alt │ Space │ Alt │Ctrl │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ ↠│ ↓ │ → │
+ * └───┴───┴───┘
+ */
+ [_BASE] = LAYOUT_80_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MO(_FN1), KC_INS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Rst││ │ │ │ ││ │ │ │ ││ │PSc│SLk│Pau││ ││Mut│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││Vl+│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ │Tog│ │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│Sp+│Sp-│ │ ││Vl-│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ │ │ │mod│Ver│ │NKR│ │ │ │ │ │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│PUp│
+ * │ │ │ │ │ │ │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│Hom│PDn│End│
+ * └───┴───┴───┘
+ */
+ [_FN1] = LAYOUT_80_ansi(
+ QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_MUTE,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU,
+ _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, _______, _______, KC_VOLD,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, RGB_RMOD, KB_VRSN, _______, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP,
+ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+ ),
+
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │ ││ │ │ │ ││ │ │ │ ││ │ │ │ ││ ││ │
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ │
+ * │ │ │ │ │ │ │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ │ │ │
+ * └───┴───┴───┘
+ */
+ [_FN2] = LAYOUT_80_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ [_FN3] = LAYOUT_80_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
+
+#ifdef RGB_MATRIX_ENABLE
+
+/*
+ * RGB Stuff
+ */
+
+#define ID80_CAPS_LOCK_KEY_INDEX 34 // position of Caps Lock key
+
+#define ID80_CAPS_LOCK_MAX_BRIGHTNESS 0xFF
+#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
+ #undef ID80_CAPS_LOCK_MAX_BRIGHTNESS
+ #define ID80_CAPS_LOCK_MAX_BRIGHTNESS RGB_MATRIX_MAXIMUM_BRIGHTNESS
+#endif
+
+#define ID80_CAPS_LOCK_VAL_STEP 8
+#ifdef RGB_MATRIX_VAL_STEP
+ #undef ID80_CAPS_LOCK_VAL_STEP
+ #define ID80_CAPS_LOCK_VAL_STEP RGB_MATRIX_VAL_STEP
+#endif
+
+user_config_t user_config;
+
+void id80_update_rgb_mode(void) {
+ uint8_t flags = LED_FLAG_ALL;
+
+ if (user_config.rgb_disable_perkey && user_config.rgb_disable_underglow) {
+ flags = 0; // All OFF Condition
+ } else {
+ if (user_config.rgb_disable_perkey) {
+ flags = LED_FLAG_UNDERGLOW | 0xF0;
+ }
+ if (user_config.rgb_disable_underglow) {
+ flags = LED_FLAG_MODIFIER | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR | 0xF0;
+ }
+ }
+
+ if (flags == 0) {
+ rgb_matrix_set_flags(0);
+ rgb_matrix_set_color_all(HSV_OFF);
+ } else {
+ rgb_matrix_set_flags(flags);
+ rgb_matrix_enable_noeeprom();
+ }
+
+ eeconfig_update_kb(user_config.raw); // write back to EEPROM
+}
+
+void id80_get_rgb_mode(void) {
+ user_config.raw = eeconfig_read_kb(); // read config from EEPROM
+ id80_update_rgb_mode();
+}
+
+void keyboard_post_init_user(void) {
+ id80_get_rgb_mode();
+}
+
+void eeconfig_init_user(void) {
+ // EEPROM is getting reset!
+ user_config.raw = 0;
+ id80_update_rgb_mode();
+}
+
+void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
+ // Caps Lock key stuff
+
+ if (host_keyboard_led_state().caps_lock) {
+ uint8_t v = rgb_matrix_get_val();
+ if (v < ID80_CAPS_LOCK_VAL_STEP) {
+ v = ID80_CAPS_LOCK_VAL_STEP;
+ } else if (v < (ID80_CAPS_LOCK_MAX_BRIGHTNESS - ID80_CAPS_LOCK_VAL_STEP)) {
+ if (!user_config.rgb_disable_perkey) {
+ v += ID80_CAPS_LOCK_VAL_STEP; // inc. by one more step than current brightness
+ } // else leave as current brightness
+ } else {
+ v = ID80_CAPS_LOCK_MAX_BRIGHTNESS;
+ }
+ rgb_matrix_set_color(ID80_CAPS_LOCK_KEY_INDEX, v, v, v); // white, brightness adjusted
+ } else if (user_config.rgb_disable_perkey) {
+ rgb_matrix_set_color(ID80_CAPS_LOCK_KEY_INDEX, HSV_OFF); // off
+ }
+}
+
+#endif // RGB_MATRIX_ENABLE
+
+/*
+ * Extra keys and RGB Toggle handler
+ */
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+
+ switch (keycode) {
+
+ // handle RGB toggle key - this ensures caps lock always works
+ #ifdef RGB_MATRIX_ENABLE
+
+ case QK_BOOT:
+ if (record->event.pressed) {
+ rgb_matrix_set_color_all(RGB_MATRIX_MAXIMUM_BRIGHTNESS, 0, 0); // All red
+ rgb_matrix_driver.flush();
+ }
+ return true;
+
+ case RGB_TOG:
+ /* roll through the LED modes
+ * | Level | Per-key | Underglow |
+ * |------------|---------|-----------|
+ * | 0 (defalt) | on | on |
+ * | 1 | OFF | on |
+ * | 2 | on | OFF |
+ * | 3 | OFF | OFF |
+ */
+ if (record->event.pressed) {
+ if ( (!user_config.rgb_disable_perkey) && (!user_config.rgb_disable_underglow) ) {
+ user_config.rgb_disable_perkey = 1;
+ } else if ( user_config.rgb_disable_perkey && (!user_config.rgb_disable_underglow) ) {
+ user_config.rgb_disable_perkey = 0;
+ user_config.rgb_disable_underglow = 1;
+ } else if ( (!user_config.rgb_disable_perkey) && user_config.rgb_disable_underglow ) {
+ user_config.rgb_disable_perkey = 1;
+ } else {
+ user_config.rgb_disable_perkey = 0;
+ user_config.rgb_disable_underglow = 0;
+ }
+ id80_update_rgb_mode();
+ }
+ return false;
+
+ case RGB_TPK:
+ if (record->event.pressed) {
+ user_config.rgb_disable_perkey ^= 1;
+ id80_update_rgb_mode();
+ }
+ return false;
+
+ case RGB_TUG:
+ if (record->event.pressed) {
+ user_config.rgb_disable_underglow ^= 1;
+ id80_update_rgb_mode();
+ }
+ return false;
+
+ case EE_CLR:
+ if (!record->event.pressed) { // on release
+ id80_get_rgb_mode();
+ }
+ return true; // let this one pass on
+
+ #endif // RGB_MATRIX_ENABLE
+
+ // print firmware version
+ case KB_VRSN:
+ if (!get_mods()) {
+ if (!record->event.pressed) {
+ SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " (v" QMK_VERSION ")");
+ }
+ }
+ return false;
+
+ // @see: https://github.com/qmk/qmk_firmware/issues/10111#issuecomment-752300353
+ case KC_MCON:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_WINDOWS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case KC_LPAD:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_APPS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ default:
+ return true; /* Process all other keycodes normally */
+ }
+}
diff --git a/keyboards/idobao/id80/v3/ansi/keymaps/idobao/rules.mk b/keyboards/idobao/id80/v3/ansi/keymaps/idobao/rules.mk
new file mode 100644
index 0000000000..ca9fed0e6b
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/keymaps/idobao/rules.mk
@@ -0,0 +1,2 @@
+LTO_ENABLE = yes
+VIA_ENABLE = yes
diff --git a/keyboards/idobao/id80/v3/ansi/keymaps/via/keymap.c b/keyboards/idobao/id80/v3/ansi/keymaps/via/keymap.c
new file mode 100644
index 0000000000..9ca5d285fa
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/keymaps/via/keymap.c
@@ -0,0 +1,90 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Esc││F1 │F2 │F3 │F4 ││F5 │F6 │F7 │F8 ││F9 │F10│F11│F12││Fn1││Ins│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │`~ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │-_ │=+ │Backspc││Hom│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │[{ │]} │ \| ││Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │;: │'" │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │,< │.> │/? │Shift │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ ↑ │
+ * │Ctrl│Win │Alt │ Space │ Alt │Ctrl │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ ↠│ ↓ │ → │
+ * └───┴───┴───┘
+ */
+ [0] = LAYOUT_80_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MO(1), KC_INS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │Rst││ │ │ │ ││ │ │ │ ││ │PSc│SLk│Pau││ ││Mut│
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││Vl+│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ │Tog│ │Mod│Hu+│Hu-│Sa+│Sa-│Br+│Br-│Sp+│Sp-│ │ ││Vl-│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ │ │ │mod│ │ │NKR│ │ │ │ │ │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│PUp│
+ * │ │ │ │ │ │ │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│Hom│PDn│End│
+ * └───┴───┴───┘
+ */
+ [1] = LAYOUT_80_ansi(
+ QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_MUTE,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU,
+ _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, _______, _______, KC_VOLD,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, RGB_RMOD, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP,
+ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+ ),
+
+ /*
+ * ┌───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───┬───┬───┬───â”┌───â”┌───â”
+ * │ ││ │ │ │ ││ │ │ │ ││ │ │ │ ││ ││ │
+ * ├───┼┴──┬┴──┬┴──┬┴──┬┴┴─┬─┴─┬─┴─┬─┴─┬─┴┴┬──┴┬──┴┬──┴┬──┴┴───┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤├───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤└───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │┌───â”
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴──┬───┘│ │
+ * │ │ │ │ │ │ │┌───┼───┼───â”
+ * └────┴────┴────┴────────────────────────┴─────┴─────┘│ │ │ │
+ * └───┴───┴───┘
+ */
+ [2] = LAYOUT_80_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ [3] = LAYOUT_80_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
diff --git a/keyboards/idobao/id80/v3/ansi/keymaps/via/rules.mk b/keyboards/idobao/id80/v3/ansi/keymaps/via/rules.mk
new file mode 100644
index 0000000000..ca9fed0e6b
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+LTO_ENABLE = yes
+VIA_ENABLE = yes
diff --git a/keyboards/idobao/id80/v3/ansi/rules.mk b/keyboards/idobao/id80/v3/ansi/rules.mk
new file mode 100644
index 0000000000..eab741fd0a
--- /dev/null
+++ b/keyboards/idobao/id80/v3/ansi/rules.mk
@@ -0,0 +1,5 @@
+# This file intentionally left blank
+# ** settings are data driven & stored in `info.json` **
+
+RGB_MATRIX_ENABLE = yes
+RGB_MATRIX_DRIVER = WS2812
diff --git a/keyboards/idobao/id80/v3/config.h b/keyboards/idobao/id80/v3/config.h
deleted file mode 100644
index 4b2fb8d056..0000000000
--- a/keyboards/idobao/id80/v3/config.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-Copyright 2020 Sergey Vlasov <sigprof@gmail.com>
-Copyright 2022 peepeetee
-
-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 "config_common.h"
-
-/* USB Device descriptor parameter */
-#define VENDOR_ID 0x6964 /* "id" */
-#define PRODUCT_ID 0x0080
-#define DEVICE_VER 0x0003
-#define MANUFACTURER IDOBAO
-#define PRODUCT ID80 v3
-
-
-/* key matrix size */
-#define MATRIX_ROWS 9
-#define MATRIX_COLS 11
-
-/*
- * Keyboard Matrix Assignments
- *
- * Change this to how you wired your keyboard
- * COLS: AVR pins used for columns, left to right
- * ROWS: AVR pins used for rows, top to bottom
- * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
- * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
- *
- * The matrix description in the vendor-supplied JSON file for kbfirmware.com
- * had 9 columns:
- * { D0, D1, D2, D3, D5, D4, D6, D7, B4 }
- * and 12 rows:
- * { B7, B3, B2, B1, B0, E6, F0, F1, F4, F5, F6, F7 }
- * However, the row 6 was completely empty, and the pin F0 was not actually
- * routed anywhere on the PCB, therefore this row was removed to save some
- * resources (the EEPROM space for dynamic keymaps is especially scarce).
- *
- * After doing the above change, the matrix was transposed (rows and columns
- * were swapped), because a matrix with the COL2ROW layout can be scanned much
- * more efficiently than a matrix with the ROW2COL layout (depending on various
- * optimizations, the difference in scan rate can be over 2 times). Because of
- * this, the "columns" in the matrix layout now mostly correspond to physical
- * rows, and the "rows" have mostly vertical physical orientation.
- */
-#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5, D4, D6, D7, B4 }
-#define MATRIX_COL_PINS { B7, B3, B2, B1, B0, E6, F1, F4, F5, F6, F7 }
-
-#define DIODE_DIRECTION COL2ROW
-
-#undef RGB_DI_PIN
-#define RGB_DI_PIN B6
-#ifdef RGB_MATRIX_ENABLE
-# define DRIVER_LED_TOTAL 96 /* 16 Bottom 80 top*/
-# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180 // Limit to vendor-recommended value
-// RGB Matrix Animation modes. Explicitly enabled
-// For full list of effects, see:
-// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
-# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
-# define RGB_MATRIX_KEYPRESSES
-# define ENABLE_RGB_MATRIX_ALPHAS_MODS
-# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
-# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
-# define ENABLE_RGB_MATRIX_BREATHING
-# define ENABLE_RGB_MATRIX_BAND_SAT
-# define ENABLE_RGB_MATRIX_BAND_VAL
-# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
-# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
-# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
-# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
-# define ENABLE_RGB_MATRIX_CYCLE_ALL
-# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
-# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
-# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
-# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
-# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
-# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
-# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
-# define ENABLE_RGB_MATRIX_DUAL_BEACON
-# define ENABLE_RGB_MATRIX_RAINBOW_BEACON
-# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
-# define ENABLE_RGB_MATRIX_RAINDROPS
-# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
-# define ENABLE_RGB_MATRIX_HUE_BREATHING
-# define ENABLE_RGB_MATRIX_HUE_PENDULUM
-# define ENABLE_RGB_MATRIX_HUE_WAVE
-# define ENABLE_RGB_MATRIX_PIXEL_RAIN
-# define ENABLE_RGB_MATRIX_PIXEL_FLOW
-# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
-// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
-# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
-# define ENABLE_RGB_MATRIX_DIGITAL_RAIN
-// enabled only if RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
-# define ENABLE_RGB_MATRIX_SPLASH
-# define ENABLE_RGB_MATRIX_MULTISPLASH
-# define ENABLE_RGB_MATRIX_SOLID_SPLASH
-# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
-#endif
-
-/* Bootmagic Lite key configuration: use the Esc key */
-#define BOOTMAGIC_LITE_ROW 0
-#define BOOTMAGIC_LITE_COLUMN 5
-
-#define ENCODERS_PAD_A { C7 }
-#define ENCODERS_PAD_B { C6 }
-
-
-
-
diff --git a/keyboards/idobao/id80/v3/info.json b/keyboards/idobao/id80/v3/info.json
deleted file mode 100644
index 0dc8efaf02..0000000000
--- a/keyboards/idobao/id80/v3/info.json
+++ /dev/null
@@ -1,96 +0,0 @@
-{
- "keyboard_name": "ID80 v3",
- "url": "",
- "maintainer": "qmk",
- "layouts": {
- "LAYOUT": {
- "layout": [
- {"label":"Esc", "x":0, "y":0},
- {"label":"F1", "x":1.25, "y":0},
- {"label":"F2", "x":2.25, "y":0},
- {"label":"F3", "x":3.25, "y":0},
- {"label":"F4", "x":4.25, "y":0},
- {"label":"F5", "x":5.5, "y":0},
- {"label":"F6", "x":6.5, "y":0},
- {"label":"F7", "x":7.5, "y":0},
- {"label":"F8", "x":8.5, "y":0},
- {"label":"F9", "x":9.75, "y":0},
- {"label":"F10", "x":10.75, "y":0},
- {"label":"F11", "x":11.75, "y":0},
- {"label":"F12", "x":12.75, "y":0},
- {"label":"Fn", "x":14, "y":0},
- {"label":"Insert", "x":15.25, "y":0},
-
- {"label":"`", "x":0, "y":1.25},
- {"label":"1", "x":1, "y":1.25},
- {"label":"2", "x":2, "y":1.25},
- {"label":"3", "x":3, "y":1.25},
- {"label":"4", "x":4, "y":1.25},
- {"label":"5", "x":5, "y":1.25},
- {"label":"6", "x":6, "y":1.25},
- {"label":"7", "x":7, "y":1.25},
- {"label":"8", "x":8, "y":1.25},
- {"label":"9", "x":9, "y":1.25},
- {"label":"0", "x":10, "y":1.25},
- {"label":"-", "x":11, "y":1.25},
- {"label":"=", "x":12, "y":1.25},
- {"label":"Backspace", "x":13, "y":1.25, "w":2},
- {"label":"Home", "x":15.25, "y":1.25},
-
- {"label":"Tab", "x":0, "y":2.25, "w":1.5},
- {"label":"Q", "x":1.5, "y":2.25},
- {"label":"W", "x":2.5, "y":2.25},
- {"label":"E", "x":3.5, "y":2.25},
- {"label":"R", "x":4.5, "y":2.25},
- {"label":"T", "x":5.5, "y":2.25},
- {"label":"Y", "x":6.5, "y":2.25},
- {"label":"U", "x":7.5, "y":2.25},
- {"label":"I", "x":8.5, "y":2.25},
- {"label":"O", "x":9.5, "y":2.25},
- {"label":"P", "x":10.5, "y":2.25},
- {"label":"[", "x":11.5, "y":2.25},
- {"label":"]", "x":12.5, "y":2.25},
- {"label":"\\", "x":13.5, "y":2.25, "w":1.5},
- {"label":"Delete", "x":15.25, "y":2.25},
-
- {"label":"Caps Lock", "x":0, "y":3.25, "w":1.75},
- {"label":"A", "x":1.75, "y":3.25},
- {"label":"S", "x":2.75, "y":3.25},
- {"label":"D", "x":3.75, "y":3.25},
- {"label":"F", "x":4.75, "y":3.25},
- {"label":"G", "x":5.75, "y":3.25},
- {"label":"H", "x":6.75, "y":3.25},
- {"label":"J", "x":7.75, "y":3.25},
- {"label":"K", "x":8.75, "y":3.25},
- {"label":"L", "x":9.75, "y":3.25},
- {"label":";", "x":10.75, "y":3.25},
- {"label":"'", "x":11.75, "y":3.25},
- {"label":"Enter", "x":12.75, "y":3.25, "w":2.25},
-
- {"label":"Shift", "x":0, "y":4.25, "w":2.25},
- {"label":"Z", "x":2.25, "y":4.25},
- {"label":"X", "x":3.25, "y":4.25},
- {"label":"C", "x":4.25, "y":4.25},
- {"label":"V", "x":5.25, "y":4.25},
- {"label":"B", "x":6.25, "y":4.25},
- {"label":"N", "x":7.25, "y":4.25},
- {"label":"M", "x":8.25, "y":4.25},
- {"label":",", "x":9.25, "y":4.25},
- {"label":".", "x":10.25, "y":4.25},
- {"label":"/", "x":11.25, "y":4.25},
- {"label":"Shift", "x":12.25, "y":4.25, "w":1.75},
- {"label":"\u2191", "x":14.25, "y":4.5},
-
- {"label":"Ctrl", "x":0, "y":5.25, "w":1.25},
- {"label":"Win", "x":1.25, "y":5.25, "w":1.25},
- {"label":"Alt", "x":2.5, "y":5.25, "w":1.25},
- {"x":3.75, "y":5.25, "w":6.25},
- {"label":"Alt", "x":10, "y":5.25, "w":1.5},
- {"label":"Ctrl", "x":11.5, "y":5.25, "w":1.5},
- {"label":"\u2190", "x":13.25, "y":5.5},
- {"label":"\u2193", "x":14.25, "y":5.5},
- {"label":"\u2192", "x":15.25, "y":5.5}
- ]
- }
- }
-}
diff --git a/keyboards/idobao/id80/v3/keymaps/default/keymap.c b/keyboards/idobao/id80/v3/keymaps/default/keymap.c
deleted file mode 100644
index f7886f1e0e..0000000000
--- a/keyboards/idobao/id80/v3/keymaps/default/keymap.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright 2020 Sergey Vlasov <sigprof@gmail.com>
- *
- * 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 QMK_KEYBOARD_H
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [0] = LAYOUT(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MO(1), KC_INS,
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
- ),
- [1] = LAYOUT(
- QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, BL_DEC, BL_TOGG, BL_INC, NK_TOGG, _______, _______, _______, _______, _______, BL_INC,
- _______, _______, _______, _______, _______, _______, BL_TOGG, BL_DEC, BL_STEP
- ),
-};
-
diff --git a/keyboards/idobao/id80/v3/keymaps/default/readme.md b/keyboards/idobao/id80/v3/keymaps/default/readme.md
deleted file mode 100644
index 8ae9f656cd..0000000000
--- a/keyboards/idobao/id80/v3/keymaps/default/readme.md
+++ /dev/null
@@ -1 +0,0 @@
-# The default keymap for id80
diff --git a/keyboards/idobao/id80/v3/keymaps/via/keymap.c b/keyboards/idobao/id80/v3/keymaps/via/keymap.c
deleted file mode 100644
index 19787b6b89..0000000000
--- a/keyboards/idobao/id80/v3/keymaps/via/keymap.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2020 Sergey Vlasov <sigprof@gmail.com>
- *
- * 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 QMK_KEYBOARD_H
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [0] = LAYOUT(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MO(1), KC_INS,
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
- ),
- [1] = LAYOUT(
- QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, BL_DEC, BL_TOGG, BL_INC, NK_TOGG, _______, _______, _______, _______, _______, BL_INC,
- _______, _______, _______, _______, _______, _______, BL_TOGG, BL_DEC, BL_STEP
- ),
- [2] = LAYOUT(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
- [3] = LAYOUT(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
-};
-
diff --git a/keyboards/idobao/id80/v3/readme.md b/keyboards/idobao/id80/v3/readme.md
index dc6c67b4f4..ad3b9b272c 100644
--- a/keyboards/idobao/id80/v3/readme.md
+++ b/keyboards/idobao/id80/v3/readme.md
@@ -1,27 +1,36 @@
-# ID80v3
+# IDOBAO ID80v3
-![ID80v3](https://i.imgur.com/PGvZfQj.jpg)
+![IDOBAO ID80](https://i.imgur.com/977ENjp.png)
-A 75% hotswap in-switch RGB keyboard with an encoder.
+A 75% hotswap keyboard from IDOBAO.
-* Keyboard Maintainer: [peepeetee](https://github.com/peepeetee)
-* Hardware Supported: ID80v3
-* Hardware Availability: Not avaliable yet
+## ANSI Support
+
+* Keyboard Maintainer: [Vino Rodrigues](https://github.com/vinorodrigues)
+* Hardware Supported: **IDOBAO ID80v3**
+* Hardware Availability: [IDOBAO.net](https://idobao.net/search?type=product&q=id80*)
+
+## ANSI Layout
+
+![](https://idobao.github.io/kle/idobao-id80.png)
+
+## Compiling and Flashing
Make example for this keyboard (after setting up your build environment):
- make idobao/id80/v3:default
+ make idobao/id80/v3/ansi:default
Flashing example for this keyboard:
- make idobao/id80/v3:default:flash
+ make idobao/id80/v3/ansi:default:flash
-See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information.
+Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
-* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Bootmagic reset**: Hold down the [Escape] key (the top left key) and plug in the keyboard
* **Physical reset button**: Briefly press the button on the back of the PCB
-* **Keycode in layout**: Press the key mapped to `RESET` if it is available
+* **Keycode in layout**: Press the key mapped to `RESET` if it is available
diff --git a/keyboards/idobao/id80/v3/rules.mk b/keyboards/idobao/id80/v3/rules.mk
index 6805b8f0f9..218fc05539 100644
--- a/keyboards/idobao/id80/v3/rules.mk
+++ b/keyboards/idobao/id80/v3/rules.mk
@@ -1,23 +1,2 @@
-# MCU name
-MCU = atmega32u4
-
-# Bootloader selection
-BOOTLOADER = atmel-dfu
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = yes # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
-AUDIO_ENABLE = no # Audio output
-ENCODER_ENABLE = yes
-LTO_ENABLE = yes
-
-RGB_MATRIX_ENABLE = yes
-RGB_MATRIX_DRIVER = WS2812
+# Defalt to the ansi version
+DEFAULT_FOLDER = idobao/id80/v3/ansi
diff --git a/keyboards/idobao/id80/v3/v3.c b/keyboards/idobao/id80/v3/v3.c
deleted file mode 100644
index cd05a26a49..0000000000
--- a/keyboards/idobao/id80/v3/v3.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2022 peepeetee (@peepeetee)
-// Copyright 2022 Xelus22
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "v3.h"
-
-#ifdef ENCODER_ENABLE
-bool encoder_update_kb(uint8_t index, bool clockwise) {
- if (!encoder_update_user(index, clockwise)) { return false; }
- if (index == 0) {
- if (clockwise) {
- tap_code_delay(KC_VOLU, 10);
- } else {
- tap_code_delay(KC_VOLD, 10);
- }
- }
- return true;
-}
-#endif
-
-#ifdef RGB_MATRIX_ENABLE
-led_config_t g_led_config = { {
- // Key Matrix to LED Index
- { 8, 9, 34, 35, 64, 65, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
- { 7, NO_LED, 33, 36, 63, 66, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
- { 6, 10, 32, 37, 62, 67, NO_LED, NO_LED, 49, 50, 79 },
- { 0, 11, 31, 38, 61, 68, 21, NO_LED, 48, NO_LED, 77 },
- { 1, 12, 30, 39, 60, 69, 20, 22, 47, 52, 76 },
- { 2, 13, 29, 40, 59, 70, 19, 23, 46, 53, 75 },
- { 5, 14, 28, 41, 58, 71, NO_LED, NO_LED, NO_LED, 51, 78 },
- { 3, 15, 27, 42, 57, 72, 18, 24, 45, 54, 74 },
- { 4, 16, 26, 43, 56, 73, 17, 25, 44, 55, NO_LED },
-}, {
- // LED Index to Physical Position
-{224, 64}, {209, 64}, {195, 64}, {173, 61}, {151, 61}, {94 , 61}, {39 , 61}, {20 , 61}, {2 , 61}, {9 , 50}, {33 , 50},
-{48 , 50}, {62 , 50}, {77 , 50}, {92 , 50}, {106, 50}, {121, 50}, {136, 50}, {151, 50}, {165, 50}, {185, 50}, {209, 53},
-{196, 39}, {173, 39}, {158, 39}, {143, 39}, {129, 39}, {114, 39}, {99 , 39}, {84 , 39}, {70 , 39}, {55 , 39}, {40 , 39},
-{26 , 39}, {6 , 39}, {4 , 28}, {22 , 28}, {37 , 28}, {51 , 28}, {66 , 28}, {81 , 28}, {95 , 28}, {110, 28}, {125, 28},
-{140, 28}, {154, 28}, {169, 28}, {184, 28}, {202, 28}, {224, 28}, {224, 17}, {198, 17}, {176, 17}, {162, 17}, {147, 17},
-{132, 17}, {118, 17}, {103, 17}, {88 , 17}, {73 , 17}, {59 , 17}, {44 , 17}, {29 , 17}, {15 , 17}, {0 , 17}, {0 , 0},
-{18 , 0}, {33 , 0}, {48 , 0}, {62 , 0}, {81 , 0}, {95 , 0}, {110, 0}, {125, 0}, {143, 0}, {158, 0}, {173, 0},
-{187, 0}, {206, 0}, {224, 0},
-
-{ 207, 13},
-{ 207, 32},
-{ 207, 51},{ 174, 51},{ 141, 51},{ 108, 51},{ 73, 51},{ 40, 51},{ 13, 51 },
-{ 13, 32},
-{ 13, 13},{ 40, 13},{ 73, 13},{ 108, 13},{ 141, 13},{ 174, 13},
-
-}, {
- // LED Index to Flag
-1,1,1,1,1,4,1,1,1,
-1,4,4,4,4,4,4,4,4,4,4,1,1,
-1,4,4,4,4,4,4,4,4,4,4,4,1,
-1,4,4,4,4,4,4,4,4,4,4,4,4,4,1,
-1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,
-1,4,4,4,4,1,1,1,1,4,4,4,4,1,1,
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-
-} };
-
-#endif
diff --git a/keyboards/idobao/id80/v3/v3.h b/keyboards/idobao/id80/v3/v3.h
deleted file mode 100644
index 94626fe4f6..0000000000
--- a/keyboards/idobao/id80/v3/v3.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2020 Sergey Vlasov <sigprof@gmail.com>
- *
- * 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 "quantum.h"
-
-#define LAYOUT( \
- K50, K51, K52, K53, K54, K55, K56, K57, K58, KA7, KA5, KA4, KA3, KA6, KA2, \
- K40, K41, K42, K43, K44, K45, K46, K47, K48, K98, K97, K95, K94, K96, K92, \
- K30, K31, K32, K33, K34, K35, K36, K37, K38, K88, K87, K85, K84, K83, K82, \
- K20, K21, K22, K23, K24, K25, K26, K27, K28, K78, K77, K75, K74, \
- K10, K12, K13, K14, K15, K16, K17, K18, K68, K67, K65, K64, K63, \
- K00, K01, K02, K06, K08, K07, K05, K04, K03 \
-) { \
- { K00, K10, K20, K30, K40, K50, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { K01, KC_NO, K21, K31, K41, K51, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { K02, K12, K22, K32, K42, K52, KC_NO, KC_NO, K82, K92, KA2 }, \
- { K03, K13, K23, K33, K43, K53, K63, KC_NO, K83, KC_NO, KA3 }, \
- { K04, K14, K24, K34, K44, K54, K64, K74, K84, K94, KA4 }, \
- { K05, K15, K25, K35, K45, K55, K65, K75, K85, K95, KA5 }, \
- { K06, K16, K26, K36, K46, K56, KC_NO, KC_NO, KC_NO, K96, KA6 }, \
- { K07, K17, K27, K37, K47, K57, K67, K77, K87, K97, KA7 }, \
- { K08, K18, K28, K38, K48, K58, K68, K78, K88, K98, KC_NO }, \
-}
diff --git a/keyboards/idobao/id87/v2/config.h b/keyboards/idobao/id87/v2/config.h
index f094ef0638..8f1a9ddf03 100644
--- a/keyboards/idobao/id87/v2/config.h
+++ b/keyboards/idobao/id87/v2/config.h
@@ -1,144 +1,78 @@
-// Copyright 2022 peepeetee (@peepeetee)
+// Copyright 2022 vinorodrigues (@vinorodrigues)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "config_common.h"
-/* USB Device descriptor parameter */
-#define VENDOR_ID 0x6964 // "id"
-#define PRODUCT_ID 0x0087
-#define DEVICE_VER 0x0002
-#define MANUFACTURER IDOBAO
-#define PRODUCT ID87
-
-/* key matrix size */
-#define MATRIX_ROWS 11
-#define MATRIX_COLS 9
-
-/*
- * Keyboard Matrix Assignments
- *
- * Change this to how you wired your keyboard
- * COLS: AVR pins used for columns, left to right
- * ROWS: AVR pins used for rows, top to bottom
- * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
- * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
- *
- */
-#define MATRIX_ROW_PINS { E6, B0, B1, B2, B3, B7, F7, F6, F5, F4, F1 }
-
-#define MATRIX_COL_PINS { D0, D1, D2, D3, D5, D4, D6, D7, B4 }
-//#define UNUSED_PINS
-
-/* COL2ROW, ROW2COL*/
-#define DIODE_DIRECTION ROW2COL
-
-#define LED_CAPS_LOCK_PIN C7
-
-//#define BACKLIGHT_PIN B7
-//#define BACKLIGHT_LEVELS 3
-//#define BACKLIGHT_BREATHING
+/* ----------------
+ * RGB Matrix stuff
+ * ---------------- */
#define RGB_DI_PIN E2
-# define DRIVER_LED_TOTAL 103 /* 16 Bottom 87 top*/
-#ifdef RGB_DI_PIN
-# define RGBLED_NUM 103 /* 16 Bottom 87 top*/
-# define RGB_MATRIX_KEYPRESSES // reacts to keypresses
-#endif
-#ifdef RGB_MATRIX_ENABLE
-# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180 // Limit to vendor-recommended value
-// RGB Matrix Animation modes. Explicitly enabled
-// For full list of effects, see:
-// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
-# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
-# define RGB_MATRIX_KEYPRESSES
-# define ENABLE_RGB_MATRIX_ALPHAS_MODS
-# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
-# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
-# define ENABLE_RGB_MATRIX_BREATHING
-# define ENABLE_RGB_MATRIX_BAND_SAT
-# define ENABLE_RGB_MATRIX_BAND_VAL
-# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
-# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
-# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
-# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
-# define ENABLE_RGB_MATRIX_CYCLE_ALL
-# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
-# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
-# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
-# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
-# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
-# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
-# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
-# define ENABLE_RGB_MATRIX_DUAL_BEACON
-# define ENABLE_RGB_MATRIX_RAINBOW_BEACON
-# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
-# define ENABLE_RGB_MATRIX_RAINDROPS
-# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
-# define ENABLE_RGB_MATRIX_HUE_BREATHING
-# define ENABLE_RGB_MATRIX_HUE_PENDULUM
-# define ENABLE_RGB_MATRIX_HUE_WAVE
-// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
-# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
-# define ENABLE_RGB_MATRIX_DIGITAL_RAIN
-// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
-# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
-# define ENABLE_RGB_MATRIX_SPLASH
-# define ENABLE_RGB_MATRIX_MULTISPLASH
-# define ENABLE_RGB_MATRIX_SOLID_SPLASH
-# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
-#endif
-
-
-/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
-#define DEBOUNCE 5
-
-/* define if matrix has ghost (lacks anti-ghosting diodes) */
-//#define MATRIX_HAS_GHOST
-
-/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
-#define LOCKING_SUPPORT_ENABLE
-/* Locking resynchronize hack */
-#define LOCKING_RESYNC_ENABLE
-
-/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
- * This is useful for the Windows task manager shortcut (ctrl+shift+esc).
- */
-//#define GRAVE_ESC_CTRL_OVERRIDE
-
-/*
- * Force NKRO
- *
- * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
- * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
- * makefile for this to work.)
- *
- * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
- * until the next keyboard reset.
- *
- * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
- * fully operational during normal computer usage.
- *
- * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
- * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
- * bootmagic, NKRO mode will always be enabled until it is toggled again during a
- * power-up.
- *
- */
-#define FORCE_NKRO
-
-/*
+
+// RGB Matrix config
+#if defined(RGB_MATRIX_ENABLE)
+
+ #define DRIVER_LED_TOTAL 103
+
+ #define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
+ #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180 // limits maximum brightness of LEDs to x out of 255. If not defined maximum brightness is set to 255
+
+ #define RGB_MATRIX_KEYPRESSES
+
+ #define ENABLE_RGB_MATRIX_SOLID_COLOR // Static single color
+ #define ENABLE_RGB_MATRIX_ALPHAS_MODS // Static dual hue, speed is hue for secondary hue
+ #define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN // Static gradient top to bottom, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT // Static gradient left to right, speed controls how much gradient changes
+ #define ENABLE_RGB_MATRIX_BREATHING // Single hue brightness cycling animation
+ #define ENABLE_RGB_MATRIX_BAND_SAT // Single hue band fading saturation scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_VAL // Single hue band fading brightness scrolling left to right
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT // Single hue 3 blade spinning pinwheel fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL // Single hue 3 blade spinning pinwheel fades brightness
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT // Single hue spinning spiral fades saturation
+ #define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL // Single hue spinning spiral fades brightness
+ #define ENABLE_RGB_MATRIX_CYCLE_ALL // Full keyboard solid hue cycling through full gradient
+ #define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT // Full gradient scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN // Full gradient scrolling top to bottom
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN // Full gradient scrolling out to in
+ #define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL // Full dual gradients scrolling out to in
+ #define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON // Full gradient Chevron shaped scrolling left to right
+ #define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL // Full gradient spinning pinwheel around center of keyboard
+ #define ENABLE_RGB_MATRIX_CYCLE_SPIRAL // Full gradient spinning spiral around center of keyboard
+ #define ENABLE_RGB_MATRIX_DUAL_BEACON // Full gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_BEACON // Full tighter gradient spinning around center of keyboard
+ #define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS // Full dual gradients spinning two halfs of keyboard
+ #define ENABLE_RGB_MATRIX_RAINDROPS // Randomly changes a single key's hue
+ #define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS // Randomly changes a single key's hue and saturation
+ #define ENABLE_RGB_MATRIX_HUE_BREATHING // Hue shifts up a slight amount at the same time, then shifts back
+ #define ENABLE_RGB_MATRIX_HUE_PENDULUM // Hue shifts up a slight amount in a wave to the right, then back to the left
+ #define ENABLE_RGB_MATRIX_HUE_WAVE // Hue shifts up a slight amount and then back down in a wave to the right
+
+ /* RGB_MATRIX_FRAMEBUFFER_EFFECTS -- do not enable */
+ // #define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+ // #define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+
+ /* RGB_MATRIX_KEYPRESSES | RGB_MATRIX_KEYRELEASES */
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE // Pulses keys hit to hue & value then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE // Static single hue, pulses keys hit to shifted hue then fades to current hue
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SPLASH // Full gradient & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_MULTISPLASH // Full gradient & value pulse away from multiple key hits then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_SPLASH // Hue & value pulse away from a single key hit then fades value out
+ #define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH // Hue & value pulse away from multiple key hits then fades value out
+#endif // RGB_MATRIX_ENABLE
+
+
+/* -----------------------
* Feature disable options
* These options are also useful to firmware size reduction.
- */
+ * ----------------------- */
/* disable debug print */
//#define NO_DEBUG
@@ -150,7 +84,3 @@
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
-
-/* Bootmagic Lite key configuration */
-//#define BOOTMAGIC_LITE_ROW 0
-//#define BOOTMAGIC_LITE_COLUMN 0
diff --git a/keyboards/idobao/id87/v2/info.json b/keyboards/idobao/id87/v2/info.json
index e4e252aa64..7292ce29ca 100644
--- a/keyboards/idobao/id87/v2/info.json
+++ b/keyboards/idobao/id87/v2/info.json
@@ -1,97 +1,126 @@
{
- "keyboard_name": "ID87",
- "url": "https://www.idobao.net/products/idobao-id87-80-hot-swappable-mechanical-keyboard-kit",
- "maintainer": "qmk",
+ "manufacturer": "IDOBAO",
+ "keyboard_name": "ID87v2",
+ "maintainer": "vinorodrigues",
+ "bootloader": "atmel-dfu",
+ "diode_direction": "ROW2COL",
+ "features": {
+ "bootmagic": true,
+ "mousekey": true,
+ "extrakey": true,
+ "console": false,
+ "command": false,
+ "nkro": true,
+ "backlight": false,
+ "rgblight": false
+ },
+ "debounce": 5,
+ "matrix_pins": {
+ "cols": ["D0", "D1", "D2", "D3", "D5", "D4", "D6", "D7", "B4"],
+ "rows": ["E6", "B0", "B1", "B2", "B3", "B7", "F7", "F6", "F5", "F4", "F1"]
+ },
+ "processor": "atmega32u4",
+ "url": "https://idobao.net/search?type=product&q=ID87*",
+ "usb": {
+ "vid": "0x6964",
+ "pid": "0x0287",
+ "device_version": "2.0.0"
+ },
"layouts": {
"LAYOUT_tkl_ansi": {
"layout": [
- {"label":"Esc", "x":0, "y":0},
- {"label":"F1", "x":2, "y":0},
- {"label":"F2", "x":3, "y":0},
- {"label":"F3", "x":4, "y":0},
- {"label":"F4", "x":5, "y":0},
- {"label":"F5", "x":6.5, "y":0},
- {"label":"F6", "x":7.5, "y":0},
- {"label":"F7", "x":8.5, "y":0},
- {"label":"F8", "x":9.5, "y":0},
- {"label":"F9", "x":11, "y":0},
- {"label":"F10", "x":12, "y":0},
- {"label":"F11", "x":13, "y":0},
- {"label":"F12", "x":14, "y":0},
- {"label":"PrtSc", "x":15.25, "y":0},
- {"label":"Scroll Lock", "x":16.25, "y":0},
- {"label":"Pause", "x":17.25, "y":0},
- {"label":"~", "x":0, "y":1.5},
- {"label":"1", "x":1, "y":1.5},
- {"label":"2", "x":2, "y":1.5},
- {"label":"3", "x":3, "y":1.5},
- {"label":"4", "x":4, "y":1.5},
- {"label":"5", "x":5, "y":1.5},
- {"label":"6", "x":6, "y":1.5},
- {"label":"7", "x":7, "y":1.5},
- {"label":"8", "x":8, "y":1.5},
- {"label":"9", "x":9, "y":1.5},
- {"label":"0", "x":10, "y":1.5},
- {"label":"-", "x":11, "y":1.5},
- {"label":"=", "x":12, "y":1.5},
- {"label":"Backspace", "x":13, "y":1.5, "w":2},
- {"label":"Insert", "x":15.25, "y":1.5},
- {"label":"Home", "x":16.25, "y":1.5},
- {"label":"PgUp", "x":17.25, "y":1.5},
- {"label":"Tab", "x":0, "y":2.5, "w":1.5},
- {"label":"Q", "x":1.5, "y":2.5},
- {"label":"W", "x":2.5, "y":2.5},
- {"label":"E", "x":3.5, "y":2.5},
- {"label":"R", "x":4.5, "y":2.5},
- {"label":"T", "x":5.5, "y":2.5},
- {"label":"Y", "x":6.5, "y":2.5},
- {"label":"U", "x":7.5, "y":2.5},
- {"label":"I", "x":8.5, "y":2.5},
- {"label":"O", "x":9.5, "y":2.5},
- {"label":"P", "x":10.5, "y":2.5},
- {"label":"[", "x":11.5, "y":2.5},
- {"label":"]", "x":12.5, "y":2.5},
- {"label":"\\", "x":13.5, "y":2.5, "w":1.5},
- {"label":"Delete", "x":15.25, "y":2.5},
- {"label":"End", "x":16.25, "y":2.5},
- {"label":"PgDn", "x":17.25, "y":2.5},
- {"label":"Caps Lock", "x":0, "y":3.5, "w":1.75},
- {"label":"A", "x":1.75, "y":3.5},
- {"label":"S", "x":2.75, "y":3.5},
- {"label":"D", "x":3.75, "y":3.5},
- {"label":"F", "x":4.75, "y":3.5},
- {"label":"G", "x":5.75, "y":3.5},
- {"label":"H", "x":6.75, "y":3.5},
- {"label":"J", "x":7.75, "y":3.5},
- {"label":"K", "x":8.75, "y":3.5},
- {"label":"L", "x":9.75, "y":3.5},
- {"label":";", "x":10.75, "y":3.5},
- {"label":"'", "x":11.75, "y":3.5},
- {"label":"Enter", "x":12.75, "y":3.5, "w":2.25},
- {"label":"Shift", "x":0, "y":4.5, "w":2.25},
- {"label":"Z", "x":2.25, "y":4.5},
- {"label":"X", "x":3.25, "y":4.5},
- {"label":"C", "x":4.25, "y":4.5},
- {"label":"V", "x":5.25, "y":4.5},
- {"label":"B", "x":6.25, "y":4.5},
- {"label":"N", "x":7.25, "y":4.5},
- {"label":"M", "x":8.25, "y":4.5},
- {"label":",", "x":9.25, "y":4.5},
- {"label":".", "x":10.25, "y":4.5},
- {"label":"/", "x":11.25, "y":4.5},
- {"label":"Shift", "x":12.25, "y":4.5, "w":2.75},
- {"label":"Up", "x":16.25, "y":4.5},
- {"label":"Ctrl", "x":0, "y":5.5, "w":1.25},
- {"label":"Win", "x":1.25, "y":5.5, "w":1.25},
- {"label":"Alt", "x":2.5, "y":5.5, "w":1.25},
- {"label":"Space", "x":3.75, "y":5.5, "w":6.25},
- {"label":"Alt", "x":10, "y":5.5, "w":1.25},
- {"label":"Win", "x":11.25, "y":5.5, "w":1.25},
- {"label":"LT(1, KC_APP)", "x":12.5, "y":5.5, "w":1.25},
- {"label":"Ctrl", "x":13.75, "y":5.5, "w":1.25},
- {"label":"Left", "x":15.25, "y":5.5},
- {"label":"Down", "x":16.25, "y":5.5},
- {"label":"Right", "x":17.25, "y":5.5}
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [0, 2], "x": 2, "y": 0 },
+ { "matrix": [0, 3], "x": 3, "y": 0 },
+ { "matrix": [0, 4], "x": 4, "y": 0 },
+ { "matrix": [0, 5], "x": 5, "y": 0 },
+ { "matrix": [0, 6], "x": 6.5, "y": 0 },
+ { "matrix": [0, 7], "x": 7.5, "y": 0 },
+ { "matrix": [0, 8], "x": 8.5, "y": 0 },
+ { "matrix": [6, 8], "x": 9.5, "y": 0 },
+ { "matrix": [6, 7], "x": 11, "y": 0 },
+ { "matrix": [6, 5], "x": 12, "y": 0 },
+ { "matrix": [6, 4], "x": 13, "y": 0 },
+ { "matrix": [6, 3], "x": 14, "y": 0 },
+ { "matrix": [6, 6], "x": 15.25, "y": 0 },
+ { "matrix": [6, 2], "x": 16.25, "y": 0 },
+ { "matrix": [6, 1], "x": 17.25, "y": 0 },
+
+ { "matrix": [1, 0], "x": 0, "y": 1.25 },
+ { "matrix": [1, 1], "x": 1, "y": 1.25 },
+ { "matrix": [1, 2], "x": 2, "y": 1.25 },
+ { "matrix": [1, 3], "x": 3, "y": 1.25 },
+ { "matrix": [1, 4], "x": 4, "y": 1.25 },
+ { "matrix": [1, 5], "x": 5, "y": 1.25 },
+ { "matrix": [1, 6], "x": 6, "y": 1.25 },
+ { "matrix": [1, 7], "x": 7, "y": 1.25 },
+ { "matrix": [1, 8], "x": 8, "y": 1.25 },
+ { "matrix": [7, 8], "x": 9, "y": 1.25 },
+ { "matrix": [7, 0], "x": 10, "y": 1.25 },
+ { "matrix": [7, 7], "x": 11, "y": 1.25 },
+ { "matrix": [7, 5], "x": 12, "y": 1.25 },
+ { "matrix": [7, 3], "x": 13, "y": 1.25, "w": 2 },
+ { "matrix": [7, 6], "x": 15.25, "y": 1.25 },
+ { "matrix": [7, 2], "x": 16.25, "y": 1.25 },
+ { "matrix": [7, 1], "x": 17.25, "y": 1.25 },
+
+ { "matrix": [2, 0], "w": 1.5, "x": 0, "y": 2.25 },
+ { "matrix": [2, 1], "x": 1.5, "y": 2.25 },
+ { "matrix": [2, 2], "x": 2.5, "y": 2.25 },
+ { "matrix": [2, 3], "x": 3.5, "y": 2.25 },
+ { "matrix": [2, 4], "x": 4.5, "y": 2.25 },
+ { "matrix": [2, 5], "x": 5.5, "y": 2.25 },
+ { "matrix": [2, 6], "x": 6.5, "y": 2.25 },
+ { "matrix": [2, 7], "x": 7.5, "y": 2.25 },
+ { "matrix": [2, 8], "x": 8.5, "y": 2.25 },
+ { "matrix": [8, 8], "x": 9.5, "y": 2.25 },
+ { "matrix": [8, 7], "x": 10.5, "y": 2.25 },
+ { "matrix": [8, 5], "x": 11.5, "y": 2.25 },
+ { "matrix": [8, 4], "x": 12.5, "y": 2.25 },
+ { "matrix": [8, 3], "w": 1.5, "x": 13.5, "y": 2.25 },
+ { "matrix": [8, 6], "x": 15.25, "y": 2.25 },
+ { "matrix": [8, 2], "x": 16.25, "y": 2.25 },
+ { "matrix": [8, 1], "x": 17.25, "y": 2.25 },
+
+ { "matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75 },
+ { "matrix": [3, 1], "x": 1.75, "y": 3.25 },
+ { "matrix": [3, 2], "x": 2.75, "y": 3.25 },
+ { "matrix": [3, 3], "x": 3.75, "y": 3.25 },
+ { "matrix": [3, 4], "x": 4.75, "y": 3.25 },
+ { "matrix": [3, 5], "x": 5.75, "y": 3.25 },
+ { "matrix": [3, 6], "x": 6.75, "y": 3.25 },
+ { "matrix": [3, 7], "x": 7.75, "y": 3.25 },
+ { "matrix": [3, 8], "x": 8.75, "y": 3.25 },
+ { "matrix": [9, 8], "x": 9.75, "y": 3.25 },
+ { "matrix": [9, 7], "x": 10.75, "y": 3.25 },
+ { "matrix": [9, 5], "x": 11.75, "y": 3.25 },
+ { "matrix": [9, 3], "x": 12.75, "y": 3.25, "w": 2.25 },
+
+ { "matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25 },
+ { "matrix": [4, 2], "x": 2.25, "y": 4.25 },
+ { "matrix": [4, 3], "x": 3.25, "y": 4.25 },
+ { "matrix": [4, 4], "x": 4.25, "y": 4.25 },
+ { "matrix": [4, 5], "x": 5.25, "y": 4.25 },
+ { "matrix": [4, 6], "x": 6.25, "y": 4.25 },
+ { "matrix": [4, 7], "x": 7.25, "y": 4.25 },
+ { "matrix": [4, 8], "x": 8.25, "y": 4.25 },
+ { "matrix": [10, 8], "x": 9.25, "y": 4.25 },
+ { "matrix": [10, 7], "x": 10.25, "y": 4.25 },
+ { "matrix": [10, 5], "x": 11.25, "y": 4.25 },
+ { "matrix": [10, 4], "x": 12.25, "y": 4.25, "w": 2.75 },
+ { "matrix": [9, 2], "x": 16.25, "y": 4.25 },
+
+ { "matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 6], "x": 3.75, "y": 5.25, "w": 6.25 },
+ { "matrix": [5, 8], "x": 10, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 7], "x": 11.25, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 4], "x": 12.5, "y": 5.25, "w": 1.25 },
+ { "matrix": [5, 3], "x": 13.75, "y": 5.25, "w": 1.25 },
+ { "matrix": [10, 6], "x": 15.25, "y": 5.25 },
+ { "matrix": [10, 2], "x": 16.25, "y": 5.25 },
+ { "matrix": [10, 1], "x": 17.25, "y": 5.25 }
]
}
}
diff --git a/keyboards/idobao/id87/v2/keymaps/default/keymap.c b/keyboards/idobao/id87/v2/keymaps/default/keymap.c
index 9465dca531..53690899c1 100644
--- a/keyboards/idobao/id87/v2/keymaps/default/keymap.c
+++ b/keyboards/idobao/id87/v2/keymaps/default/keymap.c
@@ -1,35 +1,58 @@
-/*
-Copyright 2020 Tybera
-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/>.
-*/
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
+#define LT_1_AP LT(1, KC_APP) // Tap = Menu, Hold = MO(1)
+
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Esc│ │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Scr│Pse│
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │Del│End│PgD│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ │ ↑ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │Ctrl│GUI │Alt │ │ Alt│ GUI│Fn1*│Ctrl│ │ ↠│ ↓ │ → │ Fn1* => Tap = Menu, Hold = MO(1)
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
[0] = LAYOUT_tkl_ansi(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT(1, KC_APP), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
- ),
- [1] = LAYOUT_tkl_ansi(
- QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, _______,
- _______, BL_TOGG, RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_SAI, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, BL_INC,
- _______, _______, _______, _______, _______, _______, _______, _______, BL_INC, BL_DEC, RGB_MOD
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT_1_AP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Rst│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │Hu+│ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ │Tog│Mod│ │ │ │ │ │ │ │ │ │ │ │ │St-│Hu-│St+│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ │ │mod│ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ │ │ │ │ │ │NRO│ │ │ │ │ │ │Br+│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ │ │ │ │ │ │ │ │ │Sp-│Br-│Sp+│
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [1] = LAYOUT_tkl_ansi(
+ QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, _______,
+ _______, RGB_TOG, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAD, RGB_HUD, RGB_SAI,
+ _______, _______, RGB_RMOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, RGB_VAI,
+ _______, _______, _______, _______, _______, _______, _______, _______, RGB_SPD, RGB_VAD, RGB_SPI
+ )
};
diff --git a/keyboards/idobao/id87/v2/keymaps/default/readme.md b/keyboards/idobao/id87/v2/keymaps/default/readme.md
deleted file mode 100644
index 6054431de4..0000000000
--- a/keyboards/idobao/id87/v2/keymaps/default/readme.md
+++ /dev/null
@@ -1 +0,0 @@
-# The default keymap for id87 \ No newline at end of file
diff --git a/keyboards/idobao/id87/v2/keymaps/idobao/config.h b/keyboards/idobao/id87/v2/keymaps/idobao/config.h
new file mode 100644
index 0000000000..a1612e6e32
--- /dev/null
+++ b/keyboards/idobao/id87/v2/keymaps/idobao/config.h
@@ -0,0 +1,4 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/idobao/id87/v2/keymaps/idobao/keymap.c b/keyboards/idobao/id87/v2/keymaps/idobao/keymap.c
new file mode 100644
index 0000000000..59b60b7e1d
--- /dev/null
+++ b/keyboards/idobao/id87/v2/keymaps/idobao/keymap.c
@@ -0,0 +1,299 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// Copyright 2022 IDOBAO (@idobaokb)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* ------------------------------------------------------------------
+ * This is the IDOBAO factory default keymap ;)
+ * ------------------------------------------------------------------ */
+
+#include QMK_KEYBOARD_H
+#include "version.h"
+
+#ifdef RGB_MATRIX_ENABLE
+
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_disable_perkey:1;
+ bool rgb_disable_underglow:1;
+ };
+} user_config_t;
+
+#endif // RGB_MATRIX_ENABLE
+
+enum {
+ KC_MCON = USER00, // macOS Open Mission Control
+ KC_LPAD, // macOS Open Launchpad
+ #ifdef RGB_MATRIX_ENABLE
+ RGB_TPK, // Toggle Per-Key
+ RGB_TUG, // Toggle Underglow
+ #endif // RGB_MATRIX_ENABLE
+ KB_VRSN = USER09 // debug, type version
+};
+
+#ifndef RGB_MATRIX_ENABLE
+ #define RGB_TPK _______
+ #define RGB_TUG _______
+#endif
+
+enum macos_consumer_usages {
+ _AC_SHOW_ALL_WINDOWS = 0x29F, // mapped to KC_MCON
+ _AC_SHOW_ALL_APPS = 0x2A0 // mapped to KC_LPAD
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Esc│ │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Scr│Pse│
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │Backspc│ │Ins│Hom│PgU│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │Del│End│PgD│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ │ ↑ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │Ctrl│GUI │Alt │ space │ Alt│ GUI│MO(1│Ctrl│ │ ↠│ ↓ │ → │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [0] = LAYOUT_tkl_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Rst│ │BR+│BR-│mMC│mLP│ │Br-│Br+│Prv│Ply│ │Nxt│Mut│Vl-│Vl+│ │ │ │ │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │Hu+│ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ │Tog│Mod│ │ │ │ │ │ │ │ │ │ │ │ │St-│Hu-│St+│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ │ │mod│ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ │ │ │ │Ver│ │NRO│ │ │ │ │ MO(2) │ │Br+│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ │ │ │ │ │ │ │ │ │Sp-│Br-│Sp+│
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [1] = LAYOUT_tkl_ansi(
+ QK_BOOT, KC_BRID, KC_BRIU, KC_MCON, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, _______,
+ _______, RGB_TOG, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAD, RGB_HUD, RGB_SAI,
+ _______, _______, RGB_RMOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, KB_VRSN, _______, NK_TOGG, _______, _______, _______, _______, MO(2), RGB_VAI,
+ _______, _______, _______, _______, _______, _______, _______, _______, RGB_SPD, RGB_VAD, RGB_SPI
+ ),
+
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │M00│M01│M02│M03│M04│M05│M06│M07│M08│M09│M10│ │ │ │ │ │ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ │M11│M12│M13│M14│M15│M16│ │ │ │ │ │ │ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [2] = LAYOUT_tkl_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ MACRO00, MACRO01, MACRO02, MACRO03, MACRO04, MACRO05, MACRO06, MACRO07, MACRO08, MACRO09, MACRO10, _______, _______, _______, _______, _______, _______,
+ _______, MACRO11, MACRO12, MACRO13, MACRO14, MACRO15, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
+
+#ifdef RGB_MATRIX_ENABLE
+
+/*
+ * RGB Stuff
+ */
+
+#define ID87_CAPS_LOCK_KEY_INDEX 40 // position of Caps Lock key
+
+#define ID87_CAPS_LOCK_MAX_BRIGHTNESS 0xFF
+#ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
+ #undef ID87_CAPS_LOCK_MAX_BRIGHTNESS
+ #define ID87_CAPS_LOCK_MAX_BRIGHTNESS RGB_MATRIX_MAXIMUM_BRIGHTNESS
+#endif
+
+#define ID87_CAPS_LOCK_VAL_STEP 8
+#ifdef RGB_MATRIX_VAL_STEP
+ #undef ID87_CAPS_LOCK_VAL_STEP
+ #define ID87_CAPS_LOCK_VAL_STEP RGB_MATRIX_VAL_STEP
+#endif
+
+user_config_t user_config;
+
+void id87_update_rgb_mode(void) {
+ uint8_t flags = LED_FLAG_ALL;
+
+ if (user_config.rgb_disable_perkey && user_config.rgb_disable_underglow) {
+ flags = 0; // All OFF Condition
+ } else {
+ if (user_config.rgb_disable_perkey) {
+ flags = LED_FLAG_UNDERGLOW | 0xF0;
+ }
+ if (user_config.rgb_disable_underglow) {
+ flags = LED_FLAG_MODIFIER | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR | 0xF0;
+ }
+ }
+
+ if (flags == 0) {
+ rgb_matrix_set_flags(0);
+ rgb_matrix_set_color_all(HSV_OFF);
+ } else {
+ rgb_matrix_set_flags(flags);
+ rgb_matrix_enable_noeeprom();
+ }
+
+ eeconfig_update_kb(user_config.raw); // write back to EEPROM
+}
+
+void id87_get_rgb_mode(void) {
+ user_config.raw = eeconfig_read_kb(); // read config from EEPROM
+ id87_update_rgb_mode();
+}
+
+void keyboard_post_init_user(void) {
+ id87_get_rgb_mode();
+}
+
+void eeconfig_init_user(void) {
+ // EEPROM is getting reset!
+ user_config.raw = 0;
+ id87_update_rgb_mode();
+}
+
+void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
+ // Caps Lock key stuff
+
+ if (host_keyboard_led_state().caps_lock) {
+ uint8_t v = rgb_matrix_get_val();
+ if (v < ID87_CAPS_LOCK_VAL_STEP) {
+ v = ID87_CAPS_LOCK_VAL_STEP;
+ } else if (v < (ID87_CAPS_LOCK_MAX_BRIGHTNESS - ID87_CAPS_LOCK_VAL_STEP)) {
+ if (!user_config.rgb_disable_perkey) {
+ v += ID87_CAPS_LOCK_VAL_STEP; // inc. by one more step than current brightness
+ } // else leave as current brightness
+ } else {
+ v = ID87_CAPS_LOCK_MAX_BRIGHTNESS;
+ }
+ rgb_matrix_set_color(ID87_CAPS_LOCK_KEY_INDEX, v, v, v); // white, brightness adjusted
+ } else if (user_config.rgb_disable_perkey) {
+ rgb_matrix_set_color(ID87_CAPS_LOCK_KEY_INDEX, HSV_OFF); // off
+ }
+}
+
+#endif // RGB_MATRIX_ENABLE
+
+/*
+ * Extra keys and RGB Toggle handler
+ */
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+
+ switch (keycode) {
+
+ // handle RGB toggle key - this ensures caps lock always works
+ #ifdef RGB_MATRIX_ENABLE
+
+ case QK_BOOT:
+ if (record->event.pressed) {
+ rgb_matrix_set_color_all(RGB_MATRIX_MAXIMUM_BRIGHTNESS, 0, 0); // All red
+ rgb_matrix_driver.flush();
+ }
+ return true;
+
+ case RGB_TOG:
+ /* roll through the LED modes
+ * | Level | Per-key | Underglow |
+ * |------------|---------|-----------|
+ * | 0 (defalt) | on | on |
+ * | 1 | OFF | on |
+ * | 2 | on | OFF |
+ * | 3 | OFF | OFF |
+ */
+ if (record->event.pressed) {
+ if ( (!user_config.rgb_disable_perkey) && (!user_config.rgb_disable_underglow) ) {
+ user_config.rgb_disable_perkey = 1;
+ } else if ( user_config.rgb_disable_perkey && (!user_config.rgb_disable_underglow) ) {
+ user_config.rgb_disable_perkey = 0;
+ user_config.rgb_disable_underglow = 1;
+ } else if ( (!user_config.rgb_disable_perkey) && user_config.rgb_disable_underglow ) {
+ user_config.rgb_disable_perkey = 1;
+ } else {
+ user_config.rgb_disable_perkey = 0;
+ user_config.rgb_disable_underglow = 0;
+ }
+ id87_update_rgb_mode();
+ }
+ return false;
+
+ case RGB_TPK:
+ if (record->event.pressed) {
+ user_config.rgb_disable_perkey ^= 1;
+ id87_update_rgb_mode();
+ }
+ return false;
+
+ case RGB_TUG:
+ if (record->event.pressed) {
+ user_config.rgb_disable_underglow ^= 1;
+ id87_update_rgb_mode();
+ }
+ return false;
+
+ case EE_CLR:
+ if (!record->event.pressed) { // on release
+ id87_get_rgb_mode();
+ }
+ return true; // let this one pass on
+
+ #endif // RGB_MATRIX_ENABLE
+
+ // print firmware version
+ case KB_VRSN:
+ if (!get_mods()) {
+ if (!record->event.pressed) {
+ SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " (v" QMK_VERSION ")");
+ }
+ }
+ return false;
+
+ // @see: https://github.com/qmk/qmk_firmware/issues/10111#issuecomment-752300353
+ case KC_MCON:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_WINDOWS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case KC_LPAD:
+ if (record->event.pressed) {
+ host_consumer_send(_AC_SHOW_ALL_APPS);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ default:
+ return true; /* Process all other keycodes normally */
+ }
+}
diff --git a/keyboards/idobao/id87/v2/keymaps/idobao/rules.mk b/keyboards/idobao/id87/v2/keymaps/idobao/rules.mk
new file mode 100644
index 0000000000..974ef99660
--- /dev/null
+++ b/keyboards/idobao/id87/v2/keymaps/idobao/rules.mk
@@ -0,0 +1,3 @@
+
+LTO_ENABLE = yes
+VIA_ENABLE = yes
diff --git a/keyboards/idobao/id87/v2/keymaps/via/config.h b/keyboards/idobao/id87/v2/keymaps/via/config.h
new file mode 100644
index 0000000000..a1612e6e32
--- /dev/null
+++ b/keyboards/idobao/id87/v2/keymaps/via/config.h
@@ -0,0 +1,4 @@
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/idobao/id87/v2/keymaps/via/keymap.c b/keyboards/idobao/id87/v2/keymaps/via/keymap.c
index e71a924bfd..15e909c7e7 100644
--- a/keyboards/idobao/id87/v2/keymaps/via/keymap.c
+++ b/keyboards/idobao/id87/v2/keymaps/via/keymap.c
@@ -1,50 +1,81 @@
-/*
-Copyright 2020 Tybera
-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/>.
-*/
+// Copyright 2022 Vino Rodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [0] = LAYOUT_tkl_ansi(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT(1, KC_APP), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Esc│ │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Scr│Pse│
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │Del│End│PgD│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ │ ↑ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │Ctrl│GUI │Alt │ │ Alt│ GUI│MO(1│Ctrl│ │ ↠│ ↓ │ → │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [0] = LAYOUT_tkl_ansi(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
+
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │Rst│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │Hu+│ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ │Tog│Mod│ │ │ │ │ │ │ │ │ │ │ │ │St-│Hu-│St+│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ │ │mod│ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ │ │ │ │ │ │NRO│ │ │ │ │ MO(2) │ │Br+│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ │ │ │ │ │ │ │ │ │Sp-│Br-│Sp+│
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
[1] = LAYOUT_tkl_ansi(
- QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, _______,
- _______, BL_TOGG, RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_SAI, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, BL_INC,
- _______, _______, _______, _______, _______, _______, _______, _______, BL_INC, BL_DEC, RGB_MOD
+ QK_BOOT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, _______,
+ _______, RGB_TOG, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAD, RGB_HUD, RGB_SAI,
+ _______, _______, RGB_RMOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, MO(2), RGB_VAI,
+ _______, _______, _______, _______, _______, KC_APP, _______, _______, RGB_SPD, RGB_VAD, RGB_SPI
),
- [2] = LAYOUT_tkl_ansi(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
- [3] = LAYOUT_tkl_ansi(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
- ),
+
+ /*
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │M00│M01│M02│M03│M04│M05│M06│M07│M08│M09│M10│ │ │ │ │ │ │ │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ │M11│M12│M13│M14│M15│M16│ │ │ │ │ │ │ │ │ │ │ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ */
+ [2] = LAYOUT_tkl_ansi(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ MACRO00, MACRO01, MACRO02, MACRO03, MACRO04, MACRO05, MACRO06, MACRO07, MACRO08, MACRO09, MACRO10, _______, _______, _______, _______, _______, _______,
+ _______, MACRO11, MACRO12, MACRO13, MACRO14, MACRO15, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
};
diff --git a/keyboards/idobao/id87/v2/keymaps/via/rules.mk b/keyboards/idobao/id87/v2/keymaps/via/rules.mk
index ca9fed0e6b..974ef99660 100644
--- a/keyboards/idobao/id87/v2/keymaps/via/rules.mk
+++ b/keyboards/idobao/id87/v2/keymaps/via/rules.mk
@@ -1,2 +1,3 @@
+
LTO_ENABLE = yes
VIA_ENABLE = yes
diff --git a/keyboards/idobao/id87/v2/readme.md b/keyboards/idobao/id87/v2/readme.md
index 06a3f2c08a..f689d2175a 100644
--- a/keyboards/idobao/id87/v2/readme.md
+++ b/keyboards/idobao/id87/v2/readme.md
@@ -1,12 +1,24 @@
-# ID87 v2
+# IDOBAO ID87 v2
-![ID87 v2](https://i.imgur.com/woTSycN.jpg)
+![IDOBAO ID87](https://i.imgur.com/LIpWjog.png)
-A TKL keyboard with hotswap sockets and in switch RGB.
+A TKL hotswap board from IDOBAO.
-* Keyboard Maintainer: [peepeetee](https://github.com/peepeetee)
-* Hardware Supported: ID87 v2
-* Hardware Availability: [Drop](https://drop.com/buy/idobao-id87-v2-tkl-mechanical-keyboard-kit), [idobao](https://idobao.net/products/idobao-id87-v2-tkl-pcb-mounted-hot-swappable-mechanical-keyboard-kit)
+## ANSI Support
+
+* Keyboard Maintainer: [Vino Rodrigues](https://github.com/vinorodrigues)
+* Hardware Supported:
+ - **IDOBAO ID87v2**
+ - **IDOBAO ID87 Crystal**
+ - **IDOBAO ID87 Bestype**
+ - **IDOBAO ID87 Charm** *(Limited Edition)*
+* Hardware Availability: [IDOBAO.net](https://idobao.net/search?type=product&q=ID87*)
+
+## ANSI Layout
+
+![](https://idobao.github.io/kle/idobao-id87.png)
+
+## Compiling & Flashing
Make example for this keyboard (after setting up your build environment):
@@ -22,6 +34,6 @@ See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_to
Enter the bootloader in 3 ways:
-* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Bootmagic reset**: Hold down the [Escape] key *(the top left)* and plug in the keyboard
* **Physical reset button**: Briefly press the button on the back of the PCB
-* **Keycode in layout**: Press the key mapped to `RESET` if it is available
+* **Keycode in layout**: Press the key mapped to `RESET` *(default is [Fn]+[Escape])*
diff --git a/keyboards/idobao/id87/v2/rules.mk b/keyboards/idobao/id87/v2/rules.mk
index 1d519258e3..eab741fd0a 100644
--- a/keyboards/idobao/id87/v2/rules.mk
+++ b/keyboards/idobao/id87/v2/rules.mk
@@ -1,22 +1,5 @@
-# MCU name
-MCU = atmega32u4
+# This file intentionally left blank
+# ** settings are data driven & stored in `info.json` **
-# Bootloader selection
-BOOTLOADER = atmel-dfu
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = yes # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
-AUDIO_ENABLE = no # Audio output
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = WS2812
-
-LAYOUTS = tkl_ansi
diff --git a/keyboards/idobao/id87/v2/v2.c b/keyboards/idobao/id87/v2/v2.c
index 5bca630ca3..34f0a74669 100644
--- a/keyboards/idobao/id87/v2/v2.c
+++ b/keyboards/idobao/id87/v2/v2.c
@@ -1,45 +1,83 @@
-// Copyright 2022 peepeetee (@peepeetee)
+// Copyright 2022 vinorodrigues (@vinorodrigues)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "v2.h"
-#ifdef RGB_MATRIX_ENABLE
+#define __ NO_LED
+
+#if defined(RGB_MATRIX_ENABLE)
+
+/* Under-, Per-Key
+ * ┌───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───┬───┠┌───┬───┬───â”
+ * │102│ │101│100│99 │98 │ │97 │96 │95 │94 │ │93 │92 │91 │90 │ │89 │88 │87 │
+ * └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┠┌───┬───┬───â”
+ * │70 │71 │72 │73 │74 │75 │76 │77 │78 │79 │80 │81 │82 │ 83 │ │84 │85 │86 │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤
+ * │ 69 │68 │67 │66 │65 │64 │63 │62 │61 │60 │59 │58 │57 │ 56 │ │55 │54 │53 │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘
+ * │ 40 │41 │42 │43 │44 │45 │46 │47 │48 │49 │50 │51 │ 52 │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───â”
+ * │ 39 │38 │37 │36 │35 │34 │33 │32 │31 │30 │29 │ 28 │ │27 │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───â”
+ * │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ │24 │25 │26 │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
+ *
+ * Underglow (as seen from top)
+ * ┌───┬───┬───┬───┬───┬───┬───â”
+ * │14 │13 │12 │11 │10 │ 9 │ 8 │
+ * ├───┼───┴───┴───┴───┴───┼───┤
+ * │15 │ │ 7 │
+ * ├───┼───┬───┬───┬───┬───┼───┤
+ * │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
+ * └───┴───┴───┴───┴───┴───┴───┘
+*/
led_config_t g_led_config = { {
// Key Matrix to LED Index
- { 102, NO_LED, 101, 100, 99, 98, 97, 96, 95 }, //0
- { 70, 71, 72, 73, 74, 75, 76, 77, 78 }, //1
- { 69, 68, 67, 66, 65, 64, 63, 62, 61 }, //2
- { 40, 41, 42, 43, 44, 45, 46, 47, 48 }, //3
- { 39, NO_LED, 38, 37, 36, 35, 34, 33, 32 }, //4
- { 16, 17, 18, 23, 22, NO_LED, 19, 21, 20 }, //5
- { NO_LED, 87, 88, 90, 91, 92, 89, 93, 94 }, //6
- { 80, 86, 85, 83, NO_LED, 82, 84, 81, 79 }, //7
- { NO_LED, 53, 54, 56, 57, 58, 55, 59, 60 }, //8
- { NO_LED, NO_LED, 27, 52, NO_LED, 51, NO_LED, 50, 49 }, //9
- { NO_LED, 26, 25, NO_LED, 28, 29, 24, 30, 31 } //A
+ // partially generated from: https://xelus.netlify.app/guides/KLE_to_RGB_parser & CSV Excel formula
+
+ { 102, __, 101, 100, 99, 98, 97, 96, 95 },
+ { 70, 71, 72, 73, 74, 75, 76, 77, 78 },
+ { 69, 68, 67, 66, 65, 64, 63, 62, 61 },
+ { 40, 41, 42, 43, 44, 45, 46, 47, 48 },
+ { 39, __, 38, 37, 36, 35, 34, 33, 32 },
+ { 16, 17, 18, 23, 22, __, 19, 21, 20 },
+ { __, 87, 88, 90, 91, 92, 89, 93, 94 },
+ { 80, 86, 85, 83, __, 82, 84, 81, 79 },
+ { __, 53, 54, 56, 57, 58, 55, 59, 60 },
+ { __, __, 27, 52, __, 51, __, 50, 49 },
+ { __, 26, 25, __, 28, 29, 24, 30, 31 }
}, {
// LED Index to Physical Position
- { 13, 51 },{ 40, 51},{ 73, 51},{ 108, 51},{ 141, 51},{ 174, 51},{ 207, 51},
- { 207, 32},
- { 207, 13},{ 174, 13},{ 141, 13},{ 108, 13},{ 73, 13},{ 40, 13},{ 13, 13},
- { 13, 32},
-
-{ 8, 59 }, { 23, 59 }, { 38, 59 }, { 83, 59 }, { 129, 59 }, { 144, 59 }, { 159, 59 }, { 174, 59 }, { 193, 59 }, { 205, 59 }, { 217, 59 },
-{ 205, 49 }, { 165, 49 }, { 142, 49 }, { 130, 49 }, { 118, 49 }, { 106, 49 }, { 94, 49 }, { 82, 49 }, { 70, 49 }, { 58, 49 }, { 46, 49 }, { 34, 49 }, { 14, 49 },
-{ 11, 39 }, { 28, 39 }, { 40, 39 }, { 52, 39 }, { 64, 39 }, { 76, 39 }, { 88, 39 }, { 100, 39 }, { 112, 39 }, { 124, 39 }, { 136, 39 }, { 148, 39 }, { 168, 39 },
-{ 217, 30 }, { 205, 30 }, { 193, 30 }, { 172, 30 }, { 157, 30 }, { 145, 30 }, { 133, 30 }, { 121, 30 }, { 109, 30 }, { 97, 30 }, { 85, 30 }, { 73, 30 }, { 61, 30 }, { 49, 30 }, { 37, 30 }, { 25, 30 }, { 10, 30 },
-{ 7, 20 }, { 19, 20 }, { 31, 20 }, { 43, 20 }, { 55, 20 }, { 67, 20 }, { 79, 20 }, { 91, 20 }, { 103, 20 }, { 115, 20 }, { 127, 20 }, { 139, 20 }, { 151, 20 }, { 169, 20 }, { 193, 20 }, { 205, 20 }, { 217, 20 },
-{ 217, 5 }, { 205, 5 }, { 193, 5 }, { 175, 5 }, { 163, 5 }, { 151, 5 }, { 139, 5 }, { 121, 5 }, { 109, 5 }, { 97, 5 }, { 85, 5 }, { 67, 5 }, { 55, 5 }, { 43, 5 }, { 31, 5 },{ 7, 5 },
+ // generated from: https://xelus.netlify.app/guides/KLE_to_RGB_parser
+ // underglow
+ /* colors are pushed to the edge as only the edges can be seen */
+ { 0,64 }, { 37,64 }, { 75,64 }, {112,64 }, {149,64 }, {187,64 }, {224,64 },
+ {224,32 },
+ {224,0 }, {187,0 }, {149,0 }, {112,0 }, { 75,0 }, { 37,0 }, { 0,0 },
+ { 0,32 },
+ // under-, per-key
+ /* pattern is complex; starts at btm-lft, zig-zags up, and ends top-lft */
+ { 2,64 }, { 18,64 }, { 34,64 }, { 83,64 }, {131,64 }, {148,64 }, {164,64 }, {180,64 }, {198,64 }, {211,64 }, {224,64 }, // lf-2-rt, btm
+ {211,52 }, {170,52 }, {146,52 }, {133,52 }, {120,52 }, {107,52 }, { 94,52 }, { 81,52 }, { 68,52 }, { 55,52 }, { 42,52 }, { 29,52 }, { 8,52 }, // rt-2-lf**
+ { 5,40 }, { 23,40 }, { 36,40 }, { 49,40 }, { 62,40 }, { 75,40 }, { 88,40 }, {101,40 }, {114,40 }, {127,40 }, {140,40 }, {153,40 }, {174,40 }, // lf-2-rt
+ {224,27 }, {211,27 }, {198,27 }, {179,27 }, {162,27 }, {149,27 }, {136,27 }, {123,27 }, {110,27 }, { 97,27 }, { 84,27 }, { 71,27 }, { 58,27 }, { 45,27 }, { 32,27 }, { 19,27 }, { 3,27 }, // rt-2-lf**
+ { 0,15 }, { 13,15 }, { 26,15 }, { 39,15 }, { 52,15 }, { 65,15 }, { 78,15 }, { 91,15 }, {104,15 }, {117,15 }, {130,15 }, {143,15 }, {156,15 }, {175,15 }, {198,15 }, {211,15 }, {224,15 }, // lf-2-rt
+ {224,0 }, {211,0 }, {198,0 }, {182,0 }, {169,0 }, {156,0 }, {143,0 }, {123,0 }, {110,0 }, { 97,0 }, { 84,0 }, { 65,0 }, { 52,0 }, { 39,0 }, { 26,0 }, { 0,0 }, // rt-2-lf**, top
}, {
// LED Index to Flag
-2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-
-1,1,1,4,1,1,1,1,1,1,1,
-1,1,4,4,4,4,4,4,4,4,4,4,1,
-9,4,4,4,4,4,4,4,4,4,4,4,1,
-1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,1,
-4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,
-1,9,1,4,4,4,4,1,1,1,1,4,4,4,4,1
+ // underglow
+ 2, 2, 2, 2, 2, 2, 2,
+ 2,
+ 2, 2, 2, 2, 2, 2, 2,
+ 2,
+ // under-, per-key
+ 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
+ 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
+ 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
} };
-#endif
+#endif // RGB_MATRIX_ENABLE
diff --git a/keyboards/idobao/id87/v2/v2.h b/keyboards/idobao/id87/v2/v2.h
index 1a75d95755..38b3c9dfda 100644
--- a/keyboards/idobao/id87/v2/v2.h
+++ b/keyboards/idobao/id87/v2/v2.h
@@ -1,40 +1,6 @@
-/*
-Copyright 2020 Tybera
-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/>.
-*/
+// Copyright 2022 vinorodrigues (@vinorodrigues)
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
-
-#define LAYOUT_tkl_ansi( \
- K00, K02, K03, K04, K05, K06, K07, K08, K68, K67, K65, K64, K63, K66, K62, K61, \
- K10, K11, K12, K13, K14, K15, K16, K17, K18, K78, K70, K77, K75, K73, K76, K72, K71, \
- K20, K21, K22, K23, K24, K25, K26, K27, K28, K88, K87, K85, K84, K83, K86, K82, K81, \
- K30, K31, K32, K33, K34, K35, K36, K37, K38, K98, K97, K95, K93, \
- K40, K42, K43, K44, K45, K46, K47, K48, KA8, KA7, KA5, KA4, K92, \
- K50, K51, K52, K56, K58, K57, K54, K53, KA6, KA2, KA1 \
-) { \
- { K00, KC_NO, K02, K03, K04, K05, K06, K07, K08 }, \
- { K10, K11, K12, K13, K14, K15, K16, K17, K18 }, \
- { K20, K21, K22, K23, K24, K25, K26, K27, K28 }, \
- { K30, K31, K32, K33, K34, K35, K36, K37, K38 }, \
- { K40, KC_NO, K42, K43, K44, K45, K46, K47, K48 }, \
- { K50, K51, K52, K53, K54, KC_NO, K56, K57, K58 }, \
- { KC_NO, K61, K62, K63, K64, K65, K66, K67, K68 }, \
- { K70, K71, K72, K73, KC_NO, K75, K76, K77, K78 }, \
- { KC_NO, K81, K82, K83, K84, K85, K86, K87, K88 }, \
- { KC_NO, KC_NO, K92, K93, KC_NO, K95, KC_NO, K97, K98 }, \
- { KC_NO, KA1, KA2, KC_NO, KA4, KA5, KA6, KA7, KA8 }, \
-}
-
-
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/default/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/default/keymap.c
index cd65001803..6f9967b46e 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/default/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/default/keymap.c
@@ -167,7 +167,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/gordon/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/gordon/keymap.c
index c321d546fb..50e3238a7d 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/gordon/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/gordon/keymap.c
@@ -335,7 +335,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_on();
ergodox_led_all_on();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/halfkeyboard/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/halfkeyboard/keymap.c
index 3870dd8ffd..c8498fe9e9 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/halfkeyboard/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/halfkeyboard/keymap.c
@@ -492,7 +492,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/input_club/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/input_club/keymap.c
index 545429fca0..e941cee154 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/input_club/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/input_club/keymap.c
@@ -223,7 +223,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/narze/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/narze/keymap.c
index dd721e9a78..184eb638c9 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/narze/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/narze/keymap.c
@@ -659,7 +659,7 @@ void matrix_setup(void) {
}
void matrix_scan_user(void) {
- // uint8_t layer = biton32(layer_state);
+ // uint8_t layer = get_highest_layer(layer_state);
// ergodox_board_led_off();
// ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/nordic_ergo/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/nordic_ergo/keymap.c
index d08b96cc6e..70f49bb5c9 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/nordic_ergo/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/nordic_ergo/keymap.c
@@ -221,7 +221,7 @@ void matrix_init_user(void){
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/rask/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/rask/keymap.c
index e31c1c5d6b..b202823c77 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/rask/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/rask/keymap.c
@@ -179,7 +179,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/rjhilgefort/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/rjhilgefort/keymap.c
index 31d218ebfb..c322222baf 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/rjhilgefort/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/rjhilgefort/keymap.c
@@ -309,7 +309,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/ergodox_infinity/keymaps/trulyergonomic/keymap.c b/keyboards/input_club/ergodox_infinity/keymaps/trulyergonomic/keymap.c
index 02f409ad9e..bbc24ea27f 100644
--- a/keyboards/input_club/ergodox_infinity/keymaps/trulyergonomic/keymap.c
+++ b/keyboards/input_club/ergodox_infinity/keymaps/trulyergonomic/keymap.c
@@ -137,7 +137,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/input_club/infinity60/keymaps/jpetermans/keymap.c b/keyboards/input_club/infinity60/keymaps/jpetermans/keymap.c
index 3c2e0d4da8..a19be6664c 100644
--- a/keyboards/input_club/infinity60/keymaps/jpetermans/keymap.c
+++ b/keyboards/input_club/infinity60/keymaps/jpetermans/keymap.c
@@ -239,7 +239,7 @@ void matrix_scan_user(void) {
//Turn on layer indicator or page depending on mode
switch(led_mode_global) {
case MODE_FLASH: //flash preset page leds then single indicator
- page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
+ page = get_highest_layer(layer_state) > max_pages ? 7 : get_highest_layer(layer_state);
msg=(page << 8) | DISPLAY_PAGE;
chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
chThdSleepMilliseconds(500);
@@ -254,7 +254,7 @@ void matrix_scan_user(void) {
break;
case MODE_PAGE: //display pre-defined led page
- page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
+ page = get_highest_layer(layer_state) > max_pages ? 7 : get_highest_layer(layer_state);
msg=(page << 8) | DISPLAY_PAGE;
chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
break;
diff --git a/keyboards/jc65/v32u4/keymaps/gam3cat/keymap.c b/keyboards/jc65/v32u4/keymaps/gam3cat/keymap.c
index 7572b9e073..453cd2360d 100644
--- a/keyboards/jc65/v32u4/keymaps/gam3cat/keymap.c
+++ b/keyboards/jc65/v32u4/keymaps/gam3cat/keymap.c
@@ -224,7 +224,7 @@ void matrix_scan_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _BL:
custom_backlight_level(0);
rgblight_sethsv_noeeprom(180,100,255);
diff --git a/keyboards/jones/v03/keymaps/default_jp/config.h b/keyboards/jones/v03/keymaps/default_jp/config.h
index aa06121c1c..7545003ac7 100644
--- a/keyboards/jones/v03/keymaps/default_jp/config.h
+++ b/keyboards/jones/v03/keymaps/default_jp/config.h
@@ -21,3 +21,4 @@
// time for long press
#define TAPPING_TERM 200
+#define TAPPING_TERM_PER_KEY
diff --git a/keyboards/jones/v03/keymaps/default_jp/keymap.c b/keyboards/jones/v03/keymaps/default_jp/keymap.c
index 3f5b10208c..bdcb9e88b1 100644
--- a/keyboards/jones/v03/keymaps/default_jp/keymap.c
+++ b/keyboards/jones/v03/keymaps/default_jp/keymap.c
@@ -51,9 +51,18 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data);
// Tap Dance definitions
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
- [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275),
+ [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_ESC_NUM):
+ return 275;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MAC = SAFE_RANGE,
@@ -303,7 +312,7 @@ static tap ql_tap_state = {
// Functions that control what our tap dance key does
void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
ql_tap_state.state = cur_dance(state);
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM): // ESC key action
switch (ql_tap_state.state) {
case SINGLE_TAP:
@@ -332,7 +341,7 @@ void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
}
void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM):
// If the key was held down and now is released then switch off the layer
if (ql_tap_state.state == TAP_HOLD) {
diff --git a/keyboards/jones/v03_1/keymaps/default_ansi/config.h b/keyboards/jones/v03_1/keymaps/default_ansi/config.h
index 0b51190bbe..ee7b09a90c 100644
--- a/keyboards/jones/v03_1/keymaps/default_ansi/config.h
+++ b/keyboards/jones/v03_1/keymaps/default_ansi/config.h
@@ -21,6 +21,7 @@
// time for long press
#define TAPPING_TERM 200
+#define TAPPING_TERM_PER_KEY
// music map for music-mode
#define MUSIC_MAP
diff --git a/keyboards/jones/v03_1/keymaps/default_ansi/keymap.c b/keyboards/jones/v03_1/keymaps/default_ansi/keymap.c
index 5b1486bb86..a592418c4d 100644
--- a/keyboards/jones/v03_1/keymaps/default_ansi/keymap.c
+++ b/keyboards/jones/v03_1/keymaps/default_ansi/keymap.c
@@ -50,9 +50,18 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data);
// Tap Dance definitions
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
- [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275),
+ [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_ESC_NUM):
+ return 275;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MAC = SAFE_RANGE,
@@ -244,7 +253,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
}
}
if (index == 1) { /* Second encoder, Left side */
- switch(biton32(layer_state)) {
+ switch(get_highest_layer(layer_state)) {
case _LOWER:
if (clockwise) {
rgblight_decrease_hue();
@@ -322,7 +331,7 @@ static tap ql_tap_state = {
// Functions that control what our tap dance key does
void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
ql_tap_state.state = cur_dance(state);
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM): // ESC key action
switch (ql_tap_state.state) {
case SINGLE_TAP:
@@ -351,7 +360,7 @@ void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
}
void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM):
// If the key was held down and now is released then switch off the layer
if (ql_tap_state.state == TAP_HOLD) {
diff --git a/keyboards/jones/v03_1/keymaps/default_jp/config.h b/keyboards/jones/v03_1/keymaps/default_jp/config.h
index 0b51190bbe..ee7b09a90c 100644
--- a/keyboards/jones/v03_1/keymaps/default_jp/config.h
+++ b/keyboards/jones/v03_1/keymaps/default_jp/config.h
@@ -21,6 +21,7 @@
// time for long press
#define TAPPING_TERM 200
+#define TAPPING_TERM_PER_KEY
// music map for music-mode
#define MUSIC_MAP
diff --git a/keyboards/jones/v03_1/keymaps/default_jp/keymap.c b/keyboards/jones/v03_1/keymaps/default_jp/keymap.c
index 436586a721..56f51d56ce 100644
--- a/keyboards/jones/v03_1/keymaps/default_jp/keymap.c
+++ b/keyboards/jones/v03_1/keymaps/default_jp/keymap.c
@@ -51,9 +51,18 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data);
// Tap Dance definitions
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
- [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275),
+ [TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_ESC_NUM):
+ return 275;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MAC = SAFE_RANGE,
@@ -246,7 +255,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
}
}
if (index == 1) { /* Second encoder, Left side */
- switch(biton32(layer_state)) {
+ switch(get_highest_layer(layer_state)) {
case _LOWER:
if (clockwise) {
rgblight_decrease_hue();
@@ -324,7 +333,7 @@ static tap ql_tap_state = {
// Functions that control what our tap dance key does
void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
ql_tap_state.state = cur_dance(state);
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM): // ESC key action
switch (ql_tap_state.state) {
case SINGLE_TAP:
@@ -353,7 +362,7 @@ void ql_finished(qk_tap_dance_state_t *state, void *user_data) {
}
void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
- switch(state->keycode) {
+ switch(TAP_DANCE_KEYCODE(state)) {
case TD(TD_ESC_NUM):
// If the key was held down and now is released then switch off the layer
if (ql_tap_state.state == TAP_HOLD) {
diff --git a/keyboards/kakunpc/angel64/alpha/keymaps/default/keymap.c b/keyboards/kakunpc/angel64/alpha/keymaps/default/keymap.c
index 0f2a8dada1..92dfa7da6e 100644
--- a/keyboards/kakunpc/angel64/alpha/keymaps/default/keymap.c
+++ b/keyboards/kakunpc/angel64/alpha/keymaps/default/keymap.c
@@ -40,7 +40,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef OLED_ENABLE
bool oled_task_user(void) {
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case BASE:
oled_write_P(PSTR("Default\n"), false);
break;
diff --git a/keyboards/kakunpc/angel64/rev1/keymaps/kakunpc/keymap.c b/keyboards/kakunpc/angel64/rev1/keymaps/kakunpc/keymap.c
index 6c5184c1b3..601bf5f02f 100644
--- a/keyboards/kakunpc/angel64/rev1/keymaps/kakunpc/keymap.c
+++ b/keyboards/kakunpc/angel64/rev1/keymaps/kakunpc/keymap.c
@@ -175,7 +175,7 @@ void matrix_scan_user(void) {
#ifdef OLED_ENABLE
bool oled_task_user(void) {
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case BASE:
oled_write_P(PSTR("Default\n"), false);
break;
diff --git a/keyboards/kakunpc/suihankey/alpha/keymaps/default/keymap.c b/keyboards/kakunpc/suihankey/alpha/keymaps/default/keymap.c
index b682f0f15d..d937b68813 100644
--- a/keyboards/kakunpc/suihankey/alpha/keymaps/default/keymap.c
+++ b/keyboards/kakunpc/suihankey/alpha/keymaps/default/keymap.c
@@ -58,7 +58,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef OLED_ENABLE
bool oled_task_user(void) {
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case BASE:
oled_write_P(PSTR("Default\n"), false);
break;
diff --git a/keyboards/kakunpc/suihankey/rev1/keymaps/default/keymap.c b/keyboards/kakunpc/suihankey/rev1/keymaps/default/keymap.c
index b682f0f15d..d937b68813 100644
--- a/keyboards/kakunpc/suihankey/rev1/keymaps/default/keymap.c
+++ b/keyboards/kakunpc/suihankey/rev1/keymaps/default/keymap.c
@@ -58,7 +58,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef OLED_ENABLE
bool oled_task_user(void) {
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case BASE:
oled_write_P(PSTR("Default\n"), false);
break;
diff --git a/keyboards/kbdfans/kbd6x/keymaps/othi/keymap.c b/keyboards/kbdfans/kbd6x/keymaps/othi/keymap.c
index 6bbbdd87c1..ce341509a6 100644
--- a/keyboards/kbdfans/kbd6x/keymaps/othi/keymap.c
+++ b/keyboards/kbdfans/kbd6x/keymaps/othi/keymap.c
@@ -38,7 +38,7 @@ void eeconfig_init_user(void) {
#define DE_UDIA_CAP UC(0x00DC)
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case NM_MODE:
rgblight_setrgb (0x00, 0x66, 0x00);
break;
@@ -187,4 +187,3 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______
),
};
-
diff --git a/keyboards/kbdfans/kbd75/keymaps/edulpn/keymap.c b/keyboards/kbdfans/kbd75/keymaps/edulpn/keymap.c
index 998f1a25d2..5a6d760355 100644
--- a/keyboards/kbdfans/kbd75/keymaps/edulpn/keymap.c
+++ b/keyboards/kbdfans/kbd75/keymaps/edulpn/keymap.c
@@ -45,7 +45,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case WINDOWS_LAYER:
rgblight_setrgb_blue();
break;
diff --git a/keyboards/kbdfans/niu_mini/keymaps/tobias/keymap.c b/keyboards/kbdfans/niu_mini/keymaps/tobias/keymap.c
index 935dd5c506..8c03ae2df2 100644
--- a/keyboards/kbdfans/niu_mini/keymaps/tobias/keymap.c
+++ b/keyboards/kbdfans/niu_mini/keymaps/tobias/keymap.c
@@ -8,7 +8,7 @@
* 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.
+ * 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/>.
@@ -103,8 +103,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_EQL, S(KC_EQL), RALT(KC_2), RALT(KC_3), RALT(KC_4), RALT(KC_E), KC_RBRC, RALT(KC_7), RALT(KC_8), RALT(KC_9), RALT(KC_0), RALT(KC_MINS),
KC_LSFT, KC_NUBS, RALT(KC_NUBS), S(KC_NUBS), DGRMCRO, XXXXXXX, XXXXXXX, RALT(KC_M), KC_RBRC, S(KC_RBRC), RALT(KC_RBRC), _______,
_______, _______, KC_RALT, _______,TO(_ADJUST), _______, _______, _______, _______, _______, _______, TO(_QWERTY)
-),
-
+),
+
/* Lower
* ,-----------------------------------------------------------------------------------.
@@ -257,10 +257,10 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
else {
workmode = false;
- return false;
- }
+ return false;
+ }
}
-
+
}
return true;
}
@@ -293,7 +293,7 @@ void rgbflag(uint8_t r, uint8_t g, uint8_t b) {
layer_state_t layer_state_set_user(layer_state_t state) {
// if(rgblight_get_mode() == 1) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _QWERTY:
if(!workmode){
rgblight_mode(9);
@@ -312,7 +312,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
tap_code(KC_NLCK);
}
rgbflag(0xFF, 0x00, 0x00);
-
+
break;
case _ADJUST:
rgblight_mode(1);
@@ -350,7 +350,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
rgblight_mode(1);
if(bnumlock) {
tap_code(KC_NLCK);
- }
+ }
rgbflag(0xFF, 0xFF, 0xFF);
break;
}
@@ -363,8 +363,8 @@ layer_state_t layer_state_set_user(layer_state_t state) {
//Layer LED indicators
uint32_t layer = layer_state;
-
-
+
+
if (layer & (1<<2)) {
if(!bnumlock) {
numlock_changed = true;
@@ -373,10 +373,10 @@ layer_state_t layer_state_set_user(layer_state_t state) {
bnumlock = true;
}
}
-}
+}
*/
-
-
+
+
void led_set_user(uint8_t usb_led) {
if (usb_led & (1 << USB_LED_NUM_LOCK)) {
@@ -410,4 +410,4 @@ void led_set_user(uint8_t usb_led) {
}
-} \ No newline at end of file
+}
diff --git a/keyboards/kbdfans/niu_mini/keymaps/xtonhasvim/keymap.c b/keyboards/kbdfans/niu_mini/keymaps/xtonhasvim/keymap.c
index bfda812738..d3c6102b16 100644
--- a/keyboards/kbdfans/niu_mini/keymaps/xtonhasvim/keymap.c
+++ b/keyboards/kbdfans/niu_mini/keymaps/xtonhasvim/keymap.c
@@ -187,7 +187,7 @@ void rgbflag(uint8_t r, uint8_t g, uint8_t b, uint8_t rr, uint8_t gg, uint8_t bb
void set_state_leds(void) {
if (rgblight_get_mode() == 1) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _RAISE:
rgbflag(C_BLU, C_GRN);
break;
diff --git a/keyboards/keebio/bdn9/keymaps/vosechu-ksp/keymap.c b/keyboards/keebio/bdn9/keymaps/vosechu-ksp/keymap.c
index a449c3ec3d..3b92657d4d 100644
--- a/keyboards/keebio/bdn9/keymaps/vosechu-ksp/keymap.c
+++ b/keyboards/keebio/bdn9/keymaps/vosechu-ksp/keymap.c
@@ -64,7 +64,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
flight_mode = false;
rcs_mode = false;
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _PANIC:
panic_mode = true; // For use in encoder evaluation
rgblight_sethsv_noeeprom(HSV_RED);
diff --git a/keyboards/keebio/bfo9000/keymaps/abstractkb/keymap.c b/keyboards/keebio/bfo9000/keymaps/abstractkb/keymap.c
index 29531b9973..ad56226ac6 100644
--- a/keyboards/keebio/bfo9000/keymaps/abstractkb/keymap.c
+++ b/keyboards/keebio/bfo9000/keymaps/abstractkb/keymap.c
@@ -42,7 +42,7 @@ void matrix_post_init_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _LIST:
rgblight_sethsv_noeeprom(0,255,255);
rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL);
@@ -87,6 +87,3 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
}
-
-
-
diff --git a/keyboards/keebio/iris/keymaps/edvorakjp/keymap.c b/keyboards/keebio/iris/keymaps/edvorakjp/keymap.c
index 0c0fc5a746..013d6c00a5 100644
--- a/keyboards/keebio/iris/keymaps/edvorakjp/keymap.c
+++ b/keyboards/keebio/iris/keymaps/edvorakjp/keymap.c
@@ -59,9 +59,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_init_keymap() {}
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
-uint32_t layer_state_set_keymap(uint32_t state) {
+layer_state_t layer_state_set_keymap(layer_state_t state) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case L_EDVORAKJP_LOWER:
rgblight_sethsv_noeeprom_red();
break;
diff --git a/keyboards/keebio/iris/keymaps/jerryhcooke/keymap.c b/keyboards/keebio/iris/keymaps/jerryhcooke/keymap.c
index e0c09638b2..bc04f9fbfd 100644
--- a/keyboards/keebio/iris/keymaps/jerryhcooke/keymap.c
+++ b/keyboards/keebio/iris/keymaps/jerryhcooke/keymap.c
@@ -11,7 +11,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {[0] = LAYOUT(KC_GE
#ifdef ENCODER_ENABLE
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _LOWER:
clockwise ? tap_code(KC_MS_WH_UP) : tap_code(KC_MS_WH_DOWN);
break;
@@ -23,7 +23,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
break;
}
} else if (index == 1) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _LOWER:
clockwise ? tap_code(KC_UP) : tap_code(KC_DOWN);
break;
diff --git a/keyboards/keebio/iris/keymaps/sq5rix/keymap.c b/keyboards/keebio/iris/keymaps/sq5rix/keymap.c
index 19a939a55b..d3e0d680a1 100644
--- a/keyboards/keebio/iris/keymaps/sq5rix/keymap.c
+++ b/keyboards/keebio/iris/keymaps/sq5rix/keymap.c
@@ -134,7 +134,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
}
// tmux screen
else if (index == 1) {
- switch(biton32(layer_state)){
+ switch(get_highest_layer(layer_state)){
case 0:
if (clockwise) {
send_string(SS_LCTL("B")"p");
@@ -182,4 +182,3 @@ layer_state_t layer_state_set_user(layer_state_t state) {
rgblight_set_layer_state(2, layer_state_cmp(state, 4));
return state;
}
-
diff --git a/keyboards/keebio/levinson/keymaps/issmirnov/keymap.c b/keyboards/keebio/levinson/keymaps/issmirnov/keymap.c
index d9edfebaa0..6de2279be4 100644
--- a/keyboards/keebio/levinson/keymaps/issmirnov/keymap.c
+++ b/keyboards/keebio/levinson/keymaps/issmirnov/keymap.c
@@ -91,7 +91,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE
layer_state_set_rgb(state);
#endif
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
combo_enable(); // by default, enable combos.
switch (layer) {
case 0:
diff --git a/keyboards/keebio/levinson/keymaps/issmirnov/rgb.c b/keyboards/keebio/levinson/keymaps/issmirnov/rgb.c
index de3a5342c0..3695731353 100644
--- a/keyboards/keebio/levinson/keymaps/issmirnov/rgb.c
+++ b/keyboards/keebio/levinson/keymaps/issmirnov/rgb.c
@@ -45,7 +45,7 @@ void matrix_scan_rgb(void) {
}
void set_rgb_indicators(uint8_t this_mod, uint8_t this_osm) {
- if (biton32(layer_state) == _QWERTY) {
+ if (get_highest_layer(layer_state) == _QWERTY) {
if ((this_mod | this_osm) & MOD_MASK_SHIFT) {
rgblight_setrgb_gold_at(SHFT_LED1);
} else {
diff --git a/keyboards/keebio/levinson/keymaps/issmirnov/rgb.h b/keyboards/keebio/levinson/keymaps/issmirnov/rgb.h
index 254d3cbac0..8b14d8571d 100644
--- a/keyboards/keebio/levinson/keymaps/issmirnov/rgb.h
+++ b/keyboards/keebio/levinson/keymaps/issmirnov/rgb.h
@@ -6,7 +6,7 @@
void keyboard_post_init_rgb(void);
// If rgb enabled, set underglow for layer
-uint32_t layer_state_set_rgb(uint32_t state);
+layer_state_t layer_state_set_rgb(layer_state_t state);
// Enhance matrix scan code. Note: keep this light, since it runs every 100ms
void matrix_scan_rgb(void);
diff --git a/keyboards/keebio/levinson/keymaps/xtonhasvim/keymap.c b/keyboards/keebio/levinson/keymaps/xtonhasvim/keymap.c
index 16aa965d7d..014e6c9c23 100644
--- a/keyboards/keebio/levinson/keymaps/xtonhasvim/keymap.c
+++ b/keyboards/keebio/levinson/keymaps/xtonhasvim/keymap.c
@@ -182,7 +182,7 @@ void rgbflag(uint8_t r, uint8_t g, uint8_t b, uint8_t rr, uint8_t gg, uint8_t bb
void set_state_leds(void) {
if (rgblight_get_mode() == 1) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _RAISE:
rgbflag(C_BLU, C_GRN);
break;
diff --git a/keyboards/keebio/nyquist/keymaps/danielhklein/config.h b/keyboards/keebio/nyquist/keymaps/danielhklein/config.h
index 09abbccb72..398b285b89 100644
--- a/keyboards/keebio/nyquist/keymaps/danielhklein/config.h
+++ b/keyboards/keebio/nyquist/keymaps/danielhklein/config.h
@@ -14,13 +14,11 @@ 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
#define TAPPING_TERM 150
#define USE_SERIAL
#define EE_HANDS
-#define BOOTMAGIC_KEY_SALT KC_ENT
-
#ifdef SUBPROJECT_rev1
#include "../../rev1/config.h"
diff --git a/keyboards/keebio/nyquist/keymaps/pitty/keymap.c b/keyboards/keebio/nyquist/keymaps/pitty/keymap.c
index 31912bb63e..2016cd1c46 100644
--- a/keyboards/keebio/nyquist/keymaps/pitty/keymap.c
+++ b/keyboards/keebio/nyquist/keymaps/pitty/keymap.c
@@ -143,7 +143,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE
uint8_t default_layer = eeconfig_read_default_layer();
if (rgb_layer_change) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _LOWER:
rgblight_set_purple;
rgblight_mode(5);
diff --git a/keyboards/keebio/quefrency/keymaps/georgepetri/keymap.c b/keyboards/keebio/quefrency/keymaps/georgepetri/keymap.c
index a367e877fe..7d6f9da30e 100644
--- a/keyboards/keebio/quefrency/keymaps/georgepetri/keymap.c
+++ b/keyboards/keebio/quefrency/keymaps/georgepetri/keymap.c
@@ -64,7 +64,7 @@ void keyboard_post_init_user(void) {
}
void update_led(void) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _BASE:
rgblight_sethsv_noeeprom(HSV_BLUE);
break;
diff --git a/keyboards/keycapsss/o4l_5x12/keymaps/default/keymap.c b/keyboards/keycapsss/o4l_5x12/keymaps/default/keymap.c
index 050b5a2c3e..2f64a56e9a 100644
--- a/keyboards/keycapsss/o4l_5x12/keymaps/default/keymap.c
+++ b/keyboards/keycapsss/o4l_5x12/keymaps/default/keymap.c
@@ -92,7 +92,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_ortho_5x12(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______,_______, _______, KC_DEL,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, _______, _______, _______, _______,
_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/keychron/q2/config.h b/keyboards/keychron/q2/config.h
index d019bcee15..e513536056 100644
--- a/keyboards/keychron/q2/config.h
+++ b/keyboards/keychron/q2/config.h
@@ -64,7 +64,8 @@
#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047
/* EEPROM Driver Configuration */
-#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS 0b10100010
+#define WEAR_LEVELING_LOGICAL_SIZE 2048
+#define WEAR_LEVELING_BACKING_SIZE (WEAR_LEVELING_LOGICAL_SIZE * 2)
// RGB Matrix Animation modes. Explicitly enabled
// For full list of effects, see:
diff --git a/keyboards/keychron/q2/rev_0110/rules.mk b/keyboards/keychron/q2/rev_0110/rules.mk
index 30394028b3..38d48f0b27 100644
--- a/keyboards/keychron/q2/rev_0110/rules.mk
+++ b/keyboards/keychron/q2/rev_0110/rules.mk
@@ -20,7 +20,8 @@ ENCODER_ENABLE = no # Enable Encoder
DIP_SWITCH_ENABLE = yes
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = CKLED2001
-EEPROM_DRIVER = i2c
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = embedded_flash
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/keychron/q2/rev_0111/rules.mk b/keyboards/keychron/q2/rev_0111/rules.mk
index a295f48e10..9332d29432 100644
--- a/keyboards/keychron/q2/rev_0111/rules.mk
+++ b/keyboards/keychron/q2/rev_0111/rules.mk
@@ -20,7 +20,8 @@ ENCODER_ENABLE = yes # Enable Encoder
DIP_SWITCH_ENABLE = yes
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = CKLED2001
-EEPROM_DRIVER = i2c
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = embedded_flash
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/keychron/q2/rev_0112/rules.mk b/keyboards/keychron/q2/rev_0112/rules.mk
index 30394028b3..38d48f0b27 100644
--- a/keyboards/keychron/q2/rev_0112/rules.mk
+++ b/keyboards/keychron/q2/rev_0112/rules.mk
@@ -20,7 +20,8 @@ ENCODER_ENABLE = no # Enable Encoder
DIP_SWITCH_ENABLE = yes
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = CKLED2001
-EEPROM_DRIVER = i2c
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = embedded_flash
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/keychron/q2/rev_0113/rules.mk b/keyboards/keychron/q2/rev_0113/rules.mk
index a295f48e10..9332d29432 100644
--- a/keyboards/keychron/q2/rev_0113/rules.mk
+++ b/keyboards/keychron/q2/rev_0113/rules.mk
@@ -20,7 +20,8 @@ ENCODER_ENABLE = yes # Enable Encoder
DIP_SWITCH_ENABLE = yes
RGB_MATRIX_ENABLE = yes
RGB_MATRIX_DRIVER = CKLED2001
-EEPROM_DRIVER = i2c
+EEPROM_DRIVER = wear_leveling
+WEAR_LEVELING_DRIVER = embedded_flash
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/keyhive/honeycomb/keymaps/default/keymap.c b/keyboards/keyhive/honeycomb/keymaps/default/keymap.c
index d0a5961873..429624822e 100755
--- a/keyboards/keyhive/honeycomb/keymaps/default/keymap.c
+++ b/keyboards/keyhive/honeycomb/keymaps/default/keymap.c
@@ -37,7 +37,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
report_mouse_t currentReport = {};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- //uint8_t layer = biton32(layer_state); // get the current layer
+ //uint8_t layer = get_highest_layer(layer_state); // get the current layer
// Basic example functions
switch (keycode) {
diff --git a/keyboards/keyhive/navi10/keymaps/default/keymap.c b/keyboards/keyhive/navi10/keymaps/default/keymap.c
index d1b3127760..c4295b1553 100644
--- a/keyboards/keyhive/navi10/keymaps/default/keymap.c
+++ b/keyboards/keyhive/navi10/keymaps/default/keymap.c
@@ -127,5 +127,5 @@ void tk_reset(qk_tap_dance_state_t *state, void *user_data){
//associate the tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
- [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, tk_finished, tk_reset, 275)
+ [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tk_finished, tk_reset)
};
diff --git a/keyboards/keyhive/navi10/keymaps/devdev/keymap.c b/keyboards/keyhive/navi10/keymaps/devdev/keymap.c
index b0d43ebc69..0fc20cbbd4 100644
--- a/keyboards/keyhive/navi10/keymaps/devdev/keymap.c
+++ b/keyboards/keyhive/navi10/keymaps/devdev/keymap.c
@@ -259,5 +259,5 @@ void tk_reset(qk_tap_dance_state_t *state, void *user_data){
//associate the tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
- [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, tk_finished, tk_reset, TAPPING_TERM)
+ [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tk_finished, tk_reset)
};
diff --git a/keyboards/keyhive/navi10/keymaps/emdarcher/keymap.c b/keyboards/keyhive/navi10/keymaps/emdarcher/keymap.c
index 40efed48d5..37850e28f3 100644
--- a/keyboards/keyhive/navi10/keymaps/emdarcher/keymap.c
+++ b/keyboards/keyhive/navi10/keymaps/emdarcher/keymap.c
@@ -178,5 +178,5 @@ void tk_reset(qk_tap_dance_state_t *state, void *user_data){
//associate the tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
- [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, tk_finished, tk_reset, 275)
+ [TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tk_finished, tk_reset)
};
diff --git a/keyboards/kinesis/keymaps/milestogo/keymap.c b/keyboards/kinesis/keymaps/milestogo/keymap.c
index 8c01bcb83d..72687195ef 100644
--- a/keyboards/kinesis/keymaps/milestogo/keymap.c
+++ b/keyboards/kinesis/keymaps/milestogo/keymap.c
@@ -330,7 +330,7 @@ void matrix_init_user(void) {
void matrix_scan_user(void) {
#ifdef ALVICSTEP_CONFIG_H
- int8_t layer = biton32(layer_state);
+ int8_t layer = get_highest_layer(layer_state);
switch (layer) {
case 1:
diff --git a/keyboards/kprepublic/bm40hsrgb/keymaps/gabustoledo/config.h b/keyboards/kprepublic/bm40hsrgb/keymaps/gabustoledo/config.h
index b38e4b8fc6..ba18295ead 100644
--- a/keyboards/kprepublic/bm40hsrgb/keymaps/gabustoledo/config.h
+++ b/keyboards/kprepublic/bm40hsrgb/keymaps/gabustoledo/config.h
@@ -60,10 +60,6 @@
#define RGBLIGHT_LIMIT_VAL 10
-//bootmagic
-#define BOOTMAGIC_KEY_SALT KC_V
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_Q
-
#ifdef RGB_MATRIX_ENABLE
# undef ENABLE_RGB_MATRIX_ALPHAS_MODS
diff --git a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt/config.h b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt/config.h
index 2b0d0961c4..a88ae7f2e8 100644
--- a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt/config.h
+++ b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt/config.h
@@ -25,10 +25,6 @@
//#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGBLIGHT_LIMIT_VAL 10
-//bootmagic
-#define BOOTMAGIC_KEY_SALT KC_V
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_Q
-
#ifdef RGB_MATRIX_ENABLE
#define TAPPING_TERM 200
diff --git a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_loud/config.h b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_loud/config.h
index d39f6b95c8..cdfa67acb0 100644
--- a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_loud/config.h
+++ b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_loud/config.h
@@ -25,10 +25,6 @@
//#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGBLIGHT_LIMIT_VAL 10
-//bootmagic
-#define BOOTMAGIC_KEY_SALT KC_V
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_Q
-
#ifdef RGB_MATRIX_ENABLE
#define TAPPING_TERM 200
diff --git a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_quiet/config.h b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_quiet/config.h
index a4634c581e..dbadc3da99 100644
--- a/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_quiet/config.h
+++ b/keyboards/kprepublic/bm40hsrgb/keymaps/signynt_2_quiet/config.h
@@ -25,10 +25,6 @@
//#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGBLIGHT_LIMIT_VAL 10
-//bootmagic
-#define BOOTMAGIC_KEY_SALT KC_V
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_Q
-
#ifdef RGB_MATRIX_ENABLE
#define TAPPING_TERM 200
diff --git a/keyboards/kprepublic/cospad/keymaps/detrus/keymap.c b/keyboards/kprepublic/cospad/keymaps/detrus/keymap.c
index af56305e5c..84324c6e0d 100644
--- a/keyboards/kprepublic/cospad/keymaps/detrus/keymap.c
+++ b/keyboards/kprepublic/cospad/keymaps/detrus/keymap.c
@@ -271,7 +271,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Makes sure to update the good tri-layer if a layer changes
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(default_layer_state)) {
+ switch (get_highest_layer(default_layer_state)) {
case _QWERTY_LAYER:
state = update_tri_layer_state(state, _RAISE_LAYER, _QWERTY_LOWER_LAYER, _ALTER_LAYER);
break;
@@ -289,8 +289,8 @@ layer_state_t layer_state_set_user(layer_state_t state) {
}
// Makes the tri-layer
-uint32_t default_layer_state_set_kb(uint32_t state) {
- switch (biton32(state)) {
+layer_state_t default_layer_state_set_kb(layer_state_t state) {
+ switch (get_highest_layer(state)) {
case _QWERTY_LAYER:
state = update_tri_layer_state(state, _RAISE_LAYER, _QWERTZ_LOWER_LAYER, _ALTER_LAYER);
state = update_tri_layer_state(state, _RAISE_LAYER, _COLEMA_LOWER_LAYER, _ALTER_LAYER);
diff --git a/keyboards/kprepublic/jj50/keymaps/abstractkb/keymap.c b/keyboards/kprepublic/jj50/keymaps/abstractkb/keymap.c
index e257649369..c096aaea10 100644
--- a/keyboards/kprepublic/jj50/keymaps/abstractkb/keymap.c
+++ b/keyboards/kprepublic/jj50/keymaps/abstractkb/keymap.c
@@ -42,7 +42,7 @@ void keyboard_post_init_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
rgblight_sethsv_noeeprom(170,255,255);
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
diff --git a/keyboards/kprepublic/jj50/keymaps/abstractkb_gergomatch/keymap.c b/keyboards/kprepublic/jj50/keymaps/abstractkb_gergomatch/keymap.c
index baedbb4dd2..af4c3c84bb 100644
--- a/keyboards/kprepublic/jj50/keymaps/abstractkb_gergomatch/keymap.c
+++ b/keyboards/kprepublic/jj50/keymaps/abstractkb_gergomatch/keymap.c
@@ -42,7 +42,7 @@ void keyboard_post_init_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _FUNC:
rgblight_sethsv_noeeprom(170,255,255);
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
diff --git a/keyboards/kprepublic/jj50/keymaps/archetype/config.h b/keyboards/kprepublic/jj50/keymaps/archetype/config.h
index a12e070b4f..17ce95a363 100644
--- a/keyboards/kprepublic/jj50/keymaps/archetype/config.h
+++ b/keyboards/kprepublic/jj50/keymaps/archetype/config.h
@@ -6,4 +6,4 @@
#define AUTO_SHIFT_TIMEOUT 150
#define NO_AUTO_SHIFT_ALPHA
#define TAPPING_TERM 150
-//#define BOOTMAGIC_KEY_SALT KC_LCTL
+#define TAPPING_TERM_PER_KEY
diff --git a/keyboards/kprepublic/jj50/keymaps/archetype/keymap.c b/keyboards/kprepublic/jj50/keymaps/archetype/keymap.c
index 82c615f135..ff59ef43e5 100644
--- a/keyboards/kprepublic/jj50/keymaps/archetype/keymap.c
+++ b/keyboards/kprepublic/jj50/keymaps/archetype/keymap.c
@@ -167,9 +167,18 @@ qk_tap_dance_action_t tap_dance_actions[] = {
// Single tap = ) | Double tap = ] | Triple tap = } | Single hold = KC_LALT
[TD_LALT_RBRC] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, right_brackets, right_brackets_reset),
// Layer Switcher ESC
- [TD_ESC_LAYER] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, layer_switcher, layer_switcher_reset, 100),
+ [TD_ESC_LAYER] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, layer_switcher, layer_switcher_reset),
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_ESC_LAYER):
+ return 100;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/ktec/ergodone/keymaps/eozaki/keymap.c b/keyboards/ktec/ergodone/keymaps/eozaki/keymap.c
index 09854ee89c..3910756f81 100644
--- a/keyboards/ktec/ergodone/keymaps/eozaki/keymap.c
+++ b/keyboards/ktec/ergodone/keymaps/eozaki/keymap.c
@@ -179,7 +179,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ktec/ergodone/keymaps/erovia/keymap.c b/keyboards/ktec/ergodone/keymaps/erovia/keymap.c
index 279c8a57c1..502c0dafe6 100644
--- a/keyboards/ktec/ergodone/keymaps/erovia/keymap.c
+++ b/keyboards/ktec/ergodone/keymaps/erovia/keymap.c
@@ -204,7 +204,7 @@ void matrix_init_user(void) {
layer_state_t layer_state_set_user(layer_state_t state) {
ergodox_led_all_off();
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case FN:
// Red led on Pro Micro for Fn layer
ergodox_board_led_on();
diff --git a/keyboards/ktec/ergodone/keymaps/kloki/keymap.c b/keyboards/ktec/ergodone/keymaps/kloki/keymap.c
index 87e96d20fd..1347f8f501 100644
--- a/keyboards/ktec/ergodone/keymaps/kloki/keymap.c
+++ b/keyboards/ktec/ergodone/keymaps/kloki/keymap.c
@@ -198,7 +198,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/ktec/ergodone/keymaps/vega/keymap.c b/keyboards/ktec/ergodone/keymaps/vega/keymap.c
index 6105cddf15..a0dddd5791 100644
--- a/keyboards/ktec/ergodone/keymaps/vega/keymap.c
+++ b/keyboards/ktec/ergodone/keymaps/vega/keymap.c
@@ -807,7 +807,7 @@ void matrix_init_user(void){
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/keyboards/leeku/finger65/keymaps/madhatter/keymap.c b/keyboards/leeku/finger65/keymaps/madhatter/keymap.c
index a69fe69153..f73b0371a1 100644
--- a/keyboards/leeku/finger65/keymaps/madhatter/keymap.c
+++ b/keyboards/leeku/finger65/keymaps/madhatter/keymap.c
@@ -40,7 +40,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
// layer_state_t layer_state_set_user(layer_state_t state) {
-// switch(biton32(state)) {
+// switch(get_highest_layer(state)) {
// case _FNMS:
// led_off();
// rgb_on();
diff --git a/keyboards/lets_split/keymaps/cpeters1982/keymap.c b/keyboards/lets_split/keymaps/cpeters1982/keymap.c
index c4c26d56bc..27cd9db8b4 100644
--- a/keyboards/lets_split/keymaps/cpeters1982/keymap.c
+++ b/keyboards/lets_split/keymaps/cpeters1982/keymap.c
@@ -183,7 +183,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE
uint8_t default_layer = eeconfig_read_default_layer();
if (rgb_layer_change) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
rgblight_set_orange;
rgblight_mode(5);
diff --git a/keyboards/lets_split/keymaps/geripgeri/keymap.c b/keyboards/lets_split/keymaps/geripgeri/keymap.c
index 62e3570468..eb22a1509e 100644
--- a/keyboards/lets_split/keymaps/geripgeri/keymap.c
+++ b/keyboards/lets_split/keymaps/geripgeri/keymap.c
@@ -255,7 +255,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
writePin(B0, !(state & (1UL << (_NUMPAD))));
- switch(biton32(state)) {
+ switch(get_highest_layer(state)) {
case _RAISE:
rgblight_setrgb_at(255, 255, 255, RGBLED_NUM / 2);
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
diff --git a/keyboards/lets_split/keymaps/pitty/keymap.c b/keyboards/lets_split/keymaps/pitty/keymap.c
index d723e0c026..8bc32a1eb7 100644
--- a/keyboards/lets_split/keymaps/pitty/keymap.c
+++ b/keyboards/lets_split/keymaps/pitty/keymap.c
@@ -128,7 +128,7 @@ void persistent_default_layer_set(uint16_t default_layer) {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _NAV:
if (RGB_INIT) {} else {
diff --git a/keyboards/lily58/lib/layer_state_reader.c b/keyboards/lily58/lib/layer_state_reader.c
index 0e9dd7039b..868d8e5cb4 100644
--- a/keyboards/lily58/lib/layer_state_reader.c
+++ b/keyboards/lily58/lib/layer_state_reader.c
@@ -28,7 +28,7 @@ const char *read_layer_state(void) {
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Adjust");
break;
default:
- snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Undef-%ld", layer_state);
+ snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Undef-%u", layer_state);
}
return layer_state_str;
diff --git a/keyboards/m10a/keymaps/gam3cat/keymap.c b/keyboards/m10a/keymaps/gam3cat/keymap.c
index f962246ef3..86231f8406 100644
--- a/keyboards/m10a/keymaps/gam3cat/keymap.c
+++ b/keyboards/m10a/keymaps/gam3cat/keymap.c
@@ -115,7 +115,7 @@ void matrix_scan_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _L0:
custom_backlight_level(0);
break;
diff --git a/keyboards/maple_computing/lets_split_eh/keymaps/romus/keymap.c b/keyboards/maple_computing/lets_split_eh/keymaps/romus/keymap.c
index ba5b75a5cf..398a324a0f 100644
--- a/keyboards/maple_computing/lets_split_eh/keymaps/romus/keymap.c
+++ b/keyboards/maple_computing/lets_split_eh/keymaps/romus/keymap.c
@@ -5,8 +5,8 @@
void matrix_init_keymap (void) {
}
-uint32_t layer_state_set_keymap(uint32_t state) {
-
+layer_state_t layer_state_set_keymap(layer_state_t state) {
+
return state;
}
diff --git a/keyboards/massdrop/alt/keymaps/pregame/rules.mk b/keyboards/massdrop/alt/keymaps/pregame/rules.mk
index 184405662a..5981633f7c 100644
--- a/keyboards/massdrop/alt/keymaps/pregame/rules.mk
+++ b/keyboards/massdrop/alt/keymaps/pregame/rules.mk
@@ -8,7 +8,6 @@ DYNAMIC_MACRO_ENABLE = no # Dynamic macro recording and play
MOUSEKEY_ENABLE = no # Enable mouse control keycodes. Increases firmware size.
TAP_DANCE_ENABLE = no # Enable tap dance keys
CONSOLE_ENABLE = no # Enable debugging console. Increases firmware size.
-TERMINAL_ENABLE = no
EXTRAKEY_ENABLE = yes # Audio control and System control
# RAW_ENABLE = yes # Raw HID has not yet been implemented for this keyboard
# COMBO_ENABLE # Key combo feature
diff --git a/keyboards/massdrop/ctrl/keymaps/endgame/rules.mk b/keyboards/massdrop/ctrl/keymaps/endgame/rules.mk
index 9502c242dd..c4fab8ad53 100644
--- a/keyboards/massdrop/ctrl/keymaps/endgame/rules.mk
+++ b/keyboards/massdrop/ctrl/keymaps/endgame/rules.mk
@@ -7,7 +7,6 @@ MOUSEKEY_ENABLE = yes # Enable mouse control keycodes. Increases firmware size
TAP_DANCE_ENABLE = yes # Enable tap dance keys
CONSOLE_ENABLE = yes # Enable debugging console. Increases firmware size.
SRC += config_led.c # Used to add files to the compilation/linking list.
-TERMINAL_ENABLE = yes
EXTRAKEY_ENABLE = yes # Audio control and System control
# RAW_ENABLE = yes # Raw HID has not yet been implemented for this keyboard
# COMBO_ENABLE # Key combo feature
diff --git a/keyboards/massdrop/ctrl/keymaps/matthewrobo/rules.mk b/keyboards/massdrop/ctrl/keymaps/matthewrobo/rules.mk
index e834404e29..4bb43f525b 100644
--- a/keyboards/massdrop/ctrl/keymaps/matthewrobo/rules.mk
+++ b/keyboards/massdrop/ctrl/keymaps/matthewrobo/rules.mk
@@ -7,7 +7,6 @@ MOUSEKEY_ENABLE = no # Enable mouse control keycodes. Increases firmware size.
TAP_DANCE_ENABLE = no # Enable tap dance keys
CONSOLE_ENABLE = no # Enable debugging console. Increases firmware size.
SRC += config_led.c # Used to add files to the compilation/linking list.
-TERMINAL_ENABLE = no
EXTRAKEY_ENABLE = yes # Audio control and System control
#RAW_ENABLE = yes #Raw HID has not yet been implemented for this keyboard
#COMBO_ENABLE #Key combo feature
diff --git a/keyboards/massdrop/ctrl/keymaps/xanimos/rules.mk b/keyboards/massdrop/ctrl/keymaps/xanimos/rules.mk
index 43a312ce4e..2913eff83b 100644
--- a/keyboards/massdrop/ctrl/keymaps/xanimos/rules.mk
+++ b/keyboards/massdrop/ctrl/keymaps/xanimos/rules.mk
@@ -8,7 +8,6 @@ TAP_DANCE_ENABLE = yes # Enable tap dance keys
CONSOLE_ENABLE = no # Enable debugging console. Increases firmware size.
SRC += config_led.c # Used to add files to the compilation/linking list.
EXTRAKEY_ENABLE = yes # Audio control and System control
-TERMINAL_ENABLE = no
# RAW_ENABLE = yes # Raw HID has not yet been implemented for this keyboard
# COMBO_ENABLE # Key combo feature
# LEADER_ENABLE # Enable leader key chording
diff --git a/keyboards/mechkeys/mechmini/v2/keymaps/wsturgiss/keymap.c b/keyboards/mechkeys/mechmini/v2/keymaps/wsturgiss/keymap.c
index 218936a19b..689a9ce36e 100644
--- a/keyboards/mechkeys/mechmini/v2/keymaps/wsturgiss/keymap.c
+++ b/keyboards/mechkeys/mechmini/v2/keymaps/wsturgiss/keymap.c
@@ -87,7 +87,7 @@ void matrix_scan_user(void) {
//change colors and rgb modes on layer change
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case raise:
rgblight_mode_noeeprom(1);
rgblight_setrgb(0xc7, 0x00, 0xf4);
@@ -103,4 +103,3 @@ layer_state_t layer_state_set_user(layer_state_t state) {
}
return state;
};
-
diff --git a/keyboards/mechllama/g35/keymaps/default/keymap.c b/keyboards/mechllama/g35/keymaps/default/keymap.c
index 4568f54f54..09d7afe171 100644
--- a/keyboards/mechllama/g35/keymaps/default/keymap.c
+++ b/keyboards/mechllama/g35/keymaps/default/keymap.c
@@ -67,7 +67,7 @@ const char* get_layer_name(uint8_t layer) {
}
bool oled_task_user(void) {
- oled_write_ln_P(get_layer_name(biton32(layer_state)), false);
+ oled_write_ln_P(get_layer_name(get_highest_layer(layer_state)), false);
return false;
}
#endif
diff --git a/keyboards/mechlovin/hannah910/hannah910.c b/keyboards/mechlovin/hannah910/hannah910.c
index 3237636be2..70c1a7b8e3 100644
--- a/keyboards/mechlovin/hannah910/hannah910.c
+++ b/keyboards/mechlovin/hannah910/hannah910.c
@@ -34,20 +34,20 @@ void led_set_kb(uint8_t usb_led) {
layer_state_t layer_state_set_user(layer_state_t state)
{
// if on layer 1, turn on D2 LED, otherwise off.
- if (biton32(state) == 1) {
+ if (get_highest_layer(state) == 1) {
writePinHigh(D2);
} else {
writePinLow(D2);
}
// if on layer 2, turn on D1 LED, otherwise off.
- if (biton32(state) == 2) {
+ if (get_highest_layer(state) == 2) {
writePinHigh(D1);
} else {
writePinLow(D1);
}
// if on layer 3, turn on D0 LED, otherwise off.
- if (biton32(state) == 3) {
+ if (get_highest_layer(state) == 3) {
writePinHigh(D0);
} else {
writePinLow(D0);
diff --git a/keyboards/mechlovin/hex4b/keymaps/nazzer/keymap.c b/keyboards/mechlovin/hex4b/keymaps/nazzer/keymap.c
index 437233be52..e0634d85dc 100644
--- a/keyboards/mechlovin/hex4b/keymaps/nazzer/keymap.c
+++ b/keyboards/mechlovin/hex4b/keymaps/nazzer/keymap.c
@@ -53,9 +53,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
bool led_update_user(led_t led_state) {
-
+
// Toggle CAPS_LOCK LED normally
-
+
# if LED_PIN_ON_STATE == 0
// invert the whole thing to avoid having to conditionally !led_state.x later
led_state.raw = ~led_state.raw;
@@ -69,30 +69,30 @@ bool led_update_user(led_t led_state) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
-
- uint8_t layer = biton32(state);
-
+
+ uint8_t layer = get_highest_layer(state);
+
#if defined(LED_NUM_LOCK_PIN) && defined(LED_SCROLL_LOCK_PIN)
switch (layer) {
case 0:
- writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE);
- writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
+ writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE);
+ writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
break;
case 1:
- writePin(LED_SCROLL_LOCK_PIN, LED_PIN_ON_STATE);
- writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
+ writePin(LED_SCROLL_LOCK_PIN, LED_PIN_ON_STATE);
+ writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
break;
case 2:
- writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE);
- writePin(LED_NUM_LOCK_PIN, LED_PIN_ON_STATE);
+ writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE);
+ writePin(LED_NUM_LOCK_PIN, LED_PIN_ON_STATE);
break;
case 3:
- writePin(LED_SCROLL_LOCK_PIN, LED_PIN_ON_STATE);
- writePin(LED_NUM_LOCK_PIN, LED_PIN_ON_STATE);
+ writePin(LED_SCROLL_LOCK_PIN, LED_PIN_ON_STATE);
+ writePin(LED_NUM_LOCK_PIN, LED_PIN_ON_STATE);
break;
}
#endif
- return state;
+ return state;
}
diff --git a/keyboards/minimacro5/keymaps/devdev/keymap.c b/keyboards/minimacro5/keymaps/devdev/keymap.c
index d7f998fa3a..3c203fcc37 100644
--- a/keyboards/minimacro5/keymaps/devdev/keymap.c
+++ b/keyboards/minimacro5/keymaps/devdev/keymap.c
@@ -37,7 +37,7 @@ enum tap_dances{
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) { /* First encoder*/
- switch(biton32(layer_state)){
+ switch(get_highest_layer(layer_state)){
case _MAIN:
if (clockwise) {
tap_code(KC_VOLU);
diff --git a/keyboards/mitosis/keymaps/carvac_dv/keymap.c b/keyboards/mitosis/keymaps/carvac_dv/keymap.c
index c67f2e387c..842556324f 100644
--- a/keyboards/mitosis/keymaps/carvac_dv/keymap.c
+++ b/keyboards/mitosis/keymaps/carvac_dv/keymap.c
@@ -105,7 +105,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _STD:
@@ -121,4 +121,3 @@ void matrix_scan_user(void) {
break;
}
};
-
diff --git a/keyboards/mitosis/keymaps/datagrok/keymap.c b/keyboards/mitosis/keymaps/datagrok/keymap.c
index 220c140af0..2611e1194c 100644
--- a/keyboards/mitosis/keymaps/datagrok/keymap.c
+++ b/keyboards/mitosis/keymaps/datagrok/keymap.c
@@ -102,7 +102,7 @@ const size_t defaultlayers_n = sizeof(defaultlayers) / sizeof(defaultlayers[0]);
// New keycode KC_LAYO rotates between available default layers (for e.g.,
// selecting a base layout). Shift+KC_LAYO makes the current one persistent.
bool process_record_layout(uint16_t keycode, keyrecord_t *record) {
- uint32_t default_layer;
+ uint8_t default_layer;
uint8_t i;
#if defined(AUDIO_ENABLE)
float saved_song[][2] = SONG(COIN_SOUND);
@@ -121,7 +121,7 @@ bool process_record_layout(uint16_t keycode, keyrecord_t *record) {
} else {
// rotate default layer.
// find the current default layer
- default_layer = biton32(default_layer_state);
+ default_layer = get_highest_layer(default_layer_state);
// find next valid default layer
for (i = 1; i < defaultlayers_n; i++) {
if (defaultlayers[(default_layer + i) % defaultlayers_n]) {
diff --git a/keyboards/mitosis/keymaps/default/keymap.c b/keyboards/mitosis/keymaps/default/keymap.c
index 6132ad6f78..27b2eb2525 100644
--- a/keyboards/mitosis/keymaps/default/keymap.c
+++ b/keyboards/mitosis/keymaps/default/keymap.c
@@ -77,7 +77,7 @@ static bool singular_key = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
uint8_t layer;
- layer = biton32(layer_state); // get the current layer
+ layer = get_highest_layer(layer_state); // get the current layer
//custom layer handling for tri_layer,
switch (keycode) {
@@ -174,7 +174,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _MALT:
@@ -193,4 +193,3 @@ void matrix_scan_user(void) {
break;
}
};
-
diff --git a/keyboards/mitosis/keymaps/mjt/keymap.c b/keyboards/mitosis/keymaps/mjt/keymap.c
index f00bf59556..0946e40b8e 100644
--- a/keyboards/mitosis/keymaps/mjt/keymap.c
+++ b/keyboards/mitosis/keymaps/mjt/keymap.c
@@ -181,7 +181,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
}
uint8_t layer;
- layer = biton32(layer_state); // get the current layer
+ layer = get_highest_layer(layer_state); // get the current layer
//custom layer handling for tri_layer,
switch (keycode) {
@@ -310,7 +310,7 @@ void music_scale_user(void)
#endif
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
diff --git a/keyboards/mitosis/keymaps/nzen/keymap.c b/keyboards/mitosis/keymaps/nzen/keymap.c
index d9fd3641bc..c981441bc9 100644
--- a/keyboards/mitosis/keymaps/nzen/keymap.c
+++ b/keyboards/mitosis/keymaps/nzen/keymap.c
@@ -175,7 +175,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
@@ -205,5 +205,3 @@ void matrix_scan_user(void) {
void matrix_init_user(void) {
set_unicode_input_mode(UC_LNX); // or UC_WINC
};
-
-
diff --git a/keyboards/mlego/m48/keymaps/default/keymap.c b/keyboards/mlego/m48/keymaps/default/keymap.c
index 5eb40a332a..175f42b9b9 100644
--- a/keyboards/mlego/m48/keymaps/default/keymap.c
+++ b/keyboards/mlego/m48/keymaps/default/keymap.c
@@ -106,10 +106,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_ADJ] = LAYOUT_ortho_4x12(
- _______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
- _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, _______, _______, _______, _______, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ _______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL,
+ _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, _______, _______, _______, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
diff --git a/keyboards/mschwingen/modelm/modelm.c b/keyboards/mschwingen/modelm/modelm.c
index 7dcd4ac024..0ff58f4be3 100644
--- a/keyboards/mschwingen/modelm/modelm.c
+++ b/keyboards/mschwingen/modelm/modelm.c
@@ -163,8 +163,8 @@ void update_layer_leds(void) {
static uint8_t old_layer = 255;
static uint8_t old_default_layer = 255;
- layer = biton32(layer_state);
- default_layer = biton32(default_layer_state);
+ layer = get_highest_layer(layer_state);
+ default_layer = get_highest_layer(default_layer_state);
if (isRecording && timer_elapsed(blink_cycle_timer) > 150) {
blink_state = !blink_state;
diff --git a/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c b/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c
index 78a17233e3..ddcd3f6642 100644
--- a/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c
+++ b/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c
@@ -95,9 +95,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
if (clockwise) {
- tap_code(dynamic_keymap_get_keycode(biton32(layer_state), 4, 3));
+ tap_code(dynamic_keymap_get_keycode(get_highest_layer(layer_state), 4, 3));
} else {
- tap_code(dynamic_keymap_get_keycode(biton32(layer_state), 4, 4));
+ tap_code(dynamic_keymap_get_keycode(get_highest_layer(layer_state), 4, 4));
}
}
return true;
diff --git a/keyboards/oddball/config.h b/keyboards/oddball/config.h
index cfb134c4e3..1aaead0cae 100644
--- a/keyboards/oddball/config.h
+++ b/keyboards/oddball/config.h
@@ -56,4 +56,4 @@
// #define BOOTMAGIC_LITE_COLUMN 0
#define ADNS9800_CS_PIN SPI_SS_PIN
-#define PMW3360_CS_PIN SPI_SS_PIN
+#define PMW33XX_CS_PIN SPI_SS_PIN
diff --git a/keyboards/pearl/keymaps/cijanzen/keymap.c b/keyboards/pearl/keymaps/cijanzen/keymap.c
index 896e157fd6..5a3f1eb1cd 100644
--- a/keyboards/pearl/keymaps/cijanzen/keymap.c
+++ b/keyboards/pearl/keymaps/cijanzen/keymap.c
@@ -46,7 +46,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/**
* Status LED layer indicators courtesy of jetpacktuxedo's firmware
*/
-uint32_t layer_state_set_kb(uint32_t state)
+layer_state_t layer_state_set_kb(layer_state_t state)
{
if (state & (1<<1)) { // if we are on layer 1
PORTD |= (1 << PD0); // light num lock led
diff --git a/keyboards/pearl/keymaps/jetpacktuxedo/keymap.c b/keyboards/pearl/keymaps/jetpacktuxedo/keymap.c
index 759c6fdc7d..4fd35f63ce 100644
--- a/keyboards/pearl/keymaps/jetpacktuxedo/keymap.c
+++ b/keyboards/pearl/keymaps/jetpacktuxedo/keymap.c
@@ -27,7 +27,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
};
-uint32_t layer_state_set_kb(uint32_t state) {
+layer_state_t layer_state_set_kb(layer_state_t state) {
// if we are on layer 1
if (state & (1<<1)){
// light num lock led
diff --git a/keyboards/pearl/keymaps/phil/keymap.c b/keyboards/pearl/keymaps/phil/keymap.c
index 56326d423f..492c4cb0c5 100755
--- a/keyboards/pearl/keymaps/phil/keymap.c
+++ b/keyboards/pearl/keymaps/phil/keymap.c
@@ -64,7 +64,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
};
-uint32_t layer_state_set_kb(uint32_t state) {
+layer_state_t layer_state_set_kb(layer_state_t state) {
if (state & (1<<QWERTY)){
PORTD &= ~(1 << PD0);
} else {
diff --git a/keyboards/pearl/keymaps/rask/keymap.c b/keyboards/pearl/keymaps/rask/keymap.c
index bafb2b9738..30c8b6344f 100644
--- a/keyboards/pearl/keymaps/rask/keymap.c
+++ b/keyboards/pearl/keymaps/rask/keymap.c
@@ -43,7 +43,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/**
* Status LED layer indicators courtesy of jetpacktuxedo's firmware
*/
-uint32_t layer_state_set_kb(uint32_t state)
+layer_state_t layer_state_set_kb(layer_state_t state)
{
// if we are on layer 1
if (state & (1<<1)){
diff --git a/keyboards/percent/canoe/keymaps/dhertz/keymap.c b/keyboards/percent/canoe/keymaps/dhertz/keymap.c
index 7e8170aefc..7d855e8fa7 100644
--- a/keyboards/percent/canoe/keymaps/dhertz/keymap.c
+++ b/keyboards/percent/canoe/keymaps/dhertz/keymap.c
@@ -49,8 +49,8 @@ void keyboard_post_init_user(void) {
rgblight_sethsv_teal();
}
-uint32_t layer_state_set_keymap(uint32_t state) {
- switch (biton32(state)) {
+layer_state_t layer_state_set_keymap(layer_state_t state) {
+ switch (get_highest_layer(state)) {
case 1:
rgblight_sethsv_noeeprom_magenta();
break;
diff --git a/keyboards/phoenix/phoenix.c b/keyboards/phoenix/phoenix.c
index a8e9a42a04..706a65b4de 100644
--- a/keyboards/phoenix/phoenix.c
+++ b/keyboards/phoenix/phoenix.c
@@ -74,7 +74,7 @@ void manipulate_led(uint32_t led, bool on) {
}
-layer_state_t layer_state_set_kb(uint32_t state) {
+layer_state_t layer_state_set_kb(layer_state_t state) {
state = layer_state_set_user(state);
uint8_t layer = get_highest_layer(state);
diff --git a/keyboards/planck/keymaps/ariccb/config.h b/keyboards/planck/keymaps/ariccb/config.h
index 322aa9277f..464a8cd5db 100644
--- a/keyboards/planck/keymaps/ariccb/config.h
+++ b/keyboards/planck/keymaps/ariccb/config.h
@@ -40,6 +40,7 @@
//#define MIDI_ADVANCED
#define TAPPING_TERM 150
+#define TAPPING_TERM_PER_KEY
#define IGNORE_MOD_TAP_INTERRUPT
// #define IGNORE_MOD_TAP_INTERRUPT
// #define HOLD_ON_OTHER_KEY_PRESS
diff --git a/keyboards/planck/keymaps/ariccb/keymap.c b/keyboards/planck/keymaps/ariccb/keymap.c
index c0b4e490fa..33d0a26273 100644
--- a/keyboards/planck/keymaps/ariccb/keymap.c
+++ b/keyboards/planck/keymaps/ariccb/keymap.c
@@ -379,9 +379,18 @@ void usl_reset(qk_tap_dance_state_t *state, void *user_data) {
// Associate our tap dance key with its functionality
qk_tap_dance_action_t tap_dance_actions[] = {
- [UNDS_LOWER] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, usl_finished, usl_reset, 175)
+ [UNDS_LOWER] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, usl_finished, usl_reset)
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(UNDS_LOWER):
+ return 175;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_select_word(keycode, record, SELWORD)) { return false; }
if (!process_caps_word(keycode, record)) { return false; }
@@ -661,4 +670,4 @@ void process_combo_event(uint16_t combo_index, bool pressed) {
}
break;
}
-} \ No newline at end of file
+}
diff --git a/keyboards/planck/keymaps/aviator/keymap.c b/keyboards/planck/keymaps/aviator/keymap.c
index 8fe66b3781..7ff410c767 100644
--- a/keyboards/planck/keymaps/aviator/keymap.c
+++ b/keyboards/planck/keymaps/aviator/keymap.c
@@ -142,7 +142,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
#ifdef BACKLIGHT_BREATHING
breathing_enable();
@@ -151,7 +151,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
#ifdef BACKLIGHT_BREATHING
breathing_self_disable();
@@ -164,7 +164,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
#ifdef BACKLIGHT_BREATHING
breathing_enable();
@@ -173,7 +173,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
- uint8_t default_layer = biton32(default_layer_state);
+ uint8_t default_layer = get_highest_layer(default_layer_state);
if (default_layer == _QWERTY) {
#ifdef BACKLIGHT_BREATHING
breathing_self_disable();
diff --git a/keyboards/planck/keymaps/charlesrocket/keymap.c b/keyboards/planck/keymaps/charlesrocket/keymap.c
index cec3f0186a..bfe61294af 100644
--- a/keyboards/planck/keymaps/charlesrocket/keymap.c
+++ b/keyboards/planck/keymaps/charlesrocket/keymap.c
@@ -101,7 +101,7 @@ void set_layer_color(int layer) {
void rgb_matrix_indicators_user(void) {
if (g_suspend_state || keyboard_config.disable_layer_led) { return; }
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case 0:
set_layer_color(0);
break;
diff --git a/keyboards/planck/keymaps/default/keymap.c b/keyboards/planck/keymaps/default/keymap.c
index 3453d41746..8041e0bada 100644
--- a/keyboards/planck/keymaps/default/keymap.c
+++ b/keyboards/planck/keymaps/default/keymap.c
@@ -165,7 +165,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = LAYOUT_planck_grid(
_______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
diff --git a/keyboards/planck/keymaps/grahampheath/keymap.c b/keyboards/planck/keymaps/grahampheath/keymap.c
index babe67c442..eb5401eabd 100644
--- a/keyboards/planck/keymaps/grahampheath/keymap.c
+++ b/keyboards/planck/keymaps/grahampheath/keymap.c
@@ -231,7 +231,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
bool has_layer_changed = true;
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
static uint8_t old_layer = 0;
if (old_layer != layer) {
diff --git a/keyboards/planck/keymaps/oryx/keymap.c b/keyboards/planck/keymaps/oryx/keymap.c
index 0368c98420..fae5a94713 100644
--- a/keyboards/planck/keymaps/oryx/keymap.c
+++ b/keyboards/planck/keymaps/oryx/keymap.c
@@ -94,7 +94,7 @@ void rgb_matrix_indicators_user(void) {
if (keyboard_config.disable_layer_led) {
return;
}
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case 1:
set_layer_color(0);
break;
diff --git a/keyboards/planck/keymaps/priyadi/config.h b/keyboards/planck/keymaps/priyadi/config.h
index c85e8656e6..d72b6d3908 100644
--- a/keyboards/planck/keymaps/priyadi/config.h
+++ b/keyboards/planck/keymaps/priyadi/config.h
@@ -5,12 +5,6 @@
#define PRIYADI_PLANCK
-/* bootmagic salt key */
-#define BOOTMAGIC_KEY_SALT KC_ESC
-
-/* skip bootmagic and eeconfig */
-#define BOOTMAGIC_KEY_SKIP KC_SPACE
-
#define UNICODE_TYPE_DELAY 0
#define LAYOUT_DVORAK
diff --git a/keyboards/planck/keymaps/roguepullrequest/rules.mk b/keyboards/planck/keymaps/roguepullrequest/rules.mk
index 9394c96e5b..5eb053e886 100644
--- a/keyboards/planck/keymaps/roguepullrequest/rules.mk
+++ b/keyboards/planck/keymaps/roguepullrequest/rules.mk
@@ -1,4 +1,3 @@
AUDIO_ENABLE = yes
COMMAND_ENABLE = no
-TERMINAL_ENABLE = no
TAP_DANCE_ENABLE = yes
diff --git a/keyboards/planck/keymaps/rootiest/config.h b/keyboards/planck/keymaps/rootiest/config.h
index fc1fc81761..5bb5a73a29 100644
--- a/keyboards/planck/keymaps/rootiest/config.h
+++ b/keyboards/planck/keymaps/rootiest/config.h
@@ -87,6 +87,7 @@
/*
* TAP-DANCE options
*/
+#define TAPPING_TERM_PER_KEY // Control Tap-Dance time individually by key
#define TAPPING_TERM 250 // Default time allowed before resetting a Tap-Dance combo
#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */
#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */
diff --git a/keyboards/planck/keymaps/rootiest/keymap.c b/keyboards/planck/keymaps/rootiest/keymap.c
index 634bf2829e..c289c50e5b 100644
--- a/keyboards/planck/keymaps/rootiest/keymap.c
+++ b/keyboards/planck/keymaps/rootiest/keymap.c
@@ -502,7 +502,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
} else {
if (index == 0) { /* First encoder */
uint16_t held_keycode_timer = timer_read();
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case 0: // Base Layer
if ((get_mods() & MOD_MASK_GUI)) { // GUI-ed
if (clockwise) {
@@ -1656,13 +1656,26 @@ void sml_reset(qk_tap_dance_state_t* state, void* user_data) { sml_state.state =
// Tap Dance definitions
qk_tap_dance_action_t tap_dance_actions[] = {
// Tap once for °, twice for ℉, thrice for ℃
- [TD_DEG_DEGF] = ACTION_TAP_DANCE_FN(send_degree_symbol), //
- [TD_LSHFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, scap_finished, scap_reset, 200), //
- [TD_LCTL_STICKY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, slctl_finished, slctl_reset, 200), //
- [TD_LALT_STICKY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, slalt_finished, slalt_reset, 200), //
- [TD_SMILEY] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, sml_finished, sml_reset, 500),
+ [TD_DEG_DEGF] = ACTION_TAP_DANCE_FN(send_degree_symbol), //
+ [TD_LSHFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, scap_finished, scap_reset), //
+ [TD_LCTL_STICKY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, slctl_finished, slctl_reset), //
+ [TD_LALT_STICKY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, slalt_finished, slalt_reset), //
+ [TD_SMILEY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, sml_finished, sml_reset),
};
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_LSHFT_CAPS):
+ case TD(TD_LCTL_STICKY):
+ case TD(TD_LALT_STICKY):
+ return 200;
+ case TD(TD_SMILEY):
+ return 500;
+ default:
+ return TAPPING_TERM;
+ }
+}
+
// Dip-Switch controls
void dip_switch_update_user(uint8_t index, bool active) {
switch (index) {
diff --git a/keyboards/planck/keymaps/rootiest/rules.mk b/keyboards/planck/keymaps/rootiest/rules.mk
index b669d8bb7d..ca0f90b6e9 100644
--- a/keyboards/planck/keymaps/rootiest/rules.mk
+++ b/keyboards/planck/keymaps/rootiest/rules.mk
@@ -20,8 +20,5 @@ KEY_LOCK_ENABLE = yes # Enables using lock key to maintain holds
# SWAP_HANDS_ENABLE = yes # Enables the swap hands function
# DEBOUNCE_TYPE = sym_eager_pk # Change debounce algorithm
-# NOTE: The following requires a lot of memory to include
-TERMINAL_ENABLE = yes # Enables a command-line-like interface designed to communicate through a text editor with keystrokes
-
# NOTE: The following is not yet available in main qmk branch
KEY_OVERRIDE_ENABLE = yes # Allows overiding modifier combos (change Shift+1 without affecting 1 or Shift's normal operation)
diff --git a/keyboards/planck/keymaps/synth_sample/keymap.c b/keyboards/planck/keymaps/synth_sample/keymap.c
index 0a57b7ce9a..124c01cb05 100644
--- a/keyboards/planck/keymaps/synth_sample/keymap.c
+++ b/keyboards/planck/keymaps/synth_sample/keymap.c
@@ -160,10 +160,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = LAYOUT_planck_grid(
- _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
- _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
+ _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c
index d413d63896..a5c5491ebd 100644
--- a/keyboards/planck/keymaps/synth_wavetable/keymap.c
+++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c
@@ -160,10 +160,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = LAYOUT_planck_grid(
- _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
- _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
+ _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
diff --git a/keyboards/planck/keymaps/tom/keymap.c b/keyboards/planck/keymaps/tom/keymap.c
index 66beaf33b7..d888fb7b05 100644
--- a/keyboards/planck/keymaps/tom/keymap.c
+++ b/keyboards/planck/keymaps/tom/keymap.c
@@ -228,7 +228,7 @@ bool music_mask_user(uint16_t keycode) {
void rgb_matrix_indicators_user(void) {
#ifdef RGB_MATRIX_ENABLE
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _RAISE:
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_MODIFIER)) {
diff --git a/keyboards/planck/keymaps/tylerwince/keymap.c b/keyboards/planck/keymaps/tylerwince/keymap.c
index 5cbc47b2fb..b4c0f9af52 100644
--- a/keyboards/planck/keymaps/tylerwince/keymap.c
+++ b/keyboards/planck/keymaps/tylerwince/keymap.c
@@ -168,7 +168,7 @@ void set_layer_color(int layer) {
void rgb_matrix_indicators_user(void) {
if (g_suspend_state || disable_layer_color) { return; }
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case 0:
set_layer_color(0);
break;
@@ -276,7 +276,7 @@ bool music_mask_user(uint16_t keycode) {
layer_state_t layer_state_set_user(layer_state_t state) {
palClearPad(GPIOB, 8);
palClearPad(GPIOB, 9);
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
switch (layer) {
case _LOWER:
palSetPad(GPIOB, 9);
diff --git a/keyboards/planck/rev6_drop/matrix.c b/keyboards/planck/rev6_drop/matrix.c
index 49e115d029..d10d94dcf8 100644
--- a/keyboards/planck/rev6_drop/matrix.c
+++ b/keyboards/planck/rev6_drop/matrix.c
@@ -15,14 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include "hal.h"
-#include "timer.h"
-#include "wait.h"
-#include "debug.h"
-#include "matrix.h"
+#include "quantum.h"
/*
* col: { B11, B10, B2, B1, A7, B0 }
@@ -38,9 +31,13 @@ __attribute__((weak)) void matrix_init_user(void) {}
__attribute__((weak)) void matrix_scan_user(void) {}
-__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
+__attribute__((weak)) void matrix_init_kb(void) {
+ matrix_init_user();
+}
-__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
+__attribute__((weak)) void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
void matrix_init(void) {
dprintf("matrix init\n");
@@ -146,9 +143,13 @@ uint8_t matrix_scan(void) {
return 1;
}
-bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & (1 << col)); }
+bool matrix_is_on(uint8_t row, uint8_t col) {
+ return (matrix[row] & (1 << col));
+}
-matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
+matrix_row_t matrix_get_row(uint8_t row) {
+ return matrix[row];
+}
void matrix_print(void) {
dprintf("\nr/c 01234567\n");
diff --git a/keyboards/ploopyco/mouse/config.h b/keyboards/ploopyco/mouse/config.h
index 98fc81bb05..a3e4b76893 100644
--- a/keyboards/ploopyco/mouse/config.h
+++ b/keyboards/ploopyco/mouse/config.h
@@ -77,5 +77,5 @@
// #define DEBUG_LED_PIN F7
-/* PMW3360 Settings */
-#define PMW3360_CS_PIN B0
+/* PMW33XX Settings */
+#define PMW33XX_CS_PIN B0
diff --git a/keyboards/ploopyco/mouse/keymaps/drashna/config.h b/keyboards/ploopyco/mouse/keymaps/drashna/config.h
index 9aa9a40769..1dc1b7695f 100644
--- a/keyboards/ploopyco/mouse/keymaps/drashna/config.h
+++ b/keyboards/ploopyco/mouse/keymaps/drashna/config.h
@@ -28,4 +28,4 @@
#define RGBLIGHT_EFFECT_TWINKLE
#define RGBLIGHT_SLEEP
-#define MOUSE_EXT_REPORT
+#define MOUSE_EXTENDED_REPORT
diff --git a/keyboards/ploopyco/trackball/config.h b/keyboards/ploopyco/trackball/config.h
index dd068e4838..5c151c2e73 100644
--- a/keyboards/ploopyco/trackball/config.h
+++ b/keyboards/ploopyco/trackball/config.h
@@ -53,6 +53,6 @@
// If board has a debug LED, you can enable it by defining this
// #define DEBUG_LED_PIN F7
-/* PMW3360 Settings */
-#define PMW3360_CS_PIN B0
+/* PMW33XX Settings */
+#define PMW33XX_CS_PIN B0
#define POINTING_DEVICE_INVERT_Y
diff --git a/keyboards/preonic/keymaps/default/keymap.c b/keyboards/preonic/keymaps/default/keymap.c
index ef7614393d..c1faf464d6 100644
--- a/keyboards/preonic/keymaps/default/keymap.c
+++ b/keyboards/preonic/keymaps/default/keymap.c
@@ -157,7 +157,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = LAYOUT_preonic_grid(
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
- _______, QK_BOOT, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL,
+ _______, QK_BOOT, DEBUG, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL,
_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
diff --git a/keyboards/preonic/keymaps/dudeofawesome/keymap.c b/keyboards/preonic/keymaps/dudeofawesome/keymap.c
index 2d2a252b23..812bf35a20 100644
--- a/keyboards/preonic/keymaps/dudeofawesome/keymap.c
+++ b/keyboards/preonic/keymaps/dudeofawesome/keymap.c
@@ -275,7 +275,7 @@ bool numpadActive = false;
float tone_numpad_on[][2] = SONG(NUMPAD_ON_SOUND);
void matrix_scan_user (void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _NUMPAD:
diff --git a/keyboards/preonic/keymaps/senseored/keymap.c b/keyboards/preonic/keymaps/senseored/keymap.c
index e152507835..0f896700e6 100644
--- a/keyboards/preonic/keymaps/senseored/keymap.c
+++ b/keyboards/preonic/keymaps/senseored/keymap.c
@@ -367,7 +367,7 @@ bool dip_switch_update_user(uint8_t index, bool active) {
layer_state_t layer_state_set_user(layer_state_t state) {
// if(rgblight_get_mode() == 1) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _QWERTY:
if(bnumlock) {
tap_code(KC_NLCK);
diff --git a/keyboards/preonic/rev3_drop/matrix.c b/keyboards/preonic/rev3_drop/matrix.c
index 07171a39e9..82214e03d9 100644
--- a/keyboards/preonic/rev3_drop/matrix.c
+++ b/keyboards/preonic/rev3_drop/matrix.c
@@ -15,14 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include "hal.h"
-#include "timer.h"
-#include "wait.h"
-#include "debug.h"
-#include "matrix.h"
+#include "quantum.h"
typedef uint16_t matrix_col_t;
@@ -40,9 +33,13 @@ __attribute__((weak)) void matrix_init_user(void) {}
__attribute__((weak)) void matrix_scan_user(void) {}
-__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
+__attribute__((weak)) void matrix_init_kb(void) {
+ matrix_init_user();
+}
-__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
+__attribute__((weak)) void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
void matrix_init(void) {
dprintf("matrix init\n");
@@ -150,9 +147,13 @@ uint8_t matrix_scan(void) {
return 1;
}
-bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & (1 << col)); }
+bool matrix_is_on(uint8_t row, uint8_t col) {
+ return (matrix[row] & (1 << col));
+}
-matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
+matrix_row_t matrix_get_row(uint8_t row) {
+ return matrix[row];
+}
void matrix_print(void) {
dprintf("\nr/c 01234567\n");
diff --git a/keyboards/primekb/prime_e/keymaps/via/keymap.c b/keyboards/primekb/prime_e/keymaps/via/keymap.c
index 195f845cc2..2d1d003d51 100644
--- a/keyboards/primekb/prime_e/keymaps/via/keymap.c
+++ b/keyboards/primekb/prime_e/keymaps/via/keymap.c
@@ -108,7 +108,7 @@ void led_set_user(uint8_t usb_led) {
//function for layer indicator LED
layer_state_t layer_state_set_user(layer_state_t state)
{
- if (biton32(state) == 1) {
+ if (get_highest_layer(state) == 1) {
writePinHigh(B3);
} else {
writePinLow(B3);
diff --git a/keyboards/redox_w/keymaps/italian/keymap.c b/keyboards/redox_w/keymaps/italian/keymap.c
index e67742c6a1..b4c815e4f5 100644
--- a/keyboards/redox_w/keymaps/italian/keymap.c
+++ b/keyboards/redox_w/keymaps/italian/keymap.c
@@ -53,7 +53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
//├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┠┌────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B ,KC_ADPU ,KC_PGDN , KC_HOME ,KC_ADEN ,KC_N ,KC_M ,KC_COMM ,KC_DOT ,IT_UGRV ,IT_SHSL ,
//├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┤ ├────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤
- GUI_LESS,KC_PPLS ,KC_PMNS ,KC_ALAS , KC_CTPL , KC_BSPC ,KC_DEL , KC_ENT ,KC_SPC , ALT_IACC, KC_LEFT ,KC_DOWN ,KC_UP ,KC_RGHT
+ GUI_LESS,KC_PPLS ,KC_PMNS ,KC_ALAS , KC_CTPL , KC_BSPC ,KC_DEL , KC_ENT ,KC_SPC , ALT_IACC, KC_LEFT ,KC_DOWN ,KC_UP ,KC_RGHT
//└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘
),
@@ -67,7 +67,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
//├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┠┌────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
_______ ,IT_PERC ,IT_CIRC ,IT_LPRN ,IT_RPRN ,IT_TILD ,_______ ,_______ , _______ ,_______ ,XXXXXXX ,KC_KP_1 ,KC_KP_2 ,KC_KP_3 ,XXXXXXX ,XXXXXXX ,
//├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┤ ├────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤
- _______ ,_______ ,_______ ,_______ , _______ , _______ ,_______ , _______ ,_______ , KC_KP_0 , KC_KP_0 ,KC_PDOT ,XXXXXXX ,XXXXXXX
+ _______ ,_______ ,_______ ,_______ , _______ , _______ ,_______ , _______ ,_______ , KC_KP_0 , KC_KP_0 ,KC_PDOT ,XXXXXXX ,XXXXXXX
//└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘
),
@@ -81,7 +81,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
//├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┠┌────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,_______ ,_______ , _______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
//├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┤ ├────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤
- XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , KC_BTN1 , KC_BTN2 ,_______ , _______ ,_______ , XXXXXXX , XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
+ XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , KC_BTN1 , KC_BTN2 ,_______ , _______ ,_______ , XXXXXXX , XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
//└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘
),
@@ -95,14 +95,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
//├────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┠┌────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,_______ ,XXXXXXX , XXXXXXX ,_______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
//├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┤ ├────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤
- XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , XXXXXXX , XXXXXXX ,XXXXXXX , XXXXXXX ,XXXXXXX , XXXXXXX , XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
+ XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , XXXXXXX , XXXXXXX ,XXXXXXX , XXXXXXX ,XXXXXXX , XXXXXXX , XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
//└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘
)
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case _QWERTY:
@@ -121,5 +121,3 @@ void matrix_scan_user(void) {
break;
}
};
-
-
diff --git a/keyboards/redscarf_i/redscarf_i.c b/keyboards/redscarf_i/redscarf_i.c
index a8a685b13b..039e20664d 100644
--- a/keyboards/redscarf_i/redscarf_i.c
+++ b/keyboards/redscarf_i/redscarf_i.c
@@ -36,7 +36,7 @@ bool led_update_kb(led_t led_state) {
}
layer_state_t layer_state_set_kb(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case 1:
writePinHigh(F6);
writePinLow(F5);
diff --git a/keyboards/rgbkb/pan/keymaps/default/keymap.c b/keyboards/rgbkb/pan/keymaps/default/keymap.c
index dbc127616a..dcafeec765 100644
--- a/keyboards/rgbkb/pan/keymaps/default/keymap.c
+++ b/keyboards/rgbkb/pan/keymaps/default/keymap.c
@@ -75,7 +75,7 @@ bool oled_task_user(void) {
// Host Keyboard Layer Status
oled_write_P(PSTR("RGBKB Pan\n"), false);
oled_write_P(PSTR("Layer: "), false);
- uint8_t layer = layer_state ? biton(layer_state) : biton32(default_layer_state);
+ uint8_t layer = get_highest_layer(layer_state|default_layer_state);
switch (layer) {
case _QWERTY:
oled_write_P(PSTR("Default\n"), false);
diff --git a/keyboards/rgbkb/sol/keymaps/default/keymap.c b/keyboards/rgbkb/sol/keymaps/default/keymap.c
index c82259f5ee..1ce18bc1ab 100644
--- a/keyboards/rgbkb/sol/keymaps/default/keymap.c
+++ b/keyboards/rgbkb/sol/keymaps/default/keymap.c
@@ -233,7 +233,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
} else
#endif
{
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
uint16_t keycode = pgm_read_word(&encoders[layer][index][clockwise]);
while (keycode == KC_TRANSPARENT && layer > 0)
{
@@ -325,7 +325,7 @@ static void render_status(void) {
// Define layers here
oled_write_P(PSTR("Layer"), false);
- uint8_t layer = layer_state ? biton(layer_state) : biton32(default_layer_state);
+ uint8_t layer = get_highest_layer(layer_state|default_layer_state);
switch (layer) {
case _QWERTY:
oled_write_P(PSTR("BASE "), false);
diff --git a/keyboards/rgbkb/sol/keymaps/xyverz/keymap.c b/keyboards/rgbkb/sol/keymaps/xyverz/keymap.c
index bdcfbb1b93..bc0884c8e4 100644
--- a/keyboards/rgbkb/sol/keymaps/xyverz/keymap.c
+++ b/keyboards/rgbkb/sol/keymaps/xyverz/keymap.c
@@ -263,7 +263,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
} else
#endif
{
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
uint16_t keycode = encoders[layer][index][clockwise];
while (keycode == KC_TRANSPARENT && layer > 0)
{
@@ -306,7 +306,7 @@ static void render_status(void) {
// Define layers here
oled_write_P(PSTR(" Layer-----"), false);
- uint8_t layer = layer_state ? biton(layer_state) : biton32(default_layer_state);
+ uint8_t layer = layer_state ? get_highest_layer(layer_state) : get_highest_layer(default_layer_state);
switch (layer) {
case _DVORAK:
oled_write_P(PSTR("DVRAK"), false);
diff --git a/keyboards/rgbkb/zen/rev2/rev2.c b/keyboards/rgbkb/zen/rev2/rev2.c
index 5461890272..70e5531673 100644
--- a/keyboards/rgbkb/zen/rev2/rev2.c
+++ b/keyboards/rgbkb/zen/rev2/rev2.c
@@ -37,7 +37,7 @@ void render_status(void) {
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
oled_set_cursor(0, 3); // Line 3
oled_write_P(PSTR("Layer"), false); // Line 4
- oled_write_P(layer_name_user(biton32(layer_state)), false);
+ oled_write_P(layer_name_user(get_highest_layer(layer_state)), false);
// Host Keyboard LED Status
uint8_t led_usb_state = host_keyboard_leds();
diff --git a/keyboards/rgbkb/zygomorph/keymaps/default_oled/keymap.c b/keyboards/rgbkb/zygomorph/keymaps/default_oled/keymap.c
index 48bd1a33f7..f4d5c82a71 100644
--- a/keyboards/rgbkb/zygomorph/keymaps/default_oled/keymap.c
+++ b/keyboards/rgbkb/zygomorph/keymaps/default_oled/keymap.c
@@ -198,7 +198,7 @@ static void render_status(void) {
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _QWERTY:
oled_write_ln_P(PSTR("QWERTY"), false);
break;
diff --git a/keyboards/rocketboard_16/keymaps/default/keymap.c b/keyboards/rocketboard_16/keymaps/default/keymap.c
index ce26a834d0..dc83cbd62b 100644
--- a/keyboards/rocketboard_16/keymaps/default/keymap.c
+++ b/keyboards/rocketboard_16/keymaps/default/keymap.c
@@ -107,10 +107,10 @@ static void oled_write_ln_centered(const char * data, bool inverted)
char line_buf[21];
// Amount to offset string from left side
- uint8_t offset = (21 - strlen(data))/2;
+ uint8_t offset = (22 - strlen(data)) / 2;
// Formatted string centering... look, it works, don't ask how...
- snprintf(line_buf, 21, "%*s%s%*s\0", offset, "", data, offset, ""); // Centers data within 21 character buffer with null termination
+ snprintf(line_buf, 21, "%*s%s%*s", offset, "", data, offset, ""); // Centers data within 21 character buffer
oled_write_ln(line_buf, inverted);
}
diff --git a/keyboards/rocketboard_16/keymaps/via/keymap.c b/keyboards/rocketboard_16/keymaps/via/keymap.c
index ce26a834d0..08b8e65b4f 100644
--- a/keyboards/rocketboard_16/keymaps/via/keymap.c
+++ b/keyboards/rocketboard_16/keymaps/via/keymap.c
@@ -107,10 +107,10 @@ static void oled_write_ln_centered(const char * data, bool inverted)
char line_buf[21];
// Amount to offset string from left side
- uint8_t offset = (21 - strlen(data))/2;
+ uint8_t offset = (22 - strlen(data))/2;
// Formatted string centering... look, it works, don't ask how...
- snprintf(line_buf, 21, "%*s%s%*s\0", offset, "", data, offset, ""); // Centers data within 21 character buffer with null termination
+ snprintf(line_buf, 21, "%*s%s%*s", offset, "", data, offset, ""); // Centers data within 21 character buffer
oled_write_ln(line_buf, inverted);
}
diff --git a/keyboards/salicylic_acid3/7skb/keymaps/salicylic/keymap.c b/keyboards/salicylic_acid3/7skb/keymaps/salicylic/keymap.c
index 4e1f2acd05..7221f8c612 100644
--- a/keyboards/salicylic_acid3/7skb/keymaps/salicylic/keymap.c
+++ b/keyboards/salicylic_acid3/7skb/keymaps/salicylic/keymap.c
@@ -32,8 +32,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/7splus/keymaps/salicylic/keymap.c b/keyboards/salicylic_acid3/7splus/keymaps/salicylic/keymap.c
index 06d7972a2e..bea5978c50 100644
--- a/keyboards/salicylic_acid3/7splus/keymaps/salicylic/keymap.c
+++ b/keyboards/salicylic_acid3/7splus/keymaps/salicylic/keymap.c
@@ -39,8 +39,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESMS] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _MOUSE),
- [TD_ESAR] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _MOUSE),
+ [TD_ESAR] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/jisplit89/keymaps/salicylic/keymap.c b/keyboards/salicylic_acid3/jisplit89/keymaps/salicylic/keymap.c
index 4e8addf6b7..eba01d4d65 100644
--- a/keyboards/salicylic_acid3/jisplit89/keymaps/salicylic/keymap.c
+++ b/keyboards/salicylic_acid3/jisplit89/keymaps/salicylic/keymap.c
@@ -39,8 +39,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESMS] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _MOUSE),
- [TD_ESAR] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _MOUSE),
+ [TD_ESAR] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/naked60/keymaps/salicylic/keymap.c b/keyboards/salicylic_acid3/naked60/keymaps/salicylic/keymap.c
index 8a2dbf051f..b70e68da54 100644
--- a/keyboards/salicylic_acid3/naked60/keymaps/salicylic/keymap.c
+++ b/keyboards/salicylic_acid3/naked60/keymaps/salicylic/keymap.c
@@ -23,8 +23,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_nafuda/keymap.c b/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_nafuda/keymap.c
index 4201d79a2e..c43803be35 100644
--- a/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_nafuda/keymap.c
+++ b/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_nafuda/keymap.c
@@ -34,8 +34,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_setta21/keymap.c b/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_setta21/keymap.c
index 23786da915..6dd2ef8863 100644
--- a/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_setta21/keymap.c
+++ b/keyboards/salicylic_acid3/naked60/keymaps/salicylic_with_setta21/keymap.c
@@ -32,8 +32,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/naked64/keymaps/salicylic/keymap.c b/keyboards/salicylic_acid3/naked64/keymaps/salicylic/keymap.c
index db46075c8f..ae7843341a 100644
--- a/keyboards/salicylic_acid3/naked64/keymaps/salicylic/keymap.c
+++ b/keyboards/salicylic_acid3/naked64/keymaps/salicylic/keymap.c
@@ -33,8 +33,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/salicylic_acid3/naked64/keymaps/salicylic_with_setta21/keymap.c b/keyboards/salicylic_acid3/naked64/keymaps/salicylic_with_setta21/keymap.c
index c91716cdd4..6e2dd0886f 100644
--- a/keyboards/salicylic_acid3/naked64/keymaps/salicylic_with_setta21/keymap.c
+++ b/keyboards/salicylic_acid3/naked64/keymaps/salicylic_with_setta21/keymap.c
@@ -38,8 +38,8 @@ enum tapdances{
};
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _FLOCK),
- [TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _QWERTY),
+ [TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
+ [TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
#define LOWER MO(_LOWER)
diff --git a/keyboards/satt/comet46/keymaps/default-rgbled/keymap.c b/keyboards/satt/comet46/keymaps/default-rgbled/keymap.c
index 6c88b70bfe..1e96bd7fbc 100644
--- a/keyboards/satt/comet46/keymaps/default-rgbled/keymap.c
+++ b/keyboards/satt/comet46/keymaps/default-rgbled/keymap.c
@@ -173,7 +173,7 @@ void matrix_init_user(void) {
}
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
uint8_t default_layer = biton32(eeconfig_read_default_layer());
switch (layer) {
case _LOWER:
diff --git a/keyboards/satt/comet46/keymaps/default/keymap.c b/keyboards/satt/comet46/keymaps/default/keymap.c
index cf2c911d4c..bccca0a091 100644
--- a/keyboards/satt/comet46/keymaps/default/keymap.c
+++ b/keyboards/satt/comet46/keymaps/default/keymap.c
@@ -176,8 +176,8 @@ void render_status(struct CharacterMatrix *matrix) {
// Layer state
char layer_str[22];
matrix_write(matrix, "Layer: ");
- uint8_t layer = biton32(layer_state);
- uint8_t default_layer = biton32(eeconfig_read_default_layer());
+ uint8_t layer = get_highest_layer(layer_state);
+ uint8_t default_layer = get_highest_layer(eeconfig_read_default_layer());
switch (layer) {
case _QWERTY:
switch (default_layer) {
diff --git a/keyboards/satt/comet46/keymaps/satt/keymap.c b/keyboards/satt/comet46/keymaps/satt/keymap.c
index cdd094f747..54d1d791d7 100644
--- a/keyboards/satt/comet46/keymaps/satt/keymap.c
+++ b/keyboards/satt/comet46/keymaps/satt/keymap.c
@@ -165,7 +165,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _PSEUDO_US_LOWER:
case _PSEUDO_US_RAISE:
return update_tri_layer_state(state, _PSEUDO_US_RAISE, _PSEUDO_US_LOWER, _ADJUST);
@@ -204,7 +204,7 @@ void render_status(struct CharacterMatrix *matrix) {
// Layer state
char layer_str[22];
matrix_write(matrix, "Layer: ");
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
uint8_t default_layer = biton32(eeconfig_read_default_layer());
switch (layer) {
case _QWERTY:
diff --git a/keyboards/splitkb/kyria/keymaps/j-inc/keymap.c b/keyboards/splitkb/kyria/keymaps/j-inc/keymap.c
index af583a607f..f193c6e00c 100644
--- a/keyboards/splitkb/kyria/keymaps/j-inc/keymap.c
+++ b/keyboards/splitkb/kyria/keymaps/j-inc/keymap.c
@@ -341,7 +341,7 @@ bool oled_task_user(void) {
#ifdef ENCODER_ENABLE
bool encoder_update_user(uint8_t index, bool clockwise) {
- switch(biton32(layer_state)){
+ switch(get_highest_layer(layer_state)){
case 1:
if (clockwise) {
tap_code16(C(KC_TAB));
diff --git a/keyboards/splitkb/kyria/keymaps/j-inc/rules.mk b/keyboards/splitkb/kyria/keymaps/j-inc/rules.mk
index 000c995025..ee07f52ff1 100644
--- a/keyboards/splitkb/kyria/keymaps/j-inc/rules.mk
+++ b/keyboards/splitkb/kyria/keymaps/j-inc/rules.mk
@@ -9,7 +9,6 @@ MOUSEKEY_ENABLE = no
TAP_DANCE_ENABLE = no
STENO_ENABLE = no
BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
-TERMINAL_ENABLE = no
GRAVE_ESC_ENABLE = no
MAGIC_ENABLE = no
SPACE_CADET_ENABLE = no
diff --git a/keyboards/splitkb/kyria/keymaps/ninjonas/oled.c b/keyboards/splitkb/kyria/keymaps/ninjonas/oled.c
index 813328aa0c..d0f2a1b6cd 100644
--- a/keyboards/splitkb/kyria/keymaps/ninjonas/oled.c
+++ b/keyboards/splitkb/kyria/keymaps/ninjonas/oled.c
@@ -111,7 +111,7 @@ void oled_slash_separator(void){
void render_layout_state(void) {
oled_write_P(PSTR("Layout: "), false);
- switch (biton32(default_layer_state)) {
+ switch (get_highest_layer(default_layer_state)) {
case _COLEMAK:
oled_write_P(PSTR("Colemak"), false);
break;
diff --git a/keyboards/splitkb/kyria/keymaps/thomasbaart/keymap.c b/keyboards/splitkb/kyria/keymaps/thomasbaart/keymap.c
index 0a4f1887c3..3cd9df27fb 100644
--- a/keyboards/splitkb/kyria/keymaps/thomasbaart/keymap.c
+++ b/keyboards/splitkb/kyria/keymaps/thomasbaart/keymap.c
@@ -311,7 +311,7 @@ bool oled_task_user(void) {
#ifdef ENCODER_ENABLE
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case QWERTY:
// History scrubbing. For Adobe products, hold shift while moving
// backward to go forward instead.
@@ -336,7 +336,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
break;
}
} else if (index == 1) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case QWERTY:
// Scrolling with PageUp and PgDn.
if (clockwise) {
diff --git a/keyboards/splitography/keymaps/jeandeaual/keymap.c b/keyboards/splitography/keymaps/jeandeaual/keymap.c
index 6679d835f2..87c4159443 100644
--- a/keyboards/splitography/keymaps/jeandeaual/keymap.c
+++ b/keyboards/splitography/keymaps/jeandeaual/keymap.c
@@ -225,7 +225,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
}
return false;
case KC_QUOT:
- if ((base_layer != dvorak) || (biton32(layer_state) != _BLUE)) {
+ if ((base_layer != dvorak) || (get_highest_layer(layer_state) != _BLUE)) {
break;
}
if (record->event.pressed) {
diff --git a/keyboards/splitography/keymaps/multi/keymap.c b/keyboards/splitography/keymaps/multi/keymap.c
index af1cc1a801..7d847e40b6 100644
--- a/keyboards/splitography/keymaps/multi/keymap.c
+++ b/keyboards/splitography/keymaps/multi/keymap.c
@@ -331,7 +331,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
return false;
case KC_QUOT:
- if ((base_layer != dvorak) || (biton32(layer_state) != _BLUE)) {
+ if ((base_layer != dvorak) || (get_highest_layer(layer_state) != _BLUE)) {
break;
}
if (record->event.pressed) {
diff --git a/keyboards/tetris/keymaps/default/keymap.c b/keyboards/tetris/keymaps/default/keymap.c
index 1b53ea80b9..9e2a96ffc3 100755
--- a/keyboards/tetris/keymaps/default/keymap.c
+++ b/keyboards/tetris/keymaps/default/keymap.c
@@ -37,7 +37,7 @@ void matrix_init_user(void) {
}
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (RGB_encoder_dir != 0) {
if (timer_elapsed(RGB_encoder_timer) > 1400) {
@@ -152,7 +152,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t * record) {
bool encoder_update_user(uint8_t index, bool clockwise) {
RGB_encoder_timer = timer_read();
RGB_encoder_timer2 = timer_read();
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (clockwise) {
RGB_encoder_dir = 1;
} else {
diff --git a/keyboards/thevankeyboards/minivan/keymaps/belak/config.h b/keyboards/thevankeyboards/minivan/keymaps/belak/config.h
index 47d96a29d8..488ffa5418 100644
--- a/keyboards/thevankeyboards/minivan/keymaps/belak/config.h
+++ b/keyboards/thevankeyboards/minivan/keymaps/belak/config.h
@@ -4,5 +4,6 @@
#include "../../config.h"
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
#endif
diff --git a/keyboards/thevankeyboards/minivan/keymaps/belak/keymap.c b/keyboards/thevankeyboards/minivan/keymaps/belak/keymap.c
index 437b1881a4..0ed709747a 100644
--- a/keyboards/thevankeyboards/minivan/keymaps/belak/keymap.c
+++ b/keyboards/thevankeyboards/minivan/keymaps/belak/keymap.c
@@ -22,6 +22,9 @@
#define TD_LCTL TD(BE_TD_CTL)
#define TD_LALT TD(BE_TD_ALT)
+#define ACTION_TAP_DANCE_MOD_TAP(mod) \
+ { .fn = {mod_tap_fn, NULL, mod_reset_fn}, .user_data = (void *)&((uint8_t){mod}), }
+
enum belak_td {
BE_TD_GUI = 0,
BE_TD_CTL,
@@ -32,15 +35,9 @@ void mod_tap_fn(qk_tap_dance_state_t *state, void *user_data);
void mod_reset_fn(qk_tap_dance_state_t *state, void *user_data);
qk_tap_dance_action_t tap_dance_actions[] = {
- [BE_TD_GUI] = ACTION_TAP_DANCE_FN_ADVANCED(mod_tap_fn, NULL, mod_reset_fn),
- [BE_TD_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(mod_tap_fn, NULL, mod_reset_fn),
- [BE_TD_ALT] = ACTION_TAP_DANCE_FN_ADVANCED(mod_tap_fn, NULL, mod_reset_fn),
-};
-
-uint16_t tap_dance_keys[] = {
- [BE_TD_GUI] = KC_LGUI,
- [BE_TD_CTL] = KC_LCTL,
- [BE_TD_ALT] = KC_LALT,
+ [BE_TD_GUI] = ACTION_TAP_DANCE_MOD_TAP(KC_LGUI),
+ [BE_TD_CTL] = ACTION_TAP_DANCE_MOD_TAP(KC_LCTL),
+ [BE_TD_ALT] = ACTION_TAP_DANCE_MOD_TAP(KC_LALT),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -74,7 +71,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void mod_tap_fn(qk_tap_dance_state_t *state, void *user_data) {
switch (state->count) {
case 1:
- register_mods(MOD_BIT(tap_dance_keys[state->keycode - QK_TAP_DANCE]));
+ uint8_t *mod = (uint8_t *)user_data;
+ register_mods(MOD_BIT(*mod));
send_keyboard_report();
break;
case 2:
@@ -90,8 +88,9 @@ void mod_tap_fn(qk_tap_dance_state_t *state, void *user_data) {
}
void mod_reset_fn(qk_tap_dance_state_t *state, void *user_data) {
+ uint8_t *mod = (uint8_t *)user_data;
layer_off(_L1);
layer_off(_L2);
- unregister_mods(MOD_BIT(tap_dance_keys[state->keycode - QK_TAP_DANCE]));
+ unregister_mods(MOD_BIT(*mod));
send_keyboard_report();
}
diff --git a/keyboards/thevankeyboards/minivan/keymaps/halvves/config.h b/keyboards/thevankeyboards/minivan/keymaps/halvves/config.h
index 6be8d217bd..c6404f8ce5 100644
--- a/keyboards/thevankeyboards/minivan/keymaps/halvves/config.h
+++ b/keyboards/thevankeyboards/minivan/keymaps/halvves/config.h
@@ -1,6 +1,7 @@
#pragma once
#define TAPPING_TERM 505
+#define PERMISSIVE_HOLD
#define RETRO_TAPPING
// smooth mousekeys (copied from the ergo ez config)
diff --git a/keyboards/thevankeyboards/roadkit/keymaps/flipphone/keymap.c b/keyboards/thevankeyboards/roadkit/keymaps/flipphone/keymap.c
index b00cf80f5c..a6fa5ed722 100644
--- a/keyboards/thevankeyboards/roadkit/keymaps/flipphone/keymap.c
+++ b/keyboards/thevankeyboards/roadkit/keymaps/flipphone/keymap.c
@@ -147,7 +147,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
}
uint8_t layer;
- layer = biton32(layer_state);
+ layer = get_highest_layer(layer_state);
switch (keycode) {
case FPH_1 ... FPH_9:
diff --git a/keyboards/tzarc/djinn/djinn.c b/keyboards/tzarc/djinn/djinn.c
index 23f59991a9..5e5fe44c67 100644
--- a/keyboards/tzarc/djinn/djinn.c
+++ b/keyboards/tzarc/djinn/djinn.c
@@ -70,7 +70,7 @@ void keyboard_post_init_kb(void) {
wait_ms(150);
// Initialise the LCD
- lcd = qp_ili9341_make_spi_device(320, 240, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 3);
+ lcd = qp_ili9341_make_spi_device(320, 240, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 0);
qp_init(lcd, QP_ROTATION_0);
// Turn on the LCD and clear the display
diff --git a/keyboards/tzarc/djinn/graphics/theme_djinn_default.c b/keyboards/tzarc/djinn/graphics/theme_djinn_default.c
index 616a3c2430..a4e87bd341 100644
--- a/keyboards/tzarc/djinn/graphics/theme_djinn_default.c
+++ b/keyboards/tzarc/djinn/graphics/theme_djinn_default.c
@@ -158,7 +158,7 @@ void draw_ui_user(void) {
if (hue_redraw || rgb_effect_redraw) {
static int max_rgb_xpos = 0;
xpos = 16;
- snprintf_(buf, sizeof(buf), "rgb: %s", rgb_matrix_name(curr_effect));
+ snprintf(buf, sizeof(buf), "rgb: %s", rgb_matrix_name(curr_effect));
for (int i = 5; i < sizeof(buf); ++i) {
if (buf[i] == 0)
@@ -187,7 +187,7 @@ void draw_ui_user(void) {
static int max_layer_xpos = 0;
xpos = 16;
- snprintf_(buf, sizeof(buf), "layer: %s", layer_name);
+ snprintf(buf, sizeof(buf), "layer: %s", layer_name);
xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
if (max_layer_xpos < xpos) {
max_layer_xpos = xpos;
@@ -200,7 +200,7 @@ void draw_ui_user(void) {
if (hue_redraw || power_state_redraw) {
static int max_power_xpos = 0;
xpos = 16;
- snprintf_(buf, sizeof(buf), "power: %s", usbpd_str(kb_state.current_setting));
+ snprintf(buf, sizeof(buf), "power: %s", usbpd_str(kb_state.current_setting));
xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
if (max_power_xpos < xpos) {
max_power_xpos = xpos;
@@ -213,7 +213,7 @@ void draw_ui_user(void) {
if (hue_redraw || scan_redraw) {
static int max_scans_xpos = 0;
xpos = 16;
- snprintf_(buf, sizeof(buf), "scans: %d", (int)theme_state.scan_rate);
+ snprintf(buf, sizeof(buf), "scans: %d", (int)theme_state.scan_rate);
xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
if (max_scans_xpos < xpos) {
max_scans_xpos = xpos;
@@ -226,7 +226,7 @@ void draw_ui_user(void) {
if (hue_redraw || wpm_redraw) {
static int max_wpm_xpos = 0;
xpos = 16;
- snprintf_(buf, sizeof(buf), "wpm: %d", (int)get_current_wpm());
+ snprintf(buf, sizeof(buf), "wpm: %d", (int)get_current_wpm());
xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
if (max_wpm_xpos < xpos) {
max_wpm_xpos = xpos;
diff --git a/keyboards/v60_type_r/keymaps/xtonhasvim/keymap.c b/keyboards/v60_type_r/keymaps/xtonhasvim/keymap.c
index 82a7e52808..8927a8ee0a 100644
--- a/keyboards/v60_type_r/keymaps/xtonhasvim/keymap.c
+++ b/keyboards/v60_type_r/keymaps/xtonhasvim/keymap.c
@@ -104,7 +104,7 @@ void rgbflag(uint8_t r, uint8_t g, uint8_t b) {
}
void set_state_leds(void) {
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _MOVE:
rgbflag(C_BLU);
break;
@@ -192,4 +192,3 @@ void suspend_wakeup_init_user(void)
backlight_set(backlight_config.level);
rgblight_set();
}
-
diff --git a/keyboards/woodkeys/bigseries/1key/keymaps/dudeofawesome/config.h b/keyboards/woodkeys/bigseries/1key/keymaps/dudeofawesome/config.h
index 30b86224c6..131c755d4a 100644
--- a/keyboards/woodkeys/bigseries/1key/keymaps/dudeofawesome/config.h
+++ b/keyboards/woodkeys/bigseries/1key/keymaps/dudeofawesome/config.h
@@ -19,5 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define CONFIG_USER_H
#define TAPPING_TERM 1000
+#define PERMISSIVE_HOLD
#endif
diff --git a/keyboards/work_louder/work_board/keymaps/default/keymap.c b/keyboards/work_louder/work_board/keymaps/default/keymap.c
index 59bb437d9d..cae65ff5c2 100644
--- a/keyboards/work_louder/work_board/keymaps/default/keymap.c
+++ b/keyboards/work_louder/work_board/keymaps/default/keymap.c
@@ -144,9 +144,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = LAYOUT(
- _______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , _______,
- _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______,
+ _______, QK_BOOT, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , _______,
+ _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______,
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
diff --git a/keyboards/xiudi/xd002/keymaps/tap_dance/config.h b/keyboards/xiudi/xd002/keymaps/tap_dance/config.h
index b86e862d30..1fd93f875f 100644
--- a/keyboards/xiudi/xd002/keymaps/tap_dance/config.h
+++ b/keyboards/xiudi/xd002/keymaps/tap_dance/config.h
@@ -1,3 +1,4 @@
#pragma once
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
diff --git a/keyboards/xiudi/xd60/keymaps/birkir/keymap.c b/keyboards/xiudi/xd60/keymaps/birkir/keymap.c
index fe7cd60662..ab129332c9 100644
--- a/keyboards/xiudi/xd60/keymaps/birkir/keymap.c
+++ b/keyboards/xiudi/xd60/keymaps/birkir/keymap.c
@@ -47,7 +47,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
edit = false;
}
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case 1:
rgblight_mode(1);
rgblight_setrgb(0xD3, 0x7F, 0xED);
diff --git a/keyboards/xiudi/xd60/keymaps/kmontag42/keymap.c b/keyboards/xiudi/xd60/keymaps/kmontag42/keymap.c
index 8e081c6731..d17fc2f35d 100644
--- a/keyboards/xiudi/xd60/keymaps/kmontag42/keymap.c
+++ b/keyboards/xiudi/xd60/keymaps/kmontag42/keymap.c
@@ -25,7 +25,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Loop
void matrix_scan_user(void) {
static uint8_t old_layer = 255;
- uint8_t new_layer = biton32(layer_state);
+ uint8_t new_layer = get_highest_layer(layer_state);
if (old_layer != new_layer) {
switch (new_layer) {
diff --git a/keyboards/xiudi/xd75/keymaps/arpinfidel/keymap.c b/keyboards/xiudi/xd75/keymaps/arpinfidel/keymap.c
index 5f7337d68b..c278df1b21 100644
--- a/keyboards/xiudi/xd75/keymaps/arpinfidel/keymap.c
+++ b/keyboards/xiudi/xd75/keymaps/arpinfidel/keymap.c
@@ -100,7 +100,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs whenever there is a layer state change.
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
gp100_led_off();
gp103_led_off();
diff --git a/keyboards/xiudi/xd75/keymaps/cbbrowne/keymap.c b/keyboards/xiudi/xd75/keymaps/cbbrowne/keymap.c
index 1b29686cff..a0295f2f45 100644
--- a/keyboards/xiudi/xd75/keymaps/cbbrowne/keymap.c
+++ b/keyboards/xiudi/xd75/keymaps/cbbrowne/keymap.c
@@ -286,7 +286,7 @@ void matrix_init_user(void) {
}
layer_state_t layer_state_set_user(layer_state_t state) {
- switch(biton32(state)) {
+ switch(get_highest_layer(state)) {
case _QWERTY:
rgblight_sethsv_white();
break;
diff --git a/keyboards/xiudi/xd75/keymaps/kloki/keymap.c b/keyboards/xiudi/xd75/keymaps/kloki/keymap.c
index a630019347..d25a16fbb6 100644
--- a/keyboards/xiudi/xd75/keymaps/kloki/keymap.c
+++ b/keyboards/xiudi/xd75/keymaps/kloki/keymap.c
@@ -70,7 +70,7 @@ bool WINDOWN = false;
bool SHIFTDOWN = false;
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
case 0:
diff --git a/keyboards/xiudi/xd75/keymaps/tdl-jturner/keymap.c b/keyboards/xiudi/xd75/keymaps/tdl-jturner/keymap.c
index b7b98cd4c5..f48eb94214 100644
--- a/keyboards/xiudi/xd75/keymaps/tdl-jturner/keymap.c
+++ b/keyboards/xiudi/xd75/keymaps/tdl-jturner/keymap.c
@@ -180,7 +180,7 @@ void matrix_init_user(void) {
//Set a color based on the layer
layer_state_t layer_state_set_user(layer_state_t state) {
- switch(biton32(state)) {
+ switch(get_highest_layer(state)) {
case _LYFK:
rgblight_setrgb_user_LYFK();
break;
diff --git a/keyboards/zfrontier/big_switch/config.h b/keyboards/zfrontier/big_switch/config.h
index ddec2b2796..99bd790cae 100644
--- a/keyboards/zfrontier/big_switch/config.h
+++ b/keyboards/zfrontier/big_switch/config.h
@@ -51,3 +51,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* long tapping config */
#define TAPPING_TERM 500
+#define PERMISSIVE_HOLD
diff --git a/layouts/community/66_ansi/xyverz/config.h b/layouts/community/66_ansi/xyverz/config.h
index 06e5830af8..37a57dbffd 100644
--- a/layouts/community/66_ansi/xyverz/config.h
+++ b/layouts/community/66_ansi/xyverz/config.h
@@ -1,5 +1,6 @@
#pragma once
#define TAPPING_TERM 600 // ms
+#define PERMISSIVE_HOLD
#undef RGBLIGHT_HUE_STEP
#define RGBLIGHT_HUE_STEP 8
diff --git a/layouts/community/ergodox/ab/keymap.c b/layouts/community/ergodox/ab/keymap.c
index 001123e286..e85d5d528c 100644
--- a/layouts/community/ergodox/ab/keymap.c
+++ b/layouts/community/ergodox/ab/keymap.c
@@ -130,7 +130,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/absenth/keymap.c b/layouts/community/ergodox/absenth/keymap.c
index d84b68f0ef..884167aa31 100644
--- a/layouts/community/ergodox/absenth/keymap.c
+++ b/layouts/community/ergodox/absenth/keymap.c
@@ -157,7 +157,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/adam/config.h b/layouts/community/ergodox/adam/config.h
index 62e82d8b2b..1555ae11fd 100644
--- a/layouts/community/ergodox/adam/config.h
+++ b/layouts/community/ergodox/adam/config.h
@@ -1,5 +1,5 @@
#pragma once
#undef TAPPING_TERM
-#define TAPPING_TERM 300 //At 500 some bad logic takes hold
+#define TAPPING_TERM 300
#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/layouts/community/ergodox/adam/keymap.c b/layouts/community/ergodox/adam/keymap.c
index 50270838aa..9dd611e03e 100644
--- a/layouts/community/ergodox/adam/keymap.c
+++ b/layouts/community/ergodox/adam/keymap.c
@@ -129,7 +129,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
diff --git a/layouts/community/ergodox/adnw_k_o_y/keymap.c b/layouts/community/ergodox/adnw_k_o_y/keymap.c
index 589a9ea873..6aa309c2cc 100644
--- a/layouts/community/ergodox/adnw_k_o_y/keymap.c
+++ b/layouts/community/ergodox/adnw_k_o_y/keymap.c
@@ -139,7 +139,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/alexjj/keymap.c b/layouts/community/ergodox/alexjj/keymap.c
index 64e7c94433..c9adf7af63 100644
--- a/layouts/community/ergodox/alexjj/keymap.c
+++ b/layouts/community/ergodox/alexjj/keymap.c
@@ -206,7 +206,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/andrew_osx/keymap.c b/layouts/community/ergodox/andrew_osx/keymap.c
index 990fea4f45..4f3f6ef0cb 100644
--- a/layouts/community/ergodox/andrew_osx/keymap.c
+++ b/layouts/community/ergodox/andrew_osx/keymap.c
@@ -141,7 +141,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/berfarah/keymap.c b/layouts/community/ergodox/berfarah/keymap.c
index 164d026ef3..7dc09e7543 100644
--- a/layouts/community/ergodox/berfarah/keymap.c
+++ b/layouts/community/ergodox/berfarah/keymap.c
@@ -219,7 +219,7 @@ static inline void mod_layer_with_rgb(keyrecord_t *record, uint8_t layer) {
bf_set_led(layer);
} else {
layer_off(layer);
- uint8_t currentLayer = biton32(layer_state);
+ uint8_t currentLayer = get_highest_layer(layer_state);
bf_set_led(currentLayer);
};
};
@@ -266,7 +266,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/layouts/community/ergodox/bryan/keymap.c b/layouts/community/ergodox/bryan/keymap.c
index acae77d5fc..ab301e8922 100644
--- a/layouts/community/ergodox/bryan/keymap.c
+++ b/layouts/community/ergodox/bryan/keymap.c
@@ -200,7 +200,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/choromanski/keymap.c b/layouts/community/ergodox/choromanski/keymap.c
index 8be3c7ea7e..933f13b25f 100644
--- a/layouts/community/ergodox/choromanski/keymap.c
+++ b/layouts/community/ergodox/choromanski/keymap.c
@@ -30,15 +30,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
OSL(3), TG(2), TO(5), TO(1), KC_CAPS,
KC_LCTL, KC_LALT,
KC_MUTE,
- KC_BSPC, KC_DEL, KC_LGUI,
+ KC_BSPC, KC_DEL, KC_LGUI,
- KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
+ KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
KC_RPRN, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSLS,
- KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
+ KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
KC_RBRC, KC_K, KC_M, KC_COMM, ALT_T(KC_DOT), CTL_T(KC_SLSH), KC_RSFT,
- KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, TG(4),
- KC_RALT, KC_RCTL,
- KC_WH_U,
+ KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, TG(4),
+ KC_RALT, KC_RCTL,
+ KC_WH_U,
KC_WH_D, KC_ENT, KC_SPC
),
@@ -106,22 +106,22 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[2] = LAYOUT_ergodox(
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
- KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS,
+ KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 3: Symbols
@@ -147,9 +147,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[3] = LAYOUT_ergodox(
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
- KC_TRNS, KC_PIPE, KC_PLUS, KC_LABK, KC_RABK, KC_HASH, KC_TRNS,
- KC_TRNS, KC_EXLM, KC_MINS, KC_EQL, KC_PERC, KC_AT,
- KC_TRNS, KC_ASTR, KC_AMPR, KC_SLSH, KC_DLR, KC_CIRC, KC_TRNS,
+ KC_TRNS, KC_PIPE, KC_PLUS, KC_LABK, KC_RABK, KC_HASH, KC_TRNS,
+ KC_TRNS, KC_EXLM, KC_MINS, KC_EQL, KC_PERC, KC_AT,
+ KC_TRNS, KC_ASTR, KC_AMPR, KC_SLSH, KC_DLR, KC_CIRC, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
@@ -229,8 +229,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[5] = LAYOUT_ergodox(
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_TRNS,
- KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MPLY,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MPLY,
KC_LCTL, LALT(KC_TAB), TO(0), KC_LALT, KC_SPC,
KC_MPRV, KC_MNXT,
KC_VOLU,
@@ -249,7 +249,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/colemak/keymap.c b/layouts/community/ergodox/colemak/keymap.c
index 54b0c5834a..db2addd6d9 100644
--- a/layouts/community/ergodox/colemak/keymap.c
+++ b/layouts/community/ergodox/colemak/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/colemak_code_friendly/keymap.c b/layouts/community/ergodox/colemak_code_friendly/keymap.c
index 936ddbc2a5..6350bd9ee2 100644
--- a/layouts/community/ergodox/colemak_code_friendly/keymap.c
+++ b/layouts/community/ergodox/colemak_code_friendly/keymap.c
@@ -59,7 +59,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D,
KC_LSFT, LCTL_T(KC_Z), LGUI_T(KC_X), KC_C, KC_V, RALT_T(KC_B), KC_LCBR,
KC_LCTL, KC_LGUI, KC_LALT, KC_LBRC, KC_RBRC,
-
+
KC_HOME, KC_END,
KC_PSCR,
MO(LAYER_LNUM), KC_ENT, KC_LGUI,
@@ -101,7 +101,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_F8, KC_F7, KC_F6, KC_F5, M_IN_PRN,
KC_TRNS, KC_F4, KC_F3, KC_F2, KC_F1, M_IN_BRC, KC_TRNS,
KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
-
+
KC_TRNS, KC_TRNS,
DYN_REC_START1,
KC_TRNS, KC_TRNS, DYN_MACRO_PLAY1,
@@ -126,8 +126,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |--------+------+------+------+------+------| | | } |------+------+------+------+------+--------|
* | | F4 | F3 | F2 | F1 | [] | | | |K/RAlt| M | , |./Supe|/ RCtl| RShift |
* '--------+------+------+------+------+-------------' '-------------+------+------+------+------+--------'
- * | MUTE | VOLD | VOLU | | | | Left | Down | Up |Right | Del |
- * '----------------------------------' '----------------------------------'
+ * | MUTE | VOLD | VOLU | | | | Left | Down | Up |Right | Del |
+ * '----------------------------------' '----------------------------------'
* .-------------. .-------------.
* | | | | Ins |ScrLck|
* .------+------+------| |------+------+------.
@@ -143,7 +143,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_F8, KC_F7, KC_F6, KC_F5, M_IN_PRN,
KC_TRNS, KC_F4, KC_F3, KC_F2, KC_F1, M_IN_BRC, KC_TRNS,
KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_TRNS,
-
+
KC_TRNS, KC_TRNS,
DYN_REC_START1,
KC_TRNS, KC_TRNS, DYN_MACRO_PLAY1,
@@ -185,7 +185,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
S(KC_ESC), S(KC_A), S(KC_R), S(KC_S), S(KC_T), S(KC_D),
KC_LSFT, S(KC_Z), S(KC_X), S(KC_C), S(KC_V), S(KC_B), KC_LCBR,
S(KC_LCTL), S(KC_LGUI), S(KC_LALT), S(KC_LBRC), S(KC_RBRC),
-
+
S(KC_HOME), S(KC_END),
S(KC_PSCR),
KC_CAPS, S(KC_ENT), S(KC_LGUI),
@@ -227,7 +227,7 @@ static bool process_record_dynamic_macro_wrapper(uint16_t keycode, keyrecord_t *
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
-
+
/* the purpose of the ..._wrapper is to detect START/ST0P keys to
light the blue led during recording */
if (!process_record_dynamic_macro_wrapper(keycode, record)) {
@@ -308,19 +308,19 @@ void matrix_init_user(void) {
/* Runs constantly in the background, in a loop. */
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
//led 1, RED, Caps-Lock ON
//if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ergodox_right_led_1_on();
//led 2, GREEN
- if (layer == LAYER_NUM)
+ if (layer == LAYER_NUM)
ergodox_right_led_2_on();
else
ergodox_right_led_2_off();
//led 3, BLUE
- if (recording_dynamic_macro)
+ if (recording_dynamic_macro)
ergodox_right_led_3_on();
else
ergodox_right_led_3_off();
diff --git a/layouts/community/ergodox/colemak_programmer/keymap.c b/layouts/community/ergodox/colemak_programmer/keymap.c
index 46cd28dc8c..b4ace197de 100644
--- a/layouts/community/ergodox/colemak_programmer/keymap.c
+++ b/layouts/community/ergodox/colemak_programmer/keymap.c
@@ -23,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |symbol|N-Lock| End | | PgDn | | |
* `---------------------' `---------------------'
*/
-[0] = LAYOUT_ergodox( // layer 0 : default
+[0] = LAYOUT_ergodox( // layer 0 : default
// left hand
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, TG(3),
@@ -68,7 +68,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `----------------------'
*/
-[1] = LAYOUT_ergodox( // layer 1: QWERTY layer (games)
+[1] = LAYOUT_ergodox( // layer 1: QWERTY layer (games)
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_TRNS,
KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G,
@@ -78,7 +78,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
-
+
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_TRNS,
@@ -243,7 +243,7 @@ void matrix_scan_user(void) {
//bit 1: default layer 1 - QWERTY
if (default_layer_state & (1UL << 1)) ergodox_right_led_1_on();
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
//layer 2 : Symbols (& Fs)
//if (layer == 2) ergodox_right_led_2_on();
diff --git a/layouts/community/ergodox/common_nighthawk/keymap.c b/layouts/community/ergodox/common_nighthawk/keymap.c
index cb13822e4e..a7ed10d715 100644
--- a/layouts/community/ergodox/common_nighthawk/keymap.c
+++ b/layouts/community/ergodox/common_nighthawk/keymap.c
@@ -188,7 +188,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/csharp_dev/keymap.c b/layouts/community/ergodox/csharp_dev/keymap.c
index 221389ef24..f22938429d 100644
--- a/layouts/community/ergodox/csharp_dev/keymap.c
+++ b/layouts/community/ergodox/csharp_dev/keymap.c
@@ -57,7 +57,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_RPRN, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_BSPACE,
KC_LCBR, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_RCBR, ALT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_SLASH,
- CTL_T(KC_TAB), LSFT(KC_COMMA),LSFT(KC_DOT),KC_PIPE,KC_AMPR,
+ CTL_T(KC_TAB), LSFT(KC_COMMA),LSFT(KC_DOT),KC_PIPE,KC_AMPR,
LT(1,KC_DOT), KC_COMM,
LCTL(KC_C),
GUI_T(KC_ENTER),SFT_T(KC_SPACE),LCTL(KC_V),
@@ -125,81 +125,81 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
case MACRO_PUBLIC:
if (record->event.pressed) {
return MACRO( T(P), T(U), T(B), T(L), T(I), T(C), T(SPACE),END);
- }
+ }
break;
case MACRO_PRIVATE:
if (record->event.pressed) {
return MACRO( T(P), T(R), T(I), T(V), T(A), T(T), T(E), T(SPACE),END);
- }
+ }
break;
case MACRO_STATIC:
if (record->event.pressed) {
return MACRO( T(S), T(T), T(A), T(T), T(I), T(C), T(SPACE), END);
- }
+ }
break;
case MACRO_CONST:
if (record->event.pressed) {
return MACRO( T(C), T(O), T(N), T(S), T(T), T(SPACE), END);
- }
+ }
break;
case MACRO_VOID:
if (record->event.pressed) {
return MACRO( T(V), T(O), T(I), T(D), T(SPACE), END);
- }
+ }
break;
case MACRO_VAR:
if (record->event.pressed) {
return MACRO( T(V), T(A), T(R), T(SPACE), END);
- }
+ }
break;
case MACRO_STRING:
if (record->event.pressed) {
return MACRO( T(S), T(T), T(R), T(I), T(N), T(G), T(SPACE), END);
- }
- break;
+ }
+ break;
case MACRO_BOOL:
if (record->event.pressed) {
return MACRO( T(B), T(O), T(O), T(L), T(SPACE), END);
- }
- break;
+ }
+ break;
case MACRO_INT:
if (record->event.pressed) {
return MACRO( T(I), T(N), T(T), T(SPACE), END);
- }
+ }
break;
case MACRO_FLOAT:
if (record->event.pressed) {
return MACRO( T(F), T(L), T(O), T(A),T(T),T(SPACE), END);
- }
+ }
break;
case MACRO_RETURN:
if (record->event.pressed) {
return MACRO( T(R), T(E), T(T), T(U),T(R),T(N), END);
- }
+ }
break;
case MACRO_NULL:
if (record->event.pressed) {
return MACRO( T(N), T(U), T(L), T(L), END);
- }
+ }
case MACRO_BREAK:
if (record->event.pressed) {
return MACRO( T(B), T(R), T(E), T(A), T(K), T(SCOLON), END);
- }
+ }
break;
case MACRO_TODO:
if (record->event.pressed) {
return MACRO( T(SLASH), T(SLASH), D(LSHIFT) ,T(T), T(O), T(D), T(O),U(LSHIFT), T(SPACE),END);
- }
+ }
break;
case MACRO_NEW:
if (record->event.pressed) {
return MACRO( T(N), T(E), T(W), T(SPACE), END);
- }
+ }
break;
case MACRO_PARENTHESE:
if (record->event.pressed) {
return MACRO( D(LSHIFT),T(9), T(0),U(LSHIFT), T(SCOLON), END);
- }
+ }
break;
}
return MACRO_NONE;
@@ -213,7 +213,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dave/keymap.c b/layouts/community/ergodox/dave/keymap.c
index efa270c406..c54e50ba98 100644
--- a/layouts/community/ergodox/dave/keymap.c
+++ b/layouts/community/ergodox/dave/keymap.c
@@ -147,7 +147,7 @@ void matrix_scan_user(void) {
*/
static uint8_t leds[4];
uint8_t led;
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
diff --git a/layouts/community/ergodox/deadcyclo/keymap.c b/layouts/community/ergodox/deadcyclo/keymap.c
index 345e25e03e..76f5279257 100644
--- a/layouts/community/ergodox/deadcyclo/keymap.c
+++ b/layouts/community/ergodox/deadcyclo/keymap.c
@@ -90,10 +90,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LALT, KC_RALT,KC_LEAD,LCTL(LSFT(KC_U)), LT(SYMB,KC_TILD),
KC_PGUP, KC_INS,
KC_PGDN,
- KC_RBRC,KC_BSPC, KC_ENT
+ KC_RBRC,KC_BSPC, KC_ENT
),
-/* Keymap 1: Symbol Layer LCTL(LSFT(KC_U))
- *
+/* Keymap 1: Symbol Layer LCTL(LSFT(KC_U))
+ *
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
@@ -192,7 +192,7 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, I3_RUN, KC_TRNS, KC_TRNS,
* ,-------------. ,-------------.
* | | | | â–’ | â–“ |
* ,------|------|------| |------+------+------.
- * | | | | | | | |
+ * | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
@@ -218,7 +218,7 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, I3_RUN, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
-/* Keymap 4: Unicode 2
+/* Keymap 4: Unicode 2
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | ¹ | ² | ³ | ⴠ| ⵠ| ⶠ| | ⶠ| ⷠ| ⸠| ⹠| Ⱐ| ℃ | ™ |
@@ -234,12 +234,12 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, I3_RUN, KC_TRNS, KC_TRNS,
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
- * | | | | | | | |
+ * | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
-// Unicode 2
+// Unicode 2
[UNI2] = LAYOUT_ergodox(
KC_TRNS, UC(0x00b9), UC(0x00b2), UC(0x00b3), UC(0x2074), UC(0x2075), UC(0x2076),
KC_TRNS, UC(0x2081), UC(0x2082), UC(0x2083), UC(0x2084), UC(0x2085), UC(0x2086),
@@ -346,7 +346,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dragon788/keymap.c b/layouts/community/ergodox/dragon788/keymap.c
index 956a592b6d..b32346a9df 100644
--- a/layouts/community/ergodox/dragon788/keymap.c
+++ b/layouts/community/ergodox/dragon788/keymap.c
@@ -183,7 +183,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak/keymap.c b/layouts/community/ergodox/dvorak/keymap.c
index 68b575fd68..664d8055a4 100644
--- a/layouts/community/ergodox/dvorak/keymap.c
+++ b/layouts/community/ergodox/dvorak/keymap.c
@@ -138,7 +138,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_emacs/keymap.c b/layouts/community/ergodox/dvorak_emacs/keymap.c
index 6055fd770d..14c592f27f 100644
--- a/layouts/community/ergodox/dvorak_emacs/keymap.c
+++ b/layouts/community/ergodox/dvorak_emacs/keymap.c
@@ -120,7 +120,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_emacs_software/keymap.c b/layouts/community/ergodox/dvorak_emacs_software/keymap.c
index 4f90f193c6..c2bc1ef8f2 100644
--- a/layouts/community/ergodox/dvorak_emacs_software/keymap.c
+++ b/layouts/community/ergodox/dvorak_emacs_software/keymap.c
@@ -121,7 +121,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_intl_squisher/keymap.c b/layouts/community/ergodox/dvorak_intl_squisher/keymap.c
index 3ebbd2df09..2d3ec3806b 100644
--- a/layouts/community/ergodox/dvorak_intl_squisher/keymap.c
+++ b/layouts/community/ergodox/dvorak_intl_squisher/keymap.c
@@ -139,7 +139,7 @@ LAYOUT_ergodox( // layer 0 : default
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_plover/keymap.c b/layouts/community/ergodox/dvorak_plover/keymap.c
index 989aafb90a..51f7e61203 100644
--- a/layouts/community/ergodox/dvorak_plover/keymap.c
+++ b/layouts/community/ergodox/dvorak_plover/keymap.c
@@ -181,7 +181,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_programmer/keymap.c b/layouts/community/ergodox/dvorak_programmer/keymap.c
index 33115d21f3..a8acee119a 100644
--- a/layouts/community/ergodox/dvorak_programmer/keymap.c
+++ b/layouts/community/ergodox/dvorak_programmer/keymap.c
@@ -45,7 +45,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, MO(KEY_SEL),
MO(BRACKETS), KC_A, KC_O, KC_E, KC_U, KC_I,
MO(SHELL_NAV), KC_SCLN, KC_Q, KC_J, KC_K, KC_X, MO(KEY_NAV),
- OSL(SHORTCUTS),OSM(MOD_LCTL), OSM(MOD_LALT),OSL(SYMBOL),MO(NUMBER),
+ OSL(SHORTCUTS),OSM(MOD_LCTL), OSM(MOD_LALT),OSL(SYMBOL),MO(NUMBER),
// thumb cluster
OSM(MOD_LSFT), RCTL(KC_S),
RCTL(KC_DEL),
@@ -62,10 +62,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_UP,
KC_DOWN,KC_ENT, KC_SPC
),
-
-
-
+
+
+
// shell navigation layer
[SHELL_NAV] = LAYOUT_ergodox(
// left hand
@@ -92,7 +92,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS
),
-
+
// key navigation layer
[KEY_NAV] = LAYOUT_ergodox(
// left hand
@@ -177,7 +177,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
- KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
@@ -187,7 +187,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_PLUS, KC_AMPR, KC_ASTR, KC_GRAVE,KC_TILD, KC_TRNS,
KC_MINS, KC_DLR, KC_PERC, KC_CIRC, KC_PIPE, KC_TRNS,
KC_TRNS, KC_EQUAL,KC_EXLM, KC_AT, KC_HASH, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
M(SEMICOLON_NEWLINE), M(END_NEWLINE),
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
@@ -198,7 +198,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,M(OPEN_CLOSE_CURLY), M(OPEN_CLOSE_PAREN),M(OPEN_CLOSE_BRACKET), KC_TRNS,KC_TRNS,
KC_TRNS,KC_LPRN, KC_RPRN, KC_LBRC, KC_RBRC, KC_TRNS,
- KC_TRNS,KC_TRNS,KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
@@ -207,8 +207,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS, KC_TRNS, M(OPEN_CLOSE_BRACKET),M(OPEN_CLOSE_PAREN),M(OPEN_CLOSE_CURLY),KC_TRNS,KC_TRNS,
KC_TRNS, KC_LBRC, KC_RBRC, KC_LPRN, KC_RPRN, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
@@ -219,7 +219,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_NO, MEH(KC_F1), MEH(KC_F2), MEH(KC_F3), MEH(KC_F4), MEH(KC_F5), MEH(KC_F6),
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
- KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
MEH(KC_0),MEH(KC_1),
MEH(KC_2),
@@ -272,12 +272,12 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
case MC_CUT_LINE:
if (record->event.pressed) {
return MACRO( T(HOME), D(LSFT), T(END), U(LSFT), D(LCTL), T(X), U(LCTL), END);
- }
+ }
break;
case MC_PASTE_LINE:
if (record->event.pressed) {
return MACRO( T(END), T(ENTER), D(LCTL), T(V), U(LCTL), END);
- }
+ }
break;
case MC_NEW_SEARCH_TAB:
if (record->event.pressed) {
@@ -287,17 +287,17 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
case SCREEN_TAB_LEFT:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(P), END);
- }
+ }
break;
case SCREEN_TAB_RIGHT:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(N), END);
- }
+ }
break;
case SCREEN_NEW_TAB:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(C), END);
- }
+ }
break;
case SCREEN_COPY_MODE:
if (record->event.pressed) {
@@ -306,14 +306,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
break;
case SCREEN_PASTE:
if (record->event.pressed) {
- return MACRO( D(LCTL), T(A), U(LCTL), T(RBRC), END);
+ return MACRO( D(LCTL), T(A), U(LCTL), T(RBRC), END);
}
- break;
+ break;
case SWITCH_NDS:
if (record->event.pressed) {
return MACRO( D(LSFT), T(F11), U(LSFT), W(255), D(LALT), T(TAB), U(LALT), END);
- }
- break;
+ }
+ break;
case OPEN_CLOSE_PAREN:
if (record->event.pressed) {
return MACRO( D(LSFT), T(9), T(0), U(LSFT), T(LEFT), END);
@@ -323,39 +323,39 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (record->event.pressed) {
return MACRO( T(LBRC), T(RBRC), T(LEFT), END);
}
- break;
+ break;
case OPEN_CLOSE_CURLY:
if (record->event.pressed) {
return MACRO( D(LSFT), T(LBRC), T(RBRC), U(LSFT), T(LEFT), END);
}
- break;
+ break;
case OPEN_CLOSE_SINGLE_QUOTE:
if (record->event.pressed) {
return MACRO( T(QUOT), T(QUOT), T(LEFT), END);
}
- break;
+ break;
case OPEN_CLOSE_DOUBLE_QUOTE:
if (record->event.pressed) {
return MACRO( D(LSFT), T(QUOT), T(QUOT), U(LSFT), T(LEFT), END);
}
- break;
+ break;
case SHELL_RECALL_LAST_ARG_REMOVE_FIRST_COMMAND:
if (record->event.pressed) {
return MACRO( T(UP), T(HOME), D(LALT), T(D), U(LALT), END);
}
- break;
+ break;
case SEMICOLON_NEWLINE:
if (record->event.pressed) {
return MACRO( T(END), T(SCLN), T(ENTER), END);
- }
+ }
break;
case END_NEWLINE:
if (record->event.pressed) {
return MACRO( T(END), T(ENTER), END);
- }
- break;
-
-
+ }
+ break;
+
+
}
return MACRO_NONE;
};
@@ -378,7 +378,7 @@ void led_set_user(uint8_t usb_led) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_2_off();
@@ -387,13 +387,13 @@ void matrix_scan_user(void) {
case NUMBER:
case SYMBOL:
case BRACKETS:
- //case SHELL_LAYER:
+ //case SHELL_LAYER:
ergodox_right_led_2_on();
break;
case KEY_NAV:
case KEY_SEL:
ergodox_right_led_3_on();
- break;
+ break;
case SHORTCUTS:
ergodox_right_led_2_on();
ergodox_right_led_3_on();
@@ -401,6 +401,6 @@ void matrix_scan_user(void) {
default:
// none
break;
- }
+ }
return;
};
diff --git a/layouts/community/ergodox/dvorak_programmer_swe/keymap.c b/layouts/community/ergodox/dvorak_programmer_swe/keymap.c
index a8a428a04b..2578547f17 100644
--- a/layouts/community/ergodox/dvorak_programmer_swe/keymap.c
+++ b/layouts/community/ergodox/dvorak_programmer_swe/keymap.c
@@ -306,7 +306,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/dvorak_spanish/keymap.c b/layouts/community/ergodox/dvorak_spanish/keymap.c
index 98aa638a0f..805abb0b77 100644
--- a/layouts/community/ergodox/dvorak_spanish/keymap.c
+++ b/layouts/community/ergodox/dvorak_spanish/keymap.c
@@ -192,13 +192,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (record->event.pressed) {
key_timer = timer_read();
register_code(KC_RSFT);
- } else {
+ } else {
unregister_code(KC_RSFT);
- if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
- register_code(KC_RALT);
- register_code(KC_BSLS);
- unregister_code(KC_BSLS);
- unregister_code(KC_RALT);
+ if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
+ register_code(KC_RALT);
+ register_code(KC_BSLS);
+ unregister_code(KC_BSLS);
+ unregister_code(KC_RALT);
}
}
break;
@@ -207,13 +207,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (record->event.pressed) {
key_timer = timer_read();
register_code(KC_LALT);
- } else {
+ } else {
unregister_code(KC_LALT);
- if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
- register_code(KC_RALT);
- register_code(KC_LBRACKET);
- unregister_code(KC_LBRACKET);
- unregister_code(KC_RALT);
+ if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
+ register_code(KC_RALT);
+ register_code(KC_LBRACKET);
+ unregister_code(KC_LBRACKET);
+ unregister_code(KC_RALT);
}
}
break;
@@ -222,13 +222,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (record->event.pressed) {
key_timer = timer_read();
register_code(KC_LALT);
- } else {
+ } else {
unregister_code(KC_LALT);
- if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
- register_code(KC_RALT);
- register_code(KC_RBRACKET);
- unregister_code(KC_RBRACKET);
- unregister_code(KC_RALT);
+ if (timer_elapsed(key_timer) < KEY_TAP_SLOW) {
+ register_code(KC_RALT);
+ register_code(KC_RBRACKET);
+ unregister_code(KC_RBRACKET);
+ unregister_code(KC_RALT);
}
}
break;
@@ -236,7 +236,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
case CAPS: {
if (record->event.pressed) {
register_code(KC_CAPSLOCK);
- } else {
+ } else {
unregister_code(KC_CAPSLOCK);
}
break;
@@ -253,7 +253,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -270,11 +270,10 @@ void matrix_scan_user(void) {
// none
break;
}
-
+
// Turn the caps lock led on
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
ergodox_right_led_1_on();
}
}
-
diff --git a/layouts/community/ergodox/dvorak_svorak_a5/keymap.c b/layouts/community/ergodox/dvorak_svorak_a5/keymap.c
index 3ecef9d9b6..6729dbeeb6 100644
--- a/layouts/community/ergodox/dvorak_svorak_a5/keymap.c
+++ b/layouts/community/ergodox/dvorak_svorak_a5/keymap.c
@@ -186,7 +186,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/emacs_osx_dk/keymap.c b/layouts/community/ergodox/emacs_osx_dk/keymap.c
index 1de894616b..2c3430c236 100644
--- a/layouts/community/ergodox/emacs_osx_dk/keymap.c
+++ b/layouts/community/ergodox/emacs_osx_dk/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/french_hacker/keymap.c b/layouts/community/ergodox/french_hacker/keymap.c
index 44b0c47860..73e3076475 100644
--- a/layouts/community/ergodox/french_hacker/keymap.c
+++ b/layouts/community/ergodox/french_hacker/keymap.c
@@ -147,7 +147,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/galson/keymap.c b/layouts/community/ergodox/galson/keymap.c
index 2b7994b11d..83c6638d57 100644
--- a/layouts/community/ergodox/galson/keymap.c
+++ b/layouts/community/ergodox/galson/keymap.c
@@ -53,7 +53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
/* Keymap 1: Symbol Layer
*
- * ,--------------------------------------------------.
+ * ,--------------------------------------------------.
* |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
@@ -157,7 +157,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/german-kinergo/keymap.c b/layouts/community/ergodox/german-kinergo/keymap.c
index 9f8b72596e..eae02d8925 100644
--- a/layouts/community/ergodox/german-kinergo/keymap.c
+++ b/layouts/community/ergodox/german-kinergo/keymap.c
@@ -165,7 +165,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/german-lukas/keymap.c b/layouts/community/ergodox/german-lukas/keymap.c
index 76a77acdb2..a63a13c12d 100644
--- a/layouts/community/ergodox/german-lukas/keymap.c
+++ b/layouts/community/ergodox/german-lukas/keymap.c
@@ -188,7 +188,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/german-manuneo/compile_keymap.py b/layouts/community/ergodox/german-manuneo/compile_keymap.py
index df5d429842..ae7ff50397 100644
--- a/layouts/community/ergodox/german-manuneo/compile_keymap.py
+++ b/layouts/community/ergodox/german-manuneo/compile_keymap.py
@@ -27,29 +27,34 @@ PY2 = sys.version_info.major == 2
if PY2:
chr = unichr
-
KEYBOARD_LAYOUTS = {
# These map positions in the parsed layout to
# positions in the LAYOUT_ergodox MATRIX
'ergodox_ez': [
- [ 0, 1, 2, 3, 4, 5, 6], [38, 39, 40, 41, 42, 43, 44],
- [ 7, 8, 9, 10, 11, 12, 13], [45, 46, 47, 48, 49, 50, 51],
- [14, 15, 16, 17, 18, 19 ], [ 52, 53, 54, 55, 56, 57],
- [20, 21, 22, 23, 24, 25, 26], [58, 59, 60, 61, 62, 63, 64],
- [27, 28, 29, 30, 31 ], [ 65, 66, 67, 68, 69],
- [ 32, 33], [70, 71 ],
- [ 34], [72 ],
- [ 35, 36, 37], [73, 74, 75 ],
+ [0, 1, 2, 3, 4, 5, 6],
+ [38, 39, 40, 41, 42, 43, 44],
+ [7, 8, 9, 10, 11, 12, 13],
+ [45, 46, 47, 48, 49, 50, 51],
+ [14, 15, 16, 17, 18, 19],
+ [52, 53, 54, 55, 56, 57],
+ [20, 21, 22, 23, 24, 25, 26],
+ [58, 59, 60, 61, 62, 63, 64],
+ [27, 28, 29, 30, 31],
+ [65, 66, 67, 68, 69],
+ [32, 33],
+ [70, 71],
+ [34],
+ [72],
+ [35, 36, 37],
+ [73, 74, 75],
]
}
-ROW_INDENTS = {
- 'ergodox_ez': [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 5, 0, 6, 0, 4, 0]
-}
+ROW_INDENTS = {'ergodox_ez': [0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 5, 0, 6, 0, 4, 0]}
BLANK_LAYOUTS = [
-# Compact Layout
-"""
+ # Compact Layout
+ """
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
@@ -70,8 +75,8 @@ BLANK_LAYOUTS = [
'-----------------' '-----------------'
""",
-# Wide Layout
-"""
+ # Wide Layout
+ """
.---------------------------------------------. .---------------------------------------------.
| | | | | | | | ! | | | | | | |
!-------+-----+-----+-----+-----+-------------! !-------+-----+-----+-----+-----+-----+-------!
@@ -93,26 +98,22 @@ BLANK_LAYOUTS = [
""",
]
-
DEFAULT_CONFIG = {
- "keymaps_includes": [
- "keymap_common.h",
- ],
+ "keymaps_includes": ["keymap_common.h",],
'filler': "-+.'!:x",
'separator': "|",
'default_key_prefix': ["KC_"],
}
-
SECTIONS = [
'layout_config',
'layers',
]
-
# Markdown Parsing
-ONELINE_COMMENT_RE = re.compile(r"""
+ONELINE_COMMENT_RE = re.compile(
+ r"""
^ # comment must be at the start of the line
\s* # arbitrary whitespace
// # start of the comment
@@ -121,22 +122,26 @@ ONELINE_COMMENT_RE = re.compile(r"""
""", re.MULTILINE | re.VERBOSE
)
-INLINE_COMMENT_RE = re.compile(r"""
+INLINE_COMMENT_RE = re.compile(
+ r"""
([\,\"\[\]\{\}\d]) # anythig that might end a expression
\s+ # comment must be preceded by whitespace
// # start of the comment
\s # and succeded by whitespace
(?:[^\"\]\}\{\[]*) # the comment (except things which might be json)
$ # until the end of line
-""", re.MULTILINE | re.VERBOSE)
+""", re.MULTILINE | re.VERBOSE
+)
-TRAILING_COMMA_RE = re.compile(r"""
+TRAILING_COMMA_RE = re.compile(
+ r"""
, # the comma
(?:\s*) # arbitrary whitespace
$ # only works if the trailing comma is followed by newline
(\s*) # arbitrary whitespace
([\]\}]) # end of an array or object
-""", re.MULTILINE | re.VERBOSE)
+""", re.MULTILINE | re.VERBOSE
+)
def loads(raw_data):
@@ -178,9 +183,7 @@ def parse_config(path):
def end_section():
if section['start_line'] >= 0:
if section['name'] == 'layout_config':
- config.update(loads("\n".join(
- section['code_lines']
- )))
+ config.update(loads("\n".join(section['code_lines'])))
elif section['sub_name'].startswith('layer'):
layer_name = section['sub_name']
config['layer_lines'][layer_name] = section['code_lines']
@@ -215,6 +218,7 @@ def parse_config(path):
assert 'layout' in config
return config
+
# header file parsing
IF0_RE = re.compile(r"""
@@ -224,7 +228,6 @@ IF0_RE = re.compile(r"""
#endif
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
COMMENT_RE = re.compile(r"""
/\*
.*?
@@ -244,6 +247,7 @@ def regex_partial(re_str_fmt, flags):
def partial(*args, **kwargs):
re_str = re_str_fmt.format(*args, **kwargs)
return re.compile(re_str, flags)
+
return partial
@@ -256,7 +260,6 @@ KEYDEF_REP = regex_partial(r"""
) # capture group end
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
ENUM_RE = re.compile(r"""
(
enum
@@ -268,7 +271,6 @@ ENUM_RE = re.compile(r"""
) # capture group end
""", re.MULTILINE | re.DOTALL | re.VERBOSE)
-
ENUM_KEY_REP = regex_partial(r"""
(
{} # the prefixes
@@ -309,14 +311,13 @@ def parse_valid_keys(config, out_path):
include_path = os.path.join(dirpath, include)
if os.path.exists(include_path):
header_data = read_header_file(include_path)
- valid_keycodes.update(
- parse_keydefs(config, header_data)
- )
+ valid_keycodes.update(parse_keydefs(config, header_data))
return valid_keycodes
# Keymap Parsing
+
def iter_raw_codes(layer_lines, filler, separator):
filler_re = re.compile("[" + filler + " ]")
for line in layer_lines:
@@ -346,28 +347,21 @@ LAYER_CHANGE_RE = re.compile(r"""
(DF|TG|MO)\(\d+\)
""", re.VERBOSE)
-
MACRO_RE = re.compile(r"""
M\(\w+\)
""", re.VERBOSE)
-
UNICODE_RE = re.compile(r"""
U[0-9A-F]{4}
""", re.VERBOSE)
-
NON_CODE = re.compile(r"""
^[^A-Z0-9_]$
""", re.VERBOSE)
def parse_uni_code(raw_code):
- macro_id = "UC_" + (
- unicodedata.name(raw_code)
- .replace(" ", "_")
- .replace("-", "_")
- )
+ macro_id = "UC_" + (unicodedata.name(raw_code).replace(" ", "_").replace("-", "_"))
code = "M({})".format(macro_id)
uc_hex = "{:04X}".format(ord(raw_code))
return code, macro_id, uc_hex
@@ -407,19 +401,13 @@ def parse_code(raw_code, key_prefixes, valid_keycodes):
def parse_keymap(config, key_indexes, layer_lines, valid_keycodes):
keymap = {}
- raw_codes = list(iter_raw_codes(
- layer_lines, config['filler'], config['separator']
- ))
+ raw_codes = list(iter_raw_codes(layer_lines, config['filler'], config['separator']))
indexed_codes = iter_indexed_codes(raw_codes, key_indexes)
key_prefixes = config['key_prefixes']
for raw_code, key_index, row_index in indexed_codes:
- code, macro_id, uc_hex = parse_code(
- raw_code, key_prefixes, valid_keycodes
- )
+ code, macro_id, uc_hex = parse_code(raw_code, key_prefixes, valid_keycodes)
# TODO: line numbers for invalid codes
- err_msg = "Could not parse key '{}' on row {}".format(
- raw_code, row_index
- )
+ err_msg = "Could not parse key '{}' on row {}".format(raw_code, row_index)
assert code is not None, err_msg
# print(repr(raw_code), repr(code), macro_id, uc_hex)
if macro_id:
@@ -432,17 +420,14 @@ def parse_keymap(config, key_indexes, layer_lines, valid_keycodes):
def parse_keymaps(config, valid_keycodes):
keymaps = collections.OrderedDict()
- key_indexes = config.get(
- 'key_indexes', KEYBOARD_LAYOUTS[config['layout']]
- )
+ key_indexes = config.get('key_indexes', KEYBOARD_LAYOUTS[config['layout']])
# TODO: maybe validate key_indexes
for layer_name, layer_lines, in config['layer_lines'].items():
- keymaps[layer_name] = parse_keymap(
- config, key_indexes, layer_lines, valid_keycodes
- )
+ keymaps[layer_name] = parse_keymap(config, key_indexes, layer_lines, valid_keycodes)
return keymaps
+
# keymap.c output
USERCODE = """
@@ -453,7 +438,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -572,7 +557,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {{
}};
"""
-
UNICODE_MACRO_TEMPLATE = """
case {macro_id}:
unicode_action_function(0x{hi:02x}, 0x{lo:02x});
@@ -584,9 +568,7 @@ def unicode_macro_cases(config):
for macro_id, uc_hex in config['unicode_macros'].items():
hi = int(uc_hex, 16) >> 8
lo = int(uc_hex, 16) & 0xFF
- yield UNICODE_MACRO_TEMPLATE.format(
- macro_id=macro_id, hi=hi, lo=lo
- )
+ yield UNICODE_MACRO_TEMPLATE.format(macro_id=macro_id, hi=hi, lo=lo)
def iter_keymap_lines(keymap, row_indents=None):
diff --git a/layouts/community/ergodox/german-manuneo/keymap.c b/layouts/community/ergodox/german-manuneo/keymap.c
index 9b24df83db..b6217800c3 100644
--- a/layouts/community/ergodox/german-manuneo/keymap.c
+++ b/layouts/community/ergodox/german-manuneo/keymap.c
@@ -741,7 +741,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/german/keymap.c b/layouts/community/ergodox/german/keymap.c
index 99dda5185c..150aaf3a73 100644
--- a/layouts/community/ergodox/german/keymap.c
+++ b/layouts/community/ergodox/german/keymap.c
@@ -140,7 +140,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/haegin/keymap.c b/layouts/community/ergodox/haegin/keymap.c
index c3c2afecb8..cf5db6333b 100644
--- a/layouts/community/ergodox/haegin/keymap.c
+++ b/layouts/community/ergodox/haegin/keymap.c
@@ -226,7 +226,7 @@ qk_tap_dance_action_t tap_dance_actions[] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/ishigoya-jp/keymap.c b/layouts/community/ergodox/ishigoya-jp/keymap.c
index e9d89d1bbc..8fe2b7e415 100644
--- a/layouts/community/ergodox/ishigoya-jp/keymap.c
+++ b/layouts/community/ergodox/ishigoya-jp/keymap.c
@@ -109,7 +109,7 @@ static uint16_t start;
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
- *
+ *
* ,----------------------------------------------------. ,--------------------------------------------------.
* | En / 和 | | ^ | % | | |Selall| | Undo | | $ | @ | LT | UP | RT |
* |----------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
@@ -129,9 +129,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | Num | | Esc | | |
* `--------------------' `----------------------'
*
- *
+ *
* tmux prefix set to C-b
- *
+ *
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
@@ -175,9 +175,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | shift| fn |------| |------| |kazari|
* | | | Num | | | | |
* `--------------------' `--------------------'
- *
- *
- *
+ *
+ *
+ *
*/
[JP] = LAYOUT_ergodox(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
@@ -218,14 +218,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
- *
- *
- *
+ *
+ *
+ *
*/
[JPXON] = LAYOUT_ergodox(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, M(JPXE), KC_NO, M(JPXKE), KC_NO, KC_NO,
- KC_NO, KC_NO, KC_NO, M(JPXKA), KC_NO, KC_NO,
+ KC_NO, KC_NO, KC_NO, M(JPXKA), KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
@@ -261,14 +261,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
- *
- *
- *
+ *
+ *
+ *
*/
[JPKAZARI] = LAYOUT_ergodox(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, M(JPGO), M(JPZA), M(JPBE), M(JPGE), KC_NO,
- KC_NO, M(JPDO), M(JPJI), M(JPGA), M(JPGI), M(JPZU),
+ KC_NO, M(JPDO), M(JPJI), M(JPGA), M(JPGI), M(JPZU),
KC_NO, KC_NO, M(JPZO), M(JPBI), M(JPDI), KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
@@ -304,14 +304,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
- *
- *
- *
+ *
+ *
+ *
*/
[JPTOPROW] = LAYOUT_ergodox(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_E, KC_MINS, M(JPRE), KC_NO, KC_NO,
- KC_NO, M(JPRA), M(JPRI), M(JPNA), M(JPNO), M(JPMI),
+ KC_NO, M(JPRA), M(JPRI), M(JPNA), M(JPNO), M(JPMI),
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
@@ -348,14 +348,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
- *
- *
- *
+ *
+ *
+ *
*/
[JPTRKZ] = LAYOUT_ergodox(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, M(JPPE),KC_NO, KC_NO,
- KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
+ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, M(JPPI), KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
@@ -397,7 +397,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// left hand
KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_NO,
KC_NO, KC_NO, KC_NO, JP_DQUO, KC_RBRACKET, KC_BSPC, KC_SCLN,
- KC_NO, KC_NO, KC_SLSH, JP_PLUS, LSFT(KC_RBRACKET), JP_RCBR,
+ KC_NO, KC_NO, KC_SLSH, JP_PLUS, LSFT(KC_RBRACKET), JP_RCBR,
KC_NO, KC_NO, JP_ASTR, KC_MINS, LSFT(KC_8), LSFT(KC_9), JP_COLN,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_HASH,
KC_NO, KC_NO,
@@ -417,7 +417,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
-
+
// MACRO only works in this function
switch(id) {
case 0:
@@ -445,9 +445,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
}
}
break;
-
+
// kana macros start here
-
+
case JPVU:
if (record->event.pressed) {
return MACRO( I(1), T(V), T(U), END);
@@ -641,7 +641,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
case JPDI:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(I), END);
- }
+ }
break;
case JPZE:
if (record->event.pressed) {
@@ -838,9 +838,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO( I(1), T(B), T(U), END);
}
break;
-
+
// kana macros end here
-
+
break;
case SHIFT:
if (record->event.pressed) {
@@ -848,8 +848,8 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (layer_state == (1<<JPKAZARI)) {
layer_state = (1<<JPTOPROW)| (1<<JPTRKZ);
} else {
- layer_state = (1<<JPTOPROW);
- }
+ layer_state = (1<<JPTOPROW);
+ }
} else {
layer_state = (0<<JPTOPROW);
clear_keyboard_but_mods();
@@ -864,8 +864,8 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
if (layer_state == (1<<JPTOPROW)) {
layer_state = (1<<JPKAZARI)| (1<<JPTRKZ);
} else {
- layer_state = (1<<JPKAZARI);
- }
+ layer_state = (1<<JPKAZARI);
+ }
break;
} else {
layer_state = (0<<JPKAZARI);
@@ -874,7 +874,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO( T(ENTER), END);
}
}
- break;
+ break;
case JPFN:
if (record->event.pressed) {
start = timer_read();
@@ -917,7 +917,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
break;
*/
}
- return MACRO_NONE;
+ return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
@@ -927,15 +927,15 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
- uint8_t deflayer = biton32(default_layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
+ uint8_t deflayer = get_highest_layer(default_layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
-
-
+
+
switch (layer) {
case 0:
//none
diff --git a/layouts/community/ergodox/issmirnov/keymap.c b/layouts/community/ergodox/issmirnov/keymap.c
index b129148b08..2743a04e93 100644
--- a/layouts/community/ergodox/issmirnov/keymap.c
+++ b/layouts/community/ergodox/issmirnov/keymap.c
@@ -125,7 +125,7 @@ _______, _______, KC_LGUI
// called by QMK during key processing before the actual key event is handled. Useful for macros.
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (keycode) {
case TAP_TOG_LAYER:
process_tap_tog(_SYMB,record);
@@ -157,7 +157,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs constantly in the background, in a loop every 100ms or so.
// Best used for LED status output triggered when user isn't actively typing.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
if (layer == 0) {
// Set up LED indicators for stuck modifier keys.
// https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/report.h#L118
@@ -202,7 +202,7 @@ void matrix_scan_user(void) {
// only runs when when the layer is changed, good for updating LED's and clearing sticky state
layer_state_t layer_state_set_user(layer_state_t state) {
- uint8_t layer = biton32(state);
+ uint8_t layer = get_highest_layer(state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/italian/keymap.c b/layouts/community/ergodox/italian/keymap.c
index 64dd51db67..3a81cc213b 100644
--- a/layouts/community/ergodox/italian/keymap.c
+++ b/layouts/community/ergodox/italian/keymap.c
@@ -43,7 +43,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TT(SYMB),
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LALT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LALT,
MT(MOD_LGUI,KC_NONUS_BSLASH),KC_PPLS, KC_PMNS,KC_PAST,MT(MOD_LCTL,KC_PSLS),
KC_INS, KC_LGUI,
KC_HOME,
@@ -197,7 +197,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/j3rn/keymap.c b/layouts/community/ergodox/j3rn/keymap.c
index 5081ddf527..8ff8db2381 100644
--- a/layouts/community/ergodox/j3rn/keymap.c
+++ b/layouts/community/ergodox/j3rn/keymap.c
@@ -141,7 +141,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/jackhumbert/keymap.c b/layouts/community/ergodox/jackhumbert/keymap.c
index 9d357881e2..b6d1b33e33 100644
--- a/layouts/community/ergodox/jackhumbert/keymap.c
+++ b/layouts/community/ergodox/jackhumbert/keymap.c
@@ -23,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_NO, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, KC_P, KC_BSPC,
RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_SCLN, KC_QUOT,
KC_NO, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_ENT,
- MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT,
+ MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT,
RGB_TOG, RGB_HUI,
RGB_MOD,
M(2), KC_SPC,KC_SPC
@@ -32,7 +32,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS,
- KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
@@ -43,7 +43,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
KC_TRNS, KC_F12, KC_NO, KC_NO, KC_NO, RESET, KC_TRNS,
- KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,
+ KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
@@ -51,9 +51,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MDIA] = LAYOUT_ergodox(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_TRNS,
- KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
@@ -62,7 +62,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,
KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
KC_TRNS, KC_F12, KC_NO, KC_NO, KC_NO, RESET, KC_TRNS,
- KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,
+ KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
@@ -97,7 +97,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/jacobono/keymap.c b/layouts/community/ergodox/jacobono/keymap.c
index e97209fc84..7c5b914872 100644
--- a/layouts/community/ergodox/jacobono/keymap.c
+++ b/layouts/community/ergodox/jacobono/keymap.c
@@ -227,7 +227,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/jafo/keymap.c b/layouts/community/ergodox/jafo/keymap.c
index b8b8e63517..28c95d6540 100644
--- a/layouts/community/ergodox/jafo/keymap.c
+++ b/layouts/community/ergodox/jafo/keymap.c
@@ -139,7 +139,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/jgarr/keymap.c b/layouts/community/ergodox/jgarr/keymap.c
index ac4e562263..38eaa5fca0 100644
--- a/layouts/community/ergodox/jgarr/keymap.c
+++ b/layouts/community/ergodox/jgarr/keymap.c
@@ -138,7 +138,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/josh/keymap.c b/layouts/community/ergodox/josh/keymap.c
index 07ee97ec82..3f9d8779e1 100644
--- a/layouts/community/ergodox/josh/keymap.c
+++ b/layouts/community/ergodox/josh/keymap.c
@@ -188,7 +188,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/kastyle/keymap.c b/layouts/community/ergodox/kastyle/keymap.c
index c9789955b3..268080c7dc 100644
--- a/layouts/community/ergodox/kastyle/keymap.c
+++ b/layouts/community/ergodox/kastyle/keymap.c
@@ -1,5 +1,5 @@
/* Setup to approximate a Kinesis Advantage with an eye to use in a
- * Mac/OSX environment
+ * Mac/OSX environment
* This version adds a hand swap feature to flip the keyboard */
#include QMK_KEYBOARD_H
#include "debug.h"
@@ -143,7 +143,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/kejadlen/keymap.c b/layouts/community/ergodox/kejadlen/keymap.c
index 6ce209f806..92a667dec0 100644
--- a/layouts/community/ergodox/kejadlen/keymap.c
+++ b/layouts/community/ergodox/kejadlen/keymap.c
@@ -74,7 +74,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/kines-ish/keymap.c b/layouts/community/ergodox/kines-ish/keymap.c
index 2d1513667f..718bf6cee1 100644
--- a/layouts/community/ergodox/kines-ish/keymap.c
+++ b/layouts/community/ergodox/kines-ish/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/kristian/keymap.c b/layouts/community/ergodox/kristian/keymap.c
index 3fdccb790a..3f84823b99 100644
--- a/layouts/community/ergodox/kristian/keymap.c
+++ b/layouts/community/ergodox/kristian/keymap.c
@@ -35,7 +35,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/maz/keymap.c b/layouts/community/ergodox/maz/keymap.c
index 3244f2152d..4d313dee43 100644
--- a/layouts/community/ergodox/maz/keymap.c
+++ b/layouts/community/ergodox/maz/keymap.c
@@ -183,7 +183,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/mclennon_osx/keymap.c b/layouts/community/ergodox/mclennon_osx/keymap.c
index 72e9d505a1..ae67d8fb40 100644
--- a/layouts/community/ergodox/mclennon_osx/keymap.c
+++ b/layouts/community/ergodox/mclennon_osx/keymap.c
@@ -98,7 +98,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/meagerfindings/keymap.c b/layouts/community/ergodox/meagerfindings/keymap.c
index f4340b8e1b..c780c1a9fb 100644
--- a/layouts/community/ergodox/meagerfindings/keymap.c
+++ b/layouts/community/ergodox/meagerfindings/keymap.c
@@ -538,7 +538,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
};
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/msc/keymap.c b/layouts/community/ergodox/msc/keymap.c
index 5d9de3239b..62d18798dd 100644
--- a/layouts/community/ergodox/msc/keymap.c
+++ b/layouts/community/ergodox/msc/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/naps62/keymap.c b/layouts/community/ergodox/naps62/keymap.c
index 230b3376b2..fe6289097b 100644
--- a/layouts/community/ergodox/naps62/keymap.c
+++ b/layouts/community/ergodox/naps62/keymap.c
@@ -141,7 +141,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/neo2_on_qwertz_hardware/keymap.c b/layouts/community/ergodox/neo2_on_qwertz_hardware/keymap.c
index 7c91b3fbb0..7c57820c43 100644
--- a/layouts/community/ergodox/neo2_on_qwertz_hardware/keymap.c
+++ b/layouts/community/ergodox/neo2_on_qwertz_hardware/keymap.c
@@ -5,7 +5,7 @@
#define UM 0
#define L0 0 // layer_0
-#define L1 1 // layer_1
+#define L1 1 // layer_1
#define L2 2 // layer_2
#define L3 3 // layer_3
#define L4 4 // layer_4
@@ -344,7 +344,7 @@ void unicode_action_function(uint16_t hi, uint16_t lo) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/osx_de/keymap.c b/layouts/community/ergodox/osx_de/keymap.c
index 5c3d7e49ea..cbbfc42280 100644
--- a/layouts/community/ergodox/osx_de/keymap.c
+++ b/layouts/community/ergodox/osx_de/keymap.c
@@ -31,117 +31,117 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[BASE]=LAYOUT_ergodox(
//left half
- KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, M(M_CTL_SFT_HASH),
- KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, KC_LGUI,
- KC_LALT, DE_A, DE_S, DE_D, DE_F, DE_G,
- KC_LSFT, CTL_T(DE_Y), DE_X, DE_C, DE_V, DE_B, KC_LALT,
- LT(SYMB,DE_LABK), M(M_DE_CIRC_CTRLCMD), M(M_DE_PLUS_CTRLALT), KC_UP, KC_DOWN,
- M(M_MEH_SH_ACUT), TG(MDIA),
- KC_HOME,
- KC_BSPC, KC_DEL, LT(SMLY,KC_END),
+ KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, M(M_CTL_SFT_HASH),
+ KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, KC_LGUI,
+ KC_LALT, DE_A, DE_S, DE_D, DE_F, DE_G,
+ KC_LSFT, CTL_T(DE_Y), DE_X, DE_C, DE_V, DE_B, KC_LALT,
+ LT(SYMB,DE_LABK), M(M_DE_CIRC_CTRLCMD), M(M_DE_PLUS_CTRLALT), KC_UP, KC_DOWN,
+ M(M_MEH_SH_ACUT), TG(MDIA),
+ KC_HOME,
+ KC_BSPC, KC_DEL, LT(SMLY,KC_END),
//right half
- M(M_CTL_SFT_HASH), DE_6, DE_7, DE_8, DE_9, DE_0, DE_SS,
- KC_RGUI, DE_Z, DE_U, DE_I, DE_O, DE_P, DE_UDIA,
- DE_H, DE_J, DE_K, DE_L, DE_ODIA, ALT_T(DE_ADIA),
- KC_RALT, DE_N, DE_M, DE_COMM, DE_DOT, CTL_T(DE_MINS), KC_RSFT,
- KC_LEFT, KC_RIGHT, LGUI(KC_LSFT), LALT(KC_LSFT), LT(SYMB,DE_PLUS),
- TG(NUMB), ALL_T(DE_ACUT),
- KC_PGUP,
+ M(M_CTL_SFT_HASH), DE_6, DE_7, DE_8, DE_9, DE_0, DE_SS,
+ KC_RGUI, DE_Z, DE_U, DE_I, DE_O, DE_P, DE_UDIA,
+ DE_H, DE_J, DE_K, DE_L, DE_ODIA, ALT_T(DE_ADIA),
+ KC_RALT, DE_N, DE_M, DE_COMM, DE_DOT, CTL_T(DE_MINS), KC_RSFT,
+ KC_LEFT, KC_RIGHT, LGUI(KC_LSFT), LALT(KC_LSFT), LT(SYMB,DE_PLUS),
+ TG(NUMB), ALL_T(DE_ACUT),
+ KC_PGUP,
KC_PGDN, KC_ENT, KC_SPC),
[SYMB]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
- KC_TRNS, DE_LABK, DE_RABK, DE_EXLM, DE_QUES, KC_TRNS, KC_TRNS,
- KC_TRNS, DE_HASH, DE_DLR, DE_BSLS, DE_SLSH, KC_DOT,
- KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, DE_PIPE, DE_TILD, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
+ KC_TRNS, DE_LABK, DE_RABK, DE_EXLM, DE_QUES, KC_TRNS, KC_TRNS,
+ KC_TRNS, DE_HASH, DE_DLR, DE_BSLS, DE_SLSH, KC_DOT,
+ KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, DE_PIPE, DE_TILD, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_DEL, KC_TRNS,
//right half
- M(M_TOGGLE_5), KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, LALT(LSFT(KC_7)), LALT(KC_5), LALT(KC_6), DE_LABK, DE_RABK, DE_EXLM,
- DE_SLSH, DE_LPRN, DE_RPRN, LALT(KC_8), LALT(KC_9), DE_HASH,
- KC_TRNS, DE_PIPE, DE_TILD, DE_CIRC, KC_UP, DE_MINS, LSFT(KC_4),
- DE_QUOT, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS,
- KC_F13, KC_F12,
- KC_F14,
+ M(M_TOGGLE_5), KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, LALT(LSFT(KC_7)), LALT(KC_5), LALT(KC_6), DE_LABK, DE_RABK, DE_EXLM,
+ DE_SLSH, DE_LPRN, DE_RPRN, LALT(KC_8), LALT(KC_9), DE_HASH,
+ KC_TRNS, DE_PIPE, DE_TILD, DE_CIRC, KC_UP, DE_MINS, LSFT(KC_4),
+ DE_QUOT, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS,
+ KC_F13, KC_F12,
+ KC_F14,
KC_F15, KC_TRNS, KC_TRNS),
[MDIA]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D,
- KC_TRNS, KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D,
+ KC_TRNS, KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_VOLU, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_VOLD, KC_TRNS, KC_MPRV, KC_MNXT, KC_UP, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_VOLU, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_VOLD, KC_TRNS, KC_MPRV, KC_MNXT, KC_UP, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK),
[SMLY]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- M(SM_SMILE), M(SM_SMIRK), M(SM_LAUGH), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, M(SM_FROWN), M(SM_SAD), M(SM_CRY), KC_TRNS, KC_TRNS, KC_TRNS,
- M(SM_HEART), M(SM_KISS), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ M(SM_SMILE), M(SM_SMIRK), M(SM_LAUGH), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, M(SM_FROWN), M(SM_SAD), M(SM_CRY), KC_TRNS, KC_TRNS, KC_TRNS,
+ M(SM_HEART), M(SM_KISS), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
[NUMB]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, KC_UP, KC_7, KC_8, KC_9, LSFT(KC_RBRC), KC_F12,
- KC_DOWN, KC_4, KC_5, KC_6, KC_RBRC, DE_MINS,
- KC_TRNS, LSFT(KC_6), KC_1, KC_2, KC_3, LSFT(KC_7), KC_TRNS,
- KC_0, KC_DOT, KC_COMM, DE_EQL, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, KC_UP, KC_7, KC_8, KC_9, LSFT(KC_RBRC), KC_F12,
+ KC_DOWN, KC_4, KC_5, KC_6, KC_RBRC, DE_MINS,
+ KC_TRNS, LSFT(KC_6), KC_1, KC_2, KC_3, LSFT(KC_7), KC_TRNS,
+ KC_0, KC_DOT, KC_COMM, DE_EQL, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
[EGOS]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_LSFT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_LCTL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_F1, KC_F2,
- KC_F3,
- KC_SPC, KC_LCTL, KC_F4,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_LSFT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_LCTL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_F1, KC_F2,
+ KC_F3,
+ KC_SPC, KC_LCTL, KC_F4,
//right half
- M(M_TOGGLE_5), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ M(M_TOGGLE_5), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
};
@@ -318,7 +318,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
-uint8_t layer = biton32(layer_state);
+uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -328,22 +328,22 @@ switch (layer) {
case SYMB:
ergodox_right_led_1_on();
-
-
+
+
break;
case MDIA:
-
+
ergodox_right_led_2_on();
-
+
break;
case SMLY:
-
-
+
+
ergodox_right_led_3_on();
break;
case NUMB:
ergodox_right_led_1_on();
-
+
ergodox_right_led_3_on();
break;
case EGOS:
@@ -357,4 +357,3 @@ break;
}
};
-
diff --git a/layouts/community/ergodox/osx_de_adnw_koy/keymap.c b/layouts/community/ergodox/osx_de_adnw_koy/keymap.c
index b8ffc2e51f..cd09d066a6 100644
--- a/layouts/community/ergodox/osx_de_adnw_koy/keymap.c
+++ b/layouts/community/ergodox/osx_de_adnw_koy/keymap.c
@@ -27,105 +27,105 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[BASE]=LAYOUT_ergodox(
//left half
- KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LCTL,
- KC_TAB, KC_K, KC_DOT, KC_O, KC_COMM, KC_Z, KC_LGUI,
- TG(QWERTZ), KC_H, KC_A, KC_E, KC_I, KC_U,
- KC_LSFT, CTL_T(KC_X), KC_Q, DE_ADIA, DE_UDIA, DE_ODIA, KC_LALT,
- LT(SYMB,KC_GRV), DE_LABK, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
- TG(MDIA), MEH_T(LSFT(DE_ACUT)),
- KC_HOME,
- KC_BSPC, KC_DEL, KC_END,
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LCTL,
+ KC_TAB, KC_K, KC_DOT, KC_O, KC_COMM, KC_Z, KC_LGUI,
+ TG(QWERTZ), KC_H, KC_A, KC_E, KC_I, KC_U,
+ KC_LSFT, CTL_T(KC_X), KC_Q, DE_ADIA, DE_UDIA, DE_ODIA, KC_LALT,
+ LT(SYMB,KC_GRV), DE_LABK, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
+ TG(MDIA), MEH_T(LSFT(DE_ACUT)),
+ KC_HOME,
+ KC_BSPC, KC_DEL, KC_END,
//right half
- KC_RCTL, KC_6, KC_7, KC_8, KC_9, KC_0, DE_MINS,
- KC_RGUI, KC_V, KC_G, KC_C, KC_L, KC_MINS, KC_Y,
- KC_D, KC_T, KC_R, KC_N, KC_S, LT(MDIA,KC_F),
- KC_RALT, KC_B, KC_P, KC_W, KC_M, CTL_T(KC_J), KC_RSFT,
- KC_UP, KC_DOWN, LGUI(KC_LSFT), KC_RBRC, LT(SYMB,KC_BSLS),
- ALL_T(DE_ACUT), TG(NUMB),
- KC_PGUP,
+ KC_RCTL, KC_6, KC_7, KC_8, KC_9, KC_0, DE_MINS,
+ KC_RGUI, KC_V, KC_G, KC_C, KC_L, KC_MINS, KC_Y,
+ KC_D, KC_T, KC_R, KC_N, KC_S, LT(MDIA,KC_F),
+ KC_RALT, KC_B, KC_P, KC_W, KC_M, CTL_T(KC_J), KC_RSFT,
+ KC_UP, KC_DOWN, LGUI(KC_LSFT), KC_RBRC, LT(SYMB,KC_BSLS),
+ ALL_T(DE_ACUT), TG(NUMB),
+ KC_PGUP,
KC_PGDN, KC_ENT, KC_SPC),
[SYMB]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
- KC_TRNS, KC_GRV, LSFT(KC_GRV), DE_EXLM, DE_QUES, KC_TRNS, KC_TRNS,
- KC_TRNS, DE_HASH, DE_DLR, LALT(LSFT(KC_7)), DE_SLSH, KC_DOT,
- KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, LALT(KC_7), LALT(KC_N), KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
+ KC_TRNS, KC_GRV, LSFT(KC_GRV), DE_EXLM, DE_QUES, KC_TRNS, KC_TRNS,
+ KC_TRNS, DE_HASH, DE_DLR, LALT(LSFT(KC_7)), DE_SLSH, KC_DOT,
+ KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, LALT(KC_7), LALT(KC_N), KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_DEL, KC_TRNS,
//right half
- KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, LALT(LSFT(KC_7)), LALT(KC_5), LALT(KC_6), LALT(KC_7), DE_HASH, KC_F12,
- DE_SLSH, DE_LPRN, DE_RPRN, LALT(KC_8), LALT(KC_9), KC_TRNS,
- KC_TRNS, DE_AMPR, KC_GRV, LSFT(KC_GRV), DE_DQUO, DE_QUOT, DE_QUES,
- KC_TRNS, KC_DOT, KC_EXLM, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, LALT(LSFT(KC_7)), LALT(KC_5), LALT(KC_6), LALT(KC_7), DE_HASH, KC_F12,
+ DE_SLSH, DE_LPRN, DE_RPRN, LALT(KC_8), LALT(KC_9), KC_TRNS,
+ KC_TRNS, DE_AMPR, KC_GRV, LSFT(KC_GRV), DE_DQUO, DE_QUOT, DE_QUES,
+ KC_TRNS, KC_DOT, KC_EXLM, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
[MDIA]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
- KC_TRNS, KC_WH_L, KC_WH_U, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
+ KC_TRNS, KC_WH_L, KC_WH_U, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_MUTE, KC_MPRV, KC_MNXT, KC_UP, KC_TRNS,
- KC_VOLU, KC_VOLD, KC_LEFT, KC_DOWN, KC_RIGHT,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MUTE, KC_MPRV, KC_MNXT, KC_UP, KC_TRNS,
+ KC_VOLU, KC_VOLD, KC_LEFT, KC_DOWN, KC_RIGHT,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK),
[QWERTZ]=LAYOUT_ergodox(
//left half
- KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, LGUI(KC_V),
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LGUI,
- KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G,
- KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_LALT,
- LT(SYMB,KC_GRV), DE_LABK, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
- KC_TRNS, MEH_T(LSFT(DE_ACUT)),
- KC_HOME,
- KC_BSPC, KC_DEL, KC_END,
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, LGUI(KC_V),
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LGUI,
+ KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G,
+ KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_LALT,
+ LT(SYMB,KC_GRV), DE_LABK, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
+ KC_TRNS, MEH_T(LSFT(DE_ACUT)),
+ KC_HOME,
+ KC_BSPC, KC_DEL, KC_END,
//right half
- LGUI(KC_C), KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
- KC_RGUI, KC_Y, KC_U, KC_I, KC_O, KC_P, DE_UDIA,
- KC_H, KC_J, KC_K, KC_L, KC_SCLN, LT(MDIA,DE_ADIA),
- KC_RALT, KC_N, KC_M, KC_COMM, KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
- KC_UP, KC_DOWN, LGUI(KC_LSFT), KC_RBRC, LT(SYMB,KC_BSLS),
- ALL_T(DE_ACUT), KC_TRNS,
- KC_PGUP,
+ LGUI(KC_C), KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
+ KC_RGUI, KC_Y, KC_U, KC_I, KC_O, KC_P, DE_UDIA,
+ KC_H, KC_J, KC_K, KC_L, KC_SCLN, LT(MDIA,DE_ADIA),
+ KC_RALT, KC_N, KC_M, KC_COMM, KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
+ KC_UP, KC_DOWN, LGUI(KC_LSFT), KC_RBRC, LT(SYMB,KC_BSLS),
+ ALL_T(DE_ACUT), KC_TRNS,
+ KC_PGUP,
KC_PGDN, KC_ENT, KC_SPC),
[NUMB]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, KC_UP, KC_7, KC_8, KC_9, LSFT(KC_RBRC), KC_F12,
- KC_DOWN, KC_4, KC_5, KC_6, KC_RBRC, KC_TRNS,
- KC_TRNS, LSFT(KC_6), KC_1, KC_2, KC_3, LSFT(KC_7), KC_TRNS,
- KC_0, KC_DOT, KC_0, KC_EQL, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, KC_UP, KC_7, KC_8, KC_9, LSFT(KC_RBRC), KC_F12,
+ KC_DOWN, KC_4, KC_5, KC_6, KC_RBRC, KC_TRNS,
+ KC_TRNS, LSFT(KC_6), KC_1, KC_2, KC_3, LSFT(KC_7), KC_TRNS,
+ KC_0, KC_DOT, KC_0, KC_EQL, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
-uint8_t layer = biton32(layer_state);
+uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -139,4 +139,3 @@ break;
}
};
-
diff --git a/layouts/community/ergodox/osx_de_experimental/keymap.c b/layouts/community/ergodox/osx_de_experimental/keymap.c
index 8228b5e371..faf238726f 100644
--- a/layouts/community/ergodox/osx_de_experimental/keymap.c
+++ b/layouts/community/ergodox/osx_de_experimental/keymap.c
@@ -66,315 +66,315 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/**
* Layer: BASE
-* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
-* | ESC | 1 | 2 | 3 | 4 | 5 | Hold or toggle | | Hold or toggle | 6 | 7 | 8 | 9 | 0 | ß |
-* | | | | | | | Layer NUMB | | Layer MDIA | | | | | | |
-* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
-* | TAB | Q | W | E | R | T | Cmd | | Cmd | Z | U | I | O | P | Ü |
-* | | | | | | | | | | | | | | | |
-* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/\-------------------\ \-------------------\/-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
-* | Alt | A | S | D | F | G | | H | J | K | L | Ö | Ä |
-* | | | | | | | | | | | | | ALT |
-* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
-* | Shift | Y | X | C | V | B | Alt | | Alt | N | M | , | . | - | Shift |
-* | | Ctrl | | | | | | | | | | | | Ctrl | |
-* \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\ \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\
-*
-*
-* /-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------/
-* | < | LongPress / Type | LongPress / Type | Shift+Ctrl | Type | | # | ACUT | CMD+Shift | ALT+Shift | + |
-* | SYMB | DE_CIRC_CTRLCMD | DE_PLUS_CTRAlt | | Toggle SMLY | | Meh | Hyper | | | SYMB |
-* \-------------------\\-------------------\\-------------------\\-------------------\/-------------------//-------------------/ /-------------------//-------------------/ \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\
-* | HOME | END | | LEFT | RIGHT |
-* | | | | | |
-* \-------------------\/-------------------/ /-------------------/\-------------------\
-* | PGUP | | UP |
-* | | | |
-* /-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------/
-* | BSPC | DEL | PGDN | | DOWN | ENT | SPC |
-* | | | | | | | |
-* \-------------------\\-------------------\\-------------------\ \-------------------\\-------------------\\-------------------\
-*
-*
+* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
+* | ESC | 1 | 2 | 3 | 4 | 5 | Hold or toggle | | Hold or toggle | 6 | 7 | 8 | 9 | 0 | ß |
+* | | | | | | | Layer NUMB | | Layer MDIA | | | | | | |
+* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
+* | TAB | Q | W | E | R | T | Cmd | | Cmd | Z | U | I | O | P | Ü |
+* | | | | | | | | | | | | | | | |
+* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/\-------------------\ \-------------------\/-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
+* | Alt | A | S | D | F | G | | H | J | K | L | Ö | Ä |
+* | | | | | | | | | | | | | ALT |
+* /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------//-------------------//-------------------/
+* | Shift | Y | X | C | V | B | Alt | | Alt | N | M | , | . | - | Shift |
+* | | Ctrl | | | | | | | | | | | | Ctrl | |
+* \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\ \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\\-------------------\
+*
+*
+* /-------------------//-------------------//-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------//-------------------//-------------------/
+* | < | LongPress / Type | LongPress / Type | Shift+Ctrl | Type | | # | ACUT | CMD+Shift | ALT+Shift | + |
+* | SYMB | DE_CIRC_CTRLCMD | DE_PLUS_CTRAlt | | Toggle SMLY | | Meh | Hyper | | | SYMB |
+* \-------------------\\-------------------\\-------------------\\-------------------\/-------------------//-------------------/ /-------------------//-------------------/ \-------------------\\-------------------\\-------------------\\-------------------\\-------------------\
+* | HOME | END | | LEFT | RIGHT |
+* | | | | | |
+* \-------------------\/-------------------/ /-------------------/\-------------------\
+* | PGUP | | UP |
+* | | | |
+* /-------------------//-------------------//-------------------/ /-------------------//-------------------//-------------------/
+* | BSPC | DEL | PGDN | | DOWN | ENT | SPC |
+* | | | | | | | |
+* \-------------------\\-------------------\\-------------------\ \-------------------\\-------------------\\-------------------\
+*
+*
**/
[BASE]=LAYOUT_ergodox(
//left half
- KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, M(TGH_NUM),
- KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, KC_LGUI,
- KC_LALT, DE_A, DE_S, DE_D, DE_F, DE_G,
- KC_LSFT, CTL_T(DE_Y), DE_X, DE_C, DE_V, DE_B, KC_LALT,
- LT(SYMB,DE_LABK), M(M_DE_CIRC_CTRLCMD), M(M_DE_PLUS_CTRLALT), LSFT(KC_LCTRL), M(SMLY_TOG_QUOT),
- KC_HOME, KC_END,
- KC_PGUP,
- KC_BSPC, KC_DEL, KC_PGDN,
+ KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, M(TGH_NUM),
+ KC_TAB, DE_Q, DE_W, DE_E, DE_R, DE_T, KC_LGUI,
+ KC_LALT, DE_A, DE_S, DE_D, DE_F, DE_G,
+ KC_LSFT, CTL_T(DE_Y), DE_X, DE_C, DE_V, DE_B, KC_LALT,
+ LT(SYMB,DE_LABK), M(M_DE_CIRC_CTRLCMD), M(M_DE_PLUS_CTRLALT), LSFT(KC_LCTRL), M(SMLY_TOG_QUOT),
+ KC_HOME, KC_END,
+ KC_PGUP,
+ KC_BSPC, KC_DEL, KC_PGDN,
//right half
- M(TOG_HLD_MDIA), DE_6, DE_7, DE_8, DE_9, DE_0, DE_SS,
- KC_RGUI, DE_Z, DE_U, DE_I, DE_O, DE_P, DE_UDIA,
- DE_H, DE_J, DE_K, DE_L, DE_ODIA, ALT_T(DE_ADIA),
- KC_RALT, DE_N, DE_M, DE_COMM, DE_DOT, CTL_T(DE_MINS), KC_RSFT,
- MEH_T(DE_HASH), ALL_T(DE_ACUT), LGUI(KC_LSFT), LALT(KC_LSFT), LT(SYMB,DE_PLUS),
- KC_LEFT, KC_RIGHT,
- KC_UP,
+ M(TOG_HLD_MDIA), DE_6, DE_7, DE_8, DE_9, DE_0, DE_SS,
+ KC_RGUI, DE_Z, DE_U, DE_I, DE_O, DE_P, DE_UDIA,
+ DE_H, DE_J, DE_K, DE_L, DE_ODIA, ALT_T(DE_ADIA),
+ KC_RALT, DE_N, DE_M, DE_COMM, DE_DOT, CTL_T(DE_MINS), KC_RSFT,
+ MEH_T(DE_HASH), ALL_T(DE_ACUT), LGUI(KC_LSFT), LALT(KC_LSFT), LT(SYMB,DE_PLUS),
+ KC_LEFT, KC_RIGHT,
+ KC_UP,
KC_DOWN, KC_ENT, KC_SPC),
/**
* Layer: SYMB
-* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
-* | APPLICATION| F1 | F2 | F3 | F4 | F5 | F5 | | F6 | F6 | F7 | F8 | F9 | F10 | F11 |
-* | | | | | | | | | | | | | | | |
-* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
-* | | < | > | ! | ? | | | | | \ | [ | ] | < | > | ! |
-* | | | | | | | | | | | | | | | |
-* /-----------//-----------//-----------//-----------//-----------//-----------/\-----------\ \-----------\/-----------//-----------//-----------//-----------//-----------//-----------/
-* | | # | $ | \ | / | . | | / | ( | ) | { | } | # |
-* | | | | | | | | | | | | | |
-* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
-* | | | < | % | | | ~ | | | | | | ~ | | | | |
-* | | | | | | | | | | | | | | | |
-* \-----------\\-----------\\-----------\\-----------\\-----------\\-----------\\-----------\ \-----------\\-----------\\-----------\\-----------\\-----------\\-----------\\-----------\
-*
-*
-* /-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------/
-* | | | | | | | ' | DQOT | | Toggle 5 | |
-* | | | | | | | | | | | |
-* \-----------\\-----------\\-----------\\-----------\/-----------//-----------/ /-----------//-----------/ \-----------\\-----------\\-----------\\-----------\\-----------\
-* | | | | F13 | F12 |
-* | | | | | |
-* \-----------\/-----------/ /-----------/\-----------\
-* | | | F14 |
-* | | | |
-* /-----------//-----------//-----------/ /-----------//-----------//-----------/
-* | | DEL | | | F15 | | |
-* | | | | | | | |
-* \-----------\\-----------\\-----------\ \-----------\\-----------\\-----------\
-*
-*
+* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
+* | APPLICATION| F1 | F2 | F3 | F4 | F5 | F5 | | F6 | F6 | F7 | F8 | F9 | F10 | F11 |
+* | | | | | | | | | | | | | | | |
+* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
+* | | < | > | ! | ? | | | | | \ | [ | ] | < | > | ! |
+* | | | | | | | | | | | | | | | |
+* /-----------//-----------//-----------//-----------//-----------//-----------/\-----------\ \-----------\/-----------//-----------//-----------//-----------//-----------//-----------/
+* | | # | $ | \ | / | . | | / | ( | ) | { | } | # |
+* | | | | | | | | | | | | | |
+* /-----------//-----------//-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------//-----------//-----------/
+* | | | < | % | | | ~ | | | | | | ~ | | | | |
+* | | | | | | | | | | | | | | | |
+* \-----------\\-----------\\-----------\\-----------\\-----------\\-----------\\-----------\ \-----------\\-----------\\-----------\\-----------\\-----------\\-----------\\-----------\
+*
+*
+* /-----------//-----------//-----------//-----------//-----------/ /-----------//-----------//-----------//-----------//-----------/
+* | | | | | | | ' | DQOT | | Toggle 5 | |
+* | | | | | | | | | | | |
+* \-----------\\-----------\\-----------\\-----------\/-----------//-----------/ /-----------//-----------/ \-----------\\-----------\\-----------\\-----------\\-----------\
+* | | | | F13 | F12 |
+* | | | | | |
+* \-----------\/-----------/ /-----------/\-----------\
+* | | | F14 |
+* | | | |
+* /-----------//-----------//-----------/ /-----------//-----------//-----------/
+* | | DEL | | | F15 | | |
+* | | | | | | | |
+* \-----------\\-----------\\-----------\ \-----------\\-----------\\-----------\
+*
+*
**/
[SYMB]=LAYOUT_ergodox(
//left half
- KC_APPLICATION, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F5,
- KC_TRNS, DE_LABK, DE_RABK, DE_EXLM, DE_QST, KC_TRNS, KC_TRNS,
- KC_TRNS, DE_HASH, DE_DLR, DE_BSLS, DE_SLSH, KC_DOT,
- KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, DE_PIPE, DE_TILD, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_DEL, KC_TRNS,
+ KC_APPLICATION, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F5,
+ KC_TRNS, DE_LABK, DE_RABK, DE_EXLM, DE_QST, KC_TRNS, KC_TRNS,
+ KC_TRNS, DE_HASH, DE_DLR, DE_BSLS, DE_SLSH, KC_DOT,
+ KC_TRNS, KC_TRNS, DE_LABK, DE_PERC, DE_PIPE, DE_TILD, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_DEL, KC_TRNS,
//right half
- KC_F6, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, DE_BSLS, DE_LBRC, DE_RBRC, DE_LABK, DE_RABK, DE_EXLM,
- DE_SLSH, DE_LPRN, DE_RPRN, DE_LCBR, DE_RCBR, DE_HASH,
- KC_TRNS, DE_PIPE, DE_TILD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- DE_QUOT, DE_DQUO, KC_TRNS, M(M_TOGGLE_5), KC_TRNS,
- KC_F13, KC_F12,
- KC_F14,
+ KC_F6, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, DE_BSLS, DE_LBRC, DE_RBRC, DE_LABK, DE_RABK, DE_EXLM,
+ DE_SLSH, DE_LPRN, DE_RPRN, DE_LCBR, DE_RCBR, DE_HASH,
+ KC_TRNS, DE_PIPE, DE_TILD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ DE_QUOT, DE_DQUO, KC_TRNS, M(M_TOGGLE_5), KC_TRNS,
+ KC_F13, KC_F12,
+ KC_F14,
KC_F15, KC_TRNS, KC_TRNS),
/**
* Layer: MDIA
-* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
-* | | | | | | | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
-* | | | BTN1 | U | BTN2 | U | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* /-----//-----//-----//-----//-----//-----/\-----\ \-----\/-----//-----//-----//-----//-----//-----/
-* | | | L | D | R | D | | | | | | | |
-* | | | | | | | | | | | | | |
-* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
-* | | | L | D | R | BTN3 | | | | | | | | UP | |
-* | | | | | | | | | | | | | | | |
-* \-----\\-----\\-----\\-----\\-----\\-----\\-----\ \-----\\-----\\-----\\-----\\-----\\-----\\-----\
-*
-*
-* /-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----/
-* | | | | | | | | | LEFT | DOWN | RIGHT|
-* | | | | | | | | | | | |
-* \-----\\-----\\-----\\-----\/-----//-----/ /-----//-----/ \-----\\-----\\-----\\-----\\-----\
-* | | | | MPRV | MNXT |
-* | | | | | |
-* \-----\/-----/ /-----/\-----\
-* | | | VOLU |
-* | | | |
-* /-----//-----//-----/ /-----//-----//-----/
-* | | | | | VOLD | MUTE | MPLY |
-* | | | | | | | |
-* \-----\\-----\\-----\ \-----\\-----\\-----\
-*
-*
+* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
+* | | | | | | | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
+* | | | BTN1 | U | BTN2 | U | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* /-----//-----//-----//-----//-----//-----/\-----\ \-----\/-----//-----//-----//-----//-----//-----/
+* | | | L | D | R | D | | | | | | | |
+* | | | | | | | | | | | | | |
+* /-----//-----//-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----//-----//-----/
+* | | | L | D | R | BTN3 | | | | | | | | UP | |
+* | | | | | | | | | | | | | | | |
+* \-----\\-----\\-----\\-----\\-----\\-----\\-----\ \-----\\-----\\-----\\-----\\-----\\-----\\-----\
+*
+*
+* /-----//-----//-----//-----//-----/ /-----//-----//-----//-----//-----/
+* | | | | | | | | | LEFT | DOWN | RIGHT|
+* | | | | | | | | | | | |
+* \-----\\-----\\-----\\-----\/-----//-----/ /-----//-----/ \-----\\-----\\-----\\-----\\-----\
+* | | | | MPRV | MNXT |
+* | | | | | |
+* \-----\/-----/ /-----/\-----\
+* | | | VOLU |
+* | | | |
+* /-----//-----//-----/ /-----//-----//-----/
+* | | | | | VOLD | MUTE | MPLY |
+* | | | | | | | |
+* \-----\\-----\\-----\ \-----\\-----\\-----\
+*
+*
**/
[MDIA]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D,
- KC_TRNS, KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D,
+ KC_TRNS, KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_R, KC_BTN3, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT,
- KC_MPRV, KC_MNXT,
- KC_VOLU,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT,
+ KC_MPRV, KC_MNXT,
+ KC_VOLU,
KC_VOLD, KC_MUTE, KC_MPLY),
/**
* Layer: SMLY
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | Typing | Typing | Typing | | | | |
-* | | | | | | | | | SM_SMILE| SM_SMIRK| SM_LAUGH| | | | |
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | | Typing | Typing | Typing | | | |
-* | | | | | | | | | | SM_FROWN| SM_SAD | SM_CRY | | | |
-* /--------//--------//--------//--------//--------//--------/\--------\ \--------\/--------//--------//--------//--------//--------//--------/
-* | | | | | | | | Typing | Typing | | | | |
-* | | | | | | | | SM_HEART| SM_KISS | | | | |
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* \--------\\--------\\--------\\--------\\--------\\--------\\--------\ \--------\\--------\\--------\\--------\\--------\\--------\\--------\
-*
-*
-* /--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------/
-* | | | | | | | | | | | |
-* | | | | | | | | | | | |
-* \--------\\--------\\--------\\--------\/--------//--------/ /--------//--------/ \--------\\--------\\--------\\--------\\--------\
-* | | | | | |
-* | | | | | |
-* \--------\/--------/ /--------/\--------\
-* | | | |
-* | | | |
-* /--------//--------//--------/ /--------//--------//--------/
-* | | | | | | | |
-* | | | | | | | |
-* \--------\\--------\\--------\ \--------\\--------\\--------\
-*
-*
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | Typing | Typing | Typing | | | | |
+* | | | | | | | | | SM_SMILE| SM_SMIRK| SM_LAUGH| | | | |
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | | Typing | Typing | Typing | | | |
+* | | | | | | | | | | SM_FROWN| SM_SAD | SM_CRY | | | |
+* /--------//--------//--------//--------//--------//--------/\--------\ \--------\/--------//--------//--------//--------//--------//--------/
+* | | | | | | | | Typing | Typing | | | | |
+* | | | | | | | | SM_HEART| SM_KISS | | | | |
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* \--------\\--------\\--------\\--------\\--------\\--------\\--------\ \--------\\--------\\--------\\--------\\--------\\--------\\--------\
+*
+*
+* /--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------/
+* | | | | | | | | | | | |
+* | | | | | | | | | | | |
+* \--------\\--------\\--------\\--------\/--------//--------/ /--------//--------/ \--------\\--------\\--------\\--------\\--------\
+* | | | | | |
+* | | | | | |
+* \--------\/--------/ /--------/\--------\
+* | | | |
+* | | | |
+* /--------//--------//--------/ /--------//--------//--------/
+* | | | | | | | |
+* | | | | | | | |
+* \--------\\--------\\--------\ \--------\\--------\\--------\
+*
+*
**/
[SMLY]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- M(SM_SMILE), M(SM_SMIRK), M(SM_LAUGH), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, M(SM_FROWN), M(SM_SAD), M(SM_CRY), KC_TRNS, KC_TRNS, KC_TRNS,
- M(SM_HEART), M(SM_KISS), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ M(SM_SMILE), M(SM_SMIRK), M(SM_LAUGH), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, M(SM_FROWN), M(SM_SAD), M(SM_CRY), KC_TRNS, KC_TRNS, KC_TRNS,
+ M(SM_HEART), M(SM_KISS), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
/**
* Layer: NUMB
-* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
-* | | | | | | | | | | F6 | F7 | F8 | F9 | F10 | F11 |
-* | | | | | | | | | | | | | | | |
-* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
-* | | | | UP | | | | | | / | 7 | 8 | 9 | * | F12 |
-* | | | | | | | | | | | | | | | |
-* /----//----//----//----//----//----/\----\ \----\/----//----//----//----//----//----/
-* | | | LEFT| DOWN| RGHT| | | / | 4 | 5 | 6 | + | - |
-* | | | | | | | | | | | | | |
-* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
-* | | | | | | | | | | % | 1 | 2 | 3 | | |
-* | | | | | | | | | | | | | | | |
-* \----\\----\\----\\----\\----\\----\\----\ \----\\----\\----\\----\\----\\----\\----\
-*
-*
-* /----//----//----//----//----/ /----//----//----//----//----/
-* | | | | | | | 0 | . | , | = | |
-* | | | | | | | | | | | |
-* \----\\----\\----\\----\/----//----/ /----//----/ \----\\----\\----\\----\\----\
-* | | | | | |
-* | | | | | |
-* \----\/----/ /----/\----\
-* | | | |
-* | | | |
-* /----//----//----/ /----//----//----/
-* | | | | | | | |
-* | | | | | | | |
-* \----\\----\\----\ \----\\----\\----\
-*
-*
+* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
+* | | | | | | | | | | F6 | F7 | F8 | F9 | F10 | F11 |
+* | | | | | | | | | | | | | | | |
+* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
+* | | | | UP | | | | | | / | 7 | 8 | 9 | * | F12 |
+* | | | | | | | | | | | | | | | |
+* /----//----//----//----//----//----/\----\ \----\/----//----//----//----//----//----/
+* | | | LEFT| DOWN| RGHT| | | / | 4 | 5 | 6 | + | - |
+* | | | | | | | | | | | | | |
+* /----//----//----//----//----//----//----/ /----//----//----//----//----//----//----/
+* | | | | | | | | | | % | 1 | 2 | 3 | | |
+* | | | | | | | | | | | | | | | |
+* \----\\----\\----\\----\\----\\----\\----\ \----\\----\\----\\----\\----\\----\\----\
+*
+*
+* /----//----//----//----//----/ /----//----//----//----//----/
+* | | | | | | | 0 | . | , | = | |
+* | | | | | | | | | | | |
+* \----\\----\\----\\----\/----//----/ /----//----/ \----\\----\\----\\----\\----\
+* | | | | | |
+* | | | | | |
+* \----\/----/ /----/\----\
+* | | | |
+* | | | |
+* /----//----//----/ /----//----//----/
+* | | | | | | | |
+* | | | | | | | |
+* \----\\----\\----\ \----\\----\\----\
+*
+*
**/
[NUMB]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
//right half
- KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
- KC_TRNS, DE_SLSH, KC_7, KC_8, KC_9, DE_ASTR, KC_F12,
- DE_SLSH, KC_4, KC_5, KC_6, DE_PLUS, DE_MINS,
- KC_TRNS, DE_PERC, KC_1, KC_2, KC_3, KC_TRNS, KC_TRNS,
- KC_0, KC_DOT, KC_COMM, DE_EQL, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, DE_SLSH, KC_7, KC_8, KC_9, DE_ASTR, KC_F12,
+ DE_SLSH, KC_4, KC_5, KC_6, DE_PLUS, DE_MINS,
+ KC_TRNS, DE_PERC, KC_1, KC_2, KC_3, KC_TRNS, KC_TRNS,
+ KC_0, KC_DOT, KC_COMM, DE_EQL, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
/**
* Layer: EGOS
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* /--------//--------//--------//--------//--------//--------/\--------\ \--------\/--------//--------//--------//--------//--------//--------/
-* | Shift | | | | | | | | | | | | |
-* | | | | | | | | | | | | | |
-* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
-* | | | | | | | | | | | | | | | |
-* | | | | | | | | | | | | | | | |
-* \--------\\--------\\--------\\--------\\--------\\--------\\--------\ \--------\\--------\\--------\\--------\\--------\\--------\\--------\
-*
-*
-* /--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------/
-* | Ctrl | | | | | | | | | Toggle 5| |
-* | | | | | | | | | | | |
-* \--------\\--------\\--------\\--------\/--------//--------/ /--------//--------/ \--------\\--------\\--------\\--------\\--------\
-* | F1 | F2 | | | |
-* | | | | | |
-* \--------\/--------/ /--------/\--------\
-* | F3 | | |
-* | | | |
-* /--------//--------//--------/ /--------//--------//--------/
-* | SPC | Ctrl | F4 | | | | |
-* | | | | | | | |
-* \--------\\--------\\--------\ \--------\\--------\\--------\
-*
-*
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* /--------//--------//--------//--------//--------//--------/\--------\ \--------\/--------//--------//--------//--------//--------//--------/
+* | Shift | | | | | | | | | | | | |
+* | | | | | | | | | | | | | |
+* /--------//--------//--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------//--------//--------/
+* | | | | | | | | | | | | | | | |
+* | | | | | | | | | | | | | | | |
+* \--------\\--------\\--------\\--------\\--------\\--------\\--------\ \--------\\--------\\--------\\--------\\--------\\--------\\--------\
+*
+*
+* /--------//--------//--------//--------//--------/ /--------//--------//--------//--------//--------/
+* | Ctrl | | | | | | | | | Toggle 5| |
+* | | | | | | | | | | | |
+* \--------\\--------\\--------\\--------\/--------//--------/ /--------//--------/ \--------\\--------\\--------\\--------\\--------\
+* | F1 | F2 | | | |
+* | | | | | |
+* \--------\/--------/ /--------/\--------\
+* | F3 | | |
+* | | | |
+* /--------//--------//--------/ /--------//--------//--------/
+* | SPC | Ctrl | F4 | | | | |
+* | | | | | | | |
+* \--------\\--------\\--------\ \--------\\--------\\--------\
+*
+*
**/
[EGOS]=LAYOUT_ergodox(
//left half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_LSFT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_LCTL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_F1, KC_F2,
- KC_F3,
- KC_SPC, KC_LCTL, KC_F4,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_LSFT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_LCTL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_F1, KC_F2,
+ KC_F3,
+ KC_SPC, KC_LCTL, KC_F4,
//right half
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, M(M_TOGGLE_5), KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, M(M_TOGGLE_5), KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
};
@@ -556,7 +556,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
-uint8_t layer = biton32(layer_state);
+uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -566,17 +566,17 @@ switch (layer) {
case SYMB:
ergodox_right_led_1_on();
-
-
+
+
break;
case MDIA:
-
+
ergodox_right_led_2_on();
-
+
break;
case NUMB:
-
-
+
+
ergodox_right_led_3_on();
break;
case EGOS:
@@ -590,4 +590,3 @@ break;
}
};
-
diff --git a/layouts/community/ergodox/osx_fr/keymap.c b/layouts/community/ergodox/osx_fr/keymap.c
index 886e54208a..22451c1a30 100644
--- a/layouts/community/ergodox/osx_fr/keymap.c
+++ b/layouts/community/ergodox/osx_fr/keymap.c
@@ -141,7 +141,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/osx_kinesis_pnut/keymap.c b/layouts/community/ergodox/osx_kinesis_pnut/keymap.c
index ad6ea27364..fb50a3407e 100644
--- a/layouts/community/ergodox/osx_kinesis_pnut/keymap.c
+++ b/layouts/community/ergodox/osx_kinesis_pnut/keymap.c
@@ -145,7 +145,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/osx_neo2/keymap.c b/layouts/community/ergodox/osx_neo2/keymap.c
index 3dbfceabc4..125cc43a8f 100644
--- a/layouts/community/ergodox/osx_neo2/keymap.c
+++ b/layouts/community/ergodox/osx_neo2/keymap.c
@@ -704,7 +704,7 @@ void matrix_init_user(void){
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/phoenix/keymap.c b/layouts/community/ergodox/phoenix/keymap.c
index a66462e3a8..4371e5f2e7 100644
--- a/layouts/community/ergodox/phoenix/keymap.c
+++ b/layouts/community/ergodox/phoenix/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/plover/keymap.c b/layouts/community/ergodox/plover/keymap.c
index ffb869309a..7b34dde2ed 100644
--- a/layouts/community/ergodox/plover/keymap.c
+++ b/layouts/community/ergodox/plover/keymap.c
@@ -182,7 +182,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/qwerty_code_friendly/keymap.c b/layouts/community/ergodox/qwerty_code_friendly/keymap.c
index 6e285d5613..ed06446907 100644
--- a/layouts/community/ergodox/qwerty_code_friendly/keymap.c
+++ b/layouts/community/ergodox/qwerty_code_friendly/keymap.c
@@ -662,7 +662,7 @@ void matrix_init_user(void) {
/* Runs constantly in the background, in a loop. */
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/reset_eeprom/keymap.c b/layouts/community/ergodox/reset_eeprom/keymap.c
index 83c252a9a1..726447cbd0 100644
--- a/layouts/community/ergodox/reset_eeprom/keymap.c
+++ b/layouts/community/ergodox/reset_eeprom/keymap.c
@@ -96,7 +96,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/romanzolotarev-norman-plover-osx-hjkl/keymap.c b/layouts/community/ergodox/romanzolotarev-norman-plover-osx-hjkl/keymap.c
index 819944121e..6eb319ca63 100644
--- a/layouts/community/ergodox/romanzolotarev-norman-plover-osx-hjkl/keymap.c
+++ b/layouts/community/ergodox/romanzolotarev-norman-plover-osx-hjkl/keymap.c
@@ -88,7 +88,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/layouts/community/ergodox/romanzolotarev-norman-plover-osx/keymap.c b/layouts/community/ergodox/romanzolotarev-norman-plover-osx/keymap.c
index a0964fac77..adf420daa0 100644
--- a/layouts/community/ergodox/romanzolotarev-norman-plover-osx/keymap.c
+++ b/layouts/community/ergodox/romanzolotarev-norman-plover-osx/keymap.c
@@ -88,7 +88,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/layouts/community/ergodox/romanzolotarev-norman-qwerty-osx/keymap.c b/layouts/community/ergodox/romanzolotarev-norman-qwerty-osx/keymap.c
index 6aca3a6d5f..cf3941ee1d 100644
--- a/layouts/community/ergodox/romanzolotarev-norman-qwerty-osx/keymap.c
+++ b/layouts/community/ergodox/romanzolotarev-norman-qwerty-osx/keymap.c
@@ -48,7 +48,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
diff --git a/layouts/community/ergodox/sethbc/keymap.c b/layouts/community/ergodox/sethbc/keymap.c
index 26d3106ec4..f3a1f64309 100644
--- a/layouts/community/ergodox/sethbc/keymap.c
+++ b/layouts/community/ergodox/sethbc/keymap.c
@@ -77,7 +77,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/siroken3/keymap.c b/layouts/community/ergodox/siroken3/keymap.c
index fed8b4a0c8..dd5125d20e 100644
--- a/layouts/community/ergodox/siroken3/keymap.c
+++ b/layouts/community/ergodox/siroken3/keymap.c
@@ -141,7 +141,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/sneako/keymap.c b/layouts/community/ergodox/sneako/keymap.c
index 9d3cdd5a11..dffe797ab0 100644
--- a/layouts/community/ergodox/sneako/keymap.c
+++ b/layouts/community/ergodox/sneako/keymap.c
@@ -141,7 +141,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/software_neo2/keymap.c b/layouts/community/ergodox/software_neo2/keymap.c
index 5f600a5ab5..c191a034f2 100644
--- a/layouts/community/ergodox/software_neo2/keymap.c
+++ b/layouts/community/ergodox/software_neo2/keymap.c
@@ -98,7 +98,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/swedish-lindhe/keymap.c b/layouts/community/ergodox/swedish-lindhe/keymap.c
index 368e216cdc..b0abff9ec6 100644
--- a/layouts/community/ergodox/swedish-lindhe/keymap.c
+++ b/layouts/community/ergodox/swedish-lindhe/keymap.c
@@ -162,7 +162,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/swedish/keymap.c b/layouts/community/ergodox/swedish/keymap.c
index 90218aa886..5e2d47de57 100644
--- a/layouts/community/ergodox/swedish/keymap.c
+++ b/layouts/community/ergodox/swedish/keymap.c
@@ -203,7 +203,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/swissgerman/keymap.c b/layouts/community/ergodox/swissgerman/keymap.c
index 8ba9582934..8766d16ae0 100644
--- a/layouts/community/ergodox/swissgerman/keymap.c
+++ b/layouts/community/ergodox/swissgerman/keymap.c
@@ -222,7 +222,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
diff --git a/layouts/community/ergodox/techtomas/keymap.c b/layouts/community/ergodox/techtomas/keymap.c
index 742eca03a4..bdbb50be42 100644
--- a/layouts/community/ergodox/techtomas/keymap.c
+++ b/layouts/community/ergodox/techtomas/keymap.c
@@ -180,7 +180,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/tkuichooseyou/keymap.c b/layouts/community/ergodox/tkuichooseyou/keymap.c
index ea6c8f259f..08f1cfc9ab 100644
--- a/layouts/community/ergodox/tkuichooseyou/keymap.c
+++ b/layouts/community/ergodox/tkuichooseyou/keymap.c
@@ -138,7 +138,7 @@ LAYOUT_ergodox(
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/tonyabra_osx/keymap.c b/layouts/community/ergodox/tonyabra_osx/keymap.c
index 741a6396e8..9b8048dda3 100644
--- a/layouts/community/ergodox/tonyabra_osx/keymap.c
+++ b/layouts/community/ergodox/tonyabra_osx/keymap.c
@@ -138,7 +138,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/townk_osx/keymap.c b/layouts/community/ergodox/townk_osx/keymap.c
index 6799ad7460..c79d74d6eb 100644
--- a/layouts/community/ergodox/townk_osx/keymap.c
+++ b/layouts/community/ergodox/townk_osx/keymap.c
@@ -229,7 +229,7 @@ uint8_t current_layer = BASE;
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_led_all_off();
ergodox_led_all_set(LED_BRIGHTNESS_LO);
diff --git a/layouts/community/ergodox/twentylives_dvorak_with_hebrew/keymap.c b/layouts/community/ergodox/twentylives_dvorak_with_hebrew/keymap.c
index 4b5181a70d..12548ae0ea 100644
--- a/layouts/community/ergodox/twentylives_dvorak_with_hebrew/keymap.c
+++ b/layouts/community/ergodox/twentylives_dvorak_with_hebrew/keymap.c
@@ -36,7 +36,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_DELETE, KC_TRNS,
KC_LGUI,
KC_BSPACE,CTL_T(KC_NO),KC_LALT,
-
+
KC_TILD, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQUAL,
KC_TRNS, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLASH,
KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINUS,
@@ -77,7 +77,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
-
+
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_Y, KC_U, KC_E, KC_O, KC_P, KC_TRNS,
KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_TRNS,
@@ -110,9 +110,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `--------------------' `--------------------'
*/
[2] = LAYOUT_ergodox(
- KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_UP, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
@@ -120,12 +120,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
- KC_F11, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_F11, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_TRNS,
KC_F12, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_MS_BTN1, KC_MS_BTN2, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
- KC_TRNS,
+ KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
@@ -154,19 +154,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Left Hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// Right Hand
- KC_TRNS, KC_TRNS, KC_LOCKING_NUM, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_LOCKING_NUM, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_PLUS, KC_TRNS,
- KC_TRNS, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_TRNS,
+ KC_TRNS, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_KP_1, KC_KP_2, KC_KP_3, KC_ENTER, KC_TRNS,
KC_KP_0, KC_KP_0, KC_KP_DOT, KC_ENTER, KC_TRNS,
- KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
@@ -175,7 +175,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/win10_writers-block/keymap.c b/layouts/community/ergodox/win10_writers-block/keymap.c
index 05adaed759..443e403b18 100644
--- a/layouts/community/ergodox/win10_writers-block/keymap.c
+++ b/layouts/community/ergodox/win10_writers-block/keymap.c
@@ -4,8 +4,8 @@
#include "version.h"
#include "wait.h"
-#define BASE 0 // default layer - helpful for writing in Office-style word processors.
-#define SYMB 1 // symbol layer - NumPad, etc. - same as Ergodox EZ default but no EEPROM or Version key
+#define BASE 0 // default layer - helpful for writing in Office-style word processors.
+#define SYMB 1 // symbol layer - NumPad, etc. - same as Ergodox EZ default but no EEPROM or Version key
#define RIMW 2 // rimworld layer - made for the game RimWorld, by Tynan Sylvester | feel free to remap for your favorite game!
#define MDIA 3 // media layer - mouse and music - close to Ergodox EZ default media layer
@@ -27,19 +27,19 @@ enum {
};
void cake_count (qk_tap_dance_state_t *state, void *user_data) {
- if (state->count == 2) {
+ if (state->count == 2) {
layer_on (SYMB); //define double tap here
layer_off (MDIA);
- }
- else {
+ }
+ else {
layer_off (SYMB); //define single tap or hold here
layer_off (MDIA);
}
- if (state->count == 3) {
+ if (state->count == 3) {
layer_on (RIMW); //define triple tap here
layer_off (MDIA);
- }
- else {
+ }
+ else {
layer_off (RIMW); //define single tap or hold here
layer_off (MDIA);
reset_tap_dance (state);
@@ -83,7 +83,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* ,--------------------------------------------------. ,--------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 7 | 8 | 9 | 0 | - | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
- * | F12/L1 | Q | W | E | R | T | {/[ | |TD(L0 | Y | U | I | O | P | \ |
+ * | F12/L1 | Q | W | E | R | T | {/[ | |TD(L0 | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | |L1 L2)|------+------+------+------+------+--------|
* |Caps/Win| A | S | D | F | G |------| |------| H | J | K | L | ; | ' |
* |--------+------+------+------+------+------| }/] | TD(ctrl|------+------+------+------+------+--------|
@@ -163,8 +163,8 @@ LT(SYMB, KC_F12), KC_Q, KC_W, KC_E, KC_R, KC_T,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
-),
-
+),
+
/* Keymap 2: RimWorld Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
@@ -186,7 +186,7 @@ LT(SYMB, KC_F12), KC_Q, KC_W, KC_E, KC_R, KC_T,
* | | | Q | | | | |
* `--------------------' `--------------------'
*/
-// RIMWORLD
+// RIMWORLD
[RIMW] = LAYOUT_ergodox(
// left hand
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
@@ -300,7 +300,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
@@ -315,7 +315,7 @@ void matrix_scan_user(void) {
break;
case 3:
ergodox_right_led_3_on();
- break;
+ break;
default:
// none
break;
diff --git a/layouts/community/ergodox/xyverz/keymap.c b/layouts/community/ergodox/xyverz/keymap.c
index c77920bb13..f348736c6e 100644
--- a/layouts/community/ergodox/xyverz/keymap.c
+++ b/layouts/community/ergodox/xyverz/keymap.c
@@ -1,6 +1,6 @@
/*
* About this keymap:
- *
+ *
* The Dvorak layout shown here stems from my early Kinesis years, using the Contour PS/2 with a Dvorak
* software layout. Because of this, the RBRC and LBRC were on opposite sides of the board in the corner
* keys. When I originally set up this keymap, I'd decided to continue using this layout with my ErgoDox.
@@ -14,7 +14,7 @@
* layouts.
*
* What's New:
- *
+ *
* I've overhauled this Dvorak layout a bit to more match what I've got on my other Ortho boards. For
* some keys, I'm moving away from my old Kinesis keymap and adding the brackets and braces to the
* inner column vertical keys. I figure this will help me have better ease of use. In this update, I
@@ -246,7 +246,7 @@ void matrix_init_user(void) {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ergodox/zweihander-macos/keymap.c b/layouts/community/ergodox/zweihander-macos/keymap.c
index b2ddeb0d6b..0aecc24e67 100644
--- a/layouts/community/ergodox/zweihander-macos/keymap.c
+++ b/layouts/community/ergodox/zweihander-macos/keymap.c
@@ -140,7 +140,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
- uint8_t layer = biton32(layer_state);
+ uint8_t layer = get_highest_layer(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
diff --git a/layouts/community/ortho_4x12/peej/keymap.c b/layouts/community/ortho_4x12/peej/keymap.c
index d78f03da41..1e2874ac99 100644
--- a/layouts/community/ortho_4x12/peej/keymap.c
+++ b/layouts/community/ortho_4x12/peej/keymap.c
@@ -56,7 +56,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
writePinLow(LED_RED);
writePinLow(LED_GREEN);
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _FUNCTION:
writePinHigh(LED_RED);
break;
diff --git a/lib/chibios b/lib/chibios
-Subproject 257302333c31f1f710800c2b97acf3550de043e
+Subproject f836d24b06d7265696a33d1cea010bd6a931791
diff --git a/lib/chibios-contrib b/lib/chibios-contrib
-Subproject 2a6b73ff51baf89083a220b6692a04ca2cae875
+Subproject 2bfb681d68df4294f73847dba2cf2218b21a50e
diff --git a/lib/fnv/Makefile b/lib/fnv/Makefile
new file mode 100644
index 0000000000..c0673ded40
--- /dev/null
+++ b/lib/fnv/Makefile
@@ -0,0 +1,304 @@
+#!/bin/make
+#
+# hash - makefile for FNV hash tools
+#
+# @(#) $Revision: 5.2 $
+# @(#) $Id: Makefile,v 5.2 2012/03/21 01:42:15 chongo Exp $
+# @(#) $Source: /usr/local/src/cmd/fnv/RCS/Makefile,v $
+#
+# See:
+# http://www.isthe.com/chongo/tech/comp/fnv/index.html
+#
+# for the most up to date copy of this code and the FNV hash home page.
+#
+# Please do not copyright this code. This code is in the public domain.
+#
+# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+# By:
+# chongo <Landon Curt Noll> /\oo/\
+# http://www.isthe.com/chongo/
+#
+# Share and Enjoy! :-)
+
+# make tools
+#
+SHELL= /bin/sh
+CFLAGS= -O3 -g3
+#CFLAGS= -O2 -g3
+#CC= cc
+AR= ar
+TAR= tar
+EGREP= egrep
+GZIP_BIN= gzip
+INSTALL= install
+
+# If your system needs ranlib use:
+# RANLIB= ranlib
+# otherwise use:
+# RANLIB= :
+#
+#RANLIB= ranlib
+RANLIB= :
+
+# where to install things
+#
+DESTBIN= /usr/local/bin
+DESTLIB= /usr/local/lib
+DESTINC= /usr/local/include
+
+# what to build
+#
+SRC= hash_32.c hash_32a.c hash_64.c hash_64a.c \
+ fnv32.c fnv64.c \
+ have_ulong64.c test_fnv.c
+NO64BIT_SRC= no64bit_fnv64.c no64bit_hash_64.c \
+ no64bit_hash_64a.c no64bit_test_fnv.c
+HSRC= fnv.h \
+ longlong.h
+ALL= ${SRC} ${HSRC} \
+ README Makefile
+PROGS= fnv032 fnv064 fnv132 fnv164 fnv1a32 fnv1a64
+OBSOLETE_PROGS= fnv0_32 fnv0_64 fnv1_32 fnv1_64 fnv1a_32 fnv1a_64
+NO64BIT_PROGS= no64bit_fnv064 no64bit_fnv164 no64bit_fnv1a64
+LIBS= libfnv.a
+LIBOBJ= hash_32.o hash_64.o hash_32a.o hash_64a.o test_fnv.o
+NO64BIT_OBJ= no64bit_fnv64.o no64bit_hash_64.o \
+ no64bit_hash_64a.o no64bit_test_fnv.o
+OTHEROBJ= fnv32.o fnv64.o
+TARGETS= ${LIBOBJ} ${LIBS} ${PROGS}
+
+# default rule
+#
+all: ${TARGETS}
+
+# things to build
+#
+hash_32.o: hash_32.c longlong.h fnv.h
+ ${CC} ${CFLAGS} hash_32.c -c
+
+hash_64.o: hash_64.c longlong.h fnv.h
+ ${CC} ${CFLAGS} hash_64.c -c
+
+hash_32a.o: hash_32a.c longlong.h fnv.h
+ ${CC} ${CFLAGS} hash_32a.c -c
+
+hash_64a.o: hash_64a.c longlong.h fnv.h
+ ${CC} ${CFLAGS} hash_64a.c -c
+
+test_fnv.o: test_fnv.c longlong.h fnv.h
+ ${CC} ${CFLAGS} test_fnv.c -c
+
+fnv32.o: fnv32.c longlong.h fnv.h
+ ${CC} ${CFLAGS} fnv32.c -c
+
+fnv032: fnv32.o libfnv.a
+ ${CC} fnv32.o libfnv.a -o fnv032
+
+fnv64.o: fnv64.c longlong.h fnv.h
+ ${CC} ${CFLAGS} fnv64.c -c
+
+fnv064: fnv64.o libfnv.a
+ ${CC} fnv64.o libfnv.a -o fnv064
+
+libfnv.a: ${LIBOBJ}
+ rm -f $@
+ ${AR} rv $@ ${LIBOBJ}
+ ${RANLIB} $@
+
+fnv132: fnv032
+ -rm -f $@
+ -cp -f $? $@
+
+fnv1a32: fnv032
+ -rm -f $@
+ -cp -f $? $@
+
+fnv164: fnv064
+ -rm -f $@
+ -cp -f $? $@
+
+fnv1a64: fnv064
+ -rm -f $@
+ -cp -f $? $@
+
+longlong.h: have_ulong64.c Makefile
+ -@rm -f have_ulong64 have_ulong64.o ll_tmp longlong.h
+ @echo 'forming longlong.h'
+ @echo '/*' > longlong.h
+ @echo ' * DO NOT EDIT -- generated by the Makefile' >> longlong.h
+ @echo ' */' >> longlong.h
+ @echo '' >> longlong.h
+ @echo '#if !defined(__LONGLONG_H__)' >> longlong.h
+ @echo '#define __LONGLONG_H__' >> longlong.h
+ @echo '' >> longlong.h
+ @echo '/* do we have/want to use a long long type? */' >> longlong.h
+ -@rm -f have_ulong64.o have_ulong64
+ -@${CC} ${CFLAGS} have_ulong64.c -c 2>/dev/null; true
+ -@${CC} ${CFLAGS} have_ulong64.o -o have_ulong64 2>/dev/null; true
+ -@${SHELL} -c "./have_ulong64 > ll_tmp 2>/dev/null" \
+ >/dev/null 2>&1; true
+ -@if [ -s ll_tmp ]; then \
+ cat ll_tmp >> longlong.h; \
+ else \
+ echo '#undef HAVE_64BIT_LONG_LONG /* no */' >> longlong.h; \
+ fi
+ @echo '' >> longlong.h
+ @echo '/*' >> longlong.h
+ @echo ' * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG' >> longlong.h
+ @echo ' */' >> longlong.h
+ @echo '#if defined(NO64BIT_LONG_LONG)' >> longlong.h
+ @echo '#undef HAVE_64BIT_LONG_LONG' >> longlong.h
+ @echo '#endif /* NO64BIT_LONG_LONG */' >> longlong.h
+ @echo '' >> longlong.h
+ @echo '#endif /* !__LONGLONG_H__ */' >> longlong.h
+ -@rm -f have_ulong64 have_ulong64.o ll_tmp
+ @echo 'longlong.h formed'
+
+# utilities
+#
+install: all
+ -@if [ -d "${DESTBIN}" ]; then \
+ echo " mkdir -p ${DESTBIN}"; \
+ mkdir -p ${DESTBIN}; \
+ fi
+ -@if [ -d "${DESTLIB}" ]; then \
+ echo " mkdir -p ${DESTLIB}"; \
+ mkdir -p ${DESTLIB}; \
+ fi
+ -@if [ -d "${DESTINC}" ]; then \
+ echo " mkdir -p ${DESTINC}"; \
+ mkdir -p ${DESTINC}; \
+ fi
+ ${INSTALL} -m 0755 ${PROGS} ${DESTBIN}
+ ${INSTALL} -m 0644 ${LIBS} ${DESTLIB}
+ ${RANLIB} ${DESTLIB}/libfnv.a
+ ${INSTALL} -m 0644 ${HSRC} ${DESTINC}
+ @# remove osolete programs
+ for i in ${OBSOLETE_PROGS}; do \
+ if [ -f "${DESTBIN}/$$i" ]; then \
+ echo "rm -f ${DESTBIN}/$$i"; \
+ rm -f "${DESTBIN}/$$i"; \
+ fi; \
+ done
+
+clean:
+ -rm -f have_ulong64 have_ulong64.o ll_tmp ll_tmp2 longlong.h
+ -rm -f ${LIBOBJ}
+ -rm -f ${OTHEROBJ}
+
+clobber: clean
+ -rm -f ${TARGETS}
+ -rm -f ${OBSOLETE_PROGS} lltmp lltmp2 ll_tmp
+ -rm -f ${NO64BIT_SRC}
+ -rm -f ${NO64BIT_OBJ}
+ -rm -f ${NO64BIT_PROGS}
+ -rm -f vector.c
+
+check: ${PROGS}
+ @echo -n "FNV-0 32 bit tests: "
+ @./fnv032 -t 1 -v
+ @echo -n "FNV-1 32 bit tests: "
+ @./fnv132 -t 1 -v
+ @echo -n "FNV-1a 32 bit tests: "
+ @./fnv1a32 -t 1 -v
+ @echo -n "FNV-0 64 bit tests: "
+ @./fnv064 -t 1 -v
+ @echo -n "FNV-1 64 bit tests: "
+ @./fnv164 -t 1 -v
+ @echo -n "FNV-1a 64 bit tests: "
+ @./fnv1a64 -t 1 -v
+
+###############################
+# generate test vector source #
+###############################
+
+no64bit_fnv64.c: fnv64.c
+ -rm -f $@
+ -cp -f $? $@
+
+no64bit_hash_64.c: hash_64.c
+ -rm -f $@
+ -cp -f $? $@
+
+no64bit_hash_64a.c: hash_64a.c
+ -rm -f $@
+ -cp -f $? $@
+
+no64bit_test_fnv.c: test_fnv.c
+ -rm -f $@
+ -cp -f $? $@
+
+no64bit_fnv64.o: no64bit_fnv64.c longlong.h fnv.h
+ ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_fnv64.c -c
+
+no64bit_hash_64.o: no64bit_hash_64.c longlong.h fnv.h
+ ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64.c -c
+
+no64bit_hash_64a.o: no64bit_hash_64a.c longlong.h fnv.h
+ ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_hash_64a.c -c
+
+no64bit_test_fnv.o: no64bit_test_fnv.c longlong.h fnv.h
+ ${CC} ${CFLAGS} -DNO64BIT_LONG_LONG no64bit_test_fnv.c -c
+
+no64bit_fnv064: no64bit_fnv64.o no64bit_hash_64.o \
+ no64bit_hash_64a.o no64bit_test_fnv.o
+ ${CC} ${CFLAGS} no64bit_fnv64.o no64bit_hash_64.o \
+ no64bit_hash_64a.o no64bit_test_fnv.o -o $@
+
+no64bit_fnv164: no64bit_fnv064
+ -rm -f $@
+ -cp -f $? $@
+
+no64bit_fnv1a64: no64bit_fnv064
+ -rm -f $@
+ -cp -f $? $@
+
+vector.c: ${PROGS} ${NO64BIT_PROGS}
+ -rm -f $@
+ echo '/* start of output generated by make $@ */' >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-0 32 bit test vectors */' >> $@
+ ./fnv032 -t 0 >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-1 32 bit test vectors */' >> $@
+ ./fnv132 -t 0 >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-1a 32 bit test vectors */' >> $@
+ ./fnv1a32 -t 0 >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-0 64 bit test vectors */' >> $@
+ echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@
+ ./fnv064 -t 0 >> $@
+ echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@
+ ./no64bit_fnv064 -t 0 >> $@
+ echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-1 64 bit test vectors */' >> $@
+ echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@
+ ./fnv164 -t 0 >> $@
+ echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@
+ ./no64bit_fnv164 -t 0 >> $@
+ echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@
+ echo '' >> $@
+ #@
+ echo '/* FNV-1a 64 bit test vectors */' >> $@
+ echo '#if defined(HAVE_64BIT_LONG_LONG)' >> $@
+ ./fnv1a64 -t 0 >> $@
+ echo '#else /* HAVE_64BIT_LONG_LONG */' >> $@
+ ./no64bit_fnv1a64 -t 0 >> $@
+ echo '#endif /* HAVE_64BIT_LONG_LONG */' >> $@
+ echo '' >> $@
+ #@
+ echo '/* end of output generated by make $@ */' >> $@
diff --git a/lib/fnv/README b/lib/fnv/README
new file mode 100644
index 0000000000..60aa9aaf61
--- /dev/null
+++ b/lib/fnv/README
@@ -0,0 +1,158 @@
+#=====================#
+# Fowler/Noll/Vo hash #
+#=====================#
+
+The basis of this hash algorithm was taken from an idea sent
+as reviewer comments to the IEEE POSIX P1003.2 committee by:
+
+ Phong Vo (http://www.research.att.com/info/kpv)
+ Glenn Fowler (http://www.research.att.com/~gsf/)
+
+In a subsequent ballot round:
+
+ Landon Curt Noll (http://www.isthe.com/chongo)
+
+improved on their algorithm. Some people tried this hash
+and found that it worked rather well. In an EMail message
+to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+
+FNV hashes are designed to be fast while maintaining a low
+collision rate. The FNV speed allows one to quickly hash lots
+of data while maintaining a reasonable collision rate. See:
+
+ http://www.isthe.com/chongo/tech/comp/fnv/index.html
+
+for more details as well as other forms of the FNV hash.
+Comments, questions, bug fixes and suggestions welcome at
+the address given in the above URL.
+
+
+#==================#
+# FNV hash utility #
+#==================#
+
+Two hash utilities (32 bit and 64 bit) are provided:
+
+ fnv032 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+ fnv132 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+ fnv1a32 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+
+ fnv064 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+ fnv164 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+ fnv1a64 [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]
+
+ -b bcnt mask off all but the lower bcnt bits (default: 32)
+ -m multiple hashes, one per line for each arg
+ -s hash arg as a string (ignoring terminating NUL bytes)
+ -t code 0 ==> generate test vectors, 1 ==> test FNV hash
+ -v verbose mode, print arg after hash (implies -m)
+ arg string (if -s was given) or filename (default stdin)
+
+The fnv032, fnv064 implement the historic FNV-0 hash.
+The fnv132, fnv164 implement the recommended FNV-1 hash.
+The fnv1a32, fnv1a64 implement the recommended FNV-1a hash.
+
+This is the original historic FNV algorithm with a 0 offset basis.
+It is recommended that FNV-1, with a non-0 offset basis be used instead.
+
+To test FNV hashes, try:
+
+ fnv032 -t 1 -v
+ fnv132 -t 1 -v
+ fnv1a32 -t 1 -v
+
+ fnv064 -t 1 -v
+ fnv164 -t 1 -v
+ fnv1a64 -t 1 -v
+
+If you are compiling, try:
+
+ make check
+
+
+#==================#
+# FNV hash library #
+#==================#
+
+The libfnv.a library implements both a 32 bit and a 64 bit FNV hash
+on collections of bytes, a NUL terminated strings or on an open file
+descriptor.
+
+Here is the 32 bit FNV 1 hash:
+
+ Fnv32_t fnv_32_buf(void *buf, int len, Fnv32_t hval); /* byte buf */
+ Fnv32_t fnv_32_str(char *string, Fnv32_t hval); /* string */
+
+Here is the 32 bit FNV 1a hash:
+
+ Fnv32_t fnv_32a_buf(void *buf, int len, Fnv32_t hval); /* byte buf */
+ Fnv32_t fnv_32a_str(char *string, Fnv32_t hval); /* string */
+
+Here is the 64 bit FNV 1 hash:
+
+ Fnv64_t fnv_64_buf(void *buf, int len, Fnv64_t hval); /* byte buf */
+ Fnv64_t fnv_64_str(char *string, Fnv64_t hval); /* string */
+
+Here is the 64 bit FNV 1a hash:
+
+ Fnv64_t fnv_64a_buf(void *buf, int len, Fnv64_t hval); /* byte buf */
+ Fnv64_t fnv_64a_str(char *string, Fnv64_t hval); /* string */
+
+On the first call to a hash function, one must supply the initial basis
+that is appropriate for the hash in question:
+
+ FNV-0: (not recommended)
+
+ FNV0_32_INIT /* 32 bit FNV-0 initial basis */
+ FNV0_64_INIT /* 64 bit FNV-0 initial basis */
+
+ FNV-1:
+
+ FNV1_32_INIT /* 32 bit FNV-1 initial basis */
+ FNV1_64_INIT /* 64 bit FNV-1 initial basis */
+
+ FNV-1a:
+
+ FNV1A_32_INIT /* 32 bit FNV-1a initial basis */
+ FNV1A_64_INIT /* 64 bit FNV-1a initial basis */
+
+For example to perform a 64 bit FNV-1 hash:
+
+ #include "fnv.h"
+
+ Fnv64_t hash_val;
+
+ hash_val = fnv_64_str("a string", FNV1_64_INIT);
+ hash_val = fnv_64_str("more string", hash_val);
+
+produces the same final hash value as:
+
+ hash_val = fnv_64_str("a stringmore string", FNV1_64_INIT);
+
+NOTE: If one used 'FNV0_64_INIT' instead of 'FNV1_64_INIT' one would get the
+ historic FNV-0 hash instead recommended FNV-1 hash.
+
+To perform a 32 bit FNV-1 hash:
+
+ #include "fnv.h"
+
+ Fnv32_t hash_val;
+
+ hash_val = fnv_32_buf(buf, length_of_buf, FNV1_32_INIT);
+ hash_val = fnv_32_str("more data", hash_val);
+
+To perform a 64 bit FNV-1a hash:
+
+ #include "fnv.h"
+
+ Fnv64_t hash_val;
+
+ hash_val = fnv_64a_buf(buf, length_of_buf, FNV1_64_INIT);
+ hash_val = fnv_64a_str("more data", hash_val);
+
+=-=
+
+chongo <Landon Curt Noll> /\oo/\
+http://www.isthe.com/chongo
+
+Share and Enjoy!
diff --git a/lib/fnv/fnv.h b/lib/fnv/fnv.h
new file mode 100644
index 0000000000..2083a4aa23
--- /dev/null
+++ b/lib/fnv/fnv.h
@@ -0,0 +1,249 @@
+/*
+ * fnv - Fowler/Noll/Vo- hash code
+ *
+ * @(#) $Revision: 5.4 $
+ * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo- hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * NOTE: The FNV-0 historic hash is not recommended. One should use
+ * the FNV-1 hash instead.
+ *
+ * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the
+ * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
+ *
+ * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
+ *
+ * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
+ * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
+ *
+ * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
+ *
+ * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
+ * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
+ *
+ * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str().
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#if !defined(__FNV_H__)
+#define __FNV_H__
+
+#include <sys/types.h>
+
+#define FNV_VERSION "5.0.2" /* @(#) FNV Version */
+
+
+/*
+ * 32 bit FNV-0 hash type
+ */
+typedef u_int32_t Fnv32_t;
+
+
+/*
+ * 32 bit FNV-0 zero initial basis
+ *
+ * This historic hash is not recommended. One should use
+ * the FNV-1 hash and initial basis instead.
+ */
+#define FNV0_32_INIT ((Fnv32_t)0)
+
+
+/*
+ * 32 bit FNV-1 and FNV-1a non-zero initial basis
+ *
+ * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
+ *
+ * chongo <Landon Curt Noll> /\../\
+ *
+ * NOTE: The \'s above are not back-slashing escape characters.
+ * They are literal ASCII backslash 0x5c characters.
+ *
+ * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
+ */
+#define FNV1_32_INIT ((Fnv32_t)0x811c9dc5)
+#define FNV1_32A_INIT FNV1_32_INIT
+
+
+/*
+ * determine how 64 bit unsigned values are represented
+ */
+#include "longlong.h"
+
+
+/*
+ * 64 bit FNV-0 hash
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+typedef u_int64_t Fnv64_t;
+#else /* HAVE_64BIT_LONG_LONG */
+typedef struct {
+ u_int32_t w32[2]; /* w32[0] is low order, w32[1] is high order word */
+} Fnv64_t;
+#endif /* HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * 64 bit FNV-0 zero initial basis
+ *
+ * This historic hash is not recommended. One should use
+ * the FNV-1 hash and initial basis instead.
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+#define FNV0_64_INIT ((Fnv64_t)0)
+#else /* HAVE_64BIT_LONG_LONG */
+extern const Fnv64_t fnv0_64_init;
+#define FNV0_64_INIT (fnv0_64_init)
+#endif /* HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * 64 bit FNV-1 non-zero initial basis
+ *
+ * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
+ *
+ * chongo <Landon Curt Noll> /\../\
+ *
+ * NOTE: The \'s above are not back-slashing escape characters.
+ * They are literal ASCII backslash 0x5c characters.
+ *
+ * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+#define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL)
+#define FNV1A_64_INIT FNV1_64_INIT
+#else /* HAVE_64BIT_LONG_LONG */
+extern const fnv1_64_init;
+extern const Fnv64_t fnv1a_64_init;
+#define FNV1_64_INIT (fnv1_64_init)
+#define FNV1A_64_INIT (fnv1a_64_init)
+#endif /* HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * hash types
+ */
+enum fnv_type {
+ FNV_NONE = 0, /* invalid FNV hash type */
+ FNV0_32 = 1, /* FNV-0 32 bit hash */
+ FNV1_32 = 2, /* FNV-1 32 bit hash */
+ FNV1a_32 = 3, /* FNV-1a 32 bit hash */
+ FNV0_64 = 4, /* FNV-0 64 bit hash */
+ FNV1_64 = 5, /* FNV-1 64 bit hash */
+ FNV1a_64 = 6, /* FNV-1a 64 bit hash */
+};
+
+
+/*
+ * these test vectors are used as part o the FNV test suite
+ */
+struct test_vector {
+ void *buf; /* start of test vector buffer */
+ int len; /* length of test vector */
+};
+struct fnv0_32_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv32_t fnv0_32; /* expected FNV-0 32 bit hash value */
+};
+struct fnv1_32_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv32_t fnv1_32; /* expected FNV-1 32 bit hash value */
+};
+struct fnv1a_32_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv32_t fnv1a_32; /* expected FNV-1a 32 bit hash value */
+};
+struct fnv0_64_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv64_t fnv0_64; /* expected FNV-0 64 bit hash value */
+};
+struct fnv1_64_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv64_t fnv1_64; /* expected FNV-1 64 bit hash value */
+};
+struct fnv1a_64_test_vector {
+ struct test_vector *test; /* test vector buffer to hash */
+ Fnv64_t fnv1a_64; /* expected FNV-1a 64 bit hash value */
+};
+
+
+/*
+ * external functions
+ */
+/* hash_32.c */
+extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval);
+extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval);
+
+/* hash_32a.c */
+extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval);
+extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval);
+
+/* hash_64.c */
+extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval);
+extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval);
+
+/* hash_64a.c */
+extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval);
+extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval);
+
+/* test_fnv.c */
+extern struct test_vector fnv_test_str[];
+extern struct fnv0_32_test_vector fnv0_32_vector[];
+extern struct fnv1_32_test_vector fnv1_32_vector[];
+extern struct fnv1a_32_test_vector fnv1a_32_vector[];
+extern struct fnv0_64_test_vector fnv0_64_vector[];
+extern struct fnv1_64_test_vector fnv1_64_vector[];
+extern struct fnv1a_64_test_vector fnv1a_64_vector[];
+extern void unknown_hash_type(char *prog, enum fnv_type type, int code);
+extern void print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg);
+extern void print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg);
+
+
+#endif /* __FNV_H__ */
diff --git a/lib/fnv/fnv32.c b/lib/fnv/fnv32.c
new file mode 100644
index 0000000000..58c61f03fc
--- /dev/null
+++ b/lib/fnv/fnv32.c
@@ -0,0 +1,467 @@
+/*
+ * fnv32 - 32 bit Fowler/Noll/Vo hash of a buffer or string
+ *
+ * @(#) $Revision: 5.5 $
+ * @(#) $Id: fnv32.c,v 5.5 2012/03/21 01:38:12 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv32.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include "longlong.h"
+#include "fnv.h"
+
+#define WIDTH 32 /* bit width of hash */
+
+#define BUF_SIZE (32*1024) /* number of bytes to hash at a time */
+
+static char *usage =
+"usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n"
+"\n"
+"\t-b bcnt\tmask off all but the lower bcnt bits (default 32)\n"
+"\t-m\tmultiple hashes, one per line for each arg\n"
+"\t-s\thash arg as a string (ignoring terminating NUL bytes)\n"
+"\t-t code\t test hash code: (0 ==> generate test vectors\n"
+"\t\t\t\t 1 ==> validate against FNV test vectors)\n"
+"\t-v\tverbose mode, print arg after hash (implies -m)\n"
+"\targ\tstring (if -s was given) or filename (default stdin)\n"
+"\n"
+"\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n"
+"\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n"
+"\n"
+"\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n"
+"\n"
+"\t@(#) FNV Version: %s\n";
+static char *program; /* our name */
+
+
+/*
+ * test_fnv32 - test the FNV32 hash
+ *
+ * given:
+ * hash_type type of FNV hash to test
+ * init_hval initial hash value
+ * mask lower bit mask
+ * v_flag 1 => print test failure info on stderr
+ * code 0 ==> generate FNV test vectors
+ * 1 ==> validate against FNV test vectors
+ *
+ * returns: 0 ==> OK, else test vector failure number
+ */
+static int
+test_fnv32(enum fnv_type hash_type, Fnv32_t init_hval,
+ Fnv32_t mask, int v_flag, int code)
+{
+ struct test_vector *t; /* FNV test vestor */
+ Fnv32_t hval; /* current hash value */
+ int tstnum; /* test vector that failed, starting at 1 */
+
+ /*
+ * print preamble if generating test vectors
+ */
+ if (code == 0) {
+ switch (hash_type) {
+ case FNV0_32:
+ printf("struct fnv0_32_test_vector fnv0_32_vector[] = {\n");
+ break;
+ case FNV1_32:
+ printf("struct fnv1_32_test_vector fnv1_32_vector[] = {\n");
+ break;
+ case FNV1a_32:
+ printf("struct fnv1a_32_test_vector fnv1a_32_vector[] = {\n");
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 12); /* exit(12) */
+ /*NOTREACHED*/
+ }
+ }
+
+ /*
+ * loop thru all test vectors
+ */
+ for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) {
+
+ /*
+ * compute the FNV hash
+ */
+ hval = init_hval;
+ switch (hash_type) {
+ case FNV0_32:
+ case FNV1_32:
+ hval = fnv_32_buf(t->buf, t->len, hval);
+ break;
+ case FNV1a_32:
+ hval = fnv_32a_buf(t->buf, t->len, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 13); /* exit(13) */
+ /*NOTREACHED*/
+ }
+
+ /*
+ * print the vector
+ */
+ switch (code) {
+ case 0: /* generate the test vector */
+ printf(" { &fnv_test_str[%d], (Fnv32_t) 0x%08lxUL },\n",
+ tstnum-1, hval & mask);
+ break;
+ case 1: /* validate against test vector */
+ switch (hash_type) {
+ case FNV0_32:
+ if ((hval&mask) != (fnv0_32_vector[tstnum-1].fnv0_32 & mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv0_32 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08lx != generated: 0x%08lx\n",
+ program, (hval&mask),
+ (fnv0_32_vector[tstnum-1].fnv0_32 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1_32:
+ if ((hval&mask) != (fnv1_32_vector[tstnum-1].fnv1_32 & mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1_32 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08lx != generated: 0x%08lx\n",
+ program, (hval&mask),
+ (fnv1_32_vector[tstnum-1].fnv1_32 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1a_32:
+ if ((hval&mask) != (fnv1a_32_vector[tstnum-1].fnv1a_32 &mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1a_32 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08lx != generated: 0x%08lx\n",
+ program, (hval&mask),
+ (fnv1a_32_vector[tstnum-1].fnv1a_32 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ }
+ break;
+ default:
+ fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
+ exit(14);
+ }
+ }
+
+ /*
+ * print completion if generating test vectors
+ */
+ if (code == 0) {
+ printf(" { NULL, 0 }\n");
+ printf("};\n");
+ }
+
+ /*
+ * no failures, return code 0 ==> all OK
+ */
+ return 0;
+}
+
+
+/*
+ * main - the main function
+ *
+ * See the above usage for details.
+ */
+int
+main(int argc, char *argv[])
+{
+ char buf[BUF_SIZE+1]; /* read buffer */
+ int readcnt; /* number of characters written */
+ Fnv32_t hval; /* current hash value */
+ int s_flag = 0; /* 1 => -s was given, hash args as strings */
+ int m_flag = 0; /* 1 => print multiple hashes, one per arg */
+ int v_flag = 0; /* 1 => verbose hash print */
+ int b_flag = WIDTH; /* -b flag value */
+ int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */
+ enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */
+ Fnv32_t bmask; /* mask to apply to output */
+ extern char *optarg; /* option argument */
+ extern int optind; /* argv index of the next arg */
+ int fd; /* open file to process */
+ char *p;
+ int i;
+
+ /*
+ * parse args
+ */
+ program = argv[0];
+ while ((i = getopt(argc, argv, "b:mst:v")) != -1) {
+ switch (i) {
+ case 'b': /* bcnt bit mask count */
+ b_flag = atoi(optarg);
+ break;
+ case 'm': /* print multiple hashes, one per arg */
+ m_flag = 1;
+ break;
+ case 's': /* hash args as strings */
+ s_flag = 1;
+ break;
+ case 't': /* FNV test vector code */
+ t_flag = atoi(optarg);
+ if (t_flag < 0 || t_flag > 1) {
+ fprintf(stderr, "%s: -t code must be 0 or 1\n", program);
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(1);
+ }
+ m_flag = 1;
+ break;
+ case 'v': /* verbose hash print */
+ m_flag = 1;
+ v_flag = 1;
+ break;
+ default:
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(1);
+ }
+ }
+ /* -t code incompatible with -b, -m and args */
+ if (t_flag >= 0) {
+ if (b_flag != WIDTH) {
+ fprintf(stderr, "%s: -t code incompatible with -b\n", program);
+ exit(2);
+ }
+ if (s_flag != 0) {
+ fprintf(stderr, "%s: -t code incompatible with -s\n", program);
+ exit(3);
+ }
+ if (optind < argc) {
+ fprintf(stderr, "%s: -t code incompatible args\n", program);
+ exit(4);
+ }
+ }
+ /* -s requires at least 1 arg */
+ if (s_flag && optind >= argc) {
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(5);
+ }
+ /* limit -b values */
+ if (b_flag < 0 || b_flag > WIDTH) {
+ fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n",
+ program, b_flag, WIDTH);
+ exit(6);
+ }
+ if (b_flag == WIDTH) {
+ bmask = (Fnv32_t)0xffffffff;
+ } else {
+ bmask = (Fnv32_t)((1 << b_flag) - 1);
+ }
+
+ /*
+ * start with the initial basis depending on the hash type
+ */
+ p = strrchr(program, '/');
+ if (p == NULL) {
+ p = program;
+ } else {
+ ++p;
+ }
+ if (strcmp(p, "fnv032") == 0) {
+ /* using non-recommended FNV-0 and zero initial basis */
+ hval = FNV0_32_INIT;
+ hash_type = FNV0_32;
+ } else if (strcmp(p, "fnv132") == 0) {
+ /* using FNV-1 and non-zero initial basis */
+ hval = FNV1_32_INIT;
+ hash_type = FNV1_32;
+ } else if (strcmp(p, "fnv1a32") == 0) {
+ /* start with the FNV-1a initial basis */
+ hval = FNV1_32A_INIT;
+ hash_type = FNV1a_32;
+ } else {
+ fprintf(stderr, "%s: unknown program name, unknown hash type\n",
+ program);
+ exit(7);
+ }
+
+ /*
+ * FNV test vector processing, if needed
+ */
+ if (t_flag >= 0) {
+ int code; /* test vector that failed, starting at 1 */
+
+ /*
+ * perform all tests
+ */
+ code = test_fnv32(hash_type, hval, bmask, v_flag, t_flag);
+
+ /*
+ * evaluate the tests
+ */
+ if (code == 0) {
+ if (v_flag) {
+ printf("passed\n");
+ }
+ exit(0);
+ } else {
+ printf("failed vector (1 is 1st test): %d\n", code);
+ exit(8);
+ }
+ }
+
+ /*
+ * string hashing
+ */
+ if (s_flag) {
+
+ /* hash any other strings */
+ for (i=optind; i < argc; ++i) {
+ switch (hash_type) {
+ case FNV0_32:
+ case FNV1_32:
+ hval = fnv_32_str(argv[i], hval);
+ break;
+ case FNV1a_32:
+ hval = fnv_32a_str(argv[i], hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 9); /* exit(9) */
+ /*NOTREACHED*/
+ }
+ if (m_flag) {
+ print_fnv32(hval, bmask, v_flag, argv[i]);
+ }
+ }
+
+
+ /*
+ * file hashing
+ */
+ } else {
+
+ /*
+ * case: process only stdin
+ */
+ if (optind >= argc) {
+
+ /* case: process only stdin */
+ while ((readcnt = read(0, buf, BUF_SIZE)) > 0) {
+ switch (hash_type) {
+ case FNV0_32:
+ case FNV1_32:
+ hval = fnv_32_buf(buf, readcnt, hval);
+ break;
+ case FNV1a_32:
+ hval = fnv_32a_buf(buf, readcnt, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 10); /* exit(10) */
+ /*NOTREACHED*/
+ }
+ }
+ if (m_flag) {
+ print_fnv32(hval, bmask, v_flag, "(stdin)");
+ }
+
+ } else {
+
+ /*
+ * process any other files
+ */
+ for (i=optind; i < argc; ++i) {
+
+ /* open the file */
+ fd = open(argv[i], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: unable to open file: %s\n",
+ program, argv[i]);
+ exit(4);
+ }
+
+ /* hash the file */
+ while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) {
+ switch (hash_type) {
+ case FNV0_32:
+ case FNV1_32:
+ hval = fnv_32_buf(buf, readcnt, hval);
+ break;
+ case FNV1a_32:
+ hval = fnv_32a_buf(buf, readcnt, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 11);/* exit(11) */
+ /*NOTREACHED*/
+ }
+ }
+
+ /* finish processing the file */
+ if (m_flag) {
+ print_fnv32(hval, bmask, v_flag, argv[i]);
+ }
+ close(fd);
+ }
+ }
+ }
+
+ /*
+ * report hash and exit
+ */
+ if (!m_flag) {
+ print_fnv32(hval, bmask, v_flag, "");
+ }
+ return 0; /* exit(0); */
+}
diff --git a/lib/fnv/fnv64.c b/lib/fnv/fnv64.c
new file mode 100644
index 0000000000..0662d4d657
--- /dev/null
+++ b/lib/fnv/fnv64.c
@@ -0,0 +1,591 @@
+/*
+ * fnv_64 - 64 bit Fowler/Noll/Vo hash of a buffer or string
+ *
+ * @(#) $Revision: 5.5 $
+ * @(#) $Id: fnv64.c,v 5.5 2012/03/21 01:38:12 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv64.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include "longlong.h"
+#include "fnv.h"
+
+#define WIDTH 64 /* bit width of hash */
+
+#define BUF_SIZE (32*1024) /* number of bytes to hash at a time */
+
+static char *usage =
+"usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n"
+"\n"
+"\t-b bcnt\tmask off all but the lower bcnt bits (default 64)\n"
+"\t-m\tmultiple hashes, one per line for each arg\n"
+"\t-s\thash arg as a string (ignoring terminating NUL bytes)\n"
+"\t-t code\t test hash code: (0 ==> generate test vectors\n"
+"\t\t\t\t 1 ==> validate against FNV test vectors)\n"
+"\t-v\tverbose mode, print arg after hash (implies -m)\n"
+"\targ\tstring (if -s was given) or filename (default stdin)\n"
+"\n"
+"\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n"
+"\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n"
+"\n"
+"\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n"
+"\n"
+"\t@(#) FNV Version: %s\n";
+static char *program; /* our name */
+
+
+/*
+ * test_fnv64 - test the FNV64 hash
+ *
+ * given:
+ * hash_type type of FNV hash to test
+ * init_hval initial hash value
+ * mask lower bit mask
+ * v_flag 1 => print test failure info on stderr
+ * code 0 ==> generate FNV test vectors
+ * 1 ==> validate against FNV test vectors
+ *
+ * returns: 0 ==> OK, else test vector failure number
+ */
+static int
+test_fnv64(enum fnv_type hash_type, Fnv64_t init_hval,
+ Fnv64_t mask, int v_flag, int code)
+{
+ struct test_vector *t; /* FNV test vestor */
+ Fnv64_t hval; /* current hash value */
+ int tstnum; /* test vector that failed, starting at 1 */
+
+ /*
+ * print preamble if generating test vectors
+ */
+ if (code == 0) {
+ switch (hash_type) {
+ case FNV0_64:
+ printf("struct fnv0_64_test_vector fnv0_64_vector[] = {\n");
+ break;
+ case FNV1_64:
+ printf("struct fnv1_64_test_vector fnv1_64_vector[] = {\n");
+ break;
+ case FNV1a_64:
+ printf("struct fnv1a_64_test_vector fnv1a_64_vector[] = {\n");
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 12); /* exit(12) */
+ /*NOTREACHED*/
+ }
+ }
+
+ /*
+ * loop thru all test vectors
+ */
+ for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) {
+
+ /*
+ * compute the FNV hash
+ */
+ hval = init_hval;
+ switch (hash_type) {
+ case FNV0_64:
+ case FNV1_64:
+ hval = fnv_64_buf(t->buf, t->len, hval);
+ break;
+ case FNV1a_64:
+ hval = fnv_64a_buf(t->buf, t->len, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 13); /* exit(13) */
+ /*NOTREACHED*/
+ }
+
+ /*
+ * print the vector
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+ /*
+ * HAVE_64BIT_LONG_LONG testing
+ */
+ switch (code) {
+ case 0: /* generate the test vector */
+ printf(" { &fnv_test_str[%d], (Fnv64_t) 0x%016llxULL },\n",
+ tstnum-1, hval & mask);
+ break;
+
+ case 1: /* validate against test vector */
+ switch (hash_type) {
+ case FNV0_64:
+ if ((hval&mask) != (fnv0_64_vector[tstnum-1].fnv0_64 & mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv0_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%016llx != generated: 0x%016llx\n",
+ program,
+ (hval&mask),
+ (fnv0_64_vector[tstnum-1].fnv0_64 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1_64:
+ if ((hval&mask) != (fnv1_64_vector[tstnum-1].fnv1_64 & mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%016llx != generated: 0x%016llx\n",
+ program,
+ (hval&mask),
+ (fnv1_64_vector[tstnum-1].fnv1_64 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1a_64:
+ if ((hval&mask) != (fnv1a_64_vector[tstnum-1].fnv1a_64 &mask)) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1a_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%016llx != generated: 0x%016llx\n",
+ program,
+ (hval&mask),
+ (fnv1a_64_vector[tstnum-1].fnv1a_64 & mask));
+ }
+ return tstnum;
+ }
+ break;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
+ exit(14);
+ }
+#else /* HAVE_64BIT_LONG_LONG */
+ /*
+ * non HAVE_64BIT_LONG_LONG testing
+ */
+ switch (code) {
+ case 0: /* generate the test vector */
+ printf(" { &fnv_test_str[%d], "
+ "(Fnv64_t) {0x%08lxUL, 0x%08lxUL} },\n",
+ tstnum-1,
+ (hval.w32[0] & mask.w32[0]),
+ (hval.w32[1] & mask.w32[1]));
+ break;
+
+ case 1: /* validate against test vector */
+ switch (hash_type) {
+ case FNV0_64:
+ if (((hval.w32[0] & mask.w32[0]) !=
+ (fnv0_64_vector[tstnum-1].fnv0_64.w32[0] &
+ mask.w32[0])) &&
+ ((hval.w32[1] & mask.w32[1]) !=
+ (fnv0_64_vector[tstnum-1].fnv0_64.w32[1] &
+ mask.w32[1]))) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv0_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08llx%08llx != "
+ "generated: 0x%08llx%08llx\n",
+ program,
+ (hval.w32[0] & mask.w32[0]),
+ (hval.w32[1] & mask.w32[1]),
+ ((fnv0_64_vector[tstnum-1].fnv0_64.w32[0] &
+ mask.w32[0])),
+ ((fnv0_64_vector[tstnum-1].fnv0_64.w32[1] &
+ mask.w32[1])));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1_64:
+ if (((hval.w32[0] & mask.w32[0]) !=
+ (fnv1_64_vector[tstnum-1].fnv1_64.w32[0] &
+ mask.w32[0])) &&
+ ((hval.w32[1] & mask.w32[1]) !=
+ (fnv1_64_vector[tstnum-1].fnv1_64.w32[1] &
+ mask.w32[1]))) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08llx%08llx != "
+ "generated: 0x%08llx%08llx\n",
+ program,
+ (hval.w32[0] & mask.w32[0]),
+ (hval.w32[1] & mask.w32[1]),
+ ((fnv1_64_vector[tstnum-1].fnv1_64.w32[0] &
+ mask.w32[0])),
+ ((fnv1_64_vector[tstnum-1].fnv1_64.w32[1] &
+ mask.w32[1])));
+ }
+ return tstnum;
+ }
+ break;
+ case FNV1a_64:
+ if (((hval.w32[0] & mask.w32[0]) !=
+ (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] &
+ mask.w32[0])) &&
+ ((hval.w32[1] & mask.w32[1]) !=
+ (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] &
+ mask.w32[1]))) {
+ if (v_flag) {
+ fprintf(stderr, "%s: failed fnv1a_64 test # %d\n",
+ program, tstnum);
+ fprintf(stderr, "%s: test # 1 is 1st test\n", program);
+ fprintf(stderr,
+ "%s: expected 0x%08llx%08llx != "
+ "generated: 0x%08llx%08llx\n",
+ program,
+ (hval.w32[0] & mask.w32[0]),
+ (hval.w32[1] & mask.w32[1]),
+ ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] &
+ mask.w32[0])),
+ ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] &
+ mask.w32[1])));
+ }
+ return tstnum;
+ }
+ break;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
+ exit(15);
+ }
+#endif /* HAVE_64BIT_LONG_LONG */
+ }
+
+ /*
+ * print completion if generating test vectors
+ */
+ if (code == 0) {
+#if defined(HAVE_64BIT_LONG_LONG)
+ printf(" { NULL, (Fnv64_t) 0 }\n");
+#else /* HAVE_64BIT_LONG_LONG */
+ printf(" { NULL, (Fnv64_t) {0,0} }\n");
+#endif /* HAVE_64BIT_LONG_LONG */
+ printf("};\n");
+ }
+
+ /*
+ * no failures, return code 0 ==> all OK
+ */
+ return 0;
+}
+
+
+/*
+ * main - the main function
+ *
+ * See the above usage for details.
+ */
+int
+main(int argc, char *argv[])
+{
+ char buf[BUF_SIZE+1]; /* read buffer */
+ int readcnt; /* number of characters written */
+ Fnv64_t hval; /* current hash value */
+ int s_flag = 0; /* 1 => -s was given, hash args as strings */
+ int m_flag = 0; /* 1 => print multiple hashes, one per arg */
+ int v_flag = 0; /* 1 => verbose hash print */
+ int b_flag = WIDTH; /* -b flag value */
+ int t_flag = -1; /* FNV test vector code (0=>print, 1=>test) */
+ enum fnv_type hash_type = FNV_NONE; /* type of FNV hash to perform */
+ Fnv64_t bmask; /* mask to apply to output */
+ extern char *optarg; /* option argument */
+ extern int optind; /* argv index of the next arg */
+ int fd; /* open file to process */
+ char *p;
+ int i;
+
+ /*
+ * parse args
+ */
+ program = argv[0];
+ while ((i = getopt(argc, argv, "b:mst:v")) != -1) {
+ switch (i) {
+ case 'b': /* bcnt bit mask count */
+ b_flag = atoi(optarg);
+ break;
+ case 'm': /* print multiple hashes, one per arg */
+ m_flag = 1;
+ break;
+ case 's': /* hash args as strings */
+ s_flag = 1;
+ break;
+ case 't': /* FNV test vector code */
+ t_flag = atoi(optarg);
+ if (t_flag < 0 || t_flag > 1) {
+ fprintf(stderr, "%s: -t code must be 0 or 1\n", program);
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(1);
+ }
+ m_flag = 1;
+ break;
+ case 'v': /* verbose hash print */
+ m_flag = 1;
+ v_flag = 1;
+ break;
+ default:
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(1);
+ }
+ }
+ /* -t code incompatible with -b, -m and args */
+ if (t_flag >= 0) {
+ if (b_flag != WIDTH) {
+ fprintf(stderr, "%s: -t code incompatible with -b\n", program);
+ exit(2);
+ }
+ if (s_flag != 0) {
+ fprintf(stderr, "%s: -t code incompatible with -s\n", program);
+ exit(3);
+ }
+ if (optind < argc) {
+ fprintf(stderr, "%s: -t code incompatible args\n", program);
+ exit(4);
+ }
+ }
+ /* -s requires at least 1 arg */
+ if (s_flag && optind >= argc) {
+ fprintf(stderr, usage, program, FNV_VERSION);
+ exit(5);
+ }
+ /* limit -b values */
+ if (b_flag < 0 || b_flag > WIDTH) {
+ fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n",
+ program, b_flag, WIDTH);
+ exit(6);
+ }
+#if defined(HAVE_64BIT_LONG_LONG)
+ if (b_flag == WIDTH) {
+ bmask = (Fnv64_t)0xffffffffffffffffULL;
+ } else {
+ bmask = (Fnv64_t)((1ULL << b_flag) - 1ULL);
+ }
+#else /* HAVE_64BIT_LONG_LONG */
+ if (b_flag == WIDTH) {
+ bmask.w32[0] = 0xffffffffUL;
+ bmask.w32[1] = 0xffffffffUL;
+ } else if (b_flag >= WIDTH/2) {
+ bmask.w32[0] = 0xffffffffUL;
+ bmask.w32[1] = ((1UL << (b_flag-(WIDTH/2))) - 1UL);
+ } else {
+ bmask.w32[0] = ((1UL << b_flag) - 1UL);
+ bmask.w32[1] = 0UL;
+ }
+#endif /* HAVE_64BIT_LONG_LONG */
+
+ /*
+ * start with the initial basis depending on the hash type
+ */
+ p = strrchr(program, '/');
+ if (p == NULL) {
+ p = program;
+ } else {
+ ++p;
+ }
+ if (strcmp(p, "fnv064") == 0 || strcmp(p, "no64bit_fnv064") == 0) {
+ /* using non-recommended FNV-0 and zero initial basis */
+ hval = FNV0_64_INIT;
+ hash_type = FNV0_64;
+ } else if (strcmp(p, "fnv164") == 0 || strcmp(p, "no64bit_fnv164") == 0) {
+ /* using FNV-1 and non-zero initial basis */
+ hval = FNV1_64_INIT;
+ hash_type = FNV1_64;
+ } else if (strcmp(p, "fnv1a64") == 0 || strcmp(p, "no64bit_fnv1a64") == 0) {
+ /* start with the FNV-1a initial basis */
+ hval = FNV1A_64_INIT;
+ hash_type = FNV1a_64;
+ } else {
+ fprintf(stderr, "%s: unknown program name, unknown hash type\n",
+ program);
+ exit(7);
+ }
+
+ /*
+ * FNV test vector processing, if needed
+ */
+ if (t_flag >= 0) {
+ int code; /* test vector that failed, starting at 1 */
+
+ /*
+ * perform all tests
+ */
+ code = test_fnv64(hash_type, hval, bmask, v_flag, t_flag);
+
+ /*
+ * evaluate the tests
+ */
+ if (code == 0) {
+ if (v_flag) {
+ printf("passed\n");
+ }
+ exit(0);
+ } else {
+ printf("failed vector (1 is 1st test): %d\n", code);
+ exit(8);
+ }
+ }
+
+ /*
+ * string hashing
+ */
+ if (s_flag) {
+
+ /* hash any other strings */
+ for (i=optind; i < argc; ++i) {
+ switch (hash_type) {
+ case FNV0_64:
+ case FNV1_64:
+ hval = fnv_64_str(argv[i], hval);
+ break;
+ case FNV1a_64:
+ hval = fnv_64a_str(argv[i], hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 9); /* exit(9) */
+ /*NOTREACHED*/
+ }
+ if (m_flag) {
+ print_fnv64(hval, bmask, v_flag, argv[i]);
+ }
+ }
+
+
+ /*
+ * file hashing
+ */
+ } else {
+
+ /*
+ * case: process only stdin
+ */
+ if (optind >= argc) {
+
+ /* case: process only stdin */
+ while ((readcnt = read(0, buf, BUF_SIZE)) > 0) {
+ switch (hash_type) {
+ case FNV0_64:
+ case FNV1_64:
+ hval = fnv_64_buf(buf, readcnt, hval);
+ break;
+ case FNV1a_64:
+ hval = fnv_64a_buf(buf, readcnt, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 10); /* exit(10) */
+ /*NOTREACHED*/
+ }
+ }
+ if (m_flag) {
+ print_fnv64(hval, bmask, v_flag, "(stdin)");
+ }
+
+ } else {
+
+ /*
+ * process any other files
+ */
+ for (i=optind; i < argc; ++i) {
+
+ /* open the file */
+ fd = open(argv[i], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: unable to open file: %s\n",
+ program, argv[i]);
+ exit(4);
+ }
+
+ /* hash the file */
+ while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) {
+ switch (hash_type) {
+ case FNV0_64:
+ case FNV1_64:
+ hval = fnv_64_buf(buf, readcnt, hval);
+ break;
+ case FNV1a_64:
+ hval = fnv_64a_buf(buf, readcnt, hval);
+ break;
+ default:
+ unknown_hash_type(program, hash_type, 11);/* exit(11) */
+ /*NOTREACHED*/
+ }
+ }
+
+ /* finish processing the file */
+ if (m_flag) {
+ print_fnv64(hval, bmask, v_flag, argv[i]);
+ }
+ close(fd);
+ }
+ }
+ }
+
+ /*
+ * report hash and exit
+ */
+ if (!m_flag) {
+ print_fnv64(hval, bmask, v_flag, "");
+ }
+ return 0; /* exit(0); */
+}
diff --git a/lib/fnv/hash_32.c b/lib/fnv/hash_32.c
new file mode 100644
index 0000000000..077170ff6d
--- /dev/null
+++ b/lib/fnv/hash_32.c
@@ -0,0 +1,156 @@
+/*
+ * hash_32 - 32 bit Fowler/Noll/Vo hash code
+ *
+ * @(#) $Revision: 5.1 $
+ * @(#) $Id: hash_32.c,v 5.1 2009/06/30 09:13:32 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ ***
+ *
+ * NOTE: The FNV-0 historic hash is not recommended. One should use
+ * the FNV-1 hash instead.
+ *
+ * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the
+ * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
+ *
+ * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
+ * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdlib.h>
+#include "fnv.h"
+
+
+/*
+ * 32 bit magic FNV-0 and FNV-1 prime
+ */
+#define FNV_32_PRIME ((Fnv32_t)0x01000193)
+
+
+/*
+ * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * len - length of buffer in octets
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 32 bit hash as a static hash type
+ *
+ * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval
+ * argument on the first call to either fnv_32_buf() or fnv_32_str().
+ *
+ * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
+ * argument on the first call to either fnv_32_buf() or fnv_32_str().
+ */
+Fnv32_t
+fnv_32_buf(void *buf, size_t len, Fnv32_t hval)
+{
+ unsigned char *bp = (unsigned char *)buf; /* start of buffer */
+ unsigned char *be = bp + len; /* beyond end of buffer */
+
+ /*
+ * FNV-1 hash each octet in the buffer
+ */
+ while (bp < be) {
+
+ /* multiply by the 32 bit FNV magic prime mod 2^32 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_32_PRIME;
+#else
+ hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
+#endif
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv32_t)*bp++;
+ }
+
+ /* return our new hash value */
+ return hval;
+}
+
+
+/*
+ * fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string
+ *
+ * input:
+ * str - string to hash
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 32 bit hash as a static hash type
+ *
+ * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval
+ * argument on the first call to either fnv_32_buf() or fnv_32_str().
+ *
+ * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
+ * argument on the first call to either fnv_32_buf() or fnv_32_str().
+ */
+Fnv32_t
+fnv_32_str(char *str, Fnv32_t hval)
+{
+ unsigned char *s = (unsigned char *)str; /* unsigned string */
+
+ /*
+ * FNV-1 hash each octet in the buffer
+ */
+ while (*s) {
+
+ /* multiply by the 32 bit FNV magic prime mod 2^32 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_32_PRIME;
+#else
+ hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
+#endif
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv32_t)*s++;
+ }
+
+ /* return our new hash value */
+ return hval;
+}
diff --git a/lib/fnv/hash_32a.c b/lib/fnv/hash_32a.c
new file mode 100644
index 0000000000..8b10acf3e2
--- /dev/null
+++ b/lib/fnv/hash_32a.c
@@ -0,0 +1,144 @@
+/*
+ * hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code
+ *
+ * @(#) $Revision: 5.1 $
+ * @(#) $Id: hash_32a.c,v 5.1 2009/06/30 09:13:32 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32a.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ ***
+ *
+ * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
+ * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdlib.h>
+#include "fnv.h"
+
+
+/*
+ * 32 bit magic FNV-1a prime
+ */
+#define FNV_32_PRIME ((Fnv32_t)0x01000193)
+
+
+/*
+ * fnv_32a_buf - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * len - length of buffer in octets
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 32 bit hash as a static hash type
+ *
+ * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the
+ * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str().
+ */
+Fnv32_t
+fnv_32a_buf(void *buf, size_t len, Fnv32_t hval)
+{
+ unsigned char *bp = (unsigned char *)buf; /* start of buffer */
+ unsigned char *be = bp + len; /* beyond end of buffer */
+
+ /*
+ * FNV-1a hash each octet in the buffer
+ */
+ while (bp < be) {
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv32_t)*bp++;
+
+ /* multiply by the 32 bit FNV magic prime mod 2^32 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_32_PRIME;
+#else
+ hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
+#endif
+ }
+
+ /* return our new hash value */
+ return hval;
+}
+
+
+/*
+ * fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string
+ *
+ * input:
+ * str - string to hash
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 32 bit hash as a static hash type
+ *
+ * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the
+ * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str().
+ */
+Fnv32_t
+fnv_32a_str(char *str, Fnv32_t hval)
+{
+ unsigned char *s = (unsigned char *)str; /* unsigned string */
+
+ /*
+ * FNV-1a hash each octet in the buffer
+ */
+ while (*s) {
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv32_t)*s++;
+
+ /* multiply by the 32 bit FNV magic prime mod 2^32 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_32_PRIME;
+#else
+ hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
+#endif
+ }
+
+ /* return our new hash value */
+ return hval;
+}
diff --git a/lib/fnv/hash_64.c b/lib/fnv/hash_64.c
new file mode 100644
index 0000000000..4338605dca
--- /dev/null
+++ b/lib/fnv/hash_64.c
@@ -0,0 +1,312 @@
+/*
+ * hash_64 - 64 bit Fowler/Noll/Vo-0 hash code
+ *
+ * @(#) $Revision: 5.1 $
+ * @(#) $Id: hash_64.c,v 5.1 2009/06/30 09:01:38 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * NOTE: The FNV-0 historic hash is not recommended. One should use
+ * the FNV-1 hash instead.
+ *
+ * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
+ *
+ * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdlib.h>
+#include "fnv.h"
+
+
+/*
+ * FNV-0 defines the initial basis to be zero
+ */
+#if !defined(HAVE_64BIT_LONG_LONG)
+const Fnv64_t fnv0_64_init = { 0UL, 0UL };
+#endif /* ! HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * FNV-1 defines the initial basis to be non-zero
+ */
+#if !defined(HAVE_64BIT_LONG_LONG)
+const Fnv64_t fnv1_64_init = { 0x84222325UL, 0xcbf29ce4UL };
+#endif /* ! HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * 64 bit magic FNV-0 and FNV-1 prime
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+#define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL)
+#else /* HAVE_64BIT_LONG_LONG */
+#define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */
+#define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */
+#endif /* HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * fnv_64_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * len - length of buffer in octets
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 64 bit hash as a static hash type
+ *
+ * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval
+ * argument on the first call to either fnv_64_buf() or fnv_64_str().
+ *
+ * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval
+ * argument on the first call to either fnv_64_buf() or fnv_64_str().
+ */
+Fnv64_t
+fnv_64_buf(void *buf, size_t len, Fnv64_t hval)
+{
+ unsigned char *bp = (unsigned char *)buf; /* start of buffer */
+ unsigned char *be = bp + len; /* beyond end of buffer */
+
+#if defined(HAVE_64BIT_LONG_LONG)
+
+ /*
+ * FNV-1 hash each octet of the buffer
+ */
+ while (bp < be) {
+
+ /* multiply by the 64 bit FNV magic prime mod 2^64 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_64_PRIME;
+#else /* NO_FNV_GCC_OPTIMIZATION */
+ hval += (hval << 1) + (hval << 4) + (hval << 5) +
+ (hval << 7) + (hval << 8) + (hval << 40);
+#endif /* NO_FNV_GCC_OPTIMIZATION */
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv64_t)*bp++;
+ }
+
+#else /* HAVE_64BIT_LONG_LONG */
+
+ unsigned long val[4]; /* hash value in base 2^16 */
+ unsigned long tmp[4]; /* tmp 64 bit value */
+
+ /*
+ * Convert Fnv64_t hval into a base 2^16 array
+ */
+ val[0] = hval.w32[0];
+ val[1] = (val[0] >> 16);
+ val[0] &= 0xffff;
+ val[2] = hval.w32[1];
+ val[3] = (val[2] >> 16);
+ val[2] &= 0xffff;
+
+ /*
+ * FNV-1 hash each octet of the buffer
+ */
+ while (bp < be) {
+
+ /*
+ * multiply by the 64 bit FNV magic prime mod 2^64
+ *
+ * Using 0x100000001b3 we have the following digits base 2^16:
+ *
+ * 0x0 0x100 0x0 0x1b3
+ *
+ * which is the same as:
+ *
+ * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
+ */
+ /* multiply by the lowest order digit base 2^16 */
+ tmp[0] = val[0] * FNV_64_PRIME_LOW;
+ tmp[1] = val[1] * FNV_64_PRIME_LOW;
+ tmp[2] = val[2] * FNV_64_PRIME_LOW;
+ tmp[3] = val[3] * FNV_64_PRIME_LOW;
+ /* multiply by the other non-zero digit */
+ tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
+ tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
+ /* propagate carries */
+ tmp[1] += (tmp[0] >> 16);
+ val[0] = tmp[0] & 0xffff;
+ tmp[2] += (tmp[1] >> 16);
+ val[1] = tmp[1] & 0xffff;
+ val[3] = tmp[3] + (tmp[2] >> 16);
+ val[2] = tmp[2] & 0xffff;
+ /*
+ * Doing a val[3] &= 0xffff; is not really needed since it simply
+ * removes multiples of 2^64. We can discard these excess bits
+ * outside of the loop when we convert to Fnv64_t.
+ */
+
+ /* xor the bottom with the current octet */
+ val[0] ^= (unsigned long)*bp++;
+ }
+
+ /*
+ * Convert base 2^16 array back into an Fnv64_t
+ */
+ hval.w32[1] = ((val[3]<<16) | val[2]);
+ hval.w32[0] = ((val[1]<<16) | val[0]);
+
+#endif /* HAVE_64BIT_LONG_LONG */
+
+ /* return our new hash value */
+ return hval;
+}
+
+
+/*
+ * fnv_64_str - perform a 64 bit Fowler/Noll/Vo hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 64 bit hash as a static hash type
+ *
+ * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval
+ * argument on the first call to either fnv_64_buf() or fnv_64_str().
+ *
+ * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval
+ * argument on the first call to either fnv_64_buf() or fnv_64_str().
+ */
+Fnv64_t
+fnv_64_str(char *str, Fnv64_t hval)
+{
+ unsigned char *s = (unsigned char *)str; /* unsigned string */
+
+#if defined(HAVE_64BIT_LONG_LONG)
+
+ /*
+ * FNV-1 hash each octet of the string
+ */
+ while (*s) {
+
+ /* multiply by the 64 bit FNV magic prime mod 2^64 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_64_PRIME;
+#else /* NO_FNV_GCC_OPTIMIZATION */
+ hval += (hval << 1) + (hval << 4) + (hval << 5) +
+ (hval << 7) + (hval << 8) + (hval << 40);
+#endif /* NO_FNV_GCC_OPTIMIZATION */
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv64_t)*s++;
+ }
+
+#else /* !HAVE_64BIT_LONG_LONG */
+
+ unsigned long val[4]; /* hash value in base 2^16 */
+ unsigned long tmp[4]; /* tmp 64 bit value */
+
+ /*
+ * Convert Fnv64_t hval into a base 2^16 array
+ */
+ val[0] = hval.w32[0];
+ val[1] = (val[0] >> 16);
+ val[0] &= 0xffff;
+ val[2] = hval.w32[1];
+ val[3] = (val[2] >> 16);
+ val[2] &= 0xffff;
+
+ /*
+ * FNV-1 hash each octet of the string
+ */
+ while (*s) {
+
+ /*
+ * multiply by the 64 bit FNV magic prime mod 2^64
+ *
+ * Using 1099511628211, we have the following digits base 2^16:
+ *
+ * 0x0 0x100 0x0 0x1b3
+ *
+ * which is the same as:
+ *
+ * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
+ */
+ /* multiply by the lowest order digit base 2^16 */
+ tmp[0] = val[0] * FNV_64_PRIME_LOW;
+ tmp[1] = val[1] * FNV_64_PRIME_LOW;
+ tmp[2] = val[2] * FNV_64_PRIME_LOW;
+ tmp[3] = val[3] * FNV_64_PRIME_LOW;
+ /* multiply by the other non-zero digit */
+ tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
+ tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
+ /* propagate carries */
+ tmp[1] += (tmp[0] >> 16);
+ val[0] = tmp[0] & 0xffff;
+ tmp[2] += (tmp[1] >> 16);
+ val[1] = tmp[1] & 0xffff;
+ val[3] = tmp[3] + (tmp[2] >> 16);
+ val[2] = tmp[2] & 0xffff;
+ /*
+ * Doing a val[3] &= 0xffff; is not really needed since it simply
+ * removes multiples of 2^64. We can discard these excess bits
+ * outside of the loop when we convert to Fnv64_t.
+ */
+
+ /* xor the bottom with the current octet */
+ val[0] ^= (unsigned long)(*s++);
+ }
+
+ /*
+ * Convert base 2^16 array back into an Fnv64_t
+ */
+ hval.w32[1] = ((val[3]<<16) | val[2]);
+ hval.w32[0] = ((val[1]<<16) | val[0]);
+
+#endif /* !HAVE_64BIT_LONG_LONG */
+
+ /* return our new hash value */
+ return hval;
+}
diff --git a/lib/fnv/hash_64a.c b/lib/fnv/hash_64a.c
new file mode 100644
index 0000000000..6660f92ddf
--- /dev/null
+++ b/lib/fnv/hash_64a.c
@@ -0,0 +1,291 @@
+/*
+ * hash_64 - 64 bit Fowler/Noll/Vo-0 FNV-1a hash code
+ *
+ * @(#) $Revision: 5.1 $
+ * @(#) $Id: hash_64a.c,v 5.1 2009/06/30 09:01:38 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64a.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the
+ * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str().
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdlib.h>
+#include "fnv.h"
+
+
+/*
+ * FNV-1a defines the initial basis to be non-zero
+ */
+#if !defined(HAVE_64BIT_LONG_LONG)
+const Fnv64_t fnv1a_64_init = { 0x84222325, 0xcbf29ce4 };
+#endif /* ! HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * 64 bit magic FNV-1a prime
+ */
+#if defined(HAVE_64BIT_LONG_LONG)
+#define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL)
+#else /* HAVE_64BIT_LONG_LONG */
+#define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */
+#define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */
+#endif /* HAVE_64BIT_LONG_LONG */
+
+
+/*
+ * fnv_64a_buf - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * len - length of buffer in octets
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 64 bit hash as a static hash type
+ *
+ * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the
+ * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str().
+ */
+Fnv64_t
+fnv_64a_buf(void *buf, size_t len, Fnv64_t hval)
+{
+ unsigned char *bp = (unsigned char *)buf; /* start of buffer */
+ unsigned char *be = bp + len; /* beyond end of buffer */
+
+#if defined(HAVE_64BIT_LONG_LONG)
+ /*
+ * FNV-1a hash each octet of the buffer
+ */
+ while (bp < be) {
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv64_t)*bp++;
+
+ /* multiply by the 64 bit FNV magic prime mod 2^64 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_64_PRIME;
+#else /* NO_FNV_GCC_OPTIMIZATION */
+ hval += (hval << 1) + (hval << 4) + (hval << 5) +
+ (hval << 7) + (hval << 8) + (hval << 40);
+#endif /* NO_FNV_GCC_OPTIMIZATION */
+ }
+
+#else /* HAVE_64BIT_LONG_LONG */
+
+ unsigned long val[4]; /* hash value in base 2^16 */
+ unsigned long tmp[4]; /* tmp 64 bit value */
+
+ /*
+ * Convert Fnv64_t hval into a base 2^16 array
+ */
+ val[0] = hval.w32[0];
+ val[1] = (val[0] >> 16);
+ val[0] &= 0xffff;
+ val[2] = hval.w32[1];
+ val[3] = (val[2] >> 16);
+ val[2] &= 0xffff;
+
+ /*
+ * FNV-1a hash each octet of the buffer
+ */
+ while (bp < be) {
+
+ /* xor the bottom with the current octet */
+ val[0] ^= (unsigned long)*bp++;
+
+ /*
+ * multiply by the 64 bit FNV magic prime mod 2^64
+ *
+ * Using 0x100000001b3 we have the following digits base 2^16:
+ *
+ * 0x0 0x100 0x0 0x1b3
+ *
+ * which is the same as:
+ *
+ * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
+ */
+ /* multiply by the lowest order digit base 2^16 */
+ tmp[0] = val[0] * FNV_64_PRIME_LOW;
+ tmp[1] = val[1] * FNV_64_PRIME_LOW;
+ tmp[2] = val[2] * FNV_64_PRIME_LOW;
+ tmp[3] = val[3] * FNV_64_PRIME_LOW;
+ /* multiply by the other non-zero digit */
+ tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
+ tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
+ /* propagate carries */
+ tmp[1] += (tmp[0] >> 16);
+ val[0] = tmp[0] & 0xffff;
+ tmp[2] += (tmp[1] >> 16);
+ val[1] = tmp[1] & 0xffff;
+ val[3] = tmp[3] + (tmp[2] >> 16);
+ val[2] = tmp[2] & 0xffff;
+ /*
+ * Doing a val[3] &= 0xffff; is not really needed since it simply
+ * removes multiples of 2^64. We can discard these excess bits
+ * outside of the loop when we convert to Fnv64_t.
+ */
+ }
+
+ /*
+ * Convert base 2^16 array back into an Fnv64_t
+ */
+ hval.w32[1] = ((val[3]<<16) | val[2]);
+ hval.w32[0] = ((val[1]<<16) | val[0]);
+
+#endif /* HAVE_64BIT_LONG_LONG */
+
+ /* return our new hash value */
+ return hval;
+}
+
+
+/*
+ * fnv_64a_str - perform a 64 bit Fowler/Noll/Vo FNV-1a hash on a buffer
+ *
+ * input:
+ * buf - start of buffer to hash
+ * hval - previous hash value or 0 if first call
+ *
+ * returns:
+ * 64 bit hash as a static hash type
+ *
+ * NOTE: To use the recommended 64 bit FNV-1a hash, use FNV1A_64_INIT as the
+ * hval arg on the first call to either fnv_64a_buf() or fnv_64a_str().
+ */
+Fnv64_t
+fnv_64a_str(char *str, Fnv64_t hval)
+{
+ unsigned char *s = (unsigned char *)str; /* unsigned string */
+
+#if defined(HAVE_64BIT_LONG_LONG)
+
+ /*
+ * FNV-1a hash each octet of the string
+ */
+ while (*s) {
+
+ /* xor the bottom with the current octet */
+ hval ^= (Fnv64_t)*s++;
+
+ /* multiply by the 64 bit FNV magic prime mod 2^64 */
+#if defined(NO_FNV_GCC_OPTIMIZATION)
+ hval *= FNV_64_PRIME;
+#else /* NO_FNV_GCC_OPTIMIZATION */
+ hval += (hval << 1) + (hval << 4) + (hval << 5) +
+ (hval << 7) + (hval << 8) + (hval << 40);
+#endif /* NO_FNV_GCC_OPTIMIZATION */
+ }
+
+#else /* !HAVE_64BIT_LONG_LONG */
+
+ unsigned long val[4]; /* hash value in base 2^16 */
+ unsigned long tmp[4]; /* tmp 64 bit value */
+
+ /*
+ * Convert Fnv64_t hval into a base 2^16 array
+ */
+ val[0] = hval.w32[0];
+ val[1] = (val[0] >> 16);
+ val[0] &= 0xffff;
+ val[2] = hval.w32[1];
+ val[3] = (val[2] >> 16);
+ val[2] &= 0xffff;
+
+ /*
+ * FNV-1a hash each octet of the string
+ */
+ while (*s) {
+
+ /* xor the bottom with the current octet */
+
+ /*
+ * multiply by the 64 bit FNV magic prime mod 2^64
+ *
+ * Using 1099511628211, we have the following digits base 2^16:
+ *
+ * 0x0 0x100 0x0 0x1b3
+ *
+ * which is the same as:
+ *
+ * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
+ */
+ /* multiply by the lowest order digit base 2^16 */
+ tmp[0] = val[0] * FNV_64_PRIME_LOW;
+ tmp[1] = val[1] * FNV_64_PRIME_LOW;
+ tmp[2] = val[2] * FNV_64_PRIME_LOW;
+ tmp[3] = val[3] * FNV_64_PRIME_LOW;
+ /* multiply by the other non-zero digit */
+ tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
+ tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
+ /* propagate carries */
+ tmp[1] += (tmp[0] >> 16);
+ val[0] = tmp[0] & 0xffff;
+ tmp[2] += (tmp[1] >> 16);
+ val[1] = tmp[1] & 0xffff;
+ val[3] = tmp[3] + (tmp[2] >> 16);
+ val[2] = tmp[2] & 0xffff;
+ /*
+ * Doing a val[3] &= 0xffff; is not really needed since it simply
+ * removes multiples of 2^64. We can discard these excess bits
+ * outside of the loop when we convert to Fnv64_t.
+ */
+ val[0] ^= (unsigned long)(*s++);
+ }
+
+ /*
+ * Convert base 2^16 array back into an Fnv64_t
+ */
+ hval.w32[1] = ((val[3]<<16) | val[2]);
+ hval.w32[0] = ((val[1]<<16) | val[0]);
+
+#endif /* !HAVE_64BIT_LONG_LONG */
+
+ /* return our new hash value */
+ return hval;
+}
diff --git a/lib/fnv/have_ulong64.c b/lib/fnv/have_ulong64.c
new file mode 100644
index 0000000000..5c06262388
--- /dev/null
+++ b/lib/fnv/have_ulong64.c
@@ -0,0 +1,58 @@
+/*
+ * have_ulong64 - Determine if we have a 64 bit unsigned long long
+ *
+ * usage:
+ * have_ulong64 > longlong.h
+ *
+ * Not all systems have a 'long long type' so this may not compile on
+ * your system.
+ *
+ * This prog outputs the define:
+ *
+ * HAVE_64BIT_LONG_LONG
+ * defined ==> we have a 64 bit unsigned long long
+ * undefined ==> we must simulate a 64 bit unsigned long long
+ */
+/*
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+/*
+ * have the compiler try its hand with unsigned and signed long longs
+ */
+#if ! defined(NO64BIT_LONG_LONG)
+unsigned long long val = 1099511628211ULL;
+#endif /* NO64BIT_LONG_LONG */
+
+int
+main(void)
+{
+ /*
+ * ensure that the length of long long val is what we expect
+ */
+#if defined(NO64BIT_LONG_LONG)
+ printf("#undef HAVE_64BIT_LONG_LONG\t/* no */\n");
+#else /* NO64BIT_LONG_LONG */
+ if (val == 1099511628211ULL && sizeof(val) == 8) {
+ printf("#define HAVE_64BIT_LONG_LONG\t/* yes */\n");
+ }
+#endif /* NO64BIT_LONG_LONG */
+
+ /* exit(0); */
+ return 0;
+}
diff --git a/lib/fnv/longlong.h b/lib/fnv/longlong.h
new file mode 100644
index 0000000000..c8cfe48f29
--- /dev/null
+++ b/lib/fnv/longlong.h
@@ -0,0 +1,18 @@
+/*
+ * DO NOT EDIT -- generated by the Makefile
+ */
+
+#if !defined(__LONGLONG_H__)
+#define __LONGLONG_H__
+
+/* do we have/want to use a long long type? */
+#define HAVE_64BIT_LONG_LONG /* yes */
+
+/*
+ * NO64BIT_LONG_LONG undef HAVE_64BIT_LONG_LONG
+ */
+#if defined(NO64BIT_LONG_LONG)
+#undef HAVE_64BIT_LONG_LONG
+#endif /* NO64BIT_LONG_LONG */
+
+#endif /* !__LONGLONG_H__ */
diff --git a/lib/fnv/qmk_fnv_type_validation.c b/lib/fnv/qmk_fnv_type_validation.c
new file mode 100644
index 0000000000..e8576617ba
--- /dev/null
+++ b/lib/fnv/qmk_fnv_type_validation.c
@@ -0,0 +1,14 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "fnv.h"
+
+// This library was originally sourced from:
+// http://www.isthe.com/chongo/tech/comp/fnv/index.html
+//
+// Version at the time of retrieval on 2022-06-26: v5.0.3
+
+_Static_assert(sizeof(long long) == 8, "long long should be 64 bits");
+_Static_assert(sizeof(unsigned long long) == 8, "unsigned long long should be 64 bits");
+
+_Static_assert(sizeof(Fnv32_t) == 4, "Fnv32_t should be 32 bits");
+_Static_assert(sizeof(Fnv64_t) == 8, "Fnv64_t should be 64 bits");
diff --git a/lib/fnv/test_fnv.c b/lib/fnv/test_fnv.c
new file mode 100644
index 0000000000..efec3dec1d
--- /dev/null
+++ b/lib/fnv/test_fnv.c
@@ -0,0 +1,2237 @@
+/*
+ * test_fnv - FNV test suite
+ *
+ * @(#) $Revision: 5.3 $
+ * @(#) $Id: test_fnv.c,v 5.3 2009/06/30 11:50:41 chongo Exp $
+ * @(#) $Source: /usr/local/src/cmd/fnv/RCS/test_fnv.c,v $
+ *
+ ***
+ *
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of this hash algorithm was taken from an idea sent
+ * as reviewer comments to the IEEE POSIX P1003.2 committee by:
+ *
+ * Phong Vo (http://www.research.att.com/info/kpv/)
+ * Glenn Fowler (http://www.research.att.com/~gsf/)
+ *
+ * In a subsequent ballot round:
+ *
+ * Landon Curt Noll (http://www.isthe.com/chongo/)
+ *
+ * improved on their algorithm. Some people tried this hash
+ * and found that it worked rather well. In an EMail message
+ * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
+ *
+ * FNV hashes are designed to be fast while maintaining a low
+ * collision rate. The FNV speed allows one to quickly hash lots
+ * of data while maintaining a reasonable collision rate. See:
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html
+ *
+ * for more details as well as other forms of the FNV hash.
+ *
+ ***
+ *
+ * Please do not copyright this code. This code is in the public domain.
+ *
+ * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * By:
+ * chongo <Landon Curt Noll> /\oo/\
+ * http://www.isthe.com/chongo/
+ *
+ * Share and Enjoy! :-)
+ */
+
+#include <stdio.h>
+#include "longlong.h"
+#include "fnv.h"
+
+#define LEN(x) (sizeof(x)-1)
+/* TEST macro does not include trailing NUL byte in the test vector */
+#define TEST(x) {x, LEN(x)}
+/* TEST0 macro includes the trailing NUL byte in the test vector */
+#define TEST0(x) {x, sizeof(x)}
+/* REPEAT500 - repeat a string 500 times */
+#define R500(x) R100(x)R100(x)R100(x)R100(x)R100(x)
+#define R100(x) R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)R10(x)
+#define R10(x) x x x x x x x x x x
+
+/*
+ * FNV test vectors
+ *
+ * NOTE: A NULL pointer marks beyond the end of the test vectors.
+ *
+ * NOTE: The order of the fnv_test_str[] test vectors is 1-to-1 with:
+ *
+ * struct fnv0_32_test_vector fnv0_32_vector[];
+ * struct fnv1_32_test_vector fnv1_32_vector[];
+ * struct fnv1a_32_test_vector fnv1a_32_vector[];
+ * struct fnv0_64_test_vector fnv0_64_vector[];
+ * struct fnv1_64_test_vector fnv1_64_vector[];
+ * struct fnv1a_64_test_vector fnv1a_64_vector[];
+ *
+ * IMPORTANT NOTE:
+ *
+ * If you change the fnv_test_str[] array, you need
+ * to also change ALL of the above fnv*_vector arrays!!!
+ *
+ * To rebuild, try:
+ *
+ * make vector.c
+ *
+ * and then fold the results into the source file.
+ * Of course, you better make sure that the vaules
+ * produced by the above command are valid, otherwise
+ * you will be testing against invalid vectors!
+ */
+struct test_vector fnv_test_str[] = {
+ TEST(""),
+ TEST("a"),
+ TEST("b"),
+ TEST("c"),
+ TEST("d"),
+ TEST("e"),
+ TEST("f"),
+ TEST("fo"),
+ TEST("foo"),
+ TEST("foob"),
+ TEST("fooba"),
+ TEST("foobar"),
+ TEST0(""),
+ TEST0("a"),
+ TEST0("b"),
+ TEST0("c"),
+ TEST0("d"),
+ TEST0("e"),
+ TEST0("f"),
+ TEST0("fo"),
+ TEST0("foo"),
+ TEST0("foob"),
+ TEST0("fooba"),
+ TEST0("foobar"),
+ TEST("ch"),
+ TEST("cho"),
+ TEST("chon"),
+ TEST("chong"),
+ TEST("chongo"),
+ TEST("chongo "),
+ TEST("chongo w"),
+ TEST("chongo wa"),
+ TEST("chongo was"),
+ TEST("chongo was "),
+ TEST("chongo was h"),
+ TEST("chongo was he"),
+ TEST("chongo was her"),
+ TEST("chongo was here"),
+ TEST("chongo was here!"),
+ TEST("chongo was here!\n"),
+ TEST0("ch"),
+ TEST0("cho"),
+ TEST0("chon"),
+ TEST0("chong"),
+ TEST0("chongo"),
+ TEST0("chongo "),
+ TEST0("chongo w"),
+ TEST0("chongo wa"),
+ TEST0("chongo was"),
+ TEST0("chongo was "),
+ TEST0("chongo was h"),
+ TEST0("chongo was he"),
+ TEST0("chongo was her"),
+ TEST0("chongo was here"),
+ TEST0("chongo was here!"),
+ TEST0("chongo was here!\n"),
+ TEST("cu"),
+ TEST("cur"),
+ TEST("curd"),
+ TEST("curds"),
+ TEST("curds "),
+ TEST("curds a"),
+ TEST("curds an"),
+ TEST("curds and"),
+ TEST("curds and "),
+ TEST("curds and w"),
+ TEST("curds and wh"),
+ TEST("curds and whe"),
+ TEST("curds and whey"),
+ TEST("curds and whey\n"),
+ TEST0("cu"),
+ TEST0("cur"),
+ TEST0("curd"),
+ TEST0("curds"),
+ TEST0("curds "),
+ TEST0("curds a"),
+ TEST0("curds an"),
+ TEST0("curds and"),
+ TEST0("curds and "),
+ TEST0("curds and w"),
+ TEST0("curds and wh"),
+ TEST0("curds and whe"),
+ TEST0("curds and whey"),
+ TEST0("curds and whey\n"),
+ TEST("hi"), TEST0("hi"),
+ TEST("hello"), TEST0("hello"),
+ TEST("\xff\x00\x00\x01"), TEST("\x01\x00\x00\xff"),
+ TEST("\xff\x00\x00\x02"), TEST("\x02\x00\x00\xff"),
+ TEST("\xff\x00\x00\x03"), TEST("\x03\x00\x00\xff"),
+ TEST("\xff\x00\x00\x04"), TEST("\x04\x00\x00\xff"),
+ TEST("\x40\x51\x4e\x44"), TEST("\x44\x4e\x51\x40"),
+ TEST("\x40\x51\x4e\x4a"), TEST("\x4a\x4e\x51\x40"),
+ TEST("\x40\x51\x4e\x54"), TEST("\x54\x4e\x51\x40"),
+ TEST("127.0.0.1"), TEST0("127.0.0.1"),
+ TEST("127.0.0.2"), TEST0("127.0.0.2"),
+ TEST("127.0.0.3"), TEST0("127.0.0.3"),
+ TEST("64.81.78.68"), TEST0("64.81.78.68"),
+ TEST("64.81.78.74"), TEST0("64.81.78.74"),
+ TEST("64.81.78.84"), TEST0("64.81.78.84"),
+ TEST("feedface"), TEST0("feedface"),
+ TEST("feedfacedaffdeed"), TEST0("feedfacedaffdeed"),
+ TEST("feedfacedeadbeef"), TEST0("feedfacedeadbeef"),
+ TEST("line 1\nline 2\nline 3"),
+ TEST("chongo <Landon Curt Noll> /\\../\\"),
+ TEST0("chongo <Landon Curt Noll> /\\../\\"),
+ TEST("chongo (Landon Curt Noll) /\\../\\"),
+ TEST0("chongo (Landon Curt Noll) /\\../\\"),
+ TEST("http://antwrp.gsfc.nasa.gov/apod/astropix.html"),
+ TEST("http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash"),
+ TEST("http://epod.usra.edu/"),
+ TEST("http://exoplanet.eu/"),
+ TEST("http://hvo.wr.usgs.gov/cam3/"),
+ TEST("http://hvo.wr.usgs.gov/cams/HMcam/"),
+ TEST("http://hvo.wr.usgs.gov/kilauea/update/deformation.html"),
+ TEST("http://hvo.wr.usgs.gov/kilauea/update/images.html"),
+ TEST("http://hvo.wr.usgs.gov/kilauea/update/maps.html"),
+ TEST("http://hvo.wr.usgs.gov/volcanowatch/current_issue.html"),
+ TEST("http://neo.jpl.nasa.gov/risk/"),
+ TEST("http://norvig.com/21-days.html"),
+ TEST("http://primes.utm.edu/curios/home.php"),
+ TEST("http://slashdot.org/"),
+ TEST("http://tux.wr.usgs.gov/Maps/155.25-19.5.html"),
+ TEST("http://volcano.wr.usgs.gov/kilaueastatus.php"),
+ TEST("http://www.avo.alaska.edu/activity/Redoubt.php"),
+ TEST("http://www.dilbert.com/fast/"),
+ TEST("http://www.fourmilab.ch/gravitation/orbits/"),
+ TEST("http://www.fpoa.net/"),
+ TEST("http://www.ioccc.org/index.html"),
+ TEST("http://www.isthe.com/cgi-bin/number.cgi"),
+ TEST("http://www.isthe.com/chongo/bio.html"),
+ TEST("http://www.isthe.com/chongo/index.html"),
+ TEST("http://www.isthe.com/chongo/src/calc/lucas-calc"),
+ TEST("http://www.isthe.com/chongo/tech/astro/venus2004.html"),
+ TEST("http://www.isthe.com/chongo/tech/astro/vita.html"),
+ TEST("http://www.isthe.com/chongo/tech/comp/c/expert.html"),
+ TEST("http://www.isthe.com/chongo/tech/comp/calc/index.html"),
+ TEST("http://www.isthe.com/chongo/tech/comp/fnv/index.html"),
+ TEST("http://www.isthe.com/chongo/tech/math/number/howhigh.html"),
+ TEST("http://www.isthe.com/chongo/tech/math/number/number.html"),
+ TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html"),
+ TEST("http://www.isthe.com/chongo/tech/math/prime/mersenne.html#largest"),
+ TEST("http://www.lavarnd.org/cgi-bin/corpspeak.cgi"),
+ TEST("http://www.lavarnd.org/cgi-bin/haiku.cgi"),
+ TEST("http://www.lavarnd.org/cgi-bin/rand-none.cgi"),
+ TEST("http://www.lavarnd.org/cgi-bin/randdist.cgi"),
+ TEST("http://www.lavarnd.org/index.html"),
+ TEST("http://www.lavarnd.org/what/nist-test.html"),
+ TEST("http://www.macosxhints.com/"),
+ TEST("http://www.mellis.com/"),
+ TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/havoalert.cfm"),
+ TEST("http://www.nature.nps.gov/air/webcams/parks/havoso2alert/timelines_24.cfm"),
+ TEST("http://www.paulnoll.com/"),
+ TEST("http://www.pepysdiary.com/"),
+ TEST("http://www.sciencenews.org/index/home/activity/view"),
+ TEST("http://www.skyandtelescope.com/"),
+ TEST("http://www.sput.nl/~rob/sirius.html"),
+ TEST("http://www.systemexperts.com/"),
+ TEST("http://www.tq-international.com/phpBB3/index.php"),
+ TEST("http://www.travelquesttours.com/index.htm"),
+ TEST("http://www.wunderground.com/global/stations/89606.html"),
+ TEST(R10("21701")),
+ TEST(R10("M21701")),
+ TEST(R10("2^21701-1")),
+ TEST(R10("\x54\xc5")),
+ TEST(R10("\xc5\x54")),
+ TEST(R10("23209")),
+ TEST(R10("M23209")),
+ TEST(R10("2^23209-1")),
+ TEST(R10("\x5a\xa9")),
+ TEST(R10("\xa9\x5a")),
+ TEST(R10("391581216093")),
+ TEST(R10("391581*2^216093-1")),
+ TEST(R10("\x05\xf9\x9d\x03\x4c\x81")),
+ TEST(R10("FEDCBA9876543210")),
+ TEST(R10("\xfe\xdc\xba\x98\x76\x54\x32\x10")),
+ TEST(R10("EFCDAB8967452301")),
+ TEST(R10("\xef\xcd\xab\x89\x67\x45\x23\x01")),
+ TEST(R10("0123456789ABCDEF")),
+ TEST(R10("\x01\x23\x45\x67\x89\xab\xcd\xef")),
+ TEST(R10("1032547698BADCFE")),
+ TEST(R10("\x10\x32\x54\x76\x98\xba\xdc\xfe")),
+ TEST(R500("\x00")),
+ TEST(R500("\x07")),
+ TEST(R500("~")),
+ TEST(R500("\x7f")),
+ {NULL, 0} /* MUST BE LAST */
+};
+
+
+/*
+ * insert the contents of vector.c below
+ *
+ * make vector.c
+ * :r vector.c
+ */
+/* start of output generated by make vector.c */
+
+/* FNV-0 32 bit test vectors */
+struct fnv0_32_test_vector fnv0_32_vector[] = {
+ { &fnv_test_str[0], (Fnv32_t) 0x00000000UL },
+ { &fnv_test_str[1], (Fnv32_t) 0x00000061UL },
+ { &fnv_test_str[2], (Fnv32_t) 0x00000062UL },
+ { &fnv_test_str[3], (Fnv32_t) 0x00000063UL },
+ { &fnv_test_str[4], (Fnv32_t) 0x00000064UL },
+ { &fnv_test_str[5], (Fnv32_t) 0x00000065UL },
+ { &fnv_test_str[6], (Fnv32_t) 0x00000066UL },
+ { &fnv_test_str[7], (Fnv32_t) 0x6600a0fdUL },
+ { &fnv_test_str[8], (Fnv32_t) 0x8ffd6e28UL },
+ { &fnv_test_str[9], (Fnv32_t) 0xd3f4689aUL },
+ { &fnv_test_str[10], (Fnv32_t) 0x43c0aa0fUL },
+ { &fnv_test_str[11], (Fnv32_t) 0xb74bb5efUL },
+ { &fnv_test_str[12], (Fnv32_t) 0x00000000UL },
+ { &fnv_test_str[13], (Fnv32_t) 0x610098b3UL },
+ { &fnv_test_str[14], (Fnv32_t) 0x62009a46UL },
+ { &fnv_test_str[15], (Fnv32_t) 0x63009bd9UL },
+ { &fnv_test_str[16], (Fnv32_t) 0x64009d6cUL },
+ { &fnv_test_str[17], (Fnv32_t) 0x65009effUL },
+ { &fnv_test_str[18], (Fnv32_t) 0x6600a092UL },
+ { &fnv_test_str[19], (Fnv32_t) 0x8ffd6e47UL },
+ { &fnv_test_str[20], (Fnv32_t) 0xd3f468f8UL },
+ { &fnv_test_str[21], (Fnv32_t) 0x43c0aa6eUL },
+ { &fnv_test_str[22], (Fnv32_t) 0xb74bb59dUL },
+ { &fnv_test_str[23], (Fnv32_t) 0x7b2f673dUL },
+ { &fnv_test_str[24], (Fnv32_t) 0x63009bb1UL },
+ { &fnv_test_str[25], (Fnv32_t) 0x8af517ccUL },
+ { &fnv_test_str[26], (Fnv32_t) 0x8bd4764aUL },
+ { &fnv_test_str[27], (Fnv32_t) 0x69763619UL },
+ { &fnv_test_str[28], (Fnv32_t) 0x1e172934UL },
+ { &fnv_test_str[29], (Fnv32_t) 0x9275dcfcUL },
+ { &fnv_test_str[30], (Fnv32_t) 0x8b8ae0c3UL },
+ { &fnv_test_str[31], (Fnv32_t) 0x6e9fd298UL },
+ { &fnv_test_str[32], (Fnv32_t) 0xbd98853bUL },
+ { &fnv_test_str[33], (Fnv32_t) 0xb219bbc1UL },
+ { &fnv_test_str[34], (Fnv32_t) 0x1f8290bbUL },
+ { &fnv_test_str[35], (Fnv32_t) 0x5589d604UL },
+ { &fnv_test_str[36], (Fnv32_t) 0xabfbe83eUL },
+ { &fnv_test_str[37], (Fnv32_t) 0xfb8e99ffUL },
+ { &fnv_test_str[38], (Fnv32_t) 0x007c6c4cUL },
+ { &fnv_test_str[39], (Fnv32_t) 0x0fde7baeUL },
+ { &fnv_test_str[40], (Fnv32_t) 0x8af517a3UL },
+ { &fnv_test_str[41], (Fnv32_t) 0x8bd47624UL },
+ { &fnv_test_str[42], (Fnv32_t) 0x6976367eUL },
+ { &fnv_test_str[43], (Fnv32_t) 0x1e17295bUL },
+ { &fnv_test_str[44], (Fnv32_t) 0x9275dcdcUL },
+ { &fnv_test_str[45], (Fnv32_t) 0x8b8ae0b4UL },
+ { &fnv_test_str[46], (Fnv32_t) 0x6e9fd2f9UL },
+ { &fnv_test_str[47], (Fnv32_t) 0xbd988548UL },
+ { &fnv_test_str[48], (Fnv32_t) 0xb219bbe1UL },
+ { &fnv_test_str[49], (Fnv32_t) 0x1f8290d3UL },
+ { &fnv_test_str[50], (Fnv32_t) 0x5589d661UL },
+ { &fnv_test_str[51], (Fnv32_t) 0xabfbe84cUL },
+ { &fnv_test_str[52], (Fnv32_t) 0xfb8e999aUL },
+ { &fnv_test_str[53], (Fnv32_t) 0x007c6c6dUL },
+ { &fnv_test_str[54], (Fnv32_t) 0x0fde7ba4UL },
+ { &fnv_test_str[55], (Fnv32_t) 0xa93cb2eaUL },
+ { &fnv_test_str[56], (Fnv32_t) 0x63009bacUL },
+ { &fnv_test_str[57], (Fnv32_t) 0x85f50fb6UL },
+ { &fnv_test_str[58], (Fnv32_t) 0x96c7bbe6UL },
+ { &fnv_test_str[59], (Fnv32_t) 0x426ccb61UL },
+ { &fnv_test_str[60], (Fnv32_t) 0xf2442993UL },
+ { &fnv_test_str[61], (Fnv32_t) 0xf44d7208UL },
+ { &fnv_test_str[62], (Fnv32_t) 0x9dea82f6UL },
+ { &fnv_test_str[63], (Fnv32_t) 0x8e2c2926UL },
+ { &fnv_test_str[64], (Fnv32_t) 0xf584c6f2UL },
+ { &fnv_test_str[65], (Fnv32_t) 0x72052e81UL },
+ { &fnv_test_str[66], (Fnv32_t) 0xff28357bUL },
+ { &fnv_test_str[67], (Fnv32_t) 0x274c30c4UL },
+ { &fnv_test_str[68], (Fnv32_t) 0xa0f0c4f5UL },
+ { &fnv_test_str[69], (Fnv32_t) 0x50060da5UL },
+ { &fnv_test_str[70], (Fnv32_t) 0x85f50fc4UL },
+ { &fnv_test_str[71], (Fnv32_t) 0x96c7bb82UL },
+ { &fnv_test_str[72], (Fnv32_t) 0x426ccb12UL },
+ { &fnv_test_str[73], (Fnv32_t) 0xf24429b3UL },
+ { &fnv_test_str[74], (Fnv32_t) 0xf44d7269UL },
+ { &fnv_test_str[75], (Fnv32_t) 0x9dea8298UL },
+ { &fnv_test_str[76], (Fnv32_t) 0x8e2c2942UL },
+ { &fnv_test_str[77], (Fnv32_t) 0xf584c6d2UL },
+ { &fnv_test_str[78], (Fnv32_t) 0x72052ef6UL },
+ { &fnv_test_str[79], (Fnv32_t) 0xff283513UL },
+ { &fnv_test_str[80], (Fnv32_t) 0x274c30a1UL },
+ { &fnv_test_str[81], (Fnv32_t) 0xa0f0c48cUL },
+ { &fnv_test_str[82], (Fnv32_t) 0x50060dafUL },
+ { &fnv_test_str[83], (Fnv32_t) 0x9e877abfUL },
+ { &fnv_test_str[84], (Fnv32_t) 0x6800a3d1UL },
+ { &fnv_test_str[85], (Fnv32_t) 0x8a01e203UL },
+ { &fnv_test_str[86], (Fnv32_t) 0xec6d6be8UL },
+ { &fnv_test_str[87], (Fnv32_t) 0x1840de38UL },
+ { &fnv_test_str[88], (Fnv32_t) 0xa7cc97b4UL },
+ { &fnv_test_str[89], (Fnv32_t) 0x3ee6b3b4UL },
+ { &fnv_test_str[90], (Fnv32_t) 0xa7cc97b7UL },
+ { &fnv_test_str[91], (Fnv32_t) 0x7dcd6669UL },
+ { &fnv_test_str[92], (Fnv32_t) 0xa7cc97b6UL },
+ { &fnv_test_str[93], (Fnv32_t) 0xbcb4191eUL },
+ { &fnv_test_str[94], (Fnv32_t) 0xa7cc97b1UL },
+ { &fnv_test_str[95], (Fnv32_t) 0xfb9acdd3UL },
+ { &fnv_test_str[96], (Fnv32_t) 0x89380433UL },
+ { &fnv_test_str[97], (Fnv32_t) 0x8acd2855UL },
+ { &fnv_test_str[98], (Fnv32_t) 0x8938043dUL },
+ { &fnv_test_str[99], (Fnv32_t) 0xcaeed493UL },
+ { &fnv_test_str[100], (Fnv32_t) 0x89380423UL },
+ { &fnv_test_str[101], (Fnv32_t) 0x59382a25UL },
+ { &fnv_test_str[102], (Fnv32_t) 0x567f75d7UL },
+ { &fnv_test_str[103], (Fnv32_t) 0x01a68175UL },
+ { &fnv_test_str[104], (Fnv32_t) 0x567f75d4UL },
+ { &fnv_test_str[105], (Fnv32_t) 0xfea67cbcUL },
+ { &fnv_test_str[106], (Fnv32_t) 0x567f75d5UL },
+ { &fnv_test_str[107], (Fnv32_t) 0xffa67e4fUL },
+ { &fnv_test_str[108], (Fnv32_t) 0xd131b668UL },
+ { &fnv_test_str[109], (Fnv32_t) 0xb94225b8UL },
+ { &fnv_test_str[110], (Fnv32_t) 0xd231b7d7UL },
+ { &fnv_test_str[111], (Fnv32_t) 0xbb446775UL },
+ { &fnv_test_str[112], (Fnv32_t) 0xdf31cc6eUL },
+ { &fnv_test_str[113], (Fnv32_t) 0xc964d12aUL },
+ { &fnv_test_str[114], (Fnv32_t) 0x23af8f9fUL },
+ { &fnv_test_str[115], (Fnv32_t) 0xcc5f174dUL },
+ { &fnv_test_str[116], (Fnv32_t) 0x96b29b8cUL },
+ { &fnv_test_str[117], (Fnv32_t) 0xc72add64UL },
+ { &fnv_test_str[118], (Fnv32_t) 0x528fb7efUL },
+ { &fnv_test_str[119], (Fnv32_t) 0xe73e8d3dUL },
+ { &fnv_test_str[120], (Fnv32_t) 0x876386feUL },
+ { &fnv_test_str[121], (Fnv32_t) 0x811c9dc5UL },
+ { &fnv_test_str[122], (Fnv32_t) 0x050c5d1fUL },
+ { &fnv_test_str[123], (Fnv32_t) 0x14bf7238UL },
+ { &fnv_test_str[124], (Fnv32_t) 0xe160ce28UL },
+ { &fnv_test_str[125], (Fnv32_t) 0x89dc5a75UL },
+ { &fnv_test_str[126], (Fnv32_t) 0xd89b69a0UL },
+ { &fnv_test_str[127], (Fnv32_t) 0x94471a88UL },
+ { &fnv_test_str[128], (Fnv32_t) 0xe78db65fUL },
+ { &fnv_test_str[129], (Fnv32_t) 0x0c3009a2UL },
+ { &fnv_test_str[130], (Fnv32_t) 0x122dff03UL },
+ { &fnv_test_str[131], (Fnv32_t) 0xb4cd8875UL },
+ { &fnv_test_str[132], (Fnv32_t) 0xf4dba725UL },
+ { &fnv_test_str[133], (Fnv32_t) 0x41a16560UL },
+ { &fnv_test_str[134], (Fnv32_t) 0x9c0f941fUL },
+ { &fnv_test_str[135], (Fnv32_t) 0x451a5348UL },
+ { &fnv_test_str[136], (Fnv32_t) 0x3f1d1d89UL },
+ { &fnv_test_str[137], (Fnv32_t) 0x1b91b57aUL },
+ { &fnv_test_str[138], (Fnv32_t) 0x3e99b577UL },
+ { &fnv_test_str[139], (Fnv32_t) 0x4c9de07aUL },
+ { &fnv_test_str[140], (Fnv32_t) 0x1ddf7572UL },
+ { &fnv_test_str[141], (Fnv32_t) 0x64e81976UL },
+ { &fnv_test_str[142], (Fnv32_t) 0x1106a888UL },
+ { &fnv_test_str[143], (Fnv32_t) 0xa498d8e5UL },
+ { &fnv_test_str[144], (Fnv32_t) 0x3c03d2e3UL },
+ { &fnv_test_str[145], (Fnv32_t) 0x26568b28UL },
+ { &fnv_test_str[146], (Fnv32_t) 0x70d7fb42UL },
+ { &fnv_test_str[147], (Fnv32_t) 0xd3ae1d22UL },
+ { &fnv_test_str[148], (Fnv32_t) 0xac8ea5f4UL },
+ { &fnv_test_str[149], (Fnv32_t) 0x4d0abd60UL },
+ { &fnv_test_str[150], (Fnv32_t) 0x48f5e086UL },
+ { &fnv_test_str[151], (Fnv32_t) 0xa8f6241bUL },
+ { &fnv_test_str[152], (Fnv32_t) 0x572f864fUL },
+ { &fnv_test_str[153], (Fnv32_t) 0xa5340803UL },
+ { &fnv_test_str[154], (Fnv32_t) 0x22881aa8UL },
+ { &fnv_test_str[155], (Fnv32_t) 0xc2e2f5a2UL },
+ { &fnv_test_str[156], (Fnv32_t) 0xebf5aec7UL },
+ { &fnv_test_str[157], (Fnv32_t) 0x3cdbfb85UL },
+ { &fnv_test_str[158], (Fnv32_t) 0xbb859704UL },
+ { &fnv_test_str[159], (Fnv32_t) 0xc956fe11UL },
+ { &fnv_test_str[160], (Fnv32_t) 0x8f11a7c9UL },
+ { &fnv_test_str[161], (Fnv32_t) 0x36c48ecfUL },
+ { &fnv_test_str[162], (Fnv32_t) 0x24bfa27eUL },
+ { &fnv_test_str[163], (Fnv32_t) 0xf2596ad1UL },
+ { &fnv_test_str[164], (Fnv32_t) 0xf14a9b45UL },
+ { &fnv_test_str[165], (Fnv32_t) 0x7d45835aUL },
+ { &fnv_test_str[166], (Fnv32_t) 0x6e49334dUL },
+ { &fnv_test_str[167], (Fnv32_t) 0x71767337UL },
+ { &fnv_test_str[168], (Fnv32_t) 0x858a1a8aUL },
+ { &fnv_test_str[169], (Fnv32_t) 0x16e75ac2UL },
+ { &fnv_test_str[170], (Fnv32_t) 0x409f99dfUL },
+ { &fnv_test_str[171], (Fnv32_t) 0x6d6652ddUL },
+ { &fnv_test_str[172], (Fnv32_t) 0x2761a9ffUL },
+ { &fnv_test_str[173], (Fnv32_t) 0x41f0d616UL },
+ { &fnv_test_str[174], (Fnv32_t) 0x0e2d0d0fUL },
+ { &fnv_test_str[175], (Fnv32_t) 0x06adc8fdUL },
+ { &fnv_test_str[176], (Fnv32_t) 0x60e0d4b9UL },
+ { &fnv_test_str[177], (Fnv32_t) 0x5ddc79d3UL },
+ { &fnv_test_str[178], (Fnv32_t) 0x1e6d0b46UL },
+ { &fnv_test_str[179], (Fnv32_t) 0x1d1514d8UL },
+ { &fnv_test_str[180], (Fnv32_t) 0xb1903a4eUL },
+ { &fnv_test_str[181], (Fnv32_t) 0x8200c318UL },
+ { &fnv_test_str[182], (Fnv32_t) 0x15e22888UL },
+ { &fnv_test_str[183], (Fnv32_t) 0x57591760UL },
+ { &fnv_test_str[184], (Fnv32_t) 0x02462efcUL },
+ { &fnv_test_str[185], (Fnv32_t) 0x7651ec44UL },
+ { &fnv_test_str[186], (Fnv32_t) 0x7c24e9d4UL },
+ { &fnv_test_str[187], (Fnv32_t) 0x1952a034UL },
+ { &fnv_test_str[188], (Fnv32_t) 0xd4c46864UL },
+ { &fnv_test_str[189], (Fnv32_t) 0xcb57cde0UL },
+ { &fnv_test_str[190], (Fnv32_t) 0x71136a70UL },
+ { &fnv_test_str[191], (Fnv32_t) 0x0618fb40UL },
+ { &fnv_test_str[192], (Fnv32_t) 0x69a24fc0UL },
+ { &fnv_test_str[193], (Fnv32_t) 0x6a9be510UL },
+ { &fnv_test_str[194], (Fnv32_t) 0xe0477040UL },
+ { &fnv_test_str[195], (Fnv32_t) 0x85aa94b0UL },
+ { &fnv_test_str[196], (Fnv32_t) 0xc6d76240UL },
+ { &fnv_test_str[197], (Fnv32_t) 0xa9f09e40UL },
+ { &fnv_test_str[198], (Fnv32_t) 0xa0291540UL },
+ { &fnv_test_str[199], (Fnv32_t) 0x00000000UL },
+ { &fnv_test_str[200], (Fnv32_t) 0x2e672aa4UL },
+ { &fnv_test_str[201], (Fnv32_t) 0x84b1aa48UL },
+ { &fnv_test_str[202], (Fnv32_t) 0xfc24ba24UL },
+ { NULL, 0 }
+};
+
+/* FNV-1 32 bit test vectors */
+struct fnv1_32_test_vector fnv1_32_vector[] = {
+ { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL },
+ { &fnv_test_str[1], (Fnv32_t) 0x050c5d7eUL },
+ { &fnv_test_str[2], (Fnv32_t) 0x050c5d7dUL },
+ { &fnv_test_str[3], (Fnv32_t) 0x050c5d7cUL },
+ { &fnv_test_str[4], (Fnv32_t) 0x050c5d7bUL },
+ { &fnv_test_str[5], (Fnv32_t) 0x050c5d7aUL },
+ { &fnv_test_str[6], (Fnv32_t) 0x050c5d79UL },
+ { &fnv_test_str[7], (Fnv32_t) 0x6b772514UL },
+ { &fnv_test_str[8], (Fnv32_t) 0x408f5e13UL },
+ { &fnv_test_str[9], (Fnv32_t) 0xb4b1178bUL },
+ { &fnv_test_str[10], (Fnv32_t) 0xfdc80fb0UL },
+ { &fnv_test_str[11], (Fnv32_t) 0x31f0b262UL },
+ { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL },
+ { &fnv_test_str[13], (Fnv32_t) 0x70772d5aUL },
+ { &fnv_test_str[14], (Fnv32_t) 0x6f772bc7UL },
+ { &fnv_test_str[15], (Fnv32_t) 0x6e772a34UL },
+ { &fnv_test_str[16], (Fnv32_t) 0x6d7728a1UL },
+ { &fnv_test_str[17], (Fnv32_t) 0x6c77270eUL },
+ { &fnv_test_str[18], (Fnv32_t) 0x6b77257bUL },
+ { &fnv_test_str[19], (Fnv32_t) 0x408f5e7cUL },
+ { &fnv_test_str[20], (Fnv32_t) 0xb4b117e9UL },
+ { &fnv_test_str[21], (Fnv32_t) 0xfdc80fd1UL },
+ { &fnv_test_str[22], (Fnv32_t) 0x31f0b210UL },
+ { &fnv_test_str[23], (Fnv32_t) 0xffe8d046UL },
+ { &fnv_test_str[24], (Fnv32_t) 0x6e772a5cUL },
+ { &fnv_test_str[25], (Fnv32_t) 0x4197aebbUL },
+ { &fnv_test_str[26], (Fnv32_t) 0xfcc8100fUL },
+ { &fnv_test_str[27], (Fnv32_t) 0xfdf147faUL },
+ { &fnv_test_str[28], (Fnv32_t) 0xbcd44ee1UL },
+ { &fnv_test_str[29], (Fnv32_t) 0x23382c13UL },
+ { &fnv_test_str[30], (Fnv32_t) 0x846d619eUL },
+ { &fnv_test_str[31], (Fnv32_t) 0x1630abdbUL },
+ { &fnv_test_str[32], (Fnv32_t) 0xc99e89b2UL },
+ { &fnv_test_str[33], (Fnv32_t) 0x1692c316UL },
+ { &fnv_test_str[34], (Fnv32_t) 0x9f091bcaUL },
+ { &fnv_test_str[35], (Fnv32_t) 0x2556be9bUL },
+ { &fnv_test_str[36], (Fnv32_t) 0x628e0e73UL },
+ { &fnv_test_str[37], (Fnv32_t) 0x98a0bf6cUL },
+ { &fnv_test_str[38], (Fnv32_t) 0xb10d5725UL },
+ { &fnv_test_str[39], (Fnv32_t) 0xdd002f35UL },
+ { &fnv_test_str[40], (Fnv32_t) 0x4197aed4UL },
+ { &fnv_test_str[41], (Fnv32_t) 0xfcc81061UL },
+ { &fnv_test_str[42], (Fnv32_t) 0xfdf1479dUL },
+ { &fnv_test_str[43], (Fnv32_t) 0xbcd44e8eUL },
+ { &fnv_test_str[44], (Fnv32_t) 0x23382c33UL },
+ { &fnv_test_str[45], (Fnv32_t) 0x846d61e9UL },
+ { &fnv_test_str[46], (Fnv32_t) 0x1630abbaUL },
+ { &fnv_test_str[47], (Fnv32_t) 0xc99e89c1UL },
+ { &fnv_test_str[48], (Fnv32_t) 0x1692c336UL },
+ { &fnv_test_str[49], (Fnv32_t) 0x9f091ba2UL },
+ { &fnv_test_str[50], (Fnv32_t) 0x2556befeUL },
+ { &fnv_test_str[51], (Fnv32_t) 0x628e0e01UL },
+ { &fnv_test_str[52], (Fnv32_t) 0x98a0bf09UL },
+ { &fnv_test_str[53], (Fnv32_t) 0xb10d5704UL },
+ { &fnv_test_str[54], (Fnv32_t) 0xdd002f3fUL },
+ { &fnv_test_str[55], (Fnv32_t) 0x1c4a506fUL },
+ { &fnv_test_str[56], (Fnv32_t) 0x6e772a41UL },
+ { &fnv_test_str[57], (Fnv32_t) 0x26978421UL },
+ { &fnv_test_str[58], (Fnv32_t) 0xe184ff97UL },
+ { &fnv_test_str[59], (Fnv32_t) 0x9b5e5ac6UL },
+ { &fnv_test_str[60], (Fnv32_t) 0x5b88e592UL },
+ { &fnv_test_str[61], (Fnv32_t) 0xaa8164b7UL },
+ { &fnv_test_str[62], (Fnv32_t) 0x20b18c7bUL },
+ { &fnv_test_str[63], (Fnv32_t) 0xf28025c5UL },
+ { &fnv_test_str[64], (Fnv32_t) 0x84bb753fUL },
+ { &fnv_test_str[65], (Fnv32_t) 0x3219925aUL },
+ { &fnv_test_str[66], (Fnv32_t) 0x384163c6UL },
+ { &fnv_test_str[67], (Fnv32_t) 0x54f010d7UL },
+ { &fnv_test_str[68], (Fnv32_t) 0x8cea820cUL },
+ { &fnv_test_str[69], (Fnv32_t) 0xe12ab8eeUL },
+ { &fnv_test_str[70], (Fnv32_t) 0x26978453UL },
+ { &fnv_test_str[71], (Fnv32_t) 0xe184fff3UL },
+ { &fnv_test_str[72], (Fnv32_t) 0x9b5e5ab5UL },
+ { &fnv_test_str[73], (Fnv32_t) 0x5b88e5b2UL },
+ { &fnv_test_str[74], (Fnv32_t) 0xaa8164d6UL },
+ { &fnv_test_str[75], (Fnv32_t) 0x20b18c15UL },
+ { &fnv_test_str[76], (Fnv32_t) 0xf28025a1UL },
+ { &fnv_test_str[77], (Fnv32_t) 0x84bb751fUL },
+ { &fnv_test_str[78], (Fnv32_t) 0x3219922dUL },
+ { &fnv_test_str[79], (Fnv32_t) 0x384163aeUL },
+ { &fnv_test_str[80], (Fnv32_t) 0x54f010b2UL },
+ { &fnv_test_str[81], (Fnv32_t) 0x8cea8275UL },
+ { &fnv_test_str[82], (Fnv32_t) 0xe12ab8e4UL },
+ { &fnv_test_str[83], (Fnv32_t) 0x64411eaaUL },
+ { &fnv_test_str[84], (Fnv32_t) 0x6977223cUL },
+ { &fnv_test_str[85], (Fnv32_t) 0x428ae474UL },
+ { &fnv_test_str[86], (Fnv32_t) 0xb6fa7167UL },
+ { &fnv_test_str[87], (Fnv32_t) 0x73408525UL },
+ { &fnv_test_str[88], (Fnv32_t) 0xb78320a1UL },
+ { &fnv_test_str[89], (Fnv32_t) 0x0caf4135UL },
+ { &fnv_test_str[90], (Fnv32_t) 0xb78320a2UL },
+ { &fnv_test_str[91], (Fnv32_t) 0xcdc88e80UL },
+ { &fnv_test_str[92], (Fnv32_t) 0xb78320a3UL },
+ { &fnv_test_str[93], (Fnv32_t) 0x8ee1dbcbUL },
+ { &fnv_test_str[94], (Fnv32_t) 0xb78320a4UL },
+ { &fnv_test_str[95], (Fnv32_t) 0x4ffb2716UL },
+ { &fnv_test_str[96], (Fnv32_t) 0x860632aaUL },
+ { &fnv_test_str[97], (Fnv32_t) 0xcc2c5c64UL },
+ { &fnv_test_str[98], (Fnv32_t) 0x860632a4UL },
+ { &fnv_test_str[99], (Fnv32_t) 0x2a7ec4a6UL },
+ { &fnv_test_str[100], (Fnv32_t) 0x860632baUL },
+ { &fnv_test_str[101], (Fnv32_t) 0xfefe8e14UL },
+ { &fnv_test_str[102], (Fnv32_t) 0x0a3cffd8UL },
+ { &fnv_test_str[103], (Fnv32_t) 0xf606c108UL },
+ { &fnv_test_str[104], (Fnv32_t) 0x0a3cffdbUL },
+ { &fnv_test_str[105], (Fnv32_t) 0xf906c5c1UL },
+ { &fnv_test_str[106], (Fnv32_t) 0x0a3cffdaUL },
+ { &fnv_test_str[107], (Fnv32_t) 0xf806c42eUL },
+ { &fnv_test_str[108], (Fnv32_t) 0xc07167d7UL },
+ { &fnv_test_str[109], (Fnv32_t) 0xc9867775UL },
+ { &fnv_test_str[110], (Fnv32_t) 0xbf716668UL },
+ { &fnv_test_str[111], (Fnv32_t) 0xc78435b8UL },
+ { &fnv_test_str[112], (Fnv32_t) 0xc6717155UL },
+ { &fnv_test_str[113], (Fnv32_t) 0xb99568cfUL },
+ { &fnv_test_str[114], (Fnv32_t) 0x7662e0d6UL },
+ { &fnv_test_str[115], (Fnv32_t) 0x33a7f0e2UL },
+ { &fnv_test_str[116], (Fnv32_t) 0xc2732f95UL },
+ { &fnv_test_str[117], (Fnv32_t) 0xb053e78fUL },
+ { &fnv_test_str[118], (Fnv32_t) 0x3a19c02aUL },
+ { &fnv_test_str[119], (Fnv32_t) 0xa089821eUL },
+ { &fnv_test_str[120], (Fnv32_t) 0x31ae8f83UL },
+ { &fnv_test_str[121], (Fnv32_t) 0x995fa9c4UL },
+ { &fnv_test_str[122], (Fnv32_t) 0x35983f8cUL },
+ { &fnv_test_str[123], (Fnv32_t) 0x5036a251UL },
+ { &fnv_test_str[124], (Fnv32_t) 0x97018583UL },
+ { &fnv_test_str[125], (Fnv32_t) 0xb4448d60UL },
+ { &fnv_test_str[126], (Fnv32_t) 0x025dfe59UL },
+ { &fnv_test_str[127], (Fnv32_t) 0xc5eab3afUL },
+ { &fnv_test_str[128], (Fnv32_t) 0x7d21ba1eUL },
+ { &fnv_test_str[129], (Fnv32_t) 0x7704cddbUL },
+ { &fnv_test_str[130], (Fnv32_t) 0xd0071bfeUL },
+ { &fnv_test_str[131], (Fnv32_t) 0x0ff3774cUL },
+ { &fnv_test_str[132], (Fnv32_t) 0xb0fea0eaUL },
+ { &fnv_test_str[133], (Fnv32_t) 0x58177303UL },
+ { &fnv_test_str[134], (Fnv32_t) 0x4f599cdaUL },
+ { &fnv_test_str[135], (Fnv32_t) 0x3e590a47UL },
+ { &fnv_test_str[136], (Fnv32_t) 0x965595f8UL },
+ { &fnv_test_str[137], (Fnv32_t) 0xc37f178dUL },
+ { &fnv_test_str[138], (Fnv32_t) 0x9711dd26UL },
+ { &fnv_test_str[139], (Fnv32_t) 0x23c99b7fUL },
+ { &fnv_test_str[140], (Fnv32_t) 0x6e568b17UL },
+ { &fnv_test_str[141], (Fnv32_t) 0x43f0245bUL },
+ { &fnv_test_str[142], (Fnv32_t) 0xbcb7a001UL },
+ { &fnv_test_str[143], (Fnv32_t) 0x12e6dffeUL },
+ { &fnv_test_str[144], (Fnv32_t) 0x0792f2d6UL },
+ { &fnv_test_str[145], (Fnv32_t) 0xb966936bUL },
+ { &fnv_test_str[146], (Fnv32_t) 0x46439ac5UL },
+ { &fnv_test_str[147], (Fnv32_t) 0x728d49afUL },
+ { &fnv_test_str[148], (Fnv32_t) 0xd33745c9UL },
+ { &fnv_test_str[149], (Fnv32_t) 0xbc382a57UL },
+ { &fnv_test_str[150], (Fnv32_t) 0x4bda1d31UL },
+ { &fnv_test_str[151], (Fnv32_t) 0xce35ccaeUL },
+ { &fnv_test_str[152], (Fnv32_t) 0x3b6eed94UL },
+ { &fnv_test_str[153], (Fnv32_t) 0x445c9c58UL },
+ { &fnv_test_str[154], (Fnv32_t) 0x3db8bf9dUL },
+ { &fnv_test_str[155], (Fnv32_t) 0x2dee116dUL },
+ { &fnv_test_str[156], (Fnv32_t) 0xc18738daUL },
+ { &fnv_test_str[157], (Fnv32_t) 0x5b156176UL },
+ { &fnv_test_str[158], (Fnv32_t) 0x2aa7d593UL },
+ { &fnv_test_str[159], (Fnv32_t) 0xb2409658UL },
+ { &fnv_test_str[160], (Fnv32_t) 0xe1489528UL },
+ { &fnv_test_str[161], (Fnv32_t) 0xfe1ee07eUL },
+ { &fnv_test_str[162], (Fnv32_t) 0xe8842315UL },
+ { &fnv_test_str[163], (Fnv32_t) 0x3a6a63a2UL },
+ { &fnv_test_str[164], (Fnv32_t) 0x06d2c18cUL },
+ { &fnv_test_str[165], (Fnv32_t) 0xf8ef7225UL },
+ { &fnv_test_str[166], (Fnv32_t) 0x843d3300UL },
+ { &fnv_test_str[167], (Fnv32_t) 0xbb24f7aeUL },
+ { &fnv_test_str[168], (Fnv32_t) 0x878c0ec9UL },
+ { &fnv_test_str[169], (Fnv32_t) 0xb557810fUL },
+ { &fnv_test_str[170], (Fnv32_t) 0x57423246UL },
+ { &fnv_test_str[171], (Fnv32_t) 0x87f7505eUL },
+ { &fnv_test_str[172], (Fnv32_t) 0xbb809f20UL },
+ { &fnv_test_str[173], (Fnv32_t) 0x8932abb5UL },
+ { &fnv_test_str[174], (Fnv32_t) 0x0a9b3aa0UL },
+ { &fnv_test_str[175], (Fnv32_t) 0xb8682a24UL },
+ { &fnv_test_str[176], (Fnv32_t) 0xa7ac1c56UL },
+ { &fnv_test_str[177], (Fnv32_t) 0x11409252UL },
+ { &fnv_test_str[178], (Fnv32_t) 0xa987f517UL },
+ { &fnv_test_str[179], (Fnv32_t) 0xf309e7edUL },
+ { &fnv_test_str[180], (Fnv32_t) 0xc9e8f417UL },
+ { &fnv_test_str[181], (Fnv32_t) 0x7f447bddUL },
+ { &fnv_test_str[182], (Fnv32_t) 0xb929adc5UL },
+ { &fnv_test_str[183], (Fnv32_t) 0x57022879UL },
+ { &fnv_test_str[184], (Fnv32_t) 0xdcfd2c49UL },
+ { &fnv_test_str[185], (Fnv32_t) 0x6edafff5UL },
+ { &fnv_test_str[186], (Fnv32_t) 0xf04fb1f1UL },
+ { &fnv_test_str[187], (Fnv32_t) 0xfb7de8b9UL },
+ { &fnv_test_str[188], (Fnv32_t) 0xc5f1d7e9UL },
+ { &fnv_test_str[189], (Fnv32_t) 0x32c1f439UL },
+ { &fnv_test_str[190], (Fnv32_t) 0x7fd3eb7dUL },
+ { &fnv_test_str[191], (Fnv32_t) 0x81597da5UL },
+ { &fnv_test_str[192], (Fnv32_t) 0x05eb7a25UL },
+ { &fnv_test_str[193], (Fnv32_t) 0x9c0fa1b5UL },
+ { &fnv_test_str[194], (Fnv32_t) 0x53ccb1c5UL },
+ { &fnv_test_str[195], (Fnv32_t) 0xfabece15UL },
+ { &fnv_test_str[196], (Fnv32_t) 0x4ad745a5UL },
+ { &fnv_test_str[197], (Fnv32_t) 0xe5bdc495UL },
+ { &fnv_test_str[198], (Fnv32_t) 0x23b3c0a5UL },
+ { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL },
+ { &fnv_test_str[200], (Fnv32_t) 0x0c6c58b9UL },
+ { &fnv_test_str[201], (Fnv32_t) 0xe2dbccd5UL },
+ { &fnv_test_str[202], (Fnv32_t) 0xdb7f50f9UL },
+ { NULL, 0 }
+};
+
+/* FNV-1a 32 bit test vectors */
+struct fnv1a_32_test_vector fnv1a_32_vector[] = {
+ { &fnv_test_str[0], (Fnv32_t) 0x811c9dc5UL },
+ { &fnv_test_str[1], (Fnv32_t) 0xe40c292cUL },
+ { &fnv_test_str[2], (Fnv32_t) 0xe70c2de5UL },
+ { &fnv_test_str[3], (Fnv32_t) 0xe60c2c52UL },
+ { &fnv_test_str[4], (Fnv32_t) 0xe10c2473UL },
+ { &fnv_test_str[5], (Fnv32_t) 0xe00c22e0UL },
+ { &fnv_test_str[6], (Fnv32_t) 0xe30c2799UL },
+ { &fnv_test_str[7], (Fnv32_t) 0x6222e842UL },
+ { &fnv_test_str[8], (Fnv32_t) 0xa9f37ed7UL },
+ { &fnv_test_str[9], (Fnv32_t) 0x3f5076efUL },
+ { &fnv_test_str[10], (Fnv32_t) 0x39aaa18aUL },
+ { &fnv_test_str[11], (Fnv32_t) 0xbf9cf968UL },
+ { &fnv_test_str[12], (Fnv32_t) 0x050c5d1fUL },
+ { &fnv_test_str[13], (Fnv32_t) 0x2b24d044UL },
+ { &fnv_test_str[14], (Fnv32_t) 0x9d2c3f7fUL },
+ { &fnv_test_str[15], (Fnv32_t) 0x7729c516UL },
+ { &fnv_test_str[16], (Fnv32_t) 0xb91d6109UL },
+ { &fnv_test_str[17], (Fnv32_t) 0x931ae6a0UL },
+ { &fnv_test_str[18], (Fnv32_t) 0x052255dbUL },
+ { &fnv_test_str[19], (Fnv32_t) 0xbef39fe6UL },
+ { &fnv_test_str[20], (Fnv32_t) 0x6150ac75UL },
+ { &fnv_test_str[21], (Fnv32_t) 0x9aab3a3dUL },
+ { &fnv_test_str[22], (Fnv32_t) 0x519c4c3eUL },
+ { &fnv_test_str[23], (Fnv32_t) 0x0c1c9eb8UL },
+ { &fnv_test_str[24], (Fnv32_t) 0x5f299f4eUL },
+ { &fnv_test_str[25], (Fnv32_t) 0xef8580f3UL },
+ { &fnv_test_str[26], (Fnv32_t) 0xac297727UL },
+ { &fnv_test_str[27], (Fnv32_t) 0x4546b9c0UL },
+ { &fnv_test_str[28], (Fnv32_t) 0xbd564e7dUL },
+ { &fnv_test_str[29], (Fnv32_t) 0x6bdd5c67UL },
+ { &fnv_test_str[30], (Fnv32_t) 0xdd77ed30UL },
+ { &fnv_test_str[31], (Fnv32_t) 0xf4ca9683UL },
+ { &fnv_test_str[32], (Fnv32_t) 0x4aeb9bd0UL },
+ { &fnv_test_str[33], (Fnv32_t) 0xe0e67ad0UL },
+ { &fnv_test_str[34], (Fnv32_t) 0xc2d32fa8UL },
+ { &fnv_test_str[35], (Fnv32_t) 0x7f743fb7UL },
+ { &fnv_test_str[36], (Fnv32_t) 0x6900631fUL },
+ { &fnv_test_str[37], (Fnv32_t) 0xc59c990eUL },
+ { &fnv_test_str[38], (Fnv32_t) 0x448524fdUL },
+ { &fnv_test_str[39], (Fnv32_t) 0xd49930d5UL },
+ { &fnv_test_str[40], (Fnv32_t) 0x1c85c7caUL },
+ { &fnv_test_str[41], (Fnv32_t) 0x0229fe89UL },
+ { &fnv_test_str[42], (Fnv32_t) 0x2c469265UL },
+ { &fnv_test_str[43], (Fnv32_t) 0xce566940UL },
+ { &fnv_test_str[44], (Fnv32_t) 0x8bdd8ec7UL },
+ { &fnv_test_str[45], (Fnv32_t) 0x34787625UL },
+ { &fnv_test_str[46], (Fnv32_t) 0xd3ca6290UL },
+ { &fnv_test_str[47], (Fnv32_t) 0xddeaf039UL },
+ { &fnv_test_str[48], (Fnv32_t) 0xc0e64870UL },
+ { &fnv_test_str[49], (Fnv32_t) 0xdad35570UL },
+ { &fnv_test_str[50], (Fnv32_t) 0x5a740578UL },
+ { &fnv_test_str[51], (Fnv32_t) 0x5b004d15UL },
+ { &fnv_test_str[52], (Fnv32_t) 0x6a9c09cdUL },
+ { &fnv_test_str[53], (Fnv32_t) 0x2384f10aUL },
+ { &fnv_test_str[54], (Fnv32_t) 0xda993a47UL },
+ { &fnv_test_str[55], (Fnv32_t) 0x8227df4fUL },
+ { &fnv_test_str[56], (Fnv32_t) 0x4c298165UL },
+ { &fnv_test_str[57], (Fnv32_t) 0xfc563735UL },
+ { &fnv_test_str[58], (Fnv32_t) 0x8cb91483UL },
+ { &fnv_test_str[59], (Fnv32_t) 0x775bf5d0UL },
+ { &fnv_test_str[60], (Fnv32_t) 0xd5c428d0UL },
+ { &fnv_test_str[61], (Fnv32_t) 0x34cc0ea3UL },
+ { &fnv_test_str[62], (Fnv32_t) 0xea3b4cb7UL },
+ { &fnv_test_str[63], (Fnv32_t) 0x8e59f029UL },
+ { &fnv_test_str[64], (Fnv32_t) 0x2094de2bUL },
+ { &fnv_test_str[65], (Fnv32_t) 0xa65a0ad4UL },
+ { &fnv_test_str[66], (Fnv32_t) 0x9bbee5f4UL },
+ { &fnv_test_str[67], (Fnv32_t) 0xbe836343UL },
+ { &fnv_test_str[68], (Fnv32_t) 0x22d5344eUL },
+ { &fnv_test_str[69], (Fnv32_t) 0x19a1470cUL },
+ { &fnv_test_str[70], (Fnv32_t) 0x4a56b1ffUL },
+ { &fnv_test_str[71], (Fnv32_t) 0x70b8e86fUL },
+ { &fnv_test_str[72], (Fnv32_t) 0x0a5b4a39UL },
+ { &fnv_test_str[73], (Fnv32_t) 0xb5c3f670UL },
+ { &fnv_test_str[74], (Fnv32_t) 0x53cc3f70UL },
+ { &fnv_test_str[75], (Fnv32_t) 0xc03b0a99UL },
+ { &fnv_test_str[76], (Fnv32_t) 0x7259c415UL },
+ { &fnv_test_str[77], (Fnv32_t) 0x4095108bUL },
+ { &fnv_test_str[78], (Fnv32_t) 0x7559bdb1UL },
+ { &fnv_test_str[79], (Fnv32_t) 0xb3bf0bbcUL },
+ { &fnv_test_str[80], (Fnv32_t) 0x2183ff1cUL },
+ { &fnv_test_str[81], (Fnv32_t) 0x2bd54279UL },
+ { &fnv_test_str[82], (Fnv32_t) 0x23a156caUL },
+ { &fnv_test_str[83], (Fnv32_t) 0x64e2d7e4UL },
+ { &fnv_test_str[84], (Fnv32_t) 0x683af69aUL },
+ { &fnv_test_str[85], (Fnv32_t) 0xaed2346eUL },
+ { &fnv_test_str[86], (Fnv32_t) 0x4f9f2cabUL },
+ { &fnv_test_str[87], (Fnv32_t) 0x02935131UL },
+ { &fnv_test_str[88], (Fnv32_t) 0xc48fb86dUL },
+ { &fnv_test_str[89], (Fnv32_t) 0x2269f369UL },
+ { &fnv_test_str[90], (Fnv32_t) 0xc18fb3b4UL },
+ { &fnv_test_str[91], (Fnv32_t) 0x50ef1236UL },
+ { &fnv_test_str[92], (Fnv32_t) 0xc28fb547UL },
+ { &fnv_test_str[93], (Fnv32_t) 0x96c3bf47UL },
+ { &fnv_test_str[94], (Fnv32_t) 0xbf8fb08eUL },
+ { &fnv_test_str[95], (Fnv32_t) 0xf3e4d49cUL },
+ { &fnv_test_str[96], (Fnv32_t) 0x32179058UL },
+ { &fnv_test_str[97], (Fnv32_t) 0x280bfee6UL },
+ { &fnv_test_str[98], (Fnv32_t) 0x30178d32UL },
+ { &fnv_test_str[99], (Fnv32_t) 0x21addaf8UL },
+ { &fnv_test_str[100], (Fnv32_t) 0x4217a988UL },
+ { &fnv_test_str[101], (Fnv32_t) 0x772633d6UL },
+ { &fnv_test_str[102], (Fnv32_t) 0x08a3d11eUL },
+ { &fnv_test_str[103], (Fnv32_t) 0xb7e2323aUL },
+ { &fnv_test_str[104], (Fnv32_t) 0x07a3cf8bUL },
+ { &fnv_test_str[105], (Fnv32_t) 0x91dfb7d1UL },
+ { &fnv_test_str[106], (Fnv32_t) 0x06a3cdf8UL },
+ { &fnv_test_str[107], (Fnv32_t) 0x6bdd3d68UL },
+ { &fnv_test_str[108], (Fnv32_t) 0x1d5636a7UL },
+ { &fnv_test_str[109], (Fnv32_t) 0xd5b808e5UL },
+ { &fnv_test_str[110], (Fnv32_t) 0x1353e852UL },
+ { &fnv_test_str[111], (Fnv32_t) 0xbf16b916UL },
+ { &fnv_test_str[112], (Fnv32_t) 0xa55b89edUL },
+ { &fnv_test_str[113], (Fnv32_t) 0x3c1a2017UL },
+ { &fnv_test_str[114], (Fnv32_t) 0x0588b13cUL },
+ { &fnv_test_str[115], (Fnv32_t) 0xf22f0174UL },
+ { &fnv_test_str[116], (Fnv32_t) 0xe83641e1UL },
+ { &fnv_test_str[117], (Fnv32_t) 0x6e69b533UL },
+ { &fnv_test_str[118], (Fnv32_t) 0xf1760448UL },
+ { &fnv_test_str[119], (Fnv32_t) 0x64c8bd58UL },
+ { &fnv_test_str[120], (Fnv32_t) 0x97b4ea23UL },
+ { &fnv_test_str[121], (Fnv32_t) 0x9a4e92e6UL },
+ { &fnv_test_str[122], (Fnv32_t) 0xcfb14012UL },
+ { &fnv_test_str[123], (Fnv32_t) 0xf01b2511UL },
+ { &fnv_test_str[124], (Fnv32_t) 0x0bbb59c3UL },
+ { &fnv_test_str[125], (Fnv32_t) 0xce524afaUL },
+ { &fnv_test_str[126], (Fnv32_t) 0xdd16ef45UL },
+ { &fnv_test_str[127], (Fnv32_t) 0x60648bb3UL },
+ { &fnv_test_str[128], (Fnv32_t) 0x7fa4bcfcUL },
+ { &fnv_test_str[129], (Fnv32_t) 0x5053ae17UL },
+ { &fnv_test_str[130], (Fnv32_t) 0xc9302890UL },
+ { &fnv_test_str[131], (Fnv32_t) 0x956ded32UL },
+ { &fnv_test_str[132], (Fnv32_t) 0x9136db84UL },
+ { &fnv_test_str[133], (Fnv32_t) 0xdf9d3323UL },
+ { &fnv_test_str[134], (Fnv32_t) 0x32bb6cd0UL },
+ { &fnv_test_str[135], (Fnv32_t) 0xc8f8385bUL },
+ { &fnv_test_str[136], (Fnv32_t) 0xeb08bfbaUL },
+ { &fnv_test_str[137], (Fnv32_t) 0x62cc8e3dUL },
+ { &fnv_test_str[138], (Fnv32_t) 0xc3e20f5cUL },
+ { &fnv_test_str[139], (Fnv32_t) 0x39e97f17UL },
+ { &fnv_test_str[140], (Fnv32_t) 0x7837b203UL },
+ { &fnv_test_str[141], (Fnv32_t) 0x319e877bUL },
+ { &fnv_test_str[142], (Fnv32_t) 0xd3e63f89UL },
+ { &fnv_test_str[143], (Fnv32_t) 0x29b50b38UL },
+ { &fnv_test_str[144], (Fnv32_t) 0x5ed678b8UL },
+ { &fnv_test_str[145], (Fnv32_t) 0xb0d5b793UL },
+ { &fnv_test_str[146], (Fnv32_t) 0x52450be5UL },
+ { &fnv_test_str[147], (Fnv32_t) 0xfa72d767UL },
+ { &fnv_test_str[148], (Fnv32_t) 0x95066709UL },
+ { &fnv_test_str[149], (Fnv32_t) 0x7f52e123UL },
+ { &fnv_test_str[150], (Fnv32_t) 0x76966481UL },
+ { &fnv_test_str[151], (Fnv32_t) 0x063258b0UL },
+ { &fnv_test_str[152], (Fnv32_t) 0x2ded6e8aUL },
+ { &fnv_test_str[153], (Fnv32_t) 0xb07d7c52UL },
+ { &fnv_test_str[154], (Fnv32_t) 0xd0c71b71UL },
+ { &fnv_test_str[155], (Fnv32_t) 0xf684f1bdUL },
+ { &fnv_test_str[156], (Fnv32_t) 0x868ecfa8UL },
+ { &fnv_test_str[157], (Fnv32_t) 0xf794f684UL },
+ { &fnv_test_str[158], (Fnv32_t) 0xd19701c3UL },
+ { &fnv_test_str[159], (Fnv32_t) 0x346e171eUL },
+ { &fnv_test_str[160], (Fnv32_t) 0x91f8f676UL },
+ { &fnv_test_str[161], (Fnv32_t) 0x0bf58848UL },
+ { &fnv_test_str[162], (Fnv32_t) 0x6317b6d1UL },
+ { &fnv_test_str[163], (Fnv32_t) 0xafad4c54UL },
+ { &fnv_test_str[164], (Fnv32_t) 0x0f25681eUL },
+ { &fnv_test_str[165], (Fnv32_t) 0x91b18d49UL },
+ { &fnv_test_str[166], (Fnv32_t) 0x7d61c12eUL },
+ { &fnv_test_str[167], (Fnv32_t) 0x5147d25cUL },
+ { &fnv_test_str[168], (Fnv32_t) 0x9a8b6805UL },
+ { &fnv_test_str[169], (Fnv32_t) 0x4cd2a447UL },
+ { &fnv_test_str[170], (Fnv32_t) 0x1e549b14UL },
+ { &fnv_test_str[171], (Fnv32_t) 0x2fe1b574UL },
+ { &fnv_test_str[172], (Fnv32_t) 0xcf0cd31eUL },
+ { &fnv_test_str[173], (Fnv32_t) 0x6c471669UL },
+ { &fnv_test_str[174], (Fnv32_t) 0x0e5eef1eUL },
+ { &fnv_test_str[175], (Fnv32_t) 0x2bed3602UL },
+ { &fnv_test_str[176], (Fnv32_t) 0xb26249e0UL },
+ { &fnv_test_str[177], (Fnv32_t) 0x2c9b86a4UL },
+ { &fnv_test_str[178], (Fnv32_t) 0xe415e2bbUL },
+ { &fnv_test_str[179], (Fnv32_t) 0x18a98d1dUL },
+ { &fnv_test_str[180], (Fnv32_t) 0xb7df8b7bUL },
+ { &fnv_test_str[181], (Fnv32_t) 0x241e9075UL },
+ { &fnv_test_str[182], (Fnv32_t) 0x063f70ddUL },
+ { &fnv_test_str[183], (Fnv32_t) 0x0295aed9UL },
+ { &fnv_test_str[184], (Fnv32_t) 0x56a7f781UL },
+ { &fnv_test_str[185], (Fnv32_t) 0x253bc645UL },
+ { &fnv_test_str[186], (Fnv32_t) 0x46610921UL },
+ { &fnv_test_str[187], (Fnv32_t) 0x7c1577f9UL },
+ { &fnv_test_str[188], (Fnv32_t) 0x512b2851UL },
+ { &fnv_test_str[189], (Fnv32_t) 0x76823999UL },
+ { &fnv_test_str[190], (Fnv32_t) 0xc0586935UL },
+ { &fnv_test_str[191], (Fnv32_t) 0xf3415c85UL },
+ { &fnv_test_str[192], (Fnv32_t) 0x0ae4ff65UL },
+ { &fnv_test_str[193], (Fnv32_t) 0x58b79725UL },
+ { &fnv_test_str[194], (Fnv32_t) 0xdea43aa5UL },
+ { &fnv_test_str[195], (Fnv32_t) 0x2bb3be35UL },
+ { &fnv_test_str[196], (Fnv32_t) 0xea777a45UL },
+ { &fnv_test_str[197], (Fnv32_t) 0x8f21c305UL },
+ { &fnv_test_str[198], (Fnv32_t) 0x5c9d0865UL },
+ { &fnv_test_str[199], (Fnv32_t) 0xfa823dd5UL },
+ { &fnv_test_str[200], (Fnv32_t) 0x21a27271UL },
+ { &fnv_test_str[201], (Fnv32_t) 0x83c5c6d5UL },
+ { &fnv_test_str[202], (Fnv32_t) 0x813b0881UL },
+ { NULL, 0 }
+};
+
+/* FNV-0 64 bit test vectors */
+#if defined(HAVE_64BIT_LONG_LONG)
+struct fnv0_64_test_vector fnv0_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) 0x0000000000000000ULL },
+ { &fnv_test_str[1], (Fnv64_t) 0x0000000000000061ULL },
+ { &fnv_test_str[2], (Fnv64_t) 0x0000000000000062ULL },
+ { &fnv_test_str[3], (Fnv64_t) 0x0000000000000063ULL },
+ { &fnv_test_str[4], (Fnv64_t) 0x0000000000000064ULL },
+ { &fnv_test_str[5], (Fnv64_t) 0x0000000000000065ULL },
+ { &fnv_test_str[6], (Fnv64_t) 0x0000000000000066ULL },
+ { &fnv_test_str[7], (Fnv64_t) 0x000066000000ad3dULL },
+ { &fnv_test_str[8], (Fnv64_t) 0x015a8f0001265ec8ULL },
+ { &fnv_test_str[9], (Fnv64_t) 0x733fc501f4330dbaULL },
+ { &fnv_test_str[10], (Fnv64_t) 0x08697c51f2c0536fULL },
+ { &fnv_test_str[11], (Fnv64_t) 0x0b91ae3f7ccdc5efULL },
+ { &fnv_test_str[12], (Fnv64_t) 0x0000000000000000ULL },
+ { &fnv_test_str[13], (Fnv64_t) 0x000061000000a4d3ULL },
+ { &fnv_test_str[14], (Fnv64_t) 0x000062000000a686ULL },
+ { &fnv_test_str[15], (Fnv64_t) 0x000063000000a839ULL },
+ { &fnv_test_str[16], (Fnv64_t) 0x000064000000a9ecULL },
+ { &fnv_test_str[17], (Fnv64_t) 0x000065000000ab9fULL },
+ { &fnv_test_str[18], (Fnv64_t) 0x000066000000ad52ULL },
+ { &fnv_test_str[19], (Fnv64_t) 0x015a8f0001265ea7ULL },
+ { &fnv_test_str[20], (Fnv64_t) 0x733fc501f4330dd8ULL },
+ { &fnv_test_str[21], (Fnv64_t) 0x08697c51f2c0530eULL },
+ { &fnv_test_str[22], (Fnv64_t) 0x0b91ae3f7ccdc59dULL },
+ { &fnv_test_str[23], (Fnv64_t) 0x765104e111a7551dULL },
+ { &fnv_test_str[24], (Fnv64_t) 0x000063000000a851ULL },
+ { &fnv_test_str[25], (Fnv64_t) 0x01508a00011e01ccULL },
+ { &fnv_test_str[26], (Fnv64_t) 0x59dc4a01e5fd0dcaULL },
+ { &fnv_test_str[27], (Fnv64_t) 0xae5f8b39ccfe6e59ULL },
+ { &fnv_test_str[28], (Fnv64_t) 0x4ac7ec3754558154ULL },
+ { &fnv_test_str[29], (Fnv64_t) 0x6737b6044d4ac19cULL },
+ { &fnv_test_str[30], (Fnv64_t) 0xae6be54f5606fc63ULL },
+ { &fnv_test_str[31], (Fnv64_t) 0x685308cf2ddedc58ULL },
+ { &fnv_test_str[32], (Fnv64_t) 0x23f4500af1b069fbULL },
+ { &fnv_test_str[33], (Fnv64_t) 0xc88dfd98aec415a1ULL },
+ { &fnv_test_str[34], (Fnv64_t) 0x8d5b8b70f730c0fbULL },
+ { &fnv_test_str[35], (Fnv64_t) 0x634eebf407d7eae4ULL },
+ { &fnv_test_str[36], (Fnv64_t) 0x9705d3a953e4211eULL },
+ { &fnv_test_str[37], (Fnv64_t) 0x8307c6b98ca4459fULL },
+ { &fnv_test_str[38], (Fnv64_t) 0x4a7c4c49fb224d0cULL },
+ { &fnv_test_str[39], (Fnv64_t) 0xb382adb5bb48eb6eULL },
+ { &fnv_test_str[40], (Fnv64_t) 0x01508a00011e01a3ULL },
+ { &fnv_test_str[41], (Fnv64_t) 0x59dc4a01e5fd0da4ULL },
+ { &fnv_test_str[42], (Fnv64_t) 0xae5f8b39ccfe6e3eULL },
+ { &fnv_test_str[43], (Fnv64_t) 0x4ac7ec375455813bULL },
+ { &fnv_test_str[44], (Fnv64_t) 0x6737b6044d4ac1bcULL },
+ { &fnv_test_str[45], (Fnv64_t) 0xae6be54f5606fc14ULL },
+ { &fnv_test_str[46], (Fnv64_t) 0x685308cf2ddedc39ULL },
+ { &fnv_test_str[47], (Fnv64_t) 0x23f4500af1b06988ULL },
+ { &fnv_test_str[48], (Fnv64_t) 0xc88dfd98aec41581ULL },
+ { &fnv_test_str[49], (Fnv64_t) 0x8d5b8b70f730c093ULL },
+ { &fnv_test_str[50], (Fnv64_t) 0x634eebf407d7ea81ULL },
+ { &fnv_test_str[51], (Fnv64_t) 0x9705d3a953e4216cULL },
+ { &fnv_test_str[52], (Fnv64_t) 0x8307c6b98ca445faULL },
+ { &fnv_test_str[53], (Fnv64_t) 0x4a7c4c49fb224d2dULL },
+ { &fnv_test_str[54], (Fnv64_t) 0xb382adb5bb48eb64ULL },
+ { &fnv_test_str[55], (Fnv64_t) 0x4ff899cd3ce80beaULL },
+ { &fnv_test_str[56], (Fnv64_t) 0x000063000000a84cULL },
+ { &fnv_test_str[57], (Fnv64_t) 0x01508500011df956ULL },
+ { &fnv_test_str[58], (Fnv64_t) 0x59cb5501e5eead46ULL },
+ { &fnv_test_str[59], (Fnv64_t) 0x832eb839b4906d81ULL },
+ { &fnv_test_str[60], (Fnv64_t) 0x78d08b0dd16a1213ULL },
+ { &fnv_test_str[61], (Fnv64_t) 0xb46e5b7ad73cb628ULL },
+ { &fnv_test_str[62], (Fnv64_t) 0xd43b99bbbc298596ULL },
+ { &fnv_test_str[63], (Fnv64_t) 0xcacbd000ba8dfd86ULL },
+ { &fnv_test_str[64], (Fnv64_t) 0x264ff73cff45ca92ULL },
+ { &fnv_test_str[65], (Fnv64_t) 0x5fabaea5c3973661ULL },
+ { &fnv_test_str[66], (Fnv64_t) 0x27f024ab59f166bbULL },
+ { &fnv_test_str[67], (Fnv64_t) 0xce750a29d5318fa4ULL },
+ { &fnv_test_str[68], (Fnv64_t) 0x026fe915433713d5ULL },
+ { &fnv_test_str[69], (Fnv64_t) 0x5b3ce4213696b2e5ULL },
+ { &fnv_test_str[70], (Fnv64_t) 0x01508500011df924ULL },
+ { &fnv_test_str[71], (Fnv64_t) 0x59cb5501e5eead22ULL },
+ { &fnv_test_str[72], (Fnv64_t) 0x832eb839b4906df2ULL },
+ { &fnv_test_str[73], (Fnv64_t) 0x78d08b0dd16a1233ULL },
+ { &fnv_test_str[74], (Fnv64_t) 0xb46e5b7ad73cb649ULL },
+ { &fnv_test_str[75], (Fnv64_t) 0xd43b99bbbc2985f8ULL },
+ { &fnv_test_str[76], (Fnv64_t) 0xcacbd000ba8dfde2ULL },
+ { &fnv_test_str[77], (Fnv64_t) 0x264ff73cff45cab2ULL },
+ { &fnv_test_str[78], (Fnv64_t) 0x5fabaea5c3973616ULL },
+ { &fnv_test_str[79], (Fnv64_t) 0x27f024ab59f166d3ULL },
+ { &fnv_test_str[80], (Fnv64_t) 0xce750a29d5318fc1ULL },
+ { &fnv_test_str[81], (Fnv64_t) 0x026fe915433713acULL },
+ { &fnv_test_str[82], (Fnv64_t) 0x5b3ce4213696b2efULL },
+ { &fnv_test_str[83], (Fnv64_t) 0x9f2a896fc211fb1fULL },
+ { &fnv_test_str[84], (Fnv64_t) 0x000068000000b0d1ULL },
+ { &fnv_test_str[85], (Fnv64_t) 0x01618900012c7323ULL },
+ { &fnv_test_str[86], (Fnv64_t) 0x3fa86e63bc7d03c8ULL },
+ { &fnv_test_str[87], (Fnv64_t) 0xa8375b79486d6cd8ULL },
+ { &fnv_test_str[88], (Fnv64_t) 0xa0d18504e316ac54ULL },
+ { &fnv_test_str[89], (Fnv64_t) 0x08a97b0004e7fe54ULL },
+ { &fnv_test_str[90], (Fnv64_t) 0xa0d18504e316ac57ULL },
+ { &fnv_test_str[91], (Fnv64_t) 0x1152f60009cffda9ULL },
+ { &fnv_test_str[92], (Fnv64_t) 0xa0d18504e316ac56ULL },
+ { &fnv_test_str[93], (Fnv64_t) 0x19fc71000eb7fcfeULL },
+ { &fnv_test_str[94], (Fnv64_t) 0xa0d18504e316ac51ULL },
+ { &fnv_test_str[95], (Fnv64_t) 0x22a5ec00139ffa53ULL },
+ { &fnv_test_str[96], (Fnv64_t) 0x29bed00139779a33ULL },
+ { &fnv_test_str[97], (Fnv64_t) 0x4dbc81014e3c19f5ULL },
+ { &fnv_test_str[98], (Fnv64_t) 0x29bed00139779a3dULL },
+ { &fnv_test_str[99], (Fnv64_t) 0x81a72b016b9f7573ULL },
+ { &fnv_test_str[100], (Fnv64_t) 0x29bed00139779a23ULL },
+ { &fnv_test_str[101], (Fnv64_t) 0xd85411019cbbce45ULL },
+ { &fnv_test_str[102], (Fnv64_t) 0xf548616b8621d657ULL },
+ { &fnv_test_str[103], (Fnv64_t) 0xebd3e0b4eb7f35d5ULL },
+ { &fnv_test_str[104], (Fnv64_t) 0xf548616b8621d654ULL },
+ { &fnv_test_str[105], (Fnv64_t) 0xebd3ddb4eb7f30bcULL },
+ { &fnv_test_str[106], (Fnv64_t) 0xf548616b8621d655ULL },
+ { &fnv_test_str[107], (Fnv64_t) 0xebd3deb4eb7f326fULL },
+ { &fnv_test_str[108], (Fnv64_t) 0x581cb60340ab0968ULL },
+ { &fnv_test_str[109], (Fnv64_t) 0x63d2af86e2a0fbb8ULL },
+ { &fnv_test_str[110], (Fnv64_t) 0x581cb70340ab0b37ULL },
+ { &fnv_test_str[111], (Fnv64_t) 0x63d63186e2a40e75ULL },
+ { &fnv_test_str[112], (Fnv64_t) 0x581cc40340ab212eULL },
+ { &fnv_test_str[113], (Fnv64_t) 0x64023f86e2c9612aULL },
+ { &fnv_test_str[114], (Fnv64_t) 0xdbda6a26c33c909fULL },
+ { &fnv_test_str[115], (Fnv64_t) 0xd0b2feddbfe9be2dULL },
+ { &fnv_test_str[116], (Fnv64_t) 0x9c9eae3f5d037decULL },
+ { &fnv_test_str[117], (Fnv64_t) 0x252001ab0ceef804ULL },
+ { &fnv_test_str[118], (Fnv64_t) 0x4456a56f9e05cfefULL },
+ { &fnv_test_str[119], (Fnv64_t) 0x250b0ba983e0531dULL },
+ { &fnv_test_str[120], (Fnv64_t) 0x52b007213b27b33eULL },
+ { &fnv_test_str[121], (Fnv64_t) 0xcbf29ce484222325ULL },
+ { &fnv_test_str[122], (Fnv64_t) 0xaf63bd4c8601b7dfULL },
+ { &fnv_test_str[123], (Fnv64_t) 0x128599ccddae09f8ULL },
+ { &fnv_test_str[124], (Fnv64_t) 0x270e4f1caebaf068ULL },
+ { &fnv_test_str[125], (Fnv64_t) 0x01517d497446a395ULL },
+ { &fnv_test_str[126], (Fnv64_t) 0x9af5a29a89450b40ULL },
+ { &fnv_test_str[127], (Fnv64_t) 0xb502f6c063ba72e8ULL },
+ { &fnv_test_str[128], (Fnv64_t) 0xacf41561498ca7dfULL },
+ { &fnv_test_str[129], (Fnv64_t) 0x6be8c2423a351542ULL },
+ { &fnv_test_str[130], (Fnv64_t) 0xd04f1f6da96ce4a3ULL },
+ { &fnv_test_str[131], (Fnv64_t) 0x69eb9a8f282c7235ULL },
+ { &fnv_test_str[132], (Fnv64_t) 0x6a7e5a418f77cfc5ULL },
+ { &fnv_test_str[133], (Fnv64_t) 0xbcaf568ddc2ecba0ULL },
+ { &fnv_test_str[134], (Fnv64_t) 0xb03b5cc4c38f8b1fULL },
+ { &fnv_test_str[135], (Fnv64_t) 0xf89a9f51432db828ULL },
+ { &fnv_test_str[136], (Fnv64_t) 0x549e856be6103429ULL },
+ { &fnv_test_str[137], (Fnv64_t) 0x3cf50d224d29377aULL },
+ { &fnv_test_str[138], (Fnv64_t) 0xdb762df418c10c37ULL },
+ { &fnv_test_str[139], (Fnv64_t) 0xfeeb4226b0e9a6baULL },
+ { &fnv_test_str[140], (Fnv64_t) 0x7004a4cd9310c052ULL },
+ { &fnv_test_str[141], (Fnv64_t) 0xd1c727d7f5329276ULL },
+ { &fnv_test_str[142], (Fnv64_t) 0xbe313796596ce908ULL },
+ { &fnv_test_str[143], (Fnv64_t) 0x768f67ede090fcc5ULL },
+ { &fnv_test_str[144], (Fnv64_t) 0xa81563cc9db9bfc3ULL },
+ { &fnv_test_str[145], (Fnv64_t) 0x47194043c55197a8ULL },
+ { &fnv_test_str[146], (Fnv64_t) 0xc99d81864aebab02ULL },
+ { &fnv_test_str[147], (Fnv64_t) 0xcc1f161b235ea4a2ULL },
+ { &fnv_test_str[148], (Fnv64_t) 0xaadab0c420ecd434ULL },
+ { &fnv_test_str[149], (Fnv64_t) 0x6b3c034d6f44d740ULL },
+ { &fnv_test_str[150], (Fnv64_t) 0x73a45e850602cbc6ULL },
+ { &fnv_test_str[151], (Fnv64_t) 0x72360f04f0cd227bULL },
+ { &fnv_test_str[152], (Fnv64_t) 0xa9ca80be384a778fULL },
+ { &fnv_test_str[153], (Fnv64_t) 0xd4085e66906889e3ULL },
+ { &fnv_test_str[154], (Fnv64_t) 0x93aa8b2748efdbc8ULL },
+ { &fnv_test_str[155], (Fnv64_t) 0x6f8cd678407436a2ULL },
+ { &fnv_test_str[156], (Fnv64_t) 0xf39a43d4dc8be4c7ULL },
+ { &fnv_test_str[157], (Fnv64_t) 0xd7f5cec91125d245ULL },
+ { &fnv_test_str[158], (Fnv64_t) 0x691d7b73be18adc4ULL },
+ { &fnv_test_str[159], (Fnv64_t) 0xf4361e01caf6b691ULL },
+ { &fnv_test_str[160], (Fnv64_t) 0xde7d8264f64be089ULL },
+ { &fnv_test_str[161], (Fnv64_t) 0xa34ff43e5545c06fULL },
+ { &fnv_test_str[162], (Fnv64_t) 0x181f0b8e908a2bdeULL },
+ { &fnv_test_str[163], (Fnv64_t) 0x28a965b78ddbc071ULL },
+ { &fnv_test_str[164], (Fnv64_t) 0xead9cea0e3cc6ae5ULL },
+ { &fnv_test_str[165], (Fnv64_t) 0x0b6743153b43ebbaULL },
+ { &fnv_test_str[166], (Fnv64_t) 0xa7aa3f012c74528dULL },
+ { &fnv_test_str[167], (Fnv64_t) 0x2d5d8ad7f9dffeb7ULL },
+ { &fnv_test_str[168], (Fnv64_t) 0x00750fb6e19624eaULL },
+ { &fnv_test_str[169], (Fnv64_t) 0x01c125a4e6c76c82ULL },
+ { &fnv_test_str[170], (Fnv64_t) 0x3fde3afac0722f1fULL },
+ { &fnv_test_str[171], (Fnv64_t) 0xd7c3eaf4abaa379dULL },
+ { &fnv_test_str[172], (Fnv64_t) 0xd2217e1c923c9f3fULL },
+ { &fnv_test_str[173], (Fnv64_t) 0x82d0a2e3b725caf6ULL },
+ { &fnv_test_str[174], (Fnv64_t) 0x0a10bee8eeb72e4fULL },
+ { &fnv_test_str[175], (Fnv64_t) 0xc530e8723e72c6fdULL },
+ { &fnv_test_str[176], (Fnv64_t) 0xd8d34dcd2e7bad99ULL },
+ { &fnv_test_str[177], (Fnv64_t) 0xecf77466e9a2baf3ULL },
+ { &fnv_test_str[178], (Fnv64_t) 0xde3d2ddb043b9666ULL },
+ { &fnv_test_str[179], (Fnv64_t) 0xd1cc824e1a8157d8ULL },
+ { &fnv_test_str[180], (Fnv64_t) 0x7d5c68ecbc90512eULL },
+ { &fnv_test_str[181], (Fnv64_t) 0x2f7c691b1d7c76d8ULL },
+ { &fnv_test_str[182], (Fnv64_t) 0x5d88c2bad3a46bc8ULL },
+ { &fnv_test_str[183], (Fnv64_t) 0xdf107320276647a0ULL },
+ { &fnv_test_str[184], (Fnv64_t) 0x0f78f22e7e70e9bcULL },
+ { &fnv_test_str[185], (Fnv64_t) 0x8c67be5c80f67d04ULL },
+ { &fnv_test_str[186], (Fnv64_t) 0x07c1adfa4d019194ULL },
+ { &fnv_test_str[187], (Fnv64_t) 0xce1312420c5b1af4ULL },
+ { &fnv_test_str[188], (Fnv64_t) 0x043a41b2dc53ab24ULL },
+ { &fnv_test_str[189], (Fnv64_t) 0x0b038eebf7340860ULL },
+ { &fnv_test_str[190], (Fnv64_t) 0x1bcd837353fb69b0ULL },
+ { &fnv_test_str[191], (Fnv64_t) 0x46f992fc59eff180ULL },
+ { &fnv_test_str[192], (Fnv64_t) 0x497678ee29ae79c0ULL },
+ { &fnv_test_str[193], (Fnv64_t) 0xb10a62280ddd4450ULL },
+ { &fnv_test_str[194], (Fnv64_t) 0x35eb228db4d68140ULL },
+ { &fnv_test_str[195], (Fnv64_t) 0x8b350e86d9470870ULL },
+ { &fnv_test_str[196], (Fnv64_t) 0x4e1fbdb2812e9540ULL },
+ { &fnv_test_str[197], (Fnv64_t) 0x051e080df69a0600ULL },
+ { &fnv_test_str[198], (Fnv64_t) 0x45e1e8ae54dadb40ULL },
+ { &fnv_test_str[199], (Fnv64_t) 0x0000000000000000ULL },
+ { &fnv_test_str[200], (Fnv64_t) 0xcd73806290557064ULL },
+ { &fnv_test_str[201], (Fnv64_t) 0x2613a37bbe0317c8ULL },
+ { &fnv_test_str[202], (Fnv64_t) 0x1480e21fcf2ae5e4ULL },
+ { NULL, (Fnv64_t) 0 }
+};
+#else /* HAVE_64BIT_LONG_LONG */
+struct fnv0_64_test_vector fnv0_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) {0x00000000UL, 0x00000000UL} },
+ { &fnv_test_str[1], (Fnv64_t) {0x00000061UL, 0x00000000UL} },
+ { &fnv_test_str[2], (Fnv64_t) {0x00000062UL, 0x00000000UL} },
+ { &fnv_test_str[3], (Fnv64_t) {0x00000063UL, 0x00000000UL} },
+ { &fnv_test_str[4], (Fnv64_t) {0x00000064UL, 0x00000000UL} },
+ { &fnv_test_str[5], (Fnv64_t) {0x00000065UL, 0x00000000UL} },
+ { &fnv_test_str[6], (Fnv64_t) {0x00000066UL, 0x00000000UL} },
+ { &fnv_test_str[7], (Fnv64_t) {0x0000ad3dUL, 0x00006600UL} },
+ { &fnv_test_str[8], (Fnv64_t) {0x01265ec8UL, 0x015a8f00UL} },
+ { &fnv_test_str[9], (Fnv64_t) {0xf4330dbaUL, 0x733fc501UL} },
+ { &fnv_test_str[10], (Fnv64_t) {0xf2c0536fUL, 0x08697c51UL} },
+ { &fnv_test_str[11], (Fnv64_t) {0x7ccdc5efUL, 0x0b91ae3fUL} },
+ { &fnv_test_str[12], (Fnv64_t) {0x00000000UL, 0x00000000UL} },
+ { &fnv_test_str[13], (Fnv64_t) {0x0000a4d3UL, 0x00006100UL} },
+ { &fnv_test_str[14], (Fnv64_t) {0x0000a686UL, 0x00006200UL} },
+ { &fnv_test_str[15], (Fnv64_t) {0x0000a839UL, 0x00006300UL} },
+ { &fnv_test_str[16], (Fnv64_t) {0x0000a9ecUL, 0x00006400UL} },
+ { &fnv_test_str[17], (Fnv64_t) {0x0000ab9fUL, 0x00006500UL} },
+ { &fnv_test_str[18], (Fnv64_t) {0x0000ad52UL, 0x00006600UL} },
+ { &fnv_test_str[19], (Fnv64_t) {0x01265ea7UL, 0x015a8f00UL} },
+ { &fnv_test_str[20], (Fnv64_t) {0xf4330dd8UL, 0x733fc501UL} },
+ { &fnv_test_str[21], (Fnv64_t) {0xf2c0530eUL, 0x08697c51UL} },
+ { &fnv_test_str[22], (Fnv64_t) {0x7ccdc59dUL, 0x0b91ae3fUL} },
+ { &fnv_test_str[23], (Fnv64_t) {0x11a7551dUL, 0x765104e1UL} },
+ { &fnv_test_str[24], (Fnv64_t) {0x0000a851UL, 0x00006300UL} },
+ { &fnv_test_str[25], (Fnv64_t) {0x011e01ccUL, 0x01508a00UL} },
+ { &fnv_test_str[26], (Fnv64_t) {0xe5fd0dcaUL, 0x59dc4a01UL} },
+ { &fnv_test_str[27], (Fnv64_t) {0xccfe6e59UL, 0xae5f8b39UL} },
+ { &fnv_test_str[28], (Fnv64_t) {0x54558154UL, 0x4ac7ec37UL} },
+ { &fnv_test_str[29], (Fnv64_t) {0x4d4ac19cUL, 0x6737b604UL} },
+ { &fnv_test_str[30], (Fnv64_t) {0x5606fc63UL, 0xae6be54fUL} },
+ { &fnv_test_str[31], (Fnv64_t) {0x2ddedc58UL, 0x685308cfUL} },
+ { &fnv_test_str[32], (Fnv64_t) {0xf1b069fbUL, 0x23f4500aUL} },
+ { &fnv_test_str[33], (Fnv64_t) {0xaec415a1UL, 0xc88dfd98UL} },
+ { &fnv_test_str[34], (Fnv64_t) {0xf730c0fbUL, 0x8d5b8b70UL} },
+ { &fnv_test_str[35], (Fnv64_t) {0x07d7eae4UL, 0x634eebf4UL} },
+ { &fnv_test_str[36], (Fnv64_t) {0x53e4211eUL, 0x9705d3a9UL} },
+ { &fnv_test_str[37], (Fnv64_t) {0x8ca4459fUL, 0x8307c6b9UL} },
+ { &fnv_test_str[38], (Fnv64_t) {0xfb224d0cUL, 0x4a7c4c49UL} },
+ { &fnv_test_str[39], (Fnv64_t) {0xbb48eb6eUL, 0xb382adb5UL} },
+ { &fnv_test_str[40], (Fnv64_t) {0x011e01a3UL, 0x01508a00UL} },
+ { &fnv_test_str[41], (Fnv64_t) {0xe5fd0da4UL, 0x59dc4a01UL} },
+ { &fnv_test_str[42], (Fnv64_t) {0xccfe6e3eUL, 0xae5f8b39UL} },
+ { &fnv_test_str[43], (Fnv64_t) {0x5455813bUL, 0x4ac7ec37UL} },
+ { &fnv_test_str[44], (Fnv64_t) {0x4d4ac1bcUL, 0x6737b604UL} },
+ { &fnv_test_str[45], (Fnv64_t) {0x5606fc14UL, 0xae6be54fUL} },
+ { &fnv_test_str[46], (Fnv64_t) {0x2ddedc39UL, 0x685308cfUL} },
+ { &fnv_test_str[47], (Fnv64_t) {0xf1b06988UL, 0x23f4500aUL} },
+ { &fnv_test_str[48], (Fnv64_t) {0xaec41581UL, 0xc88dfd98UL} },
+ { &fnv_test_str[49], (Fnv64_t) {0xf730c093UL, 0x8d5b8b70UL} },
+ { &fnv_test_str[50], (Fnv64_t) {0x07d7ea81UL, 0x634eebf4UL} },
+ { &fnv_test_str[51], (Fnv64_t) {0x53e4216cUL, 0x9705d3a9UL} },
+ { &fnv_test_str[52], (Fnv64_t) {0x8ca445faUL, 0x8307c6b9UL} },
+ { &fnv_test_str[53], (Fnv64_t) {0xfb224d2dUL, 0x4a7c4c49UL} },
+ { &fnv_test_str[54], (Fnv64_t) {0xbb48eb64UL, 0xb382adb5UL} },
+ { &fnv_test_str[55], (Fnv64_t) {0x3ce80beaUL, 0x4ff899cdUL} },
+ { &fnv_test_str[56], (Fnv64_t) {0x0000a84cUL, 0x00006300UL} },
+ { &fnv_test_str[57], (Fnv64_t) {0x011df956UL, 0x01508500UL} },
+ { &fnv_test_str[58], (Fnv64_t) {0xe5eead46UL, 0x59cb5501UL} },
+ { &fnv_test_str[59], (Fnv64_t) {0xb4906d81UL, 0x832eb839UL} },
+ { &fnv_test_str[60], (Fnv64_t) {0xd16a1213UL, 0x78d08b0dUL} },
+ { &fnv_test_str[61], (Fnv64_t) {0xd73cb628UL, 0xb46e5b7aUL} },
+ { &fnv_test_str[62], (Fnv64_t) {0xbc298596UL, 0xd43b99bbUL} },
+ { &fnv_test_str[63], (Fnv64_t) {0xba8dfd86UL, 0xcacbd000UL} },
+ { &fnv_test_str[64], (Fnv64_t) {0xff45ca92UL, 0x264ff73cUL} },
+ { &fnv_test_str[65], (Fnv64_t) {0xc3973661UL, 0x5fabaea5UL} },
+ { &fnv_test_str[66], (Fnv64_t) {0x59f166bbUL, 0x27f024abUL} },
+ { &fnv_test_str[67], (Fnv64_t) {0xd5318fa4UL, 0xce750a29UL} },
+ { &fnv_test_str[68], (Fnv64_t) {0x433713d5UL, 0x026fe915UL} },
+ { &fnv_test_str[69], (Fnv64_t) {0x3696b2e5UL, 0x5b3ce421UL} },
+ { &fnv_test_str[70], (Fnv64_t) {0x011df924UL, 0x01508500UL} },
+ { &fnv_test_str[71], (Fnv64_t) {0xe5eead22UL, 0x59cb5501UL} },
+ { &fnv_test_str[72], (Fnv64_t) {0xb4906df2UL, 0x832eb839UL} },
+ { &fnv_test_str[73], (Fnv64_t) {0xd16a1233UL, 0x78d08b0dUL} },
+ { &fnv_test_str[74], (Fnv64_t) {0xd73cb649UL, 0xb46e5b7aUL} },
+ { &fnv_test_str[75], (Fnv64_t) {0xbc2985f8UL, 0xd43b99bbUL} },
+ { &fnv_test_str[76], (Fnv64_t) {0xba8dfde2UL, 0xcacbd000UL} },
+ { &fnv_test_str[77], (Fnv64_t) {0xff45cab2UL, 0x264ff73cUL} },
+ { &fnv_test_str[78], (Fnv64_t) {0xc3973616UL, 0x5fabaea5UL} },
+ { &fnv_test_str[79], (Fnv64_t) {0x59f166d3UL, 0x27f024abUL} },
+ { &fnv_test_str[80], (Fnv64_t) {0xd5318fc1UL, 0xce750a29UL} },
+ { &fnv_test_str[81], (Fnv64_t) {0x433713acUL, 0x026fe915UL} },
+ { &fnv_test_str[82], (Fnv64_t) {0x3696b2efUL, 0x5b3ce421UL} },
+ { &fnv_test_str[83], (Fnv64_t) {0xc211fb1fUL, 0x9f2a896fUL} },
+ { &fnv_test_str[84], (Fnv64_t) {0x0000b0d1UL, 0x00006800UL} },
+ { &fnv_test_str[85], (Fnv64_t) {0x012c7323UL, 0x01618900UL} },
+ { &fnv_test_str[86], (Fnv64_t) {0xbc7d03c8UL, 0x3fa86e63UL} },
+ { &fnv_test_str[87], (Fnv64_t) {0x486d6cd8UL, 0xa8375b79UL} },
+ { &fnv_test_str[88], (Fnv64_t) {0xe316ac54UL, 0xa0d18504UL} },
+ { &fnv_test_str[89], (Fnv64_t) {0x04e7fe54UL, 0x08a97b00UL} },
+ { &fnv_test_str[90], (Fnv64_t) {0xe316ac57UL, 0xa0d18504UL} },
+ { &fnv_test_str[91], (Fnv64_t) {0x09cffda9UL, 0x1152f600UL} },
+ { &fnv_test_str[92], (Fnv64_t) {0xe316ac56UL, 0xa0d18504UL} },
+ { &fnv_test_str[93], (Fnv64_t) {0x0eb7fcfeUL, 0x19fc7100UL} },
+ { &fnv_test_str[94], (Fnv64_t) {0xe316ac51UL, 0xa0d18504UL} },
+ { &fnv_test_str[95], (Fnv64_t) {0x139ffa53UL, 0x22a5ec00UL} },
+ { &fnv_test_str[96], (Fnv64_t) {0x39779a33UL, 0x29bed001UL} },
+ { &fnv_test_str[97], (Fnv64_t) {0x4e3c19f5UL, 0x4dbc8101UL} },
+ { &fnv_test_str[98], (Fnv64_t) {0x39779a3dUL, 0x29bed001UL} },
+ { &fnv_test_str[99], (Fnv64_t) {0x6b9f7573UL, 0x81a72b01UL} },
+ { &fnv_test_str[100], (Fnv64_t) {0x39779a23UL, 0x29bed001UL} },
+ { &fnv_test_str[101], (Fnv64_t) {0x9cbbce45UL, 0xd8541101UL} },
+ { &fnv_test_str[102], (Fnv64_t) {0x8621d657UL, 0xf548616bUL} },
+ { &fnv_test_str[103], (Fnv64_t) {0xeb7f35d5UL, 0xebd3e0b4UL} },
+ { &fnv_test_str[104], (Fnv64_t) {0x8621d654UL, 0xf548616bUL} },
+ { &fnv_test_str[105], (Fnv64_t) {0xeb7f30bcUL, 0xebd3ddb4UL} },
+ { &fnv_test_str[106], (Fnv64_t) {0x8621d655UL, 0xf548616bUL} },
+ { &fnv_test_str[107], (Fnv64_t) {0xeb7f326fUL, 0xebd3deb4UL} },
+ { &fnv_test_str[108], (Fnv64_t) {0x40ab0968UL, 0x581cb603UL} },
+ { &fnv_test_str[109], (Fnv64_t) {0xe2a0fbb8UL, 0x63d2af86UL} },
+ { &fnv_test_str[110], (Fnv64_t) {0x40ab0b37UL, 0x581cb703UL} },
+ { &fnv_test_str[111], (Fnv64_t) {0xe2a40e75UL, 0x63d63186UL} },
+ { &fnv_test_str[112], (Fnv64_t) {0x40ab212eUL, 0x581cc403UL} },
+ { &fnv_test_str[113], (Fnv64_t) {0xe2c9612aUL, 0x64023f86UL} },
+ { &fnv_test_str[114], (Fnv64_t) {0xc33c909fUL, 0xdbda6a26UL} },
+ { &fnv_test_str[115], (Fnv64_t) {0xbfe9be2dUL, 0xd0b2feddUL} },
+ { &fnv_test_str[116], (Fnv64_t) {0x5d037decUL, 0x9c9eae3fUL} },
+ { &fnv_test_str[117], (Fnv64_t) {0x0ceef804UL, 0x252001abUL} },
+ { &fnv_test_str[118], (Fnv64_t) {0x9e05cfefUL, 0x4456a56fUL} },
+ { &fnv_test_str[119], (Fnv64_t) {0x83e0531dUL, 0x250b0ba9UL} },
+ { &fnv_test_str[120], (Fnv64_t) {0x3b27b33eUL, 0x52b00721UL} },
+ { &fnv_test_str[121], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} },
+ { &fnv_test_str[122], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[123], (Fnv64_t) {0xddae09f8UL, 0x128599ccUL} },
+ { &fnv_test_str[124], (Fnv64_t) {0xaebaf068UL, 0x270e4f1cUL} },
+ { &fnv_test_str[125], (Fnv64_t) {0x7446a395UL, 0x01517d49UL} },
+ { &fnv_test_str[126], (Fnv64_t) {0x89450b40UL, 0x9af5a29aUL} },
+ { &fnv_test_str[127], (Fnv64_t) {0x63ba72e8UL, 0xb502f6c0UL} },
+ { &fnv_test_str[128], (Fnv64_t) {0x498ca7dfUL, 0xacf41561UL} },
+ { &fnv_test_str[129], (Fnv64_t) {0x3a351542UL, 0x6be8c242UL} },
+ { &fnv_test_str[130], (Fnv64_t) {0xa96ce4a3UL, 0xd04f1f6dUL} },
+ { &fnv_test_str[131], (Fnv64_t) {0x282c7235UL, 0x69eb9a8fUL} },
+ { &fnv_test_str[132], (Fnv64_t) {0x8f77cfc5UL, 0x6a7e5a41UL} },
+ { &fnv_test_str[133], (Fnv64_t) {0xdc2ecba0UL, 0xbcaf568dUL} },
+ { &fnv_test_str[134], (Fnv64_t) {0xc38f8b1fUL, 0xb03b5cc4UL} },
+ { &fnv_test_str[135], (Fnv64_t) {0x432db828UL, 0xf89a9f51UL} },
+ { &fnv_test_str[136], (Fnv64_t) {0xe6103429UL, 0x549e856bUL} },
+ { &fnv_test_str[137], (Fnv64_t) {0x4d29377aUL, 0x3cf50d22UL} },
+ { &fnv_test_str[138], (Fnv64_t) {0x18c10c37UL, 0xdb762df4UL} },
+ { &fnv_test_str[139], (Fnv64_t) {0xb0e9a6baUL, 0xfeeb4226UL} },
+ { &fnv_test_str[140], (Fnv64_t) {0x9310c052UL, 0x7004a4cdUL} },
+ { &fnv_test_str[141], (Fnv64_t) {0xf5329276UL, 0xd1c727d7UL} },
+ { &fnv_test_str[142], (Fnv64_t) {0x596ce908UL, 0xbe313796UL} },
+ { &fnv_test_str[143], (Fnv64_t) {0xe090fcc5UL, 0x768f67edUL} },
+ { &fnv_test_str[144], (Fnv64_t) {0x9db9bfc3UL, 0xa81563ccUL} },
+ { &fnv_test_str[145], (Fnv64_t) {0xc55197a8UL, 0x47194043UL} },
+ { &fnv_test_str[146], (Fnv64_t) {0x4aebab02UL, 0xc99d8186UL} },
+ { &fnv_test_str[147], (Fnv64_t) {0x235ea4a2UL, 0xcc1f161bUL} },
+ { &fnv_test_str[148], (Fnv64_t) {0x20ecd434UL, 0xaadab0c4UL} },
+ { &fnv_test_str[149], (Fnv64_t) {0x6f44d740UL, 0x6b3c034dUL} },
+ { &fnv_test_str[150], (Fnv64_t) {0x0602cbc6UL, 0x73a45e85UL} },
+ { &fnv_test_str[151], (Fnv64_t) {0xf0cd227bUL, 0x72360f04UL} },
+ { &fnv_test_str[152], (Fnv64_t) {0x384a778fUL, 0xa9ca80beUL} },
+ { &fnv_test_str[153], (Fnv64_t) {0x906889e3UL, 0xd4085e66UL} },
+ { &fnv_test_str[154], (Fnv64_t) {0x48efdbc8UL, 0x93aa8b27UL} },
+ { &fnv_test_str[155], (Fnv64_t) {0x407436a2UL, 0x6f8cd678UL} },
+ { &fnv_test_str[156], (Fnv64_t) {0xdc8be4c7UL, 0xf39a43d4UL} },
+ { &fnv_test_str[157], (Fnv64_t) {0x1125d245UL, 0xd7f5cec9UL} },
+ { &fnv_test_str[158], (Fnv64_t) {0xbe18adc4UL, 0x691d7b73UL} },
+ { &fnv_test_str[159], (Fnv64_t) {0xcaf6b691UL, 0xf4361e01UL} },
+ { &fnv_test_str[160], (Fnv64_t) {0xf64be089UL, 0xde7d8264UL} },
+ { &fnv_test_str[161], (Fnv64_t) {0x5545c06fUL, 0xa34ff43eUL} },
+ { &fnv_test_str[162], (Fnv64_t) {0x908a2bdeUL, 0x181f0b8eUL} },
+ { &fnv_test_str[163], (Fnv64_t) {0x8ddbc071UL, 0x28a965b7UL} },
+ { &fnv_test_str[164], (Fnv64_t) {0xe3cc6ae5UL, 0xead9cea0UL} },
+ { &fnv_test_str[165], (Fnv64_t) {0x3b43ebbaUL, 0x0b674315UL} },
+ { &fnv_test_str[166], (Fnv64_t) {0x2c74528dUL, 0xa7aa3f01UL} },
+ { &fnv_test_str[167], (Fnv64_t) {0xf9dffeb7UL, 0x2d5d8ad7UL} },
+ { &fnv_test_str[168], (Fnv64_t) {0xe19624eaUL, 0x00750fb6UL} },
+ { &fnv_test_str[169], (Fnv64_t) {0xe6c76c82UL, 0x01c125a4UL} },
+ { &fnv_test_str[170], (Fnv64_t) {0xc0722f1fUL, 0x3fde3afaUL} },
+ { &fnv_test_str[171], (Fnv64_t) {0xabaa379dUL, 0xd7c3eaf4UL} },
+ { &fnv_test_str[172], (Fnv64_t) {0x923c9f3fUL, 0xd2217e1cUL} },
+ { &fnv_test_str[173], (Fnv64_t) {0xb725caf6UL, 0x82d0a2e3UL} },
+ { &fnv_test_str[174], (Fnv64_t) {0xeeb72e4fUL, 0x0a10bee8UL} },
+ { &fnv_test_str[175], (Fnv64_t) {0x3e72c6fdUL, 0xc530e872UL} },
+ { &fnv_test_str[176], (Fnv64_t) {0x2e7bad99UL, 0xd8d34dcdUL} },
+ { &fnv_test_str[177], (Fnv64_t) {0xe9a2baf3UL, 0xecf77466UL} },
+ { &fnv_test_str[178], (Fnv64_t) {0x043b9666UL, 0xde3d2ddbUL} },
+ { &fnv_test_str[179], (Fnv64_t) {0x1a8157d8UL, 0xd1cc824eUL} },
+ { &fnv_test_str[180], (Fnv64_t) {0xbc90512eUL, 0x7d5c68ecUL} },
+ { &fnv_test_str[181], (Fnv64_t) {0x1d7c76d8UL, 0x2f7c691bUL} },
+ { &fnv_test_str[182], (Fnv64_t) {0xd3a46bc8UL, 0x5d88c2baUL} },
+ { &fnv_test_str[183], (Fnv64_t) {0x276647a0UL, 0xdf107320UL} },
+ { &fnv_test_str[184], (Fnv64_t) {0x7e70e9bcUL, 0x0f78f22eUL} },
+ { &fnv_test_str[185], (Fnv64_t) {0x80f67d04UL, 0x8c67be5cUL} },
+ { &fnv_test_str[186], (Fnv64_t) {0x4d019194UL, 0x07c1adfaUL} },
+ { &fnv_test_str[187], (Fnv64_t) {0x0c5b1af4UL, 0xce131242UL} },
+ { &fnv_test_str[188], (Fnv64_t) {0xdc53ab24UL, 0x043a41b2UL} },
+ { &fnv_test_str[189], (Fnv64_t) {0xf7340860UL, 0x0b038eebUL} },
+ { &fnv_test_str[190], (Fnv64_t) {0x53fb69b0UL, 0x1bcd8373UL} },
+ { &fnv_test_str[191], (Fnv64_t) {0x59eff180UL, 0x46f992fcUL} },
+ { &fnv_test_str[192], (Fnv64_t) {0x29ae79c0UL, 0x497678eeUL} },
+ { &fnv_test_str[193], (Fnv64_t) {0x0ddd4450UL, 0xb10a6228UL} },
+ { &fnv_test_str[194], (Fnv64_t) {0xb4d68140UL, 0x35eb228dUL} },
+ { &fnv_test_str[195], (Fnv64_t) {0xd9470870UL, 0x8b350e86UL} },
+ { &fnv_test_str[196], (Fnv64_t) {0x812e9540UL, 0x4e1fbdb2UL} },
+ { &fnv_test_str[197], (Fnv64_t) {0xf69a0600UL, 0x051e080dUL} },
+ { &fnv_test_str[198], (Fnv64_t) {0x54dadb40UL, 0x45e1e8aeUL} },
+ { &fnv_test_str[199], (Fnv64_t) {0x00000000UL, 0x00000000UL} },
+ { &fnv_test_str[200], (Fnv64_t) {0x90557064UL, 0xcd738062UL} },
+ { &fnv_test_str[201], (Fnv64_t) {0xbe0317c8UL, 0x2613a37bUL} },
+ { &fnv_test_str[202], (Fnv64_t) {0xcf2ae5e4UL, 0x1480e21fUL} },
+ { NULL, (Fnv64_t) {0,0} }
+};
+#endif /* HAVE_64BIT_LONG_LONG */
+
+/* FNV-1 64 bit test vectors */
+#if defined(HAVE_64BIT_LONG_LONG)
+struct fnv1_64_test_vector fnv1_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL },
+ { &fnv_test_str[1], (Fnv64_t) 0xaf63bd4c8601b7beULL },
+ { &fnv_test_str[2], (Fnv64_t) 0xaf63bd4c8601b7bdULL },
+ { &fnv_test_str[3], (Fnv64_t) 0xaf63bd4c8601b7bcULL },
+ { &fnv_test_str[4], (Fnv64_t) 0xaf63bd4c8601b7bbULL },
+ { &fnv_test_str[5], (Fnv64_t) 0xaf63bd4c8601b7baULL },
+ { &fnv_test_str[6], (Fnv64_t) 0xaf63bd4c8601b7b9ULL },
+ { &fnv_test_str[7], (Fnv64_t) 0x08326207b4eb2f34ULL },
+ { &fnv_test_str[8], (Fnv64_t) 0xd8cbc7186ba13533ULL },
+ { &fnv_test_str[9], (Fnv64_t) 0x0378817ee2ed65cbULL },
+ { &fnv_test_str[10], (Fnv64_t) 0xd329d59b9963f790ULL },
+ { &fnv_test_str[11], (Fnv64_t) 0x340d8765a4dda9c2ULL },
+ { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL },
+ { &fnv_test_str[13], (Fnv64_t) 0x08326707b4eb37daULL },
+ { &fnv_test_str[14], (Fnv64_t) 0x08326607b4eb3627ULL },
+ { &fnv_test_str[15], (Fnv64_t) 0x08326507b4eb3474ULL },
+ { &fnv_test_str[16], (Fnv64_t) 0x08326407b4eb32c1ULL },
+ { &fnv_test_str[17], (Fnv64_t) 0x08326307b4eb310eULL },
+ { &fnv_test_str[18], (Fnv64_t) 0x08326207b4eb2f5bULL },
+ { &fnv_test_str[19], (Fnv64_t) 0xd8cbc7186ba1355cULL },
+ { &fnv_test_str[20], (Fnv64_t) 0x0378817ee2ed65a9ULL },
+ { &fnv_test_str[21], (Fnv64_t) 0xd329d59b9963f7f1ULL },
+ { &fnv_test_str[22], (Fnv64_t) 0x340d8765a4dda9b0ULL },
+ { &fnv_test_str[23], (Fnv64_t) 0x50a6d3b724a774a6ULL },
+ { &fnv_test_str[24], (Fnv64_t) 0x08326507b4eb341cULL },
+ { &fnv_test_str[25], (Fnv64_t) 0xd8d5c8186ba98bfbULL },
+ { &fnv_test_str[26], (Fnv64_t) 0x1ccefc7ef118dbefULL },
+ { &fnv_test_str[27], (Fnv64_t) 0x0c92fab3ad3db77aULL },
+ { &fnv_test_str[28], (Fnv64_t) 0x9b77794f5fdec421ULL },
+ { &fnv_test_str[29], (Fnv64_t) 0x0ac742dfe7874433ULL },
+ { &fnv_test_str[30], (Fnv64_t) 0xd7dad5766ad8e2deULL },
+ { &fnv_test_str[31], (Fnv64_t) 0xa1bb96378e897f5bULL },
+ { &fnv_test_str[32], (Fnv64_t) 0x5b3f9b6733a367d2ULL },
+ { &fnv_test_str[33], (Fnv64_t) 0xb07ce25cbea969f6ULL },
+ { &fnv_test_str[34], (Fnv64_t) 0x8d9e9997f9df0d6aULL },
+ { &fnv_test_str[35], (Fnv64_t) 0x838c673d9603cb7bULL },
+ { &fnv_test_str[36], (Fnv64_t) 0x8b5ee8a5e872c273ULL },
+ { &fnv_test_str[37], (Fnv64_t) 0x4507c4e9fb00690cULL },
+ { &fnv_test_str[38], (Fnv64_t) 0x4c9ca59581b27f45ULL },
+ { &fnv_test_str[39], (Fnv64_t) 0xe0aca20b624e4235ULL },
+ { &fnv_test_str[40], (Fnv64_t) 0xd8d5c8186ba98b94ULL },
+ { &fnv_test_str[41], (Fnv64_t) 0x1ccefc7ef118db81ULL },
+ { &fnv_test_str[42], (Fnv64_t) 0x0c92fab3ad3db71dULL },
+ { &fnv_test_str[43], (Fnv64_t) 0x9b77794f5fdec44eULL },
+ { &fnv_test_str[44], (Fnv64_t) 0x0ac742dfe7874413ULL },
+ { &fnv_test_str[45], (Fnv64_t) 0xd7dad5766ad8e2a9ULL },
+ { &fnv_test_str[46], (Fnv64_t) 0xa1bb96378e897f3aULL },
+ { &fnv_test_str[47], (Fnv64_t) 0x5b3f9b6733a367a1ULL },
+ { &fnv_test_str[48], (Fnv64_t) 0xb07ce25cbea969d6ULL },
+ { &fnv_test_str[49], (Fnv64_t) 0x8d9e9997f9df0d02ULL },
+ { &fnv_test_str[50], (Fnv64_t) 0x838c673d9603cb1eULL },
+ { &fnv_test_str[51], (Fnv64_t) 0x8b5ee8a5e872c201ULL },
+ { &fnv_test_str[52], (Fnv64_t) 0x4507c4e9fb006969ULL },
+ { &fnv_test_str[53], (Fnv64_t) 0x4c9ca59581b27f64ULL },
+ { &fnv_test_str[54], (Fnv64_t) 0xe0aca20b624e423fULL },
+ { &fnv_test_str[55], (Fnv64_t) 0x13998e580afa800fULL },
+ { &fnv_test_str[56], (Fnv64_t) 0x08326507b4eb3401ULL },
+ { &fnv_test_str[57], (Fnv64_t) 0xd8d5ad186ba95dc1ULL },
+ { &fnv_test_str[58], (Fnv64_t) 0x1c72e17ef0ca4e97ULL },
+ { &fnv_test_str[59], (Fnv64_t) 0x2183c1b327c38ae6ULL },
+ { &fnv_test_str[60], (Fnv64_t) 0xb66d096c914504f2ULL },
+ { &fnv_test_str[61], (Fnv64_t) 0x404bf57ad8476757ULL },
+ { &fnv_test_str[62], (Fnv64_t) 0x887976bd815498bbULL },
+ { &fnv_test_str[63], (Fnv64_t) 0x3afd7f02c2bf85a5ULL },
+ { &fnv_test_str[64], (Fnv64_t) 0xfc4476b0eb70177fULL },
+ { &fnv_test_str[65], (Fnv64_t) 0x186d2da00f77ecbaULL },
+ { &fnv_test_str[66], (Fnv64_t) 0xf97140fa48c74066ULL },
+ { &fnv_test_str[67], (Fnv64_t) 0xa2b1cf49aa926d37ULL },
+ { &fnv_test_str[68], (Fnv64_t) 0x0690712cd6cf940cULL },
+ { &fnv_test_str[69], (Fnv64_t) 0xf7045b3102b8906eULL },
+ { &fnv_test_str[70], (Fnv64_t) 0xd8d5ad186ba95db3ULL },
+ { &fnv_test_str[71], (Fnv64_t) 0x1c72e17ef0ca4ef3ULL },
+ { &fnv_test_str[72], (Fnv64_t) 0x2183c1b327c38a95ULL },
+ { &fnv_test_str[73], (Fnv64_t) 0xb66d096c914504d2ULL },
+ { &fnv_test_str[74], (Fnv64_t) 0x404bf57ad8476736ULL },
+ { &fnv_test_str[75], (Fnv64_t) 0x887976bd815498d5ULL },
+ { &fnv_test_str[76], (Fnv64_t) 0x3afd7f02c2bf85c1ULL },
+ { &fnv_test_str[77], (Fnv64_t) 0xfc4476b0eb70175fULL },
+ { &fnv_test_str[78], (Fnv64_t) 0x186d2da00f77eccdULL },
+ { &fnv_test_str[79], (Fnv64_t) 0xf97140fa48c7400eULL },
+ { &fnv_test_str[80], (Fnv64_t) 0xa2b1cf49aa926d52ULL },
+ { &fnv_test_str[81], (Fnv64_t) 0x0690712cd6cf9475ULL },
+ { &fnv_test_str[82], (Fnv64_t) 0xf7045b3102b89064ULL },
+ { &fnv_test_str[83], (Fnv64_t) 0x74f762479f9d6aeaULL },
+ { &fnv_test_str[84], (Fnv64_t) 0x08326007b4eb2b9cULL },
+ { &fnv_test_str[85], (Fnv64_t) 0xd8c4c9186b9b1a14ULL },
+ { &fnv_test_str[86], (Fnv64_t) 0x7b495389bdbdd4c7ULL },
+ { &fnv_test_str[87], (Fnv64_t) 0x3b6dba0d69908e25ULL },
+ { &fnv_test_str[88], (Fnv64_t) 0xd6b2b17bf4b71261ULL },
+ { &fnv_test_str[89], (Fnv64_t) 0x447bfb7f98e615b5ULL },
+ { &fnv_test_str[90], (Fnv64_t) 0xd6b2b17bf4b71262ULL },
+ { &fnv_test_str[91], (Fnv64_t) 0x3bd2807f93fe1660ULL },
+ { &fnv_test_str[92], (Fnv64_t) 0xd6b2b17bf4b71263ULL },
+ { &fnv_test_str[93], (Fnv64_t) 0x3329057f8f16170bULL },
+ { &fnv_test_str[94], (Fnv64_t) 0xd6b2b17bf4b71264ULL },
+ { &fnv_test_str[95], (Fnv64_t) 0x2a7f8a7f8a2e19b6ULL },
+ { &fnv_test_str[96], (Fnv64_t) 0x23d3767e64b2f98aULL },
+ { &fnv_test_str[97], (Fnv64_t) 0xff768d7e4f9d86a4ULL },
+ { &fnv_test_str[98], (Fnv64_t) 0x23d3767e64b2f984ULL },
+ { &fnv_test_str[99], (Fnv64_t) 0xccd1837e334e4aa6ULL },
+ { &fnv_test_str[100], (Fnv64_t) 0x23d3767e64b2f99aULL },
+ { &fnv_test_str[101], (Fnv64_t) 0x7691fd7e028f6754ULL },
+ { &fnv_test_str[102], (Fnv64_t) 0x34ad3b1041204318ULL },
+ { &fnv_test_str[103], (Fnv64_t) 0xa29e749ea9d201c8ULL },
+ { &fnv_test_str[104], (Fnv64_t) 0x34ad3b104120431bULL },
+ { &fnv_test_str[105], (Fnv64_t) 0xa29e779ea9d206e1ULL },
+ { &fnv_test_str[106], (Fnv64_t) 0x34ad3b104120431aULL },
+ { &fnv_test_str[107], (Fnv64_t) 0xa29e769ea9d2052eULL },
+ { &fnv_test_str[108], (Fnv64_t) 0x02a17ebca4aa3497ULL },
+ { &fnv_test_str[109], (Fnv64_t) 0x229ef18bcd375c95ULL },
+ { &fnv_test_str[110], (Fnv64_t) 0x02a17dbca4aa32c8ULL },
+ { &fnv_test_str[111], (Fnv64_t) 0x229b6f8bcd3449d8ULL },
+ { &fnv_test_str[112], (Fnv64_t) 0x02a184bca4aa3ed5ULL },
+ { &fnv_test_str[113], (Fnv64_t) 0x22b3618bcd48c3efULL },
+ { &fnv_test_str[114], (Fnv64_t) 0x5c2c346706186f36ULL },
+ { &fnv_test_str[115], (Fnv64_t) 0xb78c410f5b84f8c2ULL },
+ { &fnv_test_str[116], (Fnv64_t) 0xed9478212b267395ULL },
+ { &fnv_test_str[117], (Fnv64_t) 0xd9bbb55c5256662fULL },
+ { &fnv_test_str[118], (Fnv64_t) 0x8c54f0203249438aULL },
+ { &fnv_test_str[119], (Fnv64_t) 0xbd9790b5727dc37eULL },
+ { &fnv_test_str[120], (Fnv64_t) 0xa64e5f36c9e2b0e3ULL },
+ { &fnv_test_str[121], (Fnv64_t) 0x8fd0680da3088a04ULL },
+ { &fnv_test_str[122], (Fnv64_t) 0x67aad32c078284ccULL },
+ { &fnv_test_str[123], (Fnv64_t) 0xb37d55d81c57b331ULL },
+ { &fnv_test_str[124], (Fnv64_t) 0x55ac0f3829057c43ULL },
+ { &fnv_test_str[125], (Fnv64_t) 0xcb27f4b8e1b6cc20ULL },
+ { &fnv_test_str[126], (Fnv64_t) 0x26caf88bcbef2d19ULL },
+ { &fnv_test_str[127], (Fnv64_t) 0x8e6e063b97e61b8fULL },
+ { &fnv_test_str[128], (Fnv64_t) 0xb42750f7f3b7c37eULL },
+ { &fnv_test_str[129], (Fnv64_t) 0xf3c6ba64cf7ca99bULL },
+ { &fnv_test_str[130], (Fnv64_t) 0xebfb69b427ea80feULL },
+ { &fnv_test_str[131], (Fnv64_t) 0x39b50c3ed970f46cULL },
+ { &fnv_test_str[132], (Fnv64_t) 0x5b9b177aa3eb3e8aULL },
+ { &fnv_test_str[133], (Fnv64_t) 0x6510063ecf4ec903ULL },
+ { &fnv_test_str[134], (Fnv64_t) 0x2b3bbd2c00797c7aULL },
+ { &fnv_test_str[135], (Fnv64_t) 0xf1d6204ff5cb4aa7ULL },
+ { &fnv_test_str[136], (Fnv64_t) 0x4836e27ccf099f38ULL },
+ { &fnv_test_str[137], (Fnv64_t) 0x82efbb0dd073b44dULL },
+ { &fnv_test_str[138], (Fnv64_t) 0x4a80c282ffd7d4c6ULL },
+ { &fnv_test_str[139], (Fnv64_t) 0x305d1a9c9ee43bdfULL },
+ { &fnv_test_str[140], (Fnv64_t) 0x15c366948ffc6997ULL },
+ { &fnv_test_str[141], (Fnv64_t) 0x80153ae218916e7bULL },
+ { &fnv_test_str[142], (Fnv64_t) 0xfa23e2bdf9e2a9e1ULL },
+ { &fnv_test_str[143], (Fnv64_t) 0xd47e8d8a2333c6deULL },
+ { &fnv_test_str[144], (Fnv64_t) 0x7e128095f688b056ULL },
+ { &fnv_test_str[145], (Fnv64_t) 0x2f5356890efcedabULL },
+ { &fnv_test_str[146], (Fnv64_t) 0x95c2b383014f55c5ULL },
+ { &fnv_test_str[147], (Fnv64_t) 0x4727a5339ce6070fULL },
+ { &fnv_test_str[148], (Fnv64_t) 0xb0555ecd575108e9ULL },
+ { &fnv_test_str[149], (Fnv64_t) 0x48d785770bb4af37ULL },
+ { &fnv_test_str[150], (Fnv64_t) 0x09d4701c12af02b1ULL },
+ { &fnv_test_str[151], (Fnv64_t) 0x79f031e78f3cf62eULL },
+ { &fnv_test_str[152], (Fnv64_t) 0x52a1ee85db1b5a94ULL },
+ { &fnv_test_str[153], (Fnv64_t) 0x6bd95b2eb37fa6b8ULL },
+ { &fnv_test_str[154], (Fnv64_t) 0x74971b7077aef85dULL },
+ { &fnv_test_str[155], (Fnv64_t) 0xb4e4fae2ffcc1aadULL },
+ { &fnv_test_str[156], (Fnv64_t) 0x2bd48bd898b8f63aULL },
+ { &fnv_test_str[157], (Fnv64_t) 0xe9966ac1556257f6ULL },
+ { &fnv_test_str[158], (Fnv64_t) 0x92a3d1cd078ba293ULL },
+ { &fnv_test_str[159], (Fnv64_t) 0xf81175a482e20ab8ULL },
+ { &fnv_test_str[160], (Fnv64_t) 0x5bbb3de722e73048ULL },
+ { &fnv_test_str[161], (Fnv64_t) 0x6b4f363492b9f2beULL },
+ { &fnv_test_str[162], (Fnv64_t) 0xc2d559df73d59875ULL },
+ { &fnv_test_str[163], (Fnv64_t) 0xf75f62284bc7a8c2ULL },
+ { &fnv_test_str[164], (Fnv64_t) 0xda8dd8e116a9f1ccULL },
+ { &fnv_test_str[165], (Fnv64_t) 0xbdc1e6ab76057885ULL },
+ { &fnv_test_str[166], (Fnv64_t) 0xfec6a4238a1224a0ULL },
+ { &fnv_test_str[167], (Fnv64_t) 0xc03f40f3223e290eULL },
+ { &fnv_test_str[168], (Fnv64_t) 0x1ed21673466ffda9ULL },
+ { &fnv_test_str[169], (Fnv64_t) 0xdf70f906bb0dd2afULL },
+ { &fnv_test_str[170], (Fnv64_t) 0xf3dcda369f2af666ULL },
+ { &fnv_test_str[171], (Fnv64_t) 0x9ebb11573cdcebdeULL },
+ { &fnv_test_str[172], (Fnv64_t) 0x81c72d9077fedca0ULL },
+ { &fnv_test_str[173], (Fnv64_t) 0x0ec074a31be5fb15ULL },
+ { &fnv_test_str[174], (Fnv64_t) 0x2a8b3280b6c48f20ULL },
+ { &fnv_test_str[175], (Fnv64_t) 0xfd31777513309344ULL },
+ { &fnv_test_str[176], (Fnv64_t) 0x194534a86ad006b6ULL },
+ { &fnv_test_str[177], (Fnv64_t) 0x3be6fdf46e0cfe12ULL },
+ { &fnv_test_str[178], (Fnv64_t) 0x017cc137a07eb057ULL },
+ { &fnv_test_str[179], (Fnv64_t) 0x9428fc6e7d26b54dULL },
+ { &fnv_test_str[180], (Fnv64_t) 0x9aaa2e3603ef8ad7ULL },
+ { &fnv_test_str[181], (Fnv64_t) 0x82c6d3f3a0ccdf7dULL },
+ { &fnv_test_str[182], (Fnv64_t) 0xc86eeea00cf09b65ULL },
+ { &fnv_test_str[183], (Fnv64_t) 0x705f8189dbb58299ULL },
+ { &fnv_test_str[184], (Fnv64_t) 0x415a7f554391ca69ULL },
+ { &fnv_test_str[185], (Fnv64_t) 0xcfe3d49fa2bdc555ULL },
+ { &fnv_test_str[186], (Fnv64_t) 0xf0f9c56039b25191ULL },
+ { &fnv_test_str[187], (Fnv64_t) 0x7075cb6abd1d32d9ULL },
+ { &fnv_test_str[188], (Fnv64_t) 0x43c94e2c8b277509ULL },
+ { &fnv_test_str[189], (Fnv64_t) 0x3cbfd4e4ea670359ULL },
+ { &fnv_test_str[190], (Fnv64_t) 0xc05887810f4d019dULL },
+ { &fnv_test_str[191], (Fnv64_t) 0x14468ff93ac22dc5ULL },
+ { &fnv_test_str[192], (Fnv64_t) 0xebed699589d99c05ULL },
+ { &fnv_test_str[193], (Fnv64_t) 0x6d99f6df321ca5d5ULL },
+ { &fnv_test_str[194], (Fnv64_t) 0x0cd410d08c36d625ULL },
+ { &fnv_test_str[195], (Fnv64_t) 0xef1b2a2c86831d35ULL },
+ { &fnv_test_str[196], (Fnv64_t) 0x3b349c4d69ee5f05ULL },
+ { &fnv_test_str[197], (Fnv64_t) 0x55248ce88f45f035ULL },
+ { &fnv_test_str[198], (Fnv64_t) 0xaa69ca6a18a4c885ULL },
+ { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL },
+ { &fnv_test_str[200], (Fnv64_t) 0x0289a488a8df69d9ULL },
+ { &fnv_test_str[201], (Fnv64_t) 0x15e96e1613df98b5ULL },
+ { &fnv_test_str[202], (Fnv64_t) 0xe6be57375ad89b99ULL },
+ { NULL, (Fnv64_t) 0 }
+};
+#else /* HAVE_64BIT_LONG_LONG */
+struct fnv1_64_test_vector fnv1_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} },
+ { &fnv_test_str[1], (Fnv64_t) {0x8601b7beUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[2], (Fnv64_t) {0x8601b7bdUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[3], (Fnv64_t) {0x8601b7bcUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[4], (Fnv64_t) {0x8601b7bbUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[5], (Fnv64_t) {0x8601b7baUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[6], (Fnv64_t) {0x8601b7b9UL, 0xaf63bd4cUL} },
+ { &fnv_test_str[7], (Fnv64_t) {0xb4eb2f34UL, 0x08326207UL} },
+ { &fnv_test_str[8], (Fnv64_t) {0x6ba13533UL, 0xd8cbc718UL} },
+ { &fnv_test_str[9], (Fnv64_t) {0xe2ed65cbUL, 0x0378817eUL} },
+ { &fnv_test_str[10], (Fnv64_t) {0x9963f790UL, 0xd329d59bUL} },
+ { &fnv_test_str[11], (Fnv64_t) {0xa4dda9c2UL, 0x340d8765UL} },
+ { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[13], (Fnv64_t) {0xb4eb37daUL, 0x08326707UL} },
+ { &fnv_test_str[14], (Fnv64_t) {0xb4eb3627UL, 0x08326607UL} },
+ { &fnv_test_str[15], (Fnv64_t) {0xb4eb3474UL, 0x08326507UL} },
+ { &fnv_test_str[16], (Fnv64_t) {0xb4eb32c1UL, 0x08326407UL} },
+ { &fnv_test_str[17], (Fnv64_t) {0xb4eb310eUL, 0x08326307UL} },
+ { &fnv_test_str[18], (Fnv64_t) {0xb4eb2f5bUL, 0x08326207UL} },
+ { &fnv_test_str[19], (Fnv64_t) {0x6ba1355cUL, 0xd8cbc718UL} },
+ { &fnv_test_str[20], (Fnv64_t) {0xe2ed65a9UL, 0x0378817eUL} },
+ { &fnv_test_str[21], (Fnv64_t) {0x9963f7f1UL, 0xd329d59bUL} },
+ { &fnv_test_str[22], (Fnv64_t) {0xa4dda9b0UL, 0x340d8765UL} },
+ { &fnv_test_str[23], (Fnv64_t) {0x24a774a6UL, 0x50a6d3b7UL} },
+ { &fnv_test_str[24], (Fnv64_t) {0xb4eb341cUL, 0x08326507UL} },
+ { &fnv_test_str[25], (Fnv64_t) {0x6ba98bfbUL, 0xd8d5c818UL} },
+ { &fnv_test_str[26], (Fnv64_t) {0xf118dbefUL, 0x1ccefc7eUL} },
+ { &fnv_test_str[27], (Fnv64_t) {0xad3db77aUL, 0x0c92fab3UL} },
+ { &fnv_test_str[28], (Fnv64_t) {0x5fdec421UL, 0x9b77794fUL} },
+ { &fnv_test_str[29], (Fnv64_t) {0xe7874433UL, 0x0ac742dfUL} },
+ { &fnv_test_str[30], (Fnv64_t) {0x6ad8e2deUL, 0xd7dad576UL} },
+ { &fnv_test_str[31], (Fnv64_t) {0x8e897f5bUL, 0xa1bb9637UL} },
+ { &fnv_test_str[32], (Fnv64_t) {0x33a367d2UL, 0x5b3f9b67UL} },
+ { &fnv_test_str[33], (Fnv64_t) {0xbea969f6UL, 0xb07ce25cUL} },
+ { &fnv_test_str[34], (Fnv64_t) {0xf9df0d6aUL, 0x8d9e9997UL} },
+ { &fnv_test_str[35], (Fnv64_t) {0x9603cb7bUL, 0x838c673dUL} },
+ { &fnv_test_str[36], (Fnv64_t) {0xe872c273UL, 0x8b5ee8a5UL} },
+ { &fnv_test_str[37], (Fnv64_t) {0xfb00690cUL, 0x4507c4e9UL} },
+ { &fnv_test_str[38], (Fnv64_t) {0x81b27f45UL, 0x4c9ca595UL} },
+ { &fnv_test_str[39], (Fnv64_t) {0x624e4235UL, 0xe0aca20bUL} },
+ { &fnv_test_str[40], (Fnv64_t) {0x6ba98b94UL, 0xd8d5c818UL} },
+ { &fnv_test_str[41], (Fnv64_t) {0xf118db81UL, 0x1ccefc7eUL} },
+ { &fnv_test_str[42], (Fnv64_t) {0xad3db71dUL, 0x0c92fab3UL} },
+ { &fnv_test_str[43], (Fnv64_t) {0x5fdec44eUL, 0x9b77794fUL} },
+ { &fnv_test_str[44], (Fnv64_t) {0xe7874413UL, 0x0ac742dfUL} },
+ { &fnv_test_str[45], (Fnv64_t) {0x6ad8e2a9UL, 0xd7dad576UL} },
+ { &fnv_test_str[46], (Fnv64_t) {0x8e897f3aUL, 0xa1bb9637UL} },
+ { &fnv_test_str[47], (Fnv64_t) {0x33a367a1UL, 0x5b3f9b67UL} },
+ { &fnv_test_str[48], (Fnv64_t) {0xbea969d6UL, 0xb07ce25cUL} },
+ { &fnv_test_str[49], (Fnv64_t) {0xf9df0d02UL, 0x8d9e9997UL} },
+ { &fnv_test_str[50], (Fnv64_t) {0x9603cb1eUL, 0x838c673dUL} },
+ { &fnv_test_str[51], (Fnv64_t) {0xe872c201UL, 0x8b5ee8a5UL} },
+ { &fnv_test_str[52], (Fnv64_t) {0xfb006969UL, 0x4507c4e9UL} },
+ { &fnv_test_str[53], (Fnv64_t) {0x81b27f64UL, 0x4c9ca595UL} },
+ { &fnv_test_str[54], (Fnv64_t) {0x624e423fUL, 0xe0aca20bUL} },
+ { &fnv_test_str[55], (Fnv64_t) {0x0afa800fUL, 0x13998e58UL} },
+ { &fnv_test_str[56], (Fnv64_t) {0xb4eb3401UL, 0x08326507UL} },
+ { &fnv_test_str[57], (Fnv64_t) {0x6ba95dc1UL, 0xd8d5ad18UL} },
+ { &fnv_test_str[58], (Fnv64_t) {0xf0ca4e97UL, 0x1c72e17eUL} },
+ { &fnv_test_str[59], (Fnv64_t) {0x27c38ae6UL, 0x2183c1b3UL} },
+ { &fnv_test_str[60], (Fnv64_t) {0x914504f2UL, 0xb66d096cUL} },
+ { &fnv_test_str[61], (Fnv64_t) {0xd8476757UL, 0x404bf57aUL} },
+ { &fnv_test_str[62], (Fnv64_t) {0x815498bbUL, 0x887976bdUL} },
+ { &fnv_test_str[63], (Fnv64_t) {0xc2bf85a5UL, 0x3afd7f02UL} },
+ { &fnv_test_str[64], (Fnv64_t) {0xeb70177fUL, 0xfc4476b0UL} },
+ { &fnv_test_str[65], (Fnv64_t) {0x0f77ecbaUL, 0x186d2da0UL} },
+ { &fnv_test_str[66], (Fnv64_t) {0x48c74066UL, 0xf97140faUL} },
+ { &fnv_test_str[67], (Fnv64_t) {0xaa926d37UL, 0xa2b1cf49UL} },
+ { &fnv_test_str[68], (Fnv64_t) {0xd6cf940cUL, 0x0690712cUL} },
+ { &fnv_test_str[69], (Fnv64_t) {0x02b8906eUL, 0xf7045b31UL} },
+ { &fnv_test_str[70], (Fnv64_t) {0x6ba95db3UL, 0xd8d5ad18UL} },
+ { &fnv_test_str[71], (Fnv64_t) {0xf0ca4ef3UL, 0x1c72e17eUL} },
+ { &fnv_test_str[72], (Fnv64_t) {0x27c38a95UL, 0x2183c1b3UL} },
+ { &fnv_test_str[73], (Fnv64_t) {0x914504d2UL, 0xb66d096cUL} },
+ { &fnv_test_str[74], (Fnv64_t) {0xd8476736UL, 0x404bf57aUL} },
+ { &fnv_test_str[75], (Fnv64_t) {0x815498d5UL, 0x887976bdUL} },
+ { &fnv_test_str[76], (Fnv64_t) {0xc2bf85c1UL, 0x3afd7f02UL} },
+ { &fnv_test_str[77], (Fnv64_t) {0xeb70175fUL, 0xfc4476b0UL} },
+ { &fnv_test_str[78], (Fnv64_t) {0x0f77eccdUL, 0x186d2da0UL} },
+ { &fnv_test_str[79], (Fnv64_t) {0x48c7400eUL, 0xf97140faUL} },
+ { &fnv_test_str[80], (Fnv64_t) {0xaa926d52UL, 0xa2b1cf49UL} },
+ { &fnv_test_str[81], (Fnv64_t) {0xd6cf9475UL, 0x0690712cUL} },
+ { &fnv_test_str[82], (Fnv64_t) {0x02b89064UL, 0xf7045b31UL} },
+ { &fnv_test_str[83], (Fnv64_t) {0x9f9d6aeaUL, 0x74f76247UL} },
+ { &fnv_test_str[84], (Fnv64_t) {0xb4eb2b9cUL, 0x08326007UL} },
+ { &fnv_test_str[85], (Fnv64_t) {0x6b9b1a14UL, 0xd8c4c918UL} },
+ { &fnv_test_str[86], (Fnv64_t) {0xbdbdd4c7UL, 0x7b495389UL} },
+ { &fnv_test_str[87], (Fnv64_t) {0x69908e25UL, 0x3b6dba0dUL} },
+ { &fnv_test_str[88], (Fnv64_t) {0xf4b71261UL, 0xd6b2b17bUL} },
+ { &fnv_test_str[89], (Fnv64_t) {0x98e615b5UL, 0x447bfb7fUL} },
+ { &fnv_test_str[90], (Fnv64_t) {0xf4b71262UL, 0xd6b2b17bUL} },
+ { &fnv_test_str[91], (Fnv64_t) {0x93fe1660UL, 0x3bd2807fUL} },
+ { &fnv_test_str[92], (Fnv64_t) {0xf4b71263UL, 0xd6b2b17bUL} },
+ { &fnv_test_str[93], (Fnv64_t) {0x8f16170bUL, 0x3329057fUL} },
+ { &fnv_test_str[94], (Fnv64_t) {0xf4b71264UL, 0xd6b2b17bUL} },
+ { &fnv_test_str[95], (Fnv64_t) {0x8a2e19b6UL, 0x2a7f8a7fUL} },
+ { &fnv_test_str[96], (Fnv64_t) {0x64b2f98aUL, 0x23d3767eUL} },
+ { &fnv_test_str[97], (Fnv64_t) {0x4f9d86a4UL, 0xff768d7eUL} },
+ { &fnv_test_str[98], (Fnv64_t) {0x64b2f984UL, 0x23d3767eUL} },
+ { &fnv_test_str[99], (Fnv64_t) {0x334e4aa6UL, 0xccd1837eUL} },
+ { &fnv_test_str[100], (Fnv64_t) {0x64b2f99aUL, 0x23d3767eUL} },
+ { &fnv_test_str[101], (Fnv64_t) {0x028f6754UL, 0x7691fd7eUL} },
+ { &fnv_test_str[102], (Fnv64_t) {0x41204318UL, 0x34ad3b10UL} },
+ { &fnv_test_str[103], (Fnv64_t) {0xa9d201c8UL, 0xa29e749eUL} },
+ { &fnv_test_str[104], (Fnv64_t) {0x4120431bUL, 0x34ad3b10UL} },
+ { &fnv_test_str[105], (Fnv64_t) {0xa9d206e1UL, 0xa29e779eUL} },
+ { &fnv_test_str[106], (Fnv64_t) {0x4120431aUL, 0x34ad3b10UL} },
+ { &fnv_test_str[107], (Fnv64_t) {0xa9d2052eUL, 0xa29e769eUL} },
+ { &fnv_test_str[108], (Fnv64_t) {0xa4aa3497UL, 0x02a17ebcUL} },
+ { &fnv_test_str[109], (Fnv64_t) {0xcd375c95UL, 0x229ef18bUL} },
+ { &fnv_test_str[110], (Fnv64_t) {0xa4aa32c8UL, 0x02a17dbcUL} },
+ { &fnv_test_str[111], (Fnv64_t) {0xcd3449d8UL, 0x229b6f8bUL} },
+ { &fnv_test_str[112], (Fnv64_t) {0xa4aa3ed5UL, 0x02a184bcUL} },
+ { &fnv_test_str[113], (Fnv64_t) {0xcd48c3efUL, 0x22b3618bUL} },
+ { &fnv_test_str[114], (Fnv64_t) {0x06186f36UL, 0x5c2c3467UL} },
+ { &fnv_test_str[115], (Fnv64_t) {0x5b84f8c2UL, 0xb78c410fUL} },
+ { &fnv_test_str[116], (Fnv64_t) {0x2b267395UL, 0xed947821UL} },
+ { &fnv_test_str[117], (Fnv64_t) {0x5256662fUL, 0xd9bbb55cUL} },
+ { &fnv_test_str[118], (Fnv64_t) {0x3249438aUL, 0x8c54f020UL} },
+ { &fnv_test_str[119], (Fnv64_t) {0x727dc37eUL, 0xbd9790b5UL} },
+ { &fnv_test_str[120], (Fnv64_t) {0xc9e2b0e3UL, 0xa64e5f36UL} },
+ { &fnv_test_str[121], (Fnv64_t) {0xa3088a04UL, 0x8fd0680dUL} },
+ { &fnv_test_str[122], (Fnv64_t) {0x078284ccUL, 0x67aad32cUL} },
+ { &fnv_test_str[123], (Fnv64_t) {0x1c57b331UL, 0xb37d55d8UL} },
+ { &fnv_test_str[124], (Fnv64_t) {0x29057c43UL, 0x55ac0f38UL} },
+ { &fnv_test_str[125], (Fnv64_t) {0xe1b6cc20UL, 0xcb27f4b8UL} },
+ { &fnv_test_str[126], (Fnv64_t) {0xcbef2d19UL, 0x26caf88bUL} },
+ { &fnv_test_str[127], (Fnv64_t) {0x97e61b8fUL, 0x8e6e063bUL} },
+ { &fnv_test_str[128], (Fnv64_t) {0xf3b7c37eUL, 0xb42750f7UL} },
+ { &fnv_test_str[129], (Fnv64_t) {0xcf7ca99bUL, 0xf3c6ba64UL} },
+ { &fnv_test_str[130], (Fnv64_t) {0x27ea80feUL, 0xebfb69b4UL} },
+ { &fnv_test_str[131], (Fnv64_t) {0xd970f46cUL, 0x39b50c3eUL} },
+ { &fnv_test_str[132], (Fnv64_t) {0xa3eb3e8aUL, 0x5b9b177aUL} },
+ { &fnv_test_str[133], (Fnv64_t) {0xcf4ec903UL, 0x6510063eUL} },
+ { &fnv_test_str[134], (Fnv64_t) {0x00797c7aUL, 0x2b3bbd2cUL} },
+ { &fnv_test_str[135], (Fnv64_t) {0xf5cb4aa7UL, 0xf1d6204fUL} },
+ { &fnv_test_str[136], (Fnv64_t) {0xcf099f38UL, 0x4836e27cUL} },
+ { &fnv_test_str[137], (Fnv64_t) {0xd073b44dUL, 0x82efbb0dUL} },
+ { &fnv_test_str[138], (Fnv64_t) {0xffd7d4c6UL, 0x4a80c282UL} },
+ { &fnv_test_str[139], (Fnv64_t) {0x9ee43bdfUL, 0x305d1a9cUL} },
+ { &fnv_test_str[140], (Fnv64_t) {0x8ffc6997UL, 0x15c36694UL} },
+ { &fnv_test_str[141], (Fnv64_t) {0x18916e7bUL, 0x80153ae2UL} },
+ { &fnv_test_str[142], (Fnv64_t) {0xf9e2a9e1UL, 0xfa23e2bdUL} },
+ { &fnv_test_str[143], (Fnv64_t) {0x2333c6deUL, 0xd47e8d8aUL} },
+ { &fnv_test_str[144], (Fnv64_t) {0xf688b056UL, 0x7e128095UL} },
+ { &fnv_test_str[145], (Fnv64_t) {0x0efcedabUL, 0x2f535689UL} },
+ { &fnv_test_str[146], (Fnv64_t) {0x014f55c5UL, 0x95c2b383UL} },
+ { &fnv_test_str[147], (Fnv64_t) {0x9ce6070fUL, 0x4727a533UL} },
+ { &fnv_test_str[148], (Fnv64_t) {0x575108e9UL, 0xb0555ecdUL} },
+ { &fnv_test_str[149], (Fnv64_t) {0x0bb4af37UL, 0x48d78577UL} },
+ { &fnv_test_str[150], (Fnv64_t) {0x12af02b1UL, 0x09d4701cUL} },
+ { &fnv_test_str[151], (Fnv64_t) {0x8f3cf62eUL, 0x79f031e7UL} },
+ { &fnv_test_str[152], (Fnv64_t) {0xdb1b5a94UL, 0x52a1ee85UL} },
+ { &fnv_test_str[153], (Fnv64_t) {0xb37fa6b8UL, 0x6bd95b2eUL} },
+ { &fnv_test_str[154], (Fnv64_t) {0x77aef85dUL, 0x74971b70UL} },
+ { &fnv_test_str[155], (Fnv64_t) {0xffcc1aadUL, 0xb4e4fae2UL} },
+ { &fnv_test_str[156], (Fnv64_t) {0x98b8f63aUL, 0x2bd48bd8UL} },
+ { &fnv_test_str[157], (Fnv64_t) {0x556257f6UL, 0xe9966ac1UL} },
+ { &fnv_test_str[158], (Fnv64_t) {0x078ba293UL, 0x92a3d1cdUL} },
+ { &fnv_test_str[159], (Fnv64_t) {0x82e20ab8UL, 0xf81175a4UL} },
+ { &fnv_test_str[160], (Fnv64_t) {0x22e73048UL, 0x5bbb3de7UL} },
+ { &fnv_test_str[161], (Fnv64_t) {0x92b9f2beUL, 0x6b4f3634UL} },
+ { &fnv_test_str[162], (Fnv64_t) {0x73d59875UL, 0xc2d559dfUL} },
+ { &fnv_test_str[163], (Fnv64_t) {0x4bc7a8c2UL, 0xf75f6228UL} },
+ { &fnv_test_str[164], (Fnv64_t) {0x16a9f1ccUL, 0xda8dd8e1UL} },
+ { &fnv_test_str[165], (Fnv64_t) {0x76057885UL, 0xbdc1e6abUL} },
+ { &fnv_test_str[166], (Fnv64_t) {0x8a1224a0UL, 0xfec6a423UL} },
+ { &fnv_test_str[167], (Fnv64_t) {0x223e290eUL, 0xc03f40f3UL} },
+ { &fnv_test_str[168], (Fnv64_t) {0x466ffda9UL, 0x1ed21673UL} },
+ { &fnv_test_str[169], (Fnv64_t) {0xbb0dd2afUL, 0xdf70f906UL} },
+ { &fnv_test_str[170], (Fnv64_t) {0x9f2af666UL, 0xf3dcda36UL} },
+ { &fnv_test_str[171], (Fnv64_t) {0x3cdcebdeUL, 0x9ebb1157UL} },
+ { &fnv_test_str[172], (Fnv64_t) {0x77fedca0UL, 0x81c72d90UL} },
+ { &fnv_test_str[173], (Fnv64_t) {0x1be5fb15UL, 0x0ec074a3UL} },
+ { &fnv_test_str[174], (Fnv64_t) {0xb6c48f20UL, 0x2a8b3280UL} },
+ { &fnv_test_str[175], (Fnv64_t) {0x13309344UL, 0xfd317775UL} },
+ { &fnv_test_str[176], (Fnv64_t) {0x6ad006b6UL, 0x194534a8UL} },
+ { &fnv_test_str[177], (Fnv64_t) {0x6e0cfe12UL, 0x3be6fdf4UL} },
+ { &fnv_test_str[178], (Fnv64_t) {0xa07eb057UL, 0x017cc137UL} },
+ { &fnv_test_str[179], (Fnv64_t) {0x7d26b54dUL, 0x9428fc6eUL} },
+ { &fnv_test_str[180], (Fnv64_t) {0x03ef8ad7UL, 0x9aaa2e36UL} },
+ { &fnv_test_str[181], (Fnv64_t) {0xa0ccdf7dUL, 0x82c6d3f3UL} },
+ { &fnv_test_str[182], (Fnv64_t) {0x0cf09b65UL, 0xc86eeea0UL} },
+ { &fnv_test_str[183], (Fnv64_t) {0xdbb58299UL, 0x705f8189UL} },
+ { &fnv_test_str[184], (Fnv64_t) {0x4391ca69UL, 0x415a7f55UL} },
+ { &fnv_test_str[185], (Fnv64_t) {0xa2bdc555UL, 0xcfe3d49fUL} },
+ { &fnv_test_str[186], (Fnv64_t) {0x39b25191UL, 0xf0f9c560UL} },
+ { &fnv_test_str[187], (Fnv64_t) {0xbd1d32d9UL, 0x7075cb6aUL} },
+ { &fnv_test_str[188], (Fnv64_t) {0x8b277509UL, 0x43c94e2cUL} },
+ { &fnv_test_str[189], (Fnv64_t) {0xea670359UL, 0x3cbfd4e4UL} },
+ { &fnv_test_str[190], (Fnv64_t) {0x0f4d019dUL, 0xc0588781UL} },
+ { &fnv_test_str[191], (Fnv64_t) {0x3ac22dc5UL, 0x14468ff9UL} },
+ { &fnv_test_str[192], (Fnv64_t) {0x89d99c05UL, 0xebed6995UL} },
+ { &fnv_test_str[193], (Fnv64_t) {0x321ca5d5UL, 0x6d99f6dfUL} },
+ { &fnv_test_str[194], (Fnv64_t) {0x8c36d625UL, 0x0cd410d0UL} },
+ { &fnv_test_str[195], (Fnv64_t) {0x86831d35UL, 0xef1b2a2cUL} },
+ { &fnv_test_str[196], (Fnv64_t) {0x69ee5f05UL, 0x3b349c4dUL} },
+ { &fnv_test_str[197], (Fnv64_t) {0x8f45f035UL, 0x55248ce8UL} },
+ { &fnv_test_str[198], (Fnv64_t) {0x18a4c885UL, 0xaa69ca6aUL} },
+ { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} },
+ { &fnv_test_str[200], (Fnv64_t) {0xa8df69d9UL, 0x0289a488UL} },
+ { &fnv_test_str[201], (Fnv64_t) {0x13df98b5UL, 0x15e96e16UL} },
+ { &fnv_test_str[202], (Fnv64_t) {0x5ad89b99UL, 0xe6be5737UL} },
+ { NULL, (Fnv64_t) {0,0} }
+};
+#endif /* HAVE_64BIT_LONG_LONG */
+
+/* FNV-1a 64 bit test vectors */
+#if defined(HAVE_64BIT_LONG_LONG)
+struct fnv1a_64_test_vector fnv1a_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) 0xcbf29ce484222325ULL },
+ { &fnv_test_str[1], (Fnv64_t) 0xaf63dc4c8601ec8cULL },
+ { &fnv_test_str[2], (Fnv64_t) 0xaf63df4c8601f1a5ULL },
+ { &fnv_test_str[3], (Fnv64_t) 0xaf63de4c8601eff2ULL },
+ { &fnv_test_str[4], (Fnv64_t) 0xaf63d94c8601e773ULL },
+ { &fnv_test_str[5], (Fnv64_t) 0xaf63d84c8601e5c0ULL },
+ { &fnv_test_str[6], (Fnv64_t) 0xaf63db4c8601ead9ULL },
+ { &fnv_test_str[7], (Fnv64_t) 0x08985907b541d342ULL },
+ { &fnv_test_str[8], (Fnv64_t) 0xdcb27518fed9d577ULL },
+ { &fnv_test_str[9], (Fnv64_t) 0xdd120e790c2512afULL },
+ { &fnv_test_str[10], (Fnv64_t) 0xcac165afa2fef40aULL },
+ { &fnv_test_str[11], (Fnv64_t) 0x85944171f73967e8ULL },
+ { &fnv_test_str[12], (Fnv64_t) 0xaf63bd4c8601b7dfULL },
+ { &fnv_test_str[13], (Fnv64_t) 0x089be207b544f1e4ULL },
+ { &fnv_test_str[14], (Fnv64_t) 0x08a61407b54d9b5fULL },
+ { &fnv_test_str[15], (Fnv64_t) 0x08a2ae07b54ab836ULL },
+ { &fnv_test_str[16], (Fnv64_t) 0x0891b007b53c4869ULL },
+ { &fnv_test_str[17], (Fnv64_t) 0x088e4a07b5396540ULL },
+ { &fnv_test_str[18], (Fnv64_t) 0x08987c07b5420ebbULL },
+ { &fnv_test_str[19], (Fnv64_t) 0xdcb28a18fed9f926ULL },
+ { &fnv_test_str[20], (Fnv64_t) 0xdd1270790c25b935ULL },
+ { &fnv_test_str[21], (Fnv64_t) 0xcac146afa2febf5dULL },
+ { &fnv_test_str[22], (Fnv64_t) 0x8593d371f738acfeULL },
+ { &fnv_test_str[23], (Fnv64_t) 0x34531ca7168b8f38ULL },
+ { &fnv_test_str[24], (Fnv64_t) 0x08a25607b54a22aeULL },
+ { &fnv_test_str[25], (Fnv64_t) 0xf5faf0190cf90df3ULL },
+ { &fnv_test_str[26], (Fnv64_t) 0xf27397910b3221c7ULL },
+ { &fnv_test_str[27], (Fnv64_t) 0x2c8c2b76062f22e0ULL },
+ { &fnv_test_str[28], (Fnv64_t) 0xe150688c8217b8fdULL },
+ { &fnv_test_str[29], (Fnv64_t) 0xf35a83c10e4f1f87ULL },
+ { &fnv_test_str[30], (Fnv64_t) 0xd1edd10b507344d0ULL },
+ { &fnv_test_str[31], (Fnv64_t) 0x2a5ee739b3ddb8c3ULL },
+ { &fnv_test_str[32], (Fnv64_t) 0xdcfb970ca1c0d310ULL },
+ { &fnv_test_str[33], (Fnv64_t) 0x4054da76daa6da90ULL },
+ { &fnv_test_str[34], (Fnv64_t) 0xf70a2ff589861368ULL },
+ { &fnv_test_str[35], (Fnv64_t) 0x4c628b38aed25f17ULL },
+ { &fnv_test_str[36], (Fnv64_t) 0x9dd1f6510f78189fULL },
+ { &fnv_test_str[37], (Fnv64_t) 0xa3de85bd491270ceULL },
+ { &fnv_test_str[38], (Fnv64_t) 0x858e2fa32a55e61dULL },
+ { &fnv_test_str[39], (Fnv64_t) 0x46810940eff5f915ULL },
+ { &fnv_test_str[40], (Fnv64_t) 0xf5fadd190cf8edaaULL },
+ { &fnv_test_str[41], (Fnv64_t) 0xf273ed910b32b3e9ULL },
+ { &fnv_test_str[42], (Fnv64_t) 0x2c8c5276062f6525ULL },
+ { &fnv_test_str[43], (Fnv64_t) 0xe150b98c821842a0ULL },
+ { &fnv_test_str[44], (Fnv64_t) 0xf35aa3c10e4f55e7ULL },
+ { &fnv_test_str[45], (Fnv64_t) 0xd1ed680b50729265ULL },
+ { &fnv_test_str[46], (Fnv64_t) 0x2a5f0639b3dded70ULL },
+ { &fnv_test_str[47], (Fnv64_t) 0xdcfbaa0ca1c0f359ULL },
+ { &fnv_test_str[48], (Fnv64_t) 0x4054ba76daa6a430ULL },
+ { &fnv_test_str[49], (Fnv64_t) 0xf709c7f5898562b0ULL },
+ { &fnv_test_str[50], (Fnv64_t) 0x4c62e638aed2f9b8ULL },
+ { &fnv_test_str[51], (Fnv64_t) 0x9dd1a8510f779415ULL },
+ { &fnv_test_str[52], (Fnv64_t) 0xa3de2abd4911d62dULL },
+ { &fnv_test_str[53], (Fnv64_t) 0x858e0ea32a55ae0aULL },
+ { &fnv_test_str[54], (Fnv64_t) 0x46810f40eff60347ULL },
+ { &fnv_test_str[55], (Fnv64_t) 0xc33bce57bef63eafULL },
+ { &fnv_test_str[56], (Fnv64_t) 0x08a24307b54a0265ULL },
+ { &fnv_test_str[57], (Fnv64_t) 0xf5b9fd190cc18d15ULL },
+ { &fnv_test_str[58], (Fnv64_t) 0x4c968290ace35703ULL },
+ { &fnv_test_str[59], (Fnv64_t) 0x07174bd5c64d9350ULL },
+ { &fnv_test_str[60], (Fnv64_t) 0x5a294c3ff5d18750ULL },
+ { &fnv_test_str[61], (Fnv64_t) 0x05b3c1aeb308b843ULL },
+ { &fnv_test_str[62], (Fnv64_t) 0xb92a48da37d0f477ULL },
+ { &fnv_test_str[63], (Fnv64_t) 0x73cdddccd80ebc49ULL },
+ { &fnv_test_str[64], (Fnv64_t) 0xd58c4c13210a266bULL },
+ { &fnv_test_str[65], (Fnv64_t) 0xe78b6081243ec194ULL },
+ { &fnv_test_str[66], (Fnv64_t) 0xb096f77096a39f34ULL },
+ { &fnv_test_str[67], (Fnv64_t) 0xb425c54ff807b6a3ULL },
+ { &fnv_test_str[68], (Fnv64_t) 0x23e520e2751bb46eULL },
+ { &fnv_test_str[69], (Fnv64_t) 0x1a0b44ccfe1385ecULL },
+ { &fnv_test_str[70], (Fnv64_t) 0xf5ba4b190cc2119fULL },
+ { &fnv_test_str[71], (Fnv64_t) 0x4c962690ace2baafULL },
+ { &fnv_test_str[72], (Fnv64_t) 0x0716ded5c64cda19ULL },
+ { &fnv_test_str[73], (Fnv64_t) 0x5a292c3ff5d150f0ULL },
+ { &fnv_test_str[74], (Fnv64_t) 0x05b3e0aeb308ecf0ULL },
+ { &fnv_test_str[75], (Fnv64_t) 0xb92a5eda37d119d9ULL },
+ { &fnv_test_str[76], (Fnv64_t) 0x73ce41ccd80f6635ULL },
+ { &fnv_test_str[77], (Fnv64_t) 0xd58c2c132109f00bULL },
+ { &fnv_test_str[78], (Fnv64_t) 0xe78baf81243f47d1ULL },
+ { &fnv_test_str[79], (Fnv64_t) 0xb0968f7096a2ee7cULL },
+ { &fnv_test_str[80], (Fnv64_t) 0xb425a84ff807855cULL },
+ { &fnv_test_str[81], (Fnv64_t) 0x23e4e9e2751b56f9ULL },
+ { &fnv_test_str[82], (Fnv64_t) 0x1a0b4eccfe1396eaULL },
+ { &fnv_test_str[83], (Fnv64_t) 0x54abd453bb2c9004ULL },
+ { &fnv_test_str[84], (Fnv64_t) 0x08ba5f07b55ec3daULL },
+ { &fnv_test_str[85], (Fnv64_t) 0x337354193006cb6eULL },
+ { &fnv_test_str[86], (Fnv64_t) 0xa430d84680aabd0bULL },
+ { &fnv_test_str[87], (Fnv64_t) 0xa9bc8acca21f39b1ULL },
+ { &fnv_test_str[88], (Fnv64_t) 0x6961196491cc682dULL },
+ { &fnv_test_str[89], (Fnv64_t) 0xad2bb1774799dfe9ULL },
+ { &fnv_test_str[90], (Fnv64_t) 0x6961166491cc6314ULL },
+ { &fnv_test_str[91], (Fnv64_t) 0x8d1bb3904a3b1236ULL },
+ { &fnv_test_str[92], (Fnv64_t) 0x6961176491cc64c7ULL },
+ { &fnv_test_str[93], (Fnv64_t) 0xed205d87f40434c7ULL },
+ { &fnv_test_str[94], (Fnv64_t) 0x6961146491cc5faeULL },
+ { &fnv_test_str[95], (Fnv64_t) 0xcd3baf5e44f8ad9cULL },
+ { &fnv_test_str[96], (Fnv64_t) 0xe3b36596127cd6d8ULL },
+ { &fnv_test_str[97], (Fnv64_t) 0xf77f1072c8e8a646ULL },
+ { &fnv_test_str[98], (Fnv64_t) 0xe3b36396127cd372ULL },
+ { &fnv_test_str[99], (Fnv64_t) 0x6067dce9932ad458ULL },
+ { &fnv_test_str[100], (Fnv64_t) 0xe3b37596127cf208ULL },
+ { &fnv_test_str[101], (Fnv64_t) 0x4b7b10fa9fe83936ULL },
+ { &fnv_test_str[102], (Fnv64_t) 0xaabafe7104d914beULL },
+ { &fnv_test_str[103], (Fnv64_t) 0xf4d3180b3cde3edaULL },
+ { &fnv_test_str[104], (Fnv64_t) 0xaabafd7104d9130bULL },
+ { &fnv_test_str[105], (Fnv64_t) 0xf4cfb20b3cdb5bb1ULL },
+ { &fnv_test_str[106], (Fnv64_t) 0xaabafc7104d91158ULL },
+ { &fnv_test_str[107], (Fnv64_t) 0xf4cc4c0b3cd87888ULL },
+ { &fnv_test_str[108], (Fnv64_t) 0xe729bac5d2a8d3a7ULL },
+ { &fnv_test_str[109], (Fnv64_t) 0x74bc0524f4dfa4c5ULL },
+ { &fnv_test_str[110], (Fnv64_t) 0xe72630c5d2a5b352ULL },
+ { &fnv_test_str[111], (Fnv64_t) 0x6b983224ef8fb456ULL },
+ { &fnv_test_str[112], (Fnv64_t) 0xe73042c5d2ae266dULL },
+ { &fnv_test_str[113], (Fnv64_t) 0x8527e324fdeb4b37ULL },
+ { &fnv_test_str[114], (Fnv64_t) 0x0a83c86fee952abcULL },
+ { &fnv_test_str[115], (Fnv64_t) 0x7318523267779d74ULL },
+ { &fnv_test_str[116], (Fnv64_t) 0x3e66d3d56b8caca1ULL },
+ { &fnv_test_str[117], (Fnv64_t) 0x956694a5c0095593ULL },
+ { &fnv_test_str[118], (Fnv64_t) 0xcac54572bb1a6fc8ULL },
+ { &fnv_test_str[119], (Fnv64_t) 0xa7a4c9f3edebf0d8ULL },
+ { &fnv_test_str[120], (Fnv64_t) 0x7829851fac17b143ULL },
+ { &fnv_test_str[121], (Fnv64_t) 0x2c8f4c9af81bcf06ULL },
+ { &fnv_test_str[122], (Fnv64_t) 0xd34e31539740c732ULL },
+ { &fnv_test_str[123], (Fnv64_t) 0x3605a2ac253d2db1ULL },
+ { &fnv_test_str[124], (Fnv64_t) 0x08c11b8346f4a3c3ULL },
+ { &fnv_test_str[125], (Fnv64_t) 0x6be396289ce8a6daULL },
+ { &fnv_test_str[126], (Fnv64_t) 0xd9b957fb7fe794c5ULL },
+ { &fnv_test_str[127], (Fnv64_t) 0x05be33da04560a93ULL },
+ { &fnv_test_str[128], (Fnv64_t) 0x0957f1577ba9747cULL },
+ { &fnv_test_str[129], (Fnv64_t) 0xda2cc3acc24fba57ULL },
+ { &fnv_test_str[130], (Fnv64_t) 0x74136f185b29e7f0ULL },
+ { &fnv_test_str[131], (Fnv64_t) 0xb2f2b4590edb93b2ULL },
+ { &fnv_test_str[132], (Fnv64_t) 0xb3608fce8b86ae04ULL },
+ { &fnv_test_str[133], (Fnv64_t) 0x4a3a865079359063ULL },
+ { &fnv_test_str[134], (Fnv64_t) 0x5b3a7ef496880a50ULL },
+ { &fnv_test_str[135], (Fnv64_t) 0x48fae3163854c23bULL },
+ { &fnv_test_str[136], (Fnv64_t) 0x07aaa640476e0b9aULL },
+ { &fnv_test_str[137], (Fnv64_t) 0x2f653656383a687dULL },
+ { &fnv_test_str[138], (Fnv64_t) 0xa1031f8e7599d79cULL },
+ { &fnv_test_str[139], (Fnv64_t) 0xa31908178ff92477ULL },
+ { &fnv_test_str[140], (Fnv64_t) 0x097edf3c14c3fb83ULL },
+ { &fnv_test_str[141], (Fnv64_t) 0xb51ca83feaa0971bULL },
+ { &fnv_test_str[142], (Fnv64_t) 0xdd3c0d96d784f2e9ULL },
+ { &fnv_test_str[143], (Fnv64_t) 0x86cd26a9ea767d78ULL },
+ { &fnv_test_str[144], (Fnv64_t) 0xe6b215ff54a30c18ULL },
+ { &fnv_test_str[145], (Fnv64_t) 0xec5b06a1c5531093ULL },
+ { &fnv_test_str[146], (Fnv64_t) 0x45665a929f9ec5e5ULL },
+ { &fnv_test_str[147], (Fnv64_t) 0x8c7609b4a9f10907ULL },
+ { &fnv_test_str[148], (Fnv64_t) 0x89aac3a491f0d729ULL },
+ { &fnv_test_str[149], (Fnv64_t) 0x32ce6b26e0f4a403ULL },
+ { &fnv_test_str[150], (Fnv64_t) 0x614ab44e02b53e01ULL },
+ { &fnv_test_str[151], (Fnv64_t) 0xfa6472eb6eef3290ULL },
+ { &fnv_test_str[152], (Fnv64_t) 0x9e5d75eb1948eb6aULL },
+ { &fnv_test_str[153], (Fnv64_t) 0xb6d12ad4a8671852ULL },
+ { &fnv_test_str[154], (Fnv64_t) 0x88826f56eba07af1ULL },
+ { &fnv_test_str[155], (Fnv64_t) 0x44535bf2645bc0fdULL },
+ { &fnv_test_str[156], (Fnv64_t) 0x169388ffc21e3728ULL },
+ { &fnv_test_str[157], (Fnv64_t) 0xf68aac9e396d8224ULL },
+ { &fnv_test_str[158], (Fnv64_t) 0x8e87d7e7472b3883ULL },
+ { &fnv_test_str[159], (Fnv64_t) 0x295c26caa8b423deULL },
+ { &fnv_test_str[160], (Fnv64_t) 0x322c814292e72176ULL },
+ { &fnv_test_str[161], (Fnv64_t) 0x8a06550eb8af7268ULL },
+ { &fnv_test_str[162], (Fnv64_t) 0xef86d60e661bcf71ULL },
+ { &fnv_test_str[163], (Fnv64_t) 0x9e5426c87f30ee54ULL },
+ { &fnv_test_str[164], (Fnv64_t) 0xf1ea8aa826fd047eULL },
+ { &fnv_test_str[165], (Fnv64_t) 0x0babaf9a642cb769ULL },
+ { &fnv_test_str[166], (Fnv64_t) 0x4b3341d4068d012eULL },
+ { &fnv_test_str[167], (Fnv64_t) 0xd15605cbc30a335cULL },
+ { &fnv_test_str[168], (Fnv64_t) 0x5b21060aed8412e5ULL },
+ { &fnv_test_str[169], (Fnv64_t) 0x45e2cda1ce6f4227ULL },
+ { &fnv_test_str[170], (Fnv64_t) 0x50ae3745033ad7d4ULL },
+ { &fnv_test_str[171], (Fnv64_t) 0xaa4588ced46bf414ULL },
+ { &fnv_test_str[172], (Fnv64_t) 0xc1b0056c4a95467eULL },
+ { &fnv_test_str[173], (Fnv64_t) 0x56576a71de8b4089ULL },
+ { &fnv_test_str[174], (Fnv64_t) 0xbf20965fa6dc927eULL },
+ { &fnv_test_str[175], (Fnv64_t) 0x569f8383c2040882ULL },
+ { &fnv_test_str[176], (Fnv64_t) 0xe1e772fba08feca0ULL },
+ { &fnv_test_str[177], (Fnv64_t) 0x4ced94af97138ac4ULL },
+ { &fnv_test_str[178], (Fnv64_t) 0xc4112ffb337a82fbULL },
+ { &fnv_test_str[179], (Fnv64_t) 0xd64a4fd41de38b7dULL },
+ { &fnv_test_str[180], (Fnv64_t) 0x4cfc32329edebcbbULL },
+ { &fnv_test_str[181], (Fnv64_t) 0x0803564445050395ULL },
+ { &fnv_test_str[182], (Fnv64_t) 0xaa1574ecf4642ffdULL },
+ { &fnv_test_str[183], (Fnv64_t) 0x694bc4e54cc315f9ULL },
+ { &fnv_test_str[184], (Fnv64_t) 0xa3d7cb273b011721ULL },
+ { &fnv_test_str[185], (Fnv64_t) 0x577c2f8b6115bfa5ULL },
+ { &fnv_test_str[186], (Fnv64_t) 0xb7ec8c1a769fb4c1ULL },
+ { &fnv_test_str[187], (Fnv64_t) 0x5d5cfce63359ab19ULL },
+ { &fnv_test_str[188], (Fnv64_t) 0x33b96c3cd65b5f71ULL },
+ { &fnv_test_str[189], (Fnv64_t) 0xd845097780602bb9ULL },
+ { &fnv_test_str[190], (Fnv64_t) 0x84d47645d02da3d5ULL },
+ { &fnv_test_str[191], (Fnv64_t) 0x83544f33b58773a5ULL },
+ { &fnv_test_str[192], (Fnv64_t) 0x9175cbb2160836c5ULL },
+ { &fnv_test_str[193], (Fnv64_t) 0xc71b3bc175e72bc5ULL },
+ { &fnv_test_str[194], (Fnv64_t) 0x636806ac222ec985ULL },
+ { &fnv_test_str[195], (Fnv64_t) 0xb6ef0e6950f52ed5ULL },
+ { &fnv_test_str[196], (Fnv64_t) 0xead3d8a0f3dfdaa5ULL },
+ { &fnv_test_str[197], (Fnv64_t) 0x922908fe9a861ba5ULL },
+ { &fnv_test_str[198], (Fnv64_t) 0x6d4821de275fd5c5ULL },
+ { &fnv_test_str[199], (Fnv64_t) 0x1fe3fce62bd816b5ULL },
+ { &fnv_test_str[200], (Fnv64_t) 0xc23e9fccd6f70591ULL },
+ { &fnv_test_str[201], (Fnv64_t) 0xc1af12bdfe16b5b5ULL },
+ { &fnv_test_str[202], (Fnv64_t) 0x39e9f18f2f85e221ULL },
+ { NULL, (Fnv64_t) 0 }
+};
+#else /* HAVE_64BIT_LONG_LONG */
+struct fnv1a_64_test_vector fnv1a_64_vector[] = {
+ { &fnv_test_str[0], (Fnv64_t) {0x84222325UL, 0xcbf29ce4UL} },
+ { &fnv_test_str[1], (Fnv64_t) {0x8601ec8cUL, 0xaf63dc4cUL} },
+ { &fnv_test_str[2], (Fnv64_t) {0x8601f1a5UL, 0xaf63df4cUL} },
+ { &fnv_test_str[3], (Fnv64_t) {0x8601eff2UL, 0xaf63de4cUL} },
+ { &fnv_test_str[4], (Fnv64_t) {0x8601e773UL, 0xaf63d94cUL} },
+ { &fnv_test_str[5], (Fnv64_t) {0x8601e5c0UL, 0xaf63d84cUL} },
+ { &fnv_test_str[6], (Fnv64_t) {0x8601ead9UL, 0xaf63db4cUL} },
+ { &fnv_test_str[7], (Fnv64_t) {0xb541d342UL, 0x08985907UL} },
+ { &fnv_test_str[8], (Fnv64_t) {0xfed9d577UL, 0xdcb27518UL} },
+ { &fnv_test_str[9], (Fnv64_t) {0x0c2512afUL, 0xdd120e79UL} },
+ { &fnv_test_str[10], (Fnv64_t) {0xa2fef40aUL, 0xcac165afUL} },
+ { &fnv_test_str[11], (Fnv64_t) {0xf73967e8UL, 0x85944171UL} },
+ { &fnv_test_str[12], (Fnv64_t) {0x8601b7dfUL, 0xaf63bd4cUL} },
+ { &fnv_test_str[13], (Fnv64_t) {0xb544f1e4UL, 0x089be207UL} },
+ { &fnv_test_str[14], (Fnv64_t) {0xb54d9b5fUL, 0x08a61407UL} },
+ { &fnv_test_str[15], (Fnv64_t) {0xb54ab836UL, 0x08a2ae07UL} },
+ { &fnv_test_str[16], (Fnv64_t) {0xb53c4869UL, 0x0891b007UL} },
+ { &fnv_test_str[17], (Fnv64_t) {0xb5396540UL, 0x088e4a07UL} },
+ { &fnv_test_str[18], (Fnv64_t) {0xb5420ebbUL, 0x08987c07UL} },
+ { &fnv_test_str[19], (Fnv64_t) {0xfed9f926UL, 0xdcb28a18UL} },
+ { &fnv_test_str[20], (Fnv64_t) {0x0c25b935UL, 0xdd127079UL} },
+ { &fnv_test_str[21], (Fnv64_t) {0xa2febf5dUL, 0xcac146afUL} },
+ { &fnv_test_str[22], (Fnv64_t) {0xf738acfeUL, 0x8593d371UL} },
+ { &fnv_test_str[23], (Fnv64_t) {0x168b8f38UL, 0x34531ca7UL} },
+ { &fnv_test_str[24], (Fnv64_t) {0xb54a22aeUL, 0x08a25607UL} },
+ { &fnv_test_str[25], (Fnv64_t) {0x0cf90df3UL, 0xf5faf019UL} },
+ { &fnv_test_str[26], (Fnv64_t) {0x0b3221c7UL, 0xf2739791UL} },
+ { &fnv_test_str[27], (Fnv64_t) {0x062f22e0UL, 0x2c8c2b76UL} },
+ { &fnv_test_str[28], (Fnv64_t) {0x8217b8fdUL, 0xe150688cUL} },
+ { &fnv_test_str[29], (Fnv64_t) {0x0e4f1f87UL, 0xf35a83c1UL} },
+ { &fnv_test_str[30], (Fnv64_t) {0x507344d0UL, 0xd1edd10bUL} },
+ { &fnv_test_str[31], (Fnv64_t) {0xb3ddb8c3UL, 0x2a5ee739UL} },
+ { &fnv_test_str[32], (Fnv64_t) {0xa1c0d310UL, 0xdcfb970cUL} },
+ { &fnv_test_str[33], (Fnv64_t) {0xdaa6da90UL, 0x4054da76UL} },
+ { &fnv_test_str[34], (Fnv64_t) {0x89861368UL, 0xf70a2ff5UL} },
+ { &fnv_test_str[35], (Fnv64_t) {0xaed25f17UL, 0x4c628b38UL} },
+ { &fnv_test_str[36], (Fnv64_t) {0x0f78189fUL, 0x9dd1f651UL} },
+ { &fnv_test_str[37], (Fnv64_t) {0x491270ceUL, 0xa3de85bdUL} },
+ { &fnv_test_str[38], (Fnv64_t) {0x2a55e61dUL, 0x858e2fa3UL} },
+ { &fnv_test_str[39], (Fnv64_t) {0xeff5f915UL, 0x46810940UL} },
+ { &fnv_test_str[40], (Fnv64_t) {0x0cf8edaaUL, 0xf5fadd19UL} },
+ { &fnv_test_str[41], (Fnv64_t) {0x0b32b3e9UL, 0xf273ed91UL} },
+ { &fnv_test_str[42], (Fnv64_t) {0x062f6525UL, 0x2c8c5276UL} },
+ { &fnv_test_str[43], (Fnv64_t) {0x821842a0UL, 0xe150b98cUL} },
+ { &fnv_test_str[44], (Fnv64_t) {0x0e4f55e7UL, 0xf35aa3c1UL} },
+ { &fnv_test_str[45], (Fnv64_t) {0x50729265UL, 0xd1ed680bUL} },
+ { &fnv_test_str[46], (Fnv64_t) {0xb3dded70UL, 0x2a5f0639UL} },
+ { &fnv_test_str[47], (Fnv64_t) {0xa1c0f359UL, 0xdcfbaa0cUL} },
+ { &fnv_test_str[48], (Fnv64_t) {0xdaa6a430UL, 0x4054ba76UL} },
+ { &fnv_test_str[49], (Fnv64_t) {0x898562b0UL, 0xf709c7f5UL} },
+ { &fnv_test_str[50], (Fnv64_t) {0xaed2f9b8UL, 0x4c62e638UL} },
+ { &fnv_test_str[51], (Fnv64_t) {0x0f779415UL, 0x9dd1a851UL} },
+ { &fnv_test_str[52], (Fnv64_t) {0x4911d62dUL, 0xa3de2abdUL} },
+ { &fnv_test_str[53], (Fnv64_t) {0x2a55ae0aUL, 0x858e0ea3UL} },
+ { &fnv_test_str[54], (Fnv64_t) {0xeff60347UL, 0x46810f40UL} },
+ { &fnv_test_str[55], (Fnv64_t) {0xbef63eafUL, 0xc33bce57UL} },
+ { &fnv_test_str[56], (Fnv64_t) {0xb54a0265UL, 0x08a24307UL} },
+ { &fnv_test_str[57], (Fnv64_t) {0x0cc18d15UL, 0xf5b9fd19UL} },
+ { &fnv_test_str[58], (Fnv64_t) {0xace35703UL, 0x4c968290UL} },
+ { &fnv_test_str[59], (Fnv64_t) {0xc64d9350UL, 0x07174bd5UL} },
+ { &fnv_test_str[60], (Fnv64_t) {0xf5d18750UL, 0x5a294c3fUL} },
+ { &fnv_test_str[61], (Fnv64_t) {0xb308b843UL, 0x05b3c1aeUL} },
+ { &fnv_test_str[62], (Fnv64_t) {0x37d0f477UL, 0xb92a48daUL} },
+ { &fnv_test_str[63], (Fnv64_t) {0xd80ebc49UL, 0x73cdddccUL} },
+ { &fnv_test_str[64], (Fnv64_t) {0x210a266bUL, 0xd58c4c13UL} },
+ { &fnv_test_str[65], (Fnv64_t) {0x243ec194UL, 0xe78b6081UL} },
+ { &fnv_test_str[66], (Fnv64_t) {0x96a39f34UL, 0xb096f770UL} },
+ { &fnv_test_str[67], (Fnv64_t) {0xf807b6a3UL, 0xb425c54fUL} },
+ { &fnv_test_str[68], (Fnv64_t) {0x751bb46eUL, 0x23e520e2UL} },
+ { &fnv_test_str[69], (Fnv64_t) {0xfe1385ecUL, 0x1a0b44ccUL} },
+ { &fnv_test_str[70], (Fnv64_t) {0x0cc2119fUL, 0xf5ba4b19UL} },
+ { &fnv_test_str[71], (Fnv64_t) {0xace2baafUL, 0x4c962690UL} },
+ { &fnv_test_str[72], (Fnv64_t) {0xc64cda19UL, 0x0716ded5UL} },
+ { &fnv_test_str[73], (Fnv64_t) {0xf5d150f0UL, 0x5a292c3fUL} },
+ { &fnv_test_str[74], (Fnv64_t) {0xb308ecf0UL, 0x05b3e0aeUL} },
+ { &fnv_test_str[75], (Fnv64_t) {0x37d119d9UL, 0xb92a5edaUL} },
+ { &fnv_test_str[76], (Fnv64_t) {0xd80f6635UL, 0x73ce41ccUL} },
+ { &fnv_test_str[77], (Fnv64_t) {0x2109f00bUL, 0xd58c2c13UL} },
+ { &fnv_test_str[78], (Fnv64_t) {0x243f47d1UL, 0xe78baf81UL} },
+ { &fnv_test_str[79], (Fnv64_t) {0x96a2ee7cUL, 0xb0968f70UL} },
+ { &fnv_test_str[80], (Fnv64_t) {0xf807855cUL, 0xb425a84fUL} },
+ { &fnv_test_str[81], (Fnv64_t) {0x751b56f9UL, 0x23e4e9e2UL} },
+ { &fnv_test_str[82], (Fnv64_t) {0xfe1396eaUL, 0x1a0b4eccUL} },
+ { &fnv_test_str[83], (Fnv64_t) {0xbb2c9004UL, 0x54abd453UL} },
+ { &fnv_test_str[84], (Fnv64_t) {0xb55ec3daUL, 0x08ba5f07UL} },
+ { &fnv_test_str[85], (Fnv64_t) {0x3006cb6eUL, 0x33735419UL} },
+ { &fnv_test_str[86], (Fnv64_t) {0x80aabd0bUL, 0xa430d846UL} },
+ { &fnv_test_str[87], (Fnv64_t) {0xa21f39b1UL, 0xa9bc8accUL} },
+ { &fnv_test_str[88], (Fnv64_t) {0x91cc682dUL, 0x69611964UL} },
+ { &fnv_test_str[89], (Fnv64_t) {0x4799dfe9UL, 0xad2bb177UL} },
+ { &fnv_test_str[90], (Fnv64_t) {0x91cc6314UL, 0x69611664UL} },
+ { &fnv_test_str[91], (Fnv64_t) {0x4a3b1236UL, 0x8d1bb390UL} },
+ { &fnv_test_str[92], (Fnv64_t) {0x91cc64c7UL, 0x69611764UL} },
+ { &fnv_test_str[93], (Fnv64_t) {0xf40434c7UL, 0xed205d87UL} },
+ { &fnv_test_str[94], (Fnv64_t) {0x91cc5faeUL, 0x69611464UL} },
+ { &fnv_test_str[95], (Fnv64_t) {0x44f8ad9cUL, 0xcd3baf5eUL} },
+ { &fnv_test_str[96], (Fnv64_t) {0x127cd6d8UL, 0xe3b36596UL} },
+ { &fnv_test_str[97], (Fnv64_t) {0xc8e8a646UL, 0xf77f1072UL} },
+ { &fnv_test_str[98], (Fnv64_t) {0x127cd372UL, 0xe3b36396UL} },
+ { &fnv_test_str[99], (Fnv64_t) {0x932ad458UL, 0x6067dce9UL} },
+ { &fnv_test_str[100], (Fnv64_t) {0x127cf208UL, 0xe3b37596UL} },
+ { &fnv_test_str[101], (Fnv64_t) {0x9fe83936UL, 0x4b7b10faUL} },
+ { &fnv_test_str[102], (Fnv64_t) {0x04d914beUL, 0xaabafe71UL} },
+ { &fnv_test_str[103], (Fnv64_t) {0x3cde3edaUL, 0xf4d3180bUL} },
+ { &fnv_test_str[104], (Fnv64_t) {0x04d9130bUL, 0xaabafd71UL} },
+ { &fnv_test_str[105], (Fnv64_t) {0x3cdb5bb1UL, 0xf4cfb20bUL} },
+ { &fnv_test_str[106], (Fnv64_t) {0x04d91158UL, 0xaabafc71UL} },
+ { &fnv_test_str[107], (Fnv64_t) {0x3cd87888UL, 0xf4cc4c0bUL} },
+ { &fnv_test_str[108], (Fnv64_t) {0xd2a8d3a7UL, 0xe729bac5UL} },
+ { &fnv_test_str[109], (Fnv64_t) {0xf4dfa4c5UL, 0x74bc0524UL} },
+ { &fnv_test_str[110], (Fnv64_t) {0xd2a5b352UL, 0xe72630c5UL} },
+ { &fnv_test_str[111], (Fnv64_t) {0xef8fb456UL, 0x6b983224UL} },
+ { &fnv_test_str[112], (Fnv64_t) {0xd2ae266dUL, 0xe73042c5UL} },
+ { &fnv_test_str[113], (Fnv64_t) {0xfdeb4b37UL, 0x8527e324UL} },
+ { &fnv_test_str[114], (Fnv64_t) {0xee952abcUL, 0x0a83c86fUL} },
+ { &fnv_test_str[115], (Fnv64_t) {0x67779d74UL, 0x73185232UL} },
+ { &fnv_test_str[116], (Fnv64_t) {0x6b8caca1UL, 0x3e66d3d5UL} },
+ { &fnv_test_str[117], (Fnv64_t) {0xc0095593UL, 0x956694a5UL} },
+ { &fnv_test_str[118], (Fnv64_t) {0xbb1a6fc8UL, 0xcac54572UL} },
+ { &fnv_test_str[119], (Fnv64_t) {0xedebf0d8UL, 0xa7a4c9f3UL} },
+ { &fnv_test_str[120], (Fnv64_t) {0xac17b143UL, 0x7829851fUL} },
+ { &fnv_test_str[121], (Fnv64_t) {0xf81bcf06UL, 0x2c8f4c9aUL} },
+ { &fnv_test_str[122], (Fnv64_t) {0x9740c732UL, 0xd34e3153UL} },
+ { &fnv_test_str[123], (Fnv64_t) {0x253d2db1UL, 0x3605a2acUL} },
+ { &fnv_test_str[124], (Fnv64_t) {0x46f4a3c3UL, 0x08c11b83UL} },
+ { &fnv_test_str[125], (Fnv64_t) {0x9ce8a6daUL, 0x6be39628UL} },
+ { &fnv_test_str[126], (Fnv64_t) {0x7fe794c5UL, 0xd9b957fbUL} },
+ { &fnv_test_str[127], (Fnv64_t) {0x04560a93UL, 0x05be33daUL} },
+ { &fnv_test_str[128], (Fnv64_t) {0x7ba9747cUL, 0x0957f157UL} },
+ { &fnv_test_str[129], (Fnv64_t) {0xc24fba57UL, 0xda2cc3acUL} },
+ { &fnv_test_str[130], (Fnv64_t) {0x5b29e7f0UL, 0x74136f18UL} },
+ { &fnv_test_str[131], (Fnv64_t) {0x0edb93b2UL, 0xb2f2b459UL} },
+ { &fnv_test_str[132], (Fnv64_t) {0x8b86ae04UL, 0xb3608fceUL} },
+ { &fnv_test_str[133], (Fnv64_t) {0x79359063UL, 0x4a3a8650UL} },
+ { &fnv_test_str[134], (Fnv64_t) {0x96880a50UL, 0x5b3a7ef4UL} },
+ { &fnv_test_str[135], (Fnv64_t) {0x3854c23bUL, 0x48fae316UL} },
+ { &fnv_test_str[136], (Fnv64_t) {0x476e0b9aUL, 0x07aaa640UL} },
+ { &fnv_test_str[137], (Fnv64_t) {0x383a687dUL, 0x2f653656UL} },
+ { &fnv_test_str[138], (Fnv64_t) {0x7599d79cUL, 0xa1031f8eUL} },
+ { &fnv_test_str[139], (Fnv64_t) {0x8ff92477UL, 0xa3190817UL} },
+ { &fnv_test_str[140], (Fnv64_t) {0x14c3fb83UL, 0x097edf3cUL} },
+ { &fnv_test_str[141], (Fnv64_t) {0xeaa0971bUL, 0xb51ca83fUL} },
+ { &fnv_test_str[142], (Fnv64_t) {0xd784f2e9UL, 0xdd3c0d96UL} },
+ { &fnv_test_str[143], (Fnv64_t) {0xea767d78UL, 0x86cd26a9UL} },
+ { &fnv_test_str[144], (Fnv64_t) {0x54a30c18UL, 0xe6b215ffUL} },
+ { &fnv_test_str[145], (Fnv64_t) {0xc5531093UL, 0xec5b06a1UL} },
+ { &fnv_test_str[146], (Fnv64_t) {0x9f9ec5e5UL, 0x45665a92UL} },
+ { &fnv_test_str[147], (Fnv64_t) {0xa9f10907UL, 0x8c7609b4UL} },
+ { &fnv_test_str[148], (Fnv64_t) {0x91f0d729UL, 0x89aac3a4UL} },
+ { &fnv_test_str[149], (Fnv64_t) {0xe0f4a403UL, 0x32ce6b26UL} },
+ { &fnv_test_str[150], (Fnv64_t) {0x02b53e01UL, 0x614ab44eUL} },
+ { &fnv_test_str[151], (Fnv64_t) {0x6eef3290UL, 0xfa6472ebUL} },
+ { &fnv_test_str[152], (Fnv64_t) {0x1948eb6aUL, 0x9e5d75ebUL} },
+ { &fnv_test_str[153], (Fnv64_t) {0xa8671852UL, 0xb6d12ad4UL} },
+ { &fnv_test_str[154], (Fnv64_t) {0xeba07af1UL, 0x88826f56UL} },
+ { &fnv_test_str[155], (Fnv64_t) {0x645bc0fdUL, 0x44535bf2UL} },
+ { &fnv_test_str[156], (Fnv64_t) {0xc21e3728UL, 0x169388ffUL} },
+ { &fnv_test_str[157], (Fnv64_t) {0x396d8224UL, 0xf68aac9eUL} },
+ { &fnv_test_str[158], (Fnv64_t) {0x472b3883UL, 0x8e87d7e7UL} },
+ { &fnv_test_str[159], (Fnv64_t) {0xa8b423deUL, 0x295c26caUL} },
+ { &fnv_test_str[160], (Fnv64_t) {0x92e72176UL, 0x322c8142UL} },
+ { &fnv_test_str[161], (Fnv64_t) {0xb8af7268UL, 0x8a06550eUL} },
+ { &fnv_test_str[162], (Fnv64_t) {0x661bcf71UL, 0xef86d60eUL} },
+ { &fnv_test_str[163], (Fnv64_t) {0x7f30ee54UL, 0x9e5426c8UL} },
+ { &fnv_test_str[164], (Fnv64_t) {0x26fd047eUL, 0xf1ea8aa8UL} },
+ { &fnv_test_str[165], (Fnv64_t) {0x642cb769UL, 0x0babaf9aUL} },
+ { &fnv_test_str[166], (Fnv64_t) {0x068d012eUL, 0x4b3341d4UL} },
+ { &fnv_test_str[167], (Fnv64_t) {0xc30a335cUL, 0xd15605cbUL} },
+ { &fnv_test_str[168], (Fnv64_t) {0xed8412e5UL, 0x5b21060aUL} },
+ { &fnv_test_str[169], (Fnv64_t) {0xce6f4227UL, 0x45e2cda1UL} },
+ { &fnv_test_str[170], (Fnv64_t) {0x033ad7d4UL, 0x50ae3745UL} },
+ { &fnv_test_str[171], (Fnv64_t) {0xd46bf414UL, 0xaa4588ceUL} },
+ { &fnv_test_str[172], (Fnv64_t) {0x4a95467eUL, 0xc1b0056cUL} },
+ { &fnv_test_str[173], (Fnv64_t) {0xde8b4089UL, 0x56576a71UL} },
+ { &fnv_test_str[174], (Fnv64_t) {0xa6dc927eUL, 0xbf20965fUL} },
+ { &fnv_test_str[175], (Fnv64_t) {0xc2040882UL, 0x569f8383UL} },
+ { &fnv_test_str[176], (Fnv64_t) {0xa08feca0UL, 0xe1e772fbUL} },
+ { &fnv_test_str[177], (Fnv64_t) {0x97138ac4UL, 0x4ced94afUL} },
+ { &fnv_test_str[178], (Fnv64_t) {0x337a82fbUL, 0xc4112ffbUL} },
+ { &fnv_test_str[179], (Fnv64_t) {0x1de38b7dUL, 0xd64a4fd4UL} },
+ { &fnv_test_str[180], (Fnv64_t) {0x9edebcbbUL, 0x4cfc3232UL} },
+ { &fnv_test_str[181], (Fnv64_t) {0x45050395UL, 0x08035644UL} },
+ { &fnv_test_str[182], (Fnv64_t) {0xf4642ffdUL, 0xaa1574ecUL} },
+ { &fnv_test_str[183], (Fnv64_t) {0x4cc315f9UL, 0x694bc4e5UL} },
+ { &fnv_test_str[184], (Fnv64_t) {0x3b011721UL, 0xa3d7cb27UL} },
+ { &fnv_test_str[185], (Fnv64_t) {0x6115bfa5UL, 0x577c2f8bUL} },
+ { &fnv_test_str[186], (Fnv64_t) {0x769fb4c1UL, 0xb7ec8c1aUL} },
+ { &fnv_test_str[187], (Fnv64_t) {0x3359ab19UL, 0x5d5cfce6UL} },
+ { &fnv_test_str[188], (Fnv64_t) {0xd65b5f71UL, 0x33b96c3cUL} },
+ { &fnv_test_str[189], (Fnv64_t) {0x80602bb9UL, 0xd8450977UL} },
+ { &fnv_test_str[190], (Fnv64_t) {0xd02da3d5UL, 0x84d47645UL} },
+ { &fnv_test_str[191], (Fnv64_t) {0xb58773a5UL, 0x83544f33UL} },
+ { &fnv_test_str[192], (Fnv64_t) {0x160836c5UL, 0x9175cbb2UL} },
+ { &fnv_test_str[193], (Fnv64_t) {0x75e72bc5UL, 0xc71b3bc1UL} },
+ { &fnv_test_str[194], (Fnv64_t) {0x222ec985UL, 0x636806acUL} },
+ { &fnv_test_str[195], (Fnv64_t) {0x50f52ed5UL, 0xb6ef0e69UL} },
+ { &fnv_test_str[196], (Fnv64_t) {0xf3dfdaa5UL, 0xead3d8a0UL} },
+ { &fnv_test_str[197], (Fnv64_t) {0x9a861ba5UL, 0x922908feUL} },
+ { &fnv_test_str[198], (Fnv64_t) {0x275fd5c5UL, 0x6d4821deUL} },
+ { &fnv_test_str[199], (Fnv64_t) {0x2bd816b5UL, 0x1fe3fce6UL} },
+ { &fnv_test_str[200], (Fnv64_t) {0xd6f70591UL, 0xc23e9fccUL} },
+ { &fnv_test_str[201], (Fnv64_t) {0xfe16b5b5UL, 0xc1af12bdUL} },
+ { &fnv_test_str[202], (Fnv64_t) {0x2f85e221UL, 0x39e9f18fUL} },
+ { NULL, (Fnv64_t) {0,0} }
+};
+#endif /* HAVE_64BIT_LONG_LONG */
+
+/* end of output generated by make vector.c */
+/*
+ * insert the contents of vector.c above
+ */
+
+
+/*
+ * unknown_hash_type - report an unknown hash type error
+ *
+ * NOTE: Does not return.
+ */
+void
+unknown_hash_type(char *prog, enum fnv_type type, int code)
+{
+ fprintf(stderr, "%s: unknown or unexpexted hash type: %d\n", prog, type);
+ exit(code);
+}
+
+
+/*
+ * print_fnv32 - print an FNV hash
+ *
+ * given:
+ * hval the hash value to print
+ * mask lower bit mask
+ * verbose 1 => print arg with hash
+ * arg string or filename arg
+ */
+void
+print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg)
+{
+ if (verbose) {
+ printf("0x%08lx %s\n", hval & mask, arg);
+ } else {
+ printf("0x%08lx\n", hval & mask);
+ }
+}
+
+
+/*
+ * print_fnv64 - print an FNV hash
+ *
+ * given:
+ * hval the hash value to print
+ * mask lower bit mask
+ * verbose 1 => print arg with hash
+ * arg string or filename arg
+ */
+void
+print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg)
+{
+#if defined(HAVE_64BIT_LONG_LONG)
+ if (verbose) {
+ printf("0x%016llx %s\n", hval & mask, arg);
+ } else {
+ printf("0x%016llx\n", hval & mask);
+ }
+#else
+ if (verbose) {
+ printf("0x%08lx%08lx %s\n",
+ hval.w32[1] & mask.w32[1],
+ hval.w32[0] & mask.w32[0],
+ arg);
+ } else {
+ printf("0x%08lx%08lx\n",
+ hval.w32[1] & mask.w32[1],
+ hval.w32[0] & mask.w32[0]);
+ }
+#endif
+}
diff --git a/lib/lufa b/lib/lufa
-Subproject 19a5d533f02a7b46eeadca99cc9699659cef7a6
+Subproject 35cc3d92f557bc8874ca602d2f22642d77cfe12
diff --git a/lib/pico-sdk b/lib/pico-sdk
new file mode 160000
+Subproject 07edde8e49890d2172bbc272aacc119f999df06
diff --git a/lib/printf b/lib/printf
-Subproject d3b984684bb8a8bdc48cc7a1abecb93ce59bbe3
+Subproject c2e3b4e10d281e7f0f694d3ecbd9f320977288c
diff --git a/lib/python/qmk/c_parse.py b/lib/python/qmk/c_parse.py
index 4b49b8d4e9..c14eb490fa 100644
--- a/lib/python/qmk/c_parse.py
+++ b/lib/python/qmk/c_parse.py
@@ -258,6 +258,9 @@ def _parse_led_config(file, matrix_cols, matrix_rows):
position_raw.append(_coerce_led_token(_type, value))
if section == 3 and bracket_count == 2:
flags.append(_coerce_led_token(_type, value))
+ elif _type in [Token.Comment.Preproc]:
+ # TODO: Promote to error
+ return None
# Slightly better intrim format
matrix = list(_get_chunks(matrix_raw, matrix_cols))
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py
index 02c6d1cbf4..8a507677ef 100644
--- a/lib/python/qmk/cli/__init__.py
+++ b/lib/python/qmk/cli/__init__.py
@@ -59,6 +59,9 @@ subcommands = [
'qmk.cli.generate.rules_mk',
'qmk.cli.generate.version_h',
'qmk.cli.hello',
+ 'qmk.cli.import.kbfirmware',
+ 'qmk.cli.import.keyboard',
+ 'qmk.cli.import.keymap',
'qmk.cli.info',
'qmk.cli.json2c',
'qmk.cli.lint',
diff --git a/lib/python/qmk/cli/doctor/macos.py b/lib/python/qmk/cli/doctor/macos.py
index 00fb272858..5d088c9492 100644
--- a/lib/python/qmk/cli/doctor/macos.py
+++ b/lib/python/qmk/cli/doctor/macos.py
@@ -8,6 +8,6 @@ from .check import CheckStatus
def os_test_macos():
"""Run the Mac specific tests.
"""
- cli.log.info("Detected {fg_cyan}macOS %s{fg_reset}.", platform.mac_ver()[0])
+ cli.log.info("Detected {fg_cyan}macOS %s (%s){fg_reset}.", platform.mac_ver()[0], 'Apple Silicon' if platform.processor() == 'arm' else 'Intel')
return CheckStatus.OK
diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py
index 216896b974..ebe739c50e 100644
--- a/lib/python/qmk/cli/flash.py
+++ b/lib/python/qmk/cli/flash.py
@@ -33,6 +33,8 @@ def print_bootloader_help():
cli.echo('\tdfu-split-right')
cli.echo('\tdfu-util-split-left')
cli.echo('\tdfu-util-split-right')
+ cli.echo('\tuf2-split-left')
+ cli.echo('\tuf2-split-right')
cli.echo('For more info, visit https://docs.qmk.fm/#/flashing')
diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py
index 893892c479..a26dcdf7d7 100755
--- a/lib/python/qmk/cli/generate/config_h.py
+++ b/lib/python/qmk/cli/generate/config_h.py
@@ -134,6 +134,36 @@ def generate_config_items(kb_info_json, config_h_lines):
config_h_lines.append(f'#endif // {config_key}')
+def generate_encoder_config(encoder_json, config_h_lines, postfix=''):
+ """Generate the config.h lines for encoders."""
+ a_pads = []
+ b_pads = []
+ resolutions = []
+ for encoder in encoder_json.get("rotary", []):
+ a_pads.append(encoder["pin_a"])
+ b_pads.append(encoder["pin_b"])
+ resolutions.append(encoder.get("resolution", None))
+
+ config_h_lines.append(f'#ifndef ENCODERS_PAD_A{postfix}')
+ config_h_lines.append(f'# define ENCODERS_PAD_A{postfix} {{ { ", ".join(a_pads) } }}')
+ config_h_lines.append(f'#endif // ENCODERS_PAD_A{postfix}')
+
+ config_h_lines.append(f'#ifndef ENCODERS_PAD_B{postfix}')
+ config_h_lines.append(f'# define ENCODERS_PAD_B{postfix} {{ { ", ".join(b_pads) } }}')
+ config_h_lines.append(f'#endif // ENCODERS_PAD_B{postfix}')
+
+ if None in resolutions:
+ cli.log.debug("Unable to generate ENCODER_RESOLUTION configuration")
+ elif len(set(resolutions)) == 1:
+ config_h_lines.append(f'#ifndef ENCODER_RESOLUTION{postfix}')
+ config_h_lines.append(f'# define ENCODER_RESOLUTION{postfix} { resolutions[0] }')
+ config_h_lines.append(f'#endif // ENCODER_RESOLUTION{postfix}')
+ else:
+ config_h_lines.append(f'#ifndef ENCODER_RESOLUTIONS{postfix}')
+ config_h_lines.append(f'# define ENCODER_RESOLUTIONS{postfix} {{ { ", ".join(map(str,resolutions)) } }}')
+ config_h_lines.append(f'#endif // ENCODER_RESOLUTIONS{postfix}')
+
+
def generate_split_config(kb_info_json, config_h_lines):
"""Generate the config.h lines for split boards."""
if 'primary' in kb_info_json['split']:
@@ -173,6 +203,9 @@ def generate_split_config(kb_info_json, config_h_lines):
if 'right' in kb_info_json['split'].get('matrix_pins', {}):
config_h_lines.append(matrix_pins(kb_info_json['split']['matrix_pins']['right'], '_RIGHT'))
+ if 'right' in kb_info_json['split'].get('encoder', {}):
+ generate_encoder_config(kb_info_json['split']['encoder']['right'], config_h_lines, '_RIGHT')
+
@cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
@@ -198,6 +231,9 @@ def generate_config_h(cli):
if 'matrix_pins' in kb_info_json:
config_h_lines.append(matrix_pins(kb_info_json['matrix_pins']))
+ if 'encoder' in kb_info_json:
+ generate_encoder_config(kb_info_json['encoder'], config_h_lines)
+
if 'split' in kb_info_json:
generate_split_config(kb_info_json, config_h_lines)
diff --git a/lib/python/qmk/cli/generate/info_json.py b/lib/python/qmk/cli/generate/info_json.py
index 284d1a8510..0dc80f10cc 100755
--- a/lib/python/qmk/cli/generate/info_json.py
+++ b/lib/python/qmk/cli/generate/info_json.py
@@ -5,7 +5,7 @@ Compile an info.json for a particular keyboard and pretty-print it.
import json
from argcomplete.completers import FilesCompleter
-from jsonschema import Draft7Validator, RefResolver, validators
+from jsonschema import Draft202012Validator, RefResolver, validators
from milc import cli
from pathlib import Path
@@ -18,7 +18,7 @@ from qmk.path import is_keyboard, normpath
def pruning_validator(validator_class):
- """Extends Draft7Validator to remove properties that aren't specified in the schema.
+ """Extends Draft202012Validator to remove properties that aren't specified in the schema.
"""
validate_properties = validator_class.VALIDATORS["properties"]
@@ -37,10 +37,10 @@ def strip_info_json(kb_info_json):
"""Remove the API-only properties from the info.json.
"""
schema_store = compile_schema_store()
- pruning_draft_7_validator = pruning_validator(Draft7Validator)
+ pruning_draft_validator = pruning_validator(Draft202012Validator)
schema = schema_store['qmk.keyboard.v1']
resolver = RefResolver.from_schema(schema_store['qmk.keyboard.v1'], store=schema_store)
- validator = pruning_draft_7_validator(schema, resolver=resolver).validate
+ validator = pruning_draft_validator(schema, resolver=resolver).validate
return validator(kb_info_json)
diff --git a/lib/python/qmk/cli/import/__init__.py b/lib/python/qmk/cli/import/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/python/qmk/cli/import/__init__.py
diff --git a/lib/python/qmk/cli/import/kbfirmware.py b/lib/python/qmk/cli/import/kbfirmware.py
new file mode 100644
index 0000000000..9c03737378
--- /dev/null
+++ b/lib/python/qmk/cli/import/kbfirmware.py
@@ -0,0 +1,25 @@
+from milc import cli
+
+from qmk.importers import import_kbfirmware as _import_kbfirmware
+from qmk.path import FileType
+from qmk.json_schema import json_load
+
+
+@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file')
+@cli.subcommand('Import kbfirmware json export')
+def import_kbfirmware(cli):
+ filename = cli.args.filename[0]
+
+ data = json_load(filename)
+
+ cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}')
+ cli.echo('')
+
+ cli.log.warn("Support here is basic - Consider using 'qmk new-keyboard' instead")
+
+ kb_name = _import_kbfirmware(data)
+
+ cli.log.info(f'{{fg_green}}Imported a new keyboard named {{fg_cyan}}{kb_name}{{fg_green}}.{{fg_reset}}')
+ cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}{{fg_reset}},')
+ cli.log.info('or open the directory in your preferred text editor.')
+ cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km default{{fg_reset}}.")
diff --git a/lib/python/qmk/cli/import/keyboard.py b/lib/python/qmk/cli/import/keyboard.py
new file mode 100644
index 0000000000..3a5ed37dee
--- /dev/null
+++ b/lib/python/qmk/cli/import/keyboard.py
@@ -0,0 +1,23 @@
+from milc import cli
+
+from qmk.importers import import_keyboard as _import_keyboard
+from qmk.path import FileType
+from qmk.json_schema import json_load
+
+
+@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file')
+@cli.subcommand('Import data-driven keyboard')
+def import_keyboard(cli):
+ filename = cli.args.filename[0]
+
+ data = json_load(filename)
+
+ cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}')
+ cli.echo('')
+
+ kb_name = _import_keyboard(data)
+
+ cli.log.info(f'{{fg_green}}Imported a new keyboard named {{fg_cyan}}{kb_name}{{fg_green}}.{{fg_reset}}')
+ cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}{{fg_reset}},')
+ cli.log.info('or open the directory in your preferred text editor.')
+ cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km default{{fg_reset}}.")
diff --git a/lib/python/qmk/cli/import/keymap.py b/lib/python/qmk/cli/import/keymap.py
new file mode 100644
index 0000000000..a499c93480
--- /dev/null
+++ b/lib/python/qmk/cli/import/keymap.py
@@ -0,0 +1,23 @@
+from milc import cli
+
+from qmk.importers import import_keymap as _import_keymap
+from qmk.path import FileType
+from qmk.json_schema import json_load
+
+
+@cli.argument('filename', type=FileType('r'), nargs='+', arg_only=True, help='file')
+@cli.subcommand('Import data-driven keymap')
+def import_keymap(cli):
+ filename = cli.args.filename[0]
+
+ data = json_load(filename)
+
+ cli.log.info(f'{{style_bright}}Importing {filename.name}.{{style_normal}}')
+ cli.echo('')
+
+ kb_name, km_name = _import_keymap(data)
+
+ cli.log.info(f'{{fg_green}}Imported a new keymap named {{fg_cyan}}{km_name}{{fg_green}}.{{fg_reset}}')
+ cli.log.info(f'To start working on things, `cd` into {{fg_cyan}}keyboards/{kb_name}/keymaps/{km_name}{{fg_reset}},')
+ cli.log.info('or open the directory in your preferred text editor.')
+ cli.log.info(f"And build with {{fg_yellow}}qmk compile -kb {kb_name} -km {km_name}{{fg_reset}}.")
diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py
index a54d9058bc..95fe9a61d0 100644
--- a/lib/python/qmk/constants.py
+++ b/lib/python/qmk/constants.py
@@ -14,7 +14,7 @@ QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware'
MAX_KEYBOARD_SUBFOLDERS = 5
# Supported processor types
-CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95'
+CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95'
LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None
VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85'
diff --git a/lib/python/qmk/git.py b/lib/python/qmk/git.py
index f493628492..960184a0a2 100644
--- a/lib/python/qmk/git.py
+++ b/lib/python/qmk/git.py
@@ -111,9 +111,9 @@ def git_check_deviation(active_branch):
def git_get_ignored_files(check_dir='.'):
- """Return a list of files that would be captured by the current .gitingore
+ """Return a list of files that would be captured by the current .gitignore
"""
- invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-standard', check_dir])
+ invalid = cli.run(['git', 'ls-files', '-c', '-o', '-i', '--exclude-from=.gitignore', check_dir])
if invalid.returncode != 0:
return []
return invalid.stdout.strip().splitlines()
diff --git a/lib/python/qmk/importers.py b/lib/python/qmk/importers.py
new file mode 100644
index 0000000000..f9ecac02ae
--- /dev/null
+++ b/lib/python/qmk/importers.py
@@ -0,0 +1,148 @@
+from dotty_dict import dotty
+import json
+
+from qmk.json_schema import validate
+from qmk.path import keyboard, keymap
+from qmk.constants import MCU2BOOTLOADER
+from qmk.json_encoders import InfoJSONEncoder, KeymapJSONEncoder
+
+
+def _gen_dummy_keymap(name, info_data):
+ # Pick the first layout macro and just dump in KC_NOs or something?
+ (layout_name, layout_data), *_ = info_data["layouts"].items()
+ layout_length = len(layout_data["layout"])
+
+ keymap_data = {
+ "keyboard": name,
+ "layout": layout_name,
+ "layers": [["KC_NO" for _ in range(0, layout_length)]],
+ }
+
+ return json.dumps(keymap_data, cls=KeymapJSONEncoder)
+
+
+def import_keymap(keymap_data):
+ # Validate to ensure we don't have to deal with bad data - handles stdin/file
+ validate(keymap_data, 'qmk.keymap.v1')
+
+ kb_name = keymap_data['keyboard']
+ km_name = keymap_data['keymap']
+
+ km_folder = keymap(kb_name) / km_name
+ keyboard_keymap = km_folder / 'keymap.json'
+
+ # This is the deepest folder in the expected tree
+ keyboard_keymap.parent.mkdir(parents=True, exist_ok=True)
+
+ # Dump out all those lovely files
+ keyboard_keymap.write_text(json.dumps(keymap_data, cls=KeymapJSONEncoder))
+
+ return (kb_name, km_name)
+
+
+def import_keyboard(info_data):
+ # Validate to ensure we don't have to deal with bad data - handles stdin/file
+ validate(info_data, 'qmk.api.keyboard.v1')
+
+ # And validate some more as everything is optional
+ if not all(key in info_data for key in ['keyboard_name', 'layouts']):
+ raise ValueError('invalid info.json')
+
+ kb_name = info_data['keyboard_name']
+
+ # bail
+ kb_folder = keyboard(kb_name)
+ if kb_folder.exists():
+ raise ValueError(f'Keyboard {{fg_cyan}}{kb_name}{{fg_reset}} already exists! Please choose a different name.')
+
+ keyboard_info = kb_folder / 'info.json'
+ keyboard_rules = kb_folder / 'rules.mk'
+ keyboard_keymap = kb_folder / 'keymaps' / 'default' / 'keymap.json'
+
+ # This is the deepest folder in the expected tree
+ keyboard_keymap.parent.mkdir(parents=True, exist_ok=True)
+
+ # Dump out all those lovely files
+ keyboard_info.write_text(json.dumps(info_data, cls=InfoJSONEncoder))
+ keyboard_rules.write_text("# This file intentionally left blank")
+ keyboard_keymap.write_text(_gen_dummy_keymap(kb_name, info_data))
+
+ return kb_name
+
+
+def import_kbfirmware(kbfirmware_data):
+ kbf_data = dotty(kbfirmware_data)
+
+ diode_direction = ["COL2ROW", "ROW2COL"][kbf_data['keyboard.settings.diodeDirection']]
+ mcu = ["atmega32u2", "atmega32u4", "at90usb1286"][kbf_data['keyboard.controller']]
+ bootloader = MCU2BOOTLOADER.get(mcu, "custom")
+
+ layout = []
+ for key in kbf_data['keyboard.keys']:
+ layout.append({
+ "matrix": [key["row"], key["col"]],
+ "x": key["state"]["x"],
+ "y": key["state"]["y"],
+ "w": key["state"]["w"],
+ "h": key["state"]["h"],
+ })
+
+ # convert to d/d info.json
+ info_data = {
+ "keyboard_name": kbf_data['keyboard.settings.name'].lower(),
+ "manufacturer": "TODO",
+ "maintainer": "TODO",
+ "processor": mcu,
+ "bootloader": bootloader,
+ "diode_direction": diode_direction,
+ "matrix_pins": {
+ "cols": kbf_data['keyboard.pins.col'],
+ "rows": kbf_data['keyboard.pins.row'],
+ },
+ "usb": {
+ "vid": "0xFEED",
+ "pid": "0x0000",
+ "device_version": "0.0.1",
+ },
+ "features": {
+ "bootmagic": True,
+ "command": False,
+ "console": False,
+ "extrakey": True,
+ "mousekey": True,
+ "nkro": True,
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": layout,
+ }
+ }
+ }
+
+ if kbf_data['keyboard.pins.num'] or kbf_data['keyboard.pins.caps'] or kbf_data['keyboard.pins.scroll']:
+ indicators = {}
+ if kbf_data['keyboard.pins.num']:
+ indicators['num_lock'] = kbf_data['keyboard.pins.num']
+ if kbf_data['keyboard.pins.caps']:
+ indicators['caps_lock'] = kbf_data['keyboard.pins.caps']
+ if kbf_data['keyboard.pins.scroll']:
+ indicators['scroll_lock'] = kbf_data['keyboard.pins.scroll']
+ info_data['indicators'] = indicators
+
+ if kbf_data['keyboard.pins.rgb']:
+ info_data['rgblight'] = {
+ 'animations': {
+ 'all': True
+ },
+ 'led_count': kbf_data['keyboard.settings.rgbNum'],
+ 'pin': kbf_data['keyboard.pins.rgb'],
+ }
+
+ if kbf_data['keyboard.pins.led']:
+ info_data['backlight'] = {
+ 'levels': kbf_data['keyboard.settings.backlightLevels'],
+ 'pin': kbf_data['keyboard.pins.led'],
+ }
+
+ # delegate as if it were a regular keyboard import
+ return import_keyboard(info_data)
diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py
index 340969f415..72424f390e 100644
--- a/lib/python/qmk/info.py
+++ b/lib/python/qmk/info.py
@@ -218,6 +218,66 @@ def _extract_audio(info_data, config_c):
info_data['audio'] = {'pins': audio_pins}
+def _extract_encoders_values(config_c, postfix=''):
+ """Common encoder extraction logic
+ """
+ a_pad = config_c.get(f'ENCODERS_PAD_A{postfix}', '').replace(' ', '')[1:-1]
+ b_pad = config_c.get(f'ENCODERS_PAD_B{postfix}', '').replace(' ', '')[1:-1]
+ resolutions = config_c.get(f'ENCODER_RESOLUTIONS{postfix}', '').replace(' ', '')[1:-1]
+
+ default_resolution = config_c.get('ENCODER_RESOLUTION', None)
+
+ if a_pad and b_pad:
+ a_pad = list(filter(None, a_pad.split(',')))
+ b_pad = list(filter(None, b_pad.split(',')))
+ resolutions = list(filter(None, resolutions.split(',')))
+ if default_resolution:
+ resolutions += [default_resolution] * (len(a_pad) - len(resolutions))
+
+ encoders = []
+ for index in range(len(a_pad)):
+ encoder = {'pin_a': a_pad[index], 'pin_b': b_pad[index]}
+ if index < len(resolutions):
+ encoder['resolution'] = int(resolutions[index])
+ encoders.append(encoder)
+
+ return encoders
+
+
+def _extract_encoders(info_data, config_c):
+ """Populate data about encoder pins
+ """
+ encoders = _extract_encoders_values(config_c)
+ if encoders:
+ if 'encoder' not in info_data:
+ info_data['encoder'] = {}
+
+ if 'rotary' in info_data['encoder']:
+ _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['encoder']['rotary'])
+
+ info_data['encoder']['rotary'] = encoders
+
+
+def _extract_split_encoders(info_data, config_c):
+ """Populate data about split encoder pins
+ """
+ encoders = _extract_encoders_values(config_c, '_RIGHT')
+ if encoders:
+ if 'split' not in info_data:
+ info_data['split'] = {}
+
+ if 'encoder' not in info_data['split']:
+ info_data['split']['encoder'] = {}
+
+ if 'right' not in info_data['split']['encoder']:
+ info_data['split']['encoder']['right'] = {}
+
+ if 'rotary' in info_data['split']['encoder']['right']:
+ _log_warning(info_data, 'Encoder config is specified in both config.h and info.json (encoder.rotary) (Value: %s), the config.h value wins.' % info_data['split']['encoder']['right']['rotary'])
+
+ info_data['split']['encoder']['right']['rotary'] = encoders
+
+
def _extract_secure_unlock(info_data, config_c):
"""Populate data about the secure unlock sequence
"""
@@ -486,6 +546,8 @@ def _extract_config_h(info_data, config_c):
_extract_split_main(info_data, config_c)
_extract_split_transport(info_data, config_c)
_extract_split_right_pins(info_data, config_c)
+ _extract_encoders(info_data, config_c)
+ _extract_split_encoders(info_data, config_c)
_extract_device_version(info_data)
return info_data
diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py
index 682346113e..01175146b5 100644
--- a/lib/python/qmk/json_schema.py
+++ b/lib/python/qmk/json_schema.py
@@ -68,11 +68,7 @@ def create_validator(schema):
schema_store = compile_schema_store()
resolver = jsonschema.RefResolver.from_schema(schema_store[schema], store=schema_store)
- # TODO: Remove this after the jsonschema>=4 requirement had time to reach users
- try:
- return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate
- except AttributeError:
- return jsonschema.Draft7Validator(schema_store[schema], resolver=resolver).validate
+ return jsonschema.Draft202012Validator(schema_store[schema], resolver=resolver).validate
def validate(data, schema):
diff --git a/lib/vusb b/lib/vusb
-Subproject bdb53e4c043d089279d9891b68bea77614cb97e
+Subproject 819dbc1e5d5926b17e27e00ca6d3d2988adae04
diff --git a/platforms/arm_atsam/platform.mk b/platforms/arm_atsam/platform.mk
index b49bf764d7..9462f517ae 100644
--- a/platforms/arm_atsam/platform.mk
+++ b/platforms/arm_atsam/platform.mk
@@ -24,13 +24,14 @@ COMPILEFLAGS += -fno-strict-aliasing
COMPILEFLAGS += -mfloat-abi=hard
COMPILEFLAGS += -mfpu=fpv4-sp-d16
COMPILEFLAGS += -mthumb
+COMPILEFLAGS += -fno-builtin-printf
#ALLOW_WARNINGS = yes
CFLAGS += $(COMPILEFLAGS)
CXXFLAGS += $(COMPILEFLAGS)
-CXXFLAGS += -fno-exceptions -std=c++11
+CXXFLAGS += -fno-exceptions $(CXXSTANDARD)
LDFLAGS +=-Wl,--gc-sections
LDFLAGS += -Wl,-Map="%OUT%%PROJ_NAME%.map"
diff --git a/platforms/avr/drivers/i2c_master.c b/platforms/avr/drivers/i2c_master.c
index c1a7b5f72d..524494c99d 100644
--- a/platforms/avr/drivers/i2c_master.c
+++ b/platforms/avr/drivers/i2c_master.c
@@ -64,7 +64,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
uint16_t timeout_timer = timer_read();
while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
return I2C_STATUS_TIMEOUT;
}
}
@@ -81,7 +81,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
timeout_timer = timer_read();
while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
return I2C_STATUS_TIMEOUT;
}
}
@@ -102,7 +102,7 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
i2c_status_t status;
do {
status = i2c_start_impl(address, time_slice);
- } while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) < timeout)));
+ } while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) <= timeout)));
return status;
}
@@ -114,7 +114,7 @@ i2c_status_t i2c_write(uint8_t data, uint16_t timeout) {
uint16_t timeout_timer = timer_read();
while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
return I2C_STATUS_TIMEOUT;
}
}
@@ -132,7 +132,7 @@ int16_t i2c_read_ack(uint16_t timeout) {
uint16_t timeout_timer = timer_read();
while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
return I2C_STATUS_TIMEOUT;
}
}
@@ -147,7 +147,7 @@ int16_t i2c_read_nack(uint16_t timeout) {
uint16_t timeout_timer = timer_read();
while (!(TWCR & (1 << TWINT))) {
- if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
return I2C_STATUS_TIMEOUT;
}
}
diff --git a/platforms/avr/drivers/i2c_master.h b/platforms/avr/drivers/i2c_master.h
index 2d95846db5..04ef126c80 100644
--- a/platforms/avr/drivers/i2c_master.h
+++ b/platforms/avr/drivers/i2c_master.h
@@ -19,6 +19,8 @@
#pragma once
+#include <stdint.h>
+
#define I2C_READ 0x01
#define I2C_WRITE 0x00
diff --git a/platforms/avr/drivers/ps2/ps2_usart.c b/platforms/avr/drivers/ps2/ps2_usart.c
index 39ec930d4a..581badac64 100644
--- a/platforms/avr/drivers/ps2/ps2_usart.c
+++ b/platforms/avr/drivers/ps2/ps2_usart.c
@@ -72,8 +72,8 @@ uint8_t ps2_error = PS2_ERR_NONE;
static inline uint8_t pbuf_dequeue(void);
static inline void pbuf_enqueue(uint8_t data);
-static inline bool pbuf_has_data(void);
static inline void pbuf_clear(void);
+bool pbuf_has_data(void);
void ps2_host_init(void) {
idle(); // without this many USART errors occur when cable is disconnected
@@ -212,7 +212,7 @@ static inline uint8_t pbuf_dequeue(void) {
return val;
}
-static inline bool pbuf_has_data(void) {
+bool pbuf_has_data(void) {
uint8_t sreg = SREG;
cli();
bool has_data = (pbuf_head != pbuf_tail);
diff --git a/platforms/avr/platform.mk b/platforms/avr/platform.mk
index 978199b385..39a11b28e4 100644
--- a/platforms/avr/platform.mk
+++ b/platforms/avr/platform.mk
@@ -24,6 +24,7 @@ COMPILEFLAGS += -fdata-sections
COMPILEFLAGS += -fpack-struct
COMPILEFLAGS += -fshort-enums
COMPILEFLAGS += -mcall-prologues
+COMPILEFLAGS += -fno-builtin-printf
# Linker relaxation is only possible if
# link time optimizations are not enabled.
@@ -38,7 +39,7 @@ CFLAGS += -fno-inline-small-functions
CFLAGS += -fno-strict-aliasing
CXXFLAGS += $(COMPILEFLAGS)
-CXXFLAGS += -fno-exceptions -std=c++11
+CXXFLAGS += -fno-exceptions $(CXXSTANDARD)
LDFLAGS += -Wl,--gc-sections
diff --git a/platforms/chibios/_pin_defs.h b/platforms/chibios/_pin_defs.h
index 0d96e2fc3b..414c9e3d11 100644
--- a/platforms/chibios/_pin_defs.h
+++ b/platforms/chibios/_pin_defs.h
@@ -21,6 +21,11 @@
# include <hal.h>
#endif
+/* Include the vendor specific pin defs */
+#if __has_include_next("_pin_defs.h")
+# include_next "_pin_defs.h"
+#endif
+
#define A0 PAL_LINE(GPIOA, 0)
#define A1 PAL_LINE(GPIOA, 1)
#define A2 PAL_LINE(GPIOA, 2)
diff --git a/platforms/chibios/_wait.h b/platforms/chibios/_wait.h
index 2f36c64a2e..c0ccbc5569 100644
--- a/platforms/chibios/_wait.h
+++ b/platforms/chibios/_wait.h
@@ -17,6 +17,7 @@
#include <ch.h>
#include <hal.h>
+#include "chibios_config.h"
/* chThdSleepX of zero maps to infinite - so we map to a tiny delay to still yield */
#define wait_ms(ms) \
@@ -30,6 +31,11 @@
#ifdef WAIT_US_TIMER
void wait_us(uint16_t duration);
+#elif PORT_SUPPORTS_RT == TRUE
+# define wait_us(us) \
+ do { \
+ chSysPolledDelayX(US2RTC(REALTIME_COUNTER_CLOCK, us)); \
+ } while (0)
#else
# define wait_us(us) \
do { \
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/board/board.mk b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/board/board.mk
new file mode 100644
index 0000000000..911cc5a058
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/board/board.mk
@@ -0,0 +1,9 @@
+# List of all the board related files.
+BOARDSRC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.c
+
+# Required include directories
+BOARDINC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040
+
+# Shared variables
+ALLCSRC += $(BOARDSRC)
+ALLINC += $(BOARDINC)
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/board.h b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/board.h
new file mode 100644
index 0000000000..b4363595d0
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/board.h
@@ -0,0 +1,12 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include_next "board.h"
+
+#undef BOARD_RP_PICO_RP2040
+#define BOARD_GENERIC_PROMICRO_RP2040
+
+#undef BOARD_NAME
+#define BOARD_NAME "Pro Micro RP2040"
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/chconf.h b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/chconf.h
new file mode 100644
index 0000000000..d53f57edd9
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/chconf.h
@@ -0,0 +1,13 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define CH_CFG_SMP_MODE TRUE
+#define CH_CFG_ST_RESOLUTION 32
+#define CH_CFG_ST_FREQUENCY 1000000
+#define CH_CFG_INTERVALS_SIZE 32
+#define CH_CFG_TIME_TYPES_SIZE 32
+#define CH_CFG_ST_TIMEDELTA 20
+
+#include_next <chconf.h>
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/config.h b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/config.h
new file mode 100644
index 0000000000..7fe9b654e1
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/config.h
@@ -0,0 +1,62 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+/**======================
+ ** I2C Driver
+ *========================**/
+
+#if !defined(I2C_DRIVER)
+# define I2C_DRIVER I2CD2
+#endif
+
+#if !defined(I2C1_SDA_PIN)
+# define I2C1_SDA_PIN GP2
+#endif
+
+#if !defined(I2C1_SCL_PIN)
+# define I2C1_SCL_PIN GP3
+#endif
+
+/**======================
+ ** SPI Driver
+ *========================**/
+
+#if !defined(SPI_DRIVER)
+# define SPI_DRIVER SPID0
+#endif
+
+#if !defined(SPI_SCK_PIN)
+# define SPI_SCK_PIN GP18
+#endif
+
+#if !defined(SPI_MISO_PIN)
+# define SPI_MISO_PIN GP20
+#endif
+
+#if !defined(SPI_MOSI_PIN)
+# define SPI_MOSI_PIN GP19
+#endif
+
+/**======================
+ ** SERIAL Driver
+ *========================**/
+
+#if !defined(SERIAL_USART_DRIVER)
+# define SERIAL_USART_DRIVER SIOD0
+#endif
+
+#if !defined(SERIAL_USART_TX_PIN) && !defined(SOFT_SERIAL_PIN)
+# define SERIAL_USART_TX_PIN GP0
+#endif
+
+#if !defined(SERIAL_USART_RX_PIN)
+# define SERIAL_USART_RX_PIN GP1
+#endif
+
+/**======================
+ ** Double-tap
+ *========================**/
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h
new file mode 100644
index 0000000000..8348e5312f
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h
@@ -0,0 +1,98 @@
+/*
+ ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef MCUCONF_H
+#define MCUCONF_H
+
+/*
+ * RP2040_MCUCONF drivers configuration.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...1 Lowest...Highest.
+ */
+
+#define RP2040_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+#define RP_NO_INIT FALSE
+#define RP_CORE1_START FALSE
+#define RP_CORE1_VECTORS_TABLE _vectors
+#define RP_CORE1_ENTRY_POINT _crt0_c1_entry
+#define RP_CORE1_STACK_END __c1_main_stack_end__
+
+/*
+ * IRQ system settings.
+ */
+#define RP_IRQ_SYSTICK_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM0_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM1_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM2_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM3_PRIORITY 2
+#define RP_IRQ_UART0_PRIORITY 3
+#define RP_IRQ_UART1_PRIORITY 3
+#define RP_IRQ_SPI0_PRIORITY 2
+#define RP_IRQ_SPI1_PRIORITY 2
+#define RP_IRQ_USB0_PRIORITY 3
+#define RP_IRQ_I2C0_PRIORITY 2
+#define RP_IRQ_I2C1_PRIORITY 2
+
+/*
+ * ADC driver system settings.
+ */
+#define RP_ADC_USE_ADC1 FALSE
+
+/*
+ * SIO driver system settings.
+ */
+#define RP_SIO_USE_UART0 TRUE
+#define RP_SIO_USE_UART1 FALSE
+
+/*
+ * SPI driver system settings.
+ */
+#define RP_SPI_USE_SPI0 TRUE
+#define RP_SPI_USE_SPI1 FALSE
+#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_DMA_PRIORITY 1
+#define RP_SPI_SPI1_DMA_PRIORITY 1
+#define RP_SPI_DMA_ERROR_HOOK(spip)
+
+/*
+ * I2C driver system settings.
+ */
+#define RP_I2C_USE_I2C0 FALSE
+#define RP_I2C_USE_I2C1 TRUE
+#define RP_I2C_BUSY_TIMEOUT 50
+#define RP_I2C_ADDRESS_MODE_10BIT FALSE
+
+/*
+ * USB driver system settings.
+ */
+#define RP_USB_USE_USBD0 TRUE
+#define RP_USB_FORCE_VBUS_DETECT TRUE
+#define RP_USE_EXTERNAL_VBUS_DETECT FALSE
+#define RP_USB_USE_SOF_INTR TRUE
+#define RP_USB_USE_ERROR_DATA_SEQ_INTR FALSE
+
+#endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/GENERIC_RP_RP2040/board/board.mk b/platforms/chibios/boards/GENERIC_RP_RP2040/board/board.mk
new file mode 100644
index 0000000000..911cc5a058
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_RP_RP2040/board/board.mk
@@ -0,0 +1,9 @@
+# List of all the board related files.
+BOARDSRC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.c
+
+# Required include directories
+BOARDINC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040
+
+# Shared variables
+ALLCSRC += $(BOARDSRC)
+ALLINC += $(BOARDINC)
diff --git a/platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h
new file mode 100644
index 0000000000..052050c944
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/board.h
@@ -0,0 +1,12 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include_next "board.h"
+
+#undef BOARD_RP_PICO_RP2040
+#define BOARD_GENERIC_RP2040
+
+#undef BOARD_NAME
+#define BOARD_NAME "Generic Raspberry Pi RP2040"
diff --git a/platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h
new file mode 100644
index 0000000000..d53f57edd9
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/chconf.h
@@ -0,0 +1,13 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define CH_CFG_SMP_MODE TRUE
+#define CH_CFG_ST_RESOLUTION 32
+#define CH_CFG_ST_FREQUENCY 1000000
+#define CH_CFG_INTERVALS_SIZE 32
+#define CH_CFG_TIME_TYPES_SIZE 32
+#define CH_CFG_ST_TIMEDELTA 20
+
+#include_next <chconf.h>
diff --git a/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
new file mode 100644
index 0000000000..9d8dc61aac
--- /dev/null
+++ b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
@@ -0,0 +1,98 @@
+/*
+ ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef MCUCONF_H
+#define MCUCONF_H
+
+/*
+ * RP2040_MCUCONF drivers configuration.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...1 Lowest...Highest.
+ */
+
+#define RP2040_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+#define RP_NO_INIT FALSE
+#define RP_CORE1_START FALSE
+#define RP_CORE1_VECTORS_TABLE _vectors
+#define RP_CORE1_ENTRY_POINT _crt0_c1_entry
+#define RP_CORE1_STACK_END __c1_main_stack_end__
+
+/*
+ * IRQ system settings.
+ */
+#define RP_IRQ_SYSTICK_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM0_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM1_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM2_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM3_PRIORITY 2
+#define RP_IRQ_UART0_PRIORITY 3
+#define RP_IRQ_UART1_PRIORITY 3
+#define RP_IRQ_SPI0_PRIORITY 2
+#define RP_IRQ_SPI1_PRIORITY 2
+#define RP_IRQ_USB0_PRIORITY 3
+#define RP_IRQ_I2C0_PRIORITY 2
+#define RP_IRQ_I2C1_PRIORITY 2
+
+/*
+ * ADC driver system settings.
+ */
+#define RP_ADC_USE_ADC1 FALSE
+
+/*
+ * SIO driver system settings.
+ */
+#define RP_SIO_USE_UART0 FALSE
+#define RP_SIO_USE_UART1 FALSE
+
+/*
+ * SPI driver system settings.
+ */
+#define RP_SPI_USE_SPI0 FALSE
+#define RP_SPI_USE_SPI1 FALSE
+#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_DMA_PRIORITY 1
+#define RP_SPI_SPI1_DMA_PRIORITY 1
+#define RP_SPI_DMA_ERROR_HOOK(spip)
+
+/*
+ * I2C driver system settings.
+ */
+#define RP_I2C_USE_I2C0 FALSE
+#define RP_I2C_USE_I2C1 FALSE
+#define RP_I2C_BUSY_TIMEOUT 50
+#define RP_I2C_ADDRESS_MODE_10BIT FALSE
+
+/*
+ * USB driver system settings.
+ */
+#define RP_USB_USE_USBD0 TRUE
+#define RP_USB_FORCE_VBUS_DETECT TRUE
+#define RP_USE_EXTERNAL_VBUS_DETECT FALSE
+#define RP_USB_USE_SOF_INTR TRUE
+#define RP_USB_USE_ERROR_DATA_SEQ_INTR FALSE
+
+#endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/QMK_PM2040/board/board.mk b/platforms/chibios/boards/QMK_PM2040/board/board.mk
new file mode 100644
index 0000000000..911cc5a058
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/board/board.mk
@@ -0,0 +1,9 @@
+# List of all the board related files.
+BOARDSRC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040/board.c
+
+# Required include directories
+BOARDINC = $(CHIBIOS)/os/hal/boards/RP_PICO_RP2040
+
+# Shared variables
+ALLCSRC += $(BOARDSRC)
+ALLINC += $(BOARDINC)
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/board.h b/platforms/chibios/boards/QMK_PM2040/configs/board.h
new file mode 100644
index 0000000000..433e1c527f
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/configs/board.h
@@ -0,0 +1,12 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include_next "board.h"
+
+#undef BOARD_RP_PICO_RP2040
+#define BOARD_PM2040
+
+#undef BOARD_NAME
+#define BOARD_NAME "Pro Micro RP2040"
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/chconf.h b/platforms/chibios/boards/QMK_PM2040/configs/chconf.h
new file mode 100644
index 0000000000..d53f57edd9
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/configs/chconf.h
@@ -0,0 +1,13 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define CH_CFG_SMP_MODE TRUE
+#define CH_CFG_ST_RESOLUTION 32
+#define CH_CFG_ST_FREQUENCY 1000000
+#define CH_CFG_INTERVALS_SIZE 32
+#define CH_CFG_TIME_TYPES_SIZE 32
+#define CH_CFG_ST_TIMEDELTA 20
+
+#include_next <chconf.h>
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/config.h b/platforms/chibios/boards/QMK_PM2040/configs/config.h
new file mode 100644
index 0000000000..9dfe86f12e
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/configs/config.h
@@ -0,0 +1,21 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#ifndef I2C_DRIVER
+# define I2C_DRIVER I2CD2
+#endif
+#ifndef I2C1_SDA_PIN
+# define I2C1_SDA_PIN 2U
+#endif
+#ifndef I2C1_SCL_PIN
+# define I2C1_SCL_PIN 3U
+#endif
+
+#ifndef RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#endif
+#ifndef RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
+#endif
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/halconf.h b/platforms/chibios/boards/QMK_PM2040/configs/halconf.h
new file mode 100644
index 0000000000..d7a58f0ea6
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/configs/halconf.h
@@ -0,0 +1,9 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define HAL_USE_I2C TRUE
+#define HAL_USE_SPI TRUE
+
+#include_next <halconf.h>
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h b/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h
new file mode 100644
index 0000000000..a737b36c1c
--- /dev/null
+++ b/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h
@@ -0,0 +1,98 @@
+/*
+ ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef MCUCONF_H
+#define MCUCONF_H
+
+/*
+ * RP2040_MCUCONF drivers configuration.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...1 Lowest...Highest.
+ */
+
+#define RP2040_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+#define RP_NO_INIT FALSE
+#define RP_CORE1_START FALSE
+#define RP_CORE1_VECTORS_TABLE _vectors
+#define RP_CORE1_ENTRY_POINT _crt0_c1_entry
+#define RP_CORE1_STACK_END __c1_main_stack_end__
+
+/*
+ * IRQ system settings.
+ */
+#define RP_IRQ_SYSTICK_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM0_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM1_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM2_PRIORITY 2
+#define RP_IRQ_TIMER_ALARM3_PRIORITY 2
+#define RP_IRQ_UART0_PRIORITY 3
+#define RP_IRQ_UART1_PRIORITY 3
+#define RP_IRQ_SPI0_PRIORITY 2
+#define RP_IRQ_SPI1_PRIORITY 2
+#define RP_IRQ_USB0_PRIORITY 3
+#define RP_IRQ_I2C0_PRIORITY 2
+#define RP_IRQ_I2C1_PRIORITY 2
+
+/*
+ * ADC driver system settings.
+ */
+#define RP_ADC_USE_ADC1 FALSE
+
+/*
+ * SIO driver system settings.
+ */
+#define RP_SIO_USE_UART0 FALSE
+#define RP_SIO_USE_UART1 FALSE
+
+/*
+ * SPI driver system settings.
+ */
+#define RP_SPI_USE_SPI0 TRUE
+#define RP_SPI_USE_SPI1 FALSE
+#define RP_SPI_SPI0_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_RX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI1_TX_DMA_CHANNEL RP_DMA_CHANNEL_ID_ANY
+#define RP_SPI_SPI0_DMA_PRIORITY 1
+#define RP_SPI_SPI1_DMA_PRIORITY 1
+#define RP_SPI_DMA_ERROR_HOOK(spip)
+
+/*
+ * I2C driver system settings.
+ */
+#define RP_I2C_USE_I2C0 FALSE
+#define RP_I2C_USE_I2C1 TRUE
+#define RP_I2C_BUSY_TIMEOUT 50
+#define RP_I2C_ADDRESS_MODE_10BIT FALSE
+
+/*
+ * USB driver system settings.
+ */
+#define RP_USB_USE_USBD0 TRUE
+#define RP_USB_FORCE_VBUS_DETECT TRUE
+#define RP_USE_EXTERNAL_VBUS_DETECT FALSE
+#define RP_USB_USE_SOF_INTR TRUE
+#define RP_USB_USE_ERROR_DATA_SEQ_INTR FALSE
+
+#endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/common/ld/RP2040_FLASH_TIMECRIT.ld b/platforms/chibios/boards/common/ld/RP2040_FLASH_TIMECRIT.ld
new file mode 100644
index 0000000000..66ed4ce086
--- /dev/null
+++ b/platforms/chibios/boards/common/ld/RP2040_FLASH_TIMECRIT.ld
@@ -0,0 +1,117 @@
+/*
+ ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/*
+ * RP2040 memory setup.
+ */
+MEMORY
+{
+ flash0 (rx) : org = 0x00000000, len = 16k /* ROM */
+ flash1 (rx) : org = 0x10000000, len = DEFINED(FLASH_LEN) ? FLASH_LEN : 2048k /* XIP */
+ flash2 (rx) : org = 0x00000000, len = 0
+ flash3 (rx) : org = 0x00000000, len = 0
+ flash4 (rx) : org = 0x00000000, len = 0
+ flash5 (rx) : org = 0x00000000, len = 0
+ flash6 (rx) : org = 0x00000000, len = 0
+ flash7 (rx) : org = 0x00000000, len = 0
+ ram0 (wx) : org = 0x20000000, len = 256k /* SRAM0 striped */
+ ram1 (wx) : org = 0x00000000, len = 256k /* SRAM0 non striped */
+ ram2 (wx) : org = 0x00000000, len = 0
+ ram3 (wx) : org = 0x00000000, len = 0
+ ram4 (wx) : org = 0x20040000, len = 4k /* SRAM4 */
+ ram5 (wx) : org = 0x20041000, len = 4k /* SRAM5 */
+ ram6 (wx) : org = 0x00000000, len = 0
+ ram7 (wx) : org = 0x20041f00, len = 256 /* SRAM5 boot */
+}
+
+/* For each data/text section two region are defined, a virtual region
+ and a load region (_LMA suffix).*/
+
+/* Flash region to be used for exception vectors.*/
+REGION_ALIAS("VECTORS_FLASH", flash1);
+REGION_ALIAS("VECTORS_FLASH_LMA", flash1);
+
+/* Flash region to be used for constructors and destructors.*/
+REGION_ALIAS("XTORS_FLASH", flash1);
+REGION_ALIAS("XTORS_FLASH_LMA", flash1);
+
+/* Flash region to be used for code text.*/
+REGION_ALIAS("TEXT_FLASH", flash1);
+REGION_ALIAS("TEXT_FLASH_LMA", flash1);
+
+/* Flash region to be used for read only data.*/
+REGION_ALIAS("RODATA_FLASH", flash1);
+REGION_ALIAS("RODATA_FLASH_LMA", flash1);
+
+/* Flash region to be used for various.*/
+REGION_ALIAS("VARIOUS_FLASH", flash1);
+REGION_ALIAS("VARIOUS_FLASH_LMA", flash1);
+
+/* Flash region to be used for RAM(n) initialization data.*/
+REGION_ALIAS("RAM_INIT_FLASH_LMA", flash1);
+
+/* RAM region to be used for Main stack. This stack accommodates the processing
+ of all exceptions and interrupts.*/
+REGION_ALIAS("MAIN_STACK_RAM", ram4);
+
+/* RAM region to be used for the process stack. This is the stack used by
+ the main() function.*/
+REGION_ALIAS("PROCESS_STACK_RAM", ram4);
+
+/* RAM region to be used for Main stack. This stack accommodates the processing
+ of all exceptions and interrupts.*/
+REGION_ALIAS("C1_MAIN_STACK_RAM", ram5);
+
+/* RAM region to be used for the process stack. This is the stack used by
+ the main() function.*/
+REGION_ALIAS("C1_PROCESS_STACK_RAM", ram5);
+
+/* RAM region to be used for data segment.*/
+REGION_ALIAS("DATA_RAM", ram0);
+REGION_ALIAS("DATA_RAM_LMA", flash1);
+
+/* RAM region to be used for BSS segment.*/
+REGION_ALIAS("BSS_RAM", ram0);
+
+/* RAM region to be used for the default heap.*/
+REGION_ALIAS("HEAP_RAM", ram0);
+
+SECTIONS
+{
+ .flash_begin : {
+ __flash_binary_start = .;
+ } > flash1
+
+ .boot2 : {
+ __boot2_start__ = .;
+ KEEP (*(.boot2))
+ __boot2_end__ = .;
+ } > flash1
+}
+
+/* Generic rules inclusion.*/
+INCLUDE rules_stacks.ld
+INCLUDE rules_stacks_c1.ld
+INCLUDE RP2040_rules_code_with_boot2.ld
+INCLUDE RP2040_rules_data_with_timecrit.ld
+INCLUDE rules_memory.ld
+
+SECTIONS
+{
+ .flash_end : {
+ __flash_binary_end = .;
+ } > flash1
+}
diff --git a/platforms/chibios/boards/common/ld/RP2040_rules_data_with_timecrit.ld b/platforms/chibios/boards/common/ld/RP2040_rules_data_with_timecrit.ld
new file mode 100644
index 0000000000..a9a47be983
--- /dev/null
+++ b/platforms/chibios/boards/common/ld/RP2040_rules_data_with_timecrit.ld
@@ -0,0 +1,46 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+SECTIONS
+{
+ .data : ALIGN(4)
+ {
+ PROVIDE(_textdata = LOADADDR(.data));
+ PROVIDE(_data = .);
+ __textdata_base__ = LOADADDR(.data);
+ __data_base__ = .;
+ *(vtable)
+ *(.time_critical*)
+ . = ALIGN(4);
+ *(.data)
+ *(.data.*)
+ *(.ramtext)
+ . = ALIGN(4);
+ PROVIDE(_edata = .);
+ __data_end__ = .;
+ } > DATA_RAM AT > DATA_RAM_LMA
+
+ .bss (NOLOAD) : ALIGN(4)
+ {
+ __bss_base__ = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ PROVIDE(end = .);
+ } > BSS_RAM
+}
diff --git a/platforms/chibios/bootloaders/rp2040.c b/platforms/chibios/bootloaders/rp2040.c
new file mode 100644
index 0000000000..bedc00f32e
--- /dev/null
+++ b/platforms/chibios/bootloaders/rp2040.c
@@ -0,0 +1,56 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+#include "hal.h"
+#include "bootloader.h"
+#include "pico/bootrom.h"
+
+#if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK 0U
+#else
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK (1U << RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
+#endif
+
+__attribute__((weak)) void mcu_reset(void) {
+ NVIC_SystemReset();
+}
+void bootloader_jump(void) {
+ reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
+}
+
+void enter_bootloader_mode_if_requested(void) {}
+
+#if defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET)
+# if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT)
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U
+# endif
+
+// Needs to be located in a RAM section that is never initialized on boot to
+// preserve its value on reset
+static volatile uint32_t __attribute__((section(".ram0.bootloader_magic"))) magic_location;
+const uint32_t magic_token = 0xCAFEB0BA;
+
+// We can not use the __early_init / enter_bootloader_mode_if_requested hook as
+// we depend on an already initialized system with usable memory regions and
+// populated function pointer tables to the optimized math functions in the
+// bootrom. This function is called just prior to main.
+void __late_init(void) {
+ // All clocks have to be enabled before jumping to the bootloader function,
+ // otherwise the bootrom will be stuck infinitely.
+ clocks_init();
+
+ if (magic_location != magic_token) {
+ magic_location = magic_token;
+ // ChibiOS is not initialized at this point, so sleeping is only
+ // possible via busy waiting.
+ wait_us(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT * 1000U);
+ magic_location = 0;
+ return;
+ }
+
+ magic_location = 0;
+ reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
+}
+
+#endif
diff --git a/platforms/chibios/bootloaders/stm32_dfu.c b/platforms/chibios/bootloaders/stm32_dfu.c
index ff866bd2bc..7b4ab86033 100644
--- a/platforms/chibios/bootloaders/stm32_dfu.c
+++ b/platforms/chibios/bootloaders/stm32_dfu.c
@@ -38,7 +38,7 @@ extern uint32_t __ram0_end__;
# endif
# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY
-# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000
+# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100
# endif
__attribute__((weak)) void bootloader_jump(void) {
@@ -55,7 +55,7 @@ __attribute__((weak)) void bootloader_jump(void) {
# endif
// Wait for a while for the capacitor to charge
- wait_ms(100);
+ wait_ms(STM32_BOOTLOADER_DUAL_BANK_DELAY);
// Issue a system reset to get the ROM bootloader to execute, with BOOT0 high
NVIC_SystemReset();
diff --git a/platforms/chibios/chibios_config.h b/platforms/chibios/chibios_config.h
index a7098f2713..8dcc23727f 100644
--- a/platforms/chibios/chibios_config.h
+++ b/platforms/chibios/chibios_config.h
@@ -19,6 +19,30 @@
# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used
#endif
+#if defined(MCU_RP)
+# define CPU_CLOCK RP_CORE_CLK
+// ChibiOS uses the RP2040 timer peripheral as its real time counter, this timer
+// is monotonic and running at 1MHz.
+# define REALTIME_COUNTER_CLOCK 1000000
+
+# define USE_GPIOV1
+# define PAL_OUTPUT_TYPE_OPENDRAIN _Static_assert(0, "RP2040 has no Open Drain GPIO configuration, setting this is not possible");
+
+# define usb_lld_endpoint_fields
+
+# define I2C1_SCL_PAL_MODE (PAL_MODE_ALTERNATE_I2C | PAL_RP_PAD_SLEWFAST | PAL_RP_PAD_PUE | PAL_RP_PAD_DRIVE4)
+# define I2C1_SDA_PAL_MODE I2C1_SCL_PAL_MODE
+
+# define USE_I2CV1_CONTRIB
+# if !defined(I2C1_CLOCK_SPEED)
+# define I2C1_CLOCK_SPEED 400000
+# endif
+
+# define SPI_SCK_PAL_MODE (PAL_MODE_ALTERNATE_SPI | PAL_RP_PAD_SLEWFAST | PAL_RP_PAD_DRIVE4)
+# define SPI_MOSI_PAL_MODE SPI_SCK_PAL_MODE
+# define SPI_MISO_PAL_MODE SPI_SCK_PAL_MODE
+#endif
+
// STM32 compatibility
#if defined(MCU_STM32)
# define CPU_CLOCK STM32_SYSCLK
@@ -60,6 +84,8 @@
# define PAL_OUTPUT_TYPE_PUSHPULL PAL_WB32_OTYPE_PUSHPULL
# define PAL_OUTPUT_SPEED_HIGHEST PAL_WB32_OSPEED_HIGH
# define PAL_PUPDR_FLOATING PAL_WB32_PUPDR_FLOATING
+
+# define SPI_SCK_FLAGS PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST | PAL_WB32_CURRENT_LEVEL3
# endif
#endif
@@ -74,13 +100,18 @@
#if defined(MCU_KINETIS)
# define CPU_CLOCK KINETIS_SYSCLK_FREQUENCY
-# if defined(K20x) || defined(KL2x)
+# if defined(K20x) || defined(K60x) || defined(KL2x)
# define USE_I2CV1
# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed
# define USE_GPIOV1
# endif
#endif
+#if defined(MCU_MIMXRT1062)
+# include "clock_config.h"
+# define CPU_CLOCK BOARD_BOOTCLOCKRUN_CORE_CLOCK
+#endif
+
#if defined(HT32)
# define CPU_CLOCK HT32_CK_SYS_FREQUENCY
# define PAL_MODE_ALTERNATE PAL_HT32_MODE_AF
@@ -88,3 +119,20 @@
# define PAL_OUTPUT_TYPE_PUSHPULL PAL_HT32_MODE_DIR
# define PAL_OUTPUT_SPEED_HIGHEST 0
#endif
+
+#if !defined(REALTIME_COUNTER_CLOCK)
+# define REALTIME_COUNTER_CLOCK CPU_CLOCK
+#endif
+
+// SPI Fallbacks
+#ifndef SPI_SCK_FLAGS
+# define SPI_SCK_FLAGS PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST
+#endif
+
+#ifndef SPI_MOSI_FLAGS
+# define SPI_MOSI_FLAGS PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST
+#endif
+
+#ifndef SPI_MISO_FLAGS
+# define SPI_MISO_FLAGS PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST
+#endif
diff --git a/platforms/chibios/converters/promicro_to_kb2040/_pin_defs.h b/platforms/chibios/converters/promicro_to_kb2040/_pin_defs.h
new file mode 100644
index 0000000000..0a3110890b
--- /dev/null
+++ b/platforms/chibios/converters/promicro_to_kb2040/_pin_defs.h
@@ -0,0 +1,36 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+// Left side (front)
+#define D3 0U
+#define D2 1U
+// GND
+// GND
+#define D1 2U
+#define D0 3U
+#define D4 4U
+#define C6 5U
+#define D7 6U
+#define E6 7U
+#define B4 8U
+#define B5 9U
+
+// Right side (front)
+// RAW
+// GND
+// RESET
+// VCC
+#define F4 29U
+#define F5 28U
+#define F6 27U
+#define F7 26U
+#define B1 18U
+#define B3 20U
+#define B2 19U
+#define B6 10U
+
+// LEDs (Mapped to QT connector to avoid collisions with button/neopixel)
+#define D5 12U
+#define B0 13U
diff --git a/platforms/chibios/converters/promicro_to_kb2040/converter.mk b/platforms/chibios/converters/promicro_to_kb2040/converter.mk
new file mode 100644
index 0000000000..6ffee357b3
--- /dev/null
+++ b/platforms/chibios/converters/promicro_to_kb2040/converter.mk
@@ -0,0 +1,9 @@
+# Adafruit KB2040 MCU settings for converting AVR projects
+MCU := RP2040
+BOARD := QMK_PM2040
+BOOTLOADER := rp2040
+
+# These are defaults based on what has been implemented for RP2040 boards
+SERIAL_DRIVER ?= vendor
+WS2812_DRIVER ?= vendor
+BACKLIGHT_DRIVER ?= software
diff --git a/platforms/chibios/converters/promicro_to_promicro_rp2040/_pin_defs.h b/platforms/chibios/converters/promicro_to_promicro_rp2040/_pin_defs.h
new file mode 100644
index 0000000000..0a1f4112a3
--- /dev/null
+++ b/platforms/chibios/converters/promicro_to_promicro_rp2040/_pin_defs.h
@@ -0,0 +1,36 @@
+// Copyright 2022 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+// Left side (front)
+#define D3 0U
+#define D2 1U
+// GND
+// GND
+#define D1 2U
+#define D0 3U
+#define D4 4U
+#define C6 5U
+#define D7 6U
+#define E6 7U
+#define B4 8U
+#define B5 9U
+
+// Right side (front)
+// RAW
+// GND
+// RESET
+// VCC
+#define F4 29U
+#define F5 28U
+#define F6 27U
+#define F7 26U
+#define B1 22U
+#define B3 20U
+#define B2 23U
+#define B6 21U
+
+// LEDs (Mapped to QT connector to avoid collisions with button/neopixel)
+#define D5 17U
+#define B0 16U
diff --git a/platforms/chibios/converters/promicro_to_promicro_rp2040/converter.mk b/platforms/chibios/converters/promicro_to_promicro_rp2040/converter.mk
new file mode 100644
index 0000000000..03863eeb02
--- /dev/null
+++ b/platforms/chibios/converters/promicro_to_promicro_rp2040/converter.mk
@@ -0,0 +1,9 @@
+# Sparkfun Pro Micro RP2040 MCU settings for converting AVR projects
+MCU := RP2040
+BOARD := QMK_PM2040
+BOOTLOADER := rp2040
+
+# These are defaults based on what has been implemented for RP2040 boards
+SERIAL_DRIVER ?= vendor
+WS2812_DRIVER ?= vendor
+BACKLIGHT_DRIVER ?= software
diff --git a/platforms/chibios/eeprom_stm32.c b/platforms/chibios/drivers/eeprom/eeprom_stm32.c
index a15bfe09ed..a15bfe09ed 100644
--- a/platforms/chibios/eeprom_stm32.c
+++ b/platforms/chibios/drivers/eeprom/eeprom_stm32.c
diff --git a/platforms/chibios/eeprom_stm32.h b/platforms/chibios/drivers/eeprom/eeprom_stm32.h
index 8fcfb556b8..8fcfb556b8 100644
--- a/platforms/chibios/eeprom_stm32.h
+++ b/platforms/chibios/drivers/eeprom/eeprom_stm32.h
diff --git a/platforms/chibios/eeprom_stm32_defs.h b/platforms/chibios/drivers/eeprom/eeprom_stm32_defs.h
index 57d0440330..57d0440330 100644
--- a/platforms/chibios/eeprom_stm32_defs.h
+++ b/platforms/chibios/drivers/eeprom/eeprom_stm32_defs.h
diff --git a/platforms/chibios/eeprom_teensy.c b/platforms/chibios/drivers/eeprom/eeprom_teensy.c
index c8777febde..c8777febde 100644
--- a/platforms/chibios/eeprom_teensy.c
+++ b/platforms/chibios/drivers/eeprom/eeprom_teensy.c
diff --git a/platforms/chibios/eeprom_teensy.h b/platforms/chibios/drivers/eeprom/eeprom_teensy.h
index 9a14a1fa79..9a14a1fa79 100755
--- a/platforms/chibios/eeprom_teensy.h
+++ b/platforms/chibios/drivers/eeprom/eeprom_teensy.h
diff --git a/platforms/chibios/flash_stm32.c b/platforms/chibios/drivers/flash/flash_stm32.c
index 72c41b8b78..72c41b8b78 100644
--- a/platforms/chibios/flash_stm32.c
+++ b/platforms/chibios/drivers/flash/flash_stm32.c
diff --git a/platforms/chibios/flash_stm32.h b/platforms/chibios/drivers/flash/flash_stm32.h
index 6c66642ec5..6c66642ec5 100644
--- a/platforms/chibios/flash_stm32.h
+++ b/platforms/chibios/drivers/flash/flash_stm32.h
diff --git a/platforms/chibios/drivers/serial.c b/platforms/chibios/drivers/serial.c
index 0cff057d1d..0dd8e71ae8 100644
--- a/platforms/chibios/drivers/serial.c
+++ b/platforms/chibios/drivers/serial.c
@@ -20,7 +20,8 @@
# error "chSysPolledDelayX method not supported on this platform"
#else
# undef wait_us
-# define wait_us(x) chSysPolledDelayX(US2RTC(CPU_CLOCK, x))
+// Force usage of polled waiting - in case WAIT_US_TIMER is activated
+# define wait_us(us) chSysPolledDelayX(US2RTC(REALTIME_COUNTER_CLOCK, us))
#endif
#ifndef SELECT_SOFT_SERIAL_SPEED
@@ -87,10 +88,7 @@ static THD_FUNCTION(Thread1, arg) {
chRegSetThreadName("blinker");
while (true) {
palWaitLineTimeout(SOFT_SERIAL_PIN, TIME_INFINITE);
-
- split_shared_memory_lock();
interrupt_handler(NULL);
- split_shared_memory_unlock();
}
}
@@ -155,6 +153,7 @@ static void __attribute__((noinline)) serial_write_byte(uint8_t data) {
// interrupt handle to be used by the slave device
void interrupt_handler(void *arg) {
+ split_shared_memory_lock_autounlock();
chSysLockFromISR();
sync_send();
@@ -212,6 +211,8 @@ void interrupt_handler(void *arg) {
static inline bool initiate_transaction(uint8_t sstd_index) {
if (sstd_index > NUM_TOTAL_TRANSACTIONS) return false;
+ split_shared_memory_lock_autounlock();
+
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
// TODO: remove extra delay between transactions
@@ -233,7 +234,7 @@ static inline bool initiate_transaction(uint8_t sstd_index) {
// check if the slave is present
if (serial_read_pin()) {
// slave failed to pull the line low, assume not present
- dprintf("serial::NO_RESPONSE\n");
+ serial_dprintf("serial::NO_RESPONSE\n");
chSysUnlock();
return false;
}
@@ -269,7 +270,7 @@ static inline bool initiate_transaction(uint8_t sstd_index) {
serial_delay();
if ((checksum_computed) != (checksum_received)) {
- dprintf("serial::FAIL[%u,%u,%u]\n", checksum_computed, checksum_received, sstd_index);
+ serial_dprintf("serial::FAIL[%u,%u,%u]\n", checksum_computed, checksum_received, sstd_index);
serial_output();
serial_high();
@@ -292,8 +293,5 @@ static inline bool initiate_transaction(uint8_t sstd_index) {
//
// this code is very time dependent, so we need to disable interrupts
bool soft_serial_transaction(int sstd_index) {
- split_shared_memory_lock();
- bool result = initiate_transaction((uint8_t)sstd_index);
- split_shared_memory_unlock();
- return result;
+ return initiate_transaction((uint8_t)sstd_index);
}
diff --git a/platforms/chibios/drivers/serial_protocol.c b/platforms/chibios/drivers/serial_protocol.c
new file mode 100644
index 0000000000..c95aed9885
--- /dev/null
+++ b/platforms/chibios/drivers/serial_protocol.c
@@ -0,0 +1,164 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <ch.h>
+
+#include "quantum.h"
+#include "serial.h"
+#include "serial_protocol.h"
+#include "printf.h"
+#include "synchronization_util.h"
+
+static inline bool initiate_transaction(uint8_t transaction_id);
+static inline bool react_to_transaction(void);
+
+/**
+ * @brief This thread runs on the slave and responds to transactions initiated
+ * by the master.
+ */
+static THD_WORKING_AREA(waSlaveThread, 1024);
+static THD_FUNCTION(SlaveThread, arg) {
+ (void)arg;
+ chRegSetThreadName("split_protocol_tx_rx");
+
+ while (true) {
+ if (unlikely(!react_to_transaction())) {
+ /* Clear the receive queue, to start with a clean slate.
+ * Parts of failed transactions or spurious bytes could still be in it. */
+ serial_transport_driver_clear();
+ }
+ }
+}
+
+/**
+ * @brief Slave specific initializations.
+ */
+void soft_serial_target_init(void) {
+ serial_transport_driver_slave_init();
+
+ /* Start transport thread. */
+ chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL);
+}
+
+/**
+ * @brief Master specific initializations.
+ */
+void soft_serial_initiator_init(void) {
+ serial_transport_driver_master_init();
+}
+
+/**
+ * @brief React to transactions started by the master.
+ */
+static inline bool react_to_transaction(void) {
+ uint8_t transaction_id = 0;
+ /* Wait until there is a transaction for us. */
+ if (unlikely(!serial_transport_receive_blocking(&transaction_id, sizeof(transaction_id)))) {
+ return false;
+ }
+
+ /* Sanity check that we are actually responding to a valid transaction. */
+ if (unlikely(transaction_id >= NUM_TOTAL_TRANSACTIONS)) {
+ return false;
+ }
+
+ split_shared_memory_lock_autounlock();
+
+ split_transaction_desc_t* transaction = &split_transaction_table[transaction_id];
+
+ /* Send back the handshake which is XORed as a simple checksum,
+ to signal that the slave is ready to receive possible transaction buffers */
+ transaction_id ^= NUM_TOTAL_TRANSACTIONS;
+ if (unlikely(!serial_transport_send(&transaction_id, sizeof(transaction_id)))) {
+ return false;
+ }
+
+ /* Receive transaction buffer from the master. If this transaction requires it.*/
+ if (transaction->initiator2target_buffer_size) {
+ if (unlikely(!serial_transport_receive(split_trans_initiator2target_buffer(transaction), transaction->initiator2target_buffer_size))) {
+ return false;
+ }
+ }
+
+ /* Allow any slave processing to occur. */
+ if (transaction->slave_callback) {
+ transaction->slave_callback(transaction->initiator2target_buffer_size, split_trans_initiator2target_buffer(transaction), transaction->initiator2target_buffer_size, split_trans_target2initiator_buffer(transaction));
+ }
+
+ /* Send transaction buffer to the master. If this transaction requires it. */
+ if (transaction->target2initiator_buffer_size) {
+ if (unlikely(!serial_transport_send(split_trans_target2initiator_buffer(transaction), transaction->target2initiator_buffer_size))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * @brief Start transaction from the master half to the slave half.
+ *
+ * @param index Transaction Table index of the transaction to start.
+ * @return bool Indicates success of transaction.
+ */
+bool soft_serial_transaction(int index) {
+ bool result = initiate_transaction((uint8_t)index);
+
+ if (unlikely(!result)) {
+ /* Clear the receive queue, to start with a clean slate.
+ * Parts of failed transactions or spurious bytes could still be in it. */
+ serial_transport_driver_clear();
+ }
+
+ return result;
+}
+
+/**
+ * @brief Initiate transaction to slave half.
+ */
+static inline bool initiate_transaction(uint8_t transaction_id) {
+ /* Sanity check that we are actually starting a valid transaction. */
+ if (unlikely(transaction_id >= NUM_TOTAL_TRANSACTIONS)) {
+ serial_dprintf("SPLIT: illegal transaction id\n");
+ return false;
+ }
+
+ split_shared_memory_lock_autounlock();
+
+ split_transaction_desc_t* transaction = &split_transaction_table[transaction_id];
+
+ /* Send transaction table index to the slave, which doubles as basic handshake token. */
+ if (unlikely(!serial_transport_send(&transaction_id, sizeof(transaction_id)))) {
+ serial_dprintf("SPLIT: sending handshake failed\n");
+ return false;
+ }
+
+ uint8_t transaction_id_shake = 0xFF;
+
+ /* Which we always read back first so that we can error out correctly.
+ * - due to the half duplex limitations on return codes, we always have to read *something*.
+ * - without the read, write only transactions *always* succeed, even during the boot process where the slave is not ready.
+ */
+ if (unlikely(!serial_transport_receive(&transaction_id_shake, sizeof(transaction_id_shake)) || (transaction_id_shake != (transaction_id ^ NUM_TOTAL_TRANSACTIONS)))) {
+ serial_dprintf("SPLIT: receiving handshake failed\n");
+ return false;
+ }
+
+ /* Send transaction buffer to the slave. If this transaction requires it. */
+ if (transaction->initiator2target_buffer_size) {
+ if (unlikely(!serial_transport_send(split_trans_initiator2target_buffer(transaction), transaction->initiator2target_buffer_size))) {
+ serial_dprintf("SPLIT: sending buffer failed\n");
+ return false;
+ }
+ }
+
+ /* Receive transaction buffer from the slave. If this transaction requires it. */
+ if (transaction->target2initiator_buffer_size) {
+ if (unlikely(!serial_transport_receive(split_trans_target2initiator_buffer(transaction), transaction->target2initiator_buffer_size))) {
+ serial_dprintf("SPLIT: receiving buffer failed\n");
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/platforms/chibios/drivers/serial_protocol.h b/platforms/chibios/drivers/serial_protocol.h
new file mode 100644
index 0000000000..4275a7f8d8
--- /dev/null
+++ b/platforms/chibios/drivers/serial_protocol.h
@@ -0,0 +1,49 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#pragma once
+
+/**
+ * @brief Clears any intermediate sending or receiving state of the driver to a known good
+ * state. This happens after errors in the middle of transactions, to start with
+ * a clean slate.
+ */
+void serial_transport_driver_clear(void);
+
+/**
+ * @brief Driver specific initialization on the slave half.
+ */
+void serial_transport_driver_slave_init(void);
+
+/**
+ * @brief Driver specific specific initialization on the master half.
+ */
+void serial_transport_driver_master_init(void);
+
+/**
+ * @brief Blocking receive of size * bytes.
+ *
+ * @return true Receive success.
+ * @return false Receive failed, e.g. by bit errors.
+ */
+bool __attribute__((nonnull, hot)) serial_transport_receive(uint8_t* destination, const size_t size);
+
+/**
+ * @brief Blocking receive of size * bytes with an implicitly defined timeout.
+ *
+ * @return true Receive success.
+ * @return false Receive failed, e.g. by timeout or bit errors.
+ */
+bool __attribute__((nonnull, hot)) serial_transport_receive_blocking(uint8_t* destination, const size_t size);
+
+/**
+ * @brief Blocking send of buffer with timeout.
+ *
+ * @return true Send success.
+ * @return false Send failed, e.g. by timeout or bit errors.
+ */
+bool __attribute__((nonnull, hot)) serial_transport_send(const uint8_t* source, const size_t size);
diff --git a/platforms/chibios/drivers/serial_usart.c b/platforms/chibios/drivers/serial_usart.c
index e9fa4af7a3..6581a5b6e9 100644
--- a/platforms/chibios/drivers/serial_usart.c
+++ b/platforms/chibios/drivers/serial_usart.c
@@ -1,49 +1,55 @@
-/* Copyright 2021 QMK
- *
- * 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 3 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/>.
- */
+// Copyright 2021 QMK
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
#include "serial_usart.h"
+#include "serial_protocol.h"
#include "synchronization_util.h"
#if defined(SERIAL_USART_CONFIG)
-static SerialConfig serial_config = SERIAL_USART_CONFIG;
-#else
-static SerialConfig serial_config = {
- .speed = (SERIAL_USART_SPEED), /* speed - mandatory */
+static QMKSerialConfig serial_config = SERIAL_USART_CONFIG;
+#elif defined(MCU_STM32) /* STM32 MCUs */
+static QMKSerialConfig serial_config = {
+# if HAL_USE_SERIAL
+ .speed = (SERIAL_USART_SPEED),
+# else
+ .baud = (SERIAL_USART_SPEED),
+# endif
.cr1 = (SERIAL_USART_CR1),
.cr2 = (SERIAL_USART_CR2),
# if !defined(SERIAL_USART_FULL_DUPLEX)
.cr3 = ((SERIAL_USART_CR3) | USART_CR3_HDSEL) /* activate half-duplex mode */
# else
- .cr3 = (SERIAL_USART_CR3)
+ .cr3 = (SERIAL_USART_CR3)
# endif
};
+#elif defined(MCU_RP) /* Raspberry Pi MCUs */
+/* USART in 8E2 config with RX and TX FIFOs enabled. */
+// clang-format off
+static QMKSerialConfig serial_config = {
+ .baud = (SERIAL_USART_SPEED),
+ .UARTLCR_H = UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_PEN | UART_UARTLCR_H_STP2 | UART_UARTLCR_H_FEN,
+ .UARTCR = 0U,
+ .UARTIFLS = UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E,
+ .UARTDMACR = 0U
+};
+// clang-format on
+#else
+# error MCU Familiy not supported by default, supply your own serial_config by defining SERIAL_USART_CONFIG in your keyboard files.
#endif
-static SerialDriver* serial_driver = &SERIAL_USART_DRIVER;
+static QMKSerialDriver* serial_driver = (QMKSerialDriver*)&SERIAL_USART_DRIVER;
-static inline bool react_to_transactions(void);
-static inline bool __attribute__((nonnull)) receive(uint8_t* destination, const size_t size);
-static inline bool __attribute__((nonnull)) send(const uint8_t* source, const size_t size);
-static inline bool initiate_transaction(uint8_t sstd_index);
-static inline void usart_clear(void);
+#if HAL_USE_SERIAL
/**
- * @brief Clear the receive input queue.
+ * @brief SERIAL Driver startup routine.
*/
-static inline void usart_clear(void) {
+static inline void usart_driver_start(void) {
+ sdStart(serial_driver, &serial_config);
+}
+
+inline void serial_transport_driver_clear(void) {
osalSysLock();
bool volatile queue_not_empty = !iqIsEmptyI(&serial_driver->iqueue);
osalSysUnlock();
@@ -64,36 +70,96 @@ static inline void usart_clear(void) {
}
}
+#elif HAL_USE_SIO
+
+void clear_rx_evt_cb(SIODriver* siop) {
+ osalSysLockFromISR();
+ /* If errors occured during transactions this callback is invoked. We just
+ * clear the error sources and move on. We rely on the fact that we check
+ * for the success of the transaction by comparing the received/send bytes
+ * with the actual received/send bytes in the send/receive functions. */
+ sioGetAndClearEventsI(serial_driver);
+ osalSysUnlockFromISR();
+}
+
+static const SIOOperation serial_usart_operation = {.rx_cb = NULL, .rx_idle_cb = NULL, .tx_cb = NULL, .tx_end_cb = NULL, .rx_evt_cb = &clear_rx_evt_cb};
+
/**
- * @brief Blocking send of buffer with timeout.
- *
- * @return true Send success.
- * @return false Send failed.
+ * @brief SIO Driver startup routine.
*/
-static inline bool send(const uint8_t* source, const size_t size) {
- bool success = (size_t)sdWriteTimeout(serial_driver, source, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
+static inline void usart_driver_start(void) {
+ sioStart(serial_driver, &serial_config);
+ sioStartOperation(serial_driver, &serial_usart_operation);
+}
+
+inline void serial_transport_driver_clear(void) {
+ osalSysLock();
+ while (!sioIsRXEmptyX(serial_driver)) {
+ (void)sioGetX(serial_driver);
+ }
+ osalSysUnlock();
+}
+
+#else
+
+# error Either the SERIAL or SIO driver has to be activated to use the usart driver for split keyboards.
+
+#endif
+
+inline bool serial_transport_send(const uint8_t* source, const size_t size) {
+ bool success = (size_t)chnWriteTimeout(serial_driver, source, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
#if !defined(SERIAL_USART_FULL_DUPLEX)
- if (success) {
- /* Half duplex fills the input queue with the data we wrote - just throw it away.
- Under the right circumstances (e.g. bad cables paired with high baud rates)
- less bytes can be present in the input queue, therefore a timeout is needed. */
- uint8_t dump[size];
- return receive(dump, size);
+ /* Half duplex fills the input queue with the data we wrote - just throw it away. */
+ if (likely(success)) {
+ size_t bytes_left = size;
+# if HAL_USE_SERIAL
+ /* The SERIAL driver uses large soft FIFOs that are filled from an IRQ
+ * context, so there is a delay between receiving the data and it
+ * becoming actually available, therefore we have to apply a timeout
+ * mechanism. Under the right circumstances (e.g. bad cables paired with
+ * high baud rates) less bytes can be present in the input queue as
+ * well. */
+ uint8_t dump[64];
+
+ while (unlikely(bytes_left >= 64)) {
+ if (unlikely(!serial_transport_receive(dump, 64))) {
+ return false;
+ }
+ bytes_left -= 64;
+ }
+
+ return serial_transport_receive(dump, bytes_left);
+# else
+ /* The SIO driver directly accesses the hardware FIFOs of the USART
+ * peripheral. As these are limited in depth, the RX FIFO might have been
+ * overflowed by a large that we just send. Therefore we attempt to read
+ * back all the data we send or until the FIFO runs empty in case it
+ * overflowed and data was truncated. */
+ if (unlikely(sioSynchronizeTXEnd(serial_driver, TIME_MS2I(SERIAL_USART_TIMEOUT)) < MSG_OK)) {
+ return false;
+ }
+
+ osalSysLock();
+ while (bytes_left > 0 && !sioIsRXEmptyX(serial_driver)) {
+ (void)sioGetX(serial_driver);
+ bytes_left--;
+ }
+ osalSysUnlock();
+# endif
}
#endif
return success;
}
-/**
- * @brief Blocking receive of size * bytes with timeout.
- *
- * @return true Receive success.
- * @return false Receive failed.
- */
-static inline bool receive(uint8_t* destination, const size_t size) {
- bool success = (size_t)sdReadTimeout(serial_driver, destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
+inline bool serial_transport_receive(uint8_t* destination, const size_t size) {
+ bool success = (size_t)chnReadTimeout(serial_driver, destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size;
+ return success;
+}
+
+inline bool serial_transport_receive_blocking(uint8_t* destination, const size_t size) {
+ bool success = (size_t)chnRead(serial_driver, destination, size) == size;
return success;
}
@@ -103,7 +169,7 @@ static inline bool receive(uint8_t* destination, const size_t size) {
* @brief Initiate pins for USART peripheral. Half-duplex configuration.
*/
__attribute__((weak)) void usart_init(void) {
-# if defined(MCU_STM32)
+# if defined(MCU_STM32) /* STM32 MCUs */
# if defined(USE_GPIOV1)
palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_OPENDRAIN);
# else
@@ -113,6 +179,8 @@ __attribute__((weak)) void usart_init(void) {
# if defined(USART_REMAP)
USART_REMAP;
# endif
+# elif defined(MCU_RP) /* Raspberry Pi MCUs */
+# error Half-duplex with the SIO driver is not supported due to hardware limitations on the RP2040, switch to the PIO driver which has half-duplex support.
# else
# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
# endif
@@ -124,7 +192,7 @@ __attribute__((weak)) void usart_init(void) {
* @brief Initiate pins for USART peripheral. Full-duplex configuration.
*/
__attribute__((weak)) void usart_init(void) {
-# if defined(MCU_STM32)
+# if defined(MCU_STM32) /* STM32 MCUs */
# if defined(USE_GPIOV1)
palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_PUSHPULL);
palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_INPUT);
@@ -136,6 +204,9 @@ __attribute__((weak)) void usart_init(void) {
# if defined(USART_REMAP)
USART_REMAP;
# endif
+# elif defined(MCU_RP) /* Raspberry Pi MCUs */
+ palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_UART);
+ palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_ALTERNATE_UART);
# else
# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files."
# endif
@@ -146,7 +217,7 @@ __attribute__((weak)) void usart_init(void) {
/**
* @brief Overridable master specific initializations.
*/
-__attribute__((weak, nonnull)) void usart_master_init(SerialDriver** driver) {
+__attribute__((weak, nonnull)) void usart_master_init(QMKSerialDriver** driver) {
(void)driver;
usart_init();
}
@@ -154,161 +225,22 @@ __attribute__((weak, nonnull)) void usart_master_init(SerialDriver** driver) {
/**
* @brief Overridable slave specific initializations.
*/
-__attribute__((weak, nonnull)) void usart_slave_init(SerialDriver** driver) {
+__attribute__((weak, nonnull)) void usart_slave_init(QMKSerialDriver** driver) {
(void)driver;
usart_init();
}
-/**
- * @brief This thread runs on the slave and responds to transactions initiated
- * by the master.
- */
-static THD_WORKING_AREA(waSlaveThread, 1024);
-static THD_FUNCTION(SlaveThread, arg) {
- (void)arg;
- chRegSetThreadName("usart_tx_rx");
-
- while (true) {
- if (!react_to_transactions()) {
- /* Clear the receive queue, to start with a clean slate.
- * Parts of failed transactions or spurious bytes could still be in it. */
- usart_clear();
- }
- split_shared_memory_unlock();
- }
-}
-
-/**
- * @brief Slave specific initializations.
- */
-void soft_serial_target_init(void) {
+void serial_transport_driver_slave_init(void) {
usart_slave_init(&serial_driver);
-
- sdStart(serial_driver, &serial_config);
-
- /* Start transport thread. */
- chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL);
+ usart_driver_start();
}
-/**
- * @brief React to transactions started by the master.
- */
-static inline bool react_to_transactions(void) {
- /* Wait until there is a transaction for us. */
- uint8_t sstd_index = (uint8_t)sdGet(serial_driver);
-
- /* Sanity check that we are actually responding to a valid transaction. */
- if (sstd_index >= NUM_TOTAL_TRANSACTIONS) {
- return false;
- }
-
- split_shared_memory_lock();
- split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
-
- /* Send back the handshake which is XORed as a simple checksum,
- to signal that the slave is ready to receive possible transaction buffers */
- sstd_index ^= HANDSHAKE_MAGIC;
- if (!send(&sstd_index, sizeof(sstd_index))) {
- return false;
- }
-
- /* Receive transaction buffer from the master. If this transaction requires it.*/
- if (trans->initiator2target_buffer_size) {
- if (!receive(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) {
- return false;
- }
- }
-
- /* Allow any slave processing to occur. */
- if (trans->slave_callback) {
- trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, split_trans_target2initiator_buffer(trans));
- }
-
- /* Send transaction buffer to the master. If this transaction requires it. */
- if (trans->target2initiator_buffer_size) {
- if (!send(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) {
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * @brief Master specific initializations.
- */
-void soft_serial_initiator_init(void) {
+void serial_transport_driver_master_init(void) {
usart_master_init(&serial_driver);
#if defined(MCU_STM32) && defined(SERIAL_USART_PIN_SWAP)
serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins
#endif
- sdStart(serial_driver, &serial_config);
-}
-
-/**
- * @brief Start transaction from the master half to the slave half.
- *
- * @param index Transaction Table index of the transaction to start.
- * @return bool Indicates success of transaction.
- */
-bool soft_serial_transaction(int index) {
- /* Clear the receive queue, to start with a clean slate.
- * Parts of failed transactions or spurious bytes could still be in it. */
- usart_clear();
-
- split_shared_memory_lock();
- bool result = initiate_transaction((uint8_t)index);
- split_shared_memory_unlock();
-
- return result;
-}
-
-/**
- * @brief Initiate transaction to slave half.
- */
-static inline bool initiate_transaction(uint8_t sstd_index) {
- /* Sanity check that we are actually starting a valid transaction. */
- if (sstd_index >= NUM_TOTAL_TRANSACTIONS) {
- dprintln("USART: Illegal transaction Id.");
- return false;
- }
-
- split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
-
- /* Send transaction table index to the slave, which doubles as basic handshake token. */
- if (!send(&sstd_index, sizeof(sstd_index))) {
- dprintln("USART: Send Handshake failed.");
- return false;
- }
-
- uint8_t sstd_index_shake = 0xFF;
-
- /* Which we always read back first so that we can error out correctly.
- * - due to the half duplex limitations on return codes, we always have to read *something*.
- * - without the read, write only transactions *always* succeed, even during the boot process where the slave is not ready.
- */
- if (!receive(&sstd_index_shake, sizeof(sstd_index_shake)) || (sstd_index_shake != (sstd_index ^ HANDSHAKE_MAGIC))) {
- dprintln("USART: Handshake failed.");
- return false;
- }
-
- /* Send transaction buffer to the slave. If this transaction requires it. */
- if (trans->initiator2target_buffer_size) {
- if (!send(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) {
- dprintln("USART: Send failed.");
- return false;
- }
- }
-
- /* Receive transaction buffer from the slave. If this transaction requires it. */
- if (trans->target2initiator_buffer_size) {
- if (!receive(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) {
- dprintln("USART: Receive failed.");
- return false;
- }
- }
-
- return true;
+ usart_driver_start();
}
diff --git a/platforms/chibios/drivers/serial_usart.h b/platforms/chibios/drivers/serial_usart.h
index 81fe9e0113..fa062cd736 100644
--- a/platforms/chibios/drivers/serial_usart.h
+++ b/platforms/chibios/drivers/serial_usart.h
@@ -1,42 +1,12 @@
-/* Copyright 2021 QMK
- *
- * 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 3 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/>.
- */
+// Copyright 2021 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
#include "serial.h"
-#include "printf.h"
-
-#include <ch.h>
#include <hal.h>
-#if !defined(SERIAL_USART_DRIVER)
-# define SERIAL_USART_DRIVER SD1
-#endif
-
-#if !defined(USE_GPIOV1)
-/* The default PAL alternate modes are used to signal that the pins are used for USART. */
-# if !defined(SERIAL_USART_TX_PAL_MODE)
-# define SERIAL_USART_TX_PAL_MODE 7
-# endif
-# if !defined(SERIAL_USART_RX_PAL_MODE)
-# define SERIAL_USART_RX_PAL_MODE 7
-# endif
-#endif
-
#if defined(SOFT_SERIAL_PIN)
# define SERIAL_USART_TX_PIN SOFT_SERIAL_PIN
#endif
@@ -49,6 +19,62 @@
# define SERIAL_USART_RX_PIN A10
#endif
+#if !defined(SELECT_SOFT_SERIAL_SPEED)
+# define SELECT_SOFT_SERIAL_SPEED 1
+#endif
+
+#if defined(SERIAL_USART_SPEED)
+// Allow advanced users to directly set SERIAL_USART_SPEED
+#elif SELECT_SOFT_SERIAL_SPEED == 0
+# define SERIAL_USART_SPEED 460800
+#elif SELECT_SOFT_SERIAL_SPEED == 1
+# define SERIAL_USART_SPEED 230400
+#elif SELECT_SOFT_SERIAL_SPEED == 2
+# define SERIAL_USART_SPEED 115200
+#elif SELECT_SOFT_SERIAL_SPEED == 3
+# define SERIAL_USART_SPEED 57600
+#elif SELECT_SOFT_SERIAL_SPEED == 4
+# define SERIAL_USART_SPEED 38400
+#elif SELECT_SOFT_SERIAL_SPEED == 5
+# define SERIAL_USART_SPEED 19200
+#else
+# error invalid SELECT_SOFT_SERIAL_SPEED value
+#endif
+
+#if !defined(SERIAL_USART_TIMEOUT)
+# define SERIAL_USART_TIMEOUT 20
+#endif
+
+#if HAL_USE_SERIAL
+
+typedef SerialDriver QMKSerialDriver;
+typedef SerialConfig QMKSerialConfig;
+
+# if !defined(SERIAL_USART_DRIVER)
+# define SERIAL_USART_DRIVER SD1
+# endif
+
+#elif HAL_USE_SIO
+
+typedef SIODriver QMKSerialDriver;
+typedef SIOConfig QMKSerialConfig;
+
+# if !defined(SERIAL_USART_DRIVER)
+# define SERIAL_USART_DRIVER SIOD1
+# endif
+
+#endif
+
+#if !defined(USE_GPIOV1)
+/* The default PAL alternate modes are used to signal that the pins are used for USART. */
+# if !defined(SERIAL_USART_TX_PAL_MODE)
+# define SERIAL_USART_TX_PAL_MODE 7
+# endif
+# if !defined(SERIAL_USART_RX_PAL_MODE)
+# define SERIAL_USART_RX_PAL_MODE 7
+# endif
+#endif
+
#if !defined(USART_CR1_M0)
# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so
#endif
@@ -86,31 +112,3 @@
(AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_FULLREMAP); \
} while (0)
#endif
-
-#if !defined(SELECT_SOFT_SERIAL_SPEED)
-# define SELECT_SOFT_SERIAL_SPEED 1
-#endif
-
-#if defined(SERIAL_USART_SPEED)
-// Allow advanced users to directly set SERIAL_USART_SPEED
-#elif SELECT_SOFT_SERIAL_SPEED == 0
-# define SERIAL_USART_SPEED 460800
-#elif SELECT_SOFT_SERIAL_SPEED == 1
-# define SERIAL_USART_SPEED 230400
-#elif SELECT_SOFT_SERIAL_SPEED == 2
-# define SERIAL_USART_SPEED 115200
-#elif SELECT_SOFT_SERIAL_SPEED == 3
-# define SERIAL_USART_SPEED 57600
-#elif SELECT_SOFT_SERIAL_SPEED == 4
-# define SERIAL_USART_SPEED 38400
-#elif SELECT_SOFT_SERIAL_SPEED == 5
-# define SERIAL_USART_SPEED 19200
-#else
-# error invalid SELECT_SOFT_SERIAL_SPEED value
-#endif
-
-#if !defined(SERIAL_USART_TIMEOUT)
-# define SERIAL_USART_TIMEOUT 20
-#endif
-
-#define HANDSHAKE_MAGIC 7
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c
index ce69e7f0ac..c3ab0623f0 100644
--- a/platforms/chibios/drivers/spi_master.c
+++ b/platforms/chibios/drivers/spi_master.c
@@ -20,7 +20,7 @@
static pin_t currentSlavePin = NO_PIN;
-#if defined(K20x) || defined(KL2x)
+#if defined(K20x) || defined(KL2x) || defined(RP2040)
static SPIConfig spiConfig = {NULL, 0, 0, 0};
#else
static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
@@ -42,10 +42,12 @@ __attribute__((weak)) void spi_init(void) {
palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_PAL_MODE);
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
#else
- palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
- palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
- palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_FLAGS);
+ palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_FLAGS);
+ palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_FLAGS);
#endif
+ spiStop(&SPI_DRIVER);
+ currentSlavePin = NO_PIN;
}
}
@@ -167,7 +169,36 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
spiConfig.SPI_CPOL = SPI_CPOL_High;
break;
}
+#elif defined(MCU_RP)
+ if (lsbFirst) {
+ osalDbgAssert(lsbFirst == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first.");
+ }
+
+ // Motorola frame format and 8bit transfer data size.
+ spiConfig.SSPCR0 = SPI_SSPCR0_FRF_MOTOROLA | SPI_SSPCR0_DSS_8BIT;
+ // Serial output clock = (ck_sys or ck_peri) / (SSPCPSR->CPSDVSR * (1 +
+ // SSPCR0->SCR)). SCR is always set to zero, as QMK SPI API expects the
+ // passed divisor to be the only value to divide the input clock by.
+ spiConfig.SSPCPSR = roundedDivisor; // Even number from 2 to 254
+ switch (mode) {
+ case 0:
+ spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low
+ spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge
+ break;
+ case 1:
+ spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low
+ spiConfig.SSPCR0 |= SPI_SSPCR0_SPH; // Clock phase: sample on second edge transition
+ break;
+ case 2:
+ spiConfig.SSPCR0 |= SPI_SSPCR0_SPO; // Clock polarity: high
+ spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge
+ break;
+ case 3:
+ spiConfig.SSPCR0 |= SPI_SSPCR0_SPO; // Clock polarity: high
+ spiConfig.SSPCR0 |= SPI_SSPCR0_SPH; // Clock phase: sample on second edge transition
+ break;
+ }
#else
spiConfig.cr1 = 0;
diff --git a/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c b/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c
new file mode 100644
index 0000000000..338146dadd
--- /dev/null
+++ b/platforms/chibios/drivers/vendor/RP/RP2040/serial_vendor.c
@@ -0,0 +1,471 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+#include "serial_usart.h"
+#include "serial_protocol.h"
+#include "hardware/pio.h"
+#include "hardware/clocks.h"
+
+#if !defined(MCU_RP)
+# error PIO Driver is only available for Raspberry Pi 2040 MCUs!
+#endif
+
+static inline bool receive_impl(uint8_t* destination, const size_t size, sysinterval_t timeout);
+static inline bool send_impl(const uint8_t* source, const size_t size);
+static inline void pio_serve_interrupt(void);
+
+#define MSG_PIO_ERROR ((msg_t)(-3))
+
+#if defined(SERIAL_PIO_USE_PIO1)
+static const PIO pio = pio1;
+
+OSAL_IRQ_HANDLER(RP_PIO1_IRQ_0_HANDLER) {
+ OSAL_IRQ_PROLOGUE();
+ pio_serve_interrupt();
+ OSAL_IRQ_EPILOGUE();
+}
+#else
+static const PIO pio = pio0;
+
+OSAL_IRQ_HANDLER(RP_PIO0_IRQ_0_HANDLER) {
+ OSAL_IRQ_PROLOGUE();
+ pio_serve_interrupt();
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#define UART_TX_WRAP_TARGET 0
+#define UART_TX_WRAP 3
+
+// clang-format off
+#if defined(SERIAL_USART_FULL_DUPLEX)
+static const uint16_t uart_tx_program_instructions[] = {
+ // .wrap_target
+ 0x9fa0, // 0: pull block side 1 [7]
+ 0xf727, // 1: set x, 7 side 0 [7]
+ 0x6001, // 2: out pins, 1
+ 0x0642, // 3: jmp x--, 2 [6]
+ // .wrap
+};
+#else
+static const uint16_t uart_tx_program_instructions[] = {
+ // .wrap_target
+ 0x9fa0, // 0: pull block side 1 [7]
+ 0xf727, // 1: set x, 7 side 0 [7]
+ 0x6081, // 2: out pindirs, 1
+ 0x0642, // 3: jmp x--, 2 [6]
+ // .wrap
+};
+#endif
+// clang-format on
+
+static const pio_program_t uart_tx_program = {
+ .instructions = uart_tx_program_instructions,
+ .length = 4,
+ .origin = -1,
+};
+
+#define UART_RX_WRAP_TARGET 0
+#define UART_RX_WRAP 8
+
+// clang-format off
+static const uint16_t uart_rx_program_instructions[] = {
+ // .wrap_target
+ 0x2020, // 0: wait 0 pin, 0
+ 0xea27, // 1: set x, 7 [10]
+ 0x4001, // 2: in pins, 1
+ 0x0642, // 3: jmp x--, 2 [6]
+ 0x00c8, // 4: jmp pin, 8
+ 0xc020, // 5: irq wait 0
+ 0x20a0, // 6: wait 1 pin, 0
+ 0x0000, // 7: jmp 0
+ 0x8020, // 8: push block
+ // .wrap
+};
+// clang-format on
+
+static const pio_program_t uart_rx_program = {
+ .instructions = uart_rx_program_instructions,
+ .length = 9,
+ .origin = -1,
+};
+
+thread_reference_t rx_thread = NULL;
+static int rx_state_machine = -1;
+
+thread_reference_t tx_thread = NULL;
+static int tx_state_machine = -1;
+
+void pio_serve_interrupt(void) {
+ uint32_t irqs = pio->ints0;
+
+ // The RX FIFO is not empty any more, therefore wake any sleeping rx thread
+ if (irqs & (PIO_IRQ0_INTF_SM0_RXNEMPTY_BITS << rx_state_machine)) {
+ // Disable rx not empty interrupt
+ pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, false);
+
+ osalSysLockFromISR();
+ osalThreadResumeI(&rx_thread, MSG_OK);
+ osalSysUnlockFromISR();
+ }
+
+ // The TX FIFO is not full any more, therefore wake any sleeping tx thread
+ if (irqs & (PIO_IRQ0_INTF_SM0_TXNFULL_BITS << tx_state_machine)) {
+ // Disable tx not full interrupt
+ pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, false);
+ osalSysLockFromISR();
+ osalThreadResumeI(&tx_thread, MSG_OK);
+ osalSysUnlockFromISR();
+ }
+
+ // IRQ 0 is set on framing or break errors by the rx state machine
+ if (pio_interrupt_get(pio, 0UL)) {
+ pio_interrupt_clear(pio, 0UL);
+
+ osalSysLockFromISR();
+ osalThreadResumeI(&rx_thread, MSG_PIO_ERROR);
+ osalSysUnlockFromISR();
+ }
+}
+
+#if !defined(SERIAL_USART_FULL_DUPLEX)
+// The internal pull-ups of the RP2040 are rather weakish with a range of 50k to
+// 80k, which in turn do not provide enough current to guarantee fast signal rise
+// times with a parasitic capacitance of greater than 100pf. In real world
+// applications, like split keyboards which might have vias in the signal path
+// or long PCB traces, this prevents a successful communication. The solution
+// is to temporarily augment the weak pull ups from the receiving side by
+// driving the tx pin high. On the receiving side the lowest possible drive
+// strength is chosen because the transmitting side must still be able to drive
+// the signal low. With this configuration the rise times are fast enough and
+// the generated low level with 360mV will generate a logical zero.
+static inline void enter_rx_state(void) {
+ osalSysLock();
+ nvicEnableVector(RP_USBCTRL_IRQ_NUMBER, RP_IRQ_USB0_PRIORITY);
+ // Wait for the transmitting state machines FIFO to run empty. At this point
+ // the last byte has been pulled from the transmitting state machines FIFO
+ // into the output shift register. We have to wait a tiny bit more until
+ // this byte is transmitted, before we can turn on the receiving state
+ // machine again.
+ while (!pio_sm_is_tx_fifo_empty(pio, tx_state_machine)) {
+ }
+ // Wait for ~11 bits, 1 start bit + 8 data bits + 1 stop bit + 1 bit
+ // headroom.
+ wait_us(1000000U * 11U / SERIAL_USART_SPEED);
+ // Disable tx state machine to not interfere with our tx pin manipulation
+ pio_sm_set_enabled(pio, tx_state_machine, false);
+ gpio_set_drive_strength(SERIAL_USART_TX_PIN, GPIO_DRIVE_STRENGTH_2MA);
+ pio_sm_set_pins_with_mask(pio, tx_state_machine, 1U << SERIAL_USART_TX_PIN, 1U << SERIAL_USART_TX_PIN);
+ pio_sm_set_consecutive_pindirs(pio, tx_state_machine, SERIAL_USART_TX_PIN, 1U, false);
+ pio_sm_set_enabled(pio, rx_state_machine, true);
+ osalSysUnlock();
+}
+
+static inline void leave_rx_state(void) {
+ osalSysLock();
+ // We don't want to be interrupted by frequent (1KHz) USB interrupts while
+ // doing our timing critical sending operation.
+ nvicDisableVector(RP_USBCTRL_IRQ_NUMBER);
+ // In Half-duplex operation the tx pin dual-functions as sender and
+ // receiver. To not receive the data we will send, we disable the receiving
+ // state machine.
+ pio_sm_set_enabled(pio, rx_state_machine, false);
+ pio_sm_set_consecutive_pindirs(pio, tx_state_machine, SERIAL_USART_TX_PIN, 1U, true);
+ pio_sm_set_pins_with_mask(pio, tx_state_machine, 0U, 1U << SERIAL_USART_TX_PIN);
+ gpio_set_drive_strength(SERIAL_USART_TX_PIN, GPIO_DRIVE_STRENGTH_12MA);
+ pio_sm_restart(pio, tx_state_machine);
+ pio_sm_set_enabled(pio, tx_state_machine, true);
+ osalSysUnlock();
+}
+#else
+// All this trickery is gladly not necessary for full-duplex.
+static inline void enter_rx_state(void) {}
+static inline void leave_rx_state(void) {}
+#endif
+
+/**
+ * @brief Clear the RX and TX hardware FIFOs of the state machines.
+ */
+inline void serial_transport_driver_clear(void) {
+ osalSysLock();
+ pio_sm_clear_fifos(pio, rx_state_machine);
+ pio_sm_clear_fifos(pio, tx_state_machine);
+ osalSysUnlock();
+}
+
+static inline msg_t sync_tx(sysinterval_t timeout) {
+ msg_t msg = MSG_OK;
+ osalSysLock();
+ while (pio_sm_is_tx_fifo_full(pio, tx_state_machine)) {
+#if !defined(SERIAL_USART_FULL_DUPLEX)
+ // Enable USB interrupts again, because we might sleep for a long time
+ // here and don't want to be disconnected from the host.
+ nvicEnableVector(RP_USBCTRL_IRQ_NUMBER, RP_IRQ_USB0_PRIORITY);
+#endif
+ pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true);
+ msg = osalThreadSuspendTimeoutS(&tx_thread, timeout);
+ if (msg < MSG_OK) {
+ break;
+ }
+ }
+#if !defined(SERIAL_USART_FULL_DUPLEX)
+ // Entering timing critical territory again.
+ nvicDisableVector(RP_USBCTRL_IRQ_NUMBER);
+#endif
+ osalSysUnlock();
+ return msg;
+}
+
+static inline bool send_impl(const uint8_t* source, const size_t size) {
+ size_t send = 0;
+ msg_t msg;
+ while (send < size) {
+ msg = sync_tx(TIME_MS2I(SERIAL_USART_TIMEOUT));
+ if (msg < MSG_OK) {
+ return false;
+ }
+
+ osalSysLock();
+ while (send < size) {
+ if (pio_sm_is_tx_fifo_full(pio, tx_state_machine)) {
+ break;
+ }
+ if (send >= size) {
+ break;
+ }
+ pio_sm_put(pio, tx_state_machine, (uint32_t)(*source));
+ source++;
+ send++;
+ }
+ osalSysUnlock();
+ }
+
+ return send == size;
+}
+
+/**
+ * @brief Blocking send of buffer with timeout.
+ *
+ * @return true Send success.
+ * @return false Send failed.
+ */
+inline bool serial_transport_send(const uint8_t* source, const size_t size) {
+ leave_rx_state();
+ bool result = send_impl(source, size);
+ enter_rx_state();
+
+ return result;
+}
+
+static inline msg_t sync_rx(sysinterval_t timeout) {
+ msg_t msg = MSG_OK;
+ osalSysLock();
+ while (pio_sm_is_rx_fifo_empty(pio, rx_state_machine)) {
+ pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, true);
+ msg = osalThreadSuspendTimeoutS(&rx_thread, timeout);
+ if (msg < MSG_OK) {
+ break;
+ }
+ }
+ osalSysUnlock();
+ return msg;
+}
+
+static inline bool receive_impl(uint8_t* destination, const size_t size, sysinterval_t timeout) {
+ size_t read = 0U;
+
+ while (read < size) {
+ msg_t msg = sync_rx(timeout);
+ if (msg < MSG_OK) {
+ return false;
+ }
+ osalSysLock();
+ while (true) {
+ if (pio_sm_is_rx_fifo_empty(pio, rx_state_machine)) {
+ break;
+ }
+ if (read >= size) {
+ break;
+ }
+ *destination++ = *((uint8_t*)&pio->rxf[rx_state_machine] + 3U);
+ read++;
+ }
+ osalSysUnlock();
+ }
+
+ return read == size;
+}
+
+/**
+ * @brief Blocking receive of size * bytes with timeout.
+ *
+ * @return true Receive success.
+ * @return false Receive failed, e.g. by timeout.
+ */
+inline bool serial_transport_receive(uint8_t* destination, const size_t size) {
+ return receive_impl(destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT));
+}
+
+/**
+ * @brief Blocking receive of size * bytes.
+ *
+ * @return true Receive success.
+ * @return false Receive failed.
+ */
+inline bool serial_transport_receive_blocking(uint8_t* destination, const size_t size) {
+ return receive_impl(destination, size, TIME_INFINITE);
+}
+
+static inline void pio_tx_init(pin_t tx_pin) {
+ uint pio_idx = pio_get_index(pio);
+ uint offset = pio_add_program(pio, &uart_tx_program);
+
+#if defined(SERIAL_USART_FULL_DUPLEX)
+ // clang-format off
+ iomode_t tx_pin_mode = PAL_RP_GPIO_OE |
+ PAL_RP_PAD_SLEWFAST |
+ PAL_RP_PAD_DRIVE4 |
+ (pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
+ // clang-format on
+ pio_sm_set_pins_with_mask(pio, tx_state_machine, 1U << tx_pin, 1U << tx_pin);
+ pio_sm_set_consecutive_pindirs(pio, tx_state_machine, tx_pin, 1U, true);
+#else
+ // clang-format off
+ iomode_t tx_pin_mode = PAL_RP_PAD_IE |
+ PAL_RP_GPIO_OE |
+ PAL_RP_PAD_SCHMITT |
+ PAL_RP_PAD_PUE |
+ PAL_RP_PAD_SLEWFAST |
+ PAL_RP_PAD_DRIVE12 |
+ PAL_RP_IOCTRL_OEOVER_DRVINVPERI |
+ (pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
+ // clang-format on
+ pio_sm_set_pins_with_mask(pio, tx_state_machine, 0U << tx_pin, 1U << tx_pin);
+ pio_sm_set_consecutive_pindirs(pio, tx_state_machine, tx_pin, 1U, true);
+#endif
+
+ palSetLineMode(tx_pin, tx_pin_mode);
+
+ pio_sm_config config = pio_get_default_sm_config();
+ sm_config_set_wrap(&config, offset + UART_TX_WRAP_TARGET, offset + UART_TX_WRAP);
+#if defined(SERIAL_USART_FULL_DUPLEX)
+ sm_config_set_sideset(&config, 2, true, false);
+#else
+ sm_config_set_sideset(&config, 2, true, true);
+#endif
+ // OUT shifts to right, no autopull
+ sm_config_set_out_shift(&config, true, false, 32);
+ // We are mapping both OUT and side-set to the same pin, because sometimes
+ // we need to assert user data onto the pin (with OUT) and sometimes
+ // assert constant values (start/stop bit)
+ sm_config_set_out_pins(&config, tx_pin, 1);
+ sm_config_set_sideset_pins(&config, tx_pin);
+ // We only need TX, so get an 8-deep FIFO!
+ sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX);
+ // SM transmits 1 bit per 8 execution cycles.
+ float div = (float)clock_get_hz(clk_sys) / (8 * SERIAL_USART_SPEED);
+ sm_config_set_clkdiv(&config, div);
+ pio_sm_init(pio, tx_state_machine, offset, &config);
+ pio_sm_set_enabled(pio, tx_state_machine, true);
+}
+
+static inline void pio_rx_init(pin_t rx_pin) {
+ uint offset = pio_add_program(pio, &uart_rx_program);
+
+#if defined(SERIAL_USART_FULL_DUPLEX)
+ uint pio_idx = pio_get_index(pio);
+ pio_sm_set_consecutive_pindirs(pio, rx_state_machine, rx_pin, 1, false);
+ // clang-format off
+ iomode_t rx_pin_mode = PAL_RP_PAD_IE |
+ PAL_RP_PAD_SCHMITT |
+ PAL_RP_PAD_PUE |
+ (pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
+ // clang-format on
+ palSetLineMode(rx_pin, rx_pin_mode);
+#endif
+
+ pio_sm_config config = pio_get_default_sm_config();
+ sm_config_set_wrap(&config, offset + UART_RX_WRAP_TARGET, offset + UART_RX_WRAP);
+ sm_config_set_in_pins(&config, rx_pin); // for WAIT, IN
+ sm_config_set_jmp_pin(&config, rx_pin); // for JMP
+ // Shift to right, autopush disabled
+ sm_config_set_in_shift(&config, true, false, 32);
+ // Deeper FIFO as we're not doing any TX
+ sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_RX);
+ // SM transmits 1 bit per 8 execution cycles.
+ float div = (float)clock_get_hz(clk_sys) / (8 * SERIAL_USART_SPEED);
+ sm_config_set_clkdiv(&config, div);
+ pio_sm_init(pio, rx_state_machine, offset, &config);
+ pio_sm_set_enabled(pio, rx_state_machine, true);
+}
+
+static inline void pio_init(pin_t tx_pin, pin_t rx_pin) {
+ uint pio_idx = pio_get_index(pio);
+
+ /* Get PIOx peripheral out of reset state. */
+ hal_lld_peripheral_unreset(pio_idx == 0 ? RESETS_ALLREG_PIO0 : RESETS_ALLREG_PIO1);
+
+ tx_state_machine = pio_claim_unused_sm(pio, true);
+ if (tx_state_machine < 0) {
+ dprintln("ERROR: Failed to acquire state machine for serial transmission!");
+ return;
+ }
+ pio_tx_init(tx_pin);
+
+ rx_state_machine = pio_claim_unused_sm(pio, true);
+ if (rx_state_machine < 0) {
+ dprintln("ERROR: Failed to acquire state machine for serial reception!");
+ return;
+ }
+ pio_rx_init(rx_pin);
+
+ // Enable error flag IRQ source for rx state machine
+ pio_set_irq0_source_enabled(pio, pis_sm0_rx_fifo_not_empty + rx_state_machine, true);
+ pio_set_irq0_source_enabled(pio, pis_sm0_tx_fifo_not_full + tx_state_machine, true);
+ pio_set_irq0_source_enabled(pio, pis_interrupt0, true);
+
+ // Enable PIO specific interrupt vector, as the pio implementation is timing
+ // critical we use the highest possible priority.
+#if defined(SERIAL_PIO_USE_PIO1)
+ nvicEnableVector(RP_PIO1_IRQ_0_NUMBER, CORTEX_MAX_KERNEL_PRIORITY);
+#else
+ nvicEnableVector(RP_PIO0_IRQ_0_NUMBER, CORTEX_MAX_KERNEL_PRIORITY);
+#endif
+
+ enter_rx_state();
+}
+
+/**
+ * @brief PIO driver specific initialization function for the master side.
+ */
+void serial_transport_driver_master_init(void) {
+#if defined(SERIAL_USART_FULL_DUPLEX)
+ pin_t tx_pin = SERIAL_USART_TX_PIN;
+ pin_t rx_pin = SERIAL_USART_RX_PIN;
+#else
+ pin_t tx_pin = SERIAL_USART_TX_PIN;
+ pin_t rx_pin = SERIAL_USART_TX_PIN;
+#endif
+
+#if defined(SERIAL_USART_PIN_SWAP)
+ pio_init(rx_pin, tx_pin);
+#else
+ pio_init(tx_pin, rx_pin);
+#endif
+}
+
+/**
+ * @brief PIO driver specific initialization function for the slave side.
+ */
+void serial_transport_driver_slave_init(void) {
+#if defined(SERIAL_USART_FULL_DUPLEX)
+ pin_t tx_pin = SERIAL_USART_TX_PIN;
+ pin_t rx_pin = SERIAL_USART_RX_PIN;
+#else
+ pin_t tx_pin = SERIAL_USART_TX_PIN;
+ pin_t rx_pin = SERIAL_USART_TX_PIN;
+#endif
+
+ pio_init(tx_pin, rx_pin);
+}
diff --git a/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c b/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
new file mode 100644
index 0000000000..bc34eded14
--- /dev/null
+++ b/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
@@ -0,0 +1,189 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+#include "ws2812.h"
+#include "hardware/pio.h"
+#include "hardware/clocks.h"
+
+#if !defined(MCU_RP)
+# error PIO Driver is only available for Raspberry Pi 2040 MCUs!
+#endif
+
+#if defined(WS2812_PIO_USE_PIO1)
+static const PIO pio = pio1;
+#else
+static const PIO pio = pio0;
+#endif
+
+#if !defined(RP_DMA_PRIORITY_WS2812)
+# define RP_DMA_PRIORITY_WS2812 12
+#endif
+
+static int state_machine = -1;
+
+#define WS2812_WRAP_TARGET 0
+#define WS2812_WRAP 3
+
+#define WS2812_T1 2
+#define WS2812_T2 5
+#define WS2812_T3 3
+
+#if defined(WS2812_EXTERNAL_PULLUP)
+
+# pragma message "The GPIOs of the RP2040 are NOT 5V tolerant! Make sure to NOT apply any voltage over 3.3V to the RGB data pin."
+
+// clang-format off
+static const uint16_t ws2812_program_instructions[] = {
+ // .wrap_target
+ 0x7221, // 0: out x, 1 side 1 [2]
+ 0x0123, // 1: jmp !x, 3 side 0 [1]
+ 0x0400, // 2: jmp 0 side 0 [4]
+ 0xb442, // 3: nop side 1 [4]
+ // .wrap
+};
+
+#else
+
+static const uint16_t ws2812_program_instructions[] = {
+ // .wrap_target
+ 0x6221, // 0: out x, 1 side 0 [2]
+ 0x1123, // 1: jmp !x, 3 side 1 [1]
+ 0x1400, // 2: jmp 0 side 1 [4]
+ 0xa442, // 3: nop side 0 [4]
+ // .wrap
+};
+// clang-format on
+#endif
+
+static const pio_program_t ws2812_program = {
+ .instructions = ws2812_program_instructions,
+ .length = 4,
+ .origin = -1,
+};
+
+static uint32_t WS2812_BUFFER[RGBLED_NUM];
+static const rp_dma_channel_t* WS2812_DMA_CHANNEL;
+
+bool ws2812_init(void) {
+ uint pio_idx = pio_get_index(pio);
+ /* Get PIOx peripheral out of reset state. */
+ hal_lld_peripheral_unreset(pio_idx == 0 ? RESETS_ALLREG_PIO0 : RESETS_ALLREG_PIO1);
+
+ // clang-format off
+ iomode_t rgb_pin_mode = PAL_RP_PAD_SLEWFAST |
+ PAL_RP_GPIO_OE |
+ (pio_idx == 0 ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1);
+ // clang-format on
+
+ palSetLineMode(RGB_DI_PIN, rgb_pin_mode);
+
+ state_machine = pio_claim_unused_sm(pio, true);
+ if (state_machine < 0) {
+ dprintln("ERROR: Failed to acquire state machine for WS2812 output!");
+ return false;
+ }
+
+ uint offset = pio_add_program(pio, &ws2812_program);
+
+ pio_sm_set_consecutive_pindirs(pio, state_machine, RGB_DI_PIN, 1, true);
+
+ pio_sm_config config = pio_get_default_sm_config();
+ sm_config_set_wrap(&config, offset + WS2812_WRAP_TARGET, offset + WS2812_WRAP);
+ sm_config_set_sideset_pins(&config, RGB_DI_PIN);
+ sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX);
+
+#if defined(WS2812_EXTERNAL_PULLUP)
+ /* Instruct side-set to change the pin-directions instead of outputting
+ * a logic level. We generate our levels the following way:
+ *
+ * 1: Set RGB data pin to high impedance input and let the pull-up drive the
+ * signal high.
+ *
+ * 0: Set RGB data pin to low impedance output and drive the pin low.
+ */
+ sm_config_set_sideset(&config, 1, false, true);
+#else
+ sm_config_set_sideset(&config, 1, false, false);
+#endif
+
+#if defined(RGBW)
+ sm_config_set_out_shift(&config, false, true, 32);
+#else
+ sm_config_set_out_shift(&config, false, true, 24);
+#endif
+
+ int cycles_per_bit = WS2812_T1 + WS2812_T2 + WS2812_T3;
+ float div = clock_get_hz(clk_sys) / (800.0f * KHZ * cycles_per_bit);
+ sm_config_set_clkdiv(&config, div);
+
+ pio_sm_init(pio, state_machine, offset, &config);
+ pio_sm_set_enabled(pio, state_machine, true);
+
+ WS2812_DMA_CHANNEL = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, RP_DMA_PRIORITY_WS2812, NULL, NULL);
+
+ // clang-format off
+ uint32_t mode = DMA_CTRL_TRIG_INCR_READ |
+ DMA_CTRL_TRIG_DATA_SIZE_WORD |
+ DMA_CTRL_TRIG_IRQ_QUIET |
+ DMA_CTRL_TRIG_TREQ_SEL(pio_idx == 0 ? state_machine : state_machine + 8);
+ // clang-format on
+
+ dmaChannelSetModeX(WS2812_DMA_CHANNEL, mode);
+ dmaChannelSetDestinationX(WS2812_DMA_CHANNEL, (uint32_t)&pio->txf[state_machine]);
+ return true;
+}
+
+/**
+ * @brief Convert RGBW value into WS2812 compatible 32-bit data word.
+ */
+__always_inline static uint32_t rgbw8888_to_u32(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
+#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
+ return ((uint32_t)green << 24) | ((uint32_t)red << 16) | ((uint32_t)blue << 8) | ((uint32_t)white);
+#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
+ return ((uint32_t)red << 24) | ((uint32_t)green << 16) | ((uint32_t)blue << 8) | ((uint32_t)white);
+#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
+ return ((uint32_t)blue << 24) | ((uint32_t)green << 16) | ((uint32_t)red << 8) | ((uint32_t)white);
+#endif
+}
+
+static inline void sync_ws2812_transfer(void) {
+ if (unlikely(dmaChannelIsBusyX(WS2812_DMA_CHANNEL) || !pio_sm_is_tx_fifo_empty(pio, state_machine))) {
+ fast_timer_t start = timer_read_fast();
+ do {
+ // Abort the synchronization if we have to wait longer than the total
+ // count of LEDs in millisecounds. This is safely much longer than it
+ // would take to push all the data out.
+ if (unlikely(timer_elapsed_fast(start) > RGBLED_NUM)) {
+ dprintln("ERROR: WS2812 DMA transfer has stalled, aborting!");
+ dmaChannelDisableX(WS2812_DMA_CHANNEL);
+ return;
+ }
+
+ } while (dmaChannelIsBusyX(WS2812_DMA_CHANNEL) || !pio_sm_is_tx_fifo_empty(pio, state_machine));
+ // We wait for the WS2812 chain to reset after all data has been pushed
+ // out.
+ wait_us(WS2812_TRST_US);
+ }
+}
+
+void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
+ static bool is_initialized = false;
+ if (unlikely(!is_initialized)) {
+ is_initialized = ws2812_init();
+ }
+
+ sync_ws2812_transfer();
+
+ for (int i = 0; i < leds; i++) {
+#if defined(RGBW)
+ WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w);
+#else
+ WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, 0);
+#endif
+ }
+
+ dmaChannelSetSourceX(WS2812_DMA_CHANNEL, (uint32_t)WS2812_BUFFER);
+ dmaChannelSetCounterX(WS2812_DMA_CHANNEL, leds);
+ dmaChannelEnableX(WS2812_DMA_CHANNEL);
+}
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c
new file mode 100644
index 0000000000..cdd1e26a7d
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl.c
@@ -0,0 +1,143 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <stdbool.h>
+#include <hal.h>
+#include "timer.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+
+static flash_offset_t base_offset = UINT32_MAX;
+
+#if defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+static flash_sector_t first_sector = WEAR_LEVELING_EFL_FIRST_SECTOR;
+#else // defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+static flash_sector_t first_sector = UINT16_MAX;
+#endif // defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+
+static flash_sector_t sector_count = UINT16_MAX;
+static BaseFlash * flash;
+
+#ifndef WEAR_LEVELING_EFL_FIRST_SECTOR
+// "Automatic" detection of the flash size -- ideally ChibiOS would have this already, but alas, it doesn't.
+static inline uint32_t detect_flash_size(void) {
+# if defined(WEAR_LEVELING_EFL_FLASH_SIZE)
+ return WEAR_LEVELING_EFL_FLASH_SIZE;
+# elif defined(FLASH_BANK_SIZE)
+ return FLASH_BANK_SIZE;
+# elif defined(FLASH_SIZE)
+ return FLASH_SIZE;
+# elif defined(FLASHSIZE_BASE)
+# if defined(QMK_MCU_SERIES_STM32F0XX) || defined(QMK_MCU_SERIES_STM32F1XX) || defined(QMK_MCU_SERIES_STM32F3XX) || defined(QMK_MCU_SERIES_STM32F4XX) || defined(QMK_MCU_SERIES_STM32G4XX) || defined(QMK_MCU_SERIES_STM32L0XX) || defined(QMK_MCU_SERIES_STM32L4XX) || defined(QMK_MCU_SERIES_GD32VF103)
+ return ((*(uint32_t *)FLASHSIZE_BASE) & 0xFFFFU) << 10U; // this register has the flash size in kB, so we convert it to bytes
+# elif defined(QMK_MCU_SERIES_STM32L1XX)
+# error This MCU family has an uncommon flash size register definition and has not been implemented. Perhaps try using the true EEPROM on the MCU instead?
+# endif
+# else
+# error Unknown flash size definition.
+ return 0;
+# endif
+}
+#endif // WEAR_LEVELING_EFL_FIRST_SECTOR
+
+bool backing_store_init(void) {
+ bs_dprintf("Init\n");
+ flash = (BaseFlash *)&EFLD1;
+
+ // Need to re-lock the EFL, as if we've just had the bootloader executing it'll already be unlocked.
+ backing_store_lock();
+
+ const flash_descriptor_t *desc = flashGetDescriptor(flash);
+ uint32_t counter = 0;
+
+#if defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+
+ // Work out how many sectors we want to use, working forwards from the first sector specified
+ for (flash_sector_t i = 0; i < desc->sectors_count - first_sector; ++i) {
+ counter += flashGetSectorSize(flash, first_sector + i);
+ if (counter >= (WEAR_LEVELING_BACKING_SIZE)) {
+ sector_count = i + 1;
+ base_offset = flashGetSectorOffset(flash, first_sector);
+ break;
+ }
+ }
+ if (sector_count == UINT16_MAX || base_offset >= flash_size) {
+ // We didn't get the required number of sectors. Can't do anything here. Fault.
+ chSysHalt("Invalid sector count intended to be used with wear_leveling");
+ }
+
+#else // defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+
+ // Work out how many sectors we want to use, working backwards from the end of the flash
+ uint32_t flash_size = detect_flash_size();
+ flash_sector_t last_sector = desc->sectors_count;
+ for (flash_sector_t i = 0; i < desc->sectors_count; ++i) {
+ first_sector = desc->sectors_count - i - 1;
+ if (flashGetSectorOffset(flash, first_sector) >= flash_size) {
+ last_sector = first_sector;
+ continue;
+ }
+ counter += flashGetSectorSize(flash, first_sector);
+ if (counter >= (WEAR_LEVELING_BACKING_SIZE)) {
+ sector_count = last_sector - first_sector;
+ base_offset = flashGetSectorOffset(flash, first_sector);
+ break;
+ }
+ }
+
+#endif // defined(WEAR_LEVELING_EFL_FIRST_SECTOR)
+
+ return true;
+}
+
+bool backing_store_unlock(void) {
+ bs_dprintf("Unlock\n");
+ return eflStart(&EFLD1, NULL) == HAL_RET_SUCCESS;
+}
+
+bool backing_store_erase(void) {
+#ifdef WEAR_LEVELING_DEBUG_OUTPUT
+ uint32_t start = timer_read32();
+#endif
+
+ bool ret = true;
+ flash_error_t status;
+ for (int i = 0; i < sector_count; ++i) {
+ // Kick off the sector erase
+ status = flashStartEraseSector(flash, first_sector + i);
+ if (status != FLASH_NO_ERROR && status != FLASH_BUSY_ERASING) {
+ ret = false;
+ }
+
+ // Wait for the erase to complete
+ status = flashWaitErase(flash);
+ if (status != FLASH_NO_ERROR && status != FLASH_BUSY_ERASING) {
+ ret = false;
+ }
+ }
+
+ bs_dprintf("Backing store erase took %ldms to complete\n", ((long)(timer_read32() - start)));
+ return ret;
+}
+
+bool backing_store_write(uint32_t address, backing_store_int_t value) {
+ uint32_t offset = (base_offset + address);
+ bs_dprintf("Write ");
+ wl_dump(offset, &value, sizeof(value));
+ value = ~value;
+ return flashProgram(flash, offset, sizeof(value), (const uint8_t *)&value) == FLASH_NO_ERROR;
+}
+
+bool backing_store_lock(void) {
+ bs_dprintf("Lock \n");
+ eflStop(&EFLD1);
+ return true;
+}
+
+bool backing_store_read(uint32_t address, backing_store_int_t *value) {
+ uint32_t offset = (base_offset + address);
+ backing_store_int_t *loc = (backing_store_int_t *)flashGetOffsetAddress(flash, offset);
+ *value = ~(*loc);
+ bs_dprintf("Read ");
+ wl_dump(offset, value, sizeof(backing_store_int_t));
+ return true;
+}
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_efl_config.h b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl_config.h
new file mode 100644
index 0000000000..9e38c2965d
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_efl_config.h
@@ -0,0 +1,50 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#ifndef __ASSEMBLER__
+# include <hal.h>
+#endif
+
+// Work out how many bytes per write to internal flash
+#ifndef BACKING_STORE_WRITE_SIZE
+// These need to match EFL's XXXXXX_FLASH_LINE_SIZE, see associated code in `lib/chibios/os/hal/ports/**/hal_efl_lld.c`,
+// or associated `stm32_registry.h` for the MCU in question (or equivalent for the family).
+# if defined(QMK_MCU_SERIES_GD32VF103)
+# define BACKING_STORE_WRITE_SIZE 2 // from hal_efl_lld.c
+# elif defined(QMK_MCU_FAMILY_NUC123)
+# define BACKING_STORE_WRITE_SIZE 4 // from hal_efl_lld.c
+# elif defined(QMK_MCU_FAMILY_STM32)
+# if defined(STM32_FLASH_LINE_SIZE) // from some family's stm32_registry.h file
+# define BACKING_STORE_WRITE_SIZE (STM32_FLASH_LINE_SIZE)
+# else
+# if defined(QMK_MCU_SERIES_STM32F1XX)
+# define BACKING_STORE_WRITE_SIZE 2 // from hal_efl_lld.c
+# elif defined(QMK_MCU_SERIES_STM32F3XX)
+# define BACKING_STORE_WRITE_SIZE 2 // from hal_efl_lld.c
+# elif defined(QMK_MCU_SERIES_STM32F4XX)
+# define BACKING_STORE_WRITE_SIZE (1 << STM32_FLASH_PSIZE) // from hal_efl_lld.c
+# elif defined(QMK_MCU_SERIES_STM32L4XX)
+# define BACKING_STORE_WRITE_SIZE 8 // from hal_efl_lld.c
+# elif defined(QMK_MCU_SERIES_STM32G0XX)
+# define BACKING_STORE_WRITE_SIZE 8 // from hal_efl_lld.c
+# elif defined(QMK_MCU_SERIES_STM32G4XX)
+# define BACKING_STORE_WRITE_SIZE 8 // from hal_efl_lld.c
+# else
+# error "ChibiOS hasn't defined STM32_FLASH_LINE_SIZE, and could not automatically determine BACKING_STORE_WRITE_SIZE" // normally defined in stm32_registry.h, should be set by STM32_FLASH_LINE_SIZE
+# endif
+# endif
+# else
+# error "Could not automatically determine BACKING_STORE_WRITE_SIZE"
+# endif
+#endif
+
+// 2kB backing space allocated
+#ifndef WEAR_LEVELING_BACKING_SIZE
+# define WEAR_LEVELING_BACKING_SIZE 2048
+#endif // WEAR_LEVELING_BACKING_SIZE
+
+// 1kB logical EEPROM
+#ifndef WEAR_LEVELING_LOGICAL_SIZE
+# define WEAR_LEVELING_LOGICAL_SIZE 1024
+#endif // WEAR_LEVELING_LOGICAL_SIZE
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy.c
new file mode 100644
index 0000000000..87126c4467
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy.c
@@ -0,0 +1,59 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <stdbool.h>
+#include <hal.h>
+#include "timer.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+#include "flash_stm32.h"
+
+bool backing_store_init(void) {
+ bs_dprintf("Init\n");
+ return true;
+}
+
+bool backing_store_unlock(void) {
+ bs_dprintf("Unlock\n");
+ FLASH_Unlock();
+ return true;
+}
+
+bool backing_store_erase(void) {
+#ifdef WEAR_LEVELING_DEBUG_OUTPUT
+ uint32_t start = timer_read32();
+#endif
+
+ bool ret = true;
+ FLASH_Status status;
+ for (int i = 0; i < (WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT); ++i) {
+ status = FLASH_ErasePage(WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS + (i * (WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE)));
+ if (status != FLASH_COMPLETE) {
+ ret = false;
+ }
+ }
+
+ bs_dprintf("Backing store erase took %ldms to complete\n", ((long)(timer_read32() - start)));
+ return ret;
+}
+
+bool backing_store_write(uint32_t address, backing_store_int_t value) {
+ uint32_t offset = ((WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS) + address);
+ bs_dprintf("Write ");
+ wl_dump(offset, &value, sizeof(backing_store_int_t));
+ return FLASH_ProgramHalfWord(offset, ~value) == FLASH_COMPLETE;
+}
+
+bool backing_store_lock(void) {
+ bs_dprintf("Lock \n");
+ FLASH_Lock();
+ return true;
+}
+
+bool backing_store_read(uint32_t address, backing_store_int_t* value) {
+ uint32_t offset = ((WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS) + address);
+ backing_store_int_t* loc = (backing_store_int_t*)offset;
+ *value = ~(*loc);
+ bs_dprintf("Read ");
+ wl_dump(offset, loc, sizeof(backing_store_int_t));
+ return true;
+}
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy_config.h b/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy_config.h
new file mode 100644
index 0000000000..1e4691a6c0
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_legacy_config.h
@@ -0,0 +1,67 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+// Work out the page size to use
+#ifndef WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE
+# if defined(QMK_MCU_STM32F042)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE 1024
+# elif defined(QMK_MCU_STM32F070) || defined(QMK_MCU_STM32F072)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE 2048
+# elif defined(QMK_MCU_STM32F401) || defined(QMK_MCU_STM32F411)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE 16384
+# endif
+#endif
+
+// Work out how much flash space we have
+#ifndef WEAR_LEVELING_LEGACY_EMULATION_FLASH_SIZE
+# define WEAR_LEVELING_LEGACY_EMULATION_FLASH_SIZE ((*(uint32_t *)FLASHSIZE_BASE) & 0xFFFFU) // in kB
+#endif
+
+// The base location of program memory
+#ifndef WEAR_LEVELING_LEGACY_EMULATION_FLASH_BASE
+# define WEAR_LEVELING_LEGACY_EMULATION_FLASH_BASE 0x08000000
+#endif
+
+// The number of pages to use
+#ifndef WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT
+# if defined(QMK_MCU_STM32F042)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT 2
+# elif defined(QMK_MCU_STM32F070) || defined(QMK_MCU_STM32F072)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT 1
+# elif defined(QMK_MCU_STM32F401) || defined(QMK_MCU_STM32F411)
+# define WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT 1
+# endif
+#endif
+
+// The origin of the emulated eeprom
+#ifndef WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS
+# if defined(QMK_MCU_STM32F042) || defined(QMK_MCU_STM32F070) || defined(QMK_MCU_STM32F072)
+# define WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS ((uintptr_t)(WEAR_LEVELING_LEGACY_EMULATION_FLASH_BASE) + WEAR_LEVELING_LEGACY_EMULATION_FLASH_SIZE * 1024 - (WEAR_LEVELING_LEGACY_EMULATION_PAGE_COUNT * WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE))
+# elif defined(QMK_MCU_STM32F401) || defined(QMK_MCU_STM32F411)
+# if defined(BOOTLOADER_STM32)
+# define WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS (WEAR_LEVELING_LEGACY_EMULATION_FLASH_BASE + (1 * (WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE))) // +16k
+# elif defined(BOOTLOADER_TINYUF2)
+# define WEAR_LEVELING_LEGACY_EMULATION_BASE_PAGE_ADDRESS (WEAR_LEVELING_LEGACY_EMULATION_FLASH_BASE + (3 * (WEAR_LEVELING_LEGACY_EMULATION_PAGE_SIZE))) // +48k
+# endif
+# endif
+#endif
+
+// 2-byte writes
+#ifndef BACKING_STORE_WRITE_SIZE
+# define BACKING_STORE_WRITE_SIZE 2
+#endif
+
+// The amount of space to use for the entire set of emulation
+#ifndef WEAR_LEVELING_BACKING_SIZE
+# if defined(QMK_MCU_STM32F042) || defined(QMK_MCU_STM32F070) || defined(QMK_MCU_STM32F072)
+# define WEAR_LEVELING_BACKING_SIZE 2048
+# elif defined(QMK_MCU_STM32F401) || defined(QMK_MCU_STM32F411)
+# define WEAR_LEVELING_BACKING_SIZE 16384
+# endif
+#endif
+
+// The logical amount of eeprom available
+#ifndef WEAR_LEVELING_LOGICAL_SIZE
+# define WEAR_LEVELING_LOGICAL_SIZE 1024
+#endif
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c
new file mode 100644
index 0000000000..640628e1e9
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ * Copyright (c) 2022 Nick Brassel (@tzarc)
+ * Copyright (c) 2022 Stefan Kerkmann (@KarlK90)
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "pico/bootrom.h"
+#include "hardware/flash.h"
+#include "hardware/sync.h"
+#include "hardware/structs/ssi.h"
+#include "hardware/structs/ioqspi.h"
+
+#include <stdbool.h>
+#include "timer.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+
+#ifndef WEAR_LEVELING_RP2040_FLASH_BULK_COUNT
+# define WEAR_LEVELING_RP2040_FLASH_BULK_COUNT 64
+#endif // WEAR_LEVELING_RP2040_FLASH_BULK_COUNT
+
+#define FLASHCMD_PAGE_PROGRAM 0x02
+#define FLASHCMD_READ_STATUS 0x05
+#define FLASHCMD_WRITE_ENABLE 0x06
+
+extern uint8_t BOOT2_ROM[256];
+static uint32_t BOOT2_ROM_RAM[64];
+
+static ssi_hw_t *const ssi = (ssi_hw_t *)XIP_SSI_BASE;
+
+// Sanity check
+check_hw_layout(ssi_hw_t, ssienr, SSI_SSIENR_OFFSET);
+check_hw_layout(ssi_hw_t, spi_ctrlr0, SSI_SPI_CTRLR0_OFFSET);
+
+static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void) {
+ ((void (*)(void))BOOT2_ROM_RAM + 1)();
+}
+
+// Bitbanging the chip select using IO overrides, in case RAM-resident IRQs
+// are still running, and the FIFO bottoms out. (the bootrom does the same)
+static void __no_inline_not_in_flash_func(flash_cs_force)(bool high) {
+ uint32_t field_val = high ? IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW;
+ hw_write_masked(&ioqspi_hw->io[1].ctrl, field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB, IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS);
+}
+
+// Also allow any unbounded loops to check whether the above abort condition
+// was asserted, and terminate early
+static int __no_inline_not_in_flash_func(flash_was_aborted)(void) {
+ return *(io_rw_32 *)(IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SD1_CTRL_OFFSET) & IO_QSPI_GPIO_QSPI_SD1_CTRL_INOVER_BITS;
+}
+
+// Put bytes from one buffer, and get bytes into another buffer.
+// These can be the same buffer.
+// If tx is NULL then send zeroes.
+// If rx is NULL then all read data will be dropped.
+//
+// If rx_skip is nonzero, this many bytes will first be consumed from the FIFO,
+// before reading a further count bytes into *rx.
+// E.g. if you have written a command+address just before calling this function.
+static void __no_inline_not_in_flash_func(flash_put_get)(const uint8_t *tx, uint8_t *rx, size_t count, size_t rx_skip) {
+ // Make sure there is never more data in flight than the depth of the RX
+ // FIFO. Otherwise, when we are interrupted for long periods, hardware
+ // will overflow the RX FIFO.
+ const uint max_in_flight = 16 - 2; // account for data internal to SSI
+ size_t tx_count = count;
+ size_t rx_count = count;
+ while (tx_count || rx_skip || rx_count) {
+ // NB order of reads, for pessimism rather than optimism
+ uint32_t tx_level = ssi_hw->txflr;
+ uint32_t rx_level = ssi_hw->rxflr;
+ bool did_something = false; // Expect this to be folded into control flow, not register
+ if (tx_count && tx_level + rx_level < max_in_flight) {
+ ssi->dr0 = (uint32_t)(tx ? *tx++ : 0);
+ --tx_count;
+ did_something = true;
+ }
+ if (rx_level) {
+ uint8_t rxbyte = ssi->dr0;
+ did_something = true;
+ if (rx_skip) {
+ --rx_skip;
+ } else {
+ if (rx) *rx++ = rxbyte;
+ --rx_count;
+ }
+ }
+ // APB load costs 4 cycles, so only do it on idle loops (our budget is
+ // 48 cyc/byte)
+ if (!did_something && __builtin_expect(flash_was_aborted(), 0)) break;
+ }
+ flash_cs_force(1);
+}
+
+// Convenience wrapper for above
+// (And it's hard for the debug host to get the tight timing between
+// cmd DR0 write and the remaining data)
+static void __no_inline_not_in_flash_func(_flash_do_cmd)(uint8_t cmd, const uint8_t *tx, uint8_t *rx, size_t count) {
+ flash_cs_force(0);
+ ssi->dr0 = cmd;
+ flash_put_get(tx, rx, count, 1);
+}
+
+// Timing of this one is critical, so do not expose the symbol to debugger etc
+static void __no_inline_not_in_flash_func(flash_put_cmd_addr)(uint8_t cmd, uint32_t addr) {
+ flash_cs_force(0);
+ addr |= cmd << 24;
+ for (int i = 0; i < 4; ++i) {
+ ssi->dr0 = addr >> 24;
+ addr <<= 8;
+ }
+}
+
+// Poll the flash status register until the busy bit (LSB) clears
+static void __no_inline_not_in_flash_func(flash_wait_ready)(void) {
+ uint8_t stat;
+ do {
+ _flash_do_cmd(FLASHCMD_READ_STATUS, NULL, &stat, 1);
+ } while (stat & 0x1 && !flash_was_aborted());
+}
+
+// Set the WEL bit (needed before any program/erase operation)
+static void __no_inline_not_in_flash_func(flash_enable_write)(void) {
+ _flash_do_cmd(FLASHCMD_WRITE_ENABLE, NULL, NULL, 0);
+}
+
+static void __no_inline_not_in_flash_func(pico_program_bulk)(uint32_t flash_address, backing_store_int_t *values, size_t item_count) {
+ rom_connect_internal_flash_fn connect_internal_flash = (rom_connect_internal_flash_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH);
+ rom_flash_exit_xip_fn flash_exit_xip = (rom_flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP);
+ rom_flash_flush_cache_fn flash_flush_cache = (rom_flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE);
+ assert(connect_internal_flash && flash_exit_xip && flash_flush_cache);
+
+ static backing_store_int_t bulk_write_buffer[WEAR_LEVELING_RP2040_FLASH_BULK_COUNT];
+
+ while (item_count) {
+ size_t batch_size = MIN(item_count, WEAR_LEVELING_RP2040_FLASH_BULK_COUNT);
+ for (size_t i = 0; i < batch_size; i++, values++, item_count--) {
+ bulk_write_buffer[i] = ~(*values);
+ }
+ __compiler_memory_barrier();
+
+ connect_internal_flash();
+ flash_exit_xip();
+ flash_enable_write();
+
+ flash_put_cmd_addr(FLASHCMD_PAGE_PROGRAM, flash_address);
+ flash_put_get((uint8_t *)bulk_write_buffer, NULL, batch_size * sizeof(backing_store_int_t), 4);
+ flash_wait_ready();
+ flash_address += batch_size * sizeof(backing_store_int_t);
+
+ flash_flush_cache();
+ flash_enable_xip_via_boot2();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// QMK Wear-Leveling Backing Store implementation
+
+static int interrupts;
+
+bool backing_store_init(void) {
+ bs_dprintf("Init\n");
+ memcpy(BOOT2_ROM_RAM, BOOT2_ROM, sizeof(BOOT2_ROM));
+ __compiler_memory_barrier();
+ return true;
+}
+
+bool backing_store_unlock(void) {
+ bs_dprintf("Unlock\n");
+ return true;
+}
+
+bool backing_store_erase(void) {
+#ifdef WEAR_LEVELING_DEBUG_OUTPUT
+ uint32_t start = timer_read32();
+#endif
+
+ // Ensure the backing size can be cleanly subtracted from the flash size without alignment issues.
+ _Static_assert((WEAR_LEVELING_BACKING_SIZE) % (FLASH_SECTOR_SIZE) == 0, "Backing size must be a multiple of FLASH_SECTOR_SIZE");
+
+ interrupts = save_and_disable_interrupts();
+ flash_range_erase((WEAR_LEVELING_RP2040_FLASH_BASE), (WEAR_LEVELING_BACKING_SIZE));
+ restore_interrupts(interrupts);
+
+ bs_dprintf("Backing store erase took %ldms to complete\n", ((long)(timer_read32() - start)));
+ return true;
+}
+
+bool backing_store_write(uint32_t address, backing_store_int_t value) {
+ return backing_store_write_bulk(address, &value, 1);
+}
+
+bool backing_store_write_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ uint32_t offset = (WEAR_LEVELING_RP2040_FLASH_BASE) + address;
+ bs_dprintf("Write ");
+ wl_dump(offset, values, sizeof(backing_store_int_t) * item_count);
+ interrupts = save_and_disable_interrupts();
+ pico_program_bulk(offset, values, item_count);
+ restore_interrupts(interrupts);
+ return true;
+}
+
+bool backing_store_lock(void) {
+ return true;
+}
+
+bool backing_store_read(uint32_t address, backing_store_int_t *value) {
+ return backing_store_read_bulk(address, value, 1);
+}
+
+bool backing_store_read_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ uint32_t offset = (WEAR_LEVELING_RP2040_FLASH_BASE) + address;
+ backing_store_int_t *loc = (backing_store_int_t *)((XIP_BASE) + offset);
+ for (size_t i = 0; i < item_count; ++i) {
+ values[i] = ~loc[i];
+ }
+ bs_dprintf("Read ");
+ wl_dump(offset, values, item_count * sizeof(backing_store_int_t));
+ return true;
+}
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash_config.h b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash_config.h
new file mode 100644
index 0000000000..93a9aa0372
--- /dev/null
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash_config.h
@@ -0,0 +1,32 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#ifndef __ASSEMBLER__
+# include "hardware/flash.h"
+#endif
+
+// 2-byte writes
+#ifndef BACKING_STORE_WRITE_SIZE
+# define BACKING_STORE_WRITE_SIZE 2
+#endif
+
+// 64kB backing space allocated
+#ifndef WEAR_LEVELING_BACKING_SIZE
+# define WEAR_LEVELING_BACKING_SIZE 8192
+#endif // WEAR_LEVELING_BACKING_SIZE
+
+// 32kB logical EEPROM
+#ifndef WEAR_LEVELING_LOGICAL_SIZE
+# define WEAR_LEVELING_LOGICAL_SIZE 4096
+#endif // WEAR_LEVELING_LOGICAL_SIZE
+
+// Define how much flash space we have (defaults to lib/pico-sdk/src/boards/include/boards/***)
+#ifndef WEAR_LEVELING_RP2040_FLASH_SIZE
+# define WEAR_LEVELING_RP2040_FLASH_SIZE (PICO_FLASH_SIZE_BYTES)
+#endif
+
+// Define the location of emulated EEPROM
+#ifndef WEAR_LEVELING_RP2040_FLASH_BASE
+# define WEAR_LEVELING_RP2040_FLASH_BASE ((WEAR_LEVELING_RP2040_FLASH_SIZE) - (WEAR_LEVELING_BACKING_SIZE))
+#endif
diff --git a/platforms/chibios/flash.mk b/platforms/chibios/flash.mk
index a91ef2cf35..790c4f3316 100644
--- a/platforms/chibios/flash.mk
+++ b/platforms/chibios/flash.mk
@@ -54,11 +54,11 @@ endef
# TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
# within the emulated eeprom via dfu-util or another tool
-ifneq (,$(filter $(MAKECMDGOALS),dfu-util-split-left))
+ifneq (,$(filter $(MAKECMDGOALS), dfu-util-split-left uf2-split-left))
OPT_DEFS += -DINIT_EE_HANDS_LEFT
endif
-ifneq (,$(filter $(MAKECMDGOALS),dfu-util-split-right))
+ifneq (,$(filter $(MAKECMDGOALS), dfu-util-split-right uf2-split-right))
OPT_DEFS += -DINIT_EE_HANDS_RIGHT
endif
@@ -66,6 +66,10 @@ dfu-util-split-left: dfu-util
dfu-util-split-right: dfu-util
+uf2-split-left: flash
+
+uf2-split-right: flash
+
ST_LINK_CLI ?= st-link_cli
ST_LINK_ARGS ?=
@@ -104,6 +108,8 @@ else ifeq ($(strip $(BOOTLOADER)),kiibohd)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL)
else ifeq ($(strip $(BOOTLOADER)),tinyuf2)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_UF2_UTIL_DEPLOY)
+else ifeq ($(strip $(BOOTLOADER)),rp2040)
+ $(UNSYNC_OUTPUT_CMD) && $(call EXEC_UF2_UTIL_DEPLOY)
else ifeq ($(strip $(MCU_FAMILY)),KINETIS)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_TEENSY)
else ifeq ($(strip $(MCU_FAMILY)),MIMXRT1062)
diff --git a/platforms/chibios/platform.mk b/platforms/chibios/platform.mk
index 21751f23fd..b2a8ec89e1 100644
--- a/platforms/chibios/platform.mk
+++ b/platforms/chibios/platform.mk
@@ -36,6 +36,7 @@ ifeq ($(strip $(MCU)), risc-v)
# RISC-V Support
# As of 7.4.2021 there is only one supported RISC-V platform in Chibios-Contrib,
# therefore all required settings are hard-coded
+ USE_CHIBIOS_CONTRIB = yes
STARTUP_MK = $(CHIBIOS_CONTRIB)/os/common/startup/RISCV-ECLIC/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
PORT_V = $(CHIBIOS_CONTRIB)/os/common/ports/RISCV-ECLIC/compilers/GCC/mk/port.mk
RULESPATH = $(CHIBIOS_CONTRIB)/os/common/startup/RISCV-ECLIC/compilers/GCC
@@ -87,12 +88,17 @@ ifeq ("$(MCU_PORT_NAME)","")
endif
ifeq ("$(wildcard $(PLATFORM_MK))","")
- PLATFORM_MK = $(CHIBIOS)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
+ PLATFORM_MK = $(CHIBIOS_CONTRIB)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
ifeq ("$(wildcard $(PLATFORM_MK))","")
- PLATFORM_MK = $(CHIBIOS_CONTRIB)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
+ PLATFORM_MK = $(CHIBIOS)/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)/$(PLATFORM_NAME).mk
endif
endif
+# If no MCU architecture specified, use the MCU instead (allows for mcu_selection.mk to swap to cortex-m0 etc.)
+ifeq ("$(MCU_ARCH)","")
+ MCU_ARCH = $(MCU)
+endif
+
include $(STARTUP_MK)
include $(PORT_V)
include $(PLATFORM_MK)
@@ -282,6 +288,17 @@ EXTRAINCDIRS += $(CHIBIOS)/os/license $(CHIBIOS)/os/oslib/include \
$(STREAMSINC) $(CHIBIOS)/os/various $(COMMON_VPATH)
#
+# QMK specific MCU family support selection.
+##############################################################################
+ifneq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_SERIES).mk)","")
+ # Either by MCU series e.g. STM32/STM32F1xx.mk or...
+ include $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_SERIES).mk
+else ifneq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_FAMILY).mk)","")
+ # By MCU family e.g. STM32/STM32.mk
+ include $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)/$(MCU_FAMILY).mk
+endif
+
+#
# ChibiOS-Contrib
##############################################################################
@@ -332,10 +349,14 @@ SHARED_CFLAGS = -fomit-frame-pointer \
-ffunction-sections \
-fdata-sections \
-fno-common \
- -fshort-wchar
+ -fshort-wchar \
+ -fno-builtin-printf
+
+LDSCRIPT_PATH := $(shell dirname "$(LDSCRIPT)")
# Shared Linker flags for all toolchains
SHARED_LDFLAGS = -T $(LDSCRIPT) \
+ -L $(LDSCRIPT_PATH) \
-Wl,--gc-sections \
-nostartfiles
diff --git a/platforms/chibios/vendors/RP/RP2040.mk b/platforms/chibios/vendors/RP/RP2040.mk
new file mode 100644
index 0000000000..de426c9c40
--- /dev/null
+++ b/platforms/chibios/vendors/RP/RP2040.mk
@@ -0,0 +1,287 @@
+#
+# Raspberry Pi RP2040 specific drivers
+##############################################################################
+COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/vendor/$(MCU_FAMILY)/$(MCU_SERIES)
+
+ifeq ($(strip $(WS2812_DRIVER)), vendor)
+ OPT_DEFS += -DRP_DMA_REQUIRED=TRUE
+endif
+
+#
+# Raspberry Pi Pico SDK Support
+##############################################################################
+ADEFS += -DCRT0_VTOR_INIT=1 \
+ -DCRT0_EXTRA_CORES_NUMBER=0
+
+CFLAGS += -DPICO_NO_FPGA_CHECK \
+ -DNDEBUG
+
+#
+# Pico SDK source and header files needed by QMK and ChibiOS
+##############################################################################
+PICOSDKROOT := $(TOP_DIR)/lib/pico-sdk
+
+PICOSDKSRC = $(PICOSDKROOT)/src/rp2_common/hardware_clocks/clocks.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_pll/pll.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_pio/pio.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_flash/flash.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_gpio/gpio.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_claim/claim.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_watchdog/watchdog.c \
+ $(PICOSDKROOT)/src/rp2_common/hardware_xosc/xosc.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_bootrom/bootrom.c
+
+PICOSDKINC = $(CHIBIOS)//os/various/pico_bindings/dumb/include \
+ $(PICOSDKROOT)/src/common/pico_base/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_platform/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_base/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_clocks/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_claim/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_flash/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_gpio/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_irq/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_pll/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_pio/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_sync/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_resets/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_watchdog/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_xosc/include \
+ $(PICOSDKROOT)/src/rp2040/hardware_regs/include \
+ $(PICOSDKROOT)/src/rp2040/hardware_structs/include \
+ $(PICOSDKROOT)/src/boards/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_bootrom/include
+
+PLATFORM_SRC += $(PICOSDKSRC)
+EXTRAINCDIRS += $(PICOSDKINC)
+
+PLATFORM_RP2040_PATH := $(PLATFORM_PATH)/$(PLATFORM_KEY)/vendors/$(MCU_FAMILY)
+
+PLATFORM_SRC += $(PLATFORM_RP2040_PATH)/stage2_bootloaders.c \
+ $(PLATFORM_RP2040_PATH)/pico_sdk_shims.c
+
+EXTRAINCDIRS += $(PLATFORM_RP2040_PATH)
+
+#
+# RP2040 optimized compiler intrinsics
+##############################################################################
+
+# Enables optimized Compiler intrinsics which are located in the RP2040
+# bootrom. This needs startup code and linker script support from ChibiOS,
+# which is WIP. Therefore disabled by default for now.
+RP2040_INTRINSICS_ENABLED ?= no
+ifeq ($(strip $(RP2040_INTRINSICS_ENABLED)), yes)
+ PICOSDKINTRINSICSSRC = $(PICOSDKROOT)/src/rp2_common/pico_float/float_aeabi.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_float/float_math.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_float/float_init_rom.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_float/float_v1_rom_shim.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_double/double_aeabi.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_double/double_math.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_double/double_init_rom.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_double/double_v1_rom_shim.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_divider/divider.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S \
+ $(PICOSDKROOT)/src/rp2_common/pico_malloc/pico_malloc.c \
+ $(PICOSDKROOT)/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S
+
+ PICOSDKINTRINSICSINC = $(PICOSDKROOT)/src/common/pico_base/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_platfrom/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_bootrom/include \
+ $(PICOSDKROOT)/src/rp2_common/hardware_divider/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_float/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_double/include \
+ $(PICOSDKROOT)/src/rp2_common/pico_malloc/include
+
+ OPT_DEFS += -DPICO_FLOAT_SUPPORT_ROM_V1=0 -DPICO_DOUBLE_SUPPORT_ROM_V1=0
+
+ CFLAGS += -Wl,--defsym=__StackLimit=__heap_end__
+ CFLAGS += -Wl,--defsym=__unhandled_user_irq=_unhandled_exception
+ CFLAGS += -Wl,--build-id=none
+
+ # single precision floating point intrinsics
+ OPT_DEFS += -DPICO_FLOAT_IN_RAM=1
+ OPT_DEFS += -DPICO_FLOAT_PROPAGATE_NANS=0
+
+ CFLAGS += -Wl,--wrap=__aeabi_fdiv
+ CFLAGS += -Wl,--wrap=__aeabi_fmul
+ CFLAGS += -Wl,--wrap=__aeabi_frsub
+ CFLAGS += -Wl,--wrap=__aeabi_fsub
+ CFLAGS += -Wl,--wrap=__aeabi_cfcmpeq
+ CFLAGS += -Wl,--wrap=__aeabi_cfrcmple
+ CFLAGS += -Wl,--wrap=__aeabi_cfcmple
+ CFLAGS += -Wl,--wrap=__aeabi_fcmpeq
+ CFLAGS += -Wl,--wrap=__aeabi_fcmplt
+ CFLAGS += -Wl,--wrap=__aeabi_fcmple
+ CFLAGS += -Wl,--wrap=__aeabi_fcmpge
+ CFLAGS += -Wl,--wrap=__aeabi_fcmpgt
+ CFLAGS += -Wl,--wrap=__aeabi_fcmpun
+ CFLAGS += -Wl,--wrap=__aeabi_i2f
+ CFLAGS += -Wl,--wrap=__aeabi_l2f
+ CFLAGS += -Wl,--wrap=__aeabi_ui2f
+ CFLAGS += -Wl,--wrap=__aeabi_ul2f
+ CFLAGS += -Wl,--wrap=__aeabi_i2f
+ CFLAGS += -Wl,--wrap=__aeabi_f2iz
+ CFLAGS += -Wl,--wrap=__aeabi_f2lz
+ CFLAGS += -Wl,--wrap=__aeabi_f2uiz
+ CFLAGS += -Wl,--wrap=__aeabi_f2ulz
+ CFLAGS += -Wl,--wrap=__aeabi_f2d
+ CFLAGS += -Wl,--wrap=sqrtf
+ CFLAGS += -Wl,--wrap=cosf
+ CFLAGS += -Wl,--wrap=sinf
+ CFLAGS += -Wl,--wrap=tanf
+ CFLAGS += -Wl,--wrap=atan2f
+ CFLAGS += -Wl,--wrap=expf
+ CFLAGS += -Wl,--wrap=logf
+ CFLAGS += -Wl,--wrap=ldexpf
+ CFLAGS += -Wl,--wrap=copysignf
+ CFLAGS += -Wl,--wrap=truncf
+ CFLAGS += -Wl,--wrap=floorf
+ CFLAGS += -Wl,--wrap=ceilf
+ CFLAGS += -Wl,--wrap=roundf
+ CFLAGS += -Wl,--wrap=sincosf
+ CFLAGS += -Wl,--wrap=asinf
+ CFLAGS += -Wl,--wrap=acosf
+ CFLAGS += -Wl,--wrap=atanf
+ CFLAGS += -Wl,--wrap=sinhf
+ CFLAGS += -Wl,--wrap=coshf
+ CFLAGS += -Wl,--wrap=tanhf
+ CFLAGS += -Wl,--wrap=asinhf
+ CFLAGS += -Wl,--wrap=acoshf
+ CFLAGS += -Wl,--wrap=atanhf
+ CFLAGS += -Wl,--wrap=exp2f
+ CFLAGS += -Wl,--wrap=log2f
+ CFLAGS += -Wl,--wrap=exp10f
+ CFLAGS += -Wl,--wrap=log10f
+ CFLAGS += -Wl,--wrap=powf
+ CFLAGS += -Wl,--wrap=powintf
+ CFLAGS += -Wl,--wrap=hypotf
+ CFLAGS += -Wl,--wrap=cbrtf
+ CFLAGS += -Wl,--wrap=fmodf
+ CFLAGS += -Wl,--wrap=dremf
+ CFLAGS += -Wl,--wrap=remainderf
+ CFLAGS += -Wl,--wrap=remquof
+ CFLAGS += -Wl,--wrap=expm1f
+ CFLAGS += -Wl,--wrap=log1pf
+ CFLAGS += -Wl,--wrap=fmaf
+
+ # double precision floating point intrinsics
+ OPT_DEFS += -DPICO_DOUBLE_IN_RAM=1
+ OPT_DEFS += -DPICO_DOUBLE_PROPAGATE_NANS=0
+
+ CFLAGS += -Wl,--wrap=__aeabi_dadd
+ CFLAGS += -Wl,--wrap=__aeabi_ddiv
+ CFLAGS += -Wl,--wrap=__aeabi_dmul
+ CFLAGS += -Wl,--wrap=__aeabi_drsub
+ CFLAGS += -Wl,--wrap=__aeabi_dsub
+ CFLAGS += -Wl,--wrap=__aeabi_cdcmpeq
+ CFLAGS += -Wl,--wrap=__aeabi_cdrcmple
+ CFLAGS += -Wl,--wrap=__aeabi_cdcmple
+ CFLAGS += -Wl,--wrap=__aeabi_dcmpeq
+ CFLAGS += -Wl,--wrap=__aeabi_dcmplt
+ CFLAGS += -Wl,--wrap=__aeabi_dcmple
+ CFLAGS += -Wl,--wrap=__aeabi_dcmpge
+ CFLAGS += -Wl,--wrap=__aeabi_dcmpgt
+ CFLAGS += -Wl,--wrap=__aeabi_dcmpun
+ CFLAGS += -Wl,--wrap=__aeabi_i2d
+ CFLAGS += -Wl,--wrap=__aeabi_l2d
+ CFLAGS += -Wl,--wrap=__aeabi_ui2d
+ CFLAGS += -Wl,--wrap=__aeabi_ul2d
+ CFLAGS += -Wl,--wrap=__aeabi_d2iz
+ CFLAGS += -Wl,--wrap=__aeabi_d2lz
+ CFLAGS += -Wl,--wrap=__aeabi_d2uiz
+ CFLAGS += -Wl,--wrap=__aeabi_d2ulz
+ CFLAGS += -Wl,--wrap=__aeabi_d2f
+ CFLAGS += -Wl,--wrap=sqrt
+ CFLAGS += -Wl,--wrap=cos
+ CFLAGS += -Wl,--wrap=sin
+ CFLAGS += -Wl,--wrap=tan
+ CFLAGS += -Wl,--wrap=atan2
+ CFLAGS += -Wl,--wrap=exp
+ CFLAGS += -Wl,--wrap=log
+ CFLAGS += -Wl,--wrap=ldexp
+ CFLAGS += -Wl,--wrap=copysign
+ CFLAGS += -Wl,--wrap=trunc
+ CFLAGS += -Wl,--wrap=floor
+ CFLAGS += -Wl,--wrap=ceil
+ CFLAGS += -Wl,--wrap=round
+ CFLAGS += -Wl,--wrap=sincos
+ CFLAGS += -Wl,--wrap=asin
+ CFLAGS += -Wl,--wrap=acos
+ CFLAGS += -Wl,--wrap=atan
+ CFLAGS += -Wl,--wrap=sinh
+ CFLAGS += -Wl,--wrap=cosh
+ CFLAGS += -Wl,--wrap=tanh
+ CFLAGS += -Wl,--wrap=asinh
+ CFLAGS += -Wl,--wrap=acosh
+ CFLAGS += -Wl,--wrap=atanh
+ CFLAGS += -Wl,--wrap=exp2
+ CFLAGS += -Wl,--wrap=log2
+ CFLAGS += -Wl,--wrap=exp10
+ CFLAGS += -Wl,--wrap=log10
+ CFLAGS += -Wl,--wrap=pow
+ CFLAGS += -Wl,--wrap=powint
+ CFLAGS += -Wl,--wrap=hypot
+ CFLAGS += -Wl,--wrap=cbrt
+ CFLAGS += -Wl,--wrap=fmod
+ CFLAGS += -Wl,--wrap=drem
+ CFLAGS += -Wl,--wrap=remainder
+ CFLAGS += -Wl,--wrap=remquo
+ CFLAGS += -Wl,--wrap=expm1
+ CFLAGS += -Wl,--wrap=log1p
+ CFLAGS += -Wl,--wrap=fma
+
+ # bit operation intrinsics
+ OPT_DEFS += -DPICO_BITS_IN_RAM=1
+
+ CFLAGS += -Wl,--wrap=__clzsi2
+ CFLAGS += -Wl,--wrap=__clzsi2
+ CFLAGS += -Wl,--wrap=__clzdi2
+ CFLAGS += -Wl,--wrap=__ctzsi2
+ CFLAGS += -Wl,--wrap=__ctzdi2
+ CFLAGS += -Wl,--wrap=__popcountsi2
+ CFLAGS += -Wl,--wrap=__popcountdi2
+ CFLAGS += -Wl,--wrap=__clz
+ CFLAGS += -Wl,--wrap=__clzl
+ CFLAGS += -Wl,--wrap=__clzsi2
+ CFLAGS += -Wl,--wrap=__clzll
+
+ # integer division intrinsics
+ OPT_DEFS += -DPICO_DIVIDER_IN_RAM=1
+ OPT_DEFS += -DPICO_DIVIDER_DISABLE_INTERRUPTS=1
+
+ CFLAGS += -Wl,--wrap=__aeabi_idiv
+ CFLAGS += -Wl,--wrap=__aeabi_idivmod
+ CFLAGS += -Wl,--wrap=__aeabi_ldivmod
+ CFLAGS += -Wl,--wrap=__aeabi_uidiv
+ CFLAGS += -Wl,--wrap=__aeabi_uidivmod
+ CFLAGS += -Wl,--wrap=__aeabi_uldivmod
+
+ # 64bit integer intrinsics
+ OPT_DEFS += -DPICO_INT64_OPS_IN_RAM=1
+
+ CFLAGS += -Wl,--wrap=__aeabi_lmul
+
+ # malloc and friends functions
+ OPT_DEFS += -DPICO_USE_MALLOC_MUTEX=0
+ OPT_DEFS += -DPICO_DEBUG_MALLOC=0
+ OPT_DEFS ?= -DPICO_MALLOC_PANIC=0
+
+ CFLAGS += -Wl,--wrap=malloc
+ CFLAGS += -Wl,--wrap=calloc
+ CFLAGS += -Wl,--wrap=free
+
+ # memory operation intrinsics
+ OPT_DEFS += -DPICO_MEM_IN_RAM=1
+
+ CFLAGS += -Wl,--wrap=memcpy
+ CFLAGS += -Wl,--wrap=memset
+ CFLAGS += -Wl,--wrap=__aeabi_memcpy
+ CFLAGS += -Wl,--wrap=__aeabi_memset
+ CFLAGS += -Wl,--wrap=__aeabi_memcpy4
+ CFLAGS += -Wl,--wrap=__aeabi_memset4
+ CFLAGS += -Wl,--wrap=__aeabi_memcpy8
+ CFLAGS += -Wl,--wrap=__aeabi_memset8
+
+ PLATFORM_SRC += $(PICOSDKINTRINSICSSRC)
+ EXTRAINCDIRS += $(PICOSDKINTRINSICSINC)
+endif
diff --git a/platforms/chibios/vendors/RP/_pin_defs.h b/platforms/chibios/vendors/RP/_pin_defs.h
new file mode 100644
index 0000000000..4241845369
--- /dev/null
+++ b/platforms/chibios/vendors/RP/_pin_defs.h
@@ -0,0 +1,37 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+/* RP2040 GPIO Numbering */
+#define GP0 0U
+#define GP1 1U
+#define GP2 2U
+#define GP3 3U
+#define GP4 4U
+#define GP5 5U
+#define GP6 6U
+#define GP7 7U
+#define GP8 8U
+#define GP9 9U
+#define GP10 10U
+#define GP11 11U
+#define GP12 12U
+#define GP13 13U
+#define GP14 14U
+#define GP15 15U
+#define GP16 16U
+#define GP17 17U
+#define GP18 18U
+#define GP19 19U
+#define GP20 20U
+#define GP21 21U
+#define GP22 22U
+#define GP23 23U
+#define GP24 24U
+#define GP25 25U
+#define GP26 26U
+#define GP27 27U
+#define GP28 28U
+#define GP29 29U
+#define GP30 30U
diff --git a/platforms/chibios/vendors/RP/pico_sdk_shims.c b/platforms/chibios/vendors/RP/pico_sdk_shims.c
new file mode 100644
index 0000000000..239155c086
--- /dev/null
+++ b/platforms/chibios/vendors/RP/pico_sdk_shims.c
@@ -0,0 +1,13 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <stdbool.h>
+#include <ch.h>
+
+void panic(const char *fmt, ...) {
+ chSysHalt(fmt);
+}
+
+void hard_assertion_failure(void) {
+ panic("hard assert");
+}
diff --git a/platforms/chibios/vendors/RP/stage2_bootloaders.c b/platforms/chibios/vendors/RP/stage2_bootloaders.c
new file mode 100644
index 0000000000..e65b0a5802
--- /dev/null
+++ b/platforms/chibios/vendors/RP/stage2_bootloaders.c
@@ -0,0 +1,178 @@
+// ----------------------------------------------------------------------------
+// Pre-compiled second stage boot code for RP2040.
+//
+// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
+// SPDX-License-Identifier: BSD-3-Clause
+// ----------------------------------------------------------------------------
+
+#include <stdint.h>
+
+#define BOOTLOADER_SECTION __attribute__((used, section(".boot2")))
+
+// clang-format off
+
+#if defined(RP2040_FLASH_AT25SF128A)
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x31, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
+ 0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2d, 0x4b,
+ 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
+ 0x99, 0x50, 0x2a, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
+ 0x00, 0xf0, 0x42, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21,
+ 0x19, 0x66, 0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x31, 0x21, 0x19, 0x66,
+ 0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e,
+ 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1,
+ 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60,
+ 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21,
+ 0x19, 0x66, 0x20, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21,
+ 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
+ 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49,
+ 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5,
+ 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42,
+ 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7,
+ 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00,
+ 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0x20,
+ 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0xdd, 0xc0, 0xb5
+};
+
+#elif defined(RP2040_FLASH_GD25Q64CS)
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x31, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
+ 0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2d, 0x4b,
+ 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
+ 0x99, 0x50, 0x2a, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
+ 0x00, 0xf0, 0x42, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21,
+ 0x19, 0x66, 0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x31, 0x21, 0x19, 0x66,
+ 0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e,
+ 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1,
+ 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60,
+ 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xe7, 0x21,
+ 0x19, 0x66, 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21,
+ 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
+ 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x12, 0x48, 0x13, 0x49,
+ 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5,
+ 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42,
+ 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7,
+ 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x02, 0x40,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00,
+ 0x21, 0x12, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x10, 0x00, 0xa0,
+ 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe2, 0xd9, 0xa2, 0xb5
+};
+
+#elif defined(RP2040_FLASH_W25X10CL)
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x14, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
+ 0x12, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60, 0x11, 0x49, 0x12, 0x48,
+ 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xbb, 0x21, 0x19, 0x66, 0x02, 0x21,
+ 0x19, 0x66, 0x08, 0x21, 0x98, 0x6a, 0x08, 0x42, 0xfc, 0xd0, 0x00, 0x21,
+ 0x99, 0x60, 0x0c, 0x49, 0x0a, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60,
+ 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x08, 0x48, 0x09, 0x49,
+ 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x3f, 0x00, 0x1d, 0x12, 0x00, 0x00,
+ 0xf4, 0x00, 0x00, 0x18, 0x1e, 0x10, 0x00, 0x20, 0x00, 0x01, 0x00, 0x10,
+ 0x08, 0xed, 0x00, 0xe0, 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,
+ 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,
+ 0x7c, 0x81, 0x53, 0x9a
+};
+
+#elif defined(RP2040_FLASH_IS25LP080)
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x2b, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
+ 0x29, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x28, 0x48, 0x00, 0xf0,
+ 0x42, 0xf8, 0x28, 0x4a, 0x90, 0x42, 0x12, 0xd0, 0x06, 0x21, 0x19, 0x66,
+ 0x00, 0xf0, 0x32, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20,
+ 0x1a, 0x66, 0x00, 0xf0, 0x2b, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x1f, 0x48,
+ 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21,
+ 0x99, 0x60, 0x1d, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60, 0x1c, 0x49,
+ 0x1c, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66,
+ 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60,
+ 0x17, 0x49, 0x16, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc,
+ 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, 0x14, 0x48, 0x14, 0x49, 0x08, 0x60,
+ 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a,
+ 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1,
+ 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff,
+ 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x07, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18,
+ 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0,
+ 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,
+ 0x28, 0x33, 0x43, 0xb2
+};
+
+#elif defined(RP2040_FLASH_GENERIC_03H)
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x0c, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61,
+ 0x0a, 0x49, 0x19, 0x60, 0x0a, 0x49, 0x0b, 0x48, 0x01, 0x60, 0x00, 0x21,
+ 0x59, 0x60, 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0,
+ 0x00, 0x47, 0x07, 0x48, 0x07, 0x49, 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3,
+ 0x08, 0x88, 0x08, 0x47, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x1f, 0x00,
+ 0x18, 0x02, 0x00, 0x03, 0xf4, 0x00, 0x00, 0x18, 0x00, 0x01, 0x00, 0x10,
+ 0x08, 0xed, 0x00, 0xe0, 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,
+ 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,
+ 0x2c, 0xec, 0x21, 0x0d
+};
+
+#else
+
+uint8_t BOOTLOADER_SECTION BOOT2_ROM[256] = {
+ 0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
+ 0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b,
+ 0x00, 0x21, 0x99, 0x60, 0x04, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22,
+ 0x99, 0x50, 0x2b, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20,
+ 0x00, 0xf0, 0x44, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21,
+ 0x19, 0x66, 0x00, 0xf0, 0x34, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66,
+ 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e,
+ 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21,
+ 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60,
+ 0x00, 0x21, 0x59, 0x60, 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21,
+ 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0,
+ 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60,
+ 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47,
+ 0x12, 0x48, 0x13, 0x49, 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88,
+ 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0,
+ 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66,
+ 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd,
+ 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18,
+ 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x0b, 0x8f, 0xd5
+};
+
+#endif
+
+// clang-format on
diff --git a/platforms/eeprom.h b/platforms/eeprom.h
index 091e6e4400..8cb7e342dc 100644
--- a/platforms/eeprom.h
+++ b/platforms/eeprom.h
@@ -27,6 +27,8 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n);
# error EEPROM_SIZE has not been defined for custom driver.
# endif
# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE)
+#elif defined(EEPROM_WEAR_LEVELING)
+# define TOTAL_EEPROM_BYTE_COUNT (WEAR_LEVELING_LOGICAL_SIZE)
#elif defined(EEPROM_TRANSIENT)
# include "eeprom_transient.h"
# define TOTAL_EEPROM_BYTE_COUNT (TRANSIENT_EEPROM_SIZE)
diff --git a/platforms/synchronization_util.h b/platforms/synchronization_util.h
index 3730f271db..59933945c3 100644
--- a/platforms/synchronization_util.h
+++ b/platforms/synchronization_util.h
@@ -9,6 +9,40 @@ void split_shared_memory_lock(void);
void split_shared_memory_unlock(void);
# endif
#else
+# if defined(SPLIT_KEYBOARD)
inline void split_shared_memory_lock(void){};
inline void split_shared_memory_unlock(void){};
+# endif
+#endif
+
+/* GCCs cleanup attribute expects a function with one parameter, which is a
+ * pointer to a type compatible with the variable. As we don't want to expose
+ * the platforms internal mutex type this workaround with auto generated adapter
+ * function is defined */
+#define QMK_DECLARE_AUTOUNLOCK_HELPERS(prefix) \
+ inline unsigned prefix##_autounlock_lock_helper(void) { \
+ prefix##_lock(); \
+ return 0; \
+ } \
+ \
+ inline void prefix##_autounlock_unlock_helper(unsigned* unused_guard) { \
+ prefix##_unlock(); \
+ }
+
+/* Convinience macro the automatically generate the correct RAII-style
+ * lock_autounlock function macro */
+#define QMK_DECLARE_AUTOUNLOCK_CALL(prefix) unsigned prefix##_guard __attribute__((unused, cleanup(prefix##_autounlock_unlock_helper))) = prefix##_autounlock_lock_helper
+
+#if defined(SPLIT_KEYBOARD)
+QMK_DECLARE_AUTOUNLOCK_HELPERS(split_shared_memory)
+
+/**
+ * @brief Acquire exclusive access to the split keyboard shared memory, by
+ * calling the platforms `split_shared_memory_lock()` function. The lock is
+ * automatically released by calling the platforms `split_shared_memory_unlock()`
+ * function. This happens when the block where
+ * `split_shared_memory_lock_autounlock()` is called in goes out of scope i.e.
+ * when the enclosing function returns.
+ */
+# define split_shared_memory_lock_autounlock QMK_DECLARE_AUTOUNLOCK_CALL(split_shared_memory)
#endif
diff --git a/platforms/test/platform.mk b/platforms/test/platform.mk
index eb2424ec5c..f07c863e69 100644
--- a/platforms/test/platform.mk
+++ b/platforms/test/platform.mk
@@ -31,4 +31,4 @@ CFLAGS += -fno-strict-aliasing
CXXFLAGS += $(COMPILEFLAGS)
CXXFLAGS += -fno-exceptions
-CXXFLAGS += -std=gnu++11
+CXXFLAGS += $(CXXSTANDARD)
diff --git a/platforms/test/rules.mk b/platforms/test/rules.mk
index 55512c7392..a2baa283d0 100644
--- a/platforms/test/rules.mk
+++ b/platforms/test/rules.mk
@@ -11,7 +11,8 @@ eeprom_stm32_large_DEFS := $(eeprom_stm32_DEFS) \
-DFEE_PAGE_COUNT=16
eeprom_stm32_INC := \
- $(PLATFORM_PATH)/chibios/
+ $(PLATFORM_PATH)/chibios/drivers/eeprom/ \
+ $(PLATFORM_PATH)/chibios/drivers/flash/
eeprom_stm32_tiny_INC := $(eeprom_stm32_INC)
eeprom_stm32_large_INC := $(eeprom_stm32_INC)
@@ -19,6 +20,6 @@ eeprom_stm32_SRC := \
$(TOP_DIR)/drivers/eeprom/eeprom_driver.c \
$(PLATFORM_PATH)/$(PLATFORM_KEY)/eeprom_stm32_tests.cpp \
$(PLATFORM_PATH)/$(PLATFORM_KEY)/flash_stm32_mock.c \
- $(PLATFORM_PATH)/chibios/eeprom_stm32.c
+ $(PLATFORM_PATH)/chibios/drivers/eeprom/eeprom_stm32.c
eeprom_stm32_tiny_SRC := $(eeprom_stm32_SRC)
eeprom_stm32_large_SRC := $(eeprom_stm32_SRC)
diff --git a/quantum/action.c b/quantum/action.c
index 4e81a5466f..83f6e2a970 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -844,7 +844,7 @@ __attribute__((weak)) void register_code(uint8_t code) {
# endif
add_key(KC_CAPS_LOCK);
send_keyboard_report();
- wait_ms(100);
+ wait_ms(TAP_HOLD_CAPS_DELAY);
del_key(KC_CAPS_LOCK);
send_keyboard_report();
}
diff --git a/quantum/action_layer.h b/quantum/action_layer.h
index b87d096eed..bd1085a70f 100644
--- a/quantum/action_layer.h
+++ b/quantum/action_layer.h
@@ -41,7 +41,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT)
-# define LAYER_STATE_32BIT
+# define LAYER_STATE_16BIT
#endif
#if defined(LAYER_STATE_8BIT)
diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c
index 3c8b5678b7..df3317ac05 100644
--- a/quantum/action_tapping.c
+++ b/quantum/action_tapping.c
@@ -125,7 +125,7 @@ void action_tapping_process(keyrecord_t record) {
/* return true when key event is processed or consumed. */
bool process_tapping(keyrecord_t *keyp) {
keyevent_t event = keyp->event;
-# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(TAPPING_TERM_PER_KEY) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
+# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
uint16_t tapping_keycode = get_record_keycode(&tapping_key, false);
# endif
@@ -164,17 +164,15 @@ bool process_tapping(keyrecord_t *keyp) {
* useful for long TAPPING_TERM but may prevent fast typing.
*/
// clang-format off
-# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
+# if defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
else if (
(
- (
- GET_TAPPING_TERM(tapping_keycode, &tapping_key) >= 500
+ IS_RELEASED(event) && waiting_buffer_typed(event)
# ifdef PERMISSIVE_HOLD_PER_KEY
- || get_permissive_hold(tapping_keycode, &tapping_key)
+ && get_permissive_hold(tapping_keycode, &tapping_key)
# elif defined(PERMISSIVE_HOLD)
- || true
+ && true
# endif
- ) && IS_RELEASED(event) && waiting_buffer_typed(event)
)
// Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
// unnecessarily and fixes them for Layer Taps.
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index 3e425abb47..ff22e6fe95 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -144,6 +144,12 @@
*/
#define USSR_ANTHEM B__NOTE(_G6), B__NOTE(_C7), W__NOTE(_G6), H__NOTE(_A6), B__NOTE(_B6), W__NOTE(_E6), W__NOTE(_E6), B__NOTE(_A6), W__NOTE(_G6), H__NOTE(_F6), B__NOTE(_G6), W__NOTE(_C6), W__NOTE(_C6), B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_E6), B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_G6), B__NOTE(_F6), W__NOTE(_G6), W__NOTE(_A6), B__NOTE(_B6),
+/* Title: Hymn Risen
+ * Author/Composer: Terrance Andrew Davis
+ * License: Public Domain
+ */
+#define TOS_HYMN_RISEN H__NOTE(_D5), H__NOTE(_E5), HD_NOTE(_F5), HD_NOTE(_F5), H__NOTE(_F5), HD_NOTE(_D5), E__NOTE(_E5), E__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_D5), Q__NOTE(_D5), H__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_G5), Q__NOTE(_F5), H__NOTE(_D5), H__NOTE(_E5), HD_NOTE(_F5), HD_NOTE(_F5), H__NOTE(_F5), HD_NOTE(_D5), E__NOTE(_E5), E__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_D5), Q__NOTE(_D5), H__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_G5), Q__NOTE(_F5), H__NOTE(_D5), H__NOTE(_C5), W__NOTE(_D5), W__NOTE(_E5), Q__NOTE(_A4), H__NOTE(_A4), Q__NOTE(_E5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_D5), Q__NOTE(_G5), Q__NOTE(_B4), Q__NOTE(_D5), Q__NOTE(_C5), M__NOTE(_F5, 80), H__NOTE(_D5), H__NOTE(_C5), W__NOTE(_D5), W__NOTE(_E5), Q__NOTE(_A4), H__NOTE(_A4), Q__NOTE(_E5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_D5), Q__NOTE(_G5), Q__NOTE(_B4), Q__NOTE(_D5), Q__NOTE(_C5), M__NOTE(_F5, 80)
+
/* Removed sounds
+ This list is here solely for compatibility, so that removed songs don't just break things
* If you think that any of these songs were wrongfully removed, let us know and provide
diff --git a/quantum/command.c b/quantum/command.c
index f90d73207c..84757b9b01 100644
--- a/quantum/command.c
+++ b/quantum/command.c
@@ -161,7 +161,7 @@ static void command_common_help(void) {
}
static void print_version(void) {
- print(/* clang-format off */
+ xprintf("%s", /* clang-format off */
"\n\t- Version -\n"
"VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
@@ -282,6 +282,7 @@ static void print_eeconfig(void) {
".swap_grave_esc: %u\n"
".swap_backslash_backspace: %u\n"
".nkro: %u\n"
+ ".swap_escape_capslock: %u\n"
, kc.raw
, kc.swap_control_capslock
@@ -294,6 +295,7 @@ static void print_eeconfig(void) {
, kc.swap_grave_esc
, kc.swap_backslash_backspace
, kc.nkro
+ , kc.swap_escape_capslock
); /* clang-format on */
# ifdef BACKLIGHT_ENABLE
diff --git a/quantum/debounce.h b/quantum/debounce.h
index 3532d9cd7b..a8629654c2 100644
--- a/quantum/debounce.h
+++ b/quantum/debounce.h
@@ -1,10 +1,16 @@
#pragma once
-// raw is the current key state
-// on entry cooked is the previous debounced state
-// on exit cooked is the current debounced state
-// changed is true if raw has changed since the last call
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed);
+/**
+ * @brief Debounce raw matrix events according to the choosen debounce algorithm.
+ *
+ * @param raw The current key state
+ * @param cooked The debounced key state
+ * @param num_rows Number of rows to debounce
+ * @param changed True if raw has changed since the last call
+ * @return true Cooked has new keychanges after debouncing
+ * @return false Cooked is the same as before
+ */
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed);
void debounce_init(uint8_t num_rows);
diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c
index b1eb4a2b7b..4745c6f465 100644
--- a/quantum/debounce/asym_eager_defer_pk.c
+++ b/quantum/debounce/asym_eager_defer_pk.c
@@ -55,6 +55,7 @@ static debounce_counter_t *debounce_counters;
static fast_timer_t last_time;
static bool counters_need_update;
static bool matrix_need_update;
+static bool cooked_changed;
# define DEBOUNCE_ELAPSED 0
@@ -77,8 +78,9 @@ void debounce_free(void) {
debounce_counters = NULL;
}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
bool updated_last = false;
+ cooked_changed = false;
if (counters_need_update) {
fast_timer_t now = timer_read_fast();
@@ -102,6 +104,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
transfer_matrix_values(raw, cooked, num_rows);
}
+
+ return cooked_changed;
}
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) {
@@ -123,7 +127,9 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[],
matrix_need_update = true;
} else {
// key-up: defer
- cooked[row] = (cooked[row] & ~col_mask) | (raw[row] & col_mask);
+ matrix_row_t cooked_next = (cooked[row] & ~col_mask) | (raw[row] & col_mask);
+ cooked_changed |= cooked_next ^ cooked[row];
+ cooked[row] = cooked_next;
}
} else {
debounce_pointer->time -= elapsed_time;
@@ -152,6 +158,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui
if (debounce_pointer->pressed) {
// key-down: eager
cooked[row] ^= col_mask;
+ cooked_changed = true;
}
}
} else if (debounce_pointer->time != DEBOUNCE_ELAPSED) {
diff --git a/quantum/debounce/none.c b/quantum/debounce/none.c
index 8a85cc04a8..4cff5e05e2 100644
--- a/quantum/debounce/none.c
+++ b/quantum/debounce/none.c
@@ -17,13 +17,16 @@
#include "matrix.h"
#include "quantum.h"
#include <stdlib.h>
+#include <string.h>
void debounce_init(uint8_t num_rows) {}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- for (int i = 0; i < num_rows; i++) {
- cooked[i] = raw[i];
- }
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ bool cooked_changed = memcmp(raw, cooked, sizeof(matrix_row_t) * num_rows) != 0;
+
+ memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows);
+
+ return cooked_changed;
}
void debounce_free(void) {}
diff --git a/quantum/debounce/sym_defer_g.c b/quantum/debounce/sym_defer_g.c
index 47450992a4..d04310a761 100644
--- a/quantum/debounce/sym_defer_g.c
+++ b/quantum/debounce/sym_defer_g.c
@@ -20,6 +20,7 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.
#include "matrix.h"
#include "timer.h"
#include "quantum.h"
+#include <string.h>
#ifndef DEBOUNCE
# define DEBOUNCE 5
#endif
@@ -30,18 +31,23 @@ static fast_timer_t debouncing_time;
void debounce_init(uint8_t num_rows) {}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ bool cooked_changed = false;
+
if (changed) {
debouncing = true;
debouncing_time = timer_read_fast();
}
if (debouncing && timer_elapsed_fast(debouncing_time) >= DEBOUNCE) {
- for (int i = 0; i < num_rows; i++) {
- cooked[i] = raw[i];
+ if (memcmp(cooked, raw, sizeof(matrix_row_t) * num_rows) != 0) {
+ memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows);
+ cooked_changed = true;
}
debouncing = false;
}
+
+ return cooked_changed;
}
void debounce_free(void) {}
diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c
index 9dee29e28e..7b59b5e100 100644
--- a/quantum/debounce/sym_defer_pk.c
+++ b/quantum/debounce/sym_defer_pk.c
@@ -48,6 +48,7 @@ typedef uint8_t debounce_counter_t;
static debounce_counter_t *debounce_counters;
static fast_timer_t last_time;
static bool counters_need_update;
+static bool cooked_changed;
# define DEBOUNCE_ELAPSED 0
@@ -70,8 +71,9 @@ void debounce_free(void) {
debounce_counters = NULL;
}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
bool updated_last = false;
+ cooked_changed = false;
if (counters_need_update) {
fast_timer_t now = timer_read_fast();
@@ -95,6 +97,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
start_debounce_counters(raw, cooked, num_rows);
}
+
+ return cooked_changed;
}
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) {
@@ -104,8 +108,10 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[],
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (*debounce_pointer != DEBOUNCE_ELAPSED) {
if (*debounce_pointer <= elapsed_time) {
- *debounce_pointer = DEBOUNCE_ELAPSED;
- cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col));
+ *debounce_pointer = DEBOUNCE_ELAPSED;
+ matrix_row_t cooked_next = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col));
+ cooked_changed |= cooked[row] ^ cooked_next;
+ cooked[row] = cooked_next;
} else {
*debounce_pointer -= elapsed_time;
counters_need_update = true;
diff --git a/quantum/debounce/sym_defer_pr.c b/quantum/debounce/sym_defer_pr.c
index ce24f0922f..452c4599d0 100644
--- a/quantum/debounce/sym_defer_pr.c
+++ b/quantum/debounce/sym_defer_pr.c
@@ -46,11 +46,12 @@ void debounce_free(void) {
last_raw = NULL;
}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint16_t now = timer_read();
- uint16_t elapsed16 = TIMER_DIFF_16(now, last_time);
- last_time = now;
- uint8_t elapsed = (elapsed16 > 255) ? 255 : elapsed16;
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ uint16_t now = timer_read();
+ uint16_t elapsed16 = TIMER_DIFF_16(now, last_time);
+ last_time = now;
+ uint8_t elapsed = (elapsed16 > 255) ? 255 : elapsed16;
+ bool cooked_changed = false;
uint8_t* countdown = countdowns;
@@ -63,10 +64,13 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
} else if (*countdown > elapsed) {
*countdown -= elapsed;
} else if (*countdown) {
+ cooked_changed |= cooked[row] ^ raw_row;
cooked[row] = raw_row;
*countdown = 0;
}
}
+
+ return cooked_changed;
}
bool debounce_active(void) {
diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c
index fe3e88bb06..f736d1645c 100644
--- a/quantum/debounce/sym_eager_pk.c
+++ b/quantum/debounce/sym_eager_pk.c
@@ -49,6 +49,7 @@ static debounce_counter_t *debounce_counters;
static fast_timer_t last_time;
static bool counters_need_update;
static bool matrix_need_update;
+static bool cooked_changed;
# define DEBOUNCE_ELAPSED 0
@@ -71,8 +72,9 @@ void debounce_free(void) {
debounce_counters = NULL;
}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
bool updated_last = false;
+ cooked_changed = false;
if (counters_need_update) {
fast_timer_t now = timer_read_fast();
@@ -96,6 +98,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
transfer_matrix_values(raw, cooked, num_rows);
}
+
+ return cooked_changed;
}
// If the current time is > debounce counter, set the counter to enable input.
@@ -132,6 +136,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui
*debounce_pointer = DEBOUNCE;
counters_need_update = true;
existing_row ^= col_mask; // flip the bit.
+ cooked_changed = true;
}
}
debounce_pointer++;
diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c
index 29b0cabefb..aad5ca351b 100644
--- a/quantum/debounce/sym_eager_pr.c
+++ b/quantum/debounce/sym_eager_pr.c
@@ -48,6 +48,7 @@ static bool matrix_need_update;
static debounce_counter_t *debounce_counters;
static fast_timer_t last_time;
static bool counters_need_update;
+static bool cooked_changed;
# define DEBOUNCE_ELAPSED 0
@@ -67,8 +68,9 @@ void debounce_free(void) {
debounce_counters = NULL;
}
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
bool updated_last = false;
+ cooked_changed = false;
if (counters_need_update) {
fast_timer_t now = timer_read_fast();
@@ -92,6 +94,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
transfer_matrix_values(raw, cooked, num_rows);
}
+
+ return cooked_changed;
}
// If the current time is > debounce counter, set the counter to enable input.
@@ -123,8 +127,9 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui
// determine new value basd on debounce pointer + raw value
if (existing_row != raw_row) {
if (*debounce_pointer == DEBOUNCE_ELAPSED) {
- *debounce_pointer = DEBOUNCE;
- cooked[row] = raw_row;
+ *debounce_pointer = DEBOUNCE;
+ cooked[row] = raw_row;
+ cooked_changed |= cooked[row] ^ raw[row];
counters_need_update = true;
}
}
diff --git a/quantum/debounce/tests/debounce_test_common.cpp b/quantum/debounce/tests/debounce_test_common.cpp
index 0d5a7bb766..bd98e32955 100644
--- a/quantum/debounce/tests/debounce_test_common.cpp
+++ b/quantum/debounce/tests/debounce_test_common.cpp
@@ -125,11 +125,15 @@ void DebounceTest::runDebounce(bool changed) {
std::copy(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_));
std::copy(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_));
- debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed);
+ bool cooked_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_);
}
+
+ if (std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_)) && cooked_changed) {
+ FAIL() << "Fatal error: debounce() did detect a wrong cooked matrix change at " << strTime() << "\noutput_matrix: cooked_changed=" << cooked_changed << "\n" << strMatrix(output_matrix_) << "\ncooked_matrix:\n" << strMatrix(cooked_matrix_);
+ }
}
void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) {
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index fc1c55784d..e80dd6d534 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -19,7 +19,13 @@
#include "progmem.h" // to read default from flash
#include "quantum.h" // for send_string()
#include "dynamic_keymap.h"
-#include "via.h" // for default VIA_EEPROM_ADDR_END
+
+#ifdef VIA_ENABLE
+# include "via.h" // for VIA_EEPROM_CONFIG_END
+# define DYNAMIC_KEYMAP_EEPROM_START (VIA_EEPROM_CONFIG_END)
+#else
+# define DYNAMIC_KEYMAP_EEPROM_START (EECONFIG_SIZE)
+#endif
#ifdef ENCODER_ENABLE
# include "encoder.h"
@@ -55,13 +61,8 @@
#endif
// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
-// default it start after VIA_EEPROM_CUSTOM_ADDR+VIA_EEPROM_CUSTOM_SIZE
#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
-# ifdef VIA_EEPROM_CUSTOM_CONFIG_ADDR
-# define DYNAMIC_KEYMAP_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE)
-# else
-# error DYNAMIC_KEYMAP_EEPROM_ADDR not defined
-# endif
+# define DYNAMIC_KEYMAP_EEPROM_ADDR DYNAMIC_KEYMAP_EEPROM_START
#endif
// Dynamic encoders starts after dynamic keymaps
@@ -93,6 +94,10 @@ _Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_A
# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 1)
#endif
+#ifndef DYNAMIC_KEYMAP_MACRO_DELAY
+# define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY
+#endif
+
uint8_t dynamic_keymap_get_layer_count(void) {
return DYNAMIC_KEYMAP_LAYER_COUNT;
}
@@ -300,6 +305,6 @@ void dynamic_keymap_macro_send(uint8_t id) {
break;
}
}
- send_string(data);
+ send_string_with_delay(data, DYNAMIC_KEYMAP_MACRO_DELAY);
}
}
diff --git a/quantum/encoder.c b/quantum/encoder.c
index 105bed0147..5f8a7ce080 100644
--- a/quantum/encoder.c
+++ b/quantum/encoder.c
@@ -163,27 +163,38 @@ static bool encoder_update(uint8_t index, uint8_t state) {
index += thisHand;
#endif
encoder_pulses[i] += encoder_LUT[state & 0xF];
+
+#ifdef ENCODER_DEFAULT_POS
+ if ((encoder_pulses[i] >= resolution) || (encoder_pulses[i] <= -resolution) || ((state & 0x3) == ENCODER_DEFAULT_POS)) {
+ if (encoder_pulses[i] >= 1) {
+#else
if (encoder_pulses[i] >= resolution) {
- encoder_value[index]++;
- changed = true;
+#endif
+
+ encoder_value[index]++;
+ changed = true;
#ifdef ENCODER_MAP_ENABLE
- encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE);
+ encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE);
#else // ENCODER_MAP_ENABLE
encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);
#endif // ENCODER_MAP_ENABLE
- }
+ }
+
+#ifdef ENCODER_DEFAULT_POS
+ if (encoder_pulses[i] <= -1) {
+#else
if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise
- encoder_value[index]--;
- changed = true;
+#endif
+ encoder_value[index]--;
+ changed = true;
#ifdef ENCODER_MAP_ENABLE
- encoder_exec_mapping(index, ENCODER_CLOCKWISE);
+ encoder_exec_mapping(index, ENCODER_CLOCKWISE);
#else // ENCODER_MAP_ENABLE
encoder_update_kb(index, ENCODER_CLOCKWISE);
#endif // ENCODER_MAP_ENABLE
- }
- encoder_pulses[i] %= resolution;
+ }
+ encoder_pulses[i] %= resolution;
#ifdef ENCODER_DEFAULT_POS
- if ((state & 0x3) == ENCODER_DEFAULT_POS) {
encoder_pulses[i] = 0;
}
#endif
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index a65f9d6d18..8273299a9a 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -381,7 +381,7 @@ void keyboard_init(void) {
#ifdef ENCODER_ENABLE
encoder_init();
#endif
-#ifdef STENO_ENABLE
+#ifdef STENO_ENABLE_ALL
steno_init();
#endif
#ifdef POINTING_DEVICE_ENABLE
diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c
index dd2a17e242..5b5cc5d28e 100644
--- a/quantum/keycode_config.c
+++ b/quantum/keycode_config.c
@@ -29,6 +29,8 @@ uint16_t keycode_config(uint16_t keycode) {
case KC_LOCKING_CAPS_LOCK:
if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
return KC_LEFT_CTRL;
+ } else if (keymap_config.swap_escape_capslock) {
+ return KC_ESCAPE;
}
return keycode;
case KC_LEFT_CTRL:
@@ -96,6 +98,8 @@ uint16_t keycode_config(uint16_t keycode) {
case KC_ESCAPE:
if (keymap_config.swap_grave_esc) {
return KC_GRAVE;
+ } else if (keymap_config.swap_escape_capslock) {
+ return KC_CAPS_LOCK;
}
return KC_ESCAPE;
case KC_BACKSLASH:
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index a2cb025ed2..81a8e61471 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -38,6 +38,7 @@ typedef union {
bool swap_lctl_lgui : 1;
bool swap_rctl_rgui : 1;
bool oneshot_enable : 1;
+ bool swap_escape_capslock : 1;
};
} keymap_config_t;
diff --git a/quantum/keymap.h b/quantum/keymap.h
index d64b271efb..edff484129 100644
--- a/quantum/keymap.h
+++ b/quantum/keymap.h
@@ -46,6 +46,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "quantum_keycodes.h"
+// Gross hack, remove me and change RESET keycode to QK_BOOT
+#if defined(MCU_RP)
+# undef RESET
+#endif
+
// translates key to keycode
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
@@ -55,3 +60,5 @@ extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
// Ensure we have a forward declaration for the encoder map
# include "encoder.h"
#endif
+
+#include "keymap_introspection.h"
diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h
index e888ccd643..07d96b7465 100644
--- a/quantum/keymap_extras/keymap_steno.h
+++ b/quantum/keymap_extras/keymap_steno.h
@@ -89,3 +89,31 @@ enum steno_combined_keycodes {
STN_COMB_MAX = STN_EU,
};
#endif
+
+#ifdef STENO_ENABLE_BOLT
+// TxBolt Codes
+# define TXB_NUL 0
+# define TXB_S_L 0b00000001
+# define TXB_T_L 0b00000010
+# define TXB_K_L 0b00000100
+# define TXB_P_L 0b00001000
+# define TXB_W_L 0b00010000
+# define TXB_H_L 0b00100000
+# define TXB_R_L 0b01000001
+# define TXB_A_L 0b01000010
+# define TXB_O_L 0b01000100
+# define TXB_STR 0b01001000
+# define TXB_E_R 0b01010000
+# define TXB_U_R 0b01100000
+# define TXB_F_R 0b10000001
+# define TXB_R_R 0b10000010
+# define TXB_P_R 0b10000100
+# define TXB_B_R 0b10001000
+# define TXB_L_R 0b10010000
+# define TXB_G_R 0b10100000
+# define TXB_T_R 0b11000001
+# define TXB_S_R 0b11000010
+# define TXB_D_R 0b11000100
+# define TXB_Z_R 0b11001000
+# define TXB_NUM 0b11010000
+#endif // STENO_ENABLE_BOLT
diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c
new file mode 100644
index 0000000000..7a96f802ef
--- /dev/null
+++ b/quantum/keymap_introspection.c
@@ -0,0 +1,30 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+// Pull the actual keymap code so that we can inspect stuff from it
+#include KEYMAP_C
+
+// Allow for keymap or userspace rules.mk to specify an alternate location for the keymap array
+#ifdef INTROSPECTION_KEYMAP_C
+# include INTROSPECTION_KEYMAP_C
+#endif // INTROSPECTION_KEYMAP_C
+
+#include "keymap_introspection.h"
+
+#define NUM_KEYMAP_LAYERS ((uint8_t)(sizeof(keymaps) / ((MATRIX_ROWS) * (MATRIX_COLS) * sizeof(uint16_t))))
+
+uint8_t keymap_layer_count(void) {
+ return NUM_KEYMAP_LAYERS;
+}
+
+#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
+
+# define NUM_ENCODERMAP_LAYERS ((uint8_t)(sizeof(encoder_map) / ((NUM_ENCODERS) * (2) * sizeof(uint16_t))))
+
+uint8_t encodermap_layer_count(void) {
+ return NUM_ENCODERMAP_LAYERS;
+}
+
+_Static_assert(NUM_KEYMAP_LAYERS == NUM_ENCODERMAP_LAYERS, "Number of encoder_map layers doesn't match the number of keymap layers");
+
+#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h
new file mode 100644
index 0000000000..23f6f2016f
--- /dev/null
+++ b/quantum/keymap_introspection.h
@@ -0,0 +1,15 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#include <stdint.h>
+
+// Get the number of layers defined in the keymap
+uint8_t keymap_layer_count(void);
+
+#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
+
+// Get the number of layers defined in the encoder map
+uint8_t encodermap_layer_count(void);
+
+#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
diff --git a/quantum/led.c b/quantum/led.c
index c5ddbc22c5..444d38f751 100644
--- a/quantum/led.c
+++ b/quantum/led.c
@@ -15,6 +15,7 @@
*/
#include "led.h"
#include "host.h"
+#include "timer.h"
#include "debug.h"
#include "gpio.h"
@@ -54,6 +55,14 @@ static void handle_backlight_caps_lock(led_t led_state) {
}
#endif
+static uint32_t last_led_modification_time = 0;
+uint32_t last_led_activity_time(void) {
+ return last_led_modification_time;
+}
+uint32_t last_led_activity_elapsed(void) {
+ return timer_elapsed32(last_led_modification_time);
+}
+
/** \brief Lock LED set callback - keymap/user level
*
* \deprecated Use led_update_user() instead.
@@ -174,7 +183,8 @@ void led_task(void) {
// update LED
uint8_t led_status = host_keyboard_leds();
if (last_led_status != led_status) {
- last_led_status = led_status;
+ last_led_status = led_status;
+ last_led_modification_time = timer_read32();
if (debug_keyboard) {
debug("led_task: ");
diff --git a/quantum/led.h b/quantum/led.h
index 934d25312c..b8262cbd8e 100644
--- a/quantum/led.h
+++ b/quantum/led.h
@@ -61,6 +61,9 @@ void led_set_kb(uint8_t usb_led);
bool led_update_user(led_t led_state);
bool led_update_kb(led_t led_state);
+uint32_t last_led_activity_time(void); // Timestamp of the LED activity
+uint32_t last_led_activity_elapsed(void); // Number of milliseconds since the last LED activity
+
#ifdef __cplusplus
}
#endif
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index 38ed79bed0..14dd0dd48a 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -618,10 +618,20 @@ void led_matrix_decrease_speed(void) {
led_matrix_decrease_speed_helper(true);
}
+void led_matrix_set_flags_eeprom_helper(led_flags_t flags, bool write_to_eeprom) {
+ led_matrix_eeconfig.flags = flags;
+ eeconfig_flag_led_matrix(write_to_eeprom);
+ dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.flags);
+}
+
led_flags_t led_matrix_get_flags(void) {
return led_matrix_eeconfig.flags;
}
void led_matrix_set_flags(led_flags_t flags) {
- led_matrix_eeconfig.flags = flags;
+ led_matrix_set_flags_eeprom_helper(flags, true);
+}
+
+void led_matrix_set_flags_noeeprom(led_flags_t flags) {
+ led_matrix_set_flags_eeprom_helper(flags, false);
}
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h
index d21f36e295..b2abec7eb1 100644
--- a/quantum/led_matrix/led_matrix.h
+++ b/quantum/led_matrix/led_matrix.h
@@ -158,6 +158,7 @@ void led_matrix_decrease_speed(void);
void led_matrix_decrease_speed_noeeprom(void);
led_flags_t led_matrix_get_flags(void);
void led_matrix_set_flags(led_flags_t flags);
+void led_matrix_set_flags_noeeprom(led_flags_t flags);
typedef struct {
/* Perform any initialisation required for the other driver functions to work. */
diff --git a/quantum/logging/print.c b/quantum/logging/print.c
index 50a6b826ee..17e6737ac4 100644
--- a/quantum/logging/print.c
+++ b/quantum/logging/print.c
@@ -28,6 +28,6 @@ void print_set_sendchar(sendchar_func_t send) {
func = send;
}
-void _putchar(char character) {
+void putchar_(char character) {
func(character);
}
diff --git a/quantum/logging/print.h b/quantum/logging/print.h
index aa72fc7074..4c4195de50 100644
--- a/quantum/logging/print.h
+++ b/quantum/logging/print.h
@@ -32,6 +32,22 @@
void print_set_sendchar(sendchar_func_t func);
+/**
+ * @brief This macro suppress format warnings for the function that is passed
+ * in. The main use-case is that `b` format specifier for printing binary
+ * numbers is not in the official C standard. Inclusion is planned for the
+ * upcoming C2X C standard, but until then GCC will always output a warning for
+ * a unknown format specifier.
+ */
+#define IGNORE_FORMAT_WARNING(func) \
+ do { \
+ _Pragma("GCC diagnostic push"); \
+ _Pragma("GCC diagnostic ignored \"-Wformat\""); \
+ _Pragma("GCC diagnostic ignored \"-Wformat-extra-args\""); \
+ func; \
+ _Pragma("GCC diagnostic pop"); \
+ } while (0)
+
#ifndef NO_PRINT
# if __has_include_next("_print.h")
# include_next "_print.h" /* Include the platforms print.h */
@@ -78,25 +94,25 @@ void print_set_sendchar(sendchar_func_t func);
#define print_hex16(i) xprintf("%04X", i)
#define print_hex32(i) xprintf("%08lX", i)
/* binary */
-#define print_bin4(i) xprintf("%04b", i)
-#define print_bin8(i) xprintf("%08b", i)
-#define print_bin16(i) xprintf("%016b", i)
-#define print_bin32(i) xprintf("%032lb", i)
-#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
-#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
-#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
+#define print_bin4(i) IGNORE_FORMAT_WARNING(xprintf("%04b", i))
+#define print_bin8(i) IGNORE_FORMAT_WARNING(xprintf("%08b", i))
+#define print_bin16(i) IGNORE_FORMAT_WARNING(xprintf("%016b", i))
+#define print_bin32(i) IGNORE_FORMAT_WARNING(xprintf("%032lb", i))
+#define print_bin_reverse8(i) IGNORE_FORMAT_WARNING(xprintf("%08b", bitrev(i)))
+#define print_bin_reverse16(i) IGNORE_FORMAT_WARNING(xprintf("%016b", bitrev16(i)))
+#define print_bin_reverse32(i) IGNORE_FORMAT_WARNING(xprintf("%032lb", bitrev32(i)))
/* print value utility */
#define print_val_dec(v) xprintf(#v ": %u\n", v)
#define print_val_decs(v) xprintf(#v ": %d\n", v)
#define print_val_hex8(v) xprintf(#v ": %X\n", v)
#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
-#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
-#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
-#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
-#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
-#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
-#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
+#define print_val_bin8(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %08b\n", v))
+#define print_val_bin16(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %016b\n", v))
+#define print_val_bin32(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %032lb\n", v))
+#define print_val_bin_reverse8(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %08b\n", bitrev(v)))
+#define print_val_bin_reverse16(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %016b\n", bitrev16(v)))
+#define print_val_bin_reverse32(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %032lb\n", bitrev32(v)))
// User print disables the normal print messages in the body of QMK/TMK code and
// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
@@ -114,22 +130,22 @@ void print_set_sendchar(sendchar_func_t func);
#define uprint_hex16(i) uprintf("%04X", i)
#define uprint_hex32(i) uprintf("%08lX", i)
/* binary */
-#define uprint_bin4(i) uprintf("%04b", i)
-#define uprint_bin8(i) uprintf("%08b", i)
-#define uprint_bin16(i) uprintf("%016b", i)
-#define uprint_bin32(i) uprintf("%032lb", i)
-#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
-#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
-#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
+#define uprint_bin4(i) IGNORE_FORMAT_WARNING(uprintf("%04b", i))
+#define uprint_bin8(i) IGNORE_FORMAT_WARNING(uprintf("%08b", i))
+#define uprint_bin16(i) IGNORE_FORMAT_WARNING(uprintf("%016b", i))
+#define uprint_bin32(i) IGNORE_FORMAT_WARNING(uprintf("%032lb", i))
+#define uprint_bin_reverse8(i) IGNORE_FORMAT_WARNING(uprintf("%08b", bitrev(i)))
+#define uprint_bin_reverse16(i) IGNORE_FORMAT_WARNING(uprintf("%016b", bitrev16(i)))
+#define uprint_bin_reverse32(i) IGNORE_FORMAT_WARNING(uprintf("%032lb", bitrev32(i)))
/* print value utility */
#define uprint_val_dec(v) uprintf(#v ": %u\n", v)
#define uprint_val_decs(v) uprintf(#v ": %d\n", v)
#define uprint_val_hex8(v) uprintf(#v ": %X\n", v)
#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v)
#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v)
-#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v)
-#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v)
-#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v)
-#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v))
-#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v))
-#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v))
+#define uprint_val_bin8(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %08b\n", v))
+#define uprint_val_bin16(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %016b\n", v))
+#define uprint_val_bin32(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %032lb\n", v))
+#define uprint_val_bin_reverse8(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %08b\n", bitrev(v)))
+#define uprint_val_bin_reverse16(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %016b\n", bitrev16(v)))
+#define uprint_val_bin_reverse32(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %032lb\n", bitrev32(v)))
diff --git a/quantum/logging/print.mk b/quantum/logging/print.mk
index 67c004192d..658c533dad 100644
--- a/quantum/logging/print.mk
+++ b/quantum/logging/print.mk
@@ -1,9 +1,12 @@
-PRINTF_PATH = $(LIB_PATH)/printf
+PRINTF_PATH = $(LIB_PATH)/printf/src
-VPATH += $(PRINTF_PATH)
-SRC += $(PRINTF_PATH)/printf.c
+VPATH += $(PRINTF_PATH) $(PRINTF_PATH)/printf
+SRC += printf.c
QUANTUM_SRC +=$(QUANTUM_DIR)/logging/print.c
-OPT_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT
-OPT_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
-OPT_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
-OPT_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
+
+OPT_DEFS += -DPRINTF_SUPPORT_DECIMAL_SPECIFIERS=0
+OPT_DEFS += -DPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=0
+OPT_DEFS += -DPRINTF_SUPPORT_LONG_LONG=0
+OPT_DEFS += -DPRINTF_SUPPORT_WRITEBACK_SPECIFIER=0
+OPT_DEFS += -DSUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS=0
+OPT_DEFS += -DPRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1
diff --git a/quantum/matrix.c b/quantum/matrix.c
index db59b73754..db683104ed 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -337,10 +337,9 @@ uint8_t matrix_scan(void) {
if (changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix));
#ifdef SPLIT_KEYBOARD
- debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
- changed = (changed || matrix_post_scan());
+ changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan();
#else
- debounce(raw_matrix, matrix, ROWS_PER_HAND, changed);
+ changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed);
matrix_scan_quantum();
#endif
return (uint8_t)changed;
diff --git a/quantum/matrix_common.c b/quantum/matrix_common.c
index 2cf8484347..68f0e38297 100644
--- a/quantum/matrix_common.c
+++ b/quantum/matrix_common.c
@@ -169,10 +169,9 @@ __attribute__((weak)) uint8_t matrix_scan(void) {
bool changed = matrix_scan_custom(raw_matrix);
#ifdef SPLIT_KEYBOARD
- debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
- changed = (changed || matrix_post_scan());
+ changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan();
#else
- debounce(raw_matrix, matrix, ROWS_PER_HAND, changed);
+ changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed);
matrix_scan_quantum();
#endif
diff --git a/quantum/mousekey.c b/quantum/mousekey.c
index c5e3f8bcda..25a89bdba7 100644
--- a/quantum/mousekey.c
+++ b/quantum/mousekey.c
@@ -66,11 +66,18 @@ uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
/* milliseconds between the initial key press and first repeated motion event (0-2550) */
uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
/* milliseconds between repeated motion events (0-255) */
-uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
+# ifdef MK_KINETIC_SPEED
+float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
+# else
+uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
+# endif
uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
# ifndef MK_COMBINED
+# ifndef MK_KINETIC_SPEED
+
+/* Default accelerated mode */
static uint8_t move_unit(void) {
uint16_t unit;
@@ -108,8 +115,7 @@ static uint8_t wheel_unit(void) {
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
}
-# else /* #ifndef MK_COMBINED */
-# ifdef MK_KINETIC_SPEED
+# else /* #ifndef MK_KINETIC_SPEED */
/*
* Kinetic movement acceleration algorithm
@@ -147,27 +153,27 @@ static uint8_t move_unit(void) {
return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed;
}
-float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
-
static uint8_t wheel_unit(void) {
float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
if (mousekey_accel & ((1 << 0) | (1 << 2))) {
speed = mousekey_accel & (1 << 2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS;
- } else if (mousekey_repeat && mouse_timer) {
+ } else if (mousekey_wheel_repeat && mouse_timer) {
if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) {
const float time_elapsed = timer_elapsed(mouse_timer) / 50;
speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed;
}
speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed;
}
-
mk_wheel_interval = 1000.0f / speed;
- return 1;
+ return (uint8_t)speed > MOUSEKEY_WHEEL_INITIAL_MOVEMENTS ? 2 : 1;
}
-# else /* #ifndef MK_KINETIC_SPEED */
+# endif /* #ifndef MK_KINETIC_SPEED */
+# else /* #ifndef MK_COMBINED */
+
+/* Combined mode */
static uint8_t move_unit(void) {
uint16_t unit;
@@ -205,8 +211,7 @@ static uint8_t wheel_unit(void) {
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
}
-# endif /* #ifndef MK_KINETIC_SPEED */
-# endif /* #ifndef MK_COMBINED */
+# endif /* #ifndef MK_COMBINED */
void mousekey_task(void) {
// report cursor and scroll movement independently
diff --git a/quantum/mousekey.h b/quantum/mousekey.h
index 1714e52ff6..da2edb481a 100644
--- a/quantum/mousekey.h
+++ b/quantum/mousekey.h
@@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# ifndef MK_KINETIC_SPEED
# define MOUSEKEY_MOVE_DELTA 8
# else
-# define MOUSEKEY_MOVE_DELTA 5
+# define MOUSEKEY_MOVE_DELTA 16
# endif
# endif
# ifndef MOUSEKEY_WHEEL_DELTA
@@ -82,7 +82,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define MOUSEKEY_INITIAL_SPEED 100
# endif
# ifndef MOUSEKEY_BASE_SPEED
-# define MOUSEKEY_BASE_SPEED 1000
+# define MOUSEKEY_BASE_SPEED 5000
# endif
# ifndef MOUSEKEY_DECELERATED_SPEED
# define MOUSEKEY_DECELERATED_SPEED 400
diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h
index e1c14d156c..47f077d0cf 100644
--- a/quantum/painter/qp.h
+++ b/quantum/painter/qp.h
@@ -440,6 +440,10 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai
# include "qp_ili9341.h"
#endif // QUANTUM_PAINTER_ILI9341_ENABLE
+#ifdef QUANTUM_PAINTER_ILI9488_ENABLE
+# include "qp_ili9488.h"
+#endif // QUANTUM_PAINTER_ILI9488_ENABLE
+
#ifdef QUANTUM_PAINTER_ST7789_ENABLE
# include "qp_st7789.h"
#endif // QUANTUM_PAINTER_ST7789_ENABLE
diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk
index 9115d3d406..675a1a5460 100644
--- a/quantum/painter/rules.mk
+++ b/quantum/painter/rules.mk
@@ -3,7 +3,7 @@ QUANTUM_PAINTER_DRIVERS ?=
QUANTUM_PAINTER_ANIMATIONS_ENABLE ?= yes
# The list of permissible drivers that can be listed in QUANTUM_PAINTER_DRIVERS
-VALID_QUANTUM_PAINTER_DRIVERS := ili9163_spi ili9341_spi st7789_spi gc9a01_spi ssd1351_spi
+VALID_QUANTUM_PAINTER_DRIVERS := ili9163_spi ili9341_spi ili9488_spi st7789_spi gc9a01_spi ssd1351_spi
#-------------------------------------------------------------------------------
@@ -61,6 +61,17 @@ define handle_quantum_painter_driver
$(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \
$(DRIVER_PATH)/painter/ili9xxx/qp_ili9341.c \
+ else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ili9488_spi)
+ QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes
+ QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes
+ OPT_DEFS += -DQUANTUM_PAINTER_ILI9488_ENABLE -DQUANTUM_PAINTER_ILI9488_SPI_ENABLE
+ COMMON_VPATH += \
+ $(DRIVER_PATH)/painter/tft_panel \
+ $(DRIVER_PATH)/painter/ili9xxx
+ SRC += \
+ $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \
+ $(DRIVER_PATH)/painter/ili9xxx/qp_ili9488.c \
+
else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),st7789_spi)
QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes
QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes
diff --git a/quantum/pointing_device.c b/quantum/pointing_device.c
index a160647890..3aa4941687 100644
--- a/quantum/pointing_device.c
+++ b/quantum/pointing_device.c
@@ -25,6 +25,13 @@
#if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1
# error More than one rotation selected. This is not supported.
#endif
+
+#if defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_COMBINED)
+# ifndef SPLIT_POINTING_ENABLE
+# error "Using POINTING_DEVICE_LEFT or POINTING_DEVICE_RIGHT or POINTING_DEVICE_COMBINED, then SPLIT_POINTING_ENABLE is required but has not been defined"
+# endif
+#endif
+
#if defined(SPLIT_POINTING_ENABLE)
# include "transactions.h"
# include "keyboard.h"
@@ -177,7 +184,8 @@ __attribute__((weak)) void pointing_device_send(void) {
report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report) {
// Support rotation of the sensor data
#if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270)
- int8_t x = mouse_report.x, y = mouse_report.y;
+ mouse_xy_report_t x = mouse_report.x;
+ mouse_xy_report_t y = mouse_report.y;
# if defined(POINTING_DEVICE_ROTATION_90)
mouse_report.x = y;
mouse_report.y = -x;
@@ -347,7 +355,7 @@ void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
* @param[in] int16_t value
* @return int8_t clamped value
*/
-static inline int8_t pointing_device_movement_clamp(int16_t value) {
+static inline int8_t pointing_device_hv_clamp(int16_t value) {
if (value < INT8_MIN) {
return INT8_MIN;
} else if (value > INT8_MAX) {
@@ -358,6 +366,21 @@ static inline int8_t pointing_device_movement_clamp(int16_t value) {
}
/**
+ * @brief clamps int16_t to int8_t
+ *
+ * @param[in] clamp_range_t value
+ * @return mouse_xy_report_t clamped value
+ */
+static inline mouse_xy_report_t pointing_device_xy_clamp(clamp_range_t value) {
+ if (value < XY_REPORT_MIN) {
+ return XY_REPORT_MIN;
+ } else if (value > XY_REPORT_MAX) {
+ return XY_REPORT_MAX;
+ } else {
+ return value;
+ }
+}
+/**
* @brief combines 2 mouse reports and returns 2
*
* Combines 2 report_mouse_t structs, clamping movement values to int8_t and ignores report_id then returns the resulting report_mouse_t struct.
@@ -369,10 +392,10 @@ static inline int8_t pointing_device_movement_clamp(int16_t value) {
* @return combined report_mouse_t of left_report and right_report
*/
report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) {
- left_report.x = pointing_device_movement_clamp((int16_t)left_report.x + right_report.x);
- left_report.y = pointing_device_movement_clamp((int16_t)left_report.y + right_report.y);
- left_report.h = pointing_device_movement_clamp((int16_t)left_report.h + right_report.h);
- left_report.v = pointing_device_movement_clamp((int16_t)left_report.v + right_report.v);
+ left_report.x = pointing_device_xy_clamp((clamp_range_t)left_report.x + right_report.x);
+ left_report.y = pointing_device_xy_clamp((clamp_range_t)left_report.y + right_report.y);
+ left_report.h = pointing_device_hv_clamp((int16_t)left_report.h + right_report.h);
+ left_report.v = pointing_device_hv_clamp((int16_t)left_report.v + right_report.v);
left_report.buttons |= right_report.buttons;
return left_report;
}
@@ -390,7 +413,8 @@ report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, repor
report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report) {
// Support rotation of the sensor data
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT) || defined(POINTING_DEVICE_ROTATION_RIGHT)
- int8_t x = mouse_report.x, y = mouse_report.y;
+ mouse_xy_report_t x = mouse_report.x;
+ mouse_xy_report_t y = mouse_report.y;
# if defined(POINTING_DEVICE_ROTATION_90_RIGHT)
mouse_report.x = y;
mouse_report.y = -x;
diff --git a/quantum/pointing_device.h b/quantum/pointing_device.h
index 5c0eaeaf34..a8e8e75e87 100644
--- a/quantum/pointing_device.h
+++ b/quantum/pointing_device.h
@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "drivers/sensors/analog_joystick.h"
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
# include "drivers/sensors/cirque_pinnacle.h"
+# include "drivers/sensors/cirque_pinnacle_gestures.h"
+# include "pointing_device_gestures.h"
#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
# include "i2c_master.h"
# include "drivers/sensors/pimoroni_trackball.h"
@@ -44,12 +46,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# ifdef PIMORONI_TRACKBALL_ROTATE
# define POINTING_DEVICE_ROTATION_90
# endif
-#elif defined(POINTING_DEVICE_DRIVER_pmw3360)
+#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389)
# include "spi_master.h"
-# include "drivers/sensors/pmw3360.h"
-#elif defined(POINTING_DEVICE_DRIVER_pmw3389)
-# include "spi_master.h"
-# include "drivers/sensors/pmw3389.h"
+# include "drivers/sensors/pmw33xx_common.h"
#else
void pointing_device_driver_init(void);
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report);
@@ -75,6 +74,16 @@ typedef enum {
POINTING_DEVICE_BUTTON8,
} pointing_device_buttons_t;
+#ifdef MOUSE_EXTENDED_REPORT
+# define XY_REPORT_MIN INT16_MIN
+# define XY_REPORT_MAX INT16_MAX
+typedef int32_t clamp_range_t;
+#else
+# define XY_REPORT_MIN INT8_MIN
+# define XY_REPORT_MAX INT8_MAX
+typedef int16_t clamp_range_t;
+#endif
+
void pointing_device_init(void);
void pointing_device_task(void);
void pointing_device_send(void);
diff --git a/quantum/pointing_device_drivers.c b/quantum/pointing_device_drivers.c
index 56363c7ac6..b7e98e897e 100644
--- a/quantum/pointing_device_drivers.c
+++ b/quantum/pointing_device_drivers.c
@@ -22,8 +22,8 @@
#include "timer.h"
#include <stddef.h>
-// hid mouse reports cannot exceed -127 to 127, so constrain to that value
-#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
+#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt)))
+#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt)))
// get_report functions should probably be moved to their respective drivers.
#if defined(POINTING_DEVICE_DRIVER_adns5050)
@@ -35,8 +35,8 @@ report_mouse_t adns5050_get_report(report_mouse_t mouse_report) {
if (debug_mouse) dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
# endif
- mouse_report.x = data.dx;
- mouse_report.y = data.dy;
+ mouse_report.x = (mouse_xy_report_t)data.dx;
+ mouse_report.y = (mouse_xy_report_t)data.dy;
}
return mouse_report;
@@ -50,16 +50,14 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = adns5050_get_cpi,
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_adns9800)
report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report) {
report_adns9800_t sensor_report = adns9800_get_report();
- int8_t clamped_x = constrain_hid(sensor_report.x);
- int8_t clamped_y = constrain_hid(sensor_report.y);
-
- mouse_report.x = clamped_x;
- mouse_report.y = clamped_y;
+ mouse_report.x = CONSTRAIN_HID_XY(sensor_report.x);
+ mouse_report.y = CONSTRAIN_HID_XY(sensor_report.y);
return mouse_report;
}
@@ -72,6 +70,7 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = adns9800_get_cpi
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_analog_joystick)
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {
report_analog_joystick_t data = analog_joystick_read();
@@ -96,72 +95,131 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = NULL
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
-# ifndef CIRQUE_PINNACLE_TAPPING_TERM
-# include "action.h"
-# include "action_tapping.h"
-# define CIRQUE_PINNACLE_TAPPING_TERM GET_TAPPING_TERM(KC_BTN1, &(keyrecord_t){})
-# endif
-# ifndef CIRQUE_PINNACLE_TOUCH_DEBOUNCE
-# define CIRQUE_PINNACLE_TOUCH_DEBOUNCE (CIRQUE_PINNACLE_TAPPING_TERM * 8)
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+static bool cursor_glide_enable = true;
+
+static cursor_glide_context_t glide = {.config = {
+ .coef = 102, /* Good default friction coef */
+ .interval = 10, /* 100sps */
+ .trigger_px = 10, /* Default threshold in case of hover, set to 0 if you'd like */
+ }};
+
+void cirque_pinnacle_enable_cursor_glide(bool enable) {
+ cursor_glide_enable = enable;
+}
+
+void cirque_pinnacle_configure_cursor_glide(float trigger_px) {
+ glide.config.trigger_px = trigger_px;
+}
# endif
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
- pinnacle_data_t touchData = cirque_pinnacle_read_data();
- static uint16_t x = 0, y = 0, mouse_timer = 0;
- int8_t report_x = 0, report_y = 0;
- static bool is_z_down = false;
+ pinnacle_data_t touchData = cirque_pinnacle_read_data();
+ mouse_xy_report_t report_x = 0, report_y = 0;
+ static mouse_xy_report_t x = 0, y = 0;
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ cursor_glide_t glide_report = {0};
+
+ if (cursor_glide_enable) {
+ glide_report = cursor_glide_check(&glide);
+ }
+# endif
- cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); // Scale coordinates to arbitrary X, Y resolution
+# if !CIRQUE_PINNACLE_POSITION_MODE
+# error Cirque Pinnacle with relative mode not implemented yet.
+# endif
- if (x && y && touchData.xValue && touchData.yValue) {
- report_x = (int8_t)(touchData.xValue - x);
- report_y = (int8_t)(touchData.yValue - y);
+ if (!touchData.valid) {
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ if (cursor_glide_enable && glide_report.valid) {
+ report_x = glide_report.dx;
+ report_y = glide_report.dy;
+ goto mouse_report_update;
+ }
+# endif
+ return mouse_report;
}
- x = touchData.xValue;
- y = touchData.yValue;
- if ((bool)touchData.zValue != is_z_down) {
- is_z_down = (bool)touchData.zValue;
- if (!touchData.zValue) {
- if (timer_elapsed(mouse_timer) < CIRQUE_PINNACLE_TAPPING_TERM && mouse_timer != 0) {
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1);
- pointing_device_set_report(mouse_report);
- pointing_device_send();
-# if TAP_CODE_DELAY > 0
- wait_ms(TAP_CODE_DELAY);
+# if CONSOLE_ENABLE
+ if (debug_mouse && touchData.touchDown) {
+ dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue);
+ }
# endif
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
- pointing_device_set_report(mouse_report);
- pointing_device_send();
+
+ // Scale coordinates to arbitrary X, Y resolution
+ cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale());
+
+ if (!cirque_pinnacle_gestures(&mouse_report, touchData)) {
+ if (x && y && touchData.xValue && touchData.yValue) {
+ report_x = (mouse_xy_report_t)(touchData.xValue - x);
+ report_y = (mouse_xy_report_t)(touchData.yValue - y);
+ }
+ x = touchData.xValue;
+ y = touchData.yValue;
+
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ if (cursor_glide_enable) {
+ if (touchData.touchDown) {
+ cursor_glide_update(&glide, report_x, report_y, touchData.zValue);
+ } else if (!glide_report.valid) {
+ glide_report = cursor_glide_start(&glide);
+ if (glide_report.valid) {
+ report_x = glide_report.dx;
+ report_y = glide_report.dy;
+ }
}
}
- mouse_timer = timer_read();
- }
- if (timer_elapsed(mouse_timer) > (CIRQUE_PINNACLE_TOUCH_DEBOUNCE)) {
- mouse_timer = 0;
+# endif
}
+
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+mouse_report_update:
+# endif
mouse_report.x = report_x;
mouse_report.y = report_y;
return mouse_report;
}
+uint16_t cirque_pinnacle_get_cpi(void) {
+ return CIRQUE_PINNACLE_PX_TO_INCH(cirque_pinnacle_get_scale());
+}
+void cirque_pinnacle_set_cpi(uint16_t cpi) {
+ cirque_pinnacle_set_scale(CIRQUE_PINNACLE_INCH_TO_PX(cpi));
+}
+
// clang-format off
const pointing_device_driver_t pointing_device_driver = {
.init = cirque_pinnacle_init,
.get_report = cirque_pinnacle_get_report,
- .set_cpi = cirque_pinnacle_set_scale,
- .get_cpi = cirque_pinnacle_get_scale
+ .set_cpi = cirque_pinnacle_set_cpi,
+ .get_cpi = cirque_pinnacle_get_cpi
};
// clang-format on
#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
+
+mouse_xy_report_t pimoroni_trackball_adapt_values(clamp_range_t* offset) {
+ if (*offset > XY_REPORT_MAX) {
+ *offset -= XY_REPORT_MAX;
+ return (mouse_xy_report_t)XY_REPORT_MAX;
+ } else if (*offset < XY_REPORT_MIN) {
+ *offset += XY_REPORT_MAX;
+ return (mouse_xy_report_t)XY_REPORT_MIN;
+ } else {
+ mouse_xy_report_t temp_return = *offset;
+ *offset = 0;
+ return temp_return;
+ }
+}
+
report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
- static uint16_t debounce = 0;
- static uint8_t error_count = 0;
- pimoroni_data_t pimoroni_data = {0};
- static int16_t x_offset = 0, y_offset = 0;
+ static uint16_t debounce = 0;
+ static uint8_t error_count = 0;
+ pimoroni_data_t pimoroni_data = {0};
+ static clamp_range_t x_offset = 0, y_offset = 0;
if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) {
i2c_status_t status = read_pimoroni_trackball(&pimoroni_data);
@@ -174,8 +232,8 @@ report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
if (!debounce) {
x_offset += pimoroni_trackball_get_offsets(pimoroni_data.right, pimoroni_data.left, PIMORONI_TRACKBALL_SCALE);
y_offset += pimoroni_trackball_get_offsets(pimoroni_data.down, pimoroni_data.up, PIMORONI_TRACKBALL_SCALE);
- pimoroni_trackball_adapt_values(&mouse_report.x, &x_offset);
- pimoroni_trackball_adapt_values(&mouse_report.y, &y_offset);
+ mouse_report.x = pimoroni_trackball_adapt_values(&x_offset);
+ mouse_report.y = pimoroni_trackball_adapt_values(&y_offset);
} else {
debounce--;
}
@@ -198,82 +256,52 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = pimoroni_trackball_get_cpi
};
// clang-format on
-#elif defined(POINTING_DEVICE_DRIVER_pmw3360)
-static void pmw3360_device_init(void) {
- pmw3360_init(0);
-}
-
-report_mouse_t pmw3360_get_report(report_mouse_t mouse_report) {
- report_pmw3360_t data = pmw3360_read_burst(0);
- static uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
- if (data.isOnSurface && data.isMotion) {
- // Reset timer if stopped moving
- if (!data.isMotion) {
- if (MotionStart != 0) MotionStart = 0;
- return mouse_report;
- }
-
- // Set timer if new motion
- if ((MotionStart == 0) && data.isMotion) {
-# ifdef CONSOLE_ENABLE
- if (debug_mouse) dprintf("Starting motion.\n");
-# endif
- MotionStart = timer_read();
- }
- mouse_report.x = constrain_hid(data.dx);
- mouse_report.y = constrain_hid(data.dy);
- }
+#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389)
+static void pmw33xx_init_wrapper(void) {
+ pmw33xx_init(0);
+}
- return mouse_report;
+static void pmw33xx_set_cpi_wrapper(uint16_t cpi) {
+ pmw33xx_set_cpi(0, cpi);
}
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pmw3360_device_init,
- .get_report = pmw3360_get_report,
- .set_cpi = pmw3360_set_cpi,
- .get_cpi = pmw3360_get_cpi
-};
-// clang-format on
-#elif defined(POINTING_DEVICE_DRIVER_pmw3389)
-static void pmw3389_device_init(void) {
- pmw3389_init();
+static uint16_t pmw33xx_get_cpi_wrapper(void) {
+ return pmw33xx_get_cpi(0);
}
-report_mouse_t pmw3389_get_report(report_mouse_t mouse_report) {
- report_pmw3389_t data = pmw3389_read_burst();
- static uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
+report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report) {
+ pmw33xx_report_t report = pmw33xx_read_burst(0);
+ static bool in_motion = false;
- if (data.isOnSurface && data.isMotion) {
- // Reset timer if stopped moving
- if (!data.isMotion) {
- if (MotionStart != 0) MotionStart = 0;
- return mouse_report;
- }
+ if (report.motion.b.is_lifted) {
+ return mouse_report;
+ }
- // Set timer if new motion
- if ((MotionStart == 0) && data.isMotion) {
-# ifdef CONSOLE_ENABLE
- if (debug_mouse) dprintf("Starting motion.\n");
-# endif
- MotionStart = timer_read();
- }
- mouse_report.x = constrain_hid(data.dx);
- mouse_report.y = constrain_hid(data.dy);
+ if (!report.motion.b.is_motion) {
+ in_motion = false;
+ return mouse_report;
}
+ if (!in_motion) {
+ in_motion = true;
+ dprintf("PWM3360 (0): starting motion\n");
+ }
+
+ mouse_report.x = CONSTRAIN_HID_XY(report.delta_x);
+ mouse_report.y = CONSTRAIN_HID_XY(report.delta_y);
return mouse_report;
}
// clang-format off
const pointing_device_driver_t pointing_device_driver = {
- .init = pmw3389_device_init,
- .get_report = pmw3389_get_report,
- .set_cpi = pmw3389_set_cpi,
- .get_cpi = pmw3389_get_cpi
+ .init = pmw33xx_init_wrapper,
+ .get_report = pmw33xx_get_report,
+ .set_cpi = pmw33xx_set_cpi_wrapper,
+ .get_cpi = pmw33xx_get_cpi_wrapper
};
// clang-format on
+
#else
__attribute__((weak)) void pointing_device_driver_init(void) {}
__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
@@ -292,4 +320,5 @@ const pointing_device_driver_t pointing_device_driver = {
.set_cpi = pointing_device_driver_set_cpi
};
// clang-format on
+
#endif
diff --git a/quantum/pointing_device_gestures.c b/quantum/pointing_device_gestures.c
new file mode 100644
index 0000000000..02b11ebe3f
--- /dev/null
+++ b/quantum/pointing_device_gestures.c
@@ -0,0 +1,133 @@
+/* Copyright 2022 Daniel Kao <daniel.m.kao@gmail.com>
+ *
+ * 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 <string.h>
+#include "pointing_device_gestures.h"
+#include "timer.h"
+
+#ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+# ifdef POINTING_DEVICE_MOTION_PIN
+# error POINTING_DEVICE_MOTION_PIN not supported when using inertial cursor. Need repeated calls to get_report() to generate glide events.
+# endif
+
+static void cursor_glide_stop(cursor_glide_context_t* glide) {
+ memset(&glide->status, 0, sizeof(glide->status));
+}
+
+static cursor_glide_t cursor_glide(cursor_glide_context_t* glide) {
+ cursor_glide_status_t* status = &glide->status;
+ cursor_glide_t report;
+ int32_t p;
+ int32_t x, y;
+
+ if (status->v0 == 0) {
+ report.dx = 0;
+ report.dy = 0;
+ report.valid = false;
+ cursor_glide_stop(glide);
+ goto exit;
+ }
+
+ status->counter++;
+ /* Calculate current 1D position */
+ p = status->v0 * status->counter - (int32_t)glide->config.coef * status->counter * status->counter / 2;
+ /*
+ * Translate to x & y axes
+ * Done this way instead of applying friction to each axis separately, so we don't end up with the shorter axis stuck at 0 towards the end of diagonal movements.
+ */
+ x = (int32_t)(p * status->dx0 / status->v0);
+ y = (int32_t)(p * status->dy0 / status->v0);
+ report.dx = (mouse_xy_report_t)(x - status->x);
+ report.dy = (mouse_xy_report_t)(y - status->y);
+ report.valid = true;
+ if (report.dx <= 1 && report.dx >= -1 && report.dy <= 1 && report.dy >= -1) {
+ /* Stop gliding once speed is low enough */
+ cursor_glide_stop(glide);
+ goto exit;
+ }
+ status->x = x;
+ status->y = y;
+ status->timer = timer_read();
+
+exit:
+ return report;
+}
+
+cursor_glide_t cursor_glide_check(cursor_glide_context_t* glide) {
+ cursor_glide_t invalid_report = {0, 0, false};
+ cursor_glide_status_t* status = &glide->status;
+
+ if (status->z || (status->dx0 == 0 && status->dy0 == 0) || timer_elapsed(status->timer) < glide->config.interval) {
+ return invalid_report;
+ } else {
+ return cursor_glide(glide);
+ }
+}
+
+static inline uint16_t sqrt32(uint32_t x) {
+ uint32_t l, m, h;
+
+ if (x == 0) {
+ return 0;
+ } else if (x > (UINT16_MAX >> 2)) {
+ /* Safe upper bound to avoid integer overflow with m * m */
+ h = UINT16_MAX;
+ } else {
+ /* Upper bound based on closest log2 */
+ h = (1 << (((__builtin_clzl(1) - __builtin_clzl(x) + 1) + 1) >> 1));
+ }
+ /* Lower bound based on closest log2 */
+ l = (1 << ((__builtin_clzl(1) - __builtin_clzl(x)) >> 1));
+
+ /* Binary search to find integer square root */
+ while (l != h - 1) {
+ m = (l + h) / 2;
+ if (m * m <= x) {
+ l = m;
+ } else {
+ h = m;
+ }
+ }
+ return l;
+}
+
+cursor_glide_t cursor_glide_start(cursor_glide_context_t* glide) {
+ cursor_glide_t invalid_report = {0, 0, false};
+ cursor_glide_status_t* status = &glide->status;
+
+ status->timer = timer_read();
+ status->counter = 0;
+ status->v0 = (status->dx0 == 0 && status->dy0 == 0) ? 0.0 : sqrt32(((int32_t)status->dx0 * 256 * status->dx0 * 256) + ((int32_t)status->dy0 * 256 * status->dy0 * 256)); // skip trigonometry if not needed, calculate distance in Q8
+ status->x = 0;
+ status->y = 0;
+ status->z = 0;
+
+ if (status->v0 < ((uint32_t)glide->config.trigger_px * 256)) { /* Q8 comparison */
+ /* Not enough velocity to be worth gliding, abort */
+ cursor_glide_stop(glide);
+ return invalid_report;
+ }
+
+ return cursor_glide(glide);
+}
+
+void cursor_glide_update(cursor_glide_context_t* glide, mouse_xy_report_t dx, mouse_xy_report_t dy, uint16_t z) {
+ cursor_glide_status_t* status = &glide->status;
+
+ status->dx0 = dx;
+ status->dy0 = dy;
+ status->z = z;
+}
+#endif
diff --git a/quantum/pointing_device_gestures.h b/quantum/pointing_device_gestures.h
new file mode 100644
index 0000000000..d2ea44971b
--- /dev/null
+++ b/quantum/pointing_device_gestures.h
@@ -0,0 +1,58 @@
+/* Copyright 2022 Daniel Kao <daniel.m.kao@gmail.com>
+ *
+ * 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 "report.h"
+
+#ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+typedef struct {
+ mouse_xy_report_t dx;
+ mouse_xy_report_t dy;
+ bool valid;
+} cursor_glide_t;
+
+typedef struct {
+ uint16_t trigger_px; /* Pixels of movement needed to trigger cursor glide */
+ uint16_t coef; /* Coefficient of friction */
+ uint16_t interval; /* Glide report interval, in milliseconds */
+} cursor_glide_config_t;
+
+typedef struct {
+ int32_t v0;
+ int32_t x;
+ int32_t y;
+ uint16_t z;
+ uint16_t timer;
+ uint16_t counter;
+ mouse_xy_report_t dx0;
+ mouse_xy_report_t dy0;
+} cursor_glide_status_t;
+
+typedef struct {
+ cursor_glide_config_t config;
+ cursor_glide_status_t status;
+} cursor_glide_context_t;
+
+/* Check glide report conditions, calculates glide coordinates */
+cursor_glide_t cursor_glide_check(cursor_glide_context_t* glide);
+
+/* Start glide reporting, gives first set of glide coordinates */
+cursor_glide_t cursor_glide_start(cursor_glide_context_t* glide);
+
+/* Update glide engine on the latest cursor movement, cursor glide is based on the final movement */
+void cursor_glide_update(cursor_glide_context_t* glide, mouse_xy_report_t dx, mouse_xy_report_t dy, uint16_t z);
+#endif
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c
index e6a7c01f2a..8cb45bc0ae 100644
--- a/quantum/process_keycode/process_auto_shift.c
+++ b/quantum/process_keycode/process_auto_shift.c
@@ -325,11 +325,13 @@ void autoshift_disable(void) {
# ifndef AUTO_SHIFT_NO_SETUP
void autoshift_timer_report(void) {
+# ifdef SEND_STRING_ENABLE
char display[8];
snprintf(display, 8, "\n%d\n", autoshift_timeout);
send_string((const char *)display);
+# endif
}
# endif
diff --git a/quantum/process_keycode/process_dynamic_macro.c b/quantum/process_keycode/process_dynamic_macro.c
index a1ada2d5a2..a7555fdd40 100644
--- a/quantum/process_keycode/process_dynamic_macro.c
+++ b/quantum/process_keycode/process_dynamic_macro.c
@@ -86,6 +86,9 @@ void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_
while (macro_buffer != macro_end) {
process_record(macro_buffer);
macro_buffer += direction;
+#ifdef DYNAMIC_MACRO_DELAY
+ wait_ms(DYNAMIC_MACRO_DELAY);
+#endif
}
clear_keyboard();
diff --git a/quantum/process_keycode/process_dynamic_tapping_term.c b/quantum/process_keycode/process_dynamic_tapping_term.c
index bdc5529e33..b682f34da6 100644
--- a/quantum/process_keycode/process_dynamic_tapping_term.c
+++ b/quantum/process_keycode/process_dynamic_tapping_term.c
@@ -22,12 +22,14 @@
#endif
static void tapping_term_report(void) {
+#ifdef SEND_STRING_ENABLE
const char *tapping_term_str = get_u16_str(g_tapping_term, ' ');
// Skip padding spaces
while (*tapping_term_str == ' ') {
tapping_term_str++;
}
send_string(tapping_term_str);
+#endif
}
bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record) {
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index c2fd02e5c7..ae00b3227a 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -64,6 +64,7 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
} else {
leading = false;
leader_end();
+ return true;
}
# ifdef LEADER_PER_KEY_TIMING
leader_time = timer_read();
diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c
index 10161adda3..ae60f29bf5 100644
--- a/quantum/process_keycode/process_magic.c
+++ b/quantum/process_keycode/process_magic.c
@@ -45,12 +45,16 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) {
case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
case MAGIC_TOGGLE_GUI:
case MAGIC_TOGGLE_CONTROL_CAPSLOCK:
+ case MAGIC_SWAP_ESCAPE_CAPSLOCK ... MAGIC_TOGGLE_ESCAPE_CAPSLOCK:
/* keymap config */
keymap_config.raw = eeconfig_read_keymap();
switch (keycode) {
case MAGIC_SWAP_CONTROL_CAPSLOCK:
keymap_config.swap_control_capslock = true;
break;
+ case MAGIC_SWAP_ESCAPE_CAPSLOCK:
+ keymap_config.swap_escape_capslock = true;
+ break;
case MAGIC_CAPSLOCK_TO_CONTROL:
keymap_config.capslock_to_control = true;
break;
@@ -94,6 +98,9 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) {
case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
keymap_config.swap_control_capslock = false;
break;
+ case MAGIC_UNSWAP_ESCAPE_CAPSLOCK:
+ keymap_config.swap_escape_capslock = false;
+ break;
case MAGIC_UNCAPSLOCK_TO_CONTROL:
keymap_config.capslock_to_control = false;
break;
@@ -172,6 +179,9 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) {
case MAGIC_TOGGLE_CONTROL_CAPSLOCK:
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
break;
+ case MAGIC_TOGGLE_ESCAPE_CAPSLOCK:
+ keymap_config.swap_escape_capslock = !keymap_config.swap_escape_capslock;
+ break;
}
eeconfig_update_keymap(keymap_config.raw);
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
index 12ee898212..20b8b9db4b 100644
--- a/quantum/process_keycode/process_steno.c
+++ b/quantum/process_keycode/process_steno.c
@@ -1,4 +1,4 @@
-/* Copyright 2017 Joseph Wasson
+/* Copyright 2017, 2022 Joseph Wasson, Vladislav Kucheriavykh
*
* 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
@@ -15,77 +15,118 @@
*/
#include "process_steno.h"
#include "quantum_keycodes.h"
-#include "eeprom.h"
#include "keymap_steno.h"
-#include "virtser.h"
#include <string.h>
+#ifdef VIRTSER_ENABLE
+# include "virtser.h"
+#endif
+#ifdef STENO_ENABLE_ALL
+# include "eeprom.h"
+#endif
-// TxBolt Codes
-#define TXB_NUL 0
-#define TXB_S_L 0b00000001
-#define TXB_T_L 0b00000010
-#define TXB_K_L 0b00000100
-#define TXB_P_L 0b00001000
-#define TXB_W_L 0b00010000
-#define TXB_H_L 0b00100000
-#define TXB_R_L 0b01000001
-#define TXB_A_L 0b01000010
-#define TXB_O_L 0b01000100
-#define TXB_STR 0b01001000
-#define TXB_E_R 0b01010000
-#define TXB_U_R 0b01100000
-#define TXB_F_R 0b10000001
-#define TXB_R_R 0b10000010
-#define TXB_P_R 0b10000100
-#define TXB_B_R 0b10001000
-#define TXB_L_R 0b10010000
-#define TXB_G_R 0b10100000
-#define TXB_T_R 0b11000001
-#define TXB_S_R 0b11000010
-#define TXB_D_R 0b11000100
-#define TXB_Z_R 0b11001000
-#define TXB_NUM 0b11010000
-
-#define TXB_GRP0 0b00000000
-#define TXB_GRP1 0b01000000
-#define TXB_GRP2 0b10000000
-#define TXB_GRP3 0b11000000
-#define TXB_GRPMASK 0b11000000
-
-#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
-
-#define BOLT_STATE_SIZE 4
-#define GEMINI_STATE_SIZE 6
-#define MAX_STATE_SIZE GEMINI_STATE_SIZE
-
-static uint8_t state[MAX_STATE_SIZE] = {0};
-static uint8_t chord[MAX_STATE_SIZE] = {0};
-static int8_t pressed = 0;
+// All steno keys that have been pressed to form this chord,
+// stored in MAX_STROKE_SIZE groups of 8-bit arrays.
+static uint8_t chord[MAX_STROKE_SIZE] = {0};
+// The number of physical keys actually being held down.
+// This is not always equal to the number of 1 bits in `chord` because it is possible to
+// simultaneously press down four keys, then release three of those four keys and then press yet
+// another key while the fourth finger is still holding down its key.
+// At the end of this scenario given as an example, `chord` would have five bits set to 1 but
+// `n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down.
+static int8_t n_pressed_keys = 0;
+
+#ifdef STENO_ENABLE_ALL
static steno_mode_t mode;
-
-static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L, TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL, TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R, TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R};
-
-#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_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U};
+#elif defined(STENO_ENABLE_GEMINI)
+static const steno_mode_t mode = STENO_MODE_GEMINI;
+#elif defined(STENO_ENABLE_BOLT)
+static const steno_mode_t mode = STENO_MODE_BOLT;
#endif
-static void steno_clear_state(void) {
- memset(state, 0, sizeof(state));
+static inline void steno_clear_chord(void) {
memset(chord, 0, sizeof(chord));
}
-static void send_steno_state(uint8_t size, bool send_empty) {
- for (uint8_t i = 0; i < size; ++i) {
- if (chord[i] || send_empty) {
-#ifdef VIRTSER_ENABLE
+#ifdef STENO_ENABLE_GEMINI
+
+# ifdef VIRTSER_ENABLE
+void send_steno_chord_gemini(void) {
+ // Set MSB to 1 to indicate the start of packet
+ chord[0] |= 0x80;
+ for (uint8_t i = 0; i < GEMINI_STROKE_SIZE; ++i) {
+ virtser_send(chord[i]);
+ }
+}
+# else
+# pragma message "VIRTSER_ENABLE = yes is required for Gemini PR to work properly out of the box!"
+# endif // VIRTSER_ENABLE
+
+/**
+ * @precondition: `key` is pressed
+ */
+bool add_gemini_key_to_chord(uint8_t key) {
+ // Although each group of the packet is 8 bits long, the MSB is reserved
+ // to indicate whether that byte is the first byte of the packet (MSB=1)
+ // or one of the remaining five bytes of the packet (MSB=0).
+ // As a consequence, only 7 out of the 8 bits are left to be used as a bit array
+ // for the steno keys of that group.
+ const int group_idx = key / 7;
+ const int intra_group_idx = key - group_idx * 7;
+ // The 0th steno key of the group has bit=0b01000000, the 1st has bit=0b00100000, etc.
+ const uint8_t bit = 1 << (6 - intra_group_idx);
+ chord[group_idx] |= bit;
+ return false;
+}
+#endif // STENO_ENABLE_GEMINI
+
+#ifdef STENO_ENABLE_BOLT
+
+# define TXB_GRP0 0b00000000
+# define TXB_GRP1 0b01000000
+# define TXB_GRP2 0b10000000
+# define TXB_GRP3 0b11000000
+# define TXB_GRPMASK 0b11000000
+
+# define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
+
+static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L, TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL, TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R, TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R};
+
+# ifdef VIRTSER_ENABLE
+static void send_steno_chord_bolt(void) {
+ for (uint8_t i = 0; i < BOLT_STROKE_SIZE; ++i) {
+ // TX Bolt uses variable length packets where each byte corresponds to a bit array of certain keys.
+ // If a user chorded the keys of the first group with keys of the last group, for example, there
+ // would be bytes of 0x00 in `chord` for the middle groups which we mustn't send.
+ if (chord[i]) {
virtser_send(chord[i]);
-#endif
}
}
+ // Sending a null packet is not always necessary, but it is simpler and more reliable
+ // to unconditionally send it every time instead of keeping track of more states and
+ // creating more branches in the execution of the program.
+ virtser_send(0);
}
+# else
+# pragma message "VIRTSER_ENABLE = yes is required for TX Bolt to work properly out of the box!"
+# endif // VIRTSER_ENABLE
+
+/**
+ * @precondition: `key` is pressed
+ */
+static bool add_bolt_key_to_chord(uint8_t key) {
+ uint8_t boltcode = pgm_read_byte(boltmap + key);
+ chord[TXB_GET_GROUP(boltcode)] |= boltcode;
+ return false;
+}
+#endif // STENO_ENABLE_BOLT
+
+#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_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
+#ifdef STENO_ENABLE_ALL
void steno_init() {
if (!eeconfig_is_enabled()) {
eeconfig_init();
@@ -94,19 +135,20 @@ void steno_init() {
}
void steno_set_mode(steno_mode_t new_mode) {
- steno_clear_state();
+ steno_clear_chord();
mode = new_mode;
eeprom_update_byte(EECONFIG_STENOMODE, mode);
}
+#endif // STENO_ENABLE_ALL
/* override to intercept chords right before they get sent.
* return zero to suppress normal sending behavior.
*/
-__attribute__((weak)) bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) {
+__attribute__((weak)) bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE]) {
return true;
}
-__attribute__((weak)) bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed) {
+__attribute__((weak)) bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE], int8_t n_pressed_keys) {
return true;
}
@@ -114,108 +156,94 @@ __attribute__((weak)) bool process_steno_user(uint16_t keycode, keyrecord_t *rec
return true;
}
-static void send_steno_chord(void) {
- if (send_steno_chord_user(mode, chord)) {
- switch (mode) {
- case STENO_MODE_BOLT:
- send_steno_state(BOLT_STATE_SIZE, false);
-#ifdef VIRTSER_ENABLE
- virtser_send(0); // terminating byte
-#endif
- break;
- case STENO_MODE_GEMINI:
- chord[0] |= 0x80; // Indicate start of packet
- send_steno_state(GEMINI_STATE_SIZE, true);
- break;
- }
+bool process_steno(uint16_t keycode, keyrecord_t *record) {
+ if (keycode < QK_STENO || keycode > QK_STENO_MAX) {
+ return true; // Not a steno key, pass it further along the chain
+ /*
+ * Clearing or sending the chord state is not necessary as we intentionally ignore whatever
+ * normal keyboard keys the user may have tapped while chording steno keys.
+ */
}
- steno_clear_state();
-}
-
-uint8_t *steno_get_state(void) {
- return &state[0];
-}
-
-uint8_t *steno_get_chord(void) {
- return &chord[0];
-}
-
-static bool update_state_bolt(uint8_t key, bool press) {
- uint8_t boltcode = pgm_read_byte(boltmap + key);
- if (press) {
- state[TXB_GET_GROUP(boltcode)] |= boltcode;
- chord[TXB_GET_GROUP(boltcode)] |= boltcode;
- } else {
- state[TXB_GET_GROUP(boltcode)] &= ~boltcode;
+ if (IS_NOEVENT(record->event)) {
+ return true;
}
- return false;
-}
-
-static bool update_state_gemini(uint8_t key, bool press) {
- int idx = key / 7;
- uint8_t bit = 1 << (6 - (key % 7));
- if (press) {
- state[idx] |= bit;
- chord[idx] |= bit;
- } else {
- state[idx] &= ~bit;
+ if (!process_steno_user(keycode, record)) {
+ return false; // User fully processed the steno key themselves
}
- return false;
-}
-
-bool process_steno(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
+#ifdef STENO_ENABLE_ALL
case QK_STENO_BOLT:
- if (!process_steno_user(keycode, record)) {
- return false;
- }
if (IS_PRESSED(record->event)) {
steno_set_mode(STENO_MODE_BOLT);
}
return false;
case QK_STENO_GEMINI:
- if (!process_steno_user(keycode, record)) {
- return false;
- }
if (IS_PRESSED(record->event)) {
steno_set_mode(STENO_MODE_GEMINI);
}
return false;
+#endif // STENO_ENABLE_ALL
#ifdef STENO_COMBINEDMAP
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);
- return result;
+ bool first_result = process_steno(combinedmap_first[keycode - QK_STENO_COMB], record);
+ bool second_result = process_steno(combinedmap_second[keycode - QK_STENO_COMB], record);
+ return first_result && second_result;
}
-#endif
+#endif // STENO_COMBINEDMAP
case STN__MIN ... STN__MAX:
- if (!process_steno_user(keycode, record)) {
- return false;
- }
- switch (mode) {
- case STENO_MODE_BOLT:
- update_state_bolt(keycode - QK_STENO, IS_PRESSED(record->event));
- break;
- case STENO_MODE_GEMINI:
- update_state_gemini(keycode - QK_STENO, IS_PRESSED(record->event));
- break;
- }
- // allow postprocessing hooks
- if (postprocess_steno_user(keycode, record, mode, chord, pressed)) {
- if (IS_PRESSED(record->event)) {
- ++pressed;
- } else {
- --pressed;
- if (pressed <= 0) {
- pressed = 0;
- send_steno_chord();
- }
+ if (IS_PRESSED(record->event)) {
+ n_pressed_keys++;
+ switch (mode) {
+#ifdef STENO_ENABLE_BOLT
+ case STENO_MODE_BOLT:
+ add_bolt_key_to_chord(keycode - QK_STENO);
+ break;
+#endif // STENO_ENABLE_BOLT
+#ifdef STENO_ENABLE_GEMINI
+ case STENO_MODE_GEMINI:
+ add_gemini_key_to_chord(keycode - QK_STENO);
+ break;
+#endif // STENO_ENABLE_GEMINI
+ default:
+ return false;
}
+ if (!postprocess_steno_user(keycode, record, mode, chord, n_pressed_keys)) {
+ return false;
+ }
+ } else { // is released
+ n_pressed_keys--;
+ if (!postprocess_steno_user(keycode, record, mode, chord, n_pressed_keys)) {
+ return false;
+ }
+ if (n_pressed_keys > 0) {
+ // User hasn't released all keys yet,
+ // so the chord cannot be sent
+ return false;
+ }
+ n_pressed_keys = 0;
+ if (!send_steno_chord_user(mode, chord)) {
+ steno_clear_chord();
+ return false;
+ }
+ switch (mode) {
+#if defined(STENO_ENABLE_BOLT) && defined(VIRTSER_ENABLE)
+ case STENO_MODE_BOLT:
+ send_steno_chord_bolt();
+ break;
+#endif // STENO_ENABLE_BOLT && VIRTSER_ENABLE
+#if defined(STENO_ENABLE_GEMINI) && defined(VIRTSER_ENABLE)
+ case STENO_MODE_GEMINI:
+ send_steno_chord_gemini();
+ break;
+#endif // STENO_ENABLE_GEMINI && VIRTSER_ENABLE
+ default:
+ break;
+ }
+ steno_clear_chord();
}
- return false;
+ break;
}
- return true;
+ return false;
}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
index d11fd40af0..68d6097b9b 100644
--- a/quantum/process_keycode/process_steno.h
+++ b/quantum/process_keycode/process_steno.h
@@ -18,10 +18,22 @@
#include "quantum.h"
-typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;
+#define BOLT_STROKE_SIZE 4
+#define GEMINI_STROKE_SIZE 6
-bool process_steno(uint16_t keycode, keyrecord_t *record);
-void steno_init(void);
-void steno_set_mode(steno_mode_t mode);
-uint8_t *steno_get_state(void);
-uint8_t *steno_get_chord(void);
+#ifdef STENO_ENABLE_GEMINI
+# define MAX_STROKE_SIZE GEMINI_STROKE_SIZE
+#else
+# define MAX_STROKE_SIZE BOLT_STROKE_SIZE
+#endif
+
+typedef enum {
+ STENO_MODE_GEMINI,
+ STENO_MODE_BOLT,
+} steno_mode_t;
+
+bool process_steno(uint16_t keycode, keyrecord_t *record);
+#ifdef STENO_ENABLE_ALL
+void steno_init(void);
+void steno_set_mode(steno_mode_t mode);
+#endif // STENO_ENABLE_ALL
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index db8df5f870..3270a1b000 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -15,12 +15,8 @@
*/
#include "quantum.h"
-#ifndef NO_ACTION_ONESHOT
-uint8_t get_oneshot_mods(void);
-#endif
-
-static uint16_t last_td;
-static int16_t highest_td = -1;
+static uint16_t active_td;
+static uint16_t last_tap_time;
void qk_tap_dance_pair_on_each_tap(qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
@@ -34,18 +30,14 @@ void qk_tap_dance_pair_on_each_tap(qk_tap_dance_state_t *state, void *user_data)
void qk_tap_dance_pair_finished(qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
- if (state->count == 1) {
- register_code16(pair->kc1);
- } else if (state->count == 2) {
- register_code16(pair->kc2);
- }
+ register_code16(pair->kc1);
}
void qk_tap_dance_pair_reset(qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
- wait_ms(TAP_CODE_DELAY);
if (state->count == 1) {
+ wait_ms(TAP_CODE_DELAY);
unregister_code16(pair->kc1);
} else if (state->count == 2) {
unregister_code16(pair->kc2);
@@ -87,23 +79,40 @@ static inline void _process_tap_dance_action_fn(qk_tap_dance_state_t *state, voi
}
static inline void process_tap_dance_action_on_each_tap(qk_tap_dance_action_t *action) {
+ action->state.count++;
+ action->state.weak_mods = get_mods();
+ action->state.weak_mods |= get_weak_mods();
+#ifndef NO_ACTION_ONESHOT
+ action->state.oneshot_mods = get_oneshot_mods();
+#endif
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_tap);
}
-static inline void process_tap_dance_action_on_dance_finished(qk_tap_dance_action_t *action) {
- if (action->state.finished) return;
- action->state.finished = true;
- add_mods(action->state.oneshot_mods);
- add_weak_mods(action->state.weak_mods);
- send_keyboard_report();
- _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished);
-}
-
static inline void process_tap_dance_action_on_reset(qk_tap_dance_action_t *action) {
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_reset);
- del_mods(action->state.oneshot_mods);
del_weak_mods(action->state.weak_mods);
+#ifndef NO_ACTION_ONESHOT
+ del_mods(action->state.oneshot_mods);
+#endif
send_keyboard_report();
+ action->state = (const qk_tap_dance_state_t){0};
+}
+
+static inline void process_tap_dance_action_on_dance_finished(qk_tap_dance_action_t *action) {
+ if (!action->state.finished) {
+ action->state.finished = true;
+ add_weak_mods(action->state.weak_mods);
+#ifndef NO_ACTION_ONESHOT
+ add_mods(action->state.oneshot_mods);
+#endif
+ send_keyboard_report();
+ _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished);
+ }
+ active_td = 0;
+ if (!action->state.pressed) {
+ // There will not be a key release event, so reset now.
+ process_tap_dance_action_on_reset(action);
+ }
}
void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
@@ -111,51 +120,33 @@ void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
if (!record->event.pressed) return;
- if (highest_td == -1) return;
-
- for (int i = 0; i <= highest_td; i++) {
- action = &tap_dance_actions[i];
- if (action->state.count) {
- if (keycode == action->state.keycode && keycode == last_td) continue;
- action->state.interrupted = true;
- action->state.interrupting_keycode = keycode;
- process_tap_dance_action_on_dance_finished(action);
- reset_tap_dance(&action->state);
-
- // Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with
- // modifiers), but these weak mods should not affect the keypress which interrupted the tap dance.
- clear_weak_mods();
- }
- }
+ if (!active_td || keycode == active_td) return;
+
+ action = &tap_dance_actions[TD_INDEX(active_td)];
+ action->state.interrupted = true;
+ action->state.interrupting_keycode = keycode;
+ process_tap_dance_action_on_dance_finished(action);
+
+ // Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with
+ // modifiers), but these weak mods should not affect the keypress which interrupted the tap dance.
+ clear_weak_mods();
}
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
- uint16_t idx = keycode - QK_TAP_DANCE;
qk_tap_dance_action_t *action;
switch (keycode) {
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
- if ((int16_t)idx > highest_td) highest_td = idx;
- action = &tap_dance_actions[idx];
+ action = &tap_dance_actions[TD_INDEX(keycode)];
action->state.pressed = record->event.pressed;
if (record->event.pressed) {
- action->state.keycode = keycode;
- action->state.count++;
- action->state.timer = timer_read();
-#ifndef NO_ACTION_ONESHOT
- action->state.oneshot_mods = get_oneshot_mods();
-#else
- action->state.oneshot_mods = 0;
-#endif
- action->state.weak_mods = get_mods();
- action->state.weak_mods |= get_weak_mods();
+ last_tap_time = timer_read();
process_tap_dance_action_on_each_tap(action);
-
- last_td = keycode;
+ active_td = action->state.finished ? 0 : keycode;
} else {
- if (action->state.count && action->state.finished) {
- reset_tap_dance(&action->state);
+ if (action->state.finished) {
+ process_tap_dance_action_on_reset(action);
}
}
@@ -166,35 +157,17 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
}
void tap_dance_task() {
- if (highest_td == -1) return;
- uint16_t tap_user_defined;
-
- for (uint8_t i = 0; i <= highest_td; i++) {
- qk_tap_dance_action_t *action = &tap_dance_actions[i];
- if (action->custom_tapping_term > 0) {
- tap_user_defined = action->custom_tapping_term;
- } else {
- tap_user_defined = GET_TAPPING_TERM(action->state.keycode, &(keyrecord_t){});
- }
- if (action->state.count && timer_elapsed(action->state.timer) > tap_user_defined) {
- process_tap_dance_action_on_dance_finished(action);
- reset_tap_dance(&action->state);
- }
- }
-}
-
-void reset_tap_dance(qk_tap_dance_state_t *state) {
qk_tap_dance_action_t *action;
- if (state->pressed) return;
+ if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
- action = &tap_dance_actions[state->keycode - QK_TAP_DANCE];
-
- process_tap_dance_action_on_reset(action);
+ action = &tap_dance_actions[TD_INDEX(active_td)];
+ if (!action->state.interrupted) {
+ process_tap_dance_action_on_dance_finished(action);
+ }
+}
- state->count = 0;
- state->interrupted = false;
- state->finished = false;
- state->interrupting_keycode = 0;
- last_td = 0;
+void reset_tap_dance(qk_tap_dance_state_t *state) {
+ active_td = 0;
+ process_tap_dance_action_on_reset((qk_tap_dance_action_t *)state);
}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index d9ffb1e73d..d97900d96b 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -22,30 +22,27 @@
# include <inttypes.h>
typedef struct {
+ uint16_t interrupting_keycode;
uint8_t count;
- uint8_t oneshot_mods;
uint8_t weak_mods;
- uint16_t keycode;
- uint16_t interrupting_keycode;
- uint16_t timer;
- bool interrupted;
- bool pressed;
- bool finished;
+# ifndef NO_ACTION_ONESHOT
+ uint8_t oneshot_mods;
+# endif
+ bool pressed : 1;
+ bool finished : 1;
+ bool interrupted : 1;
} qk_tap_dance_state_t;
-# define TD(n) (QK_TAP_DANCE | ((n)&0xFF))
-
typedef void (*qk_tap_dance_user_fn_t)(qk_tap_dance_state_t *state, void *user_data);
typedef struct {
+ qk_tap_dance_state_t state;
struct {
qk_tap_dance_user_fn_t on_each_tap;
qk_tap_dance_user_fn_t on_dance_finished;
qk_tap_dance_user_fn_t on_reset;
} fn;
- qk_tap_dance_state_t state;
- uint16_t custom_tapping_term;
- void * user_data;
+ void *user_data;
} qk_tap_dance_action_t;
typedef struct {
@@ -62,31 +59,31 @@ typedef struct {
# define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) \
{ .fn = {qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset}, .user_data = (void *)&((qk_tap_dance_pair_t){kc1, kc2}), }
-# define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) \
+# define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) \
{ .fn = {qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_move}), }
# define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \
{ .fn = {NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_invert}), }
-# define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) ACTION_TAP_DANCE_DUAL_ROLE(kc, layer)
-
# define ACTION_TAP_DANCE_FN(user_fn) \
{ .fn = {NULL, user_fn, NULL}, .user_data = NULL, }
# define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset) \
{ .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, }
-# define ACTION_TAP_DANCE_FN_ADVANCED_TIME(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, tap_specific_tapping_term) \
- { .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, .custom_tapping_term = tap_specific_tapping_term, }
+# define TD(n) (QK_TAP_DANCE | TD_INDEX(n))
+# define TD_INDEX(code) ((code)&0xFF)
+# define TAP_DANCE_KEYCODE(state) TD(((qk_tap_dance_action_t *)state) - tap_dance_actions)
extern qk_tap_dance_action_t tap_dance_actions[];
+void reset_tap_dance(qk_tap_dance_state_t *state);
+
/* To be used internally */
void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record);
bool process_tap_dance(uint16_t keycode, keyrecord_t *record);
void tap_dance_task(void);
-void reset_tap_dance(qk_tap_dance_state_t *state);
void qk_tap_dance_pair_on_each_tap(qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_pair_finished(qk_tap_dance_state_t *state, void *user_data);
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c
deleted file mode 100644
index da1c4d506f..0000000000
--- a/quantum/process_keycode/process_terminal.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* Copyright 2017 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 "process_terminal.h"
-#include <string.h>
-#include "version.h"
-#include <stdio.h>
-#include <math.h>
-
-#ifndef CMD_BUFF_SIZE
-# define CMD_BUFF_SIZE 5
-#endif
-
-bool terminal_enabled = false;
-char buffer[80] = "";
-char cmd_buffer[CMD_BUFF_SIZE][80];
-bool cmd_buffer_enabled = true; // replace with ifdef?
-char newline[2] = "\n";
-char arguments[6][20];
-bool firstTime = true;
-
-short int current_cmd_buffer_pos = 0; // used for up/down arrows - keeps track of where you are in the command buffer
-
-__attribute__((weak)) const char terminal_prompt[8] = "> ";
-
-#ifdef AUDIO_ENABLE
-# ifndef TERMINAL_SONG
-# define TERMINAL_SONG SONG(TERMINAL_SOUND)
-# endif
-float terminal_song[][2] = TERMINAL_SONG;
-# define TERMINAL_BELL() PLAY_SONG(terminal_song)
-#else
-# define TERMINAL_BELL()
-#endif
-
-__attribute__((weak)) const char keycode_to_ascii_lut[58] = {0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t', ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/'};
-
-__attribute__((weak)) const char shifted_keycode_to_ascii_lut[58] = {0, 0, 0, 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 0, 0, 0, '\t', ' ', '_', '+', '{', '}', '|', 0, ':', '\'', '~', '<', '>', '?'};
-
-struct stringcase {
- char *string;
- void (*func)(void);
-} typedef stringcase;
-
-void enable_terminal(void) {
- terminal_enabled = true;
- strcpy(buffer, "");
- memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80);
- for (int i = 0; i < 6; i++)
- strcpy(arguments[i], "");
- // select all text to start over
- // SEND_STRING(SS_LCTL("a"));
- send_string(terminal_prompt);
-}
-
-void disable_terminal(void) {
- terminal_enabled = false;
- SEND_STRING("\n");
-}
-
-void push_to_cmd_buffer(void) {
- if (cmd_buffer_enabled) {
- if (cmd_buffer == NULL) {
- return;
- } else {
- if (firstTime) {
- firstTime = false;
- strcpy(cmd_buffer[0], buffer);
- return;
- }
-
- for (int i = CMD_BUFF_SIZE - 1; i > 0; --i) {
- strncpy(cmd_buffer[i], cmd_buffer[i - 1], 80);
- }
-
- strcpy(cmd_buffer[0], buffer);
-
- return;
- }
- }
-}
-
-void terminal_about(void) {
- SEND_STRING("QMK Firmware\n");
- SEND_STRING(" v");
- SEND_STRING(QMK_VERSION);
- SEND_STRING("\n" SS_TAP(X_HOME) " Built: ");
- SEND_STRING(QMK_BUILDDATE);
- send_string(newline);
-#ifdef TERMINAL_HELP
- if (strlen(arguments[1]) != 0) {
- SEND_STRING("You entered: ");
- send_string(arguments[1]);
- send_string(newline);
- }
-#endif
-}
-
-void terminal_help(void);
-
-extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
-
-void terminal_keycode(void) {
- if (strlen(arguments[1]) != 0 && strlen(arguments[2]) != 0 && strlen(arguments[3]) != 0) {
- char keycode_dec[5];
- char keycode_hex[5];
- uint16_t layer = strtol(arguments[1], (char **)NULL, 10);
- uint16_t row = strtol(arguments[2], (char **)NULL, 10);
- uint16_t col = strtol(arguments[3], (char **)NULL, 10);
- uint16_t keycode = pgm_read_word(&keymaps[layer][row][col]);
- itoa(keycode, keycode_dec, 10);
- itoa(keycode, keycode_hex, 16);
- SEND_STRING("0x");
- send_string(keycode_hex);
- SEND_STRING(" (");
- send_string(keycode_dec);
- SEND_STRING(")\n");
- } else {
-#ifdef TERMINAL_HELP
- SEND_STRING("usage: keycode <layer> <row> <col>\n");
-#endif
- }
-}
-
-void terminal_keymap(void) {
- if (strlen(arguments[1]) != 0) {
- uint16_t layer = strtol(arguments[1], (char **)NULL, 10);
- for (int r = 0; r < MATRIX_ROWS; r++) {
- for (int c = 0; c < MATRIX_COLS; c++) {
- uint16_t keycode = pgm_read_word(&keymaps[layer][r][c]);
- char keycode_s[8];
- sprintf(keycode_s, "0x%04x,", keycode);
- send_string(keycode_s);
- }
- send_string(newline);
- }
- } else {
-#ifdef TERMINAL_HELP
- SEND_STRING("usage: keymap <layer>\n");
-#endif
- }
-}
-
-void print_cmd_buff(void) {
- /* without the below wait, a race condition can occur wherein the
- buffer can be printed before it has been fully moved */
- wait_ms(250);
- for (int i = 0; i < CMD_BUFF_SIZE; i++) {
- char tmpChar = ' ';
- itoa(i, &tmpChar, 10);
- const char *tmpCnstCharStr = &tmpChar; // because sned_string wont take a normal char *
- send_string(tmpCnstCharStr);
- SEND_STRING(". ");
- send_string(cmd_buffer[i]);
- SEND_STRING("\n");
- }
-}
-
-void flush_cmd_buffer(void) {
- memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80);
- SEND_STRING("Buffer Cleared!\n");
-}
-
-stringcase terminal_cases[] = {{"about", terminal_about}, {"help", terminal_help}, {"keycode", terminal_keycode}, {"keymap", terminal_keymap}, {"flush-buffer", flush_cmd_buffer}, {"print-buffer", print_cmd_buff}, {"exit", disable_terminal}};
-
-void terminal_help(void) {
- SEND_STRING("commands available:\n ");
- for (stringcase *case_p = terminal_cases; case_p != terminal_cases + sizeof(terminal_cases) / sizeof(terminal_cases[0]); case_p++) {
- send_string(case_p->string);
- SEND_STRING(" ");
- }
- send_string(newline);
-}
-
-void command_not_found(void) {
- wait_ms(50); // sometimes buffer isnt grabbed quick enough
- SEND_STRING("command \"");
- send_string(buffer);
- SEND_STRING("\" not found\n");
-}
-
-void process_terminal_command(void) {
- // we capture return bc of the order of events, so we need to manually send a newline
- send_string(newline);
-
- char * pch;
- uint8_t i = 0;
- pch = strtok(buffer, " ");
- while (pch != NULL) {
- strcpy(arguments[i], pch);
- pch = strtok(NULL, " ");
- i++;
- }
-
- bool command_found = false;
- for (stringcase *case_p = terminal_cases; case_p != terminal_cases + sizeof(terminal_cases) / sizeof(terminal_cases[0]); case_p++) {
- if (0 == strcmp(case_p->string, buffer)) {
- command_found = true;
- (*case_p->func)();
- break;
- }
- }
-
- if (!command_found) command_not_found();
-
- if (terminal_enabled) {
- strcpy(buffer, "");
- for (int i = 0; i < 6; i++)
- strcpy(arguments[i], "");
- SEND_STRING(SS_TAP(X_HOME));
- send_string(terminal_prompt);
- }
-}
-void check_pos(void) {
- if (current_cmd_buffer_pos >= CMD_BUFF_SIZE) { // if over the top, move it back down to the top of the buffer so you can climb back down...
- current_cmd_buffer_pos = CMD_BUFF_SIZE - 1;
- } else if (current_cmd_buffer_pos < 0) { //...and if you fall under the bottom of the buffer, reset back to 0 so you can climb back up
- current_cmd_buffer_pos = 0;
- }
-}
-
-bool process_terminal(uint16_t keycode, keyrecord_t *record) {
- if (keycode == TERM_ON && record->event.pressed) {
- enable_terminal();
- return false;
- }
-
- if (terminal_enabled && record->event.pressed) {
- if (keycode == TERM_OFF && record->event.pressed) {
- disable_terminal();
- return false;
- }
-
- if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
- keycode = keycode & 0xFF;
- }
-
- if (keycode < 256) {
- uint8_t str_len;
- char char_to_add;
- switch (keycode) {
- case KC_ENTER:
- case KC_KP_ENTER:
- push_to_cmd_buffer();
- current_cmd_buffer_pos = 0;
- process_terminal_command();
- return false;
- break;
- case KC_ESCAPE:
- SEND_STRING("\n");
- enable_terminal();
- return false;
- break;
- case KC_BACKSPACE:
- str_len = strlen(buffer);
- if (str_len > 0) {
- buffer[str_len - 1] = 0;
- return true;
- } else {
- TERMINAL_BELL();
- return false;
- }
- break;
- case KC_LEFT:
- return false;
- break;
- case KC_RIGHT:
- return false;
- break;
- case KC_UP: // 0 = recent
- check_pos(); // check our current buffer position is valid
- if (current_cmd_buffer_pos <= CMD_BUFF_SIZE - 1) { // once we get to the top, dont do anything
- 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_BACKSPACE,record);
- }
- strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 80);
-
- send_string(buffer);
- ++current_cmd_buffer_pos; // get ready to access the above cmd if up/down is pressed again
- }
- return false;
- break;
- case KC_DOWN:
- check_pos();
- if (current_cmd_buffer_pos >= 0) { // once we get to the bottom, dont do anything
- 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_BACKSPACE,record);
- }
- strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 79);
-
- send_string(buffer);
- --current_cmd_buffer_pos; // get ready to access the above cmd if down/up is pressed again
- }
- return false;
- break;
- default:
- if (keycode <= 58) {
- char_to_add = 0;
- 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];
- }
- if (char_to_add != 0) {
- strncat(buffer, &char_to_add, 1);
- }
- }
- break;
- }
- }
- }
- return true;
-}
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 33121f6b95..d1cfb5fbe0 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -307,9 +307,6 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef DYNAMIC_TAPPING_TERM_ENABLE
process_dynamic_tapping_term(keycode, record) &&
#endif
-#ifdef TERMINAL_ENABLE
- process_terminal(keycode, record) &&
-#endif
#ifdef SPACE_CADET_ENABLE
process_space_cadet(keycode, record) &&
#endif
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 92e1af1c40..f3a8a323c7 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -49,7 +49,6 @@
#include "action_util.h"
#include "action_tapping.h"
#include "print.h"
-#include "send_string.h"
#include "suspend.h"
#include <stddef.h>
#include <stdlib.h>
@@ -141,12 +140,6 @@ extern layer_state_t layer_state;
# include "process_key_lock.h"
#endif
-#ifdef TERMINAL_ENABLE
-# include "process_terminal.h"
-#else
-# include "process_terminal_nop.h"
-#endif
-
#ifdef SPACE_CADET_ENABLE
# include "process_space_cadet.h"
#endif
@@ -175,6 +168,10 @@ extern layer_state_t layer_state;
# include "hd44780.h"
#endif
+#ifdef SEND_STRING_ENABLE
+# include "send_string.h"
+#endif
+
#ifdef HAPTIC_ENABLE
# include "haptic.h"
# include "process_haptic.h"
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 40355d799a..456fad6f1b 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -473,9 +473,9 @@ enum quantum_keycodes {
// Lock Key
KC_LOCK, // 5D2B
- // Terminal
- TERM_ON, // 5D2C
- TERM_OFF, // 5D2D
+ // Unused slots
+ UNUSED_000, // 5D2C
+ UNUSED_001, // 5D2D
// Sequencer
SQ_ON, // 5D2E
@@ -605,6 +605,10 @@ enum quantum_keycodes {
CAPS_WORD,
+ MAGIC_SWAP_ESCAPE_CAPSLOCK,
+ MAGIC_UNSWAP_ESCAPE_CAPSLOCK,
+ MAGIC_TOGGLE_ESCAPE_CAPSLOCK,
+
// Start of custom keycode range for keyboards and keymaps - always leave at the end
SAFE_RANGE
};
@@ -756,6 +760,10 @@ enum quantum_keycodes {
#define CL_CAPS MAGIC_UNCAPSLOCK_TO_CONTROL
#define CL_TOGG MAGIC_TOGGLE_CONTROL_CAPSLOCK
+#define EC_SWAP MAGIC_SWAP_ESCAPE_CAPSLOCK
+#define EC_NORM MAGIC_UNSWAP_ESCAPE_CAPSLOCK
+#define EC_TOGG MAGIC_TOGGLE_ESCAPE_CAPSLOCK
+
#define LCG_SWP MAGIC_SWAP_LCTL_LGUI
#define LCG_NRM MAGIC_UNSWAP_LCTL_LGUI
#define RCG_SWP MAGIC_SWAP_RCTL_RGUI
diff --git a/quantum/quantum_keycodes_legacy.h b/quantum/quantum_keycodes_legacy.h
index ed9455ee74..51380d9c50 100644
--- a/quantum/quantum_keycodes_legacy.h
+++ b/quantum/quantum_keycodes_legacy.h
@@ -11,3 +11,6 @@
#define KC_GESC QK_GRAVE_ESCAPE
#define EEP_RST QK_CLEAR_EEPROM
+
+#define TERM_ON _Static_assert(false, "The Terminal feature has been removed from QMK. Please remove use of TERM_ON/TERM_OFF from your keymap.")
+#define TERM_OFF _Static_assert(false, "The Terminal feature has been removed from QMK.. Please remove use of TERM_ON/TERM_OFF from your keymap.") \ No newline at end of file
diff --git a/quantum/rgb_matrix/animations/pixel_rain_anim.h b/quantum/rgb_matrix/animations/pixel_rain_anim.h
index 03488b43df..ce2528a26d 100644
--- a/quantum/rgb_matrix/animations/pixel_rain_anim.h
+++ b/quantum/rgb_matrix/animations/pixel_rain_anim.h
@@ -20,17 +20,14 @@ RGB_MATRIX_EFFECT(PIXEL_RAIN)
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) {
+ void rain_pixel(uint8_t i, effect_params_t * params, bool off) {
if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) {
- return true;
+ return;
}
if (off) {
rgb_matrix_set_color(i, 0, 0, 0);
@@ -40,10 +37,13 @@ static bool PIXEL_RAIN(effect_params_t* params) {
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);
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
+ if (g_rgb_timer > wait_timer) {
+ rain_pixel(mod8(random8(), DRIVER_LED_TOTAL), params, random8() & 2);
+ }
+ return rgb_matrix_check_finished_leds(led_max);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h
index 2d4b53b7b0..a508e51183 100644
--- a/quantum/rgb_matrix/animations/raindrops_anim.h
+++ b/quantum/rgb_matrix/animations/raindrops_anim.h
@@ -14,23 +14,22 @@ static void raindrops_set_color(int i, effect_params_t* params) {
deltaH += 256;
}
- hsv.h = rgb_matrix_config.hsv.h + (deltaH * (rand() & 0x03));
+ hsv.h = rgb_matrix_config.hsv.h + (deltaH * (random8() & 0x03));
RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool RAINDROPS(effect_params_t* params) {
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
if (!params->init) {
// Change one LED every tick, make sure speed is not 0
if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) {
- raindrops_set_color(rand() % DRIVER_LED_TOTAL, params);
+ raindrops_set_color(random8() % DRIVER_LED_TOTAL, params);
+ }
+ } else {
+ for (int i = led_min; i < led_max; i++) {
+ raindrops_set_color(i, params);
}
- return false;
- }
-
- RGB_MATRIX_USE_LIMITS(led_min, led_max);
- for (int i = led_min; i < led_max; i++) {
- raindrops_set_color(i, params);
}
return rgb_matrix_check_finished_leds(led_max);
}
diff --git a/quantum/rgb_matrix/animations/solid_reactive_anim.h b/quantum/rgb_matrix/animations/solid_reactive_anim.h
index d3a7ebbdf7..052bfb22fd 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_anim.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_anim.h
@@ -4,6 +4,9 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
static HSV SOLID_REACTIVE_math(HSV hsv, uint16_t offset) {
+# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+ hsv.h = scale16by8(g_rgb_timer, add8(rgb_matrix_config.speed, 1) >> 6);
+# endif
hsv.h += qsub8(130, offset);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/solid_reactive_cross.h b/quantum/rgb_matrix/animations/solid_reactive_cross.h
index 043a369b73..9e5703a0ea 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_cross.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_cross.h
@@ -19,6 +19,9 @@ static HSV SOLID_REACTIVE_CROSS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t di
dy = dy * 16 > 255 ? 255 : dy * 16;
effect += dx > dy ? dy : dx;
if (effect > 255) effect = 255;
+# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+ hsv.h = scale16by8(g_rgb_timer, add8(rgb_matrix_config.speed, 1) >> 6);
+# endif
hsv.v = qadd8(hsv.v, 255 - effect);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/solid_reactive_nexus.h b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
index 8d62a49fea..64f5064cf9 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_nexus.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
@@ -16,6 +16,9 @@ static HSV SOLID_REACTIVE_NEXUS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t di
if (effect > 255) effect = 255;
if (dist > 72) effect = 255;
if ((dx > 8 || dx < -8) && (dy > 8 || dy < -8)) effect = 255;
+# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+ hsv.h = scale16by8(g_rgb_timer, add8(rgb_matrix_config.speed, 1) >> 6);
+# endif
hsv.v = qadd8(hsv.v, 255 - effect);
hsv.h = rgb_matrix_config.hsv.h + dy / 4;
return hsv;
diff --git a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
index 0d0a424cf3..bd3ce0817d 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
@@ -4,6 +4,9 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
static HSV SOLID_REACTIVE_SIMPLE_math(HSV hsv, uint16_t offset) {
+# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+ hsv.h = scale16by8(g_rgb_timer, add8(rgb_matrix_config.speed, 1) >> 6);
+# endif
hsv.v = scale8(255 - offset, hsv.v);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/solid_reactive_wide.h b/quantum/rgb_matrix/animations/solid_reactive_wide.h
index 7598796316..24fedc2020 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_wide.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_wide.h
@@ -14,6 +14,9 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE)
static HSV SOLID_REACTIVE_WIDE_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick + dist * 5;
if (effect > 255) effect = 255;
+# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
+ hsv.h = scale16by8(g_rgb_timer, add8(rgb_matrix_config.speed, 1) >> 6);
+# endif
hsv.v = qadd8(hsv.v, 255 - effect);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/typing_heatmap_anim.h b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
index 4b17c4c3ed..a05c07760e 100644
--- a/quantum/rgb_matrix/animations/typing_heatmap_anim.h
+++ b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
@@ -6,30 +6,41 @@ RGB_MATRIX_EFFECT(TYPING_HEATMAP)
# define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 25
# endif
+# ifndef RGB_MATRIX_TYPING_HEATMAP_SPREAD
+# define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40
+# endif
+
+# ifndef RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT
+# define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16
+# endif
void process_rgb_matrix_typing_heatmap(uint8_t row, uint8_t col) {
# ifdef RGB_MATRIX_TYPING_HEATMAP_SLIM
// Limit effect to pressed keys
g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], 32);
# else
- uint8_t m_row = row - 1;
- uint8_t p_row = row + 1;
- uint8_t m_col = col - 1;
- uint8_t p_col = col + 1;
-
- if (m_col < col) g_rgb_frame_buffer[row][m_col] = qadd8(g_rgb_frame_buffer[row][m_col], 16);
- g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], 32);
- if (p_col < MATRIX_COLS) g_rgb_frame_buffer[row][p_col] = qadd8(g_rgb_frame_buffer[row][p_col], 16);
-
- if (p_row < MATRIX_ROWS) {
- if (m_col < col) g_rgb_frame_buffer[p_row][m_col] = qadd8(g_rgb_frame_buffer[p_row][m_col], 13);
- g_rgb_frame_buffer[p_row][col] = qadd8(g_rgb_frame_buffer[p_row][col], 16);
- if (p_col < MATRIX_COLS) g_rgb_frame_buffer[p_row][p_col] = qadd8(g_rgb_frame_buffer[p_row][p_col], 13);
+ if (g_led_config.matrix_co[row][col] == NO_LED) { // skip as pressed key doesn't have an led position
+ return;
}
-
- if (m_row < row) {
- if (m_col < col) g_rgb_frame_buffer[m_row][m_col] = qadd8(g_rgb_frame_buffer[m_row][m_col], 13);
- g_rgb_frame_buffer[m_row][col] = qadd8(g_rgb_frame_buffer[m_row][col], 16);
- if (p_col < MATRIX_COLS) g_rgb_frame_buffer[m_row][p_col] = qadd8(g_rgb_frame_buffer[m_row][p_col], 13);
+ for (uint8_t i_row = 0; i_row < MATRIX_ROWS; i_row++) {
+ for (uint8_t i_col = 0; i_col < MATRIX_COLS; i_col++) {
+ if (g_led_config.matrix_co[i_row][i_col] == NO_LED) { // skip as target key doesn't have an led position
+ continue;
+ }
+ if (i_row == row && i_col == col) {
+ g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], 32);
+ } else {
+# define LED_DISTANCE(led_a, led_b) sqrt16(((int8_t)(led_a.x - led_b.x) * (int8_t)(led_a.x - led_b.x)) + ((int8_t)(led_a.y - led_b.y) * (int8_t)(led_a.y - led_b.y)))
+ uint8_t distance = LED_DISTANCE(g_led_config.point[g_led_config.matrix_co[row][col]], g_led_config.point[g_led_config.matrix_co[i_row][i_col]]);
+# undef LED_DISTANCE
+ if (distance <= RGB_MATRIX_TYPING_HEATMAP_SPREAD) {
+ uint8_t amount = qsub8(RGB_MATRIX_TYPING_HEATMAP_SPREAD, distance);
+ if (amount > RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT) {
+ amount = RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT;
+ }
+ g_rgb_frame_buffer[i_row][i_col] = qadd8(g_rgb_frame_buffer[i_row][i_col], amount);
+ }
+ }
+ }
}
# endif
}
@@ -40,10 +51,7 @@ static uint16_t heatmap_decrease_timer;
static bool decrease_heatmap_values;
bool TYPING_HEATMAP(effect_params_t* params) {
- // Modified version of RGB_MATRIX_USE_LIMITS to work off of matrix row / col size
- uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter;
- uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT;
- if (led_max > sizeof(g_rgb_frame_buffer)) led_max = sizeof(g_rgb_frame_buffer);
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
if (params->init) {
rgb_matrix_set_color_all(0, 0, 0);
@@ -63,28 +71,26 @@ bool TYPING_HEATMAP(effect_params_t* params) {
}
// Render heatmap & decrease
- for (int i = led_min; i < led_max; i++) {
- uint8_t row = i % MATRIX_ROWS;
- uint8_t col = i / MATRIX_ROWS;
- uint8_t val = g_rgb_frame_buffer[row][col];
-
- // set the pixel colour
- uint8_t led[LED_HITS_TO_REMEMBER];
- uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
- for (uint8_t j = 0; j < led_count; ++j) {
- if (!HAS_ANY_FLAGS(g_led_config.flags[led[j]], params->flags)) continue;
-
- HSV hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
- rgb_matrix_set_color(led[j], rgb.r, rgb.g, rgb.b);
- }
-
- if (decrease_heatmap_values) {
- g_rgb_frame_buffer[row][col] = qsub8(val, 1);
+ uint8_t count = 0;
+ for (uint8_t row = 0; row < MATRIX_ROWS && count < RGB_MATRIX_LED_PROCESS_LIMIT; row++) {
+ for (uint8_t col = 0; col < MATRIX_COLS && RGB_MATRIX_LED_PROCESS_LIMIT; col++) {
+ if (g_led_config.matrix_co[row][col] >= led_min && g_led_config.matrix_co[row][col] < led_max) {
+ count++;
+ uint8_t val = g_rgb_frame_buffer[row][col];
+ if (!HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[row][col]], params->flags)) continue;
+
+ HSV hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
+ RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_matrix_set_color(g_led_config.matrix_co[row][col], rgb.r, rgb.g, rgb.b);
+
+ if (decrease_heatmap_values) {
+ g_rgb_frame_buffer[row][col] = qsub8(val, 1);
+ }
+ }
}
}
- return led_max < sizeof(g_rgb_frame_buffer);
+ 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 f721dfc7f2..2730686839 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -249,8 +249,15 @@ void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) {
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
- if (rgb_matrix_config.mode == RGB_MATRIX_TYPING_HEATMAP) {
- process_rgb_matrix_typing_heatmap(row, col);
+# if defined(RGB_MATRIX_KEYRELEASES)
+ if (!pressed)
+# else
+ if (pressed)
+# endif // defined(RGB_MATRIX_KEYRELEASES)
+ {
+ if (rgb_matrix_config.mode == RGB_MATRIX_TYPING_HEATMAP) {
+ process_rgb_matrix_typing_heatmap(row, col);
+ }
}
#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
}
@@ -724,10 +731,20 @@ void rgb_matrix_decrease_speed(void) {
rgb_matrix_decrease_speed_helper(true);
}
+void rgb_matrix_set_flags_eeprom_helper(led_flags_t flags, bool write_to_eeprom) {
+ rgb_matrix_config.flags = flags;
+ eeconfig_flag_rgb_matrix(write_to_eeprom);
+ dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.flags);
+}
+
led_flags_t rgb_matrix_get_flags(void) {
return rgb_matrix_config.flags;
}
void rgb_matrix_set_flags(led_flags_t flags) {
- rgb_matrix_config.flags = flags;
+ rgb_matrix_set_flags_eeprom_helper(flags, true);
+}
+
+void rgb_matrix_set_flags_noeeprom(led_flags_t flags) {
+ rgb_matrix_set_flags_eeprom_helper(flags, false);
}
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index 359d507a4d..fc9fc3e020 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -182,6 +182,7 @@ void rgb_matrix_increase_speed_noeeprom(void);
void rgb_matrix_decrease_speed(void);
void rgb_matrix_decrease_speed_noeeprom(void);
led_flags_t rgb_matrix_get_flags(void);
+led_flags_t rgb_matrix_get_flags_noeeprom(void);
void rgb_matrix_set_flags(led_flags_t flags);
#ifndef RGBLIGHT_ENABLE
diff --git a/quantum/send_string.h b/quantum/send_string.h
deleted file mode 100644
index b90e6f6890..0000000000
--- a/quantum/send_string.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright 2021
- *
- * 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 <stdint.h>
-
-#include "progmem.h"
-#include "send_string_keycodes.h"
-
-#define SEND_STRING(string) send_string_P(PSTR(string))
-#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
-
-// Look-Up Tables (LUTs) to convert ASCII character to keycode sequence.
-extern const uint8_t ascii_to_shift_lut[16];
-extern const uint8_t ascii_to_altgr_lut[16];
-extern const uint8_t ascii_to_dead_lut[16];
-extern const uint8_t ascii_to_keycode_lut[128];
-
-// clang-format off
-#define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \
- ( ((a) ? 1 : 0) << 0 \
- | ((b) ? 1 : 0) << 1 \
- | ((c) ? 1 : 0) << 2 \
- | ((d) ? 1 : 0) << 3 \
- | ((e) ? 1 : 0) << 4 \
- | ((f) ? 1 : 0) << 5 \
- | ((g) ? 1 : 0) << 6 \
- | ((h) ? 1 : 0) << 7 )
-// clang-format on
-
-void send_string(const char *str);
-void send_string_with_delay(const char *str, uint8_t interval);
-void send_string_P(const char *str);
-void send_string_with_delay_P(const char *str, uint8_t interval);
-void send_char(char ascii_code);
-
-void send_dword(uint32_t number);
-void send_word(uint16_t number);
-void send_byte(uint8_t number);
-void send_nibble(uint8_t number);
-
-void tap_random_base64(void);
diff --git a/quantum/send_string.c b/quantum/send_string/send_string.c
index 0de12ba12d..818a52f6dc 100644
--- a/quantum/send_string.c
+++ b/quantum/send_string/send_string.c
@@ -142,40 +142,36 @@ __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// Note: we bit-pack in "reverse" order to optimize loading
#define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01)
-void send_string(const char *str) {
- send_string_with_delay(str, 0);
+void send_string(const char *string) {
+ send_string_with_delay(string, 0);
}
-void send_string_P(const char *str) {
- send_string_with_delay_P(str, 0);
-}
-
-void send_string_with_delay(const char *str, uint8_t interval) {
+void send_string_with_delay(const char *string, uint8_t interval) {
while (1) {
- char ascii_code = *str;
+ char ascii_code = *string;
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
- ascii_code = *(++str);
+ ascii_code = *(++string);
if (ascii_code == SS_TAP_CODE) {
// tap
- uint8_t keycode = *(++str);
+ uint8_t keycode = *(++string);
tap_code(keycode);
} else if (ascii_code == SS_DOWN_CODE) {
// down
- uint8_t keycode = *(++str);
+ uint8_t keycode = *(++string);
register_code(keycode);
} else if (ascii_code == SS_UP_CODE) {
// up
- uint8_t keycode = *(++str);
+ uint8_t keycode = *(++string);
unregister_code(keycode);
} else if (ascii_code == SS_DELAY_CODE) {
// delay
int ms = 0;
- uint8_t keycode = *(++str);
+ uint8_t keycode = *(++string);
while (isdigit(keycode)) {
ms *= 10;
ms += keycode - '0';
- keycode = *(++str);
+ keycode = *(++string);
}
while (ms--)
wait_ms(1);
@@ -183,50 +179,7 @@ void send_string_with_delay(const char *str, uint8_t interval) {
} else {
send_char(ascii_code);
}
- ++str;
- // interval
- {
- uint8_t ms = interval;
- while (ms--)
- wait_ms(1);
- }
- }
-}
-
-void send_string_with_delay_P(const char *str, uint8_t interval) {
- while (1) {
- char ascii_code = pgm_read_byte(str);
- if (!ascii_code) break;
- if (ascii_code == SS_QMK_PREFIX) {
- ascii_code = pgm_read_byte(++str);
- if (ascii_code == SS_TAP_CODE) {
- // tap
- uint8_t keycode = pgm_read_byte(++str);
- tap_code(keycode);
- } else if (ascii_code == SS_DOWN_CODE) {
- // down
- uint8_t keycode = pgm_read_byte(++str);
- register_code(keycode);
- } else if (ascii_code == SS_UP_CODE) {
- // up
- uint8_t keycode = pgm_read_byte(++str);
- unregister_code(keycode);
- } else if (ascii_code == SS_DELAY_CODE) {
- // delay
- int ms = 0;
- uint8_t keycode = pgm_read_byte(++str);
- while (isdigit(keycode)) {
- ms *= 10;
- ms += keycode - '0';
- keycode = pgm_read_byte(++str);
- }
- while (ms--)
- wait_ms(1);
- }
- } else {
- send_char(ascii_code);
- }
- ++str;
+ ++string;
// interval
{
uint8_t ms = interval;
@@ -250,17 +203,17 @@ void send_char(char ascii_code) {
bool is_dead = PGM_LOADBIT(ascii_to_dead_lut, (uint8_t)ascii_code);
if (is_shifted) {
- register_code(KC_LSFT);
+ register_code(KC_LEFT_SHIFT);
}
if (is_altgred) {
- register_code(KC_RALT);
+ register_code(KC_RIGHT_ALT);
}
tap_code(keycode);
if (is_altgred) {
- unregister_code(KC_RALT);
+ unregister_code(KC_RIGHT_ALT);
}
if (is_shifted) {
- unregister_code(KC_LSFT);
+ unregister_code(KC_LEFT_SHIFT);
}
if (is_dead) {
tap_code(KC_SPACE);
@@ -320,3 +273,52 @@ void tap_random_base64(void) {
break;
}
}
+
+#if defined(__AVR__)
+void send_string_P(const char *string) {
+ send_string_with_delay_P(string, 0);
+}
+
+void send_string_with_delay_P(const char *string, uint8_t interval) {
+ while (1) {
+ char ascii_code = pgm_read_byte(string);
+ if (!ascii_code) break;
+ if (ascii_code == SS_QMK_PREFIX) {
+ ascii_code = pgm_read_byte(++string);
+ if (ascii_code == SS_TAP_CODE) {
+ // tap
+ uint8_t keycode = pgm_read_byte(++string);
+ tap_code(keycode);
+ } else if (ascii_code == SS_DOWN_CODE) {
+ // down
+ uint8_t keycode = pgm_read_byte(++string);
+ register_code(keycode);
+ } else if (ascii_code == SS_UP_CODE) {
+ // up
+ uint8_t keycode = pgm_read_byte(++string);
+ unregister_code(keycode);
+ } else if (ascii_code == SS_DELAY_CODE) {
+ // delay
+ int ms = 0;
+ uint8_t keycode = pgm_read_byte(++string);
+ while (isdigit(keycode)) {
+ ms *= 10;
+ ms += keycode - '0';
+ keycode = pgm_read_byte(++string);
+ }
+ while (ms--)
+ wait_ms(1);
+ }
+ } else {
+ send_char(ascii_code);
+ }
+ ++string;
+ // interval
+ {
+ uint8_t ms = interval;
+ while (ms--)
+ wait_ms(1);
+ }
+ }
+}
+#endif
diff --git a/quantum/send_string/send_string.h b/quantum/send_string/send_string.h
new file mode 100644
index 0000000000..4eb55b88dc
--- /dev/null
+++ b/quantum/send_string/send_string.h
@@ -0,0 +1,152 @@
+/* Copyright 2021
+ *
+ * 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/>.
+ */
+
+/**
+ * \defgroup send_string
+ *
+ * Send String API. These functions allow you to create macros by typing out sequences of keystrokes.
+ * \{
+ */
+
+#include <stdint.h>
+
+#include "progmem.h"
+#include "send_string_keycodes.h"
+
+// Look-Up Tables (LUTs) to convert ASCII character to keycode sequence.
+extern const uint8_t ascii_to_shift_lut[16];
+extern const uint8_t ascii_to_altgr_lut[16];
+extern const uint8_t ascii_to_dead_lut[16];
+extern const uint8_t ascii_to_keycode_lut[128];
+
+// clang-format off
+#define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \
+ ( ((a) ? 1 : 0) << 0 \
+ | ((b) ? 1 : 0) << 1 \
+ | ((c) ? 1 : 0) << 2 \
+ | ((d) ? 1 : 0) << 3 \
+ | ((e) ? 1 : 0) << 4 \
+ | ((f) ? 1 : 0) << 5 \
+ | ((g) ? 1 : 0) << 6 \
+ | ((h) ? 1 : 0) << 7 )
+// clang-format on
+
+/**
+ * \brief Type out a string of ASCII characters.
+ *
+ * This function simply calls `send_string_with_delay(string, 0)`.
+ *
+ * Most keycodes from the basic keycode range are also supported by way of a special sequence - see `send_string_keycodes.h`.
+ *
+ * \param string The string to type out.
+ */
+void send_string(const char *string);
+
+/**
+ * \brief Type out a string of ASCII characters, with a delay between each character.
+ *
+ * \param string The string to type out.
+ * \param interval The amount of time, in milliseconds, to wait before typing the next character.
+ */
+void send_string_with_delay(const char *string, uint8_t interval);
+
+/**
+ * \brief Type out an ASCII character.
+ *
+ * \param ascii_code The character to type.
+ */
+void send_char(char ascii_code);
+
+/**
+ * \brief Type out an eight digit (unsigned 32-bit) hexadecimal value.
+ *
+ * The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`.
+ *
+ * \param number The value to type, from 0 to 4,294,967,295.
+ */
+void send_dword(uint32_t number);
+
+/**
+ * \brief Type out a four digit (unsigned 16-bit) hexadecimal value.
+ *
+ * The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`.
+ *
+ * \param number The value to type, from 0 to 65,535.
+ */
+void send_word(uint16_t number);
+
+/**
+ * \brief Type out a two digit (8-bit) hexadecimal value.
+ *
+ * The format is `[0-9a-f]{2}`, eg. `00` through `ff`.
+ *
+ * \param number The value to type, from 0 to 255.
+ */
+void send_byte(uint8_t number);
+
+/**
+ * \brief Type out a single hexadecimal digit.
+ *
+ * The format is `[0-9a-f]{1}`, eg. `0` through `f`.
+ *
+ * \param number The value to type, from 0 to 15.
+ */
+void send_nibble(uint8_t number);
+
+/**
+ * \brief Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
+ */
+void tap_random_base64(void);
+
+#if defined(__AVR__) || defined(__DOXYGEN__)
+/**
+ * \brief Type out a PROGMEM string of ASCII characters.
+ *
+ * On ARM devices, this function is simply an alias for send_string_with_delay(string, 0).
+ *
+ * \param string The string to type out.
+ */
+void send_string_P(const char *string);
+
+/**
+ * \brief Type out a PROGMEM string of ASCII characters, with a delay between each character.
+ *
+ * On ARM devices, this function is simply an alias for send_string_with_delay(string, interval).
+ *
+ * \param string The string to type out.
+ * \param interval The amount of time, in milliseconds, to wait before typing the next character.
+ */
+void send_string_with_delay_P(const char *string, uint8_t interval);
+#else
+# define send_string_P(string) send_string_with_delay(string, 0)
+# define send_string_with_delay_P(string, interval) send_string_with_delay(string, interval)
+#endif
+
+/**
+ * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), 0).
+ *
+ * On ARM devices, this define evaluates to send_string_with_delay(string, 0).
+ */
+#define SEND_STRING(string) send_string_with_delay_P(PSTR(string), 0)
+
+/**
+ * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), interval).
+ *
+ * On ARM devices, this define evaluates to send_string_with_delay(string, interval).
+ */
+#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
+
+/** \} */
diff --git a/quantum/send_string/send_string_keycodes.h b/quantum/send_string/send_string_keycodes.h
new file mode 100644
index 0000000000..7017e03d5a
--- /dev/null
+++ b/quantum/send_string/send_string_keycodes.h
@@ -0,0 +1,434 @@
+/* Copyright 2019
+ *
+ * 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
+
+// clang-format off
+
+/* Punctuation */
+#define X_ENT X_ENTER
+#define X_ESC X_ESCAPE
+#define X_BSPC X_BSPACE
+#define X_SPC X_SPACE
+#define X_MINS X_MINUS
+#define X_EQL X_EQUAL
+#define X_LBRC X_LBRACKET
+#define X_RBRC X_RBRACKET
+#define X_BSLS X_BSLASH
+#define X_NUHS X_NONUS_HASH
+#define X_SCLN X_SCOLON
+#define X_QUOT X_QUOTE
+#define X_GRV X_GRAVE
+#define X_COMM X_COMMA
+#define X_SLSH X_SLASH
+#define X_NUBS X_NONUS_BSLASH
+
+/* Lock Keys */
+#define X_CLCK X_CAPSLOCK
+#define X_CAPS X_CAPSLOCK
+#define X_SLCK X_SCROLLLOCK
+#define X_NLCK X_NUMLOCK
+#define X_LCAP X_LOCKING_CAPS
+#define X_LNUM X_LOCKING_NUM
+#define X_LSCR X_LOCKING_SCROLL
+
+/* Commands */
+#define X_PSCR X_PSCREEN
+#define X_PAUS X_PAUSE
+#define X_BRK X_PAUSE
+#define X_INS X_INSERT
+#define X_DEL X_DELETE
+#define X_PGDN X_PGDOWN
+#define X_RGHT X_RIGHT
+#define X_APP X_APPLICATION
+#define X_EXEC X_EXECUTE
+#define X_SLCT X_SELECT
+#define X_AGIN X_AGAIN
+#define X_PSTE X_PASTE
+#define X_ERAS X_ALT_ERASE
+#define X_CLR X_CLEAR
+
+/* Keypad */
+#define X_PSLS X_KP_SLASH
+#define X_PAST X_KP_ASTERISK
+#define X_PMNS X_KP_MINUS
+#define X_PPLS X_KP_PLUS
+#define X_PENT X_KP_ENTER
+#define X_P1 X_KP_1
+#define X_P2 X_KP_2
+#define X_P3 X_KP_3
+#define X_P4 X_KP_4
+#define X_P5 X_KP_5
+#define X_P6 X_KP_6
+#define X_P7 X_KP_7
+#define X_P8 X_KP_8
+#define X_P9 X_KP_9
+#define X_P0 X_KP_0
+#define X_PDOT X_KP_DOT
+#define X_PEQL X_KP_EQUAL
+#define X_PCMM X_KP_COMMA
+
+/* Japanese specific */
+#define X_ZKHK X_GRAVE
+#define X_RO X_INT1
+#define X_KANA X_INT2
+#define X_JYEN X_INT3
+#define X_HENK X_INT4
+#define X_MHEN X_INT5
+
+/* Korean specific */
+#define X_HAEN X_LANG1
+#define X_HANJ X_LANG2
+
+/* Modifiers */
+#define X_LCTL X_LCTRL
+#define X_LSFT X_LSHIFT
+#define X_LOPT X_LALT
+#define X_LCMD X_LGUI
+#define X_LWIN X_LGUI
+#define X_RCTL X_RCTRL
+#define X_RSFT X_RSHIFT
+#define X_ALGR X_RALT
+#define X_ROPT X_RALT
+#define X_RCMD X_RGUI
+#define X_RWIN X_RGUI
+
+/* Generic Desktop Page (0x01) */
+#define X_PWR X_SYSTEM_POWER
+#define X_SLEP X_SYSTEM_SLEEP
+#define X_WAKE X_SYSTEM_WAKE
+
+/* Consumer Page (0x0C) */
+#define X_MUTE X_AUDIO_MUTE
+#define X_VOLU X_AUDIO_VOL_UP
+#define X_VOLD X_AUDIO_VOL_DOWN
+#define X_MNXT X_MEDIA_NEXT_TRACK
+#define X_MPRV X_MEDIA_PREV_TRACK
+#define X_MSTP X_MEDIA_STOP
+#define X_MPLY X_MEDIA_PLAY_PAUSE
+#define X_MSEL X_MEDIA_SELECT
+#define X_EJCT X_MEDIA_EJECT
+#define X_CALC X_CALCULATOR
+#define X_MYCM X_MY_COMPUTER
+#define X_WSCH X_WWW_SEARCH
+#define X_WHOM X_WWW_HOME
+#define X_WBAK X_WWW_BACK
+#define X_WFWD X_WWW_FORWARD
+#define X_WSTP X_WWW_STOP
+#define X_WREF X_WWW_REFRESH
+#define X_WFAV X_WWW_FAVORITES
+#define X_MFFD X_MEDIA_FAST_FORWARD
+#define X_MRWD X_MEDIA_REWIND
+#define X_BRIU X_BRIGHTNESS_UP
+#define X_BRID X_BRIGHTNESS_DOWN
+
+/* System Specific */
+#define X_BRMU X_PAUSE
+#define X_BRMD X_SCROLLLOCK
+
+/* Mouse Keys */
+#define X_MS_U X_MS_UP
+#define X_MS_D X_MS_DOWN
+#define X_MS_L X_MS_LEFT
+#define X_MS_R X_MS_RIGHT
+#define X_BTN1 X_MS_BTN1
+#define X_BTN2 X_MS_BTN2
+#define X_BTN3 X_MS_BTN3
+#define X_BTN4 X_MS_BTN4
+#define X_BTN5 X_MS_BTN5
+#define X_WH_U X_MS_WH_UP
+#define X_WH_D X_MS_WH_DOWN
+#define X_WH_L X_MS_WH_LEFT
+#define X_WH_R X_MS_WH_RIGHT
+#define X_ACL0 X_MS_ACCEL0
+#define X_ACL1 X_MS_ACCEL1
+#define X_ACL2 X_MS_ACCEL2
+
+/* Keyboard/Keypad Page (0x07) */
+#define X_A 04
+#define X_B 05
+#define X_C 06
+#define X_D 07
+#define X_E 08
+#define X_F 09
+#define X_G 0a
+#define X_H 0b
+#define X_I 0c
+#define X_J 0d
+#define X_K 0e
+#define X_L 0f
+#define X_M 10
+#define X_N 11
+#define X_O 12
+#define X_P 13
+#define X_Q 14
+#define X_R 15
+#define X_S 16
+#define X_T 17
+#define X_U 18
+#define X_V 19
+#define X_W 1a
+#define X_X 1b
+#define X_Y 1c
+#define X_Z 1d
+#define X_1 1e
+#define X_2 1f
+#define X_3 20
+#define X_4 21
+#define X_5 22
+#define X_6 23
+#define X_7 24
+#define X_8 25
+#define X_9 26
+#define X_0 27
+#define X_ENTER 28
+#define X_ESCAPE 29
+#define X_BSPACE 2a
+#define X_TAB 2b
+#define X_SPACE 2c
+#define X_MINUS 2d
+#define X_EQUAL 2e
+#define X_LBRACKET 2f
+#define X_RBRACKET 30
+#define X_BSLASH 31
+#define X_NONUS_HASH 32
+#define X_SCOLON 33
+#define X_QUOTE 34
+#define X_GRAVE 35
+#define X_COMMA 36
+#define X_DOT 37
+#define X_SLASH 38
+#define X_CAPSLOCK 39
+#define X_F1 3a
+#define X_F2 3b
+#define X_F3 3c
+#define X_F4 3d
+#define X_F5 3e
+#define X_F6 3f
+#define X_F7 40
+#define X_F8 41
+#define X_F9 42
+#define X_F10 43
+#define X_F11 44
+#define X_F12 45
+#define X_PSCREEN 46
+#define X_SCROLLLOCK 47
+#define X_PAUSE 48
+#define X_INSERT 49
+#define X_HOME 4a
+#define X_PGUP 4b
+#define X_DELETE 4c
+#define X_END 4d
+#define X_PGDOWN 4e
+#define X_RIGHT 4f
+#define X_LEFT 50
+#define X_DOWN 51
+#define X_UP 52
+#define X_NUMLOCK 53
+#define X_KP_SLASH 54
+#define X_KP_ASTERISK 55
+#define X_KP_MINUS 56
+#define X_KP_PLUS 57
+#define X_KP_ENTER 58
+#define X_KP_1 59
+#define X_KP_2 5a
+#define X_KP_3 5b
+#define X_KP_4 5c
+#define X_KP_5 5d
+#define X_KP_6 5e
+#define X_KP_7 5f
+#define X_KP_8 60
+#define X_KP_9 61
+#define X_KP_0 62
+#define X_KP_DOT 63
+#define X_NONUS_BSLASH 64
+#define X_APPLICATION 65
+#define X_POWER 66
+#define X_KP_EQUAL 67
+#define X_F13 68
+#define X_F14 69
+#define X_F15 6a
+#define X_F16 6b
+#define X_F17 6c
+#define X_F18 6d
+#define X_F19 6e
+#define X_F20 6f
+#define X_F21 70
+#define X_F22 71
+#define X_F23 72
+#define X_F24 73
+#define X_EXECUTE 74
+#define X_HELP 75
+#define X_MENU 76
+#define X_SELECT 77
+#define X_STOP 78
+#define X_AGAIN 79
+#define X_UNDO 7a
+#define X_CUT 7b
+#define X_COPY 7c
+#define X_PASTE 7d
+#define X_FIND 7e
+#define X__MUTE 7f
+#define X__VOLUP 80
+#define X__VOLDOWN 81
+#define X_LOCKING_CAPS 82
+#define X_LOCKING_NUM 83
+#define X_LOCKING_SCROLL 84
+#define X_KP_COMMA 85
+#define X_KP_EQUAL_AS400 86
+#define X_INT1 87
+#define X_INT2 88
+#define X_INT3 89
+#define X_INT4 8a
+#define X_INT5 8b
+#define X_INT6 8c
+#define X_INT7 8d
+#define X_INT8 8e
+#define X_INT9 8f
+#define X_LANG1 90
+#define X_LANG2 91
+#define X_LANG3 92
+#define X_LANG4 93
+#define X_LANG5 94
+#define X_LANG6 95
+#define X_LANG7 96
+#define X_LANG8 97
+#define X_LANG9 98
+#define X_ALT_ERASE 99
+#define X_SYSREQ 9a
+#define X_CANCEL 9b
+#define X_CLEAR 9c
+#define X_PRIOR 9d
+#define X_RETURN 9e
+#define X_SEPARATOR 9f
+#define X_OUT a0
+#define X_OPER a1
+#define X_CLEAR_AGAIN a2
+#define X_CRSEL a3
+#define X_EXSEL a4
+
+/* Modifiers */
+#define X_LCTRL e0
+#define X_LSHIFT e1
+#define X_LALT e2
+#define X_LGUI e3
+#define X_RCTRL e4
+#define X_RSHIFT e5
+#define X_RALT e6
+#define X_RGUI e7
+
+/* Media and Function keys */
+/* Generic Desktop Page (0x01) */
+#define X_SYSTEM_POWER a5
+#define X_SYSTEM_SLEEP a6
+#define X_SYSTEM_WAKE a7
+
+/* Consumer Page (0x0C) */
+#define X_AUDIO_MUTE a8
+#define X_AUDIO_VOL_UP a9
+#define X_AUDIO_VOL_DOWN aa
+#define X_MEDIA_NEXT_TRACK ab
+#define X_MEDIA_PREV_TRACK ac
+#define X_MEDIA_STOP ad
+#define X_MEDIA_PLAY_PAUSE ae
+#define X_MEDIA_SELECT af
+#define X_MEDIA_EJECT b0
+#define X_MAIL b1
+#define X_CALCULATOR b2
+#define X_MY_COMPUTER b3
+#define X_WWW_SEARCH b4
+#define X_WWW_HOME b5
+#define X_WWW_BACK b6
+#define X_WWW_FORWARD b7
+#define X_WWW_STOP b8
+#define X_WWW_REFRESH b9
+#define X_WWW_FAVORITES ba
+#define X_MEDIA_FAST_FORWARD bb
+#define X_MEDIA_REWIND bc
+#define X_BRIGHTNESS_UP bd
+#define X_BRIGHTNESS_DOWN be
+
+/* Mouse Buttons (unallocated range in HID spec) */
+#ifdef VIA_ENABLE
+#define X_MS_UP f0
+#define X_MS_DOWN f1
+#define X_MS_LEFT f2
+#define X_MS_RIGHT f3
+#define X_MS_BTN1 f4
+#define X_MS_BTN2 f5
+#define X_MS_BTN3 f6
+#define X_MS_BTN4 f7
+#define X_MS_BTN5 f8
+#define X_MS_BTN6 f8
+#define X_MS_BTN7 f8
+#define X_MS_BTN8 f8
+#else
+#define X_MS_UP ed
+#define X_MS_DOWN ee
+#define X_MS_LEFT ef
+#define X_MS_RIGHT f0
+#define X_MS_BTN1 f1
+#define X_MS_BTN2 f2
+#define X_MS_BTN3 f3
+#define X_MS_BTN4 f4
+#define X_MS_BTN5 f5
+#define X_MS_BTN6 f6
+#define X_MS_BTN7 f7
+#define X_MS_BTN8 f8
+#endif
+#define X_MS_WH_UP f9
+#define X_MS_WH_DOWN fa
+#define X_MS_WH_LEFT fb
+#define X_MS_WH_RIGHT fc
+#define X_MS_ACCEL0 fd
+#define X_MS_ACCEL1 fe
+#define X_MS_ACCEL2 ff
+
+// Send string macros
+#define STRINGIZE(z) #z
+#define ADD_SLASH_X(y) STRINGIZE(\x##y)
+#define SYMBOL_STR(x) ADD_SLASH_X(x)
+
+#define SS_QMK_PREFIX 1
+
+#define SS_TAP_CODE 1
+#define SS_DOWN_CODE 2
+#define SS_UP_CODE 3
+#define SS_DELAY_CODE 4
+
+#define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode)
+#define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode)
+#define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode)
+#define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|"
+
+// `string` arguments must not be parenthesized
+#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
+#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
+#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
+#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
+#define SS_LCMD(string) SS_LGUI(string)
+#define SS_LWIN(string) SS_LGUI(string)
+
+#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
+#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
+#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
+#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
+#define SS_ALGR(string) SS_RALT(string)
+#define SS_RCMD(string) SS_RGUI(string)
+#define SS_RWIN(string) SS_RGUI(string)
+
+// DEPRECATED
+#define SS_LCTRL(string) SS_LCTL(string)
diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h
deleted file mode 100644
index b35bf66b7b..0000000000
--- a/quantum/send_string_keycodes.h
+++ /dev/null
@@ -1,505 +0,0 @@
-/* Copyright 2019
- *
- * 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
-
-// clang-format off
-
-/* Punctuation */
-#define X_ENT X_ENTER
-#define X_ESC X_ESCAPE
-#define X_BSPC X_BACKSPACE
-#define X_SPC X_SPACE
-#define X_MINS X_MINUS
-#define X_EQL X_EQUAL
-#define X_LBRC X_LEFT_BRACKET
-#define X_RBRC X_RIGHT_BRACKET
-#define X_BSLS X_BACKSLASH
-#define X_NUHS X_NONUS_HASH
-#define X_SCLN X_SEMICOLON
-#define X_QUOT X_QUOTE
-#define X_GRV X_GRAVE
-#define X_COMM X_COMMA
-#define X_SLSH X_SLASH
-#define X_NUBS X_NONUS_BACKSLASH
-
-/* Lock Keys */
-#define X_CAPS X_CAPS_LOCK
-#define X_SCRL X_SCROLL_LOCK
-#define X_NUM X_NUM_LOCK
-#define X_LCAP X_LOCKING_CAPS_LOCK
-#define X_LNUM X_LOCKING_NUM_LOCK
-#define X_LSCR X_LOCKING_SCROLL_LOCK
-
-/* Commands */
-#define X_PSCR X_PRINT_SCREEN
-#define X_PAUS X_PAUSE
-#define X_BRK X_PAUSE
-#define X_INS X_INSERT
-#define X_PGUP X_PAGE_UP
-#define X_DEL X_DELETE
-#define X_PGDN X_PAGE_DOWN
-#define X_RGHT X_RIGHT
-#define X_APP X_APPLICATION
-#define X_EXEC X_EXECUTE
-#define X_SLCT X_SELECT
-#define X_AGIN X_AGAIN
-#define X_PSTE X_PASTE
-#define X_ERAS X_ALTERNATE_ERASE
-#define X_SYRQ X_SYSTEM_REQUEST
-#define X_CNCL X_CANCEL
-#define X_CLR X_CLEAR
-#define X_PRIR X_PRIOR
-#define X_RETN X_RETURN
-#define X_SEPR X_SEPARATOR
-#define X_CLAG X_CLEAR_AGAIN
-#define X_CRSL X_CRSEL
-#define X_EXSL X_EXSEL
-
-/* Keypad */
-#define X_PSLS X_KP_SLASH
-#define X_PAST X_KP_ASTERISK
-#define X_PMNS X_KP_MINUS
-#define X_PPLS X_KP_PLUS
-#define X_PENT X_KP_ENTER
-#define X_P1 X_KP_1
-#define X_P2 X_KP_2
-#define X_P3 X_KP_3
-#define X_P4 X_KP_4
-#define X_P5 X_KP_5
-#define X_P6 X_KP_6
-#define X_P7 X_KP_7
-#define X_P8 X_KP_8
-#define X_P9 X_KP_9
-#define X_P0 X_KP_0
-#define X_PDOT X_KP_DOT
-#define X_PEQL X_KP_EQUAL
-#define X_PCMM X_KP_COMMA
-
-/* Language Specific */
-#define X_INT1 X_INTERNATIONAL_1
-#define X_INT2 X_INTERNATIONAL_2
-#define X_INT3 X_INTERNATIONAL_3
-#define X_INT4 X_INTERNATIONAL_4
-#define X_INT5 X_INTERNATIONAL_5
-#define X_INT6 X_INTERNATIONAL_6
-#define X_INT7 X_INTERNATIONAL_7
-#define X_INT8 X_INTERNATIONAL_8
-#define X_INT9 X_INTERNATIONAL_9
-#define X_LNG1 X_LANGUAGE_1
-#define X_LNG2 X_LANGUAGE_2
-#define X_LNG3 X_LANGUAGE_3
-#define X_LNG4 X_LANGUAGE_4
-#define X_LNG5 X_LANGUAGE_5
-#define X_LNG6 X_LANGUAGE_6
-#define X_LNG7 X_LANGUAGE_7
-#define X_LNG8 X_LANGUAGE_8
-#define X_LNG9 X_LANGUAGE_9
-
-/* Modifiers */
-#define X_LCTL X_LEFT_CTRL
-#define X_LSFT X_LEFT_SHIFT
-#define X_LALT X_LEFT_ALT
-#define X_LOPT X_LEFT_ALT
-#define X_LGUI X_LEFT_GUI
-#define X_LCMD X_LEFT_GUI
-#define X_LWIN X_LEFT_GUI
-#define X_RCTL X_RIGHT_CTRL
-#define X_RSFT X_RIGHT_SHIFT
-#define X_RALT X_RIGHT_ALT
-#define X_ALGR X_RIGHT_ALT
-#define X_ROPT X_RIGHT_ALT
-#define X_RGUI X_RIGHT_GUI
-#define X_RCMD X_RIGHT_GUI
-#define X_RWIN X_RIGHT_GUI
-
-/* Generic Desktop Page (0x01) */
-#define X_PWR X_SYSTEM_POWER
-#define X_SLEP X_SYSTEM_SLEEP
-#define X_WAKE X_SYSTEM_WAKE
-
-/* Consumer Page (0x0C) */
-#define X_MUTE X_AUDIO_MUTE
-#define X_VOLU X_AUDIO_VOL_UP
-#define X_VOLD X_AUDIO_VOL_DOWN
-#define X_MNXT X_MEDIA_NEXT_TRACK
-#define X_MPRV X_MEDIA_PREV_TRACK
-#define X_MSTP X_MEDIA_STOP
-#define X_MPLY X_MEDIA_PLAY_PAUSE
-#define X_MSEL X_MEDIA_SELECT
-#define X_EJCT X_MEDIA_EJECT
-#define X_CALC X_CALCULATOR
-#define X_MYCM X_MY_COMPUTER
-#define X_WSCH X_WWW_SEARCH
-#define X_WHOM X_WWW_HOME
-#define X_WBAK X_WWW_BACK
-#define X_WFWD X_WWW_FORWARD
-#define X_WSTP X_WWW_STOP
-#define X_WREF X_WWW_REFRESH
-#define X_WFAV X_WWW_FAVORITES
-#define X_MFFD X_MEDIA_FAST_FORWARD
-#define X_MRWD X_MEDIA_REWIND
-#define X_BRIU X_BRIGHTNESS_UP
-#define X_BRID X_BRIGHTNESS_DOWN
-
-/* System Specific */
-#define X_BRMU X_PAUSE
-#define X_BRMD X_SCROLL_LOCK
-
-/* Mouse Keys */
-#define X_MS_U X_MS_UP
-#define X_MS_D X_MS_DOWN
-#define X_MS_L X_MS_LEFT
-#define X_MS_R X_MS_RIGHT
-#define X_BTN1 X_MS_BTN1
-#define X_BTN2 X_MS_BTN2
-#define X_BTN3 X_MS_BTN3
-#define X_BTN4 X_MS_BTN4
-#define X_BTN5 X_MS_BTN5
-#define X_BTN6 X_MS_BTN6
-#define X_BTN7 X_MS_BTN7
-#define X_BTN8 X_MS_BTN8
-#define X_WH_U X_MS_WH_UP
-#define X_WH_D X_MS_WH_DOWN
-#define X_WH_L X_MS_WH_LEFT
-#define X_WH_R X_MS_WH_RIGHT
-#define X_ACL0 X_MS_ACCEL0
-#define X_ACL1 X_MS_ACCEL1
-#define X_ACL2 X_MS_ACCEL2
-
-/* Keyboard/Keypad Page (0x07) */
-#define X_A 04
-#define X_B 05
-#define X_C 06
-#define X_D 07
-#define X_E 08
-#define X_F 09
-#define X_G 0a
-#define X_H 0b
-#define X_I 0c
-#define X_J 0d
-#define X_K 0e
-#define X_L 0f
-#define X_M 10
-#define X_N 11
-#define X_O 12
-#define X_P 13
-#define X_Q 14
-#define X_R 15
-#define X_S 16
-#define X_T 17
-#define X_U 18
-#define X_V 19
-#define X_W 1a
-#define X_X 1b
-#define X_Y 1c
-#define X_Z 1d
-#define X_1 1e
-#define X_2 1f
-#define X_3 20
-#define X_4 21
-#define X_5 22
-#define X_6 23
-#define X_7 24
-#define X_8 25
-#define X_9 26
-#define X_0 27
-#define X_ENTER 28
-#define X_ESCAPE 29
-#define X_BACKSPACE 2a
-#define X_TAB 2b
-#define X_SPACE 2c
-#define X_MINUS 2d
-#define X_EQUAL 2e
-#define X_LEFT_BRACKET 2f
-#define X_RIGHT_BRACKET 30
-#define X_BACKSLASH 31
-#define X_NONUS_HASH 32
-#define X_SEMICOLON 33
-#define X_QUOTE 34
-#define X_GRAVE 35
-#define X_COMMA 36
-#define X_DOT 37
-#define X_SLASH 38
-#define X_CAPS_LOCK 39
-#define X_F1 3a
-#define X_F2 3b
-#define X_F3 3c
-#define X_F4 3d
-#define X_F5 3e
-#define X_F6 3f
-#define X_F7 40
-#define X_F8 41
-#define X_F9 42
-#define X_F10 43
-#define X_F11 44
-#define X_F12 45
-#define X_PRINT_SCREEN 46
-#define X_SCROLL_LOCK 47
-#define X_PAUSE 48
-#define X_INSERT 49
-#define X_HOME 4a
-#define X_PAGE_UP 4b
-#define X_DELETE 4c
-#define X_END 4d
-#define X_PAGE_DOWN 4e
-#define X_RIGHT 4f
-#define X_LEFT 50
-#define X_DOWN 51
-#define X_UP 52
-#define X_NUM_LOCK 53
-#define X_KP_SLASH 54
-#define X_KP_ASTERISK 55
-#define X_KP_MINUS 56
-#define X_KP_PLUS 57
-#define X_KP_ENTER 58
-#define X_KP_1 59
-#define X_KP_2 5a
-#define X_KP_3 5b
-#define X_KP_4 5c
-#define X_KP_5 5d
-#define X_KP_6 5e
-#define X_KP_7 5f
-#define X_KP_8 60
-#define X_KP_9 61
-#define X_KP_0 62
-#define X_KP_DOT 63
-#define X_NONUS_BACKSLASH 64
-#define X_APPLICATION 65
-#define X_KB_POWER 66
-#define X_KP_EQUAL 67
-#define X_F13 68
-#define X_F14 69
-#define X_F15 6a
-#define X_F16 6b
-#define X_F17 6c
-#define X_F18 6d
-#define X_F19 6e
-#define X_F20 6f
-#define X_F21 70
-#define X_F22 71
-#define X_F23 72
-#define X_F24 73
-#define X_EXECUTE 74
-#define X_HELP 75
-#define X_MENU 76
-#define X_SELECT 77
-#define X_STOP 78
-#define X_AGAIN 79
-#define X_UNDO 7a
-#define X_CUT 7b
-#define X_COPY 7c
-#define X_PASTE 7d
-#define X_FIND 7e
-#define X_KB_MUTE 7f
-#define X_KB_VOLUME_UP 80
-#define X_KB_VOLUME_DOWN 81
-#define X_LOCKING_CAPS_LOCK 82
-#define X_LOCKING_NUM_LOCK 83
-#define X_LOCKING_SCROLL_LOCK 84
-#define X_KP_COMMA 85
-#define X_KP_EQUAL_AS400 86
-#define X_INTERNATIONAL_1 87
-#define X_INTERNATIONAL_2 88
-#define X_INTERNATIONAL_3 89
-#define X_INTERNATIONAL_4 8a
-#define X_INTERNATIONAL_5 8b
-#define X_INTERNATIONAL_6 8c
-#define X_INTERNATIONAL_7 8d
-#define X_INTERNATIONAL_8 8e
-#define X_INTERNATIONAL_9 8f
-#define X_LANGUAGE_1 90
-#define X_LANGUAGE_2 91
-#define X_LANGUAGE_3 92
-#define X_LANGUAGE_4 93
-#define X_LANGUAGE_5 94
-#define X_LANGUAGE_6 95
-#define X_LANGUAGE_7 96
-#define X_LANGUAGE_8 97
-#define X_LANGUAGE_9 98
-#define X_ALTERNATE_ERASE 99
-#define X_SYSTEM_REQUEST 9a
-#define X_CANCEL 9b
-#define X_CLEAR 9c
-#define X_PRIOR 9d
-#define X_RETURN 9e
-#define X_SEPARATOR 9f
-#define X_OUT a0
-#define X_OPER a1
-#define X_CLEAR_AGAIN a2
-#define X_CRSEL a3
-#define X_EXSEL a4
-
-/* Modifiers */
-#define X_LEFT_CTRL e0
-#define X_LEFT_SHIFT e1
-#define X_LEFT_ALT e2
-#define X_LEFT_GUI e3
-#define X_RIGHT_CTRL e4
-#define X_RIGHT_SHIFT e5
-#define X_RIGHT_ALT e6
-#define X_RIGHT_GUI e7
-
-/* Media and Function keys */
-/* Generic Desktop Page (0x01) */
-#define X_SYSTEM_POWER a5
-#define X_SYSTEM_SLEEP a6
-#define X_SYSTEM_WAKE a7
-
-/* Consumer Page (0x0C) */
-#define X_AUDIO_MUTE a8
-#define X_AUDIO_VOL_UP a9
-#define X_AUDIO_VOL_DOWN aa
-#define X_MEDIA_NEXT_TRACK ab
-#define X_MEDIA_PREV_TRACK ac
-#define X_MEDIA_STOP ad
-#define X_MEDIA_PLAY_PAUSE ae
-#define X_MEDIA_SELECT af
-#define X_MEDIA_EJECT b0
-#define X_MAIL b1
-#define X_CALCULATOR b2
-#define X_MY_COMPUTER b3
-#define X_WWW_SEARCH b4
-#define X_WWW_HOME b5
-#define X_WWW_BACK b6
-#define X_WWW_FORWARD b7
-#define X_WWW_STOP b8
-#define X_WWW_REFRESH b9
-#define X_WWW_FAVORITES ba
-#define X_MEDIA_FAST_FORWARD bb
-#define X_MEDIA_REWIND bc
-#define X_BRIGHTNESS_UP bd
-#define X_BRIGHTNESS_DOWN be
-
-/* Mouse Buttons (unallocated range in HID spec) */
-#ifdef VIA_ENABLE
-#define X_MS_UP f0
-#define X_MS_DOWN f1
-#define X_MS_LEFT f2
-#define X_MS_RIGHT f3
-#define X_MS_BTN1 f4
-#define X_MS_BTN2 f5
-#define X_MS_BTN3 f6
-#define X_MS_BTN4 f7
-#define X_MS_BTN5 f8
-#define X_MS_BTN6 f8
-#define X_MS_BTN7 f8
-#define X_MS_BTN8 f8
-#else
-#define X_MS_UP ed
-#define X_MS_DOWN ee
-#define X_MS_LEFT ef
-#define X_MS_RIGHT f0
-#define X_MS_BTN1 f1
-#define X_MS_BTN2 f2
-#define X_MS_BTN3 f3
-#define X_MS_BTN4 f4
-#define X_MS_BTN5 f5
-#define X_MS_BTN6 f6
-#define X_MS_BTN7 f7
-#define X_MS_BTN8 f8
-#endif
-#define X_MS_WH_UP f9
-#define X_MS_WH_DOWN fa
-#define X_MS_WH_LEFT fb
-#define X_MS_WH_RIGHT fc
-#define X_MS_ACCEL0 fd
-#define X_MS_ACCEL1 fe
-#define X_MS_ACCEL2 ff
-
-// Send string macros
-#define STRINGIZE(z) #z
-#define ADD_SLASH_X(y) STRINGIZE(\x##y)
-#define SYMBOL_STR(x) ADD_SLASH_X(x)
-
-#define SS_QMK_PREFIX 1
-
-#define SS_TAP_CODE 1
-#define SS_DOWN_CODE 2
-#define SS_UP_CODE 3
-#define SS_DELAY_CODE 4
-
-#define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode)
-#define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode)
-#define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode)
-#define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|"
-
-// `string` arguments must not be parenthesized
-#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
-#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
-#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
-#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
-#define SS_LCMD(string) SS_LGUI(string)
-#define SS_LWIN(string) SS_LGUI(string)
-
-#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
-#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
-#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
-#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
-#define SS_ALGR(string) SS_RALT(string)
-#define SS_RCMD(string) SS_RGUI(string)
-#define SS_RWIN(string) SS_RGUI(string)
-
-// DEPRECATED
-#define X_BSPACE X_BACKSPACE
-#define X_LBRACKET X_LEFT_BRACKET
-#define X_RBRACKET X_RIGHT_BRACKET
-#define X_BSLASH X_BACKSLASH
-#define X_SCOLON X_SEMICOLON
-#define X_CAPSLOCK X_CAPS_LOCK
-#define X_PSCREEN X_PRINT_SCREEN
-#define X_SCROLLLOCK X_SCROLL_LOCK
-#define X_PGDOWN X_PAGE_DOWN
-#define X_NUMLOCK X_NUM_LOCK
-#define X_NONUS_BSLASH X_NONUS_BACKSLASH
-#define X_POWER X_KB_POWER
-#define X__MUTE X_KB_MUTE
-#define X__VOLUP X_KB_VOLUME_UP
-#define X__VOLDOWN X_KB_VOLUME_DOWN
-#define X_LOCKING_CAPS X_LOCKING_CAPS_LOCK
-#define X_LOCKING_NUM X_LOCKING_NUM_LOCK
-#define X_LOCKING_SCROLL X_LOCKING_SCROLL_LOCK
-#define X_LANG1 X_LANGUAGE_1
-#define X_LANG2 X_LANGUAGE_2
-#define X_LANG3 X_LANGUAGE_3
-#define X_LANG4 X_LANGUAGE_4
-#define X_LANG5 X_LANGUAGE_5
-#define X_LANG6 X_LANGUAGE_6
-#define X_LANG7 X_LANGUAGE_7
-#define X_LANG8 X_LANGUAGE_8
-#define X_LANG9 X_LANGUAGE_9
-#define X_ALT_ERASE X_ALTERNATE_ERASE
-#define X_SYSREQ X_SYSTEM_REQUEST
-
-#define X_LCTRL X_LEFT_CTRL
-#define X_LSHIFT X_LEFT_SHIFT
-#define X_RCTRL X_RIGHT_CTRL
-#define X_RSHIFT X_RIGHT_SHIFT
-
-#define X_ZKHK X_GRAVE
-#define X_RO X_INTERNATIONAL_1
-#define X_KANA X_INTERNATIONAL_2
-#define X_JYEN X_INTERNATIONAL_3
-#define X_HENK X_INTERNATIONAL_4
-#define X_MHEN X_INTERNATIONAL_5
-#define X_HAEN X_LANGUAGE_1
-#define X_HANJ X_LANGUAGE_2
-
-#define X_CLCK X_CAPS_LOCK
-#define X_SLCK X_SCROLL_LOCK
-#define X_NLCK X_NUM_LOCK
-
-#define SS_LCTRL(string) SS_LCTL(string)
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 7d50adf758..4892b7f8d8 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -57,8 +57,9 @@ static uint8_t connection_errors = 0;
volatile bool isLeftHand = true;
#if defined(SPLIT_USB_DETECT)
+_Static_assert((SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL) <= UINT16_MAX, "Please lower SPLIT_USB_TIMEOUT and/or increase SPLIT_USB_TIMEOUT_POLL.");
static bool usbIsActive(void) {
- for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
+ for (uint16_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
// This will return true if a USB connection has been established
if (usb_connected_state()) {
return true;
@@ -93,7 +94,6 @@ static uint8_t peek_matrix_intersection(pin_t out_pin, pin_t in_pin) {
__attribute__((weak)) bool is_keyboard_left(void) {
#if defined(SPLIT_HAND_PIN)
// Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
- setPinInput(SPLIT_HAND_PIN);
# ifdef SPLIT_HAND_PIN_LOW_IS_LEFT
return !readPin(SPLIT_HAND_PIN);
# else
@@ -132,6 +132,14 @@ __attribute__((weak)) bool is_keyboard_master(void) {
// this code runs before the keyboard is fully initialized
void split_pre_init(void) {
+#if defined(SPLIT_HAND_PIN)
+ setPinInput(SPLIT_HAND_PIN);
+ wait_us(100);
+#elif defined(EE_HANDS)
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+#endif
isLeftHand = is_keyboard_left();
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
diff --git a/quantum/via.c b/quantum/via.c
index 320bd5546d..d2ef0862cc 100644
--- a/quantum/via.c
+++ b/quantum/via.c
@@ -64,6 +64,7 @@ void via_qmk_rgblight_get_value(uint8_t *data);
#endif
#if defined(VIA_QMK_RGB_MATRIX_ENABLE)
+# include <lib/lib8tion/lib8tion.h>
void via_qmk_rgb_matrix_set_value(uint8_t *data);
void via_qmk_rgb_matrix_get_value(uint8_t *data);
void eeconfig_update_rgb_matrix(void);
@@ -421,7 +422,7 @@ void via_qmk_backlight_get_value(uint8_t *data) {
switch (*value_id) {
case id_qmk_backlight_brightness: {
// level / BACKLIGHT_LEVELS * 255
- value_data[0] = ((uint16_t)get_backlight_level()) * 255 / BACKLIGHT_LEVELS;
+ value_data[0] = ((uint16_t)get_backlight_level() * UINT8_MAX) / BACKLIGHT_LEVELS;
break;
}
case id_qmk_backlight_effect: {
@@ -441,7 +442,7 @@ void via_qmk_backlight_set_value(uint8_t *data) {
switch (*value_id) {
case id_qmk_backlight_brightness: {
// level / 255 * BACKLIGHT_LEVELS
- backlight_level_noeeprom(((uint16_t)value_data[0]) * BACKLIGHT_LEVELS / 255);
+ backlight_level_noeeprom(((uint16_t)value_data[0] * BACKLIGHT_LEVELS) / UINT8_MAX);
break;
}
case id_qmk_backlight_effect: {
@@ -460,13 +461,16 @@ void via_qmk_backlight_set_value(uint8_t *data) {
#endif // #if defined(VIA_QMK_BACKLIGHT_ENABLE)
#if defined(VIA_QMK_RGBLIGHT_ENABLE)
+# ifndef RGBLIGHT_LIMIT_VAL
+# define RGBLIGHT_LIMIT_VAL 255
+# endif
void via_qmk_rgblight_get_value(uint8_t *data) {
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_qmk_rgblight_brightness: {
- value_data[0] = rgblight_get_val();
+ value_data[0] = ((uint16_t)rgblight_get_val() * UINT8_MAX) / RGBLIGHT_LIMIT_VAL;
break;
}
case id_qmk_rgblight_effect: {
@@ -490,7 +494,7 @@ void via_qmk_rgblight_set_value(uint8_t *data) {
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_qmk_rgblight_brightness: {
- rgblight_sethsv_noeeprom(rgblight_get_hue(), rgblight_get_sat(), value_data[0]);
+ rgblight_sethsv_noeeprom(rgblight_get_hue(), rgblight_get_sat(), ((uint16_t)value_data[0] * RGBLIGHT_LIMIT_VAL) / UINT8_MAX);
break;
}
case id_qmk_rgblight_effect: {
@@ -517,6 +521,11 @@ void via_qmk_rgblight_set_value(uint8_t *data) {
#if defined(VIA_QMK_RGB_MATRIX_ENABLE)
+# if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
+# undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
+# define RGB_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX
+# endif
+
// VIA supports only 4 discrete values for effect speed; map these to some
// useful speed values for RGB Matrix.
enum speed_values {
@@ -557,7 +566,7 @@ void via_qmk_rgb_matrix_get_value(uint8_t *data) {
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_qmk_rgblight_brightness:
- value_data[0] = rgb_matrix_get_val();
+ value_data[0] = ((uint16_t)rgb_matrix_get_val() * UINT8_MAX) / RGB_MATRIX_MAXIMUM_BRIGHTNESS;
break;
case id_qmk_rgblight_effect:
value_data[0] = rgb_matrix_get_mode();
@@ -577,7 +586,7 @@ void via_qmk_rgb_matrix_set_value(uint8_t *data) {
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_qmk_rgblight_brightness:
- rgb_matrix_sethsv_noeeprom(rgb_matrix_get_hue(), rgb_matrix_get_sat(), value_data[0]);
+ rgb_matrix_sethsv_noeeprom(rgb_matrix_get_hue(), rgb_matrix_get_sat(), scale8(value_data[0], RGB_MATRIX_MAXIMUM_BRIGHTNESS));
break;
case id_qmk_rgblight_effect:
rgb_matrix_mode_noeeprom(value_data[0]);
diff --git a/quantum/via.h b/quantum/via.h
index ac29a58902..31d9c21af4 100644
--- a/quantum/via.h
+++ b/quantum/via.h
@@ -54,6 +54,8 @@
# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
#endif
+#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE)
+
// This is changed only when the command IDs change,
// so VIA Configurator can detect compatible firmware.
#define VIA_PROTOCOL_VERSION 0x0009
diff --git a/quantum/wear_leveling/tests/backing_mocks.cpp b/quantum/wear_leveling/tests/backing_mocks.cpp
new file mode 100644
index 0000000000..1dbb26f8e7
--- /dev/null
+++ b/quantum/wear_leveling/tests/backing_mocks.cpp
@@ -0,0 +1,154 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Backing Store Mock implementation
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void MockBackingStore::reset_instance() {
+ for (auto&& e : backing_storage)
+ e.reset();
+
+ locked = true;
+
+ backing_erasure_count = 0;
+ backing_max_write_count = 0;
+ backing_total_write_count = 0;
+
+ backing_init_invoke_count = 0;
+ backing_unlock_invoke_count = 0;
+ backing_erase_invoke_count = 0;
+ backing_write_invoke_count = 0;
+ backing_lock_invoke_count = 0;
+
+ init_success_callback = [](std::uint64_t) { return true; };
+ erase_success_callback = [](std::uint64_t) { return true; };
+ unlock_success_callback = [](std::uint64_t) { return true; };
+ write_success_callback = [](std::uint64_t, std::uint32_t) { return true; };
+ lock_success_callback = [](std::uint64_t) { return true; };
+
+ write_log.clear();
+}
+
+bool MockBackingStore::init(void) {
+ ++backing_init_invoke_count;
+
+ if (init_success_callback) {
+ return init_success_callback(backing_init_invoke_count);
+ }
+ return true;
+}
+
+bool MockBackingStore::unlock(void) {
+ ++backing_unlock_invoke_count;
+
+ EXPECT_TRUE(is_locked()) << "Attempted to unlock but was not locked";
+ locked = false;
+
+ if (unlock_success_callback) {
+ return unlock_success_callback(backing_unlock_invoke_count);
+ }
+ return true;
+}
+
+bool MockBackingStore::erase(void) {
+ ++backing_erase_invoke_count;
+
+ // Erase each slot
+ for (std::size_t i = 0; i < backing_storage.size(); ++i) {
+ // Drop out of erase early with failure if we need to
+ if (erase_success_callback && !erase_success_callback(backing_erase_invoke_count)) {
+ append_log(true);
+ return false;
+ }
+
+ backing_storage[i].erase();
+ }
+
+ // Keep track of the erase in the write log so that we can verify during tests
+ append_log(true);
+
+ ++backing_erasure_count;
+ return true;
+}
+
+bool MockBackingStore::write(uint32_t address, backing_store_int_t value) {
+ ++backing_write_invoke_count;
+
+ // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE
+ EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size";
+ EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access";
+ EXPECT_FALSE(is_locked()) << "Write was attempted without being unlocked first";
+
+ // Drop out of write early with failure if we need to
+ if (write_success_callback && !write_success_callback(backing_write_invoke_count, address)) {
+ return false;
+ }
+
+ // Write the complement as we're simulating flash memory -- 0xFF means 0x00
+ std::size_t index = address / BACKING_STORE_WRITE_SIZE;
+ backing_storage[index].set(~value);
+
+ // Keep track of the write log so that we can verify during tests
+ append_log(address, value);
+
+ // Keep track of the total number of writes into the backing store
+ ++backing_total_write_count;
+
+ return true;
+}
+
+bool MockBackingStore::lock(void) {
+ ++backing_lock_invoke_count;
+
+ EXPECT_FALSE(is_locked()) << "Attempted to lock but was not unlocked";
+ locked = true;
+
+ if (lock_success_callback) {
+ return lock_success_callback(backing_lock_invoke_count);
+ }
+ return true;
+}
+
+bool MockBackingStore::read(uint32_t address, backing_store_int_t& value) const {
+ // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE
+ EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size";
+ EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access";
+
+ // Read and take the complement as we're simulating flash memory -- 0xFF means 0x00
+ std::size_t index = address / BACKING_STORE_WRITE_SIZE;
+ value = ~backing_storage[index].get();
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Backing Implementation
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+extern "C" bool backing_store_init(void) {
+ return MockBackingStore::Instance().init();
+}
+
+extern "C" bool backing_store_unlock(void) {
+ return MockBackingStore::Instance().unlock();
+}
+
+extern "C" bool backing_store_erase(void) {
+ return MockBackingStore::Instance().erase();
+}
+
+extern "C" bool backing_store_write(uint32_t address, backing_store_int_t value) {
+ return MockBackingStore::Instance().write(address, value);
+}
+
+extern "C" bool backing_store_lock(void) {
+ return MockBackingStore::Instance().lock();
+}
+
+extern "C" bool backing_store_read(uint32_t address, backing_store_int_t* value) {
+ return MockBackingStore::Instance().read(address, *value);
+}
diff --git a/quantum/wear_leveling/tests/backing_mocks.hpp b/quantum/wear_leveling/tests/backing_mocks.hpp
new file mode 100644
index 0000000000..e7af7895f3
--- /dev/null
+++ b/quantum/wear_leveling/tests/backing_mocks.hpp
@@ -0,0 +1,210 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+#include <algorithm>
+#include <array>
+#include <cstdint>
+#include <cstdlib>
+#include <functional>
+#include <type_traits>
+#include <vector>
+
+extern "C" {
+#include "fnv.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+};
+
+// Maximum number of mock write log entries to keep
+using MOCK_WRITE_LOG_MAX_ENTRIES = std::integral_constant<std::size_t, 1024>;
+// Complement to the backing store integral, for emulating flash erases of all bytes=0xFF
+using BACKING_STORE_INTEGRAL_COMPLEMENT = std::integral_constant<backing_store_int_t, ((backing_store_int_t)(~(backing_store_int_t)0))>;
+// Total number of elements stored in the backing arrays
+using BACKING_STORE_ELEMENT_COUNT = std::integral_constant<std::size_t, (WEAR_LEVELING_BACKING_SIZE / sizeof(backing_store_int_t))>;
+
+class MockBackingStoreElement {
+ private:
+ backing_store_int_t value;
+ std::size_t writes;
+ std::size_t erases;
+
+ public:
+ MockBackingStoreElement() : value(BACKING_STORE_INTEGRAL_COMPLEMENT::value), writes(0), erases(0) {}
+ void reset() {
+ erase();
+ writes = 0;
+ erases = 0;
+ }
+ void erase() {
+ if (!is_erased()) {
+ ++erases;
+ }
+ value = BACKING_STORE_INTEGRAL_COMPLEMENT::value;
+ }
+ backing_store_int_t get() const {
+ return value;
+ }
+ void set(const backing_store_int_t& v) {
+ EXPECT_TRUE(is_erased()) << "Attempted write at index which isn't empty.";
+ value = v;
+ ++writes;
+ }
+ std::size_t num_writes() const {
+ return writes;
+ }
+ std::size_t num_erases() const {
+ return erases;
+ }
+ bool is_erased() const {
+ return value == BACKING_STORE_INTEGRAL_COMPLEMENT::value;
+ }
+};
+
+struct MockBackingStoreLogEntry {
+ MockBackingStoreLogEntry(uint32_t address, backing_store_int_t value) : address(address), value(value), erased(false) {}
+ MockBackingStoreLogEntry(bool erased) : address(0), value(0), erased(erased) {}
+ uint32_t address = 0; // The address of the operation
+ backing_store_int_t value = 0; // The value of the operation
+ bool erased = false; // Whether the entire backing store was erased
+};
+
+class MockBackingStore {
+ private:
+ MockBackingStore() {
+ reset_instance();
+ }
+
+ // Type containing each of the entries and the write counts
+ using storage_t = std::array<MockBackingStoreElement, BACKING_STORE_ELEMENT_COUNT::value>;
+
+ // Whether the backing store is locked
+ bool locked;
+ // The actual data stored in the emulated flash
+ storage_t backing_storage;
+ // The number of erase cycles that have occurred
+ std::uint64_t backing_erasure_count;
+ // The max number of writes to an element of the backing store
+ std::uint64_t backing_max_write_count;
+ // The total number of writes to all elements of the backing store
+ std::uint64_t backing_total_write_count;
+ // The write log for the backing store
+ std::vector<MockBackingStoreLogEntry> write_log;
+
+ // The number of times each API was invoked
+ std::uint64_t backing_init_invoke_count;
+ std::uint64_t backing_unlock_invoke_count;
+ std::uint64_t backing_erase_invoke_count;
+ std::uint64_t backing_write_invoke_count;
+ std::uint64_t backing_lock_invoke_count;
+
+ // Whether init should succeed
+ std::function<bool(std::uint64_t)> init_success_callback;
+ // Whether erase should succeed
+ std::function<bool(std::uint64_t)> erase_success_callback;
+ // Whether unlocks should succeed
+ std::function<bool(std::uint64_t)> unlock_success_callback;
+ // Whether writes should succeed
+ std::function<bool(std::uint64_t, std::uint32_t)> write_success_callback;
+ // Whether locks should succeed
+ std::function<bool(std::uint64_t)> lock_success_callback;
+
+ template <typename... Args>
+ void append_log(Args&&... args) {
+ if (write_log.size() < MOCK_WRITE_LOG_MAX_ENTRIES::value) {
+ write_log.emplace_back(std::forward<Args>(args)...);
+ }
+ }
+
+ public:
+ static MockBackingStore& Instance() {
+ static MockBackingStore instance;
+ return instance;
+ }
+
+ std::uint64_t erasure_count() const {
+ return backing_erasure_count;
+ }
+ std::uint64_t max_write_count() const {
+ return backing_max_write_count;
+ }
+ std::uint64_t total_write_count() const {
+ return backing_total_write_count;
+ }
+
+ // The number of times each API was invoked
+ std::uint64_t init_invoke_count() const {
+ return backing_init_invoke_count;
+ }
+ std::uint64_t unlock_invoke_count() const {
+ return backing_unlock_invoke_count;
+ }
+ std::uint64_t erase_invoke_count() const {
+ return backing_erase_invoke_count;
+ }
+ std::uint64_t write_invoke_count() const {
+ return backing_write_invoke_count;
+ }
+ std::uint64_t lock_invoke_count() const {
+ return backing_lock_invoke_count;
+ }
+
+ // Clear out the internal data for the next run
+ void reset_instance();
+
+ bool is_locked() const {
+ return locked;
+ }
+
+ // APIs for the backing store
+ bool init();
+ bool unlock();
+ bool erase();
+ bool write(std::uint32_t address, backing_store_int_t value);
+ bool lock();
+ bool read(std::uint32_t address, backing_store_int_t& value) const;
+
+ // Control over when init/writes/erases should succeed
+ void set_init_callback(std::function<bool(std::uint64_t)> callback) {
+ init_success_callback = callback;
+ }
+ void set_erase_callback(std::function<bool(std::uint64_t)> callback) {
+ erase_success_callback = callback;
+ }
+ void set_unlock_callback(std::function<bool(std::uint64_t)> callback) {
+ unlock_success_callback = callback;
+ }
+ void set_write_callback(std::function<bool(std::uint64_t, std::uint32_t)> callback) {
+ write_success_callback = callback;
+ }
+ void set_lock_callback(std::function<bool(std::uint64_t)> callback) {
+ lock_success_callback = callback;
+ }
+
+ auto storage_begin() const -> decltype(backing_storage.begin()) {
+ return backing_storage.begin();
+ }
+ auto storage_end() const -> decltype(backing_storage.end()) {
+ return backing_storage.end();
+ }
+
+ auto storage_begin() -> decltype(backing_storage.begin()) {
+ return backing_storage.begin();
+ }
+ auto storage_end() -> decltype(backing_storage.end()) {
+ return backing_storage.end();
+ }
+
+ auto log_begin() -> decltype(write_log.begin()) {
+ return write_log.begin();
+ }
+ auto log_end() -> decltype(write_log.end()) {
+ return write_log.end();
+ }
+
+ auto log_begin() const -> decltype(write_log.begin()) {
+ return write_log.begin();
+ }
+ auto log_end() const -> decltype(write_log.end()) {
+ return write_log.end();
+ }
+};
diff --git a/quantum/wear_leveling/tests/rules.mk b/quantum/wear_leveling/tests/rules.mk
new file mode 100644
index 0000000000..4d7a964049
--- /dev/null
+++ b/quantum/wear_leveling/tests/rules.mk
@@ -0,0 +1,66 @@
+wear_leveling_common_DEFS := \
+ -DWEAR_LEVELING_TESTS
+wear_leveling_common_SRC := \
+ $(LIB_PATH)/fnv/qmk_fnv_type_validation.c \
+ $(LIB_PATH)/fnv/hash_32a.c \
+ $(LIB_PATH)/fnv/hash_64a.c \
+ $(QUANTUM_PATH)/wear_leveling/wear_leveling.c \
+ $(QUANTUM_PATH)/wear_leveling/tests/backing_mocks.cpp
+wear_leveling_common_INC := \
+ $(LIB_PATH)/fnv \
+ $(QUANTUM_PATH)/wear_leveling
+
+wear_leveling_general_DEFS := \
+ $(wear_leveling_common_DEFS) \
+ -DBACKING_STORE_WRITE_SIZE=2 \
+ -DWEAR_LEVELING_BACKING_SIZE=48 \
+ -DWEAR_LEVELING_LOGICAL_SIZE=16
+wear_leveling_general_SRC := \
+ $(wear_leveling_common_SRC) \
+ $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_general.cpp
+wear_leveling_general_INC := \
+ $(wear_leveling_common_INC)
+
+wear_leveling_2byte_optimized_writes_DEFS := \
+ $(wear_leveling_common_DEFS) \
+ -DBACKING_STORE_WRITE_SIZE=2 \
+ -DWEAR_LEVELING_BACKING_SIZE=65536 \
+ -DWEAR_LEVELING_LOGICAL_SIZE=32768
+wear_leveling_2byte_optimized_writes_SRC := \
+ $(wear_leveling_common_SRC) \
+ $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp
+wear_leveling_2byte_optimized_writes_INC := \
+ $(wear_leveling_common_INC)
+
+wear_leveling_2byte_DEFS := \
+ $(wear_leveling_common_DEFS) \
+ -DBACKING_STORE_WRITE_SIZE=2 \
+ -DWEAR_LEVELING_BACKING_SIZE=48 \
+ -DWEAR_LEVELING_LOGICAL_SIZE=16
+wear_leveling_2byte_SRC := \
+ $(wear_leveling_common_SRC) \
+ $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte.cpp
+wear_leveling_2byte_INC := \
+ $(wear_leveling_common_INC)
+
+wear_leveling_4byte_DEFS := \
+ $(wear_leveling_common_DEFS) \
+ -DBACKING_STORE_WRITE_SIZE=4 \
+ -DWEAR_LEVELING_BACKING_SIZE=48 \
+ -DWEAR_LEVELING_LOGICAL_SIZE=16
+wear_leveling_4byte_SRC := \
+ $(wear_leveling_common_SRC) \
+ $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_4byte.cpp
+wear_leveling_4byte_INC := \
+ $(wear_leveling_common_INC)
+
+wear_leveling_8byte_DEFS := \
+ $(wear_leveling_common_DEFS) \
+ -DBACKING_STORE_WRITE_SIZE=8 \
+ -DWEAR_LEVELING_BACKING_SIZE=48 \
+ -DWEAR_LEVELING_LOGICAL_SIZE=16
+wear_leveling_8byte_SRC := \
+ $(wear_leveling_common_SRC) \
+ $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_8byte.cpp
+wear_leveling_8byte_INC := \
+ $(wear_leveling_common_INC) \ No newline at end of file
diff --git a/quantum/wear_leveling/tests/testlist.mk b/quantum/wear_leveling/tests/testlist.mk
new file mode 100644
index 0000000000..32cfc178b4
--- /dev/null
+++ b/quantum/wear_leveling/tests/testlist.mk
@@ -0,0 +1,6 @@
+TEST_LIST += \
+ wear_leveling_general \
+ wear_leveling_2byte_optimized_writes \
+ wear_leveling_2byte \
+ wear_leveling_4byte \
+ wear_leveling_8byte
diff --git a/quantum/wear_leveling/tests/wear_leveling_2byte.cpp b/quantum/wear_leveling/tests/wear_leveling_2byte.cpp
new file mode 100644
index 0000000000..b749c32b04
--- /dev/null
+++ b/quantum/wear_leveling/tests/wear_leveling_2byte.cpp
@@ -0,0 +1,228 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <numeric>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+class WearLeveling2Byte : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ MockBackingStore::Instance().reset_instance();
+ wear_leveling_init();
+ }
+};
+
+static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data;
+
+static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) {
+ memcpy(&verify_data[address], value, length);
+ return wear_leveling_write(address, value, length);
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location.
+ */
+TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred.
+ */
+TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash_AfterErase) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ wear_leveling_erase();
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the
+ * base logical area.
+ */
+TEST_F(WearLeveling2Byte, ConsolidationOverflow) {
+ auto& inst = MockBackingStore::Instance();
+
+ // Generate a test block of data which forces OPTIMIZED_64 writes
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue;
+
+ // Write the data
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+ EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status";
+ uint8_t dummy = 0x40;
+ EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status";
+
+ // All writes are at address<64, so each logical byte written will generate 1 write log entry, thus 1 backing store write.
+ // Expected log:
+ // [0..11]: optimised64, backing address 0x18, logical address 0x00
+ // [12]: erase
+ // [13..20]: consolidated data, backing address 0x00, logical address 0x00
+ // [21..24]: FNV1a_64 result, backing address 0x10
+ // [25]: optimised64, backing address 0x18, logical address 0x04
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 26);
+
+ // Verify the backing store writes for the write log
+ std::size_t index;
+ write_log_entry_t e;
+ for (index = 0; index < 12; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address";
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type";
+ }
+
+ // Verify the backing store erase
+ {
+ index = 12;
+ auto write_iter = inst.log_begin() + index;
+ e.raw16[0] = write_iter->value;
+ EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required";
+ }
+
+ // Verify the backing store writes for consolidation
+ for (index = 13; index < 21; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, (index - 13) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address";
+ }
+
+ // Verify the FNV1a_64 write
+ {
+ EXPECT_EQ((inst.log_begin() + 21)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address";
+ e.raw16[0] = (inst.log_begin() + 21)->value;
+ e.raw16[1] = (inst.log_begin() + 22)->value;
+ e.raw16[2] = (inst.log_begin() + 23)->value;
+ e.raw16[3] = (inst.log_begin() + 24)->value;
+ EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current
+ }
+
+ // Verify the final write
+ EXPECT_EQ((inst.log_begin() + 25)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address";
+
+ // Verify the data is what we expected
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback;
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+
+ // Re-init and re-read, verifying the reload capability
+ EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed";
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+}
+
+/**
+ * This test verifies multibyte readback gets canceled with an out-of-bounds address.
+ */
+TEST_F(WearLeveling2Byte, PlaybackReadbackMultibyte_OOB) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+ (logstart + 2)->set(0);
+ (logstart + 3)->set(0);
+
+ // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry0.raw8[3] = 0x11;
+ entry0.raw8[4] = 0x12;
+ (logstart + 4)->set(~entry0.raw16[0]);
+ (logstart + 5)->set(~entry0.raw16[1]);
+ (logstart + 6)->set(~entry0.raw16[2]);
+
+ // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds)
+ auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2);
+ entry1.raw8[3] = 0x13;
+ entry1.raw8[4] = 0x14;
+ (logstart + 7)->set(~entry1.raw16[0]);
+ (logstart + 8)->set(~entry1.raw16[1]);
+ (logstart + 9)->set(~entry1.raw16[2]);
+
+ // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x01
+ auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry2.raw8[3] = 0x15;
+ entry2.raw8[4] = 0x16;
+ (logstart + 10)->set(~entry2.raw16[0]);
+ (logstart + 11)->set(~entry2.raw16[1]);
+ (logstart + 12)->set(~entry2.raw16[2]);
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation";
+ EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count";
+
+ uint8_t buf[2];
+ wear_leveling_read(0x01, buf, sizeof(buf));
+ EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log";
+ EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log";
+}
+
+/**
+ * This test verifies optimized 64 readback gets canceled with an out-of-bounds address.
+ */
+TEST_F(WearLeveling2Byte, PlaybackReadbackOptimized64_OOB) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+ (logstart + 2)->set(0);
+ (logstart + 3)->set(0);
+
+ // Set up a 1-byte logical write of 0x11 at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11);
+ (logstart + 4)->set(~entry0.raw16[0]);
+
+ // Set up a 1-byte logical write of 0x11 at logical offset 0x30 (out of bounds)
+ auto entry1 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x30, 0x11);
+ (logstart + 5)->set(~entry1.raw16[0]);
+
+ // Set up a 1-byte logical write of 0x12 at logical offset 0x01
+ auto entry2 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x12);
+ (logstart + 6)->set(~entry2.raw16[0]);
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation";
+ EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count";
+ uint8_t tmp;
+ wear_leveling_read(0x01, &tmp, sizeof(tmp));
+ EXPECT_EQ(tmp, 0x11) << "Readback should have maintained the previous pre-failure value from the write log";
+}
+
+/**
+ * This test verifies word 0/1 readback gets canceled with an out-of-bounds address.
+ */
+TEST_F(WearLeveling2Byte, PlaybackReadbackWord01_OOB) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+ (logstart + 2)->set(0);
+ (logstart + 3)->set(0);
+
+ // Set up a 1-byte logical write of 1 at logical offset 0x02
+ auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1);
+ (logstart + 4)->set(~entry0.raw16[0]);
+
+ // Set up a 1-byte logical write of 1 at logical offset 0x1000 (out of bounds)
+ auto entry1 = LOG_ENTRY_MAKE_WORD_01(0x1000, 1);
+ (logstart + 5)->set(~entry1.raw16[0]);
+
+ // Set up a 1-byte logical write of 0 at logical offset 0x02
+ auto entry2 = LOG_ENTRY_MAKE_WORD_01(0x02, 0);
+ (logstart + 6)->set(~entry2.raw16[0]);
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation";
+ EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count";
+ uint8_t tmp;
+ wear_leveling_read(0x02, &tmp, sizeof(tmp));
+ EXPECT_EQ(tmp, 1) << "Readback should have maintained the previous pre-failure value from the write log";
+}
diff --git a/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp b/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp
new file mode 100644
index 0000000000..0b03113c89
--- /dev/null
+++ b/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp
@@ -0,0 +1,295 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <numeric>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+class WearLeveling2ByteOptimizedWrites : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ MockBackingStore::Instance().reset_instance();
+ wear_leveling_init();
+ }
+};
+
+static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data;
+
+static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) {
+ memcpy(&verify_data[address], value, length);
+ return wear_leveling_write(address, value, length);
+}
+
+/**
+ * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size.
+ */
+TEST_F(WearLeveling2ByteOptimizedWrites, MultibyteBackingStoreWriteCounts) {
+ auto& inst = MockBackingStore::Instance();
+
+ for (std::size_t length = 1; length <= 5; ++length) {
+ // Clear things out
+ std::fill(verify_data.begin(), verify_data.end(), 0);
+ inst.reset_instance();
+ wear_leveling_init();
+
+ // Generate a test block of data
+ std::vector<std::uint8_t> testvalue(length);
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+
+ // Write the data
+ EXPECT_EQ(test_write(2000, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+
+ std::size_t expected;
+ if (length > 3) {
+ expected = 4;
+ } else if (length > 1) {
+ expected = 3;
+ } else {
+ expected = 2;
+ }
+
+ // Check that we got the expected number of write log entries
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected);
+ }
+}
+
+/**
+ * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to even addresses only.
+ * - Addresses <16384 will result in a single optimised backing write
+ * - Higher addresses will result in a multibyte write of 3 backing writes
+ */
+TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToEvenAddresses) {
+ auto& inst = MockBackingStore::Instance();
+
+ // Only attempt writes for each address up to a limit that would NOT force a consolidated data write.
+ std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1
+ std::size_t final_address;
+ for (uint32_t address = 0; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) {
+ // Clear things out
+ std::fill(verify_data.begin(), verify_data.end(), 0);
+ inst.reset_instance();
+ wear_leveling_init();
+
+ // Loop through all the addresses in this range
+ std::size_t expected = 0;
+ for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) {
+ // If we're about to exceed the limit of the logical store, skip the writes
+ if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) {
+ break;
+ }
+
+ // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs.
+ uint16_t val = 1;
+ EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+ val = 0;
+ EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+
+ std::size_t backing_store_writes_expected = 0;
+ if (address + offset < 16384) {
+ // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes
+ backing_store_writes_expected = 2;
+ } else {
+ // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data
+ backing_store_writes_expected = 6;
+ }
+
+ // Keep track of the total number of expected writes to the backing store
+ expected += backing_store_writes_expected;
+
+ // Verify we're at the correct number of writes
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset);
+
+ // Verify that the write log entries we expect are actually present
+ std::size_t write_index = expected - backing_store_writes_expected;
+ auto write_iter = inst.log_begin() + write_index;
+ write_log_entry_t e;
+ if (address + offset < 16384) {
+ // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes
+ for (std::size_t i = 0; i < 2; ++i) {
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_WORD_01) << "Invalid write log entry type at " << (address + offset);
+ ++write_iter;
+ }
+ } else {
+ // Multibyte write
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type at " << (address + offset);
+ EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length at " << (address + offset);
+ ++write_iter;
+ }
+
+ // Keep track of the final address written, so we can verify the entire logical range was handled
+ final_address = address + offset;
+ }
+
+ // Verify the number of writes that occurred to the backing store
+ size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end());
+ EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address;
+
+ // Verify the data is what we expected
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback;
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match";
+
+ // Re-init and re-read, testing the reload capability
+ EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed";
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match";
+ }
+
+ // Verify the full range of the logical area got written
+ EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 2) << "Invalid final write address";
+}
+
+/**
+ * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to odd addresses only.
+ * - Addresses <63 will result in 2 optimised backing writes
+ * - Address 63 results in a single optimised backing write for the first logical byte, and a multibyte write of 2 backing writes for the second logical byte
+ * - Higher addresses will result in a multibyte write of 3 backing writes
+ */
+TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToOddAddresses) {
+ auto& inst = MockBackingStore::Instance();
+
+ // Only attempt writes for each address up to a limit that would NOT force a consolidated data write.
+ std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1
+ std::size_t final_address;
+ for (uint32_t address = 1; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) {
+ // Clear things out
+ std::fill(verify_data.begin(), verify_data.end(), 0);
+ inst.reset_instance();
+ wear_leveling_init();
+
+ // Loop through all the addresses in this range
+ std::size_t expected = 0;
+ for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) {
+ // If we're about to exceed the limit of the logical store, skip the writes
+ if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) {
+ break;
+ }
+
+ // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs.
+ uint16_t val = 1;
+ EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+ val = 0;
+ EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+
+ std::size_t backing_store_writes_expected = 0;
+ if (address + offset < 63) {
+ // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes
+ backing_store_writes_expected = 4;
+ } else if (address + offset == 63) {
+ // If we're straddling the boundary for optimised bytes (addr==64), then the first logical byte is written using the optimised write (1 backing
+ // store write), and the second logical byte uses a multibyte write (2 backing store writes)
+ backing_store_writes_expected = 2 // First logical bytes written using optimised log entries
+ + 4; // Second logical bytes written using multibyte log entries
+ } else {
+ // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data
+ backing_store_writes_expected = 6;
+ }
+
+ // Keep track of the total number of expected writes to the backing store
+ expected += backing_store_writes_expected;
+
+ // Verify we're at the correct number of writes
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset);
+
+ // Verify that the write log entries we expect are actually present
+ std::size_t write_index = expected - backing_store_writes_expected;
+ auto write_iter = inst.log_begin() + write_index;
+ write_log_entry_t e;
+ if (address + offset < 63) {
+ // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes
+ for (std::size_t i = 0; i < 4; ++i) {
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type";
+ ++write_iter;
+ }
+ } else if (address + offset == 63) {
+ // First log entry is the 64-addr optimised one
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type";
+ ++write_iter;
+
+ // Second log entry is the multibyte entry for the second logical byte
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type";
+ EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 1) << "Invalid write log entry length";
+ ++write_iter;
+ } else {
+ // Multibyte write
+ e.raw16[0] = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type";
+ EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length";
+ ++write_iter;
+ }
+
+ // Keep track of the final address written, so we can verify the entire logical range was handled
+ final_address = address + offset;
+ }
+
+ // Verify the number of writes that occurred to the backing store
+ size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end());
+ EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address;
+
+ // Verify the data is what we expected
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback;
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match";
+
+ // Re-init and re-read, testing the reload capability
+ EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed";
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match";
+ }
+
+ // Verify the full range of the logical area got written
+ EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 3) << "Invalid final write address";
+}
+
+/**
+ * This test verifies readback after playback of the write log, simulating power loss and reboot.
+ */
+TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackOptimized64_Success) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+ (logstart + 2)->set(0);
+ (logstart + 3)->set(0);
+
+ // Set up a 1-byte logical write of 0x11 at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11);
+ (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result
+
+ wear_leveling_init();
+ uint8_t tmp;
+
+ wear_leveling_read(0x01, &tmp, sizeof(tmp));
+ EXPECT_EQ(tmp, 0x11) << "Failed to read back the seeded data";
+}
+
+/**
+ * This test verifies readback after playback of the write log, simulating power loss and reboot.
+ */
+TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackWord01_Success) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+ (logstart + 2)->set(0);
+ (logstart + 3)->set(0);
+
+ // Set up a 1-byte logical write of 1 at logical offset 0x02
+ auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1);
+ (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result
+
+ wear_leveling_init();
+ uint8_t tmp;
+
+ wear_leveling_read(0x02, &tmp, sizeof(tmp));
+ EXPECT_EQ(tmp, 1) << "Failed to read back the seeded data";
+}
diff --git a/quantum/wear_leveling/tests/wear_leveling_4byte.cpp b/quantum/wear_leveling/tests/wear_leveling_4byte.cpp
new file mode 100644
index 0000000000..54482c5fe7
--- /dev/null
+++ b/quantum/wear_leveling/tests/wear_leveling_4byte.cpp
@@ -0,0 +1,193 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <numeric>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+class WearLeveling4Byte : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ MockBackingStore::Instance().reset_instance();
+ wear_leveling_init();
+ }
+};
+
+static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data;
+
+static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) {
+ memcpy(&verify_data[address], value, length);
+ return wear_leveling_write(address, value, length);
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location.
+ */
+TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred.
+ */
+TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash_AfterErase) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ wear_leveling_erase();
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size.
+ */
+TEST_F(WearLeveling4Byte, MultibyteBackingStoreWriteCounts) {
+ auto& inst = MockBackingStore::Instance();
+
+ for (std::size_t length = 1; length <= 5; ++length) {
+ // Clear things out
+ std::fill(verify_data.begin(), verify_data.end(), 0);
+ inst.reset_instance();
+ wear_leveling_init();
+
+ // Generate a test block of data
+ std::vector<std::uint8_t> testvalue(length);
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+
+ // Write the data
+ EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+
+ std::size_t expected;
+ if (length > 1) {
+ expected = 2;
+ } else {
+ expected = 1;
+ }
+
+ // Check that we got the expected number of write log entries
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected);
+ }
+}
+
+/**
+ * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the
+ * base logical area.
+ */
+TEST_F(WearLeveling4Byte, ConsolidationOverflow) {
+ auto& inst = MockBackingStore::Instance();
+
+ // Generate a test block of data
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue;
+
+ // Write the data
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+ EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status";
+ uint8_t dummy = 0x40;
+ EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status";
+
+ // Expected log:
+ // [0,1]: multibyte, 5 bytes, backing address 0x18, logical address 0x00
+ // [2,3]: multibyte, 5 bytes, backing address 0x20, logical address 0x05
+ // [4,5]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation
+ // [6]: erase
+ // [7,8]: consolidated data, backing address 0x00, logical address 0x00
+ // [9,10]: consolidated data, backing address 0x08, logical address 0x08
+ // [11,12]: FNV1a_64 result, backing address 0x10
+ // [13]: multibyte, 1 byte, backing address 0x18, logical address 0x04
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 14);
+
+ // Verify the backing store writes for the write log
+ std::size_t index;
+ write_log_entry_t e;
+ for (index = 0; index < 6; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address";
+
+ // If this is the backing store write that contains the metadata, verify it
+ if (index % 2 == 0) {
+ write_log_entry_t e;
+ e.raw64 = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type";
+ }
+ }
+
+ // Verify the backing store erase
+ {
+ index = 6;
+ auto write_iter = inst.log_begin() + index;
+ e.raw64 = write_iter->value;
+ EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required";
+ }
+
+ // Verify the backing store writes for consolidation
+ for (index = 7; index < 11; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, (index - 7) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address";
+ }
+
+ // Verify the FNV1a_64 write
+ {
+ EXPECT_EQ((inst.log_begin() + 11)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address";
+ e.raw32[0] = (inst.log_begin() + 11)->value;
+ e.raw32[1] = (inst.log_begin() + 12)->value;
+ EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current
+ }
+
+ // Verify the final write
+ EXPECT_EQ((inst.log_begin() + 13)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address";
+
+ // Verify the data is what we expected
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback;
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+
+ // Re-init and re-read, verifying the reload capability
+ EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed";
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+}
+
+/**
+ * This test verifies multibyte readback gets canceled with an out-of-bounds address.
+ */
+TEST_F(WearLeveling4Byte, PlaybackReadbackMultibyte_OOB) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+ (logstart + 1)->set(0);
+
+ // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry0.raw8[3] = 0x11;
+ entry0.raw8[4] = 0x12;
+ (logstart + 2)->set(~entry0.raw32[0]);
+ (logstart + 3)->set(~entry0.raw32[1]);
+
+ // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds)
+ auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2);
+ entry1.raw8[3] = 0x13;
+ entry1.raw8[4] = 0x14;
+ (logstart + 4)->set(~entry1.raw32[0]);
+ (logstart + 5)->set(~entry1.raw32[1]);
+
+ // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10
+ auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry2.raw8[3] = 0x15;
+ entry2.raw8[4] = 0x16;
+ (logstart + 6)->set(~entry2.raw32[0]);
+ (logstart + 7)->set(~entry2.raw32[1]);
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation";
+ EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count";
+
+ uint8_t buf[2];
+ wear_leveling_read(0x01, buf, sizeof(buf));
+ EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log";
+ EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log";
+}
diff --git a/quantum/wear_leveling/tests/wear_leveling_8byte.cpp b/quantum/wear_leveling/tests/wear_leveling_8byte.cpp
new file mode 100644
index 0000000000..c27c21d034
--- /dev/null
+++ b/quantum/wear_leveling/tests/wear_leveling_8byte.cpp
@@ -0,0 +1,178 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <numeric>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+class WearLeveling8Byte : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ MockBackingStore::Instance().reset_instance();
+ wear_leveling_init();
+ }
+};
+
+static std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> verify_data;
+
+static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) {
+ memcpy(&verify_data[address], value, length);
+ return wear_leveling_write(address, value, length);
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location.
+ */
+TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred.
+ */
+TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash_AfterErase) {
+ auto& inst = MockBackingStore::Instance();
+ uint8_t test_value = 0x15;
+ wear_leveling_erase();
+ test_write(0x02, &test_value, sizeof(test_value));
+ EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address.";
+}
+
+/**
+ * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size.
+ */
+TEST_F(WearLeveling8Byte, MultibyteBackingStoreWriteCounts) {
+ auto& inst = MockBackingStore::Instance();
+
+ for (std::size_t length = 1; length <= 5; ++length) {
+ // Clear things out
+ std::fill(verify_data.begin(), verify_data.end(), 0);
+ inst.reset_instance();
+ wear_leveling_init();
+
+ // Generate a test block of data
+ std::vector<std::uint8_t> testvalue(length);
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+
+ // Write the data
+ EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status";
+
+ // Check that we got the expected number of write log entries
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 1);
+ }
+}
+
+/**
+ * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the
+ * base logical area.
+ */
+TEST_F(WearLeveling8Byte, ConsolidationOverflow) {
+ auto& inst = MockBackingStore::Instance();
+
+ // Generate a test block of data
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue;
+
+ // Write the data
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+ EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status";
+ uint8_t dummy = 0x40;
+ EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status";
+
+ // Expected log:
+ // [0]: multibyte, 5 bytes, backing address 0x18, logical address 0x00
+ // [1]: multibyte, 5 bytes, backing address 0x20, logical address 0x05
+ // [2]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation
+ // [3]: erase
+ // [4]: consolidated data, backing address 0x00, logical address 0x00
+ // [5]: consolidated data, backing address 0x08, logical address 0x08
+ // [6]: FNV1a_64 result, backing address 0x10
+ // [7]: multibyte, 1 byte, backing address 0x18, logical address 0x04
+ EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 8);
+
+ // Verify the backing store writes for the write log
+ std::size_t index;
+ write_log_entry_t e;
+ for (index = 0; index < 3; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address";
+
+ write_log_entry_t e;
+ e.raw64 = write_iter->value;
+ EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type";
+ }
+
+ // Verify the backing store erase
+ {
+ index = 3;
+ auto write_iter = inst.log_begin() + index;
+ e.raw64 = write_iter->value;
+ EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required";
+ }
+
+ // Verify the backing store writes for consolidation
+ for (index = 4; index < 6; ++index) {
+ auto write_iter = inst.log_begin() + index;
+ EXPECT_EQ(write_iter->address, (index - 4) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address";
+ }
+
+ // Verify the FNV1a_64 write
+ {
+ EXPECT_EQ((inst.log_begin() + 6)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address";
+ e.raw64 = (inst.log_begin() + 6)->value;
+ EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current
+ }
+
+ // Verify the final write
+ EXPECT_EQ((inst.log_begin() + 7)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address";
+
+ // Verify the data is what we expected
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> readback;
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+
+ // Re-init and re-read, verifying the reload capability
+ EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed";
+ EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data";
+ EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match";
+}
+
+/**
+ * This test verifies multibyte readback gets canceled with an out-of-bounds address.
+ */
+TEST_F(WearLeveling8Byte, PlaybackReadbackMultibyte_OOB) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Invalid FNV1a_64 hash
+ (logstart + 0)->set(0);
+
+ // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry0.raw8[3] = 0x11;
+ entry0.raw8[4] = 0x12;
+ (logstart + 1)->set(~entry0.raw64);
+
+ // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds)
+ auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2);
+ entry1.raw8[3] = 0x13;
+ entry1.raw8[4] = 0x14;
+ (logstart + 2)->set(~entry1.raw64);
+
+ // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10
+ auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2);
+ entry2.raw8[3] = 0x15;
+ entry2.raw8[4] = 0x16;
+ (logstart + 3)->set(~entry2.raw64);
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation";
+ EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count";
+
+ uint8_t buf[2];
+ wear_leveling_read(0x01, buf, sizeof(buf));
+ EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log";
+ EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log";
+}
diff --git a/quantum/wear_leveling/tests/wear_leveling_general.cpp b/quantum/wear_leveling/tests/wear_leveling_general.cpp
new file mode 100644
index 0000000000..76a4bf7bf3
--- /dev/null
+++ b/quantum/wear_leveling/tests/wear_leveling_general.cpp
@@ -0,0 +1,204 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <numeric>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "backing_mocks.hpp"
+
+class WearLevelingGeneral : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ MockBackingStore::Instance().reset_instance();
+ wear_leveling_init();
+ }
+};
+
+/**
+ * This test verifies that even if there is consolidated data present, if the checksum doesn't match then the cache is zero'd after reading the consolidated area, but before write log is played back.
+ */
+TEST_F(WearLevelingGeneral, InvalidChecksum_ConsolidatedDataIgnored) {
+ auto& inst = MockBackingStore::Instance();
+ auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t));
+
+ // Generate a test block of data
+ std::array<std::uint8_t, WEAR_LEVELING_LOGICAL_SIZE> testvalue;
+ std::iota(testvalue.begin(), testvalue.end(), 0x20);
+
+ // Write the data
+ EXPECT_EQ(wear_leveling_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status";
+
+ // Invalidate the checksum
+ (logstart + 0)->erase();
+ (logstart + 1)->erase();
+ (logstart + 2)->erase();
+ (logstart + 3)->erase();
+
+ // Set up a 1-byte logical write of [0x11] at logical offset 0x01
+ auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11);
+ (logstart + 4)->set(~entry0.raw16[0]);
+
+ // Re-init
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_SUCCESS) << "Init returned incorrect status";
+ EXPECT_EQ(wear_leveling_read(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Failed to read";
+ for (int i = 0; i < WEAR_LEVELING_LOGICAL_SIZE; ++i) {
+ EXPECT_EQ(testvalue[i], i == 0x01 ? 0x11 : 0x00) << "Invalid readback";
+ }
+}
+
+/**
+ * This test verifies that writing the same data multiple times does not result in subsequent writes to the backing store.
+ */
+TEST_F(WearLevelingGeneral, SameValue_SingleBackingWrite) {
+ auto& inst = MockBackingStore::Instance();
+
+ uint8_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "First overall write operation should have succeeded";
+
+ uint64_t invoke_count = inst.unlock_invoke_count();
+ uint64_t erase_count = inst.erase_invoke_count();
+ uint64_t write_count = inst.write_invoke_count();
+ uint64_t lock_count = inst.lock_invoke_count();
+
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Subsequent overall write operation should have succeeded";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), invoke_count) << "Unlock count should match";
+ EXPECT_EQ(inst.erase_invoke_count(), erase_count) << "Erase count should match";
+ EXPECT_EQ(inst.write_invoke_count(), write_count) << "Write count should match";
+ EXPECT_EQ(inst.lock_invoke_count(), lock_count) << "Lock count should match";
+ }
+}
+
+/**
+ * This test verifies that no other invocations occur if `backing_store_init()` fails.
+ */
+TEST_F(WearLevelingGeneral, InitFailure) {
+ auto& inst = MockBackingStore::Instance();
+ inst.reset_instance(); // make sure the counters are all zero
+ inst.set_init_callback([](std::uint64_t count) { return false; });
+
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count";
+ EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Init should have failed";
+ EXPECT_EQ(inst.erasure_count(), 0) << "Invalid final erase count";
+
+ EXPECT_EQ(inst.init_invoke_count(), 1) << "Init should have been invoked once";
+ EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+}
+
+/**
+ * This test verifies that no invocations occur if the supplied address is out of range while writing.
+ */
+TEST_F(WearLevelingGeneral, WriteFailure_OOB) {
+ auto& inst = MockBackingStore::Instance();
+
+ uint8_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+}
+
+/**
+ * This test verifies that a single write occurs if the supplied address and data length hits the edge of the logical area.
+ */
+TEST_F(WearLevelingGeneral, WriteSuccess_BoundaryOK) {
+ auto& inst = MockBackingStore::Instance();
+
+ uint16_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val), &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Overall write operation should have succeeded";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 2) << "Write should have been invoked twice";
+ EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once";
+}
+
+/**
+ * This test verifies that no invocations occur if the supplied address and length would generate writes outside the logical range.
+ */
+TEST_F(WearLevelingGeneral, WriteFailure_BoundaryOverflow) {
+ auto& inst = MockBackingStore::Instance();
+
+ uint16_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val) + 1, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+}
+
+/**
+ * This test verifies that no invocations occur if the supplied address is out of range while reading.
+ */
+TEST_F(WearLevelingGeneral, ReadFailure_OOB) {
+ auto& inst = MockBackingStore::Instance();
+
+ uint8_t test_val = 0;
+ EXPECT_EQ(wear_leveling_read(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall read operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+}
+
+/**
+ * This test verifies that no write invocations occur if `backing_store_unlock()` fails.
+ */
+TEST_F(WearLevelingGeneral, UnlockFailure_NoWrite) {
+ auto& inst = MockBackingStore::Instance();
+ inst.set_unlock_callback([](std::uint64_t count) { return false; });
+
+ uint8_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+
+ test_val = 0;
+ wear_leveling_read(0x04, &test_val, sizeof(test_val));
+ EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure";
+}
+
+/**
+ * This test verifies that no erase invocations occur if `backing_store_unlock()` fails.
+ */
+TEST_F(WearLevelingGeneral, UnlockFailure_NoErase) {
+ auto& inst = MockBackingStore::Instance();
+ inst.set_unlock_callback([](std::uint64_t count) { return false; });
+
+ EXPECT_EQ(wear_leveling_erase(), WEAR_LEVELING_FAILED) << "Overall erase operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked";
+ EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked";
+}
+
+/**
+ * This test verifies that only one write invocation occurs if `backing_store_write()` fails.
+ */
+TEST_F(WearLevelingGeneral, WriteFailure_NoSubsequentWrites) {
+ auto& inst = MockBackingStore::Instance();
+ inst.set_write_callback([](std::uint64_t count, std::uint32_t address) { return false; });
+
+ uint8_t test_val = 0x14;
+ EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed";
+
+ EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once";
+ EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked";
+ EXPECT_EQ(inst.write_invoke_count(), 1) << "Write should have been invoked once";
+ EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once";
+
+ test_val = 0;
+ wear_leveling_read(0x04, &test_val, sizeof(test_val));
+ EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure";
+}
diff --git a/quantum/wear_leveling/wear_leveling.c b/quantum/wear_leveling/wear_leveling.c
new file mode 100644
index 0000000000..429df45df5
--- /dev/null
+++ b/quantum/wear_leveling/wear_leveling.c
@@ -0,0 +1,768 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <stdbool.h>
+#include "fnv.h"
+#include "wear_leveling.h"
+#include "wear_leveling_internal.h"
+
+/*
+ This wear leveling algorithm is adapted from algorithms from previous
+ implementations in QMK, namely:
+ - Artur F. (http://engsta.com/stm32-flash-memory-eeprom-emulator/)
+ - Yiancar -- QMK's base implementation for STM32F303
+ - Ilya Zhuravlev -- initial wear leveling algorithm
+ - Don Kjer -- increased flash density algorithm
+ - Nick Brassel (@tzarc) -- decoupled for use on other peripherals
+
+ At this layer, it is assumed that any reads/writes from the backing store
+ have a "reset state" after erasure of zero.
+ It is up to the backing store to perform translation of values, such as
+ taking the complement in order to deal with flash memory's reset value.
+
+ Terminology:
+
+ - Backing store: this is the storage area used by the wear leveling
+ algorithm.
+
+ - Backing size: this is the amount of storage provided by the backing
+ store for use by the wear leveling algorithm.
+
+ - Backing write size: this is the minimum number of bytes the backing
+ store can write in a single operation.
+
+ - Logical data: this is the externally-visible "emulated EEPROM" that
+ external subsystems "see" when performing reads/writes.
+
+ - Logical size: this is the amount of storage available for use
+ externally. Effectively, the "size of the EEPROM".
+
+ - Write log: this is a section of the backing store used to keep track
+ of modifications without overwriting existing data. This log is
+ "played back" on startup such that any subsequent reads are capable
+ of returning the latest data.
+
+ - Consolidated data: this is a section of the backing store reserved for
+ use for the latest copy of logical data. This is only ever written
+ when the write log is full -- the latest values for the logical data
+ are written here and the write log is cleared.
+
+ Configurables:
+
+ - BACKING_STORE_WRITE_SIZE: The number of bytes requires for a write
+ operation. This is defined by the capabilities of the backing store.
+
+ - WEAR_LEVELING_BACKING_SIZE: The number of bytes provided by the
+ backing store for use by the wear leveling algorithm. This is
+ defined by the capabilities of the backing store. This value must
+ also be at least twice the size of the logical size, as well as a
+ multiple of the logical size.
+
+ - WEAR_LEVELING_LOGICAL_SIZE: The number of bytes externally visible
+ to other subsystems performing reads/writes. This must be a multiple
+ of the write size.
+
+ General algorithm:
+
+ During initialization:
+ * The contents of the consolidated data section are read into cache.
+ * The contents of the write log are "played back" and update the
+ cache accordingly.
+
+ During reads:
+ * Logical data is served from the cache.
+
+ During writes:
+ * The cache is updated with the new data.
+ * A new write log entry is appended to the log.
+ * If the log's full, data is consolidated and the write log cleared.
+
+ Write log structure:
+
+ The first 8 bytes of the write log are a FNV1a_64 hash of the contents
+ of the consolidated data area, in an attempt to detect and guard against
+ any data corruption.
+
+ The write log follows the hash:
+
+ Given that the algorithm needs to cater for 2-, 4-, and 8-byte writes,
+ a variable-length write log entry is used such that the minimal amount
+ of storage is used based off the backing store write size.
+
+ Firstly, an empty log entry is expected to be all zeros. If the backing
+ store uses 0xFF for cleared bytes, it should return the complement, such
+ that this wear-leveling algorithm "receives" zeros.
+
+ For multi-byte writes, up to 8 bytes will be used for each log entry,
+ depending on the size of backing store writes:
+
+ â•” Multi-byte Log Entry (2, 4-byte) â•â•—
+ â•‘00XXXYYYâ•‘YYYYYYYYâ•‘YYYYYYYYâ•‘AAAAAAAAâ•‘
+ ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║
+ â•‘ LenAddâ•‘ Addressâ•‘ Addressâ•‘Value[0]â•‘
+ â•šâ•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•
+ â•” Multi-byte Log Entry (2-byte) â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
+ â•‘00XXXYYYâ•‘YYYYYYYYâ•‘YYYYYYYYâ•‘AAAAAAAAâ•‘BBBBBBBBâ•‘CCCCCCCCâ•‘
+ ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║
+ â•‘ LenAddâ•‘ Addressâ•‘ Addressâ•‘Value[0]â•‘Value[1]â•‘Value[2]â•‘
+ â•šâ•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•
+ â•” Multi-byte Log Entry (2, 4, 8-byte) â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
+ â•‘00XXXYYYâ•‘YYYYYYYYâ•‘YYYYYYYYâ•‘AAAAAAAAâ•‘BBBBBBBBâ•‘CCCCCCCCâ•‘DDDDDDDDâ•‘EEEEEEEEâ•‘
+ ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║
+ â•‘ LenAddâ•‘ Addressâ•‘ Addressâ•‘Value[0]â•‘Value[1]â•‘Value[2]â•‘Value[3]â•‘Value[4]â•‘
+ â•šâ•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•©â•â•â•â•â•â•â•â•â•
+
+ 19 bits are used for the address, which allows for a max logical size of
+ 512kB. Up to 5 bytes can be included in a single log entry.
+
+ For 2-byte backing store writes, the last two bytes are optional
+ depending on the length of data to be written. Accordingly, either 3
+ or 4 backing store write operations will occur.
+ For 4-byte backing store writes, either one or two write operations
+ occur, depending on the length.
+ For 8-byte backing store writes, one write operation occur.
+
+ 2-byte backing store optimizations:
+
+ For single byte writes, addresses between 0...63 are encoded in a single
+ backing store write operation. 4- and 8-byte backing stores do not have
+ this optimization as it does not minimize the number of bytes written.
+
+ â•” Byte-Entry â•â•â•â•â•—
+ â•‘01XXXXXXYYYYYYYYâ•‘
+ ║ └─┬──┘└──┬───┘║
+ â•‘ Address Value â•‘
+ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
+ 0 <= Address < 0x40 (64)
+
+ A second optimization takes into account uint16_t writes of 0 or 1,
+ specifically catering for KC_NO and KC_TRANSPARENT in the dynamic keymap
+ subsystem. This is valid only for the first 16kB of logical data --
+ addresses outside this range will use the multi-byte encoding above.
+
+ â•” U16-Encoded 0 â•â•—
+ â•‘100XXXXXXXXXXXXXâ•‘
+ ║ │└─────┬─────┘║
+ ║ │Address >> 1 ║
+ ║ └── Value: 0 ║
+ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
+ 0 <= Address <= 0x3FFE (16382)
+
+ â•” U16-Encoded 1 â•â•—
+ â•‘101XXXXXXXXXXXXXâ•‘
+ ║ │└─────┬─────┘║
+ ║ │Address >> 1 ║
+ ║ └── Value: 1 ║
+ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
+ 0 <= Address <= 0x3FFE (16382) */
+
+/**
+ * Storage area for the wear-leveling cache.
+ */
+static struct __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) {
+ __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) uint8_t cache[(WEAR_LEVELING_LOGICAL_SIZE)];
+ uint32_t write_address;
+ bool unlocked;
+} wear_leveling;
+
+/**
+ * Locking helper: status
+ */
+typedef enum backing_store_lock_status_t { STATUS_FAILURE = 0, STATUS_SUCCESS, STATUS_UNCHANGED } backing_store_lock_status_t;
+
+/**
+ * Locking helper: unlock
+ */
+static inline backing_store_lock_status_t wear_leveling_unlock(void) {
+ if (wear_leveling.unlocked) {
+ return STATUS_UNCHANGED;
+ }
+ if (!backing_store_unlock()) {
+ return STATUS_FAILURE;
+ }
+ wear_leveling.unlocked = true;
+ return STATUS_SUCCESS;
+}
+
+/**
+ * Locking helper: lock
+ */
+static inline backing_store_lock_status_t wear_leveling_lock(void) {
+ if (!wear_leveling.unlocked) {
+ return STATUS_UNCHANGED;
+ }
+ if (!backing_store_lock()) {
+ return STATUS_FAILURE;
+ }
+ wear_leveling.unlocked = false;
+ return STATUS_SUCCESS;
+}
+
+/**
+ * Resets the cache, ensuring the write address is correctly initialised.
+ */
+static void wear_leveling_clear_cache(void) {
+ memset(wear_leveling.cache, 0, (WEAR_LEVELING_LOGICAL_SIZE));
+ wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 is due to the FNV1a_64 of the consolidated buffer
+}
+
+/**
+ * Reads the consolidated data from the backing store into the cache.
+ * Does not consider the write log.
+ */
+static wear_leveling_status_t wear_leveling_read_consolidated(void) {
+ wl_dprintf("Reading consolidated data\n");
+
+ wear_leveling_status_t status = WEAR_LEVELING_SUCCESS;
+ if (!backing_store_read_bulk(0, (backing_store_int_t *)wear_leveling.cache, sizeof(wear_leveling.cache) / sizeof(backing_store_int_t))) {
+ wl_dprintf("Failed to read from backing store\n");
+ status = WEAR_LEVELING_FAILED;
+ }
+
+ // Verify the FNV1a_64 result
+ if (status != WEAR_LEVELING_FAILED) {
+ uint64_t expected = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT);
+ write_log_entry_t entry;
+ wl_dprintf("Reading checksum\n");
+#if BACKING_STORE_WRITE_SIZE == 2
+ backing_store_read_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw16, 4);
+#elif BACKING_STORE_WRITE_SIZE == 4
+ backing_store_read_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw32, 2);
+#elif BACKING_STORE_WRITE_SIZE == 8
+ backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 0, &entry.raw64);
+#endif
+ // If we have a mismatch, clear the cache but do not flag a failure,
+ // which will cater for the completely clean MCU case.
+ if (entry.raw64 == expected) {
+ wl_dprintf("Checksum matches, consolidated data is correct\n");
+ } else {
+ wl_dprintf("Checksum mismatch, clearing cache\n");
+ wear_leveling_clear_cache();
+ }
+ }
+
+ // If we failed for any reason, then clear the cache
+ if (status == WEAR_LEVELING_FAILED) {
+ wear_leveling_clear_cache();
+ }
+
+ return status;
+}
+
+/**
+ * Writes the current cache to consolidated data at the beginning of the backing store.
+ * Does not clear the write log.
+ * Pre-condition: this is just after an erase, so we can write directly without reading.
+ */
+static wear_leveling_status_t wear_leveling_write_consolidated(void) {
+ wl_dprintf("Writing consolidated data\n");
+
+ backing_store_lock_status_t lock_status = wear_leveling_unlock();
+ wear_leveling_status_t status = WEAR_LEVELING_CONSOLIDATED;
+ if (!backing_store_write_bulk(0, (backing_store_int_t *)wear_leveling.cache, sizeof(wear_leveling.cache) / sizeof(backing_store_int_t))) {
+ wl_dprintf("Failed to write to backing store\n");
+ status = WEAR_LEVELING_FAILED;
+ }
+
+ if (status != WEAR_LEVELING_FAILED) {
+ // Write out the FNV1a_64 result of the consolidated data
+ write_log_entry_t entry;
+ entry.raw64 = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT);
+ wl_dprintf("Writing checksum\n");
+ do {
+#if BACKING_STORE_WRITE_SIZE == 2
+ if (!backing_store_write_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw16, 4)) {
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+#elif BACKING_STORE_WRITE_SIZE == 4
+ if (!backing_store_write_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw32, 2)) {
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+#elif BACKING_STORE_WRITE_SIZE == 8
+ if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE), entry.raw64)) {
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+#endif
+ } while (0);
+ }
+
+ if (lock_status == STATUS_SUCCESS) {
+ wear_leveling_lock();
+ }
+ return status;
+}
+
+/**
+ * Forces a write of the current cache.
+ * Erases the backing store, including the write log.
+ * During this operation, there is the potential for data loss if a power loss occurs.
+ */
+static wear_leveling_status_t wear_leveling_consolidate_force(void) {
+ wl_dprintf("Erasing backing store\n");
+
+ // Erase the backing store. Expectation is that any un-written values that are read back after this call come back as zero.
+ bool ok = backing_store_erase();
+ if (!ok) {
+ wl_dprintf("Failed to erase backing store\n");
+ return WEAR_LEVELING_FAILED;
+ }
+
+ // Write the cache to the first section of the backing store.
+ wear_leveling_status_t status = wear_leveling_write_consolidated();
+ if (status == WEAR_LEVELING_FAILED) {
+ wl_dprintf("Failed to write consolidated data\n");
+ }
+
+ // Next write of the log occurs after the consolidated values at the start of the backing store.
+ wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area
+
+ return status;
+}
+
+/**
+ * Potential write of the current cache to the backing store.
+ * Skipped if the current write log position is not at the end of the backing store.
+ * During this operation, there is the potential for data loss if a power loss occurs.
+ *
+ * @return true if consolidation occurred
+ */
+static wear_leveling_status_t wear_leveling_consolidate_if_needed(void) {
+ if (wear_leveling.write_address >= (WEAR_LEVELING_BACKING_SIZE)) {
+ return wear_leveling_consolidate_force();
+ }
+
+ return WEAR_LEVELING_SUCCESS;
+}
+
+/**
+ * Appends the supplied fixed-width entry to the write log, optionally consolidating if the log is full.
+ *
+ * @return true if consolidation occurred
+ */
+static wear_leveling_status_t wear_leveling_append_raw(backing_store_int_t value) {
+ bool ok = backing_store_write(wear_leveling.write_address, value);
+ if (!ok) {
+ wl_dprintf("Failed to write to backing store\n");
+ return WEAR_LEVELING_FAILED;
+ }
+ wear_leveling.write_address += (BACKING_STORE_WRITE_SIZE);
+ return wear_leveling_consolidate_if_needed();
+}
+
+/**
+ * Handles writing multi_byte-encoded data to the backing store.
+ *
+ * @return true if consolidation occurred
+ */
+static wear_leveling_status_t wear_leveling_write_raw_multibyte(uint32_t address, const void *value, size_t length) {
+ const uint8_t * p = value;
+ write_log_entry_t log = LOG_ENTRY_MAKE_MULTIBYTE(address, length);
+ for (size_t i = 0; i < length; ++i) {
+ log.raw8[3 + i] = p[i];
+ }
+
+ // Write to the backing store. See the multi-byte log format in the documentation header at the top of the file.
+ wear_leveling_status_t status;
+#if BACKING_STORE_WRITE_SIZE == 2
+ status = wear_leveling_append_raw(log.raw16[0]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+
+ status = wear_leveling_append_raw(log.raw16[1]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+
+ if (length > 1) {
+ status = wear_leveling_append_raw(log.raw16[2]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+ }
+
+ if (length > 3) {
+ status = wear_leveling_append_raw(log.raw16[3]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+ }
+#elif BACKING_STORE_WRITE_SIZE == 4
+ status = wear_leveling_append_raw(log.raw32[0]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+
+ if (length > 1) {
+ status = wear_leveling_append_raw(log.raw32[1]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+ }
+#elif BACKING_STORE_WRITE_SIZE == 8
+ status = wear_leveling_append_raw(log.raw64);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ return status;
+ }
+#endif
+ return status;
+}
+
+/**
+ * Handles the actual writing of logical data into the write log section of the backing store.
+ */
+static wear_leveling_status_t wear_leveling_write_raw(uint32_t address, const void *value, size_t length) {
+ const uint8_t * p = value;
+ size_t remaining = length;
+ wear_leveling_status_t status = WEAR_LEVELING_SUCCESS;
+ while (remaining > 0) {
+#if BACKING_STORE_WRITE_SIZE == 2
+ // Small-write optimizations - uint16_t, 0 or 1, address is even, address <16384:
+ if (remaining >= 2 && address % 2 == 0 && address < 16384) {
+ const uint16_t v = ((uint16_t)p[1]) << 8 | p[0]; // don't just dereference a uint16_t here -- if unaligned it generates faults on some MCUs
+ if (v == 0 || v == 1) {
+ const write_log_entry_t log = LOG_ENTRY_MAKE_WORD_01(address, v);
+ status = wear_leveling_append_raw(log.raw16[0]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue.
+ // If a failure occurred, pass it on.
+ return status;
+ }
+
+ remaining -= 2;
+ address += 2;
+ p += 2;
+ continue;
+ }
+ }
+
+ // Small-write optimizations - address<64:
+ if (address < 64) {
+ const write_log_entry_t log = LOG_ENTRY_MAKE_OPTIMIZED_64(address, *p);
+ status = wear_leveling_append_raw(log.raw16[0]);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue.
+ // If a failure occurred, pass it on.
+ return status;
+ }
+
+ remaining--;
+ address++;
+ p++;
+ continue;
+ }
+#endif // BACKING_STORE_WRITE_SIZE == 2
+ const size_t this_length = remaining >= LOG_ENTRY_MULTIBYTE_MAX_BYTES ? LOG_ENTRY_MULTIBYTE_MAX_BYTES : remaining;
+ status = wear_leveling_write_raw_multibyte(address, p, this_length);
+ if (status != WEAR_LEVELING_SUCCESS) {
+ // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue.
+ // If a failure occurred, pass it on.
+ return status;
+ }
+ remaining -= this_length;
+ address += (uint32_t)this_length;
+ p += this_length;
+ }
+
+ return status;
+}
+
+/**
+ * "Replays" the write log from the backing store, updating the local cache with updated values.
+ */
+static wear_leveling_status_t wear_leveling_playback_log(void) {
+ wl_dprintf("Playback write log\n");
+
+ wear_leveling_status_t status = WEAR_LEVELING_SUCCESS;
+ bool cancel_playback = false;
+ uint32_t address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area
+ while (!cancel_playback && address < (WEAR_LEVELING_BACKING_SIZE)) {
+ backing_store_int_t value;
+ bool ok = backing_store_read(address, &value);
+ if (!ok) {
+ wl_dprintf("Failed to load from backing store, skipping playback of write log\n");
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+ if (value == 0) {
+ wl_dprintf("Found empty slot, no more log entries\n");
+ cancel_playback = true;
+ break;
+ }
+
+ // If we got a nonzero value, then we need to increment the address to ensure next write occurs at next location
+ address += (BACKING_STORE_WRITE_SIZE);
+
+ // Read from the write log
+ write_log_entry_t log;
+#if BACKING_STORE_WRITE_SIZE == 2
+ log.raw16[0] = value;
+#elif BACKING_STORE_WRITE_SIZE == 4
+ log.raw32[0] = value;
+#elif BACKING_STORE_WRITE_SIZE == 8
+ log.raw64 = value;
+#endif
+
+ switch (LOG_ENTRY_GET_TYPE(log)) {
+ case LOG_ENTRY_TYPE_MULTIBYTE: {
+#if BACKING_STORE_WRITE_SIZE == 2
+ ok = backing_store_read(address, &log.raw16[1]);
+ if (!ok) {
+ wl_dprintf("Failed to load from backing store, skipping playback of write log\n");
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+ address += (BACKING_STORE_WRITE_SIZE);
+#endif // BACKING_STORE_WRITE_SIZE == 2
+ const uint32_t a = LOG_ENTRY_MULTIBYTE_GET_ADDRESS(log);
+ const uint8_t l = LOG_ENTRY_MULTIBYTE_GET_LENGTH(log);
+
+ if (a + l > (WEAR_LEVELING_LOGICAL_SIZE)) {
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+
+#if BACKING_STORE_WRITE_SIZE == 2
+ if (l > 1) {
+ ok = backing_store_read(address, &log.raw16[2]);
+ if (!ok) {
+ wl_dprintf("Failed to load from backing store, skipping playback of write log\n");
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+ address += (BACKING_STORE_WRITE_SIZE);
+ }
+ if (l > 3) {
+ ok = backing_store_read(address, &log.raw16[3]);
+ if (!ok) {
+ wl_dprintf("Failed to load from backing store, skipping playback of write log\n");
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+ address += (BACKING_STORE_WRITE_SIZE);
+ }
+#elif BACKING_STORE_WRITE_SIZE == 4
+ if (l > 1) {
+ ok = backing_store_read(address, &log.raw32[1]);
+ if (!ok) {
+ wl_dprintf("Failed to load from backing store, skipping playback of write log\n");
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+ address += (BACKING_STORE_WRITE_SIZE);
+ }
+#endif
+
+ memcpy(&wear_leveling.cache[a], &log.raw8[3], l);
+ } break;
+#if BACKING_STORE_WRITE_SIZE == 2
+ case LOG_ENTRY_TYPE_OPTIMIZED_64: {
+ const uint32_t a = LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(log);
+ const uint8_t v = LOG_ENTRY_OPTIMIZED_64_GET_VALUE(log);
+
+ if (a >= (WEAR_LEVELING_LOGICAL_SIZE)) {
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+
+ wear_leveling.cache[a] = v;
+ } break;
+ case LOG_ENTRY_TYPE_WORD_01: {
+ const uint32_t a = LOG_ENTRY_WORD_01_GET_ADDRESS(log);
+ const uint8_t v = LOG_ENTRY_WORD_01_GET_VALUE(log);
+
+ if (a + 1 >= (WEAR_LEVELING_LOGICAL_SIZE)) {
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+
+ wear_leveling.cache[a + 0] = v;
+ wear_leveling.cache[a + 1] = 0;
+ } break;
+#endif // BACKING_STORE_WRITE_SIZE == 2
+ default: {
+ cancel_playback = true;
+ status = WEAR_LEVELING_FAILED;
+ } break;
+ }
+ }
+
+ // We've reached the end of the log, so we're at the new write location
+ wear_leveling.write_address = address;
+
+ if (status == WEAR_LEVELING_FAILED) {
+ // If we had a failure during readback, assume we're corrupted -- force a consolidation with the data we already have
+ status = wear_leveling_consolidate_force();
+ } else {
+ // Consolidate the cache + write log if required
+ status = wear_leveling_consolidate_if_needed();
+ }
+
+ return status;
+}
+
+/**
+ * Wear-leveling initialization
+ */
+wear_leveling_status_t wear_leveling_init(void) {
+ wl_dprintf("Init\n");
+
+ // Reset the cache
+ wear_leveling_clear_cache();
+
+ // Initialise the backing store
+ if (!backing_store_init()) {
+ // If it failed, clear the cache and return with failure
+ wear_leveling_clear_cache();
+ return WEAR_LEVELING_FAILED;
+ }
+
+ // Read the previous consolidated values, then replay the existing write log so that the cache has the "live" values
+ wear_leveling_status_t status = wear_leveling_read_consolidated();
+ if (status == WEAR_LEVELING_FAILED) {
+ // If it failed, clear the cache and return with failure
+ wear_leveling_clear_cache();
+ return status;
+ }
+
+ status = wear_leveling_playback_log();
+ if (status == WEAR_LEVELING_FAILED) {
+ // If it failed, clear the cache and return with failure
+ wear_leveling_clear_cache();
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * Wear-leveling erase.
+ * Post-condition: any reads from the backing store directly after an erase operation must come back as zero.
+ */
+wear_leveling_status_t wear_leveling_erase(void) {
+ wl_dprintf("Erase\n");
+
+ // Unlock the backing store
+ backing_store_lock_status_t lock_status = wear_leveling_unlock();
+ if (lock_status == STATUS_FAILURE) {
+ wear_leveling_lock();
+ return WEAR_LEVELING_FAILED;
+ }
+
+ // Perform the erase
+ bool ret = backing_store_erase();
+ wear_leveling_clear_cache();
+
+ // Lock the backing store if we acquired the lock successfully
+ if (lock_status == STATUS_SUCCESS) {
+ ret &= (wear_leveling_lock() != STATUS_FAILURE);
+ }
+
+ return ret ? WEAR_LEVELING_SUCCESS : WEAR_LEVELING_FAILED;
+}
+
+/**
+ * Writes logical data into the backing store. Skips writes if there are no changes to values.
+ */
+wear_leveling_status_t wear_leveling_write(const uint32_t address, const void *value, size_t length) {
+ wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE));
+ if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) {
+ return WEAR_LEVELING_FAILED;
+ }
+
+ wl_dprintf("Write ");
+ wl_dump(address, value, length);
+
+ // Skip write if there's no change compared to the current cached value
+ if (memcmp(value, &wear_leveling.cache[address], length) == 0) {
+ return true;
+ }
+
+ // Update the cache before writing to the backing store -- if we hit the end of the backing store during writes to the log then we'll force a consolidation in-line
+ memcpy(&wear_leveling.cache[address], value, length);
+
+ // Unlock the backing store
+ backing_store_lock_status_t lock_status = wear_leveling_unlock();
+ if (lock_status == STATUS_FAILURE) {
+ wear_leveling_lock();
+ return WEAR_LEVELING_FAILED;
+ }
+
+ // Perform the actual write
+ wear_leveling_status_t status = wear_leveling_write_raw(address, value, length);
+ switch (status) {
+ case WEAR_LEVELING_CONSOLIDATED:
+ case WEAR_LEVELING_FAILED:
+ // If the write triggered consolidation, or the write failed, then nothing else needs to occur.
+ break;
+
+ case WEAR_LEVELING_SUCCESS:
+ // Consolidate the cache + write log if required
+ status = wear_leveling_consolidate_if_needed();
+ break;
+
+ default:
+ // Unsure how we'd get here...
+ status = WEAR_LEVELING_FAILED;
+ break;
+ }
+
+ if (lock_status == STATUS_SUCCESS) {
+ if (wear_leveling_lock() == STATUS_FAILURE) {
+ status = WEAR_LEVELING_FAILED;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * Reads logical data from the cache.
+ */
+wear_leveling_status_t wear_leveling_read(const uint32_t address, void *value, size_t length) {
+ wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE));
+ if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) {
+ return WEAR_LEVELING_FAILED;
+ }
+
+ // Only need to copy from the cache
+ memcpy(value, &wear_leveling.cache[address], length);
+
+ wl_dprintf("Read ");
+ wl_dump(address, value, length);
+ return WEAR_LEVELING_SUCCESS;
+}
+
+/**
+ * Weak implementation of bulk read, drivers can implement more optimised implementations.
+ */
+__attribute__((weak)) bool backing_store_read_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ for (size_t i = 0; i < item_count; ++i) {
+ if (!backing_store_read(address + (i * BACKING_STORE_WRITE_SIZE), &values[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * Weak implementation of bulk write, drivers can implement more optimised implementations.
+ */
+__attribute__((weak)) bool backing_store_write_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) {
+ for (size_t i = 0; i < item_count; ++i) {
+ if (!backing_store_write(address + (i * BACKING_STORE_WRITE_SIZE), values[i])) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/quantum/wear_leveling/wear_leveling.h b/quantum/wear_leveling/wear_leveling.h
new file mode 100644
index 0000000000..6641bc49b3
--- /dev/null
+++ b/quantum/wear_leveling/wear_leveling.h
@@ -0,0 +1,54 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+#include <stdint.h>
+#include <stdlib.h>
+
+/**
+ * @typedef Status returned from any wear-leveling API.
+ */
+typedef enum wear_leveling_status_t {
+ WEAR_LEVELING_FAILED, //< Invocation failed
+ WEAR_LEVELING_SUCCESS, //< Invocation succeeded
+ WEAR_LEVELING_CONSOLIDATED //< Invocation succeeded, consolidation occurred
+} wear_leveling_status_t;
+
+/**
+ * Wear-leveling initialization
+ *
+ * @return Status of the request
+ */
+wear_leveling_status_t wear_leveling_init(void);
+
+/**
+ * Wear-leveling erasure.
+ *
+ * Clears the wear-leveling area, with the definition that the "reset state" of all data is zero.
+ *
+ * @return Status of the request
+ */
+wear_leveling_status_t wear_leveling_erase(void);
+
+/**
+ * Writes logical data into the backing store.
+ *
+ * Skips writes if there are no changes to written values. The entire written block is considered when attempting to
+ * determine if an overwrite should occur -- if there is any data mismatch the entire block will be written to the log,
+ * not just the changed bytes.
+ *
+ * @param address[in] the logical address to write data
+ * @param value[in] pointer to the source buffer
+ * @param length[in] length of the data
+ * @return Status of the request
+ */
+wear_leveling_status_t wear_leveling_write(uint32_t address, const void* value, size_t length);
+
+/**
+ * Reads logical data from the cache.
+ *
+ * @param address[in] the logical address to read data
+ * @param value[out] pointer to the destination buffer
+ * @param length[in] length of the data
+ * @return Status of the request
+ */
+wear_leveling_status_t wear_leveling_read(uint32_t address, void* value, size_t length);
diff --git a/quantum/wear_leveling/wear_leveling_internal.h b/quantum/wear_leveling/wear_leveling_internal.h
new file mode 100644
index 0000000000..e83f9b22ea
--- /dev/null
+++ b/quantum/wear_leveling/wear_leveling_internal.h
@@ -0,0 +1,151 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#ifdef __cplusplus
+# define _Static_assert static_assert
+#endif
+
+#include <stdint.h>
+#include <string.h>
+
+#if BACKING_STORE_WRITE_SIZE == 2
+typedef uint16_t backing_store_int_t;
+#elif BACKING_STORE_WRITE_SIZE == 4
+typedef uint32_t backing_store_int_t;
+#elif BACKING_STORE_WRITE_SIZE == 8
+typedef uint64_t backing_store_int_t;
+#else
+# error Invalid BACKING_STORE_WRITE_SIZE, needs to be 2/4/8.
+#endif
+
+#ifndef WEAR_LEVELING_BACKING_SIZE
+# error WEAR_LEVELING_BACKING_SIZE was not set.
+#endif
+
+#ifndef WEAR_LEVELING_LOGICAL_SIZE
+# error WEAR_LEVELING_LOGICAL_SIZE was not set.
+#endif
+
+#ifdef WEAR_LEVELING_DEBUG_OUTPUT
+# include <debug.h>
+# define bs_dprintf(...) dprintf("Backing store: " __VA_ARGS__)
+# define wl_dprintf(...) dprintf("Wear leveling: " __VA_ARGS__)
+# define wl_dump(address, value, length) \
+ do { \
+ dprintf("[0x%04X]: ", (int)(address)); \
+ const uint8_t* p = (const uint8_t*)(value); \
+ for (int i = 0; i < (length); ++i) { \
+ dprintf(" %02X", (int)p[i]); \
+ } \
+ dprintf("\n"); \
+ } while (0)
+#else
+# define wl_dprintf(...) \
+ do { \
+ } while (0)
+# define bs_dprintf(...) \
+ do { \
+ } while (0)
+# define wl_dump(...) \
+ do { \
+ } while (0)
+#endif // WEAR_LEVELING_DEBUG_OUTPUT
+
+#ifdef WEAR_LEVELING_ASSERTS
+# include <assert.h>
+# define wl_assert(...) assert(__VA_ARGS__)
+#else
+# define wl_assert(...) \
+ do { \
+ } while (0)
+#endif // WEAR_LEVELING_ASSERTS
+
+// Compile-time validation of configurable options
+_Static_assert(WEAR_LEVELING_BACKING_SIZE >= (WEAR_LEVELING_LOGICAL_SIZE * 2), "Total backing size must be at least twice the size of the logical size");
+_Static_assert(WEAR_LEVELING_LOGICAL_SIZE % BACKING_STORE_WRITE_SIZE == 0, "Logical size must be a multiple of write size");
+_Static_assert(WEAR_LEVELING_BACKING_SIZE % WEAR_LEVELING_LOGICAL_SIZE == 0, "Backing size must be a multiple of logical size");
+
+// Backing Store API, to be implemented elsewhere by flash driver etc.
+bool backing_store_init(void);
+bool backing_store_unlock(void);
+bool backing_store_erase(void);
+bool backing_store_write(uint32_t address, backing_store_int_t value);
+bool backing_store_write_bulk(uint32_t address, backing_store_int_t* values, size_t item_count); // weak implementation already provided, optimized implementation can be implemented by driver
+bool backing_store_lock(void);
+bool backing_store_read(uint32_t address, backing_store_int_t* value);
+bool backing_store_read_bulk(uint32_t address, backing_store_int_t* values, size_t item_count); // weak implementation already provided, optimized implementation can be implemented by driver
+
+/**
+ * Helper type used to contain a write log entry.
+ */
+typedef union write_log_entry_t {
+ uint64_t raw64;
+ uint32_t raw32[2];
+ uint16_t raw16[4];
+ uint8_t raw8[8];
+} write_log_entry_t;
+
+_Static_assert(sizeof(write_log_entry_t) == 8, "Wear leveling write log entry size was not 8");
+
+/**
+ * Log entry type discriminator.
+ */
+enum {
+ // 0x00 -- Multi-byte storage type
+ LOG_ENTRY_TYPE_MULTIBYTE,
+
+ // 0x01 -- 2-byte backing store write optimization: address < 64
+ LOG_ENTRY_TYPE_OPTIMIZED_64,
+
+ // 0x02 -- 2-byte backing store write optimization: word-encoded 0/1 values
+ LOG_ENTRY_TYPE_WORD_01,
+
+ LOG_ENTRY_TYPES
+};
+
+_Static_assert(LOG_ENTRY_TYPES <= (1 << 2), "Too many log entry types to fit into 2 bits of storage");
+
+#define BITMASK_FOR_BITCOUNT(n) ((1 << (n)) - 1)
+
+#define LOG_ENTRY_GET_TYPE(entry) (((entry).raw8[0] >> 6) & BITMASK_FOR_BITCOUNT(2))
+
+#define LOG_ENTRY_MULTIBYTE_MAX_BYTES 5
+#define LOG_ENTRY_MULTIBYTE_GET_ADDRESS(entry) (((((uint32_t)((entry).raw8[0])) & BITMASK_FOR_BITCOUNT(3)) << 16) | (((uint32_t)((entry).raw8[1])) << 8) | (entry).raw8[2])
+#define LOG_ENTRY_MULTIBYTE_GET_LENGTH(entry) ((uint8_t)(((entry).raw8[0] >> 3) & BITMASK_FOR_BITCOUNT(3)))
+#define LOG_ENTRY_MAKE_MULTIBYTE(address, length) \
+ (write_log_entry_t) { \
+ .raw8 = { \
+ [0] = (((((uint8_t)LOG_ENTRY_TYPE_MULTIBYTE) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \
+ | ((((uint8_t)(length)) & BITMASK_FOR_BITCOUNT(3)) << 3) /* length */ \
+ | ((((uint8_t)((address) >> 16))) & BITMASK_FOR_BITCOUNT(3)) /* address */ \
+ ), \
+ [1] = (((uint8_t)((address) >> 8)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \
+ [2] = (((uint8_t)(address)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \
+ } \
+ }
+
+#define LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(entry) ((uint32_t)((entry).raw8[0] & BITMASK_FOR_BITCOUNT(6)))
+#define LOG_ENTRY_OPTIMIZED_64_GET_VALUE(entry) ((entry).raw8[1])
+#define LOG_ENTRY_MAKE_OPTIMIZED_64(address, value) \
+ (write_log_entry_t) { \
+ .raw8 = { \
+ [0] = (((((uint8_t)LOG_ENTRY_TYPE_OPTIMIZED_64) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \
+ | ((((uint8_t)(address))) & BITMASK_FOR_BITCOUNT(6)) /* address */ \
+ ), \
+ [1] = ((uint8_t)(value)), /* value */ \
+ } \
+ }
+
+#define LOG_ENTRY_WORD_01_GET_ADDRESS(entry) ((((uint32_t)(((entry).raw8[0]) & BITMASK_FOR_BITCOUNT(5))) << 9) | (((uint32_t)((entry).raw8[1])) << 1))
+#define LOG_ENTRY_WORD_01_GET_VALUE(entry) ((uint8_t)((entry).raw8[0] >> 5) & BITMASK_FOR_BITCOUNT(1))
+#define LOG_ENTRY_MAKE_WORD_01(address, value) \
+ (write_log_entry_t) { \
+ .raw8 = { \
+ [0] = (((((uint8_t)LOG_ENTRY_TYPE_WORD_01) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \
+ | (((((uint8_t)((value) ? 1 : 0))) & BITMASK_FOR_BITCOUNT(1)) << 5) /* value */ \
+ | ((((uint8_t)((address) >> 9))) & BITMASK_FOR_BITCOUNT(5)) /* address */ \
+ ), \
+ [1] = (uint8_t)((address) >> 1), /* address */ \
+ } \
+ }
diff --git a/readme.md b/readme.md
index 5649ddfa09..63b483c744 100644
--- a/readme.md
+++ b/readme.md
@@ -1,3 +1,7 @@
+# This is the `develop` branch!
+
+See the [Breaking Changes](https://docs.qmk.fm/#/breaking_changes) document for more information.
+
# Quantum Mechanical Keyboard Firmware
[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags)
diff --git a/keyboards/boardsource/holiday/spooky/spooky.c b/tests/tap_dance/config.h
index 87fe02c1a8..6aada3efd3 100644
--- a/keyboards/boardsource/holiday/spooky/spooky.c
+++ b/tests/tap_dance/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2020 boardsource
+/* Copyright 2022 Jouke Witteveen
*
* 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
@@ -14,4 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "spooky.h"
+#pragma once
+
+#include "test_common.h"
diff --git a/tests/tap_dance/examples.c b/tests/tap_dance/examples.c
new file mode 100644
index 0000000000..4a5be41b08
--- /dev/null
+++ b/tests/tap_dance/examples.c
@@ -0,0 +1,199 @@
+/* Copyright 2022 Jouke Witteveen
+ *
+ * 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 "quantum.h"
+#include "examples.h"
+
+// Example code from the tap dance documentation, adapted for testing
+
+// clang-format off
+
+// Example 1
+
+void dance_egg(qk_tap_dance_state_t *state, void *user_data) {
+ if (state->count >= 100) {
+ // SEND_STRING("Safety dance!");
+ tap_code(KC_C);
+ reset_tap_dance(state);
+ }
+}
+
+
+// Example 2
+
+void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) {
+ switch (state->count) {
+ case 1:
+ register_code(KC_3);
+ break;
+ case 2:
+ register_code(KC_2);
+ break;
+ case 3:
+ register_code(KC_1);
+ break;
+ case 4:
+ unregister_code(KC_3);
+ // wait_ms(50);
+ unregister_code(KC_2);
+ // wait_ms(50);
+ unregister_code(KC_1);
+ }
+}
+
+void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) {
+ if (state->count >= 4) {
+ // reset_keyboard();
+ tap_code(KC_R);
+ }
+}
+
+void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) {
+ unregister_code(KC_1);
+ // wait_ms(50);
+ unregister_code(KC_2);
+ // wait_ms(50);
+ unregister_code(KC_3);
+}
+
+
+// Example 3
+
+typedef struct {
+ uint16_t tap;
+ uint16_t hold;
+ uint16_t held;
+} tap_dance_tap_hold_t;
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ qk_tap_dance_action_t *action;
+
+ switch (keycode) {
+ case TD(CT_CLN):
+ action = &tap_dance_actions[TD_INDEX(keycode)];
+ if (!record->event.pressed && action->state.count && !action->state.finished) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
+ tap_code16(tap_hold->tap);
+ }
+ }
+ return true;
+}
+
+void tap_dance_tap_hold_finished(qk_tap_dance_state_t *state, void *user_data) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
+
+ if (state->pressed) {
+ if (state->count == 1
+#ifndef PERMISSIVE_HOLD
+ && !state->interrupted
+#endif
+ ) {
+ register_code16(tap_hold->hold);
+ tap_hold->held = tap_hold->hold;
+ } else {
+ register_code16(tap_hold->tap);
+ tap_hold->held = tap_hold->tap;
+ }
+ }
+}
+
+void tap_dance_tap_hold_reset(qk_tap_dance_state_t *state, void *user_data) {
+ tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
+
+ if (tap_hold->held) {
+ unregister_code16(tap_hold->held);
+ tap_hold->held = 0;
+ }
+}
+
+#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \
+ { .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), }
+
+
+// Example 4
+
+typedef enum {
+ TD_NONE,
+ TD_UNKNOWN,
+ TD_SINGLE_TAP,
+ TD_SINGLE_HOLD,
+ TD_DOUBLE_TAP,
+ TD_DOUBLE_HOLD,
+ TD_DOUBLE_SINGLE_TAP,
+ TD_TRIPLE_TAP,
+ TD_TRIPLE_HOLD
+} td_state_t;
+
+typedef struct {
+ bool is_press_action;
+ td_state_t state;
+} td_tap_t;
+
+td_state_t cur_dance(qk_tap_dance_state_t *state) {
+ if (state->count == 1) {
+ if (state->interrupted || !state->pressed) return TD_SINGLE_TAP;
+ else return TD_SINGLE_HOLD;
+ } else if (state->count == 2) {
+ if (state->interrupted) return TD_DOUBLE_SINGLE_TAP;
+ else if (state->pressed) return TD_DOUBLE_HOLD;
+ else return TD_DOUBLE_TAP;
+ }
+
+ if (state->count == 3) {
+ if (state->interrupted || !state->pressed) return TD_TRIPLE_TAP;
+ else return TD_TRIPLE_HOLD;
+ } else return TD_UNKNOWN;
+}
+
+static td_tap_t xtap_state = {
+ .is_press_action = true,
+ .state = TD_NONE
+};
+
+void x_finished(qk_tap_dance_state_t *state, void *user_data) {
+ xtap_state.state = cur_dance(state);
+ switch (xtap_state.state) {
+ case TD_SINGLE_TAP: register_code(KC_X); break;
+ case TD_SINGLE_HOLD: register_code(KC_LCTL); break;
+ case TD_DOUBLE_TAP: register_code(KC_ESC); break;
+ case TD_DOUBLE_HOLD: register_code(KC_LALT); break;
+ case TD_DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X);
+ default: break; // Not present in documentation
+ }
+}
+
+void x_reset(qk_tap_dance_state_t *state, void *user_data) {
+ switch (xtap_state.state) {
+ case TD_SINGLE_TAP: unregister_code(KC_X); break;
+ case TD_SINGLE_HOLD: unregister_code(KC_LCTL); break;
+ case TD_DOUBLE_TAP: unregister_code(KC_ESC); break;
+ case TD_DOUBLE_HOLD: unregister_code(KC_LALT);
+ case TD_DOUBLE_SINGLE_TAP: unregister_code(KC_X);
+ default: break; // Not present in documentation
+ }
+ xtap_state.state = TD_NONE;
+}
+
+
+qk_tap_dance_action_t tap_dance_actions[] = {
+ [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
+ [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
+ [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset),
+ [CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN),
+ [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)
+};
+
+// clang-format on
diff --git a/tests/tap_dance/examples.h b/tests/tap_dance/examples.h
new file mode 100644
index 0000000000..2622af6b2f
--- /dev/null
+++ b/tests/tap_dance/examples.h
@@ -0,0 +1,33 @@
+/* Copyright 2022 Jouke Witteveen
+ *
+ * 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 __cplusplus
+extern "C" {
+#endif
+
+enum {
+ TD_ESC_CAPS,
+ CT_EGG,
+ CT_FLSH,
+ CT_CLN,
+ X_CTL,
+};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/tap_dance/test.mk b/tests/tap_dance/test.mk
new file mode 100644
index 0000000000..041d9b4dc9
--- /dev/null
+++ b/tests/tap_dance/test.mk
@@ -0,0 +1,22 @@
+# Copyright 2022 Jouke Witteveen
+#
+# 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/>.
+
+# --------------------------------------------------------------------------------
+# Keep this file, even if it is empty, as a marker that this folder contains tests
+# --------------------------------------------------------------------------------
+
+TAP_DANCE_ENABLE = yes
+
+SRC += examples.c
diff --git a/tests/tap_dance/test_examples.cpp b/tests/tap_dance/test_examples.cpp
new file mode 100644
index 0000000000..e67e6cb907
--- /dev/null
+++ b/tests/tap_dance/test_examples.cpp
@@ -0,0 +1,319 @@
+/* Copyright 2022 Jouke Witteveen
+ *
+ * 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 "keyboard_report_util.hpp"
+#include "keycode.h"
+#include "test_common.hpp"
+#include "action_tapping.h"
+#include "test_keymap_key.hpp"
+#include "examples.h"
+
+using testing::_;
+using testing::InSequence;
+
+class TapDance : public TestFixture {};
+
+TEST_F(TapDance, DoubleTap) {
+ TestDriver driver;
+ InSequence s;
+ auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)};
+
+ set_keymap({key_esc_caps});
+
+ /* The tap dance key does nothing on the first press */
+ key_esc_caps.press();
+ run_one_scan_loop();
+ key_esc_caps.release();
+ EXPECT_NO_REPORT(driver);
+
+ /* We get the key press and the release on timeout */
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_ESC));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Double tap gets us the second key */
+ tap_key(key_esc_caps);
+ EXPECT_NO_REPORT(driver);
+ key_esc_caps.press();
+ EXPECT_REPORT(driver, (KC_CAPS));
+ run_one_scan_loop();
+ key_esc_caps.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, DoubleTapWithMod) {
+ TestDriver driver;
+ InSequence s;
+ auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)};
+ auto key_shift = KeymapKey{0, 2, 0, KC_LSFT};
+
+ set_keymap({key_esc_caps, key_shift});
+
+ /* The tap dance key does nothing on the first press */
+ key_shift.press();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ run_one_scan_loop();
+ key_esc_caps.press();
+ run_one_scan_loop();
+
+ key_esc_caps.release();
+ key_shift.release();
+ EXPECT_EMPTY_REPORT(driver);
+
+ /* We get the key press and the release */
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_REPORT(driver, (KC_LSFT, KC_ESC));
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Double tap gets us the second key */
+ key_shift.press();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ run_one_scan_loop();
+ tap_key(key_esc_caps);
+ EXPECT_NO_REPORT(driver);
+ key_shift.release();
+ key_esc_caps.press();
+ EXPECT_REPORT(driver, (KC_LSFT, KC_CAPS));
+ run_one_scan_loop();
+ key_esc_caps.release();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ run_one_scan_loop();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, DoubleTapInterrupted) {
+ TestDriver driver;
+ InSequence s;
+ auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)};
+ auto regular_key = KeymapKey(0, 2, 0, KC_A);
+
+ set_keymap({key_esc_caps, regular_key});
+
+ /* Interrupted double tap */
+ tap_key(key_esc_caps);
+ regular_key.press();
+ /* Immediate tap of the first key */
+ EXPECT_REPORT(driver, (KC_ESC));
+ EXPECT_EMPTY_REPORT(driver);
+ /* Followed by the interrupting key */
+ EXPECT_REPORT(driver, (KC_A));
+ run_one_scan_loop();
+ regular_key.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Second tap after being interrupted acts as a single tap */
+ key_esc_caps.press();
+ run_one_scan_loop();
+ key_esc_caps.release();
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_ESC));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, DanceFn) {
+ TestDriver driver;
+ InSequence s;
+ auto key_egg = KeymapKey(0, 1, 0, TD(CT_EGG));
+
+ set_keymap({key_egg});
+
+ /* 99 taps do nothing */
+ for (int i = 0; i < 99; i++) {
+ run_one_scan_loop();
+ key_egg.press();
+ run_one_scan_loop();
+ key_egg.release();
+ }
+ idle_for(TAPPING_TERM);
+ EXPECT_NO_REPORT(driver);
+ run_one_scan_loop();
+
+ /* 100 taps trigger the action */
+ for (int i = 0; i < 100; i++) {
+ run_one_scan_loop();
+ key_egg.press();
+ run_one_scan_loop();
+ key_egg.release();
+ }
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_C));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* 250 taps act the same as 100 taps */
+ /* Taps are counted in an uint8_t, so the count overflows after 255 taps */
+ for (int i = 0; i < 250; i++) {
+ run_one_scan_loop();
+ key_egg.press();
+ run_one_scan_loop();
+ key_egg.release();
+ }
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_C));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, DanceFnAdvanced) {
+ TestDriver driver;
+ InSequence s;
+ auto key_flsh = KeymapKey(0, 1, 0, TD(CT_FLSH));
+
+ set_keymap({key_flsh});
+
+ /* Three taps don't trigger a reset */
+ EXPECT_REPORT(driver, (KC_3));
+ EXPECT_REPORT(driver, (KC_3, KC_2));
+ EXPECT_REPORT(driver, (KC_3, KC_2, KC_1));
+ for (int i = 0; i < 3; i++) {
+ run_one_scan_loop();
+ key_flsh.press();
+ run_one_scan_loop();
+ key_flsh.release();
+ }
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_3, KC_2));
+ EXPECT_REPORT(driver, (KC_3));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Four taps trigger a reset */
+ EXPECT_REPORT(driver, (KC_3));
+ EXPECT_REPORT(driver, (KC_3, KC_2));
+ EXPECT_REPORT(driver, (KC_3, KC_2, KC_1));
+ EXPECT_REPORT(driver, (KC_2, KC_1));
+ EXPECT_REPORT(driver, (KC_1));
+ EXPECT_EMPTY_REPORT(driver);
+ for (int i = 0; i < 4; i++) {
+ run_one_scan_loop();
+ key_flsh.press();
+ run_one_scan_loop();
+ key_flsh.release();
+ }
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_R));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, TapHold) {
+ TestDriver driver;
+ InSequence s;
+ auto key_cln = KeymapKey{0, 1, 0, TD(CT_CLN)};
+
+ set_keymap({key_cln});
+
+ /* Short taps fire on release */
+ key_cln.press();
+ run_one_scan_loop();
+ key_cln.release();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_REPORT(driver, (KC_LSFT, KC_SCLN));
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Holds immediate following a tap apply to the tap key */
+ key_cln.press();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_REPORT(driver, (KC_LSFT, KC_SCLN));
+ idle_for(TAPPING_TERM * 2);
+ key_cln.release();
+ EXPECT_REPORT(driver, (KC_LSFT));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Holds trigger the hold key */
+ key_cln.press();
+ idle_for(TAPPING_TERM);
+ run_one_scan_loop();
+ EXPECT_REPORT(driver, (KC_SCLN));
+ run_one_scan_loop();
+ key_cln.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
+
+TEST_F(TapDance, QuadFunction) {
+ TestDriver driver;
+ InSequence s;
+ auto key_quad = KeymapKey{0, 1, 0, TD(X_CTL)};
+ auto regular_key = KeymapKey(0, 2, 0, KC_A);
+
+ set_keymap({key_quad, regular_key});
+
+ /* Single tap */
+ key_quad.press();
+ run_one_scan_loop();
+ key_quad.release();
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_X));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Single hold */
+ key_quad.press();
+ run_one_scan_loop();
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_LCTL));
+ run_one_scan_loop();
+ key_quad.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Double tap */
+ tap_key(key_quad);
+ key_quad.press();
+ run_one_scan_loop();
+ key_quad.release();
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_ESC));
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Double tap and hold */
+ tap_key(key_quad);
+ key_quad.press();
+ run_one_scan_loop();
+ idle_for(TAPPING_TERM);
+ EXPECT_REPORT(driver, (KC_LALT));
+ run_one_scan_loop();
+ key_quad.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+
+ /* Double single tap */
+ tap_key(key_quad);
+ tap_key(key_quad);
+ regular_key.press();
+ EXPECT_REPORT(driver, (KC_X));
+ EXPECT_EMPTY_REPORT(driver);
+ EXPECT_REPORT(driver, (KC_X));
+ EXPECT_EMPTY_REPORT(driver);
+ EXPECT_REPORT(driver, (KC_A));
+ run_one_scan_loop();
+ regular_key.release();
+ EXPECT_EMPTY_REPORT(driver);
+ run_one_scan_loop();
+}
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
index 3ed83a44a6..52fe86d297 100644
--- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
+++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
@@ -450,7 +450,7 @@ static void md_rgb_matrix_config_override(int i) {
float bo = 0;
float po;
- uint8_t highest_active_layer = biton32(layer_state);
+ uint8_t highest_active_layer = get_highest_layer(layer_state);
if (led_animation_circular) {
// TODO: should use min/max values from LED configuration instead of
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 19e2e858fc..4bb6949b4f 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -32,6 +32,7 @@
#include "usb_main.h"
#include "host.h"
+#include "chibios_config.h"
#include "debug.h"
#include "suspend.h"
#ifdef SLEEP_LED_ENABLE
@@ -91,6 +92,13 @@ uint8_t extra_report_blank[3] = {0};
* ---------------------------------------------------------
*/
+/* USB Low Level driver specific endpoint fields */
+#if !defined(usb_lld_endpoint_fields)
+# define usb_lld_endpoint_fields \
+ 2, /* IN multiplier */ \
+ NULL, /* SETUP buffer (not a SETUP endpoint) */
+#endif
+
/* HID specific constants */
#define HID_GET_REPORT 0x01
#define HID_GET_IDLE 0x02
@@ -121,16 +129,15 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype
static USBInEndpointState kbd_ep_state;
/* keyboard endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
static const USBEndpointConfig kbd_ep_config = {
- USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
- NULL, /* SETUP packet notification callback */
- kbd_in_cb, /* IN notification callback */
- NULL, /* OUT notification callback */
- KEYBOARD_EPSIZE, /* IN maximum packet size */
- 0, /* OUT maximum packet size */
- &kbd_ep_state, /* IN Endpoint state */
- NULL, /* OUT endpoint state */
- 2, /* IN multiplier */
- NULL /* SETUP buffer (not a SETUP endpoint) */
+ USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
+ NULL, /* SETUP packet notification callback */
+ kbd_in_cb, /* IN notification callback */
+ NULL, /* OUT notification callback */
+ KEYBOARD_EPSIZE, /* IN maximum packet size */
+ 0, /* OUT maximum packet size */
+ &kbd_ep_state, /* IN Endpoint state */
+ NULL, /* OUT endpoint state */
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */
};
#endif
@@ -140,16 +147,15 @@ static USBInEndpointState mouse_ep_state;
/* mouse endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
static const USBEndpointConfig mouse_ep_config = {
- USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
- NULL, /* SETUP packet notification callback */
- mouse_in_cb, /* IN notification callback */
- NULL, /* OUT notification callback */
- MOUSE_EPSIZE, /* IN maximum packet size */
- 0, /* OUT maximum packet size */
- &mouse_ep_state, /* IN Endpoint state */
- NULL, /* OUT endpoint state */
- 2, /* IN multiplier */
- NULL /* SETUP buffer (not a SETUP endpoint) */
+ USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
+ NULL, /* SETUP packet notification callback */
+ mouse_in_cb, /* IN notification callback */
+ NULL, /* OUT notification callback */
+ MOUSE_EPSIZE, /* IN maximum packet size */
+ 0, /* OUT maximum packet size */
+ &mouse_ep_state, /* IN Endpoint state */
+ NULL, /* OUT endpoint state */
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */
};
#endif
@@ -159,16 +165,15 @@ static USBInEndpointState shared_ep_state;
/* shared endpoint initialization structure (IN) - see USBEndpointConfig comment at top of file */
static const USBEndpointConfig shared_ep_config = {
- USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
- NULL, /* SETUP packet notification callback */
- shared_in_cb, /* IN notification callback */
- NULL, /* OUT notification callback */
- SHARED_EPSIZE, /* IN maximum packet size */
- 0, /* OUT maximum packet size */
- &shared_ep_state, /* IN Endpoint state */
- NULL, /* OUT endpoint state */
- 2, /* IN multiplier */
- NULL /* SETUP buffer (not a SETUP endpoint) */
+ USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
+ NULL, /* SETUP packet notification callback */
+ shared_in_cb, /* IN notification callback */
+ NULL, /* OUT notification callback */
+ SHARED_EPSIZE, /* IN maximum packet size */
+ 0, /* OUT maximum packet size */
+ &shared_ep_state, /* IN Endpoint state */
+ NULL, /* OUT endpoint state */
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */
};
#endif
@@ -251,29 +256,27 @@ typedef struct {
.queue_capacity_in = stream##_IN_CAPACITY, .queue_capacity_out = stream##_OUT_CAPACITY, \
.in_ep_config = \
{ \
- stream##_IN_MODE, /* Interrupt EP */ \
- NULL, /* SETUP packet notification callback */ \
- qmkusbDataTransmitted, /* IN notification callback */ \
- NULL, /* OUT notification callback */ \
- stream##_EPSIZE, /* IN maximum packet size */ \
- 0, /* OUT maximum packet size */ \
- NULL, /* IN Endpoint state */ \
- NULL, /* OUT endpoint state */ \
- 2, /* IN multiplier */ \
- NULL /* SETUP buffer (not a SETUP endpoint) */ \
+ stream##_IN_MODE, /* Interrupt EP */ \
+ NULL, /* SETUP packet notification callback */ \
+ qmkusbDataTransmitted, /* IN notification callback */ \
+ NULL, /* OUT notification callback */ \
+ stream##_EPSIZE, /* IN maximum packet size */ \
+ 0, /* OUT maximum packet size */ \
+ NULL, /* IN Endpoint state */ \
+ NULL, /* OUT endpoint state */ \
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
}, \
.out_ep_config = \
{ \
- stream##_OUT_MODE, /* Interrupt EP */ \
- NULL, /* SETUP packet notification callback */ \
- NULL, /* IN notification callback */ \
- qmkusbDataReceived, /* OUT notification callback */ \
- 0, /* IN maximum packet size */ \
- stream##_EPSIZE, /* OUT maximum packet size */ \
- NULL, /* IN Endpoint state */ \
- NULL, /* OUT endpoint state */ \
- 2, /* IN multiplier */ \
- NULL, /* SETUP buffer (not a SETUP endpoint) */ \
+ stream##_OUT_MODE, /* Interrupt EP */ \
+ NULL, /* SETUP packet notification callback */ \
+ NULL, /* IN notification callback */ \
+ qmkusbDataReceived, /* OUT notification callback */ \
+ 0, /* IN maximum packet size */ \
+ stream##_EPSIZE, /* OUT maximum packet size */ \
+ NULL, /* IN Endpoint state */ \
+ NULL, /* OUT endpoint state */ \
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
}, \
.int_ep_config = \
{ \
@@ -285,8 +288,7 @@ typedef struct {
0, /* OUT maximum packet size */ \
NULL, /* IN Endpoint state */ \
NULL, /* OUT endpoint state */ \
- 2, /* IN multiplier */ \
- NULL, /* SETUP buffer (not a SETUP endpoint) */ \
+ usb_lld_endpoint_fields /* USB driver specific endpoint fields */ \
}, \
.config = { \
.usbp = &USB_DRIVER, \
diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
index 053d2b79e3..3d8604d541 100644
--- a/tmk_core/protocol/host.c
+++ b/tmk_core/protocol/host.c
@@ -94,6 +94,11 @@ void host_mouse_send(report_mouse_t *report) {
#ifdef MOUSE_SHARED_EP
report->report_id = REPORT_ID_MOUSE;
#endif
+#ifdef MOUSE_EXTENDED_REPORT
+ // clip and copy to Boot protocol XY
+ report->boot_x = (report->x > 127) ? 127 : ((report->x < -127) ? -127 : report->x);
+ report->boot_y = (report->y > 127) ? 127 : ((report->y < -127) ? -127 : report->y);
+#endif
(*driver->send_mouse)(report);
}
diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h
index 7bbeb78af7..735ccdb4a1 100644
--- a/tmk_core/protocol/report.h
+++ b/tmk_core/protocol/report.h
@@ -201,15 +201,25 @@ typedef struct {
uint32_t usage;
} __attribute__((packed)) report_programmable_button_t;
+#ifdef MOUSE_EXTENDED_REPORT
+typedef int16_t mouse_xy_report_t;
+#else
+typedef int8_t mouse_xy_report_t;
+#endif
+
typedef struct {
#ifdef MOUSE_SHARED_EP
uint8_t report_id;
#endif
uint8_t buttons;
- int8_t x;
- int8_t y;
- int8_t v;
- int8_t h;
+#ifdef MOUSE_EXTENDED_REPORT
+ int8_t boot_x;
+ int8_t boot_y;
+#endif
+ mouse_xy_report_t x;
+ mouse_xy_report_t y;
+ int8_t v;
+ int8_t h;
} __attribute__((packed)) report_mouse_t;
typedef struct {
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 063bd2c3f1..52e3276d35 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -126,14 +126,27 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
- // X/Y position (2 bytes)
+# ifdef MOUSE_EXTENDED_REPORT
+ // Boot protocol XY ignored in Report protocol
+ HID_RI_REPORT_COUNT(8, 0x02),
+ HID_RI_REPORT_SIZE(8, 0x08),
+ HID_RI_INPUT(8, HID_IOF_CONSTANT),
+# endif
+ // X/Y position (2 or 4 bytes)
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
HID_RI_USAGE(8, 0x30), // X
HID_RI_USAGE(8, 0x31), // Y
+# ifndef MOUSE_EXTENDED_REPORT
HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08),
+# else
+ HID_RI_LOGICAL_MINIMUM(16, -32767),
+ HID_RI_LOGICAL_MAXIMUM(16, 32767),
+ HID_RI_REPORT_COUNT(8, 0x02),
+ HID_RI_REPORT_SIZE(8, 0x10),
+# endif
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
// Vertical wheel (1 byte)
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index ebde955d3b..d07cc0d27e 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -482,14 +482,28 @@ const PROGMEM uchar shared_hid_report[] = {
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
- // X/Y position (2 bytes)
+# ifdef MOUSE_EXTENDED_REPORT
+ // Boot protocol XY ignored in Report protocol
+ 0x95, 0x02, // Report Count (2)
+ 0x75, 0x08, // Report Size (8)
+ 0x81, 0x03, // Input (Constant)
+# endif
+
+ // X/Y position (2 or 4 bytes)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
+# ifndef MOUSE_EXTENDED_REPORT
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x95, 0x02, // Report Count (2)
0x75, 0x08, // Report Size (8)
+# else
+ 0x16, 0x01, 0x80, // Logical Minimum (-32767)
+ 0x26, 0xFF, 0x7F, // Logical Maximum (32767)
+ 0x95, 0x02, // Report Count (2)
+ 0x75, 0x10, // Report Size (16)
+# endif
0x81, 0x06, // Input (Data, Variable, Relative)
// Vertical wheel (1 byte)
diff --git a/users/333fred/333fred.c b/users/333fred/333fred.c
index 99f4e01685..ea7b904403 100644
--- a/users/333fred/333fred.c
+++ b/users/333fred/333fred.c
@@ -115,7 +115,7 @@ void tap_dance_process_keycode(uint16_t keycode) {
}
__attribute__ ((weak))
-void layer_state_set_rgb(uint32_t state) {}
+void layer_state_set_rgb(layer_state_t state) {}
layer_state_t layer_state_set_user(layer_state_t state) {
layer_state_set_rgb(state);
diff --git a/users/333fred/rgb.c b/users/333fred/rgb.c
index d287143302..ae21702030 100644
--- a/users/333fred/rgb.c
+++ b/users/333fred/rgb.c
@@ -23,8 +23,8 @@
#include "quantum.h"
#include "333fred.h"
-void layer_state_set_rgb(uint32_t state) {
- switch (biton32(state)) {
+void layer_state_set_rgb(layer_state_t state) {
+ switch (get_highest_layer(state)) {
case BASE:
// purple
rgblight_sethsv_noeeprom(210, 255, 20);
diff --git a/users/bbaserdem/bbaserdem.c b/users/bbaserdem/bbaserdem.c
index 08346c3d64..e0e204c302 100644
--- a/users/bbaserdem/bbaserdem.c
+++ b/users/bbaserdem/bbaserdem.c
@@ -146,7 +146,7 @@ __attribute__ ((weak)) void keyboard_post_init_user(void) {
transaction_register_rpc( RPC_ID_CONFIG_SYNC, userspace_config_sync );
transaction_register_rpc(RPC_ID_RUNTIME_SYNC, userspace_runtime_sync);
// Load default config values
- if (is_keyboard_master()) {
+ if (is_keyboard_master()) {
// If we are main; load from eeconfig
userspace_config.raw = eeconfig_read_user();
// And update the transport variable
@@ -321,7 +321,7 @@ void led_set_user(uint8_t usb_led) {
/*-----------------*\
|*-----SUSPEND-----*|
\*-----------------*/
-/* Suspend stuff here, mostly for the rgb lighting.
+/* Suspend stuff here, mostly for the rgb lighting.
*/
__attribute__ ((weak)) void suspend_power_down_keymap (void) { }
void suspend_power_down_user(void) {
@@ -340,6 +340,21 @@ void suspend_wakeup_init_user(void) {
# endif // RGB_MATRIX_ENABLE
}
+<<<<<<< HEAD
+ state = layer_state_set_keymap (state);
+#ifdef RGBLIGHT_ENABLE
+ // Change RGB lighting depending on the last layer activated
+ rgblight_change( get_highest_layer(state) );
+#endif
+ return state;
+||||||| f439fe6055
+ state = layer_state_set_keymap (state);
+#ifdef RGBLIGHT_ENABLE
+ // Change RGB lighting depending on the last layer activated
+ rgblight_change( biton32(state) );
+#endif
+ return state;
+=======
/*------------------*\
|*-----SHUTDOWN-----*|
\*------------------*/
@@ -357,4 +372,5 @@ void shutdown_user(void) {
# endif // RGB_MATRIX_ENABLE
// Keymap hooks
shutdown_keymap();
+>>>>>>> upstream/master
}
diff --git a/users/bcat/rules.mk b/users/bcat/rules.mk
index 1ad2ee0aa8..090f7474eb 100644
--- a/users/bcat/rules.mk
+++ b/users/bcat/rules.mk
@@ -47,7 +47,6 @@ endif
COMMAND_ENABLE = no
CONSOLE_ENABLE = no
MOUSEKEY_ENABLE = no
-TERMINAL_ENABLE = no
# Disable unwanted hardware options on all keyboards. (Some keyboards turn
# these features on by default even though they aren't actually required.)
diff --git a/users/billypython/billypython.c b/users/billypython/billypython.c
index 180b478d7a..f165d2e260 100644
--- a/users/billypython/billypython.c
+++ b/users/billypython/billypython.c
@@ -23,7 +23,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
__attribute__((weak))
-uint32_t layer_state_set_keymap(uint32_t state) {
+layer_state_t layer_state_set_keymap(layer_state_t state) {
return state;
}
diff --git a/users/billypython/billypython.h b/users/billypython/billypython.h
index 4a444e9787..cdf5121f2f 100644
--- a/users/billypython/billypython.h
+++ b/users/billypython/billypython.h
@@ -31,4 +31,4 @@ enum layers_user {
};
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
-uint32_t layer_state_set_keymap(uint32_t state);
+layer_state_t layer_state_set_keymap(layer_state_t state);
diff --git a/users/dhertz/dhertz.c b/users/dhertz/dhertz.c
index 163b1cb644..1a2b6e38f1 100644
--- a/users/dhertz/dhertz.c
+++ b/users/dhertz/dhertz.c
@@ -18,7 +18,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
__attribute__ ((weak))
@@ -107,4 +107,3 @@ layer_state_t layer_state_set_user (layer_state_t state) {
void led_set_user(uint8_t usb_led) {
led_set_keymap(usb_led);
}
-
diff --git a/users/doogle999/doogle999.c b/users/doogle999/doogle999.c
index 320de7cff8..c9ee125741 100644
--- a/users/doogle999/doogle999.c
+++ b/users/doogle999/doogle999.c
@@ -382,7 +382,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t* record)
static char text[CALC_BUFFER_SIZE + 1]; // Used to store input and then output when ready to print
static char backspaceText[CALC_BUFFER_SIZE + 1]; // Pretty dumb waste of memory because only backspace characters, used with send_string to backspace and remove input
- if((biton32(layer_state) == CALC_LAYER && CALC_FORCE_NUM_LOCK_INSIDE_CALC) || (biton32(layer_state) != CALC_LAYER && CALC_FORCE_NUM_LOCK_OUTSIDE_CALC))
+ if((get_highest_layer(layer_state) == CALC_LAYER && CALC_FORCE_NUM_LOCK_INSIDE_CALC) || (get_highest_layer(layer_state) != CALC_LAYER && CALC_FORCE_NUM_LOCK_OUTSIDE_CALC))
{
bool numpadKeyPressed = record->event.pressed &&
!(get_mods() & MODS_SHIFT_MASK) &&
@@ -397,7 +397,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t* record)
}
}
- if(biton32(layer_state) != CALC_LAYER) { return true; }
+ if(get_highest_layer(layer_state) != CALC_LAYER) { return true; }
int action = process_input(keycode, get_mods(), record->event);
switch(action)
@@ -457,4 +457,4 @@ bool process_record_user(uint16_t keycode, keyrecord_t* record)
send_string(characterToSend);
}
return false;
-} \ No newline at end of file
+}
diff --git a/users/edvorakjp/edvorakjp.c b/users/edvorakjp/edvorakjp.c
index c44d8bb440..c95b03d981 100644
--- a/users/edvorakjp/edvorakjp.c
+++ b/users/edvorakjp/edvorakjp.c
@@ -12,7 +12,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
return layer_state_set_keymap(state);
}
-__attribute__((weak)) uint32_t layer_state_set_keymap(uint32_t state) { return state; }
+__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) { return state; }
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
bool process_record_user_result = process_record_keymap(keycode, record) && process_record_edvorakjp_swap_scln(keycode, record) && process_record_edvorakjp_config(keycode, record) && process_record_layer(keycode, record) && process_record_ime(keycode, record);
diff --git a/users/edvorakjp/edvorakjp.h b/users/edvorakjp/edvorakjp.h
index 93cd9851b7..a878f71ca8 100644
--- a/users/edvorakjp/edvorakjp.h
+++ b/users/edvorakjp/edvorakjp.h
@@ -68,7 +68,7 @@ enum tap_dance_code {
void matrix_init_user(void);
void matrix_init_keymap(void);
layer_state_t layer_state_set_user(layer_state_t state);
-uint32_t layer_state_set_keymap(uint32_t state);
+layer_state_t layer_state_set_keymap(layer_state_t state);
bool process_record_user(uint16_t keycode, keyrecord_t *record);
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
diff --git a/users/edvorakjp/edvorakjp_tap_dance.c b/users/edvorakjp/edvorakjp_tap_dance.c
index cee10de693..69fcbac1ca 100644
--- a/users/edvorakjp/edvorakjp_tap_dance.c
+++ b/users/edvorakjp/edvorakjp_tap_dance.c
@@ -64,6 +64,15 @@ void td_raise_reset(qk_tap_dance_state_t *state, void *user_data) {
}
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_EDVORAKJP_LOWER] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, td_lower_finished, td_lower_reset, 150),
- [TD_EDVORAKJP_RAISE] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, td_raise_finished, td_raise_reset, 150),
+ [TD_EDVORAKJP_LOWER] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_lower_finished, td_lower_reset),
+ [TD_EDVORAKJP_RAISE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_raise_finished, td_raise_reset),
};
+
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
+ return 150;
+ default:
+ return TAPPING_TERM;
+ }
+}
diff --git a/users/ericgebhart/ericgebhart.c b/users/ericgebhart/ericgebhart.c
index 2a34110ae2..a071fb8c2e 100755
--- a/users/ericgebhart/ericgebhart.c
+++ b/users/ericgebhart/ericgebhart.c
@@ -40,7 +40,7 @@ __attribute__ ((weak))
void matrix_scan_keymap(void) {}
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
diff --git a/users/ericgebhart/tap_dances.c b/users/ericgebhart/tap_dances.c
index 9f344986aa..8f9503a261 100755
--- a/users/ericgebhart/tap_dances.c
+++ b/users/ericgebhart/tap_dances.c
@@ -47,7 +47,7 @@ void tap_dance_mouse_btns (qk_tap_dance_state_t *state, void *user_data) {
// counting on all the qwerty layers to be less than dvorak_on_bepo
int on_qwerty(){
- uint8_t deflayer = (biton32(default_layer_state));
+ uint8_t deflayer = (get_highest_layer(default_layer_state));
return (deflayer < _DVORAK_BP);
}
@@ -58,7 +58,7 @@ static void switch_default_layer(uint8_t layer) {
// so the keyboard remembers which layer it's in after power disconnect.
/*
- uint32_t default_layer_state_set_kb(uint32_t state) {
+ layer_state_t default_layer_state_set_kb(layer_state_t state) {
eeconfig_update_default_layer(state);
return state;
}
diff --git a/users/gourdo1/gourdo1.c b/users/gourdo1/gourdo1.c
index 9062a452ff..51f774061e 100644
--- a/users/gourdo1/gourdo1.c
+++ b/users/gourdo1/gourdo1.c
@@ -413,7 +413,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t * record) {
} else unregister_code16(keycode);
break;
- // Double Zero
+ // Double Zero
case KC_00:
if (record -> event.pressed) {
// when keycode KC_00 is pressed
diff --git a/users/hvp/config.h b/users/hvp/config.h
index 68dd8b4828..b7d0443bbc 100644
--- a/users/hvp/config.h
+++ b/users/hvp/config.h
@@ -15,4 +15,5 @@
*/
#pragma once
-#define LONG_TAPPING_TERM 1000 \ No newline at end of file
+#define LONG_TAPPING_TERM 1000
+#define PERMISSIVE_HOLD
diff --git a/users/kuchosauronad0/kuchosauronad0.c b/users/kuchosauronad0/kuchosauronad0.c
index a8f17b08ee..820d84daad 100644
--- a/users/kuchosauronad0/kuchosauronad0.c
+++ b/users/kuchosauronad0/kuchosauronad0.c
@@ -117,7 +117,7 @@ void matrix_scan_user(void){
}
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
@@ -133,12 +133,12 @@ layer_state_t layer_state_set_user(layer_state_t state) {
__attribute__ ((weak))
-uint32_t default_layer_state_set_keymap (uint32_t state) {
+layer_state_t default_layer_state_set_keymap (layer_state_t state) {
return state;
}
// Runs state check and changes underglow color and animation
-uint32_t default_layer_state_set_user(uint32_t state) {
+layer_state_t default_layer_state_set_user(layer_state_t state) {
state = default_layer_state_set_keymap(state);
#if 0
#ifdef RGBLIGHT_ENABLE
diff --git a/users/kuchosauronad0/kuchosauronad0.h b/users/kuchosauronad0/kuchosauronad0.h
index da996457c6..5cbd517d67 100644
--- a/users/kuchosauronad0/kuchosauronad0.h
+++ b/users/kuchosauronad0/kuchosauronad0.h
@@ -65,8 +65,8 @@ void shutdown_keymap(void);
void suspend_power_down_keymap(void);
void suspend_wakeup_init_keymap(void);
void matrix_scan_keymap(void);
-uint32_t layer_state_set_keymap (uint32_t state);
-uint32_t default_layer_state_set_keymap (uint32_t state);
+layer_state_t layer_state_set_keymap (layer_state_t state);
+layer_state_t default_layer_state_set_keymap (layer_state_t state);
void led_set_keymap(uint8_t usb_led);
void eeconfig_init_keymap(void);
diff --git a/users/kuchosauronad0/rgblight_user.c b/users/kuchosauronad0/rgblight_user.c
index 63e412c557..feea0c412f 100644
--- a/users/kuchosauronad0/rgblight_user.c
+++ b/users/kuchosauronad0/rgblight_user.c
@@ -84,7 +84,7 @@ void matrix_scan_rgb(void) {
layer_state_t layer_state_set_rgb(layer_state_t state) {
# ifdef RGBLIGHT_ENABLE
if (userspace_config.rgb_layer_change) {
- switch (biton32(state)) { // _RAISE, _LOWER and _ADJUST use a custom color and the breathing effect
+ switch (get_highest_layer(state)) { // _RAISE, _LOWER and _ADJUST use a custom color and the breathing effect
case _RAISE:
rgblight_sethsv_noeeprom_green();
rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3);
@@ -98,7 +98,7 @@ layer_state_t layer_state_set_rgb(layer_state_t state) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 2);
break;
default: // Use a solid color for normal layers
- switch (biton32(default_layer_state)) {
+ switch (get_highest_layer(default_layer_state)) {
case _QWERTY:
rgblight_sethsv_noeeprom_magenta();
break;
@@ -118,7 +118,7 @@ layer_state_t layer_state_set_rgb(layer_state_t state) {
rgblight_sethsv_noeeprom_white();
break;
}
- biton32(state) == _MODS ? rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING) : rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); // if _MODS layer is on, then breath to denote it
+ get_highest_layer(state) == _MODS ? rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING) : rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); // if _MODS layer is on, then breath to denote it
break;
}
}
@@ -135,7 +135,7 @@ void matrix_scan_indicator(void) {
#endif // !INDICATOR_LIGHTS
void rgblight_fade_helper(bool direction){
- // true: increase val = fade in
+ // true: increase val = fade in
// false: decrease val = fade out
for (uint8_t index = 0; index < RGBLIGHT_VAL_STEP ; index++) {
direction ? rgblight_increase_val() : rgblight_decrease_val();
@@ -147,10 +147,10 @@ void fadeflash_leds(uint8_t hue, uint8_t sat, uint8_t val){
// fade out, set new hue and saturation, fade in, fade out, set old color, fade in
// this is used in leader.c
// TODO: come up with a better name maybe
- rgblight_fade_helper(false);
- rgblight_sethsv_noeeprom(hue, sat, 0);
- rgblight_fade_helper(true);
- rgblight_fade_helper(false);
- rgblight_sethsv_noeeprom(base_hue, base_sat, 0);
- rgblight_fade_helper(true);
+ rgblight_fade_helper(false);
+ rgblight_sethsv_noeeprom(hue, sat, 0);
+ rgblight_fade_helper(true);
+ rgblight_fade_helper(false);
+ rgblight_sethsv_noeeprom(base_hue, base_sat, 0);
+ rgblight_fade_helper(true);
}
diff --git a/users/kuchosauronad0/template.c b/users/kuchosauronad0/template.c
index 475e45d391..76cc572be3 100644
--- a/users/kuchosauronad0/template.c
+++ b/users/kuchosauronad0/template.c
@@ -63,11 +63,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
-uint32_t layer_state_set_user (uint32_t state) {
+layer_state_t layer_state_set_user (layer_state_t state) {
return layer_state_set_keymap (state);
}
diff --git a/users/manna-harbour_miryoku/post_rules.mk b/users/manna-harbour_miryoku/post_rules.mk
index c5b4b7d28e..8fece85e66 100644
--- a/users/manna-harbour_miryoku/post_rules.mk
+++ b/users/manna-harbour_miryoku/post_rules.mk
@@ -1,8 +1,6 @@
# Copyright 2019 Manna Harbour
# https://github.com/manna-harbour/miryoku
-SRC += manna-harbour_miryoku.c # keymaps
-
# alternative layouts:
# alphas
diff --git a/users/manna-harbour_miryoku/rules.mk b/users/manna-harbour_miryoku/rules.mk
index 879c7fc43e..ea226c4a3d 100644
--- a/users/manna-harbour_miryoku/rules.mk
+++ b/users/manna-harbour_miryoku/rules.mk
@@ -5,7 +5,7 @@ MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
AUTO_SHIFT_ENABLE = yes # Auto Shift
-SRC += manna-harbour_miryoku.c # keymaps
+INTROSPECTION_KEYMAP_C = manna-harbour_miryoku.c # keymaps
include users/manna-harbour_miryoku/custom_rules.mk
diff --git a/users/mnil/config.h b/users/mnil/config.h
index 3547785ff7..b471b9a818 100644
--- a/users/mnil/config.h
+++ b/users/mnil/config.h
@@ -19,3 +19,4 @@
#define MK_3_SPEED
#define MK_MOMENTARY_ACCEL
#define PERMISSIVE_HOLD
+#define TAPPING_TERM 250
diff --git a/users/mnil/mnil.c b/users/mnil/mnil.c
index d5bd0ef0bb..00da6086ef 100644
--- a/users/mnil/mnil.c
+++ b/users/mnil/mnil.c
@@ -140,7 +140,7 @@ void aa_reset(qk_tap_dance_state_t *state, void *user_data) {
// clang-format off
qk_tap_dance_action_t tap_dance_actions[] = {
- [AAE] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ae_finished, ae_reset, 250),
- [OAA] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, aa_finished, aa_reset, 250)
+ [AAE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ae_finished, ae_reset),
+ [OAA] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, aa_finished, aa_reset)
};
// clang-format on
diff --git a/users/mtdjr/mtdjr.c b/users/mtdjr/mtdjr.c
index 9c6c26bc86..cd67bf3b5f 100644
--- a/users/mtdjr/mtdjr.c
+++ b/users/mtdjr/mtdjr.c
@@ -137,7 +137,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
};
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _RAISE:
#ifdef RGBLIGHT_ENABLE
rgblight_sethsv_noeeprom (240, 255, 255);
diff --git a/users/ninjonas/config.h b/users/ninjonas/config.h
index 025dbb541a..565e40e841 100644
--- a/users/ninjonas/config.h
+++ b/users/ninjonas/config.h
@@ -2,6 +2,7 @@
#undef TAPPING_TERM
#define TAPPING_TERM 200
#endif
+#define TAPPING_TERM_PER_KEY
// Mouse Settings: Smoothing out mouse movement on keypress
#ifndef MOUSEKEY_INTERVAL
@@ -18,4 +19,4 @@
#undef COMBO_TERM
#define COMBO_COUNT 5
#define COMBO_TERM 60
-#endif \ No newline at end of file
+#endif
diff --git a/users/ninjonas/oled.c b/users/ninjonas/oled.c
index 55eaf88ccb..463c6dfebb 100644
--- a/users/ninjonas/oled.c
+++ b/users/ninjonas/oled.c
@@ -23,7 +23,7 @@ bool process_record_oled(uint16_t keycode, keyrecord_t *record) {
void render_layout_state(void) {
oled_write_P(PSTR("Layout: "), false);
- switch (biton32(default_layer_state)) {
+ switch (get_highest_layer(default_layer_state)) {
case _COLEMAK:
oled_write_P(PSTR("Colemak"), false);
break;
diff --git a/users/ninjonas/tap_dances.c b/users/ninjonas/tap_dances.c
index 63e4d3ba47..3e4cec9133 100644
--- a/users/ninjonas/tap_dances.c
+++ b/users/ninjonas/tap_dances.c
@@ -107,6 +107,16 @@ qk_tap_dance_action_t tap_dance_actions[] = {
[TD_GUI_GUISPC] = ACTION_TAP_DANCE_DOUBLE(KC_LGUI, LGUI(KC_SPC)),
// Advanced Tap Dances
- [TD_COPY_PASTE_APP] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, copy_paste_app_finished, copy_paste_app_reset, 300),
- [TD_Y_NUMPAD] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, y_numpad_finished, y_numpad_reset, 300),
-}; \ No newline at end of file
+ [TD_COPY_PASTE_APP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, copy_paste_app_finished, copy_paste_app_reset),
+ [TD_Y_NUMPAD] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, y_numpad_finished, y_numpad_reset),
+};
+
+uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case TD(TD_COPY_PASTE_APP):
+ case TD(TD_Y_NUMPAD):
+ return 300;
+ default:
+ return TAPPING_TERM;
+ }
+}
diff --git a/users/pvinis/pvinis.c b/users/pvinis/pvinis.c
index 71f9210aec..96b01bb461 100644
--- a/users/pvinis/pvinis.c
+++ b/users/pvinis/pvinis.c
@@ -95,4 +95,4 @@ void keyboard_post_init_user(void) {
// Default functions.
__attribute__((weak)) void keyboard_post_init_user_keymap(void) {}
-__attribute__((weak)) uint32_t layer_state_set_user_keymap(uint32_t state) { return state; }
+__attribute__((weak)) layer_state_t layer_state_set_user_keymap(layer_state_t state) { return state; }
diff --git a/users/pvinis/pvinis.h b/users/pvinis/pvinis.h
index c50033a440..5a11a6cb6f 100644
--- a/users/pvinis/pvinis.h
+++ b/users/pvinis/pvinis.h
@@ -169,4 +169,4 @@ enum {
// Extra stuff that might be needed.
void keyboard_post_init_user_keymap(void);
-uint32_t layer_state_set_user_keymap(uint32_t state);
+layer_state_t layer_state_set_user_keymap(layer_state_t state);
diff --git a/users/romus/romus.c b/users/romus/romus.c
index f707bb8843..a41a6df578 100644
--- a/users/romus/romus.c
+++ b/users/romus/romus.c
@@ -59,7 +59,7 @@ __attribute__ ((weak)) void matrix_scan_keymap(void) { }
__attribute__ ((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
-__attribute__ ((weak)) uint32_t layer_state_set_keymap (uint32_t state) {
+__attribute__ ((weak)) layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
__attribute__ ((weak)) void led_set_keymap(uint8_t usb_led) { }
@@ -551,7 +551,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
state = layer_state_set_keymap (state);
#ifdef RGBLIGHT_ENABLE
// Change RGB lighting depending on the last layer activated
- rgblight_change( biton32(state) );
+ rgblight_change( get_highest_layer(state) );
#endif
return state;
}
diff --git a/users/sigma/sigma.c b/users/sigma/sigma.c
index 527925a63f..8470060a53 100644
--- a/users/sigma/sigma.c
+++ b/users/sigma/sigma.c
@@ -49,12 +49,12 @@ bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
__attribute__ ((weak))
-uint32_t default_layer_state_set_keymap (uint32_t state) {
+layer_state_t default_layer_state_set_keymap (layer_state_t state) {
return state;
}
diff --git a/users/stanrc85/layer_rgb.c b/users/stanrc85/layer_rgb.c
index 6d57198f3b..ad30c2ee65 100644
--- a/users/stanrc85/layer_rgb.c
+++ b/users/stanrc85/layer_rgb.c
@@ -5,7 +5,7 @@ void matrix_init_user(void) {
};
layer_state_t layer_state_set_user(layer_state_t state) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case 0:
rgblight_setrgb (0xFF, 0x00, 0x00);
break;
diff --git a/users/talljoe/config.h b/users/talljoe/config.h
index 8a5fd50cb7..dcdbbd89f4 100644
--- a/users/talljoe/config.h
+++ b/users/talljoe/config.h
@@ -19,9 +19,5 @@
#define RESET_LAYER 15
-#define BOOTMAGIC_KEY_SALT KC_ESC
-#define BOOTMAGIC_KEY_SKIP KC_I
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_E
-
#define COMBO_COUNT 2
#define COMBO_TERM 250
diff --git a/users/talljoe/talljoe.c b/users/talljoe/talljoe.c
index 517f712ec8..6655170d4a 100644
--- a/users/talljoe/talljoe.c
+++ b/users/talljoe/talljoe.c
@@ -138,7 +138,7 @@ void matrix_init_user(void) {
}
}
-uint32_t default_layer_state_set_kb(uint32_t state) {
+layer_state_t default_layer_state_set_kb(layer_state_t state) {
// persist changes to default layers
eeconfig_update_default_layer(state);
return state;
diff --git a/users/tominabox1/config.h b/users/tominabox1/config.h
index 4a2433eb0b..f853e18605 100644
--- a/users/tominabox1/config.h
+++ b/users/tominabox1/config.h
@@ -3,8 +3,6 @@
// Tapping term settings
#define TAPPING_TERM_PER_KEY
#define TAP_HOLD_CAPS_DELAY 350
-#define BOOTMAGIC_KEY_SALT KC_BSPACE
-#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_Q
// OLED settings
#define OLED_FONT_H "users/tominabox1/doug.c"
diff --git a/users/tominabox1/tominabox1.c b/users/tominabox1/tominabox1.c
index 7322ead0dc..b4ec224d07 100644
--- a/users/tominabox1/tominabox1.c
+++ b/users/tominabox1/tominabox1.c
@@ -128,7 +128,7 @@ layer_state_t layer_state_set_keymap (layer_state_t state) {
layer_state_t layer_state_set_user(layer_state_t state) {
state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _LOWER:
break;
case _RAISE:
@@ -231,7 +231,7 @@ void render_status_main(void) {
// Host Keyboard Layer Status
oled_write_P(PSTR("Layer: "), false);
- switch (biton32(layer_state)) {
+ switch (get_highest_layer(layer_state)) {
case _BASE:
oled_write_P(PSTR("Colemak\n"), false);
break;
diff --git a/users/turbomech/backupturbomech.c b/users/turbomech/backupturbomech.c
index aaea05df96..3671d27ab4 100644
--- a/users/turbomech/backupturbomech.c
+++ b/users/turbomech/backupturbomech.c
@@ -31,7 +31,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
__attribute__ ((weak))
@@ -300,7 +300,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE
uint8_t default_layer = eeconfig_read_default_layer();
if (rgb_layer_change) {
- switch (biton32(state)) {
+ switch (get_highest_layer(state)) {
case _FUNCTION:
rgblight_set_blue;
rgblight_mode(1);
@@ -377,7 +377,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
-uint32_t layer_state_set_keymap (uint32_t state) {
+layer_state_t layer_state_set_keymap (layer_state_t state) {
return state;
}
__attribute__ ((weak))
diff --git a/users/xulkal/custom_oled.c b/users/xulkal/custom_oled.c
index 7fe8040927..fd03033ad6 100644
--- a/users/xulkal/custom_oled.c
+++ b/users/xulkal/custom_oled.c
@@ -37,7 +37,7 @@ static void render_icon(void)
static void render_layer(void)
{
- uint8_t layer = layer_state ? biton(layer_state) : biton32(default_layer_state);
+ uint8_t layer = layer_state ? get_highest_layer(layer_state) : get_highest_layer(default_layer_state);
#ifdef OLED_90ROTATION
oled_write_P(PSTR("Layer"), false);
#else
diff --git a/users/zer09/zer09.c b/users/zer09/zer09.c
index a6768f0a1a..78433b4c20 100644
--- a/users/zer09/zer09.c
+++ b/users/zer09/zer09.c
@@ -43,7 +43,7 @@ void matrix_init_user(void) {
void matrix_scan_user(void) {
static uint8_t is_leds_changes = 1;
- c_lyr = biton32(layer_state);
+ c_lyr = get_highest_layer(layer_state);
is_leds_changes = is_leds_changes << set_layer_led(c_lyr);
is_leds_changes = is_leds_changes << shifted_layer();
diff --git a/util/uf2conv.py b/util/uf2conv.py
index df94b5ac99..7f5645414a 100755
--- a/util/uf2conv.py
+++ b/util/uf2conv.py
@@ -219,6 +219,9 @@ def get_drives():
tmp = rootpath + "/" + os.environ["USER"]
if os.path.isdir(tmp):
rootpath = tmp
+ tmp = "/run" + rootpath + "/" + os.environ["USER"]
+ if os.path.isdir(tmp):
+ rootpath = tmp
for d in os.listdir(rootpath):
drives.append(os.path.join(rootpath, d))
diff --git a/util/update_chibios_mirror.sh b/util/update_chibios_mirror.sh
index e6666c55c9..bd4c5c1529 100755
--- a/util/update_chibios_mirror.sh
+++ b/util/update_chibios_mirror.sh
@@ -7,7 +7,7 @@
chibios_branches="trunk stable_20.3.x stable_21.11.x"
# The ChibiOS tags to mirror
-chibios_tags="ver20.3.1 ver20.3.2 ver20.3.3 ver20.3.4 ver21.11.1"
+chibios_tags="ver20.3.1 ver20.3.2 ver20.3.3 ver20.3.4 ver21.11.1 ver21.11.2"
# The ChibiOS-Contrib branches to mirror
contrib_branches="chibios-20.3.x chibios-21.11.x"