mirror of
https://github.com/qmk/qmk_firmware.git
synced 2026-06-20 14:23:45 -04:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c638100030 | |||
| 85886db43b | |||
| d8c8872753 | |||
| 520b726b5c | |||
| 4dc0a6e9e3 | |||
| 7b30455a93 | |||
| 1ef87578e2 | |||
| f34bc9a6bc | |||
| 486f01f513 |
+48
-235
@@ -1,11 +1,13 @@
|
||||
---
|
||||
applyTo: "**"
|
||||
applyTo: "keyboards/**"
|
||||
excludeAgent:
|
||||
- "coding-agent"
|
||||
---
|
||||
# GitHub Copilot Instructions for QMK Pull Request Review
|
||||
This document provides automated review guidance based on the [QMK PR Checklist](https://docs.qmk.fm/pr_checklist) and it is intended only for use by GitHub Copilot code-review agent during pull request reviews.
|
||||
|
||||
> **Scope**: This review applies **only to changes within the `keyboards/` folder**. Changes outside `keyboards/` (e.g., core code, quantum, platforms, drivers) must be flagged and deferred to a QMK Collaborator — do not review them.
|
||||
|
||||
## General PR Requirements
|
||||
|
||||
### Branch and Submission Standards
|
||||
@@ -41,37 +43,20 @@ This document provides automated review guidance based on the [QMK PR Checklist]
|
||||
- **Exception**: Simple assignment-only `rules.mk` files don't need headers
|
||||
- **Flag**: Missing or ambiguous license headers (blocks merge)
|
||||
|
||||
### QMK Best Practices
|
||||
- **Include Guards**: Use `#pragma once` instead of `#ifndef` guards in headers
|
||||
- **Abstractions Required**: No low-level GPIO/I2C/SPI functions
|
||||
- Must use QMK abstractions (flag direct hardware access)
|
||||
- **Timing Functions**:
|
||||
- Use `wait_ms()` instead of `_delay_ms()`
|
||||
- Remove `#include <util/delay.h>`
|
||||
- Use `timer_read()`, `timer_read32()` from `timer.h`
|
||||
- **New Abstractions**: If proposing new abstraction, suggest:
|
||||
1. Prototype in own keyboard first
|
||||
2. Discuss with QMK Collaborators on Discord
|
||||
3. Refactor as separate core change
|
||||
4. Remove the keyboard-specific implementation from board
|
||||
|
||||
---
|
||||
|
||||
## Keymap PR Reviews
|
||||
|
||||
**Scope**: These rules apply to files within `keyboards/*/keymaps/*` subdirectories.
|
||||
|
||||
### Note on Personal Keymaps
|
||||
- **Policy Change**: Personal keymap submissions no longer accepted
|
||||
- **Permitted**: Vendor-specific keymaps only
|
||||
- Naming convention: `default_${vendor}` (e.g., `default_clueboard`)
|
||||
- Can be more feature-rich than stock `default` keymaps
|
||||
### Note on Non-Default Keymaps
|
||||
- Any keymap folder named something other than `default` (e.g., `default_clueboard`, `via`) is a non-default keymap
|
||||
- **Do not review the content** of non-default keymaps — flag their presence and note that a QMK Collaborator must review them
|
||||
|
||||
### Keymap Code Standards
|
||||
- **Includes**: `#include QMK_KEYBOARD_H` preferred over specific board files
|
||||
- **Enums**: Prefer layer enums to `#define`s
|
||||
- **Enums**: Suggest using layer enums instead of `#define`s for layers (soft suggestion only)
|
||||
- **Custom Keycodes**: First entry must be `QK_USER`
|
||||
- **Formatting**: Check spacing alignment on commas and keycodes (spaces, not tabs)
|
||||
- **VIA**: Keymaps should NOT enable VIA
|
||||
- VIA keymaps belong in [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via)
|
||||
|
||||
@@ -96,245 +81,70 @@ This document provides automated review guidance based on the [QMK PR Checklist]
|
||||
- **Data Driven Migration**: Must target `develop`
|
||||
|
||||
### info.json and keyboard.json Requirements
|
||||
- **Data-Driven Configuration**: Encourage maximum use of `info.json` and `keyboard.json` schema features
|
||||
- **Schema Validation**: All `info.json` and `keyboard.json` files must validate against `data/schemas/keyboard.jsonschema`
|
||||
- Use QMK CLI: `qmk lint -kb <keyboard_name>` to validate
|
||||
- Schema defines required fields, data types, and valid values
|
||||
- Check for schema validation errors before submitting PR
|
||||
- **Schema Validation**: Verify that `info.json` and `keyboard.json` files are valid JSON (no syntax errors, no trailing commas, properly closed brackets)
|
||||
- **Mandatory Elements**:
|
||||
- Valid URL
|
||||
- Valid maintainer
|
||||
- Valid USB VID/PID and device version
|
||||
- Displays correctly in Configurator (Ctrl+Shift+I to preview)
|
||||
- `layout` definitions include matrix positions
|
||||
- Standard layout definitions where applicable
|
||||
- Community Layout macro names when applicable
|
||||
- `url` field is present and begins with `http://` or `https://`
|
||||
- `maintainer` field is present and non-empty
|
||||
- `usb.vid` and `usb.pid` fields are present and match the `0x` hexadecimal format (e.g. `"vid": "0x1234"`, `"pid": "0xFEED"`)
|
||||
- `usb.device_version` field is present
|
||||
- Each key entry in every `layout` array must include a `"matrix"` property (e.g. `{"label": "L01", "matrix": [0, 0], "x": 0, "y": 0}`)
|
||||
- Microcontroller and bootloader specified
|
||||
- Diode direction (if not using direct pins)
|
||||
- **Layout Naming**:
|
||||
- Single layout: Use `LAYOUT` or community layout name
|
||||
- Multiple layouts: Include `LAYOUT_all` + alternate names
|
||||
- Prefer community layout names (e.g., `LAYOUT_tkl_ansi`, `LAYOUT_ortho_4x4`)
|
||||
- **Configuration in info.json or keyboard.json** (when applicable):
|
||||
- Direct pin configuration
|
||||
- Backlight, Split keyboard, Encoder, Bootmagic configs
|
||||
- LED Indicator, RGB Light, RGB Matrix configs
|
||||
- **Format**: Run `qmk format-json -i` before submitting
|
||||
|
||||
### USB VID/PID Uniqueness
|
||||
VID+PID combination must be unique across all keyboards. Individual VID or PID values can be reused with different partners.
|
||||
**Validation Steps:**
|
||||
1. Extract VID and PID from keyboard.json/info.json in the PR
|
||||
2. Search for existing usage: `grep -r '"vid".*"0xVVVV"' keyboards/ --include="*.json" | grep -l '"pid".*"0xPPPP"'`
|
||||
3. If results found: Check if BOTH VID AND PID match in same file
|
||||
- Both match = **COLLISION** - request different PID
|
||||
- Only one matches = **OK** - different keyboards can share individual values
|
||||
4. For keyboard variants/revisions under same keyboard folder:
|
||||
- Different PID recommended for functionally different variants
|
||||
- Same PID acceptable if revisions only differ in hardware routing/pin assignments
|
||||
**Quick Reference:**
|
||||
- Same PID + Different VID = Valid
|
||||
- Same VID + Different PID = Valid
|
||||
- Same VID + Same PID = Invalid
|
||||
**Review Response:**
|
||||
For collision:
|
||||
```
|
||||
VID+PID collision: 0xVVVV:0xPPPP already used by keyboards/[path]/file.json
|
||||
+Please assign a different PID. VID can remain the same.
|
||||
```
|
||||
For uniqueness confirmed:
|
||||
```
|
||||
VID+PID validation: 0xVVVV:0xPPPP is unique (no collisions found)
|
||||
```
|
||||
- Single layout: Must be named `LAYOUT` or match `LAYOUT_*` pattern
|
||||
- Multiple layouts: Must include `LAYOUT_all` plus at least one alternate name
|
||||
|
||||
### readme.md Requirements
|
||||
- **Template**: Must follow [official template](https://github.com/qmk/qmk_firmware/blob/master/data/templates/keyboard/readme.md)
|
||||
- **Flash Command**: Present with `:flash` at end
|
||||
- **Hardware Link**: Valid availability link (unless handwired)
|
||||
- Private groupbuys acceptable
|
||||
- One-off prototypes will be questioned
|
||||
- Open-source should link to files
|
||||
- **Reset Instructions**: Clear bootloader mode instructions
|
||||
- **Images Required**:
|
||||
- Keyboard and PCB photos preferred
|
||||
- Must be hosted externally (imgur, etc.)
|
||||
- Direct image links required (not preview pages)
|
||||
- Example: `https://i.imgur.com/vqgE7Ok.jpg` not `https://imgur.com/vqgE7Ok`
|
||||
- **Reset Instructions**: Bootloader reset instructions must be present (non-empty)
|
||||
- **Images**: A keyboard image is preferred but not mandatory
|
||||
- If present, images must not be hosted in the repository
|
||||
- If an imgur URL is used, it must link directly to the image (i.e. `https://i.imgur.com/<id>.<ext>`), not the preview page (i.e. not `https://imgur.com/<id>`)
|
||||
|
||||
### rules.mk Standards
|
||||
- **Removed Items**:
|
||||
- `MIDI_ENABLE`, `FAUXCLICKY_ENABLE`, `HD44780_ENABLE`
|
||||
- Size comments like `(-/+size)`
|
||||
- Alternate bootloader lists if one specified
|
||||
- MCU parameter re-definitions matching defaults in `mcu_selection.mk`
|
||||
- **Comment Updates**: Change bootloader comments to generic
|
||||
- **Forbidden Features at Keyboard Level** (these belong in keymap-level `rules.mk` only):
|
||||
- `COMBO_ENABLE`
|
||||
- `ENCODER_MAP_ENABLE`
|
||||
|
||||
### config.h Standards (Keyboard Level)
|
||||
- **Prohibited**:
|
||||
- `#define DESCRIPTION`
|
||||
- Magic Key Options, MIDI Options, HD44780 configuration
|
||||
- User preference `#define`s (belong in keymap)
|
||||
- Re-defining default values (`DEBOUNCE`, RGB settings)
|
||||
- Copy/pasted comment blocks explaining features
|
||||
- Comment blocks explaining features
|
||||
- Commented-out unused defines
|
||||
- `#include "config_common.h"`
|
||||
- `#define MATRIX_ROWS/COLS` (unless custom matrix)
|
||||
- **Minimal Code**: Only critical board boot code required
|
||||
- **No Vial**: Vial-related files/changes not accepted
|
||||
|
||||
### Keyboard Implementation Files
|
||||
|
||||
#### `<keyboard>.c`
|
||||
- **Remove Empty Functions**: Delete empty or commented-out weak-defined functions
|
||||
- `xxxx_xxxx_kb()`, `xxxx_xxxx_user()` implementations
|
||||
- **Migration**: `matrix_init_board()` → `keyboard_pre_init_kb()`
|
||||
- **Custom Matrix**: Use `lite` variant when possible for standard debounce
|
||||
- `CUSTOM_MATRIX = lite` preferred
|
||||
- Full custom matrix (`yes`) requires justification
|
||||
- **LED Indicators**: Prefer Configuration Options over custom `led_update_*()` implementations
|
||||
- **Hardware Configuration**: Basic functionality for OLED, encoders, etc. at keyboard level
|
||||
- **Advanced Code Flag**: ⚠️ If a `<keyboard>.c` file is present in the PR, flag it as possible advanced code requiring QMK Collaborator review
|
||||
|
||||
#### `<keyboard>.h`
|
||||
- **Include**: `#include "quantum.h"` at top
|
||||
- **Layout Macros**: Move to `info.json` or `keyboard.json` (no longer in header)
|
||||
- **Layout Macros**: If `LAYOUT` macros are present, suggest moving them to `info.json` or `keyboard.json`
|
||||
|
||||
### Default Keymap Standards
|
||||
|
||||
**Scope**: These rules specifically apply to files within `keyboards/*/keymaps/default/` directories.
|
||||
|
||||
- **Pristine Requirement**: Bare minimum clean slate
|
||||
- No custom keycodes
|
||||
- No advanced features (non-exhaustive list of examples: tap dance, macros)
|
||||
- Basic mod taps and home row mods acceptable when necessary
|
||||
- Standard layouts preferred -- see examples in `layouts/default/` and `layouts/community/`
|
||||
- ⚠️ If `keymap.c` contains anything beyond the `keymaps[]` array, or if the `default` keymap folder contains additional `.c` or `.h` files, flag this as possible advanced code requiring QMK Collaborator review
|
||||
- **Removed Examples**: Delete `QMKBEST`/`QMKURL` macros
|
||||
- **Tri Layer**: Use Tri Layer feature instead of manual `layer_on/off()` + `update_tri_layer()`
|
||||
- **Encoder Map**: Use encoder map feature, `encoder_update_user()` may not be present
|
||||
- **No VIA**: Default keymap should not enable VIA
|
||||
- **Additional Keymaps**: Example/bells-and-whistles keymaps acceptable in same PR (separate from default)
|
||||
|
||||
### Prohibited Files
|
||||
- **No VIA JSON**: Belongs in [VIA Keyboard Repo](https://github.com/the-via/keyboards)
|
||||
- **No KLE JSON**: Not used within QMK
|
||||
- **Single Keyboard Per PR**: A PR must not modify more than one `keyboards/<folder>/` directory
|
||||
- Flag PRs that touch multiple top-level keyboard folders (e.g., both `keyboards/mykeyboard1/` and `keyboards/mykeyboard2/`) — each keyboard must be a separate PR
|
||||
- **No Cross-Keyboard Sources**: Don't include files from other keyboard vendors
|
||||
- Exception: Core files (e.g., `drivers/sensors/pmw3360.c`)
|
||||
- Use of vendor-specific code (e.g., `wilba_tech/wt_main.c`) only when keyboard exists in the same enclosing vendor folder (e.g. a `wilba_tech` keyboard)
|
||||
- Multi-board code is candidate for core refactoring when intended for use by multiple vendors
|
||||
|
||||
### Wireless Keyboards
|
||||
- **Policy**: Wireless/Bluetooth PRs rejected without complete wireless code
|
||||
- Wireless code may not include anything resembling precompiled data such as `*.a` files or other libraries
|
||||
- Firmware blobs are not permitted in raw form or as compiled C-style arrays either.
|
||||
- GPL2+ license requires full source disclosure
|
||||
- Historically abused for VIA compatibility without releasing sources
|
||||
- PRs without wireless capability will be held indefinitely
|
||||
- Existing merged wireless boards from same vendor held until sources provided
|
||||
|
||||
### ChibiOS-Specific Requirements
|
||||
- **Board Definitions**: Strong preference for existing ChibiOS board definitions
|
||||
- Use equivalent Nucleo boards when possible
|
||||
- Example: STM32L082KZ can use `BOARD = ST_NUCLEO64_L073RZ`
|
||||
- QMK is eliminating custom board definitions due to maintenance burden
|
||||
- **New Board Definitions**:
|
||||
- Must NOT be embedded in keyboard PR
|
||||
- Submit as separate Core PR
|
||||
- `board.c` must have standard `__early_init()` and empty `boardInit()`
|
||||
- Migrate code intended for `__early_init()` → keyboard-local `early_hardware_init_pre/post()`
|
||||
- Migrate code intended for `boardInit()` → keyboard-local `board_init()`
|
||||
|
||||
---
|
||||
|
||||
## Core PR Reviews
|
||||
|
||||
### Targeting and Scope
|
||||
- **Branch**: All core PRs must target `develop` branch
|
||||
- **Single Focus**: Smallest set of changes per PR
|
||||
- PRs with multiple areas will be asked to split
|
||||
- Keyboard/keymap changes only if affecting base builds or default-like keymaps
|
||||
- Keymap modifications (non-default) should be followup PR after core merge
|
||||
- Large refactoring PRs affecting other keymaps raised separately
|
||||
|
||||
### Testing Requirements
|
||||
- **New Hardware Support**: Requires test keyboard under `keyboards/handwired/onekey`
|
||||
- New MCUs: Add child keyboard targeting new MCU for build verification
|
||||
- New hardware (displays, matrix, peripherals): Provide associated keymap
|
||||
- Exception: If existing keymap can leverage functionality (consult Collaborators)
|
||||
- **Callbacks**: New `_kb`/`_user` callbacks must return `bool` for user override
|
||||
- **Unit Tests**: Strongly recommended, may be required
|
||||
- Critical code areas (keycode pipeline) will require tests
|
||||
- Boost confidence in current and future correctness
|
||||
|
||||
### Code Quality
|
||||
- **Subjective Review**: Other requirements at QMK Collaborators' discretion
|
||||
- **Documentation**: Core changes should be well-documented
|
||||
|
||||
---
|
||||
|
||||
## Automated Review Checklist
|
||||
|
||||
When reviewing PRs, check the following systematically:
|
||||
|
||||
### File Changes Review
|
||||
1. **License headers** on all C/H files (GPL2+ preferred, others must be GPL2+ compatible, SPDX format preferred)
|
||||
2. **File naming** lowercase (flag exceptions needing justification)
|
||||
3. **Include guards** use `#pragma once`
|
||||
4. **No low-level hardware access** (GPIO, I2C, SPI direct register writes)
|
||||
5. **Timing abstractions** (`wait_ms()`, `timer_read()` usage)
|
||||
|
||||
### info.json and keyboard.json Validation
|
||||
1. **Schema Compliance**: `keyboard.json` and `info.json` files validate against `data/schemas/keyboard.jsonschema`
|
||||
- Both files are identical syntax, however the `keyboard.json` dictates a buildable target, `info.json` does not
|
||||
- Run `qmk lint -kb <keyboard>` to check schema validation
|
||||
- Check for proper data types (strings, integers, arrays, objects)
|
||||
- Verify required fields are present
|
||||
- Ensure enum values match allowed options in schema
|
||||
2. All mandatory fields present and valid
|
||||
3. `qmk format-json -i` has been run (formats and validates)
|
||||
4. Layout macros moved from headers
|
||||
5. Community layout names used where applicable
|
||||
|
||||
### rules.mk Cleanup
|
||||
1. Deprecated features removed
|
||||
2. No size comments
|
||||
3. No keymap-only features at keyboard level
|
||||
4. No redundant MCU parameter definitions
|
||||
|
||||
### config.h Cleanup
|
||||
1. No `DESCRIPTION`, `config_common.h`, or prohibited includes
|
||||
2. No default value re-definitions
|
||||
3. No commented-out defines or feature documentation blocks
|
||||
4. No user preference defines at keyboard level
|
||||
|
||||
### Keymap Quality
|
||||
1. Default keymaps are pristine (no custom keycodes/advanced features)
|
||||
2. No `QMKBEST`/`QMKURL` macros
|
||||
3. Encoder map feature used instead of `encoder_update_user()`
|
||||
4. Tri Layer feature used for multi-layer access
|
||||
5. No VIA enabled in default keymap
|
||||
|
||||
### Documentation
|
||||
1. readme.md follows template
|
||||
2. Flash command present with `:flash`
|
||||
3. Reset instructions clear
|
||||
4. External image hosting (direct links)
|
||||
5. Valid hardware availability link
|
||||
|
||||
### Code Organization
|
||||
1. Empty weak-defined functions removed from `<keyboard>.c`
|
||||
2. Proper migration of init functions
|
||||
3. No cross-vendor source files
|
||||
4. No VIA/KLE JSON files
|
||||
|
||||
### Branch and Scope
|
||||
1. Not submitted from submitter's own `master` branch (use feature branches)
|
||||
2. PR is focused on single change
|
||||
3. Targets correct branch:
|
||||
- `master` for new keyboard additions
|
||||
- `develop` for keyboard updates/refactors/moves and core changes
|
||||
4. No merge conflicts
|
||||
|
||||
---
|
||||
|
||||
@@ -352,7 +162,6 @@ See: [Best Practices: Your Fork's Master](https://docs.qmk.fm/newbs_git_using_yo
|
||||
❌ This PR targets the wrong branch:
|
||||
- **New keyboard additions** should target `master`
|
||||
- **Keyboard updates/refactors/moves** should target `develop`
|
||||
- **Core changes** should target `develop`
|
||||
|
||||
Please change the target branch accordingly.
|
||||
```
|
||||
@@ -380,7 +189,7 @@ Exception: Only valid if from upstream sources (LUFA, ChibiOS) or justified by c
|
||||
### For config.h violations:
|
||||
```
|
||||
⚠️ Found prohibited config.h elements:
|
||||
- [list specific issues: DESCRIPTION, default value re-definitions, etc.]
|
||||
- [list specific issues: `#define DESCRIPTION`, `#include "config_common.h"`, comment blocks, commented-out defines]
|
||||
|
||||
Please remove these and refer to [Data Driven Configuration](https://docs.qmk.fm/data_driven_config).
|
||||
```
|
||||
@@ -393,31 +202,34 @@ Please remove these and refer to [Data Driven Configuration](https://docs.qmk.fm
|
||||
- Validate with: \`qmk lint -kb <keyboard_name>\`
|
||||
```
|
||||
|
||||
### For schema validation errors:
|
||||
```
|
||||
❌ Schema validation failed for info.json or keyboard.json:
|
||||
- [list specific validation errors from schema]
|
||||
- Check `data/schemas/keyboard.jsonschema` for valid field definitions
|
||||
- Common issues:
|
||||
- Invalid data types (e.g., string instead of integer)
|
||||
- Missing required fields
|
||||
- Invalid enum values
|
||||
- Incorrectly formatted pin definitions
|
||||
```
|
||||
|
||||
### For non-pristine default keymap:
|
||||
```
|
||||
⚠️ Default keymap should be pristine (clean slate for users):
|
||||
- Remove: [custom keycodes/tap dance/macros/etc.]
|
||||
- Keep it minimal with standard layouts where possible
|
||||
⚠️ Default keymap requires collaborator review:
|
||||
The default `keymap.c` contains code beyond the `keymaps[]` array. The following was detected:
|
||||
- [describe: extra functions/definitions in keymap.c, or additional .c/.h files in the default keymap folder]
|
||||
|
||||
Consider moving advanced features to a separate example keymap.
|
||||
A QMK Collaborator must review this before merging.
|
||||
```
|
||||
|
||||
### For non-default keymaps:
|
||||
```
|
||||
⚠️ Non-default keymap detected: `keyboards/[path]/keymaps/[name]/`
|
||||
|
||||
This keymap requires a QMK Collaborator to review its content. No automated review of its code was performed.
|
||||
```
|
||||
|
||||
### For `<keyboard>.c` detected:
|
||||
```
|
||||
⚠️ `<keyboard>.c` file detected: `keyboards/[path]/[keyboard].c`
|
||||
|
||||
This file may contain advanced hardware configuration. A QMK Collaborator must review this before merging.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes for GitHub Copilot
|
||||
## Constraints and Conduct
|
||||
|
||||
- **Scope**: Only review changes within the `keyboards/` folder. Flag any changes outside `keyboards/` and defer to a QMK Collaborator without reviewing them.
|
||||
- Focus reviews on **objective checklist items** that can be automatically verified
|
||||
- Flag **definite violations** with ❌
|
||||
- Suggest improvements for **recommendations** with ⚠️
|
||||
@@ -425,6 +237,7 @@ Consider moving advanced features to a separate example keymap.
|
||||
- **Link to relevant QMK documentation** for each issue
|
||||
- **Prioritize blocking issues** (license, merge conflicts, branch policy)
|
||||
- **Be constructive**: Suggest fixes, not just problems
|
||||
- **Acknowledge trade-offs**: Some guidelines have valid exceptions
|
||||
- **Do not review non-default keymaps** — flag their presence and defer to a QMK Collaborator
|
||||
- **Do not review `<keyboard>.c` content in detail** — flag its presence and defer to a QMK Collaborator
|
||||
|
||||
This is meant as a **first-pass review** to catch common issues before human review. Complex architectural decisions, code quality, and subjective assessments still require human QMK Collaborator review.
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
echo 'Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"' >> /etc/sudoers
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: recursive
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: recursive
|
||||
@@ -258,7 +258,7 @@ jobs:
|
||||
git:
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: recursive
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
- name: Checkout QMK Firmware
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements-dev.txt
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
- name: Checkout QMK Firmware
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
- name: Checkout QMK Firmware
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements-dev.txt
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
- name: Checkout QMK Firmware
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout QMK Firmware
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Download firmwares
|
||||
uses: actions/download-artifact@v8
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- riot
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements-dev.txt
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Disable safe.directory check
|
||||
run : git config --global --add safe.directory '*'
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements-dev.txt
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
container: ghcr.io/qmk/qmk_cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ endef
|
||||
TRY_TO_MATCH_RULE_FROM_LIST = $(eval $(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER,$1))$(RULE_FOUND)
|
||||
|
||||
# As TRY_TO_MATCH_RULE_FROM_LIST_HELPER, but with additional
|
||||
# resolution of keyboard_aliases.hjson for provided rule
|
||||
# resolution of keyboard_aliases.hjson for provided rule
|
||||
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER_KB
|
||||
# Split on ":", padding with empty strings to avoid indexing issues
|
||||
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
|
||||
@@ -452,16 +452,17 @@ distclean_userspace: clean
|
||||
endif
|
||||
|
||||
# Extra targets for formatting and/or pytest, running within the qmk/qmk_cli container to match GHA.
|
||||
CONTAINER_PREAMBLE := export HOME="/tmp"; export PATH="/tmp/.local/bin:\$$PATH"; python3 -m pip install --upgrade pip; python3 -m pip install -r requirements-dev.txt
|
||||
|
||||
.PHONY: format-core
|
||||
format-core:
|
||||
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a"
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk format-c --core-only -a
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk format-python -a
|
||||
|
||||
.PHONY: pytest
|
||||
pytest:
|
||||
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk pytest"
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk pytest
|
||||
|
||||
.PHONY: format-and-pytest
|
||||
format-and-pytest:
|
||||
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a && qmk pytest"
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk format-c --core-only -a
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk format-python -a
|
||||
RUNTIME=docker ./util/docker_cmd.sh qmk pytest
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
// Audio
|
||||
"AUDIO_DEFAULT_ON": {"info_key": "audio.default.on", "value_type": "bool"},
|
||||
"AUDIO_DEFAULT_CLICKY_ON": {"info_key": "audio.default.clicky", "value_type": "bool"},
|
||||
"AUDIO_PIN": {"info_key": "audio.pins.0"},
|
||||
"AUDIO_PIN_ALT": {"info_key": "audio.pins.1"},
|
||||
"AUDIO_POWER_CONTROL_PIN": {"info_key": "audio.power_control.pin"},
|
||||
"AUDIO_POWER_CONTROL_PIN_ON_STATE": {"info_key": "audio.power_control.on_state", "value_type": "int" },
|
||||
"AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "flag"},
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"manufacturer": "Owlab",
|
||||
"keyboard_name": "LINK Hotswap",
|
||||
"maintainer": "Owlab",
|
||||
"bootloader": "custom",
|
||||
"diode_direction": "COL2ROW",
|
||||
"features": {
|
||||
"bootmagic": true,
|
||||
"extrakey": true,
|
||||
"mousekey": true,
|
||||
"nkro": true
|
||||
},
|
||||
"host": {
|
||||
"default": {
|
||||
"nkro": true
|
||||
}
|
||||
},
|
||||
"indicators": {
|
||||
"caps_lock": "A0",
|
||||
"on_state": 0
|
||||
},
|
||||
"matrix_pins": {
|
||||
"cols": ["A7", "B0", "B1", "B2", "B10", "B11", "B12", "B13", "B14", "B15", "A8", "A9", "A10", "A6", "A15"],
|
||||
"rows": ["A1", "A2", "A3", "A4", "A5"]
|
||||
},
|
||||
"processor": "STM32F103",
|
||||
"url": "https://owlab.store",
|
||||
"usb": {
|
||||
"device_version": "0.0.1",
|
||||
"pid": "0x4C49",
|
||||
"vid": "0x4F53"
|
||||
},
|
||||
"community_layouts": ["65_ansi_blocker"],
|
||||
"layouts": {
|
||||
"LAYOUT_65_ansi_blocker": {
|
||||
"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": 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},
|
||||
{"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},
|
||||
{"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},
|
||||
{"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
|
||||
{"matrix": [3, 1], "x": 2.25, "y": 3},
|
||||
{"matrix": [3, 2], "x": 3.25, "y": 3},
|
||||
{"matrix": [3, 3], "x": 4.25, "y": 3},
|
||||
{"matrix": [3, 4], "x": 5.25, "y": 3},
|
||||
{"matrix": [3, 5], "x": 6.25, "y": 3},
|
||||
{"matrix": [3, 6], "x": 7.25, "y": 3},
|
||||
{"matrix": [3, 7], "x": 8.25, "y": 3},
|
||||
{"matrix": [3, 8], "x": 9.25, "y": 3},
|
||||
{"matrix": [3, 9], "x": 10.25, "y": 3},
|
||||
{"matrix": [3, 10], "x": 11.25, "y": 3},
|
||||
{"matrix": [3, 11], "x": 12.25, "y": 3, "w": 1.75},
|
||||
{"matrix": [3, 13], "x": 14, "y": 3},
|
||||
{"matrix": [3, 14], "x": 15, "y": 3},
|
||||
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 4], "x": 3.75, "y": 4, "w": 6.25},
|
||||
{"matrix": [4, 7], "x": 10, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 8], "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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2022 Owlab
|
||||
|
||||
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_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_DEL,
|
||||
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_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_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, MO(1),
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
|
||||
),
|
||||
|
||||
[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, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
||||
),
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* STM32F103x8 memory setup for use with the STM32Duino bootloader.
|
||||
*/
|
||||
f103_flash_size = 128k;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/*Here we give 22K flash to bootloader*/
|
||||
/*0x08005800 : the application bin start address*/
|
||||
flash0 : org = 0x08006000, len = f103_flash_size - 0x6000
|
||||
flash1 : org = 0x00000000, len = 0
|
||||
flash2 : org = 0x00000000, len = 0
|
||||
flash3 : org = 0x00000000, len = 0
|
||||
flash4 : org = 0x00000000, len = 0
|
||||
flash5 : org = 0x00000000, len = 0
|
||||
flash6 : org = 0x00000000, len = 0
|
||||
flash7 : org = 0x00000000, len = 0
|
||||
ram0 : org = 0x20000000, len = 20k
|
||||
ram1 : org = 0x00000000, len = 0
|
||||
ram2 : org = 0x00000000, len = 0
|
||||
ram3 : org = 0x00000000, len = 0
|
||||
ram4 : org = 0x00000000, len = 0
|
||||
ram5 : org = 0x00000000, len = 0
|
||||
ram6 : org = 0x00000000, len = 0
|
||||
ram7 : org = 0x00000000, len = 0
|
||||
}
|
||||
|
||||
/* 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", flash0);
|
||||
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for constructors and destructors.*/
|
||||
REGION_ALIAS("XTORS_FLASH", flash0);
|
||||
REGION_ALIAS("XTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for code text.*/
|
||||
REGION_ALIAS("TEXT_FLASH", flash0);
|
||||
REGION_ALIAS("TEXT_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for read only data.*/
|
||||
REGION_ALIAS("RODATA_FLASH", flash0);
|
||||
REGION_ALIAS("RODATA_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for various.*/
|
||||
REGION_ALIAS("VARIOUS_FLASH", flash0);
|
||||
REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for RAM(n) initialization data.*/
|
||||
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
|
||||
|
||||
/* RAM region to be used for Main stack. This stack accommodates the processing
|
||||
of all exceptions and interrupts.*/
|
||||
REGION_ALIAS("MAIN_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for the process stack. This is the stack used by
|
||||
the main() function.*/
|
||||
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for data segment.*/
|
||||
REGION_ALIAS("DATA_RAM", ram0);
|
||||
REGION_ALIAS("DATA_RAM_LMA", flash0);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Generic rules inclusion.*/
|
||||
INCLUDE rules.ld
|
||||
@@ -0,0 +1,23 @@
|
||||
# LINK65 - Hotswap PCB
|
||||
|
||||

|
||||
|
||||
A 65% keyboard made by Owlab.
|
||||
|
||||
* Keyboard Maintainer: [Owlab](https://github.com/owlab-git)
|
||||
* Hardware Supported: LINK65 Hotswap PCB
|
||||
* Hardware Availability: https://owlab.store
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make owlab/link65/hotswap:default
|
||||
|
||||
Flashing example for this keyboard:
|
||||
|
||||
make owlab/link65/hotswap:default:flash
|
||||
|
||||
**Bootloader:** This PCB uses the stm32duino bootloader with firmware starting at address `0x08006000`. To enter bootloader mode, hold the `B` key while plugging in USB.
|
||||
|
||||
> ⚠️ **QMK Toolbox is not supported.** It flashes to the wrong address (`0x08000000`) and will overwrite the bootloader, bricking the board. Use `qmk flash` or `dfu-util` directly with `-s 0x08006000:leave`.
|
||||
|
||||
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).
|
||||
@@ -0,0 +1,7 @@
|
||||
MCU_LDSCRIPT = STM32F103x8_0x08006000_bootloader
|
||||
BOARD = STM32_F103_STM32DUINO
|
||||
DFU_ARGS = -d 1688:2220 -a 0 -s 0x08006000
|
||||
# PID
|
||||
DFU_SUFFIX_ARGS = -v 1688 -p 2220
|
||||
|
||||
OPT_DEFS += -DBOOTLOADER_STM32DUINO
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Copyright 2024 Yiancar-Designs
|
||||
*
|
||||
* 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
|
||||
|
||||
/* RGB options */
|
||||
|
||||
#define WS2812_SPI_DRIVER SPID2
|
||||
#define WS2812_SPI_MOSI_PAL_MODE 0
|
||||
#define WS2812_SPI_SCK_PAL_MODE 0
|
||||
#define WS2812_SPI_SCK_PIN B13
|
||||
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2024 Yiancar-Designs
|
||||
*
|
||||
* 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
|
||||
|
||||
#define HAL_USE_SPI TRUE
|
||||
|
||||
#include_next <halconf.h>
|
||||
@@ -0,0 +1,333 @@
|
||||
{
|
||||
"manufacturer": "Yiancar-Designs",
|
||||
"keyboard_name": "Float 65",
|
||||
"maintainer": "Yiancar",
|
||||
"bootloader": "stm32-dfu",
|
||||
"diode_direction": "COL2ROW",
|
||||
"features": {
|
||||
"bootmagic": true,
|
||||
"extrakey": true,
|
||||
"mousekey": true,
|
||||
"nkro": true,
|
||||
"rgblight": true
|
||||
},
|
||||
"matrix_pins": {
|
||||
"cols": ["A13", "A10", "A9", "A14", "A15", "B8", "B9", "B2", "B1", "B0", "A0", "A1", "A2", "A3", "A5"],
|
||||
"rows": ["B3", "B4", "B5", "A8", "A4"]
|
||||
},
|
||||
"processor": "STM32F072",
|
||||
"rgblight": {
|
||||
"animations": {
|
||||
"alternating": true,
|
||||
"breathing": true,
|
||||
"christmas": true,
|
||||
"knight": true,
|
||||
"rainbow_mood": true,
|
||||
"rainbow_swirl": true,
|
||||
"snake": true,
|
||||
"static_gradient": true,
|
||||
"twinkle": true
|
||||
},
|
||||
"led_count": 8
|
||||
},
|
||||
"url": "https://yiancar-designs.com",
|
||||
"usb": {
|
||||
"device_version": "0.0.1",
|
||||
"pid": "0x5334",
|
||||
"vid": "0x8968"
|
||||
},
|
||||
"ws2812": {
|
||||
"driver": "spi",
|
||||
"pin": "B15"
|
||||
},
|
||||
"community_layouts": ["65_ansi_blocker", "65_ansi_blocker_split_bs", "65_ansi_blocker_tsangan", "65_ansi_blocker_tsangan_split_bs"],
|
||||
"layout_aliases": {
|
||||
"LAYOUT": "LAYOUT_65_ansi_blocker_split_bs"
|
||||
},
|
||||
"layouts": {
|
||||
"LAYOUT_65_ansi_blocker": {
|
||||
"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": 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},
|
||||
{"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": [2, 12], "x": 13.5, "y": 1, "w": 1.5},
|
||||
{"matrix": [1, 14], "x": 15, "y": 1},
|
||||
{"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},
|
||||
{"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},
|
||||
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
|
||||
{"matrix": [4, 9], "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}
|
||||
]
|
||||
},
|
||||
"LAYOUT_65_ansi_blocker_split_bs": {
|
||||
"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": 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": [1, 13], "x": 13, "y": 0},
|
||||
{"matrix": [0, 13], "x": 14, "y": 0},
|
||||
{"matrix": [0, 14], "x": 15, "y": 0},
|
||||
{"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": [2, 12], "x": 13.5, "y": 1, "w": 1.5},
|
||||
{"matrix": [1, 14], "x": 15, "y": 1},
|
||||
{"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},
|
||||
{"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},
|
||||
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
|
||||
{"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
|
||||
{"matrix": [4, 9], "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}
|
||||
]
|
||||
},
|
||||
"LAYOUT_65_ansi_blocker_tsangan": {
|
||||
"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": 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},
|
||||
{"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": [2, 12], "x": 13.5, "y": 1, "w": 1.5},
|
||||
{"matrix": [1, 14], "x": 15, "y": 1},
|
||||
{"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},
|
||||
{"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},
|
||||
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 1], "x": 1.5, "y": 4},
|
||||
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
|
||||
{"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 12], "x": 13, "y": 4},
|
||||
{"matrix": [4, 13], "x": 14, "y": 4},
|
||||
{"matrix": [4, 14], "x": 15, "y": 4}
|
||||
]
|
||||
},
|
||||
"LAYOUT_65_ansi_blocker_tsangan_split_bs": {
|
||||
"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": 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": [1, 13], "x": 13, "y": 0},
|
||||
{"matrix": [0, 13], "x": 14, "y": 0},
|
||||
{"matrix": [0, 14], "x": 15, "y": 0},
|
||||
{"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": [2, 12], "x": 13.5, "y": 1, "w": 1.5},
|
||||
{"matrix": [1, 14], "x": 15, "y": 1},
|
||||
{"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},
|
||||
{"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},
|
||||
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 1], "x": 1.5, "y": 4},
|
||||
{"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
|
||||
{"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
|
||||
{"matrix": [4, 12], "x": 13, "y": 4},
|
||||
{"matrix": [4, 13], "x": 14, "y": 4},
|
||||
{"matrix": [4, 14], "x": 15, "y": 4}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2024 Yiancar-Designs
|
||||
*
|
||||
* 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_65_ansi_blocker_split_bs( /* Base */
|
||||
QK_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_BSPC, KC_DEL,
|
||||
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_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_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_END,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RCTL, MO(1), KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
[1] = LAYOUT_65_ansi_blocker_split_bs( /* FN */
|
||||
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, KC_DEL, KC_DEL, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, UG_NEXT, UG_HUEU, UG_SATU, UG_VALU, UG_SPDU, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
KC_VOLU, KC_VOLD, KC_MUTE, _______, _______, _______, _______, _______, _______)
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2024 Yiancar-Designs
|
||||
*
|
||||
* 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 STM32_SPI_USE_SPI2
|
||||
#define STM32_SPI_USE_SPI2 TRUE
|
||||
@@ -0,0 +1,32 @@
|
||||
# Float 65
|
||||
|
||||
This is a 65% layout PCB. It supports VIA.
|
||||
|
||||
* Keyboard Maintainer: [Yiancar](http://yiancar-designs.com/) and on [GitHub](https://github.com/yiancar)
|
||||
* Hardware Supported: A 65% keyboard with STM32F072CB
|
||||
* Hardware Availability: https://omnitype.com
|
||||
|
||||
## Instructions
|
||||
|
||||
### Build
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make yiancardesigns/float65: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).
|
||||
|
||||
### Reset
|
||||
|
||||
- Unplug
|
||||
- Hold Escape
|
||||
- Plug In
|
||||
- Unplug
|
||||
- Release Escape
|
||||
|
||||
### Flash
|
||||
|
||||
- Unplug
|
||||
- Hold Escape
|
||||
- Plug In
|
||||
- Flash using QMK Toolbox or CLI (`make yiancardesigns/float65:<keymap>:flash`)
|
||||
@@ -95,7 +95,7 @@ def generate_config_items(kb_info_json, config_h_lines):
|
||||
|
||||
try:
|
||||
config_value = kb_info_json[info_key]
|
||||
except KeyError:
|
||||
except (KeyError, IndexError):
|
||||
continue
|
||||
|
||||
if key_type.startswith('array.array'):
|
||||
|
||||
@@ -31,7 +31,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
|
||||
|
||||
try:
|
||||
rules_value = kb_info_json[info_key]
|
||||
except KeyError:
|
||||
except (KeyError, IndexError):
|
||||
return None
|
||||
|
||||
if key_type in ['array', 'list']:
|
||||
|
||||
@@ -394,7 +394,6 @@ combo_t *overlaps(combo_t *combo1, combo_t *combo2) {
|
||||
while ((key2 = pgm_read_word(&combo2->keys[idx2])) != COMBO_END) {
|
||||
if (key1 == key2) {
|
||||
overlaps = true;
|
||||
break;
|
||||
}
|
||||
idx2 += 1;
|
||||
}
|
||||
|
||||
@@ -366,13 +366,13 @@ static bool try_activating_override(const uint16_t keycode, const uint8_t layer,
|
||||
schedule_deferred_register(mod_free_replacement);
|
||||
send_keyboard_report();
|
||||
} else {
|
||||
send_keyboard_report();
|
||||
// On macOS there seems to be a race condition when it comes to the keyboard report and consumer keycodes. It seems the OS may recognize a consumer keycode before an updated keyboard report, even if the keyboard report is actually sent before the consumer key. I assume it is some sort of race condition because it happens infrequently and very irregularly. Waiting for about at least 10ms between sending the keyboard report and sending the consumer code has shown to fix this.
|
||||
wait_ms(10);
|
||||
if (IS_BASIC_KEYCODE(mod_free_replacement)) {
|
||||
add_key(mod_free_replacement);
|
||||
} else {
|
||||
key_override_printf("NOT KEY 2\n");
|
||||
send_keyboard_report();
|
||||
// On macOS there seems to be a race condition when it comes to the keyboard report and consumer keycodes. It seems the OS may recognize a consumer keycode before an updated keyboard report, even if the keyboard report is actually sent before the consumer key. I assume it is some sort of race condition because it happens infrequently and very irregularly. Waiting for about at least 10ms between sending the keyboard report and sending the consumer code has shown to fix this.
|
||||
wait_ms(10);
|
||||
register_code(mod_free_replacement);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user