diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index fc0ed11c43f..3f7fbbe7aff 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -37,7 +37,7 @@ jobs: qmk --verbose generate-docs - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4.5.0 + uses: JamesIves/github-pages-deploy-action@v4.6.0 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BASE_BRANCH: master diff --git a/docs/pr_checklist.md b/docs/pr_checklist.md index 0d503ab4177..94ff7eed665 100644 --- a/docs/pr_checklist.md +++ b/docs/pr_checklist.md @@ -148,6 +148,13 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard - For instance, only `wilba_tech` boards shall include `keyboards/wilba_tech/wt_main.c` and `keyboards/wilba_tech/wt_rgb_backlight.c`. But including `drivers/sensors/pmw3360.c` is absolutely fine for any and all boards that require it. - Code that needs to be used by multiple boards is a candidate for core code changes, and should be separated out. +Wireless-capable boards: +- Given license abuse from vendors, QMK does not accept any vendor PRs for wireless- or Bluetooth-capable keyboards without wireless and/or Bluetooth code + - Historically, vendors have done this in bad faith in order to attain downstream VIA compatibility with no intention of releasing wireless sources + - QMK's license, the GPL2+, requires full source disclosure for any distributed binary -- including full sources for any keyboard shipped by vendors containing QMK and/or firmware-side VIA code + - If a vendor's wireless-capable keyboard PR submission is lacking wireless capability, then the PR will be left on-hold and unmergeable until wireless bindings are provided + - If a vendor's wireless-capable keyboard is merged into QMK before it's known that the board is wireless, then all existing and future PRs from the same vendor will be put on hold until wireless bindings for the offending keyboard are provided + Also, specific to ChibiOS: - **strong** preference to using existing ChibiOS board definitions. - a lot of the time, an equivalent Nucleo board can be used with a different flash size or slightly different model in the same family diff --git a/keyboards/keyten/lisa/info.json b/keyboards/keyten/lisa/info.json new file mode 100644 index 00000000000..deac0f37408 --- /dev/null +++ b/keyboards/keyten/lisa/info.json @@ -0,0 +1,81 @@ +{ + "manufacturer": "keyten", + "keyboard_name": "Lisa", + "maintainer": "key10iq", + "bootloader": "stm32-dfu", + "diode_direction": "COL2ROW", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + "cols": ["B7", "B6", "B5", "B4", "B3", "A15", "A3", "A4", "A5", "A6", "A7", "B0", "B1"], + "rows": ["B13", "B15", "B14", "A8"] + }, + "indicators": { + "caps_lock": "B10", + "num_lock": "B11" + } + "processor": "STM32F072", + "usb": { + "vid": "0xEB69", + "pid": "0x4001", + "device_version": "0.0.1" + }, + "layouts": { + "LAYOUT": { + "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": [0, 6], "x": 7.5, "y": 0}, + {"matrix": [0, 7], "x": 8.5, "y": 0}, + {"matrix": [0, 8], "x": 9.5, "y": 0}, + {"matrix": [0, 9], "x": 10.5, "y": 0}, + {"matrix": [0, 10], "x": 11.5, "y": 0}, + {"matrix": [0, 11], "x": 12.5, "y": 0}, + {"matrix": [0, 12], "x": 13.5, "y": 0}, + {"matrix": [1, 0], "w": 1.25, "x": 0, "y": 1}, + {"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": [1, 6], "x": 7.75, "y": 1}, + {"matrix": [1, 7], "x": 8.75, "y": 1}, + {"matrix": [1, 8], "x": 9.75, "y": 1}, + {"matrix": [1, 9], "x": 10.75, "y": 1}, + {"matrix": [1, 10], "x": 11.75, "y": 1}, + {"matrix": [1, 12], "w": 1.75, "x": 12.75, "y": 1}, + {"matrix": [2, 0], "w": 1.75, "x": 0, "y": 2}, + {"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": 7.25, "y": 2}, + {"matrix": [2, 7], "x": 8.25, "y": 2}, + {"matrix": [2, 8], "x": 9.25, "y": 2}, + {"matrix": [2, 9], "x": 10.25, "y": 2}, + {"matrix": [2, 10], "x": 11.25, "y": 2}, + {"matrix": [2, 11], "x": 12.25, "y": 2}, + {"matrix": [2, 12], "w": 1.25, "x": 13.25, "y": 2}, + {"matrix": [3, 0], "w": 1.25, "x": 0, "y": 3}, + {"matrix": [3, 1], "w": 1.25, "x": 1.25, "y": 3}, + {"matrix": [3, 3], "w": 1.25, "x": 3.5, "y": 3}, + {"matrix": [3, 5], "w": 2, "x": 4.75, "y": 3}, + {"matrix": [3, 6], "w": 2.25, "x": 7.25, "y": 3}, + {"matrix": [3, 8], "w": 1.25, "x": 9.5, "y": 3}, + {"matrix": [3, 11], "w": 1.25, "x": 12, "y": 3}, + {"matrix": [3, 12], "w": 1.25, "x": 13.25, "y": 3} + ] + } + } +} diff --git a/keyboards/keyten/lisa/keymaps/default/keymap.c b/keyboards/keyten/lisa/keymaps/default/keymap.c new file mode 100644 index 00000000000..0803f25b6e0 --- /dev/null +++ b/keyboards/keyten/lisa/keymaps/default/keymap.c @@ -0,0 +1,28 @@ +// Copyright 2024 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, 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_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_ENT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LCTL, KC_LGUI, KC_LALT, LT(1,KC_SPC), LT(2,KC_BSPC), KC_RALT, KC_RGUI, KC_RCTL + ), + + [1] = LAYOUT( + KC_TRNS, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [2] = LAYOUT( + KC_TRNS, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/keyboards/keyten/lisa/keymaps/via/keymap.c b/keyboards/keyten/lisa/keymaps/via/keymap.c new file mode 100644 index 00000000000..0803f25b6e0 --- /dev/null +++ b/keyboards/keyten/lisa/keymaps/via/keymap.c @@ -0,0 +1,28 @@ +// Copyright 2024 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, 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_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_ENT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LCTL, KC_LGUI, KC_LALT, LT(1,KC_SPC), LT(2,KC_BSPC), KC_RALT, KC_RGUI, KC_RCTL + ), + + [1] = LAYOUT( + KC_TRNS, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [2] = LAYOUT( + KC_TRNS, 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/keyboards/keyten/lisa/keymaps/via/rules.mk b/keyboards/keyten/lisa/keymaps/via/rules.mk new file mode 100644 index 00000000000..036bd6d1c3e --- /dev/null +++ b/keyboards/keyten/lisa/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes \ No newline at end of file diff --git a/keyboards/keyten/lisa/lisa.c b/keyboards/keyten/lisa/lisa.c new file mode 100644 index 00000000000..2ecff3a642c --- /dev/null +++ b/keyboards/keyten/lisa/lisa.c @@ -0,0 +1,12 @@ +// Copyright 2024 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "quantum.h" + +#define LED_INDICATOR_PIN B2 + +void matrix_init_kb(void) { + gpio_set_pin_output(LED_INDICATOR_PIN); + gpio_write_pin_high(LED_INDICATOR_PIN); + matrix_init_user(); +} diff --git a/keyboards/keyten/lisa/readme.md b/keyboards/keyten/lisa/readme.md new file mode 100644 index 00000000000..e5d783e8406 --- /dev/null +++ b/keyboards/keyten/lisa/readme.md @@ -0,0 +1,27 @@ +# keyten Lisa + +Lisa is a Tadpole mount keyboard with Prime_E layout + +![Lisa](https://i.imgur.com/PaVECKC.png) + +* Keyboard Maintainer: [keyten](https://github.com/key10iq) +* Hardware Supported: keyten Lisa +* Hardware Availability: private GB + +Make example for this keyboard (after setting up your build environment): + + make keyten/lisa:default + +Flashing example for this keyboard: + + make keyten/lisa: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 (usually the top left key or Escape) and plug in the keyboard +* Keycode in layout: Press the key mapped to `QK_BOOT` if it is available +* Physical reset button: Hold the button on the back of the PCB diff --git a/keyboards/keyten/lisa/rules.mk b/keyboards/keyten/lisa/rules.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/python/qmk/cli/license_check.py b/lib/python/qmk/cli/license_check.py index 4bda272ec9b..119a228c6d4 100644 --- a/lib/python/qmk/cli/license_check.py +++ b/lib/python/qmk/cli/license_check.py @@ -1,9 +1,9 @@ # Copyright 2023 Nick Brassel (@tzarc) # SPDX-License-Identifier: GPL-2.0-or-later import re -from pathlib import Path from milc import cli from qmk.constants import LICENSE_TEXTS +from qmk.path import normpath L_PAREN = re.compile(r'\(\[\{\<') R_PAREN = re.compile(r'\)\]\}\>') @@ -27,7 +27,45 @@ def _simplify_text(input): return ' '.join(lines) -def _detect_license_from_file_contents(filename, absolute=False): +def _preformat_license_texts(): + # Pre-format all the licenses + for _, long_licenses in LICENSE_TEXTS: + for i in range(len(long_licenses)): + long_licenses[i] = _simplify_text(long_licenses[i]) + + +def _determine_suffix_condition(extensions): + def _default_suffix_condition(s): + return s in SUFFIXES + + conditional = _default_suffix_condition + + if extensions is not None and len(extensions) > 0: + suffixes = [f'.{s}' if not s.startswith('.') else s for s in extensions] + + def _specific_suffix_condition(s): + return s in suffixes + + conditional = _specific_suffix_condition + + return conditional + + +def _determine_file_list(inputs, conditional): + check_list = set() + for filename in inputs: + if filename.is_dir(): + for file in sorted(filename.rglob('*')): + if file.is_file() and conditional(file.suffix): + check_list.add(file) + elif filename.is_file(): + if conditional(filename.suffix): + check_list.add(filename) + + return list(sorted(check_list)) + + +def _detect_license_from_file_contents(filename, absolute=False, short=False): data = filename.read_text(encoding='utf-8', errors='ignore') filename_out = str(filename.absolute()) if absolute else str(filename) @@ -42,13 +80,13 @@ def _detect_license_from_file_contents(filename, absolute=False): break if not found: - if cli.args.short: + if short: print(f'{filename_out} UNKNOWN') else: cli.log.error(f'{{fg_cyan}}{filename_out}{{fg_reset}} -- unknown license, or no license detected!') return False - if cli.args.short: + if short: print(f'{filename_out} {license}') else: cli.log.info(f'{{fg_cyan}}{filename_out}{{fg_reset}} -- license detected: {license} (SPDX License Identifier)') @@ -59,13 +97,13 @@ def _detect_license_from_file_contents(filename, absolute=False): for short_license, long_licenses in LICENSE_TEXTS: for long_license in long_licenses: if long_license in simple_text: - if cli.args.short: + if short: print(f'{filename_out} {short_license}') else: cli.log.info(f'{{fg_cyan}}{filename_out}{{fg_reset}} -- license detected: {short_license} (Full text)') return True - if cli.args.short: + if short: print(f'{filename_out} UNKNOWN') else: cli.log.error(f'{{fg_cyan}}{filename_out}{{fg_reset}} -- unknown license, or no license detected!') @@ -73,43 +111,20 @@ def _detect_license_from_file_contents(filename, absolute=False): return False -@cli.argument('inputs', nargs='*', arg_only=True, type=Path, help='List of input files or directories.') +@cli.argument('inputs', nargs='*', arg_only=True, type=normpath, help='List of input files or directories.') @cli.argument('-s', '--short', action='store_true', help='Short output.') @cli.argument('-a', '--absolute', action='store_true', help='Print absolute paths.') @cli.argument('-e', '--extension', arg_only=True, action='append', default=[], help='Override list of extensions. Can be specified multiple times for multiple extensions.') @cli.subcommand('File license check.', hidden=False if cli.config.user.developer else True) def license_check(cli): - def _default_suffix_condition(s): - return s in SUFFIXES + _preformat_license_texts() - conditional = _default_suffix_condition - - if len(cli.args.extension) > 0: - suffixes = [f'.{s}' if not s.startswith('.') else s for s in cli.args.extension] - - def _specific_suffix_condition(s): - return s in suffixes - - conditional = _specific_suffix_condition - - # Pre-format all the licenses - for _, long_licenses in LICENSE_TEXTS: - for i in range(len(long_licenses)): - long_licenses[i] = _simplify_text(long_licenses[i]) - - check_list = set() - for filename in sorted(cli.args.inputs): - if filename.is_dir(): - for file in sorted(filename.rglob('*')): - if file.is_file() and conditional(file.suffix): - check_list.add(file) - elif filename.is_file(): - if conditional(filename.suffix): - check_list.add(filename) + conditional = _determine_suffix_condition(cli.args.extension) + check_list = _determine_file_list(cli.args.inputs, conditional) failed = False for filename in sorted(check_list): - if not _detect_license_from_file_contents(filename, absolute=cli.args.absolute): + if not _detect_license_from_file_contents(filename, absolute=cli.args.absolute, short=cli.args.short): failed = True if failed: