Compare commits

...

271 Commits

Author SHA1 Message Date
JIKEDINGZHI
ac399fa469
Merge 822516992d into 9e9b4acbde 2024-11-23 00:36:26 +00:00
QMK Bot
9e9b4acbde Merge remote-tracking branch 'origin/master' into develop 2024-11-21 18:47:10 +00:00
Joel Challis
57be487161
Fix rendering of reference_configurator_support.md (#24629) 2024-11-21 18:46:36 +00:00
Joel Challis
968a611476
Review fixes for layer lock feature (#24627) 2024-11-21 13:02:49 +00:00
Ryan
65a8a5ff69
qmk find: expand operator support (#24468) 2024-11-21 22:57:36 +11:00
Drashna Jaelre
c7a04bd930
Bring supported STM32F4 configs in line with F4x1 (#24413)
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
2024-11-21 22:54:01 +11:00
Drashna Jaelre
36b5559b99
[Core] Add Layer Lock feature (#23430)
Co-authored-by: Daniel <1767914+iamdanielv@users.noreply.github.com>
Co-authored-by: Pascal Getreuer <getreuer@google.com>
Co-authored-by: Pascal Getreuer <50221757+getreuer@users.noreply.github.com>
2024-11-21 17:31:54 +11:00
HorrorTroll
39161b9ee7
Added MCU support for ArteryTek AT32F415 (#23445) 2024-11-21 17:28:28 +11:00
QMK Bot
074bbbfb21 Merge remote-tracking branch 'origin/master' into develop 2024-11-21 06:22:51 +00:00
Ryan
638b22d057
qmk new-keyboard: separate dev board and MCU selection (#24548) 2024-11-21 17:22:14 +11:00
Ryan
9bea332a21
qmk via2json: Improve macro parsing (#24345) 2024-11-21 17:20:05 +11:00
Ryan
8cbcdcac62
qmk new-keymap: validate keymap name (#23420) 2024-11-21 17:18:51 +11:00
Pablo Martínez
88afd53b1f
[CLI] Refactor painter arguments to table instead of commandline (#24456)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-11-21 17:16:46 +11:00
Ryan
9c86583981
Backward compatibility for new RGB keycode handling (#24490)
Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
2024-11-20 09:53:33 +11:00
QMK Bot
e66fce38b2 Merge remote-tracking branch 'origin/master' into develop 2024-11-19 21:59:43 +00:00
Nick Brassel
c843ad1268
Add Sagittarius encoder support. (#24617) 2024-11-20 08:59:07 +11:00
QMK Bot
0853a8ea35 Merge remote-tracking branch 'origin/master' into develop 2024-11-19 20:38:13 +00:00
russell-myers1
0988523851
Fix typo in docs/api_development_overview.md (#24620) 2024-11-19 13:37:39 -07:00
QMK Bot
7936a791ed Merge remote-tracking branch 'origin/master' into develop 2024-11-17 15:06:31 +00:00
Amund Tenstad
3a6df60ba5
docs: fix RWIN alias (#24610) 2024-11-17 15:05:57 +00:00
QMK Bot
5ab408aef7 Merge remote-tracking branch 'origin/master' into develop 2024-11-17 07:16:16 +00:00
Naoki Katahira
da34d652d4
[Keyboard]Add Lily58 Lite Rev3(lily58/lite_rev3) (#24255)
* add Lily58 Lite Rev3 Firmware

* fix README

* Update README

* delete lite_rev3.h

* Update keyboards/lily58/lite_rev3/halconf.h

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/lily58/lite_rev3/config.h

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/lily58/lite_rev3/keyboard.json

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/lily58/lite_rev3/keyboard.json

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/lily58/lite_rev3/mcuconf.h

Co-authored-by: jack <jack@pngu.org>

* fix image url

* fix SERIAL_DRIVER definition

* fix VIA_ENABLE definition disable

* fix cols pin

* Update keyboards/lily58/lite_rev3/config.h

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/lily58/lite_rev3/keyboard.json

Co-authored-by: jack <jack@pngu.org>

* delete rules.mk

* Update README

* Update keyboards/lily58/lite_rev3/readme.md

---------

Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-11-17 00:15:45 -07:00
QMK Bot
310c4847d5 Merge remote-tracking branch 'origin/master' into develop 2024-11-15 18:16:23 +00:00
Amund Tenstad
f4e58eeff4
docs: move description of host_language from Macros to Language-specific Keycodes (#24584)
Co-authored-by: フィルターペーパー <76888457+filterpaper@users.noreply.github.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-11-15 11:15:48 -07:00
QMK Bot
79a661fe61 Merge remote-tracking branch 'origin/master' into develop 2024-11-14 18:00:36 +00:00
Ryan
46236ce3de
[docs] Improve halconf/mcuconf code examples (#24597) 2024-11-14 18:00:02 +00:00
Nick Brassel
0bda0f4775
Revert removal of QK_OUTPUT_AUTO, fixup docs to reflect. (#24593) 2024-11-14 21:16:52 +11:00
QMK Bot
f8b4e24d37 Merge remote-tracking branch 'origin/master' into develop 2024-11-14 09:43:56 +00:00
Nick Brassel
a8a47c4011
Perform test compiles during qmk doctor. (#24282)
Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
2024-11-14 20:43:23 +11:00
QMK Bot
d04789e9ea Merge remote-tracking branch 'origin/master' into develop 2024-11-13 04:29:48 +00:00
Druah
4757ef281f
[Keyboard] Add Majestouch Redux (#24586)
* [Keyboard] Add Majestouch Redux

* Apply suggestions from code review

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

---------

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-11-12 21:29:12 -07:00
QMK Bot
4e77ab66e2 Merge remote-tracking branch 'origin/master' into develop 2024-11-12 02:21:49 +00:00
Ryan
3d4da6de29
[docs] Add "edit this page" link at the bottom (#24585) 2024-11-12 02:20:56 +00:00
QMK Bot
be7b479c4a Merge remote-tracking branch 'origin/master' into develop 2024-11-12 02:20:13 +00:00
dependabot[bot]
9cd7896760
Bump JamesIves/github-pages-deploy-action from 4.6.8 to 4.6.9 (#24592)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.8 to 4.6.9.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.8...v4.6.9)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-12 02:18:51 +00:00
QMK Bot
291f1992d3 Merge remote-tracking branch 'origin/master' into develop 2024-11-10 19:12:22 +00:00
Duncan Sutherland
8cbd631fcb
remove "w": 1 from /keyboards/ (#24587) 2024-11-10 12:11:48 -07:00
Ryan
a3cfb1dab7
Joystick: add support for 8-way hat switch (#24515) 2024-11-09 14:10:10 -08:00
QMK Bot
69093f6de9 Merge remote-tracking branch 'origin/master' into develop 2024-11-09 19:04:48 +00:00
Ryan
3eb172d08e
[docs] Turn on icons for external links (#24580) 2024-11-09 12:04:14 -07:00
QMK Bot
a8fc265bf1 Merge remote-tracking branch 'origin/master' into develop 2024-11-09 16:49:43 +00:00
Ryan
b3f5408e72
[docs] Fix dead link to keyboard list in newbs.md (#24579) 2024-11-09 09:49:11 -07:00
QMK Bot
b06e9fdd95 Merge remote-tracking branch 'origin/master' into develop 2024-11-09 04:24:07 +00:00
Amund Tenstad
f156e57f8e
[Keyboard] Add tenstad (#24571)
* [Keyboard] Add tenstad

* fix: remove settings disabled by default

Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com>

* fix: add serial and transport to json

Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com>

* fix: format json

* docs: update img url

* fix: delete now-redundant rules.mk

* fix: format keymap.json (keeping 'layout' at the top)

---------

Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com>
2024-11-08 21:24:00 -07:00
Danny Tan
10849dac68
Add Fuyu HS (#24567)
* Add Fuyu HS

* Fix keyboard.json linting

* Fix rgbmatrix configuration

* Apply suggestions from code review

Co-authored-by: Joel Challis <git@zvecr.com>

---------

Co-authored-by: Joel Challis <git@zvecr.com>
2024-11-08 21:23:31 -07:00
QMK Bot
94b6039620 Merge remote-tracking branch 'origin/master' into develop 2024-11-09 04:22:23 +00:00
Danny Tan
fb3a414a40
Add Idyllic Pizza Pad (#24566)
* Initial PizzaPad firmware

* Updated files to conform to PR checklist

* Fix default keymap location

* Update keyboard.json

* Apply suggestions from code review

Co-authored-by: Joel Challis <git@zvecr.com>

* Update keyboards/idyllic/pizzapad/keymaps/default/keymap.c

Co-authored-by: jack <jack@pngu.org>

---------

Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <jack@pngu.org>
2024-11-08 21:21:52 -07:00
QMK Bot
fca6ad4ebc Merge remote-tracking branch 'origin/master' into develop 2024-11-08 09:10:10 +00:00
Akshay
e31eeb85db
added support for shorty KB (#24518)
* added support for shorty KB

Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-11-08 09:09:35 +00:00
Eric N. Vander Weele
9523ed9e32
Expose rgb_matrix_update_pwm_buffers to be available in keymaps (#24573)
* Expose rgb_matrix_update_pwm_buffers to be available in keymaps

Exposing this API enables the examples in the keyboard shutdown/reboot
documentation to compile instead of calling `rgb_matrix_driver.flush`
directly.

* Remove extraneous rgb_matrix_update_pwm_buffers prototype declarations

Now that `rgb_matrix_update_pwm_buffers` is public, there isn't the need
for local prototype declarations.
2024-11-07 23:12:59 -07:00
QMK Bot
b17322b9b8 Merge remote-tracking branch 'origin/master' into develop 2024-11-08 04:57:57 +00:00
Nick Brassel
580d18d2e9
Speed improvements to qmk find. (#24385) 2024-11-08 04:57:22 +00:00
QMK Bot
b10fa5032f Merge remote-tracking branch 'origin/master' into develop 2024-11-08 02:53:15 +00:00
HereVoLand
4f9ef90754
Add keyboard buff75 (#24297)
* Create herevoland

* Delete keyboards/herevoland

* Add files via upload

* Delete keyboards/herevoland/buff75 directory

* Add files via upload

* Delete keyboards/herevoland/buff75/buff75.h

* Delete keyboards/herevoland/buff75/rules.mk

* Delete keyboards/herevoland/buff75/halconf.h

* Update and rename info.json to keyboard.json

* Delete keyboards/herevoland/buff75/matrix_diagram.md

* Update readme.md

* Update readme.md

* Add files via upload

* Delete keyboards/herevoland/buff75/keymaps/via directory

* Update readme.md

* Update keymap.c

* Update matrix_diagram.md

* Update readme.md

* Update keyboard.json

* Update readme.md

* Update matrix_diagram.md

* Update keyboard.json

* Update keymap.c

* Update keymap.c

* Update keyboard.json

* Update mcuconf.h

* Delete keyboards/herevoland/buff75/mcuconf.h
2024-11-07 19:52:41 -07:00
QMK Bot
f2a7f4b804 Merge remote-tracking branch 'origin/master' into develop 2024-11-08 00:59:05 +00:00
Christian C. Berclaz
3cda9ffcd6
Adding support for Windstudio's Wind X R1 keyboard (#24564)
* Added a default firmware and layout for the WindStudio Wind X R1
keyboard.

* Wind X R1: cleaned-up the folders to make clear that this firmware is
for the release 1 of this keyboard.

* Added rules.mk to the default layout

* Renamed the folder R1 into r1.

* Added readme.md files for the keyboard and default layout.

* Added a license header to keymap.c

* Update keyboards/windstudio/wind_x/r1/keyboard.json

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/windstudio/wind_x/r1/keyboard.json

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/windstudio/wind_x/r1/keymaps/default/keymap.c

Co-authored-by: jack <jack@pngu.org>

* Update keyboards/windstudio/wind_x/r1/readme.md

Co-authored-by: jack <jack@pngu.org>

* Added a proper link to the image (logo of windstudio)

* Wind X R1
- Corrected the default keymap with the QK_GESC key instead of the
  KC_ESC.
- Removed the unnecessary rules.mk in the default layout

* Wind X R1:
applied `qmk format-json -i` on keyboard.json to conform with the
project formatt standards.

* Added a picture of the keyboard.

* Added a caption to the image.

---------

Co-authored-by: jack <jack@pngu.org>
2024-11-07 17:58:57 -07:00
Bennett Balogh
54860ed238
[Keyboard] Add Teton78 (#24562)
* Added Teton_78 qmk keyboard files

* Fixed a syntax issue

* Waffles suggested changes

* Read me updated

Used the Alpine65 reame to model off.

* Update keyboards/mountainmechdesigns/teton_78/keymaps/default/keymap.c

Co-authored-by: jack <jack@pngu.org>

* Accidental File

* Updated readme with missing info

* Update readme.md

* Update keyboards/mountainmechdesigns/teton_78/readme.md

Co-authored-by: Ryan <fauxpark@gmail.com>

* Update keyboards/mountainmechdesigns/teton_78/readme.md

Co-authored-by: Ryan <fauxpark@gmail.com>

* Update keyboards/mountainmechdesigns/teton_78/readme.md

Co-authored-by: Joel Challis <git@zvecr.com>

---------

Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
2024-11-07 17:58:33 -07:00
QMK Bot
83950c7dd9 Merge remote-tracking branch 'origin/master' into develop 2024-11-06 07:47:08 +00:00
Diego Andres Rabaioli
f4e6af2dbe
Adding SdraKb00 keyboard (#24552)
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-11-06 00:46:17 -07:00
QMK Bot
7877023b48 Merge remote-tracking branch 'origin/master' into develop 2024-11-06 07:45:57 +00:00
Michael Büchler
f5f11b7c79
Add keyboards/converter/thinkpad_t6x/rpi_pico (#23696) 2024-11-06 00:45:20 -07:00
QMK Bot
cfb870d219 Merge remote-tracking branch 'origin/master' into develop 2024-11-06 07:44:10 +00:00
takashicompany
6fbfd659ff
Add new keyboard "KLEC-02" (#24559)
Co-authored-by: jack <0x6a73@protonmail.com>
2024-11-06 00:43:35 -07:00
QMK Bot
81a6f3e641 Merge remote-tracking branch 'origin/master' into develop 2024-11-03 20:14:27 +00:00
takashicompany
c8cdee3e4e
[Keyboard] Add KLEC-01 (#24543) 2024-11-03 12:13:56 -08:00
Joel Challis
292e0af293
Bump minimum required Python version (#24554) 2024-10-31 23:21:20 +00:00
QMK Bot
f1f875063c Merge remote-tracking branch 'origin/master' into develop 2024-10-30 11:27:27 +00:00
Joel Challis
465cbc87de
Handle 'MILCInterface' object has no attribute 'log_level' error (#24549) 2024-10-30 11:26:53 +00:00
QMK Bot
834f88b0a3 Merge remote-tracking branch 'origin/master' into develop 2024-10-30 05:44:03 +00:00
Joel Challis
6693a30671
Remove appdirs from requirements.txt (#24550) 2024-10-30 05:43:31 +00:00
QMK Bot
114b3db96a Merge remote-tracking branch 'origin/master' into develop 2024-10-30 05:17:31 +00:00
Joel Challis
e6daffce46
Handle cli._subcommand.__name__ deprecation warning (#24533) 2024-10-30 05:16:59 +00:00
QMK Bot
b8dd09994a Merge remote-tracking branch 'origin/master' into develop 2024-10-29 15:56:59 +00:00
leyew
92afc8198a
[Keyboard] Add Singa Kohaku (#24309)
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-10-29 09:56:23 -06:00
Cipulot
2aa186873e
Cipulot Updates (#24539) 2024-10-28 19:54:05 +00:00
フィルターペーパー
06b7dce565
Refactor LED Breathing effect with runner (#24540) 2024-10-28 10:56:54 -07:00
QMK Bot
95406717e7 Merge remote-tracking branch 'origin/master' into develop 2024-10-28 07:00:26 +00:00
Thanh Son Tran
7c9e650b1c
[Keyboard] Add S6xty PCB (#24465)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Trần Thanh Sơn <son.tt1@teko.vn>
2024-10-27 23:59:54 -07:00
David Hoelscher
7630a80791
Change default ARM hardware PWM WS2812 tick frequency to 800kHz (#24508) 2024-10-27 23:29:43 -07:00
Nikolai Grigoriev
2c0cdcf7b2
Improve consistency of syntax within data/constants/keycodes (#24528) 2024-10-28 06:23:15 +00:00
フィルターペーパー
25fac5e737
Refactor Breathing effect with runner (#24535) 2024-10-27 23:20:38 -07:00
フィルターペーパー
dd7287bf4e
Update Jellybean Raindrops to respect LED range limits (#24534) 2024-10-27 23:20:14 -07:00
フィルターペーパー
d9fedce9b9
Update Pixel Rain to respect LED range limits (#24532) 2024-10-27 23:19:45 -07:00
QMK Bot
01f6fa7cd6 Merge remote-tracking branch 'origin/master' into develop 2024-10-28 05:51:14 +00:00
フィルターペーパー
644588baef
Refactor Riverflow matrix effect with runner (#24520)
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-10-27 22:51:01 -07:00
Guido Bartolucci
7005522176
Add madjax_macropad keyboard (#24524)
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-10-27 22:50:42 -07:00
Dasky
f5b495e06e
Move pointing device driver code (#24445)
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-10-25 18:11:51 +01:00
Dasky
5c85271e48
Add timer_save and _restore functions. (#23887)
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-10-25 18:10:17 +01:00
QMK Bot
f486605bab Merge remote-tracking branch 'origin/master' into develop 2024-10-25 05:36:38 +00:00
Felix Jen
32b6faaf35
Add Vanguard65 Keyboard (#24497)
* Initial commit

* update

* added two options for the slider

* comments

* added rounding for the lower end of the LED values

* moved folder, cleaned up code

* fixed layout def

* fioxed default layout

* Update keyboards/keebfront/vanguard65/config.h

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/readme.md

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/rules.mk

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: jack <0x6a73@protonmail.com>

* updated default keymap to have encoder map functionality

* Update keyboards/keebfront/vanguard65/rules.mk

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/config.h

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/keebfront/vanguard65/config.h

Co-authored-by: jack <0x6a73@protonmail.com>

* add encoder_update_kb

* Update keyboards/keebfront/vanguard65/vanguard65.c

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/keebfront/vanguard65/vanguard65.c

Co-authored-by: Drashna Jaelre <drashna@live.com>

* new qmk

* misc fixes

* Test

* Removed extraneous parts of hte rules.mk

* Remove extra layers in the keymap

* Revert "Remove extra layers in the keymap"

This reverts commit c82ee931ac.

* removed excess layers

* update for latest QMK led definition

* update

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/readme.md

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Delete vanguard65.c

* run qmk format_json

* Update keyboards/keebfront/vanguard65/rules.mk

Co-authored-by: Ryan <fauxpark@gmail.com>

* Update keyboards/keebfront/vanguard65/readme.md

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/readme.md

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/info.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/via/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>

* Update keyboards/keebfront/vanguard65/keymaps/default/keymap.c

Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>

* Confirm all keymaps compile

* update for latest QMK best definitions

* Apply suggestions from code review

Co-authored-by: jack <jack@pngu.org>

* Added minimum slider functionality.

* update readme

* Apply suggestions from code review

Co-authored-by: Joel Challis <git@zvecr.com>

* Update keyboards/keebfront/vanguard65/keyboard.json

Co-authored-by: jack <jack@pngu.org>

---------

Co-authored-by: jack <0x6a73@protonmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Joel Challis <git@zvecr.com>
2024-10-24 23:35:53 -06:00
QMK Bot
d00df05df1 Merge remote-tracking branch 'origin/master' into develop 2024-10-25 05:25:43 +00:00
era
bf327f7a81
[Keyboard] Add SIRIND Tomak79H (#24505)
* Add Tomak79H

Add Tomak79H

* Update

Update

* Update keyboards/era/sirind/tomak79h/tomak79h.c

Co-authored-by: Drashna Jaelre <drashna@live.com>

---------

Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-10-24 23:25:12 -06:00
QMK Bot
d316331ab1 Merge remote-tracking branch 'origin/master' into develop 2024-10-24 09:05:24 +00:00
Daniel Weeks
3b874ee434
[Keyboard] Add xdboards/recon keyboard (#24135)
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-10-24 02:04:51 -07:00
Ryan
bb9625ba55
RGBLight: Improve RGB Test animation (#24477) 2024-10-24 15:27:24 +11:00
QMK Bot
11db924a31 Merge remote-tracking branch 'origin/master' into develop 2024-10-23 02:14:47 +00:00
Danny
453ec007c1
Add Iris LM series of keyboards (#24510) 2024-10-22 22:14:12 -04:00
QMK Bot
b2608e3162 Merge remote-tracking branch 'origin/master' into develop 2024-10-21 21:38:44 +00:00
Jan Bláha
459de98222
Fix 6x13 default keymap (#24509)
Update keymap.c
2024-10-21 22:38:11 +01:00
Ramon Imbao
c6b2553470
Rename saevus to concreteflowers (#24249) 2024-10-19 13:25:30 +01:00
Drashna Jaelre
baa29fef9d
[Bug] Fix compiliation issues with OS Detection (#24502) 2024-10-19 12:24:42 +02:00
QMK Bot
22e6a8d15e Merge remote-tracking branch 'origin/master' into develop 2024-10-18 08:06:12 +00:00
Duncan Sutherland
7f22cb52e3
Correct layouts/default/readme.md (#23805)
Update readme.md

remove orphan layout
2024-10-18 19:04:29 +11:00
Stefan Kerkmann
3f9d464412
[Core] usb_device_state: consolidate usb state handling across implementations (#24258)
* usb_device_state: add idle_rate, led and protocol

Previously all usb drivers and platform implementations (expect for our
oddball atsam) tracked the same two global variables:

- keyboard_protocol: to indicate if we are in report or boot protocol
- keyboard_idle: for the idle_rate of the keyboard endpoint

And a local variable that was exposed trough some indirection:

- keyboard_led_state: for the currently set indicator leds (caps lock etc.)

These have all been moved into the usb_device_state struct wich is
accessible by getters and setters.

This reduces code duplication and centralizes the state management
across platforms and drivers.

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>

* usb_device_state: reset protocol on reset

The usb hid specification section 7.2.6 states:

When initialized, all devices default to report protocol. However the
host should not make any assumptions about the device’s state and should
set the desired protocol whenever initializing a device.

Thus on reset we should always do exactly that.

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>

* keyboards: fix oversize warnings

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>

---------

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
2024-10-18 09:57:08 +02:00
QMK Bot
80f8aae3ec Merge remote-tracking branch 'origin/master' into develop 2024-10-17 16:06:54 +00:00
David Doan
36008922f8
add vector macropad (#24487)
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-10-17 10:06:17 -06:00
QMK Bot
6602ee04af Merge remote-tracking branch 'origin/master' into develop 2024-10-16 16:17:06 +00:00
Alabahuy
2ad13037ab
[Keyboard] Add JK60 RGB (#24485) 2024-10-16 10:16:31 -06:00
QMK Bot
7e53bb9965 Merge remote-tracking branch 'origin/master' into develop 2024-10-15 14:06:17 +00:00
Ryan
85a7627641
Digitizer: fix units tag in report descriptor (#24482) 2024-10-15 07:05:43 -07:00
Joel Challis
13581820b8
horrortroll/nyx/rev1: Fix compilation of custom RGB effect (#24481) 2024-10-13 11:35:35 +11:00
Joel Challis
d0d170e6a0
xiudi/xd002: Remove broken oversized multilayer_rgb keymap (#24480) 2024-10-12 12:19:18 -07:00
Joel Challis
dd0068cfd4
keebio/nyquist: Remove invalid I2C config (#24479) 2024-10-12 12:18:23 -07:00
Ryan
9884e4982b
Rename RGB/HSV structs: keyboard-level code (#24476) 2024-10-12 19:00:56 +01:00
Stefan Kerkmann
5478051d74
[Core] quantum: util: add bit and bitmask helpers (#24229)
quantum: util: add bit and bitmask helpers

These helpers are handy and can prevent off-by-one errors when working
with registers and general low level bit manipulation tasks. The macros
themself are inspired by the bits.h macros from the linux kernel source
code.

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
Co-authored-by: Pascal Getreuer <50221757+getreuer@users.noreply.github.com>
2024-10-12 18:48:00 +02:00
Ryan
6fa11bf219
Separate RGBLight/RGB Matrix keycode handling (#23679)
* Separate RGBLight/RGB Matrix keycode handling

* Remove `_DISABLE_KEYCODES` handling

* Update RGB Matrix keycode docs

* Update underglow keycodes for previously migrated boards

* Update keycodes for boards with custom handling

* Fix typos

* Fix bad merge
2024-10-12 18:43:50 +02:00
QMK Bot
5c97a78ce6 Merge remote-tracking branch 'origin/master' into develop 2024-10-11 23:30:07 +00:00
Joel Challis
11daef82e0
zsa/moonlander: Fix execution of user callback (#24475) 2024-10-11 16:29:32 -07:00
Sadek Baroudi
9d17779832
Add svlinky converter (#24449) 2024-10-12 00:16:25 +01:00
フィルターペーパー
8844fba607
Update combo user function variable (#24467) 2024-10-12 00:13:31 +01:00
Ryan
6129af93f4
Rename RGB and HSV structs (#24471) 2024-10-12 00:10:02 +01:00
Joel Challis
a10e7cc858
Fix rendering of keymap_config.no_gui within led_update_kb (#24473) 2024-10-12 00:06:10 +01:00
Joel Challis
40d49ee487
Fix duplication of core GU_TOGG keycode (#24474) 2024-10-12 00:05:57 +01:00
QMK Bot
9246163b77 Merge remote-tracking branch 'origin/master' into develop 2024-10-11 15:49:32 +00:00
Ryan
c95f0fb671
mykeyclub/jris65/hotswap: fix keymap (#24472) 2024-10-11 09:48:59 -06:00
QMK Bot
049865c30c Merge remote-tracking branch 'origin/master' into develop 2024-10-11 03:31:45 +00:00
Woodrow Douglass
f0b5feb858
fix hotdox76v2 oled font to more closely mirror utf8 (#23807) 2024-10-10 20:31:08 -07:00
QMK Bot
eac4053a07 Merge remote-tracking branch 'origin/master' into develop 2024-10-11 03:28:29 +00:00
Joe Scotto
f43c9127bf
Add Scotto37 handwired keyboard (#23938)
Co-authored-by: Joel Challis <git@zvecr.com>
2024-10-10 20:27:56 -07:00
Victor
27d68ef8b9
Add Ploopyco functions for host state control (#23953) 2024-10-10 20:27:15 -07:00
QMK Bot
c8a87ff3fe Merge remote-tracking branch 'origin/master' into develop 2024-10-11 03:01:33 +00:00
azhizhinov
4055798807
[Keyboard] Add Piantor UV 44 (#24247)
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-10-10 20:01:00 -07:00
QMK Bot
29bc842fe2 Merge remote-tracking branch 'origin/master' into develop 2024-10-10 19:55:27 +00:00
Drashna Jaelre
49a1a12a32
Expand count checks in keymap introspection (#24464)
* Add check Tap Dance count check to keymap introspection

* Add checks for combos and key overrides to introspection
2024-10-11 06:54:53 +11:00
QMK Bot
00db6f2397 Merge remote-tracking branch 'origin/master' into develop 2024-10-09 04:31:06 +00:00
フィルターペーパー
fb598e7e61
Fixup Lily58 keymap comment (#24466) 2024-10-09 05:30:32 +01:00
QMK Bot
8cc6127668 Merge remote-tracking branch 'origin/master' into develop 2024-10-08 18:51:56 +00:00
yiancar
c0d57a6826
Fix indicator code for NK classics (#24462)
Fix indicator code

Co-authored-by: yiancar <yiancar@gmail.com>
2024-10-08 12:51:23 -06:00
Duncan Sutherland
c3ffbe4504
add ergodox Community Layout for LAYOUT_ergodox keyboards (#22963)
initial commit
2024-10-07 17:29:43 +13:00
QMK Bot
8c27ae8fd7 Merge remote-tracking branch 'origin/master' into develop 2024-10-07 04:29:33 +00:00
Álvaro A. Volpato
1a284f2b92
Fix Caps Lock indication on Valhalla v2 (#23012)
* Fix Caps Lock indication

* User LED state function override added

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Change backlight enabled check and remove backlight headers

Co-authored-by: Drashna Jaelre <drashna@live.com>

---------

Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-10-07 17:29:03 +13:00
QMK Bot
3a5be8bd22 Merge remote-tracking branch 'origin/master' into develop 2024-10-06 17:27:18 +00:00
Joel Challis
f25624dca4
Fix thumbsup:default keymap (#24459) 2024-10-06 18:26:48 +01:00
QMK Bot
a428727897 Merge remote-tracking branch 'origin/master' into develop 2024-10-06 17:02:01 +00:00
sizezero
035dcf213c
Add keyboard Jris65 (#23936)
* first compiled, flashed, and tested version of jris65

* adding readmes for mykeyclub and jris65

* removed commented out code and unneeded files

* typo in build instructions

* renamed info.json to keyboard.json as per new standard

* formatted with qmk format-json

* fixed layout offset problem

* moved some settings from c/h files to json

* moved matrix from .h file to .json

* cleaned up non-json options

* moved settings from rules.mk to keyboard.json

* fix for via after removing .h file

* converted keymap.c to keymap.json

* keymap.c has been replaced by keymap.json

* FN+Backspace loads bootload

* added custom keymap for Sean

* config.h setting is only needed by via

* formatted json

* convert via keymap from .c .h .mk to keymap.json

* moved keyboard configuration to hotswap dir; note in readme that only hotswap has been tested

* Update keyboards/mykeyclub/jris65/keymaps/default/keymap.json

Co-authored-by: jack <jack@pngu.org>

* typo

Co-authored-by: jack <jack@pngu.org>

* blank layers do not need to be specified

Co-authored-by: jack <jack@pngu.org>

* added other valid layouts

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* added other valid layouts

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* added other valid layouts

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* added other valid layouts

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* removed extra newline

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* cleaned up wording in readme

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* QMK no longer supports user keymaps

* remove settings that are already the default (false settings)

Co-authored-by: jack <jack@pngu.org>

* add image

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* add missing commas (formatting)

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* add missing commas (formatting)

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* add missing commas (formatting)

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

* re-added second layer with QK_BOOT for backspace

* make the hotswap the default keyboard

* added keyboard director prefix to DEFAULT_FOLDER

* ran qmk format-json on keyboard.json

* DEFAULT_FOLDER option is going away so don't use it

* removed via keymap as they now reside in qmk_userspace_via

---------

Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-10-06 11:01:30 -06:00
eynsai
2cb35373c6
Extended wheel reports (#24422)
extended wheel reports
2024-10-06 11:26:55 +02:00
QMK Bot
bf6de46d7f Merge remote-tracking branch 'origin/master' into develop 2024-10-06 09:09:10 +00:00
ak66666
7446c6ea7d
Added a new keyboard ThumbsUp! v9 with a default keymap (#23800)
* Added a cleaned-up set of files for ThumbsUp! v9.

* Renamed the keymap for v9 as default

* Update keyboards/thumbsup/keymaps/default/keymap.c

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/keymaps/default/keymap.c

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/keymaps/default/keymap.c

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/keymaps/default/keymap.c

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/keymaps/default/keymap.c

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/rev9_promicro_4x12/info.json

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/rev9_promicro_4x12/readme.md

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/rev9_promicro_4x12/readme.md

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/rev9_promicro_4x12/rules.mk

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Update keyboards/thumbsup/rev9_promicro_4x12/info.json

As per PR review suggestions.

Co-authored-by: jack <0x6a73@protonmail.com>

* Apply suggestions from code review

Co-authored-by: jack <0x6a73@protonmail.com>

* Delete keyboards/thumbsup/keymaps/default/readme.md as per review recommendation.

* v9: Fixed the layout name in keymap.c file.

* v9: PR recommendatios applied - rules.mk file removed, info.json renamed to keyboard.json.

* v9: PR recommendatios applied - rules.mk file removed, info.json renamed to keyboard.json.

* v9: Fixed the copyright header modified by mistake.

* v9: Fixed the tri-layer switch as per the review recommendation.

* v9: Fixed the copyright header modified by mistake.

---------

Co-authored-by: jack <0x6a73@protonmail.com>
2024-10-06 22:08:18 +13:00
Drashna Jaelre
c9cd92ece3
[Keyboard] Corne rev4 (#24084)
* [Keyboard] Corne rev4

* Remove unneeded update interval and moved split pin to dd

* Cleanup config and errors

* Move bootmagic config to dd

* Re-add existing configs

* Additional config fixes

* shove off via keymap
2024-10-06 22:05:10 +13:00
QMK Bot
ddfb8765ec Merge remote-tracking branch 'origin/master' into develop 2024-10-06 09:01:57 +00:00
Robin Haberkorn
ff21363627
ibm/model_m/modelh: added ISO layout and keymap for Wheelwriter 10/15 keyboard modules (#24248)
These are probably compatible with the Wheelwriter 1000 as well.
2024-10-06 22:01:20 +13:00
QMK Bot
d381bb7258 Merge remote-tracking branch 'origin/master' into develop 2024-10-06 08:57:52 +00:00
Steven Karrmann
c2dd0c1845
Update Janus keyboard firmware to use EE_HANDS (#24261)
* Use EE_HANDS https://docs.qmk.fm/features/split_keyboard#handedness-by-eeprom

* Update Janus readme to indicate EEPROM handedness is used
2024-10-06 21:52:56 +13:00
QMK Bot
50e54d8e1a Merge remote-tracking branch 'origin/master' into develop 2024-10-06 08:52:12 +00:00
rahanahu
13a87ad354
hotdox76v2: Update g_led_config.matrix_co to fix key electrical matrix to led index lookup table. (#24293)
update g_led_config on hotdox76v2/hotdox76v2.c

Co-authored-by: rahanahu <ra87who@gmail.com>
2024-10-06 21:51:06 +13:00
Andre Brait
7f475b590a
Tweak OS detect, add OS_DETECTION_SINGLE_REPORT (#24379)
* Default OS_DETECTION_DEBOUNCE bumped from 200ms to 250ms
* Add OS_DETECTION_SINGLE_REPORT to prevent undesired multiple reports
* Prevents random stability issues on ARM MacBooks after switching via KVM
* Works for every device I could test, including ARM MacBooks
* Disabled by default to keep current behavior
* Add Troubleshooting section on documentation
* Tweak reset logic to prevent a freeze with some KVMs

The USB stack on ARM MacBooks is more similar to that of iOS and,
for some reason, it seems to like sending packets that influence
the OS detection and results in a second OS_MACOS report being sent
at a random period of time after plugging the keyboard back. This
does not always happen and the consequences of this vary based on
what the user is doing in the callback, but since this is not
obvious and it's hard to debug, I've decided to add a flag for
those affected by such issue. The stability issue I had in mine was
a combination of factors and I found the actual cause being my own
bad math when changing the default layer, but this change alone is
also confirmed to fix it. Lastly, soem KVMs seem to leave the USB
controlled in a suspended state when cold-booting Windows, meaning
the keyboard would hang and the reset logic would not work. This
tunes it so that it can get out of such state. Also retested for
compatibility with my old KVM to ensure the logic works for both.
2024-10-06 21:50:39 +13:00
durken1
a322107cb7
add USART configuration to config.h for PS/2 mouse support (#24398) 2024-10-06 21:47:15 +13:00
Nick Brassel
305e7baa71
Allow for get_hardware_id() to be used for serial number. (#24053)
* Allow for `get_hardware_id()` to be used for serial number.

* Length checks.

* Explain length.

* Cleanup.

* Preprocessor magic.

* Use the force, Batman.

* Swap logic; if SERIAL_NUMBER is defined use that, otherwise derive it.

* Cleanup.

* Cleanup.
2024-10-06 21:44:36 +13:00
QMK Bot
65b5dc7e0f Merge remote-tracking branch 'origin/master' into develop 2024-10-06 08:40:06 +00:00
Nick Brassel
c82f675266
Install dnf copr plugin if not present (i.e. docker containers). (#24308)
* Install `dnf copr` plugin if not present (i.e. docker containers).

* Don't need to skip prompt when invoking help.
2024-10-06 21:39:37 +13:00
Andre Brait
3cf94cb308
Add easier way to set default single layer (#24376)
* Add set_single_default_layer to match set_single_persistent_default_layer
* Implements exactly the same behavior, except the write to EEPROM
2024-10-06 21:39:21 +13:00
Ryan
208ebf54a9
WS2812 API rework (#24364)
* Begin WS2812 API rework

* Move RGBW conversion, clean up color.h, fix RGBW for AVR bitbang

* Formatting & update PS2AVRGB I2C driver (untested)

* Tested ARM bitbang RGB+RGBW

* Tested ARM SPI RGB - RGBW not working

* Tested ARM PWM RGB+RGBW

* Tested RP2040 PIO driver RGB+RGBW

* Update RGBLight

* Formatting

* Fix BM60HSRGB rev2

* Fix oddforge/vea

* Fix 1k and XD002 RGBLite

* Fix model_m/mschwingen

* Fix handwired/promethium

* Rename `WS2812_LED_TOTAL` for BM60HSRGB

* Fix work_louder boards

* Fix dawn60

* Fix rgbkb/pan

* Fix neson_design/700e and n6

* Fix ergodox_ez/shine

* ergodox_ez/shine: invert indices for left half

* Fix matrix/abelx

* Fix matrix/m20add

* Remove custom rgblight driver for matrix/noah - should be done with lighting layers

* Fix LED indexes for RGBLight split

* Rename `convert_rgb_to_rgbw()` to `ws2812_rgb_to_rgbw()`

* Update WS2812 API docs

* `ergodox_ez/shine`: simplify LED index calculation

* LED/RGB Matrix: Add weak function for LED index resolution

* Bandaid fix for RGB Matrix splits not using WS2812

* `steelseries/prime_plus`: redo custom RGBLight driver

* Update keyboards/steelseries/prime_plus/rgblight_custom.c

Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>

---------

Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
2024-10-06 21:01:07 +13:00
Dasky
43e82ed5c7
Remove binary blobs from optical sensors. (#24428)
* remove pmw srom

* remove adns9800 srom

* Update drivers/sensors/pmw33xx_common.c
2024-10-06 20:41:55 +13:00
QMK Bot
3d8cebb1a0 Merge remote-tracking branch 'origin/master' into develop 2024-10-05 16:16:55 +00:00
yiancar
e12c1fefdf
NK Classic TKL ISO (#24434)
* initial_commit

* fix keymap

* Update keyboards/novelkeys/nk_classic_tkl_iso/keyboard.json

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>

---------

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-10-05 10:16:25 -06:00
QMK Bot
4bb3741288 Merge remote-tracking branch 'origin/master' into develop 2024-10-03 00:29:10 +00:00
anubhav dhiman
6a73c8299b
Add atset AT2 keyboard (#24099)
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: zvecr <git@zvecr.com>
2024-10-02 17:28:41 -07:00
QMK Bot
04c5deb503 Merge remote-tracking branch 'origin/master' into develop 2024-10-03 00:28:08 +00:00
DOIO2022
6374bad540
Add KB09-01 keyboard (#24044)
Co-authored-by: jack <jack@pngu.org>
2024-10-02 17:27:36 -07:00
QMK Bot
a1597e7292 Merge remote-tracking branch 'origin/master' into develop 2024-09-30 19:31:35 +00:00
dependabot[bot]
b78118b2dd
Bump JamesIves/github-pages-deploy-action from 4.6.4 to 4.6.8 (#24453)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.4 to 4.6.8.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.4...v4.6.8)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 20:31:03 +01:00
QMK Bot
62367b2133 Merge remote-tracking branch 'origin/master' into develop 2024-09-30 00:23:53 +00:00
Pham Duc Minh
015cd23616
[Keyboard] Add DE80 PCB (#24439) 2024-09-30 01:23:21 +01:00
QMK Bot
e31ef83495 Merge remote-tracking branch 'origin/master' into develop 2024-09-29 23:27:00 +00:00
Ryan
f18a699393
[docs] reference_info_json: add type hints (#24443) 2024-09-30 00:26:31 +01:00
QMK Bot
1118821178 Merge remote-tracking branch 'origin/master' into develop 2024-09-28 00:58:56 +00:00
Joel Challis
4d6337539d
Revert "Bump JamesIves/github-pages-deploy-action from 4.6.4 to 4.6.6" (#24450)
Revert "Bump JamesIves/github-pages-deploy-action from 4.6.4 to 4.6.6 (#24446)"

This reverts commit 17fac880bf.
2024-09-28 01:58:22 +01:00
QMK Bot
c7fec10bd7 Merge remote-tracking branch 'origin/master' into develop 2024-09-27 19:39:02 +00:00
dependabot[bot]
17fac880bf
Bump JamesIves/github-pages-deploy-action from 4.6.4 to 4.6.6 (#24446)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.4 to 4.6.6.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.4...v4.6.6)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-27 20:38:32 +01:00
QMK Bot
928b5fdf50 Merge remote-tracking branch 'origin/master' into develop 2024-09-26 18:44:11 +00:00
Eric
805cde674d
input_club/ergodox_infinity ST7565 call spi_stop (#24429) 2024-09-26 11:43:39 -07:00
QMK Bot
81895940e6 Merge remote-tracking branch 'origin/master' into develop 2024-09-25 19:25:35 +00:00
nopunin10did
f7393a5ab8
Fix jabberwocky key coordinates in QMK Configurator (#24435) 2024-09-25 20:25:03 +01:00
Nick Brassel
9a8f5a80e4
Remove RING_BUFFERED_6KRO_REPORT_ENABLE due to disuse. (#24433) 2024-09-24 12:53:55 +01:00
Joel Challis
a7486a8d87
Remove STM32_PWM_USE_ADVANCED references (#24432) 2024-09-24 21:04:15 +10:00
QMK Bot
c622e1439c Merge remote-tracking branch 'origin/master' into develop 2024-09-24 08:55:52 +00:00
dependabot[bot]
93cc3f58b1
Bump rollup from 4.16.4 to 4.22.4 in /builddefs/docsgen (#24430)
Bumps [rollup](https://github.com/rollup/rollup) from 4.16.4 to 4.22.4.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.16.4...v4.22.4)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 09:55:18 +01:00
QMK Bot
5da5b179d5 Merge remote-tracking branch 'origin/master' into develop 2024-09-21 18:49:05 +00:00
pancho horrillo
6a536d5588
.editorconfig: fix inline comment, tidy name section for yaml (#24416) 2024-09-21 19:48:31 +01:00
QMK Bot
a0bce36aa1 Merge remote-tracking branch 'origin/master' into develop 2024-09-21 17:34:27 +00:00
studiokestra
4665d9c405
[Keyboard] Add Fairholme PCB (#24400)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-09-21 10:29:12 -07:00
QMK Bot
bda3300bb3 Merge remote-tracking branch 'origin/master' into develop 2024-09-21 17:25:09 +00:00
Joe Scotto
2e86b05cab
Add Scotto69 (PCB Edition) (#24402)
Co-authored-by: Joel Challis <git@zvecr.com>
2024-09-21 10:24:38 -07:00
Dasky
90b87abb11
Add SteelSeries Prime+ mouse (#24408)
Co-authored-by: Joel Challis <git@zvecr.com>
2024-09-20 15:17:49 +10:00
QMK Bot
9cbb4a2c4c Merge remote-tracking branch 'origin/master' into develop 2024-09-20 01:29:28 +00:00
plodah
61778f6136
Fix a_jazz/akc084 render (#24411)
* Alter ZXC row to have y index of 4 and bottom row to have index of 5

* Fix other issues with `]}`,  `'"` & Enter - pointed out by noroadsleft
2024-09-19 18:28:57 -07:00
QMK Bot
17be3e4a54 Merge remote-tracking branch 'origin/master' into develop 2024-09-18 14:46:48 +00:00
Dasky
1c03574424
Fix ADNS-9800 read (#24406) 2024-09-18 15:46:13 +01:00
Dasky
49e339ba8d
Add LD7032 support to QP. (#20828)
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
2024-09-18 21:44:33 +10:00
QMK Bot
7983f7409b Merge remote-tracking branch 'origin/master' into develop 2024-09-18 09:07:31 +00:00
kbladewht
42f1763db9
Workaround for broken STM32L433 startup (#24404)
Change STM32L433 LSI to False, this is to fix board startup issue , change is same to stm32L432 board
2024-09-18 19:06:50 +10:00
QMK Bot
a93144834c Merge remote-tracking branch 'origin/master' into develop 2024-09-18 08:57:18 +00:00
dependabot[bot]
e7c009c142
Bump vite from 5.2.10 to 5.2.14 in /builddefs/docsgen (#24403)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.2.10 to 5.2.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.2.14/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.2.14/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-18 09:56:46 +01:00
Ryan
e84104fe8d
Reinstate global k_rgb_matrix_split (#24388) 2024-09-15 10:08:29 +10:00
QMK Bot
d48aac6a2c Merge remote-tracking branch 'origin/master' into develop 2024-09-14 22:09:32 +00:00
jack
aa05fa649f
Update PR template (#24397)
Initial
2024-09-14 16:09:01 -06:00
QMK Bot
64f533fa47 Merge remote-tracking branch 'origin/master' into develop 2024-09-13 20:53:01 +00:00
Sergey Vlasov
0b3ece1189
qmk find: Fix handling of keys with dots in filter functions (#24393) 2024-09-14 06:52:31 +10:00
nopunin10did
ae4ab5ed31
[Keyboard] Styrka Atmel Custom PCB (#24380)
* Workaround for broken ChibiOS startup (#23822)

* Add personal keymap JSON

* Delete viktus_styrka_nopunin10did_20240529.json

* Add custom Styrka Atmel firmware

* Styrka Atmel fixes to compile and readme

* Remove VIA keymap

* Remove user keymap and edit readme

---------

Co-authored-by: Joel Challis <git@zvecr.com>
2024-09-12 22:58:02 -06:00
QMK Bot
ccae6e596a Merge remote-tracking branch 'origin/master' into develop 2024-09-12 17:31:02 +00:00
Ryan
0c19eae916
4pplet/waffling80/rev_b_ansi: fix missing keyboard.json (#24390) 2024-09-12 18:30:28 +01:00
QMK Bot
12dae4b9b7 Merge remote-tracking branch 'origin/master' into develop 2024-09-11 05:44:07 +00:00
nonameCCC
b7729fa019
[Keyboard] Add Support for PH-AC Rhythm Game Controller (#24368)
* [Keyboard] Add PHDesign PH-AC Rhythm Game Contoller

Co-authored by alt-0191

* Detail Improvement

* Update keyboard.json

* Update readme.md

* Update readme.md

* Created Encoder Matrix

* Posted Images

* Suggested Changes

* Update keyboard.json

* Update readme.md

* Update keyboard.json

* Update readme.md
2024-09-10 23:43:36 -06:00
Dasky
2c7bf34d09
Allow for inverted SPI CS logic (#23699) 2024-09-10 08:44:35 +10:00
QMK Bot
3aaa086ac8 Merge remote-tracking branch 'origin/master' into develop 2024-09-08 18:20:09 +00:00
Cipulot
e0788d19d4
Update EC60X LED count (#24374)
Update keyboard.json
2024-09-08 12:19:39 -06:00
QMK Bot
a4c286bb34 Merge remote-tracking branch 'origin/master' into develop 2024-09-06 16:31:28 +00:00
jack
f043545144
[Docs] Remove references to bootmagic lite (#24369) 2024-09-06 17:30:54 +01:00
QMK Bot
46d2e15b1f Merge remote-tracking branch 'origin/master' into develop 2024-09-06 15:00:21 +00:00
Duncan Sutherland
c44f5375ab
Correct 2u backspace matrix co-ordinate for Fave65s (#24353) 2024-09-06 07:59:39 -07:00
QMK Bot
4691b72bd5 Merge remote-tracking branch 'origin/master' into develop 2024-09-06 14:42:53 +00:00
jack
6d4f8d8963
[Keyboard] Add Klor (#24302) 2024-09-06 07:42:22 -07:00
QMK Bot
a42652f8e7 Merge remote-tracking branch 'origin/master' into develop 2024-09-06 06:35:56 +00:00
4pplet
75848477fb
Add waffling80 hotswap PCB (#23551)
Co-authored-by: jack <0x6a73@protonmail.com>
2024-09-05 23:35:26 -07:00
Filios92
0fd9909657
Add combo key repress feature (#22858)
Co-authored-by: jack <jack@pngu.org>
2024-09-05 23:27:20 -07:00
Mega Mind
b5c807fb4a
Refactor F4 ld files to use common files (#18059) 2024-09-05 23:24:14 -07:00
QMK Bot
6af8d4210c Merge remote-tracking branch 'origin/master' into develop 2024-09-05 22:47:01 +00:00
Ryan
4a6ba1e808
Fix RGBW for WS2812 SPI driver (#24367) 2024-09-05 23:46:29 +01:00
QMK Bot
59ac1a08c8 Merge remote-tracking branch 'origin/master' into develop 2024-09-05 21:28:06 +00:00
Perry Wang
e83a36dfbf
Fixes renaming typo of uno/rev2 json back to keyboard.json (#24366)
Rename keyboard.jsono to keyboard.json
2024-09-06 07:27:35 +10:00
Ryan
c3632dce99
Remove 60_tsangan_hhkb community layout (#24355) 2024-09-05 15:21:45 +10:00
QMK Bot
deb1dcf6c7 Merge remote-tracking branch 'origin/master' into develop 2024-09-04 02:57:49 +00:00
dependabot[bot]
2b55e43e54
Bump peter-evans/create-pull-request from 6 to 7 (#24361)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-04 03:57:19 +01:00
QMK Bot
a7ed82b39b Merge remote-tracking branch 'origin/master' into develop 2024-09-02 19:46:32 +00:00
dependabot[bot]
ef3a939880
Bump JamesIves/github-pages-deploy-action from 4.6.3 to 4.6.4 (#24358)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.3 to 4.6.4.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.3...v4.6.4)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 20:46:02 +01:00
Joel Challis
3bd303f204
Remove arm_atsam platform (#24337) 2024-09-02 03:48:17 +01:00
QMK Bot
096aca63c5 Merge remote-tracking branch 'origin/master' into develop 2024-09-01 23:13:58 +00:00
Ryan
28b6a8841f
Add 60_ansi_tsangan_split_bs_rshift to community layouts (#24186) 2024-09-02 09:13:28 +10:00
Stefan Kerkmann
d210590d4d
[Maintenance] builddefs: common_rules: overhaul debug information generation (#24352)
builddefs: common_rules: overhaul debug information generation

Debug information is always generated while compiling a binary, but
debugging is not the main use-case for the majority of users. Thus the
new default is to explicitly require them with `DEBUG_ENABLE=yes`. The
same is true for linker map files which are gated by the same flag.

As we target the gcc compiler and debug with the gdb debugger we can
specify the ggdb3 flag in the most verbose to get macro expansion.

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
2024-09-01 19:54:53 +02:00
QMK Bot
07535aa2c0 Merge remote-tracking branch 'origin/master' into develop 2024-09-01 16:59:52 +00:00
Stefan Otte
884a808813
doc: "docker getting started" mentions flash limitations (#24336)
* doc: "docker getting started" mentions `flash` limitations

Mass storage bootloader don't work with `flash` target.

* Update docs/getting_started_docker.md

Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>

---------

Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
2024-09-01 10:59:21 -06:00
Stefan Kerkmann
784786c00c
[Core] util: uf2families: sync with upstream (#24351)
util: uf2families: sync with upstream

The upstream revision is:
5b9299df61/utils/uf2families.json

Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
2024-09-01 15:57:41 +01:00
QMK Bot
9985f5950d Merge remote-tracking branch 'origin/master' into develop 2024-09-01 03:47:16 +00:00
Duncan Sutherland
fba0408cb3
Add matrix diagram for EC 60X (#24045)
* add matrix_diagram.md

* Update matrix_diagram.md

* Update matrix_diagram.md

* Update matrix_diagram.md

* unix line endings
2024-08-31 21:46:47 -06:00
Thomas Weißschuh
9df36b25da
Remove global k_rgb_matrix_split (#24348)
All users have their own local definition.
2024-08-31 21:45:49 -06:00
QMK Bot
481e6f6440 Merge remote-tracking branch 'origin/master' into develop 2024-08-31 03:49:41 +00:00
Joe Scotto
16a811604b
[Keyboard] Add ScottoHazard (#24181)
* Add ScottoHazard

* Update to proper layout

* Add header license

* Update keyboards/handwired/scottokeebs/scottohazard/config.h

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Update keyboards/handwired/scottokeebs/scottohazard/keyboard.json

Co-authored-by: Drashna Jaelre <drashna@live.com>

* Delete keyboards/handwired/scottokeebs/scottohazard/rules.mk

---------

Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-08-30 21:46:38 -06:00
QMK Bot
81109100a9 Merge remote-tracking branch 'origin/master' into develop 2024-08-31 03:44:35 +00:00
Armin Anderson
d7e1eb3e48
[Docs] Update joystick.md (#23928)
Explicit note about compatibility with ARM boards and the ADC driver
2024-08-30 21:44:03 -06:00
Duncan Sutherland
dae5e9ee06
Cutie Club Fidelity Layout Additions (#23838)
* expand layout selection for fidelity

* remove VIA

* format-json
2024-08-30 17:10:28 -06:00
QMK Bot
99e491f8b5 Merge remote-tracking branch 'origin/master' into develop 2024-08-30 02:57:36 +00:00
fenggx-a-jazz
0da9bd2709
Add a-jazz akc084 keyboard (#24224)
Co-authored-by: jack <jack@pngu.org>
2024-08-29 19:57:06 -07:00
QMK Bot
0b6b4c23d2 Merge remote-tracking branch 'origin/master' into develop 2024-08-30 02:22:23 +00:00
jack
d4811c19b0
Fix wrong OLED code for a few keyboards (#24344)
* Initial

* Other keyboards too
2024-08-29 20:21:53 -06:00
QMK Bot
6644f41e91 Merge remote-tracking branch 'origin/master' into develop 2024-08-30 02:20:35 +00:00
Ryan
496f448090
Fix two firmware size warnings (#24343) 2024-08-29 20:20:05 -06:00
QMK Bot
141214122d Merge remote-tracking branch 'origin/master' into develop 2024-08-30 01:56:58 +00:00
Antoine Bertin
d95690d89c
[Keyboard] Fix splitkb/corne OLED code (#24260) 2024-08-29 19:56:25 -06:00
QMK Bot
425a4b7c57 Merge remote-tracking branch 'origin/master' into develop 2024-08-28 14:53:11 +00:00
leyew
fd65bd5ae0
[Keyboard] Add Acid and Co. Stellaron TKL (#24154) 2024-08-28 15:52:02 +01:00
QMK Bot
a5d4ed98fd Merge remote-tracking branch 'origin/master' into develop 2024-08-28 14:39:11 +00:00
Thanh Son Tran
4b1f916b99
[Keyboard] Add Tyson60s keyboard (#24047) 2024-08-28 15:38:37 +01:00
Nick Brassel
60308a2c0f
These should really have been 0.0.6. 2024-08-27 10:55:32 +10:00
Nick Brassel
70cbf08b67
Add new connection keycodes for Bluetooth, 2.4GHz. (#24251) 2024-08-27 10:52:23 +10:00
QMK Bot
ecf725b356 Merge remote-tracking branch 'origin/master' into develop 2024-08-26 22:06:15 +00:00
Nick Brassel
0f43486537
Changelog update with actual qmk_userspace_via link. (#24332) 2024-08-26 23:05:45 +01:00
QMK Bot
4b7de2ba5d Merge remote-tracking branch 'origin/master' into develop 2024-08-26 21:28:57 +00:00
Joel Challis
530e044762
Update PR Checklist for 'via' keymaps (#24330) 2024-08-27 07:28:23 +10:00
Colin Kinloch
cc3bc2af11
Add ability to poweroff ADNS5050 sensor (#24223)
* Add ability to poweroff ADNS5050 sensor

* ploopyco/trackball_nano: Poweroff ADNS5050 on suspend
2024-08-26 14:06:53 -06:00
QMK Bot
df5800b6c4 Merge remote-tracking branch 'origin/master' into develop 2024-08-26 11:59:18 +00:00
zlabkeeb
8b42e5fb8f
[Keyboard] Add Macropad VRYNBOARD (#23931)
Co-authored-by: jack <0x6a73@protonmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <jack@pngu.org>
Co-authored-by: ZahraNetMe <vericheri@gmail.com>
2024-08-26 21:58:48 +10:00
1385 changed files with 26265 additions and 81847 deletions

View File

@ -11,7 +11,8 @@ charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[{*.yaml,*.yml}] # To match GitHub Actions formatting # To match GitHub Actions formatting
[*.{yaml,yml}]
indent_size = 2 indent_size = 2
[*.md] [*.md]

View File

@ -1,6 +1,5 @@
<!--- Provide a general summary of your changes in the title above. --> <!--- Provide a general summary of your changes in the title above. -->
<!--- This template is entirely optional and can be removed, but is here to help both you and us. -->
<!--- Anything on lines wrapped in comments like these will not show up in the final text. --> <!--- Anything on lines wrapped in comments like these will not show up in the final text. -->
## Description ## Description
@ -15,7 +14,7 @@
- [ ] New feature - [ ] New feature
- [ ] Enhancement/optimization - [ ] Enhancement/optimization
- [ ] Keyboard (addition or update) - [ ] Keyboard (addition or update)
- [ ] Keymap/layout/userspace (addition or update) - [ ] Keymap/layout (addition or update)
- [ ] Documentation - [ ] Documentation
## Issues Fixed or Closed by This PR ## Issues Fixed or Closed by This PR

View File

@ -56,7 +56,7 @@ jobs:
- name: Deploy - name: Deploy
if: ${{ github.event_name == 'push' && github.repository == 'qmk/qmk_firmware' }} if: ${{ github.event_name == 'push' && github.repository == 'qmk/qmk_firmware' }}
uses: JamesIves/github-pages-deploy-action@v4.6.3 uses: JamesIves/github-pages-deploy-action@v4.6.9
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages branch: gh-pages

View File

@ -47,7 +47,7 @@ jobs:
git config user.email 'hello@qmk.fm' git config user.email 'hello@qmk.fm'
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v6 uses: peter-evans/create-pull-request@v7
if: ${{ github.repository == 'qmk/qmk_firmware'}} if: ${{ github.repository == 'qmk/qmk_firmware'}}
with: with:
token: ${{ secrets.QMK_BOT_TOKEN }} token: ${{ secrets.QMK_BOT_TOKEN }}

View File

@ -34,7 +34,7 @@ jobs:
git config user.email 'hello@qmk.fm' git config user.email 'hello@qmk.fm'
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v6 uses: peter-evans/create-pull-request@v7
if: ${{ github.repository == 'qmk/qmk_firmware'}} if: ${{ github.repository == 'qmk/qmk_firmware'}}
with: with:
token: ${{ secrets.QMK_BOT_TOKEN }} token: ${{ secrets.QMK_BOT_TOKEN }}

View File

@ -145,7 +145,7 @@ FILE_PATTERNS = *.c \
RECURSIVE = YES RECURSIVE = YES
EXCLUDE = EXCLUDE =
EXCLUDE_SYMLINKS = NO EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */protocol/arm_atsam/* EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS = EXCLUDE_SYMBOLS =
EXAMPLE_PATH = EXAMPLE_PATH =
EXAMPLE_PATTERNS = * EXAMPLE_PATTERNS = *

View File

@ -129,13 +129,13 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
MOUSE_ENABLE := yes MOUSE_ENABLE := yes
VPATH += $(QUANTUM_DIR)/pointing_device VPATH += $(QUANTUM_DIR)/pointing_device
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device.c SRC += $(QUANTUM_DIR)/pointing_device/pointing_device.c
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_drivers.c
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_auto_mouse.c SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_auto_mouse.c
ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom) ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom)
SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]')) OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]'))
endif endif
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(POINTING_DEVICE_DRIVER)) OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(POINTING_DEVICE_DRIVER))
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_NAME=$(strip $(POINTING_DEVICE_DRIVER))
ifeq ($(strip $(POINTING_DEVICE_DRIVER)), adns9800) ifeq ($(strip $(POINTING_DEVICE_DRIVER)), adns9800)
SPI_DRIVER_REQUIRED = yes SPI_DRIVER_REQUIRED = yes
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), analog_joystick) else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), analog_joystick)
@ -215,7 +215,7 @@ else
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
COMMON_VPATH += $(DRIVER_PATH)/flash COMMON_VPATH += $(DRIVER_PATH)/flash
SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx GD32VF103),) else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx AT32F415 GD32VF103),)
# Wear-leveling EEPROM implementation, backed by MCU flash # Wear-leveling EEPROM implementation, backed by MCU flash
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
SRC += eeprom_driver.c eeprom_wear_leveling.c SRC += eeprom_driver.c eeprom_wear_leveling.c
@ -238,10 +238,6 @@ else
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
SRC += eeprom_driver.c eeprom_transient.c SRC += eeprom_driver.c eeprom_transient.c
endif endif
else ifeq ($(PLATFORM),ARM_ATSAM)
# arm_atsam EEPROM
OPT_DEFS += -DEEPROM_SAMD
SRC += eeprom_samd.c
else ifeq ($(PLATFORM),TEST) else ifeq ($(PLATFORM),TEST)
# Test harness "EEPROM" # Test harness "EEPROM"
OPT_DEFS += -DEEPROM_TEST_HARNESS OPT_DEFS += -DEEPROM_TEST_HARNESS
@ -310,11 +306,11 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h
OPT_DEFS += -DRGBLIGHT_ENABLE OPT_DEFS += -DRGBLIGHT_ENABLE
OPT_DEFS += -DRGBLIGHT_$(strip $(shell echo $(RGBLIGHT_DRIVER) | tr '[:lower:]' '[:upper:]')) OPT_DEFS += -DRGBLIGHT_$(strip $(shell echo $(RGBLIGHT_DRIVER) | tr '[:lower:]' '[:upper:]'))
SRC += $(QUANTUM_DIR)/process_keycode/process_underglow.c
SRC += $(QUANTUM_DIR)/color.c SRC += $(QUANTUM_DIR)/color.c
SRC += $(QUANTUM_DIR)/rgblight/rgblight.c SRC += $(QUANTUM_DIR)/rgblight/rgblight.c
SRC += $(QUANTUM_DIR)/rgblight/rgblight_drivers.c SRC += $(QUANTUM_DIR)/rgblight/rgblight_drivers.c
CIE1931_CURVE := yes CIE1931_CURVE := yes
RGB_KEYCODES_ENABLE := yes
endif endif
ifeq ($(strip $(RGBLIGHT_DRIVER)), ws2812) ifeq ($(strip $(RGBLIGHT_DRIVER)), ws2812)
@ -460,12 +456,16 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations
COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations/runners COMMON_VPATH += $(QUANTUM_DIR)/rgb_matrix/animations/runners
POST_CONFIG_H += $(QUANTUM_DIR)/rgb_matrix/post_config.h POST_CONFIG_H += $(QUANTUM_DIR)/rgb_matrix/post_config.h
# TODO: Remove this
SRC += $(QUANTUM_DIR)/process_keycode/process_underglow.c
SRC += $(QUANTUM_DIR)/process_keycode/process_rgb_matrix.c
SRC += $(QUANTUM_DIR)/color.c SRC += $(QUANTUM_DIR)/color.c
SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix.c SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix.c
SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix_drivers.c SRC += $(QUANTUM_DIR)/rgb_matrix/rgb_matrix_drivers.c
LIB8TION_ENABLE := yes LIB8TION_ENABLE := yes
CIE1931_CURVE := yes CIE1931_CURVE := yes
RGB_KEYCODES_ENABLE := yes
ifeq ($(strip $(RGB_MATRIX_DRIVER)), aw20216s) ifeq ($(strip $(RGB_MATRIX_DRIVER)), aw20216s)
SPI_DRIVER_REQUIRED = yes SPI_DRIVER_REQUIRED = yes
@ -568,10 +568,6 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
endif endif
endif endif
ifeq ($(strip $(RGB_KEYCODES_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_rgb.c
endif
VARIABLE_TRACE ?= no VARIABLE_TRACE ?= no
ifneq ($(strip $(VARIABLE_TRACE)),no) ifneq ($(strip $(VARIABLE_TRACE)),no)
SRC += $(QUANTUM_DIR)/variable_trace.c SRC += $(QUANTUM_DIR)/variable_trace.c
@ -881,7 +877,7 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]')) OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]'))
NO_USB_STARTUP_CHECK := yes NO_USB_STARTUP_CHECK := yes
COMMON_VPATH += $(DRIVER_PATH)/bluetooth COMMON_VPATH += $(DRIVER_PATH)/bluetooth
SRC += outputselect.c SRC += outputselect.c process_connection.c
ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le) ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le)
SPI_DRIVER_REQUIRED = yes SPI_DRIVER_REQUIRED = yes
@ -936,7 +932,7 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]')) OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
SRC += ws2812_$(strip $(WS2812_DRIVER)).c SRC += ws2812.c ws2812_$(strip $(WS2812_DRIVER)).c
ifeq ($(strip $(PLATFORM)), CHIBIOS) ifeq ($(strip $(PLATFORM)), CHIBIOS)
ifeq ($(strip $(WS2812_DRIVER)), pwm) ifeq ($(strip $(WS2812_DRIVER)), pwm)

View File

@ -43,25 +43,25 @@ ifneq ($(USE_CCACHE),no)
CC_PREFIX ?= ccache CC_PREFIX ?= ccache
endif endif
#---------------- Debug Options ----------------
DEBUG_ENABLE ?= no
ifeq ($(strip $(DEBUG_ENABLE)),yes)
CFLAGS += -ggdb3
CXXFLAGS += -ggdb3
ASFLAGS += -ggdb3
# Create a map file when debugging
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
endif
#---------------- C Compiler Options ---------------- #---------------- C Compiler Options ----------------
ifeq ($(strip $(LTO_ENABLE)), yes) 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.)
$(info If unsure, set LTO_ENABLE = no.)
endif
CDEFS += -flto CDEFS += -flto
CDEFS += -DLTO_ENABLE CDEFS += -DLTO_ENABLE
endif endif
DEBUG_ENABLE ?= yes
ifeq ($(strip $(SKIP_DEBUG_INFO)),yes)
DEBUG_ENABLE=no
endif
ifeq ($(strip $(DEBUG_ENABLE)),yes)
CFLAGS += -g$(DEBUG)
endif
CFLAGS += $(CDEFS) CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT) CFLAGS += -O$(OPT)
# add color # add color
@ -83,9 +83,6 @@ CFLAGS += -fcommon
#---------------- C++ Compiler Options ---------------- #---------------- C++ Compiler Options ----------------
ifeq ($(strip $(DEBUG_ENABLE)),yes)
CXXFLAGS += -g$(DEBUG)
endif
CXXFLAGS += $(CXXDEFS) CXXFLAGS += $(CXXDEFS)
CXXFLAGS += -O$(OPT) CXXFLAGS += -O$(OPT)
# to suppress "warning: only initialized variables can be placed into program memory area" # to suppress "warning: only initialized variables can be placed into program memory area"
@ -106,14 +103,10 @@ endif
#---------------- Linker Options ---------------- #---------------- Linker Options ----------------
CREATE_MAP ?= yes
ifeq ($(CREATE_MAP),yes)
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
endif
ifeq ($(VERBOSE_LD_CMD),yes) ifeq ($(VERBOSE_LD_CMD),yes)
LDFLAGS += -v LDFLAGS += -v
endif endif
#LDFLAGS += -Wl,--relax
LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += -lm LDFLAGS += -lm
@ -130,11 +123,7 @@ ifeq ($(ADHLNS_ENABLE),yes)
else else
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst) CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CXXFLAGS += -Wa,-adhlns=$(@:%.o=%.lst) CXXFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
ifeq ($(strip $(DEBUG_ENABLE)),yes) ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100
ASFLAGS = -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
else
ASFLAGS = -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100
endif
endif endif
endif endif

View File

@ -39,8 +39,15 @@ export default defineConfig(({ mode }) => {
provider: "local", provider: "local",
}, },
editLink: {
pattern: 'https://github.com/qmk/qmk_firmware/edit/master/docs/:path'
},
lastUpdated: true,
sidebar: sidebar, sidebar: sidebar,
externalLinkIcon: true,
socialLinks: [ socialLinks: [
{ icon: { svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 29 3 C 28.0625 3 27.164063 3.382813 26.5 4 C 25.835938 4.617188 25.363281 5.433594 25 6.40625 C 24.355469 8.140625 24.085938 10.394531 24.03125 13.03125 C 19.234375 13.179688 14.820313 14.421875 11.28125 16.46875 C 10.214844 15.46875 8.855469 14.96875 7.5 14.96875 C 6.089844 14.96875 4.675781 15.511719 3.59375 16.59375 C 1.425781 18.761719 1.425781 22.238281 3.59375 24.40625 L 3.84375 24.65625 C 3.3125 26.035156 3 27.488281 3 29 C 3 33.527344 5.566406 37.585938 9.5625 40.4375 C 13.558594 43.289063 19.007813 45 25 45 C 30.992188 45 36.441406 43.289063 40.4375 40.4375 C 44.433594 37.585938 47 33.527344 47 29 C 47 27.488281 46.6875 26.035156 46.15625 24.65625 L 46.40625 24.40625 C 48.574219 22.238281 48.574219 18.761719 46.40625 16.59375 C 45.324219 15.511719 43.910156 14.96875 42.5 14.96875 C 41.144531 14.96875 39.785156 15.46875 38.71875 16.46875 C 35.195313 14.433594 30.800781 13.191406 26.03125 13.03125 C 26.09375 10.546875 26.363281 8.46875 26.875 7.09375 C 27.164063 6.316406 27.527344 5.757813 27.875 5.4375 C 28.222656 5.117188 28.539063 5 29 5 C 29.460938 5 29.683594 5.125 30.03125 5.40625 C 30.378906 5.6875 30.785156 6.148438 31.3125 6.6875 C 32.253906 7.652344 33.695313 8.714844 36.09375 8.9375 C 36.539063 11.238281 38.574219 13 41 13 C 43.75 13 46 10.75 46 8 C 46 5.25 43.75 3 41 3 C 38.605469 3 36.574219 4.710938 36.09375 6.96875 C 34.3125 6.796875 33.527344 6.109375 32.75 5.3125 C 32.300781 4.851563 31.886719 4.3125 31.3125 3.84375 C 30.738281 3.375 29.9375 3 29 3 Z M 41 5 C 42.667969 5 44 6.332031 44 8 C 44 9.667969 42.667969 11 41 11 C 39.332031 11 38 9.667969 38 8 C 38 6.332031 39.332031 5 41 5 Z M 25 15 C 30.609375 15 35.675781 16.613281 39.28125 19.1875 C 42.886719 21.761719 45 25.226563 45 29 C 45 32.773438 42.886719 36.238281 39.28125 38.8125 C 35.675781 41.386719 30.609375 43 25 43 C 19.390625 43 14.324219 41.386719 10.71875 38.8125 C 7.113281 36.238281 5 32.773438 5 29 C 5 25.226563 7.113281 21.761719 10.71875 19.1875 C 14.324219 16.613281 19.390625 15 25 15 Z M 7.5 16.9375 C 8.203125 16.9375 8.914063 17.148438 9.53125 17.59375 C 7.527344 19.03125 5.886719 20.769531 4.75 22.71875 C 3.582031 21.296875 3.660156 19.339844 5 18 C 5.714844 17.285156 6.609375 16.9375 7.5 16.9375 Z M 42.5 16.9375 C 43.390625 16.9375 44.285156 17.285156 45 18 C 46.339844 19.339844 46.417969 21.296875 45.25 22.71875 C 44.113281 20.769531 42.472656 19.03125 40.46875 17.59375 C 41.085938 17.148438 41.796875 16.9375 42.5 16.9375 Z M 17 22 C 14.800781 22 13 23.800781 13 26 C 13 28.199219 14.800781 30 17 30 C 19.199219 30 21 28.199219 21 26 C 21 23.800781 19.199219 22 17 22 Z M 33 22 C 30.800781 22 29 23.800781 29 26 C 29 28.199219 30.800781 30 33 30 C 35.199219 30 37 28.199219 37 26 C 37 23.800781 35.199219 22 33 22 Z M 17 24 C 18.117188 24 19 24.882813 19 26 C 19 27.117188 18.117188 28 17 28 C 15.882813 28 15 27.117188 15 26 C 15 24.882813 15.882813 24 17 24 Z M 33 24 C 34.117188 24 35 24.882813 35 26 C 35 27.117188 34.117188 28 33 28 C 31.882813 28 31 27.117188 31 26 C 31 24.882813 31.882813 24 33 24 Z M 34.15625 33.84375 C 34.101563 33.851563 34.050781 33.859375 34 33.875 C 33.683594 33.9375 33.417969 34.144531 33.28125 34.4375 C 33.28125 34.4375 32.757813 35.164063 31.4375 36 C 30.117188 36.835938 28.058594 37.6875 25 37.6875 C 21.941406 37.6875 19.882813 36.835938 18.5625 36 C 17.242188 35.164063 16.71875 34.4375 16.71875 34.4375 C 16.492188 34.082031 16.066406 33.90625 15.65625 34 C 15.332031 34.082031 15.070313 34.316406 14.957031 34.632813 C 14.84375 34.945313 14.894531 35.292969 15.09375 35.5625 C 15.09375 35.5625 15.863281 36.671875 17.46875 37.6875 C 19.074219 38.703125 21.558594 39.6875 25 39.6875 C 28.441406 39.6875 30.925781 38.703125 32.53125 37.6875 C 34.136719 36.671875 34.90625 35.5625 34.90625 35.5625 C 35.207031 35.273438 35.296875 34.824219 35.128906 34.441406 C 34.960938 34.058594 34.574219 33.820313 34.15625 33.84375 Z"/></svg>' }, link: "https://reddit.com/r/olkb" }, { icon: { svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 29 3 C 28.0625 3 27.164063 3.382813 26.5 4 C 25.835938 4.617188 25.363281 5.433594 25 6.40625 C 24.355469 8.140625 24.085938 10.394531 24.03125 13.03125 C 19.234375 13.179688 14.820313 14.421875 11.28125 16.46875 C 10.214844 15.46875 8.855469 14.96875 7.5 14.96875 C 6.089844 14.96875 4.675781 15.511719 3.59375 16.59375 C 1.425781 18.761719 1.425781 22.238281 3.59375 24.40625 L 3.84375 24.65625 C 3.3125 26.035156 3 27.488281 3 29 C 3 33.527344 5.566406 37.585938 9.5625 40.4375 C 13.558594 43.289063 19.007813 45 25 45 C 30.992188 45 36.441406 43.289063 40.4375 40.4375 C 44.433594 37.585938 47 33.527344 47 29 C 47 27.488281 46.6875 26.035156 46.15625 24.65625 L 46.40625 24.40625 C 48.574219 22.238281 48.574219 18.761719 46.40625 16.59375 C 45.324219 15.511719 43.910156 14.96875 42.5 14.96875 C 41.144531 14.96875 39.785156 15.46875 38.71875 16.46875 C 35.195313 14.433594 30.800781 13.191406 26.03125 13.03125 C 26.09375 10.546875 26.363281 8.46875 26.875 7.09375 C 27.164063 6.316406 27.527344 5.757813 27.875 5.4375 C 28.222656 5.117188 28.539063 5 29 5 C 29.460938 5 29.683594 5.125 30.03125 5.40625 C 30.378906 5.6875 30.785156 6.148438 31.3125 6.6875 C 32.253906 7.652344 33.695313 8.714844 36.09375 8.9375 C 36.539063 11.238281 38.574219 13 41 13 C 43.75 13 46 10.75 46 8 C 46 5.25 43.75 3 41 3 C 38.605469 3 36.574219 4.710938 36.09375 6.96875 C 34.3125 6.796875 33.527344 6.109375 32.75 5.3125 C 32.300781 4.851563 31.886719 4.3125 31.3125 3.84375 C 30.738281 3.375 29.9375 3 29 3 Z M 41 5 C 42.667969 5 44 6.332031 44 8 C 44 9.667969 42.667969 11 41 11 C 39.332031 11 38 9.667969 38 8 C 38 6.332031 39.332031 5 41 5 Z M 25 15 C 30.609375 15 35.675781 16.613281 39.28125 19.1875 C 42.886719 21.761719 45 25.226563 45 29 C 45 32.773438 42.886719 36.238281 39.28125 38.8125 C 35.675781 41.386719 30.609375 43 25 43 C 19.390625 43 14.324219 41.386719 10.71875 38.8125 C 7.113281 36.238281 5 32.773438 5 29 C 5 25.226563 7.113281 21.761719 10.71875 19.1875 C 14.324219 16.613281 19.390625 15 25 15 Z M 7.5 16.9375 C 8.203125 16.9375 8.914063 17.148438 9.53125 17.59375 C 7.527344 19.03125 5.886719 20.769531 4.75 22.71875 C 3.582031 21.296875 3.660156 19.339844 5 18 C 5.714844 17.285156 6.609375 16.9375 7.5 16.9375 Z M 42.5 16.9375 C 43.390625 16.9375 44.285156 17.285156 45 18 C 46.339844 19.339844 46.417969 21.296875 45.25 22.71875 C 44.113281 20.769531 42.472656 19.03125 40.46875 17.59375 C 41.085938 17.148438 41.796875 16.9375 42.5 16.9375 Z M 17 22 C 14.800781 22 13 23.800781 13 26 C 13 28.199219 14.800781 30 17 30 C 19.199219 30 21 28.199219 21 26 C 21 23.800781 19.199219 22 17 22 Z M 33 22 C 30.800781 22 29 23.800781 29 26 C 29 28.199219 30.800781 30 33 30 C 35.199219 30 37 28.199219 37 26 C 37 23.800781 35.199219 22 33 22 Z M 17 24 C 18.117188 24 19 24.882813 19 26 C 19 27.117188 18.117188 28 17 28 C 15.882813 28 15 27.117188 15 26 C 15 24.882813 15.882813 24 17 24 Z M 33 24 C 34.117188 24 35 24.882813 35 26 C 35 27.117188 34.117188 28 33 28 C 31.882813 28 31 27.117188 31 26 C 31 24.882813 31.882813 24 33 24 Z M 34.15625 33.84375 C 34.101563 33.851563 34.050781 33.859375 34 33.875 C 33.683594 33.9375 33.417969 34.144531 33.28125 34.4375 C 33.28125 34.4375 32.757813 35.164063 31.4375 36 C 30.117188 36.835938 28.058594 37.6875 25 37.6875 C 21.941406 37.6875 19.882813 36.835938 18.5625 36 C 17.242188 35.164063 16.71875 34.4375 16.71875 34.4375 C 16.492188 34.082031 16.066406 33.90625 15.65625 34 C 15.332031 34.082031 15.070313 34.316406 14.957031 34.632813 C 14.84375 34.945313 14.894531 35.292969 15.09375 35.5625 C 15.09375 35.5625 15.863281 36.671875 17.46875 37.6875 C 19.074219 38.703125 21.558594 39.6875 25 39.6875 C 28.441406 39.6875 30.925781 38.703125 32.53125 37.6875 C 34.136719 36.671875 34.90625 35.5625 34.90625 35.5625 C 35.207031 35.273438 35.296875 34.824219 35.128906 34.441406 C 34.960938 34.058594 34.574219 33.820313 34.15625 33.84375 Z"/></svg>' }, link: "https://reddit.com/r/olkb" },
{ icon: "discord", link: "https://discord.gg/qmk" }, { icon: "discord", link: "https://discord.gg/qmk" },

View File

@ -1,7 +1,7 @@
{ {
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"devDependencies": { "devDependencies": {
"vite": "^5.2.10", "vite": "^5.2.14",
"vitepress": "^1.1.0", "vitepress": "^1.1.0",
"vitepress-plugin-tabs": "^0.5.0", "vitepress-plugin-tabs": "^0.5.0",
"vue": "^3.4.24" "vue": "^3.4.24"

View File

@ -298,85 +298,85 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@rollup/rollup-android-arm-eabi@4.16.4": "@rollup/rollup-android-arm-eabi@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz#5e8930291f1e5ead7fb1171d53ba5c87718de062" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
integrity sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q== integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==
"@rollup/rollup-android-arm64@4.16.4": "@rollup/rollup-android-arm64@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz#ffb84f1359c04ec8a022a97110e18a5600f5f638" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb"
integrity sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w== integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==
"@rollup/rollup-darwin-arm64@4.16.4": "@rollup/rollup-darwin-arm64@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz#b2fcee8d4806a0b1b9185ac038cc428ddedce9f4" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b"
integrity sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw== integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==
"@rollup/rollup-darwin-x64@4.16.4": "@rollup/rollup-darwin-x64@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz#fcb25ccbaa3dd33a6490e9d1c64bab2e0e16b932" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791"
integrity sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ== integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==
"@rollup/rollup-linux-arm-gnueabihf@4.16.4": "@rollup/rollup-linux-arm-gnueabihf@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz#40d46bdfe667e5eca31bf40047460e326d2e26bb" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232"
integrity sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw== integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==
"@rollup/rollup-linux-arm-musleabihf@4.16.4": "@rollup/rollup-linux-arm-musleabihf@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz#7741df2448c11c56588b50835dbfe91b1a10b375" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa"
integrity sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg== integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==
"@rollup/rollup-linux-arm64-gnu@4.16.4": "@rollup/rollup-linux-arm64-gnu@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz#0a23b02d2933e4c4872ad18d879890b6a4a295df" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15"
integrity sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w== integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==
"@rollup/rollup-linux-arm64-musl@4.16.4": "@rollup/rollup-linux-arm64-musl@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz#e37ef259358aa886cc07d782220a4fb83c1e6970" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820"
integrity sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg== integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==
"@rollup/rollup-linux-powerpc64le-gnu@4.16.4": "@rollup/rollup-linux-powerpc64le-gnu@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz#8c69218b6de05ee2ba211664a2d2ac1e54e43f94" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e"
integrity sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w== integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==
"@rollup/rollup-linux-riscv64-gnu@4.16.4": "@rollup/rollup-linux-riscv64-gnu@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz#d32727dab8f538d9a4a7c03bcf58c436aecd0139" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128"
integrity sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng== integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==
"@rollup/rollup-linux-s390x-gnu@4.16.4": "@rollup/rollup-linux-s390x-gnu@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz#d46097246a187d99fc9451fe8393b7155b47c5ec" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc"
integrity sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ== integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==
"@rollup/rollup-linux-x64-gnu@4.16.4": "@rollup/rollup-linux-x64-gnu@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz#6356c5a03a4afb1c3057490fc51b4764e109dbc7" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0"
integrity sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA== integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==
"@rollup/rollup-linux-x64-musl@4.16.4": "@rollup/rollup-linux-x64-musl@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz#03a5831a9c0d05877b94653b5ddd3020d3c6fb06" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f"
integrity sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA== integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==
"@rollup/rollup-win32-arm64-msvc@4.16.4": "@rollup/rollup-win32-arm64-msvc@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz#6cc0db57750376b9303bdb6f5482af8974fcae35" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0"
integrity sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA== integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==
"@rollup/rollup-win32-ia32-msvc@4.16.4": "@rollup/rollup-win32-ia32-msvc@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz#aea0b7e492bd9ed46971cb80bc34f1eb14e07789" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422"
integrity sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w== integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==
"@rollup/rollup-win32-x64-msvc@4.16.4": "@rollup/rollup-win32-x64-msvc@4.22.4":
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz#c09ad9a132ccb5a67c4f211d909323ab1294f95f" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202"
integrity sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A== integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==
"@shikijs/core@1.3.0", "@shikijs/core@^1.3.0": "@shikijs/core@1.3.0", "@shikijs/core@^1.3.0":
version "1.3.0" version "1.3.0"
@ -697,28 +697,28 @@ rfdc@^1.3.1:
integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==
rollup@^4.13.0: rollup@^4.13.0:
version "4.16.4" version "4.22.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.4.tgz#fe328eb41293f20c9593a095ec23bdc4b5d93317" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f"
integrity sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA== integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==
dependencies: dependencies:
"@types/estree" "1.0.5" "@types/estree" "1.0.5"
optionalDependencies: optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.16.4" "@rollup/rollup-android-arm-eabi" "4.22.4"
"@rollup/rollup-android-arm64" "4.16.4" "@rollup/rollup-android-arm64" "4.22.4"
"@rollup/rollup-darwin-arm64" "4.16.4" "@rollup/rollup-darwin-arm64" "4.22.4"
"@rollup/rollup-darwin-x64" "4.16.4" "@rollup/rollup-darwin-x64" "4.22.4"
"@rollup/rollup-linux-arm-gnueabihf" "4.16.4" "@rollup/rollup-linux-arm-gnueabihf" "4.22.4"
"@rollup/rollup-linux-arm-musleabihf" "4.16.4" "@rollup/rollup-linux-arm-musleabihf" "4.22.4"
"@rollup/rollup-linux-arm64-gnu" "4.16.4" "@rollup/rollup-linux-arm64-gnu" "4.22.4"
"@rollup/rollup-linux-arm64-musl" "4.16.4" "@rollup/rollup-linux-arm64-musl" "4.22.4"
"@rollup/rollup-linux-powerpc64le-gnu" "4.16.4" "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4"
"@rollup/rollup-linux-riscv64-gnu" "4.16.4" "@rollup/rollup-linux-riscv64-gnu" "4.22.4"
"@rollup/rollup-linux-s390x-gnu" "4.16.4" "@rollup/rollup-linux-s390x-gnu" "4.22.4"
"@rollup/rollup-linux-x64-gnu" "4.16.4" "@rollup/rollup-linux-x64-gnu" "4.22.4"
"@rollup/rollup-linux-x64-musl" "4.16.4" "@rollup/rollup-linux-x64-musl" "4.22.4"
"@rollup/rollup-win32-arm64-msvc" "4.16.4" "@rollup/rollup-win32-arm64-msvc" "4.22.4"
"@rollup/rollup-win32-ia32-msvc" "4.16.4" "@rollup/rollup-win32-ia32-msvc" "4.22.4"
"@rollup/rollup-win32-x64-msvc" "4.16.4" "@rollup/rollup-win32-x64-msvc" "4.22.4"
fsevents "~2.3.2" fsevents "~2.3.2"
shiki@1.3.0, shiki@^1.3.0: shiki@1.3.0, shiki@^1.3.0:
@ -743,10 +743,10 @@ tabbable@^6.2.0:
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
vite@^5.2.10, vite@^5.2.9: vite@^5.2.14, vite@^5.2.9:
version "5.2.10" version "5.2.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7" resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.14.tgz#fd5f60facf6b5f90ec7da6323c467a365d380c3d"
integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw== integrity sha512-TFQLuwWLPms+NBNlh0D9LZQ+HXW471COABxw/9TEUBrjuHMo9BrYBPrN/SYAwIuVL+rLerycxiLT41t4f5MZpA==
dependencies: dependencies:
esbuild "^0.20.1" esbuild "^0.20.1"
postcss "^8.4.38" postcss "^8.4.38"

View File

@ -36,6 +36,7 @@ GENERIC_FEATURES = \
HAPTIC \ HAPTIC \
KEY_LOCK \ KEY_LOCK \
KEY_OVERRIDE \ KEY_OVERRIDE \
LAYER_LOCK \
LEADER \ LEADER \
MAGIC \ MAGIC \
MOUSEKEY \ MOUSEKEY \

View File

@ -67,7 +67,6 @@ OTHER_OPTION_NAMES = \
PS2_DRIVER \ PS2_DRIVER \
RAW_ENABLE \ RAW_ENABLE \
SWAP_HANDS_ENABLE \ SWAP_HANDS_ENABLE \
RING_BUFFERED_6KRO_REPORT_ENABLE \
WATCHDOG_ENABLE \ WATCHDOG_ENABLE \
ERGOINU \ ERGOINU \
NO_USB_STARTUP_CHECK \ NO_USB_STARTUP_CHECK \

View File

@ -84,7 +84,7 @@
"group": "midi", "group": "midi",
"key": "QK_MIDI_NOTE_G_SHARP_0", "key": "QK_MIDI_NOTE_G_SHARP_0",
"aliases": [ "aliases": [
"MI_Gs" "MI_Gs",
"MI_Ab" "MI_Ab"
] ]
}, },
@ -99,7 +99,7 @@
"group": "midi", "group": "midi",
"key": "QK_MIDI_NOTE_A_SHARP_0", "key": "QK_MIDI_NOTE_A_SHARP_0",
"aliases": [ "aliases": [
"MI_As" "MI_As",
"MI_Bb" "MI_Bb"
] ]
}, },

View File

@ -2,131 +2,131 @@
"keycodes": { "keycodes": {
"0x7E00": { "0x7E00": {
"group": "kb", "group": "kb",
"key": "QK_KB_0", "key": "QK_KB_0"
}, },
"0x7E01": { "0x7E01": {
"group": "kb", "group": "kb",
"key": "QK_KB_1", "key": "QK_KB_1"
}, },
"0x7E02": { "0x7E02": {
"group": "kb", "group": "kb",
"key": "QK_KB_2", "key": "QK_KB_2"
}, },
"0x7E03": { "0x7E03": {
"group": "kb", "group": "kb",
"key": "QK_KB_3", "key": "QK_KB_3"
}, },
"0x7E04": { "0x7E04": {
"group": "kb", "group": "kb",
"key": "QK_KB_4", "key": "QK_KB_4"
}, },
"0x7E05": { "0x7E05": {
"group": "kb", "group": "kb",
"key": "QK_KB_5", "key": "QK_KB_5"
}, },
"0x7E06": { "0x7E06": {
"group": "kb", "group": "kb",
"key": "QK_KB_6", "key": "QK_KB_6"
}, },
"0x7E07": { "0x7E07": {
"group": "kb", "group": "kb",
"key": "QK_KB_7", "key": "QK_KB_7"
}, },
"0x7E08": { "0x7E08": {
"group": "kb", "group": "kb",
"key": "QK_KB_8", "key": "QK_KB_8"
}, },
"0x7E09": { "0x7E09": {
"group": "kb", "group": "kb",
"key": "QK_KB_9", "key": "QK_KB_9"
}, },
"0x7E0A": { "0x7E0A": {
"group": "kb", "group": "kb",
"key": "QK_KB_10", "key": "QK_KB_10"
}, },
"0x7E0B": { "0x7E0B": {
"group": "kb", "group": "kb",
"key": "QK_KB_11", "key": "QK_KB_11"
}, },
"0x7E0C": { "0x7E0C": {
"group": "kb", "group": "kb",
"key": "QK_KB_12", "key": "QK_KB_12"
}, },
"0x7E0D": { "0x7E0D": {
"group": "kb", "group": "kb",
"key": "QK_KB_13", "key": "QK_KB_13"
}, },
"0x7E0E": { "0x7E0E": {
"group": "kb", "group": "kb",
"key": "QK_KB_14", "key": "QK_KB_14"
}, },
"0x7E0F": { "0x7E0F": {
"group": "kb", "group": "kb",
"key": "QK_KB_15", "key": "QK_KB_15"
}, },
"0x7E10": { "0x7E10": {
"group": "kb", "group": "kb",
"key": "QK_KB_16", "key": "QK_KB_16"
}, },
"0x7E11": { "0x7E11": {
"group": "kb", "group": "kb",
"key": "QK_KB_17", "key": "QK_KB_17"
}, },
"0x7E12": { "0x7E12": {
"group": "kb", "group": "kb",
"key": "QK_KB_18", "key": "QK_KB_18"
}, },
"0x7E13": { "0x7E13": {
"group": "kb", "group": "kb",
"key": "QK_KB_19", "key": "QK_KB_19"
}, },
"0x7E14": { "0x7E14": {
"group": "kb", "group": "kb",
"key": "QK_KB_20", "key": "QK_KB_20"
}, },
"0x7E15": { "0x7E15": {
"group": "kb", "group": "kb",
"key": "QK_KB_21", "key": "QK_KB_21"
}, },
"0x7E16": { "0x7E16": {
"group": "kb", "group": "kb",
"key": "QK_KB_22", "key": "QK_KB_22"
}, },
"0x7E17": { "0x7E17": {
"group": "kb", "group": "kb",
"key": "QK_KB_23", "key": "QK_KB_23"
}, },
"0x7E18": { "0x7E18": {
"group": "kb", "group": "kb",
"key": "QK_KB_24", "key": "QK_KB_24"
}, },
"0x7E19": { "0x7E19": {
"group": "kb", "group": "kb",
"key": "QK_KB_25", "key": "QK_KB_25"
}, },
"0x7E1A": { "0x7E1A": {
"group": "kb", "group": "kb",
"key": "QK_KB_26", "key": "QK_KB_26"
}, },
"0x7E1B": { "0x7E1B": {
"group": "kb", "group": "kb",
"key": "QK_KB_27", "key": "QK_KB_27"
}, },
"0x7E1C": { "0x7E1C": {
"group": "kb", "group": "kb",
"key": "QK_KB_28", "key": "QK_KB_28"
}, },
"0x7E1D": { "0x7E1D": {
"group": "kb", "group": "kb",
"key": "QK_KB_29", "key": "QK_KB_29"
}, },
"0x7E1E": { "0x7E1E": {
"group": "kb", "group": "kb",
"key": "QK_KB_30", "key": "QK_KB_30"
}, },
"0x7E1F": { "0x7E1F": {
"group": "kb", "group": "kb",
"key": "QK_KB_31", "key": "QK_KB_31"
}, }
} }
} }

View File

@ -86,7 +86,7 @@
"group": "midi", "group": "midi",
"key": "QK_MIDI_NOTE_G_SHARP_0", "key": "QK_MIDI_NOTE_G_SHARP_0",
"aliases": [ "aliases": [
"MI_Gs" "MI_Gs",
"MI_Ab" "MI_Ab"
] ]
}, },
@ -101,7 +101,7 @@
"group": "midi", "group": "midi",
"key": "QK_MIDI_NOTE_A_SHARP_0", "key": "QK_MIDI_NOTE_A_SHARP_0",
"aliases": [ "aliases": [
"MI_As" "MI_As",
"MI_Bb" "MI_Bb"
] ]
}, },

View File

@ -2,131 +2,131 @@
"keycodes": { "keycodes": {
"0x7E40": { "0x7E40": {
"group": "user", "group": "user",
"key": "QK_USER_0", "key": "QK_USER_0"
}, },
"0x7E41": { "0x7E41": {
"group": "user", "group": "user",
"key": "QK_USER_1", "key": "QK_USER_1"
}, },
"0x7E42": { "0x7E42": {
"group": "user", "group": "user",
"key": "QK_USER_2", "key": "QK_USER_2"
}, },
"0x7E43": { "0x7E43": {
"group": "user", "group": "user",
"key": "QK_USER_3", "key": "QK_USER_3"
}, },
"0x7E44": { "0x7E44": {
"group": "user", "group": "user",
"key": "QK_USER_4", "key": "QK_USER_4"
}, },
"0x7E45": { "0x7E45": {
"group": "user", "group": "user",
"key": "QK_USER_5", "key": "QK_USER_5"
}, },
"0x7E46": { "0x7E46": {
"group": "user", "group": "user",
"key": "QK_USER_6", "key": "QK_USER_6"
}, },
"0x7E47": { "0x7E47": {
"group": "user", "group": "user",
"key": "QK_USER_7", "key": "QK_USER_7"
}, },
"0x7E48": { "0x7E48": {
"group": "user", "group": "user",
"key": "QK_USER_8", "key": "QK_USER_8"
}, },
"0x7E49": { "0x7E49": {
"group": "user", "group": "user",
"key": "QK_USER_9", "key": "QK_USER_9"
}, },
"0x7E4A": { "0x7E4A": {
"group": "user", "group": "user",
"key": "QK_USER_10", "key": "QK_USER_10"
}, },
"0x7E4B": { "0x7E4B": {
"group": "user", "group": "user",
"key": "QK_USER_11", "key": "QK_USER_11"
}, },
"0x7E4C": { "0x7E4C": {
"group": "user", "group": "user",
"key": "QK_USER_12", "key": "QK_USER_12"
}, },
"0x7E4D": { "0x7E4D": {
"group": "user", "group": "user",
"key": "QK_USER_13", "key": "QK_USER_13"
}, },
"0x7E4E": { "0x7E4E": {
"group": "user", "group": "user",
"key": "QK_USER_14", "key": "QK_USER_14"
}, },
"0x7E4F": { "0x7E4F": {
"group": "user", "group": "user",
"key": "QK_USER_15", "key": "QK_USER_15"
}, },
"0x7E50": { "0x7E50": {
"group": "user", "group": "user",
"key": "QK_USER_16", "key": "QK_USER_16"
}, },
"0x7E51": { "0x7E51": {
"group": "user", "group": "user",
"key": "QK_USER_17", "key": "QK_USER_17"
}, },
"0x7E52": { "0x7E52": {
"group": "user", "group": "user",
"key": "QK_USER_18", "key": "QK_USER_18"
}, },
"0x7E53": { "0x7E53": {
"group": "user", "group": "user",
"key": "QK_USER_19", "key": "QK_USER_19"
}, },
"0x7E54": { "0x7E54": {
"group": "user", "group": "user",
"key": "QK_USER_20", "key": "QK_USER_20"
}, },
"0x7E55": { "0x7E55": {
"group": "user", "group": "user",
"key": "QK_USER_21", "key": "QK_USER_21"
}, },
"0x7E56": { "0x7E56": {
"group": "user", "group": "user",
"key": "QK_USER_22", "key": "QK_USER_22"
}, },
"0x7E57": { "0x7E57": {
"group": "user", "group": "user",
"key": "QK_USER_23", "key": "QK_USER_23"
}, },
"0x7E58": { "0x7E58": {
"group": "user", "group": "user",
"key": "QK_USER_24", "key": "QK_USER_24"
}, },
"0x7E59": { "0x7E59": {
"group": "user", "group": "user",
"key": "QK_USER_25", "key": "QK_USER_25"
}, },
"0x7E5A": { "0x7E5A": {
"group": "user", "group": "user",
"key": "QK_USER_26", "key": "QK_USER_26"
}, },
"0x7E5B": { "0x7E5B": {
"group": "user", "group": "user",
"key": "QK_USER_27", "key": "QK_USER_27"
}, },
"0x7E5C": { "0x7E5C": {
"group": "user", "group": "user",
"key": "QK_USER_28", "key": "QK_USER_28"
}, },
"0x7E5D": { "0x7E5D": {
"group": "user", "group": "user",
"key": "QK_USER_29", "key": "QK_USER_29"
}, },
"0x7E5E": { "0x7E5E": {
"group": "user", "group": "user",
"key": "QK_USER_30", "key": "QK_USER_30"
}, },
"0x7E5F": { "0x7E5F": {
"group": "user", "group": "user",
"key": "QK_USER_31", "key": "QK_USER_31"
}, }
} }
} }

View File

@ -0,0 +1,115 @@
{
"ranges": {
"0x7780/0x003F": {
"define": "QK_CONNECTION"
}
}
"keycodes": {
"0x7780": {
"group": "connection",
"key": "QK_OUTPUT_AUTO",
"aliases": [
"OU_AUTO"
]
},
"0x7781": {
"group": "connection",
"key": "QK_OUTPUT_NEXT",
"aliases": [
"OU_NEXT"
]
},
"0x7782": {
"group": "connection",
"key": "QK_OUTPUT_PREV",
"aliases": [
"OU_PREV"
]
},
"0x7783": {
"group": "connection",
"key": "QK_OUTPUT_NONE",
"aliases": [
"OU_NONE"
]
},
"0x7784": {
"group": "connection",
"key": "QK_OUTPUT_USB",
"aliases": [
"OU_USB"
]
},
"0x7785": {
"group": "connection",
"key": "QK_OUTPUT_2P4GHZ",
"aliases": [
"OU_2P4G"
]
},
"0x7786": {
"group": "connection",
"key": "QK_OUTPUT_BLUETOOTH",
"aliases": [
"OU_BT"
]
},
"0x7790": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE_NEXT",
"aliases": [
"BT_NEXT"
]
},
"0x7791": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE_PREV",
"aliases": [
"BT_PREV"
]
},
"0x7792": {
"group": "connection",
"key": "QK_BLUETOOTH_UNPAIR",
"aliases": [
"BT_UNPR"
]
}
"0x7793": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE1",
"aliases": [
"BT_PRF1"
]
},
"0x7794": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE2",
"aliases": [
"BT_PRF2"
]
},
"0x7795": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE3",
"aliases": [
"BT_PRF3"
]
},
"0x7796": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE4",
"aliases": [
"BT_PRF4"
]
},
"0x7797": {
"group": "connection",
"key": "QK_BLUETOOTH_PROFILE5",
"aliases": [
"BT_PRF5"
]
},
}
}

View File

@ -0,0 +1,14 @@
{
"keycodes": {
"0x7C20": "!delete!", // old QK_OUTPUT_AUTO
"0x7C21": "!delete!", // old QK_OUTPUT_USB
"0x7C22": "!delete!", // old QK_OUTPUT_BLUETOOTH
"0x7C7B": {
"group": "quantum",
"key": "QK_LAYER_LOCK",
"aliases": [
"QK_LLCK"
]
}
}
}

View File

@ -84,6 +84,11 @@
"board": "STEMCELL", "board": "STEMCELL",
"bootloader": "tinyuf2", "bootloader": "tinyuf2",
"processor": "STM32F411" "processor": "STM32F411"
},
"svlinky": {
"board": "QMK_PM2040",
"bootloader": "rp2040",
"processor": "RP2040"
} }
} }
} }

View File

@ -64,6 +64,9 @@
"WEAR_LEVELING_BACKING_SIZE": {"info_key": "eeprom.wear_leveling.backing_size", "value_type": "int", "to_json": false}, "WEAR_LEVELING_BACKING_SIZE": {"info_key": "eeprom.wear_leveling.backing_size", "value_type": "int", "to_json": false},
"WEAR_LEVELING_LOGICAL_SIZE": {"info_key": "eeprom.wear_leveling.logical_size", "value_type": "int", "to_json": false}, "WEAR_LEVELING_LOGICAL_SIZE": {"info_key": "eeprom.wear_leveling.logical_size", "value_type": "int", "to_json": false},
// Layer locking
"LAYER_LOCK_IDLE_TIMEOUT": {"info_key": "layer_lock.timeout", "value_type": "int"},
// Indicators // Indicators
"LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"}, "LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"},
"LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"}, "LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"},

View File

@ -1365,6 +1365,12 @@
"runner3680/5x8": { "runner3680/5x8": {
"target": "omkbd/runner3680/5x8" "target": "omkbd/runner3680/5x8"
}, },
"saevus/cor": {
"target": "concreteflowers/cor"
},
"saevus/cor_tkl": {
"target": "concreteflowers/cor_tkl"
},
"scarletbandana": { "scarletbandana": {
"target": "woodkeys/scarletbandana" "target": "woodkeys/scarletbandana"
}, },

View File

@ -45,7 +45,7 @@
}, },
"development_board": { "development_board": {
"type": "string", "type": "string",
"enum": ["promicro", "elite_c", "elite_pi", "proton_c", "kb2040", "promicro_rp2040", "blok", "michi", "bit_c_pro", "stemcell", "bluepill", "blackpill_f401", "blackpill_f411", "bonsai_c4", "helios", "liatris", "imera"] "enum": ["promicro", "elite_c", "elite_pi", "proton_c", "kb2040", "promicro_rp2040", "blok", "michi", "bit_c_pro", "stemcell", "bluepill", "blackpill_f401", "blackpill_f411", "bonsai_c4", "helios", "liatris", "imera", "svlinky"]
}, },
"pin_compatible": { "pin_compatible": {
"type": "string", "type": "string",
@ -92,6 +92,7 @@
"GD32VF103", "GD32VF103",
"WB32F3G71", "WB32F3G71",
"WB32FQ95", "WB32FQ95",
"AT32F415",
"atmega16u2", "atmega16u2",
"atmega32u2", "atmega32u2",
"atmega16u4", "atmega16u4",
@ -216,6 +217,7 @@
"type": "string", "type": "string",
"enum": [ "enum": [
"apm32-dfu", "apm32-dfu",
"at32-dfu",
"atmel-dfu", "atmel-dfu",
"bootloadhid", "bootloadhid",
"caterina", "caterina",
@ -373,6 +375,12 @@
} }
}, },
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"}, "keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
"layer_lock": {
"type": "object",
"properties": {
"timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}
}
},
"layout_aliases": { "layout_aliases": {
"type": "object", "type": "object",
"additionalProperties": {"$ref": "qmk.definitions.v1#/layout_macro"} "additionalProperties": {"$ref": "qmk.definitions.v1#/layout_macro"}

View File

@ -4,7 +4,7 @@
August 2024 brings another maintenance release of QMK. Almost all PRs this cycle were to do with cleanup or re-organization of existing features and code. August 2024 brings another maintenance release of QMK. Almost all PRs this cycle were to do with cleanup or re-organization of existing features and code.
One key item is that there are no longer any `via`-enabled keymaps in the QMK repository -- these have all transitioned to an [External Userspace](../newbs_external_userspace) repository under the VIA team's control. Going forward, all PRs to `qmk_firmware` must not contain `via` keymaps; these should instead be redirected to the the VIA team's repo: `https://github.com/the-via/qmk_userspace_via` (link placeholder until transfer is completed). One key item is that there are no longer any `via`-enabled keymaps in the QMK repository -- these have all transitioned to an [External Userspace](../newbs_external_userspace) repository under the VIA team's control. Going forward, all PRs to `qmk_firmware` must not contain `via` keymaps; these should instead be redirected to the [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) repository.
## Changes Requiring User Action ## Changes Requiring User Action
@ -76,7 +76,7 @@ In line with the [notice period](../support_deprecation_policy#how-much-advance-
### Migration of VIA keymaps to VIA team control ### Migration of VIA keymaps to VIA team control
Last breaking changes cycle, the QMK team informed that [`via` keymaps are moving](./20240526#migration-of-via-keymaps-to-via-team-control) to the control of the VIA team. As of this merge, any `via`-enabled keymaps should now be PR'ed to `https://github.com/the-via/qmk_userspace_via` (link placeholder until transfer is completed). Last breaking changes cycle, the QMK team informed that [`via` keymaps are moving](./20240526#migration-of-via-keymaps-to-via-team-control) to the control of the VIA team. As of this merge, any `via`-enabled keymaps should now be PR'ed to the [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) repository.
Any existing or newly-opened PRs against `qmk_firmware` will now be asked to remove any `via`-enabled keymaps from their submissions. Any existing or newly-opened PRs against `qmk_firmware` will now be asked to remove any `via`-enabled keymaps from their submissions.

View File

@ -16,6 +16,8 @@
"/tutorial": "/newbs", "/tutorial": "/newbs",
"/unicode": "/feature_unicode", "/unicode": "/feature_unicode",
"/features/bluetooth": "/features/wireless",
"/adc_driver": "/drivers/adc", "/adc_driver": "/drivers/adc",
"/apa102_driver": "/drivers/apa102", "/apa102_driver": "/drivers/apa102",
"/audio_driver": "/drivers/audio", "/audio_driver": "/drivers/audio",
@ -24,7 +26,7 @@
"/feature_auto_shift": "/features/auto_shift", "/feature_auto_shift": "/features/auto_shift",
"/feature_autocorrect": "/features/autocorrect", "/feature_autocorrect": "/features/autocorrect",
"/feature_backlight": "/features/backlight", "/feature_backlight": "/features/backlight",
"/feature_bluetooth": "/features/bluetooth", "/feature_bluetooth": "/features/wireless",
"/feature_bootmagic": "/features/bootmagic", "/feature_bootmagic": "/features/bootmagic",
"/feature_caps_word": "/features/caps_word", "/feature_caps_word": "/features/caps_word",
"/feature_combo": "/features/combo", "/feature_combo": "/features/combo",

View File

@ -123,6 +123,7 @@
{ "text": "Key Lock", "link": "/features/key_lock" }, { "text": "Key Lock", "link": "/features/key_lock" },
{ "text": "Key Overrides", "link": "/features/key_overrides" }, { "text": "Key Overrides", "link": "/features/key_overrides" },
{ "text": "Layers", "link": "/feature_layers" }, { "text": "Layers", "link": "/feature_layers" },
{ "text": "Layer Lock", "link": "/features/layer_lock" },
{ "text": "One Shot Keys", "link": "/one_shot_keys" }, { "text": "One Shot Keys", "link": "/one_shot_keys" },
{ "text": "OS Detection", "link": "/features/os_detection" }, { "text": "OS Detection", "link": "/features/os_detection" },
{ "text": "Raw HID", "link": "/features/rawhid" }, { "text": "Raw HID", "link": "/features/rawhid" },
@ -166,8 +167,7 @@
] ]
}, },
{ "text": "Audio", "link": "/features/audio" }, { "text": "Audio", "link": "/features/audio" },
{ "text": "Bluetooth", "link": "/features/bluetooth" }, { "text": "Bootmagic", "link": "/features/bootmagic" },
{ "text": "Bootmagic Lite", "link": "/features/bootmagic" },
{ "text": "Converters", "link": "/feature_converters" }, { "text": "Converters", "link": "/feature_converters" },
{ "text": "Custom Matrix", "link": "/custom_matrix" }, { "text": "Custom Matrix", "link": "/custom_matrix" },
{ "text": "DIP Switch", "link": "/features/dip_switch" }, { "text": "DIP Switch", "link": "/features/dip_switch" },
@ -179,7 +179,8 @@
{ "text": "Pointing Device", "link": "/features/pointing_device" }, { "text": "Pointing Device", "link": "/features/pointing_device" },
{ "text": "PS/2 Mouse", "link": "/features/ps2_mouse" }, { "text": "PS/2 Mouse", "link": "/features/ps2_mouse" },
{ "text": "Split Keyboard", "link": "/features/split_keyboard" }, { "text": "Split Keyboard", "link": "/features/split_keyboard" },
{ "text": "Stenography", "link": "/features/stenography" } { "text": "Stenography", "link": "/features/stenography" },
{ "text": "Wireless", "link": "/features/wireless" }
] ]
}, },
{ {

View File

@ -4,7 +4,7 @@ This page attempts to introduce developers to the QMK Compiler. It does not go i
# Overview # Overview
The QMK Compile API consists of a few movings parts: The QMK Compile API consists of a few moving parts:
![Architecture Diagram](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg) ![Architecture Diagram](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg)

View File

@ -153,20 +153,26 @@ qmk cd
This command allows for searching through keyboard/keymap targets, filtering by specific criteria. `info.json` and `rules.mk` files contribute to the search data, as well as keymap configurations, and the results can be filtered using "dotty" syntax matching the overall `info.json` file format. This command allows for searching through keyboard/keymap targets, filtering by specific criteria. `info.json` and `rules.mk` files contribute to the search data, as well as keymap configurations, and the results can be filtered using "dotty" syntax matching the overall `info.json` file format.
For example, one could search for all keyboards using STM32F411: For example, one could search for all keyboards powered by the STM32F411 microcontroller:
``` ```
qmk find -f 'processor=STM32F411' qmk find -f 'processor==STM32F411'
``` ```
...and one can further constrain the list to keyboards using STM32F411 as well as rgb_matrix support: The list can be further constrained by passing additional filter expressions:
``` ```
qmk find -f 'processor=STM32F411' -f 'features.rgb_matrix=true' qmk find -f 'processor==STM32F411' -f 'features.rgb_matrix==true'
``` ```
The following filter expressions are also supported: The following filter expressions are supported:
- `key == value`: Match targets where `key` is equal to `value`. May include wildcards such as `*` and `?`.
- `key != value`: Match targets where `key` is not `value`. May include wildcards such as `*` and `?`.
- `key < value`: Match targets where `key` is a number less than `value`.
- `key > value`: Match targets where `key` is a number greater than `value`.
- `key <= value`: Match targets where `key` is a number less than or equal to `value`.
- `key >= value`: Match targets where `key` is a number greater than or equal to `value`.
- `exists(key)`: Match targets where `key` is present. - `exists(key)`: Match targets where `key` is present.
- `absent(key)`: Match targets where `key` is not present. - `absent(key)`: Match targets where `key` is not present.
- `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys. - `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys.
@ -175,7 +181,7 @@ The following filter expressions are also supported:
You can also list arbitrary values for each matched target with `--print`: You can also list arbitrary values for each matched target with `--print`:
``` ```
qmk find -f 'processor=STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix' qmk find -f 'processor==STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix'
``` ```
**Usage**: **Usage**:

View File

@ -57,6 +57,10 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
* [WB32F3G71xx](http://www.westberrytech.com) * [WB32F3G71xx](http://www.westberrytech.com)
* [WB32FQ95xx](http://www.westberrytech.com) * [WB32FQ95xx](http://www.westberrytech.com)
### Artery (AT32)
* [AT32F415](https://www.arterychip.com/en/product/AT32F415.jsp)
### NXP (Kinetis) ### NXP (Kinetis)
* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) * [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x)
@ -75,10 +79,6 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040). For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040).
## 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.
## RISC-V ## RISC-V
### GigaDevice ### GigaDevice

View File

@ -413,7 +413,7 @@ Use these to enable or disable building certain features. The more you have enab
* `MAGIC_ENABLE` * `MAGIC_ENABLE`
* MAGIC actions (BOOTMAGIC without the boot) * MAGIC actions (BOOTMAGIC without the boot)
* `BOOTMAGIC_ENABLE` * `BOOTMAGIC_ENABLE`
* Enable Bootmagic Lite * Enable Bootmagic
* `MOUSEKEY_ENABLE` * `MOUSEKEY_ENABLE`
* Mouse keys * Mouse keys
* `EXTRAKEY_ENABLE` * `EXTRAKEY_ENABLE`
@ -426,8 +426,6 @@ Use these to enable or disable building certain features. The more you have enab
* Key combo feature * Key combo feature
* `NKRO_ENABLE` * `NKRO_ENABLE`
* USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work * USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
* `RING_BUFFERED_6KRO_REPORT_ENABLE`
* USB 6-Key Rollover - Instead of stopping any new input once 6 keys are pressed, the oldest key is released and the new key is pressed.
* `AUDIO_ENABLE` * `AUDIO_ENABLE`
* Enable the audio subsystem. * Enable the audio subsystem.
* `KEY_OVERRIDE_ENABLE` * `KEY_OVERRIDE_ENABLE`

View File

@ -8,8 +8,8 @@ We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have
## Installation ## Installation
Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](features/bootmagic) docs for more details). Some boards use [Command](features/command) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in. Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic](features/bootmagic) docs for more details). Some boards use [Command](features/command) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](features/bootmagic) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure. Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic](features/bootmagic) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button. To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
Alternatively, hold `BOOT` while inserting the USB cable. Alternatively, hold `BOOT` while inserting the USB cable.
@ -98,6 +98,7 @@ The device name here is the name that appears in Zadig, and may not be what the
|`bootloadhid` |HIDBoot |`16C0:05DF` |HidUsb | |`bootloadhid` |HIDBoot |`16C0:05DF` |HidUsb |
|`usbasploader`|USBasp |`16C0:05DC` |libusbK| |`usbasploader`|USBasp |`16C0:05DC` |libusbK|
|`apm32-dfu` |APM32 DFU ISP Mode |`314B:0106` |WinUSB | |`apm32-dfu` |APM32 DFU ISP Mode |`314B:0106` |WinUSB |
|`at32-dfu` |AT32 Bootloader DFU |`2E3C:DF11` |WinUSB |
|`stm32-dfu` |STM32 BOOTLOADER |`0483:DF11` |WinUSB | |`stm32-dfu` |STM32 BOOTLOADER |`0483:DF11` |WinUSB |
|`gd32v-dfu` |GD32V BOOTLOADER |`28E9:0189` |WinUSB | |`gd32v-dfu` |GD32V BOOTLOADER |`28E9:0189` |WinUSB |
|`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB | |`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB |

View File

@ -57,27 +57,32 @@ This driver needs one Timer per enabled/used DAC channel, to trigger conversion;
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8: Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8:
```c ::: code-group
//halconf.h: ```c [halconf.h]
#define HAL_USE_DAC TRUE #pragma once
#define HAL_USE_GPT TRUE
#define HAL_USE_DAC TRUE // [!code focus]
#define HAL_USE_GPT TRUE // [!code focus]
#include_next <halconf.h> #include_next <halconf.h>
``` ```
```c [mcuconf.h]
#pragma once
```c
// mcuconf.h:
#include_next <mcuconf.h> #include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE #undef STM32_DAC_USE_DAC1_CH1 // [!code focus]
#undef STM32_DAC_USE_DAC1_CH2 #define STM32_DAC_USE_DAC1_CH1 TRUE // [!code focus]
#define STM32_DAC_USE_DAC1_CH2 TRUE #undef STM32_DAC_USE_DAC1_CH2 // [!code focus]
#undef STM32_GPT_USE_TIM6 #define STM32_DAC_USE_DAC1_CH2 TRUE // [!code focus]
#define STM32_GPT_USE_TIM6 TRUE #undef STM32_GPT_USE_TIM6 // [!code focus]
#undef STM32_GPT_USE_TIM7 #define STM32_GPT_USE_TIM6 TRUE // [!code focus]
#define STM32_GPT_USE_TIM7 TRUE #undef STM32_GPT_USE_TIM7 // [!code focus]
#undef STM32_GPT_USE_TIM8 #define STM32_GPT_USE_TIM7 TRUE // [!code focus]
#define STM32_GPT_USE_TIM8 TRUE #undef STM32_GPT_USE_TIM8 // [!code focus]
#define STM32_GPT_USE_TIM8 TRUE // [!code focus]
``` ```
:::
::: tip ::: tip
Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable). Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
@ -95,23 +100,28 @@ only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; t
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6: Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6:
```c ::: code-group
//halconf.h: ```c [halconf.h]
#define HAL_USE_DAC TRUE #pragma once
#define HAL_USE_GPT TRUE
#define HAL_USE_DAC TRUE // [!code focus]
#define HAL_USE_GPT TRUE // [!code focus]
#include_next <halconf.h> #include_next <halconf.h>
``` ```
```c [mcuconf.h]
#pragma once
```c
// mcuconf.h:
#include_next <mcuconf.h> #include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE #undef STM32_DAC_USE_DAC1_CH1 // [!code focus]
#undef STM32_DAC_USE_DAC1_CH2 #define STM32_DAC_USE_DAC1_CH1 TRUE // [!code focus]
#define STM32_DAC_USE_DAC1_CH2 TRUE #undef STM32_DAC_USE_DAC1_CH2 // [!code focus]
#undef STM32_GPT_USE_TIM6 #define STM32_DAC_USE_DAC1_CH2 TRUE // [!code focus]
#define STM32_GPT_USE_TIM6 TRUE #undef STM32_GPT_USE_TIM6 // [!code focus]
#define STM32_GPT_USE_TIM6 TRUE // [!code focus]
``` ```
:::
### DAC Config ### DAC Config
@ -170,19 +180,25 @@ This driver uses the ChibiOS-PWM system to produce a square-wave on specific out
The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function.
A configuration example for the STM32F103C8 would be: A configuration example for the STM32F103C8 would be:
```c
//halconf.h: ::: code-group
#define HAL_USE_PWM TRUE ```c [halconf.h]
#define HAL_USE_PAL TRUE #pragma once
#define HAL_USE_PWM TRUE // [!code focus]
#define HAL_USE_PAL TRUE // [!code focus]
#include_next <halconf.h> #include_next <halconf.h>
``` ```
```c [mcuconf.h]
#pragma once
```c
// mcuconf.h:
#include_next <mcuconf.h> #include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE #undef STM32_PWM_USE_TIM1 // [!code focus]
#define STM32_PWM_USE_TIM1 TRUE // [!code focus]
``` ```
:::
If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions
- TIM1_CH1 = PA8 <- alternate0 - TIM1_CH1 = PA8 <- alternate0

View File

@ -13,7 +13,7 @@ The following macros provide basic control of GPIOs and are found in `platforms/
|`gpio_set_pin_input_low(pin)` |Set pin as input with builtin pull-down resistor (unavailable on AVR)| |`gpio_set_pin_input_low(pin)` |Set pin as input with builtin pull-down resistor (unavailable on AVR)|
|`gpio_set_pin_output(pin)` |Set pin as output (alias of `gpio_set_pin_output_push_pull`) | |`gpio_set_pin_output(pin)` |Set pin as output (alias of `gpio_set_pin_output_push_pull`) |
|`gpio_set_pin_output_push_pull(pin)` |Set pin as output, push/pull mode | |`gpio_set_pin_output_push_pull(pin)` |Set pin as output, push/pull mode |
|`gpio_set_pin_output_open_drain(pin)`|Set pin as output, open-drain mode (unavailable on AVR and ATSAM) | |`gpio_set_pin_output_open_drain(pin)`|Set pin as output, open-drain mode (unavailable on AVR) |
|`gpio_write_pin_high(pin)` |Set pin level as high, assuming it is an output | |`gpio_write_pin_high(pin)` |Set pin level as high, assuming it is an output |
|`gpio_write_pin_low(pin)` |Set pin level as low, assuming it is an output | |`gpio_write_pin_low(pin)` |Set pin level as low, assuming it is an output |
|`gpio_write_pin(pin, level)` |Set pin level, assuming it is an output | |`gpio_write_pin(pin, level)` |Set pin level, assuming it is an output |

View File

@ -54,18 +54,25 @@ The ATmega16/32U2 does not possess I2C functionality, and so cannot use this dri
You'll need to determine which pins can be used for I2C -- a an example, STM32 parts generally have multiple I2C peripherals, labeled I2C1, I2C2, I2C3 etc. You'll need to determine which pins can be used for I2C -- a an example, STM32 parts generally have multiple I2C peripherals, labeled I2C1, I2C2, I2C3 etc.
To enable I2C, modify your board's `halconf.h` to enable I2C: To enable I2C, modify your board's `halconf.h` to enable I2C, then modify your board's `mcuconf.h` to enable the peripheral you've chosen:
```c ::: code-group
#define HAL_USE_I2C TRUE ```c [halconf.h]
#pragma once
#define HAL_USE_I2C TRUE // [!code focus]
#include_next <halconf.h>
``` ```
```c [mcuconf.h]
#pragma once
Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: #include_next <mcuconf.h>
```c #undef STM32_I2C_USE_I2C2 // [!code focus]
#undef STM32_I2C_USE_I2C2 #define STM32_I2C_USE_I2C2 TRUE // [!code focus]
#define STM32_I2C_USE_I2C2 TRUE
``` ```
:::
|`mcuconf.h` Setting |Description |Default| |`mcuconf.h` Setting |Description |Default|
|----------------------------|----------------------------------------------------------------------------------|-------| |----------------------------|----------------------------------------------------------------------------------|-------|

View File

@ -12,8 +12,6 @@ The Serial driver powers the [Split Keyboard](../features/split_keyboard) featur
Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards. Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards.
::: :::
<hr>
## Bitbang ## Bitbang
This is the Default driver, 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. This is the Default driver, 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.
@ -53,11 +51,15 @@ SERIAL_DRIVER = bitbang
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 #define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
``` ```
3. On ARM platforms you must turn on ChibiOS `PAL_USE_CALLBACKS` feature: 3. On ARM platforms you must turn on ChibiOS PAL callbacks:
* In `halconf.h` add the line `#define PAL_USE_CALLBACKS TRUE`. ```c
#pragma once
<hr> #define PAL_USE_CALLBACKS TRUE // [!code focus]
#include_next <halconf.h>
```
## USART Half-duplex ## USART Half-duplex
@ -117,8 +119,6 @@ For STM32 MCUs several GPIO configuration options can be changed as well. See th
4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem). 4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
<hr>
## USART Full-duplex ## USART Full-duplex
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 over all others where possible. Due to its internal design Full-duplex is slightly more efficient than the Half-duplex driver, but Full-duplex should be primarily chosen if Half-duplex operation is not supported by the controller's USART peripheral. 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 over all others where possible. Due to its internal design Full-duplex is slightly more efficient than the Half-duplex driver, but Full-duplex should be primarily chosen if Half-duplex operation is not supported by the controller's USART peripheral.
@ -179,34 +179,42 @@ For STM32 MCUs several GPIO configuration options, including the ability for `TX
4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem). 4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
<hr>
## Choosing a driver subsystem ## Choosing a driver subsystem
### The `SERIAL` driver ### 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: 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: 1. Enable the SERIAL subsystem in the ChibiOS HAL.
Add the following to your keyboard's `halconf.h`, creating it if necessary:
```c ```c
#define HAL_USE_SERIAL TRUE #pragma once
#define HAL_USE_SERIAL TRUE // [!code focus]
#include_next <halconf.h>
``` ```
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. 2. 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: Add the following to your keyboard's `mcuconf.h`, creating it if necessary:
```c ```c
#pragma once
#include_next <mcuconf.h> #include_next <mcuconf.h>
#undef STM32_SERIAL_USE_USARTn #undef STM32_SERIAL_USE_USARTn // [!code focus]
#define STM32_SERIAL_USE_USARTn TRUE #define STM32_SERIAL_USE_USARTn TRUE // [!code focus]
``` ```
Where 'n' matches the peripheral number of your selected USART on the MCU. 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`. 3. 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`.
Add the following to your keyboard's `config.h`:
```c ```c
#define SERIAL_USART_DRIVER SD3 #define SERIAL_USART_DRIVER SD3
@ -218,26 +226,36 @@ The `SIO` Subsystem was added to ChibiOS with the 21.11 release and is only supp
Follow these steps in order to activate it: Follow these steps in order to activate it:
1. In your keyboards `halconf.h` add: 1. Enable the SIO subsystem in the ChibiOS HAL.
Add the following to your keyboard's `halconf.h`, creating it if necessary:
```c ```c
#define HAL_USE_SIO TRUE #pragma once
#define HAL_USE_SIO TRUE // [!code focus]
#include_next <halconf.h>
``` ```
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. 2. 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: Add the following to your keyboard's `mcuconf.h`, creating it if necessary:
```c ```c
#pragma once
#include_next <mcuconf.h> #include_next <mcuconf.h>
#undef STM32_SIO_USE_USARTn #undef STM32_SIO_USE_USARTn // [!code focus]
#define STM32_SIO_USE_USARTn TRUE #define STM32_SIO_USE_USARTn TRUE // [!code focus]
``` ```
Where 'n' matches the peripheral number of your selected USART on the MCU. Where *n* matches the peripheral number of your selected USART on the MCU.
3. In the keyboard's `config.h` file: 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`. 3. 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`.
Add the following to your keyboard's `config.h`:
```c ```c
#define SERIAL_USART_DRIVER SIOD3 #define SERIAL_USART_DRIVER SIOD3
@ -254,8 +272,6 @@ Optionally, the PIO peripheral utilized for split communication can be changed w
The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on. 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 ## Advanced Configuration
There are several advanced configuration options that can be defined in your keyboards `config.h` file: There are several advanced configuration options that can be defined in your keyboards `config.h` file:
@ -265,9 +281,11 @@ There are several advanced configuration options that can be defined in your key
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. 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 ```c
#define SELECT_SOFT_SERIAL_SPEED {#} #define SELECT_SOFT_SERIAL_SPEED n
``` ```
Where *n* is one of:
| Speed | Bitbang | Half-duplex and Full-duplex | | Speed | Bitbang | Half-duplex and Full-duplex |
| ----- | -------------------------- | --------------------------- | | ----- | -------------------------- | --------------------------- |
| `0` | 189000 baud (experimental) | 460800 baud | | `0` | 189000 baud (experimental) | 460800 baud |
@ -287,8 +305,6 @@ This is the default time window in milliseconds in which a successful communicat
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20 #define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
``` ```
<hr>
## Troubleshooting ## 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: 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:

View File

@ -32,20 +32,27 @@ You may use more than one slave select pin, not just the `SS` pin. This is usefu
You'll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc. You'll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc.
To enable SPI, modify your board's `halconf.h` to enable SPI: To enable SPI, modify your board's `halconf.h` to enable SPI, then modify your board's `mcuconf.h` to enable the peripheral you've chosen:
```c ::: code-group
#define HAL_USE_SPI TRUE ```c [halconf.h]
#define SPI_USE_WAIT TRUE #pragma once
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#define HAL_USE_SPI TRUE // [!code focus]
#define SPI_USE_WAIT TRUE // [!code focus]
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD // [!code focus]
#include_next <halconf.h>
``` ```
```c [mcuconf.h]
#pragma once
Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: #include_next <mcuconf.h>
```c #undef STM32_SPI_USE_SPI2 // [!code focus]
#undef STM32_SPI_USE_SPI2 #define STM32_SPI_USE_SPI2 TRUE // [!code focus]
#define STM32_SPI_USE_SPI2 TRUE
``` ```
:::
Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303.

View File

@ -35,8 +35,12 @@ You'll need to determine which pins can be used for UART -- as an example, STM32
To enable UART, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: To enable UART, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example:
```c ```c
#undef STM32_SERIAL_USE_USART2 #pragma once
#define STM32_SERIAL_USE_USART2 TRUE
#include_next <mcuconf.h>
#undef STM32_SERIAL_USE_USART2 // [!code focus]
#define STM32_SERIAL_USE_USART2 TRUE // [!code focus]
``` ```
Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303.

View File

@ -160,15 +160,23 @@ To configure the DI pin for open drain configuration, add the following to your
Depending on the ChibiOS board configuration, you may need to enable SPI at the keyboard level. For STM32, this would look like: Depending on the ChibiOS board configuration, you may need to enable SPI at the keyboard level. For STM32, this would look like:
`halconf.h`: ::: code-group
```c ```c [halconf.h]
#define HAL_USE_SPI TRUE #pragma once
#define HAL_USE_SPI TRUE // [!code focus]
#include_next <halconf.h>
``` ```
`mcuconf.h`: ```c [mcuconf.h]
```c #pragma once
#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE #include_next <mcuconf.h>
#undef STM32_SPI_USE_SPI1 // [!code focus]
#define STM32_SPI_USE_SPI1 TRUE // [!code focus]
``` ```
:::
The following `define`s apply only to the `spi` driver: The following `define`s apply only to the `spi` driver:
@ -213,15 +221,23 @@ The following `#define`s apply only to the PIO driver:
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like: Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
`halconf.h`: ::: code-group
```c ```c [halconf.h]
#define HAL_USE_PWM TRUE #pragma once
#define HAL_USE_PWM TRUE // [!code focus]
#include_next <halconf.h>
``` ```
`mcuconf.h`: ```c [mcuconf.h]
```c #pragma once
#undef STM32_PWM_USE_TIM2
#define STM32_PWM_USE_TIM2 TRUE #include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM2 // [!code focus]
#define STM32_PWM_USE_TIM2 TRUE // [!code focus]
``` ```
:::
The following `#define`s apply only to the `pwm` driver: The following `#define`s apply only to the `pwm` driver:
@ -236,18 +252,49 @@ The following `#define`s apply only to the `pwm` driver:
|`WS2812_PWM_COMPLEMENTARY_OUTPUT`|*Not defined* |Whether the PWM output is complementary (`TIMx_CHyN`) | |`WS2812_PWM_COMPLEMENTARY_OUTPUT`|*Not defined* |Whether the PWM output is complementary (`TIMx_CHyN`) |
::: tip ::: tip
Using a complementary timer output (`TIMx_CHyN`) is possible only for advanced-control timers (1, 8 and 20 on STM32), and the `STM32_PWM_USE_ADVANCED` option in `mcuconf.h` must be set to `TRUE`. Complementary outputs of general-purpose timers are not supported due to ChibiOS limitations. Using a complementary timer output (`TIMx_CHyN`) is possible only for advanced-control timers (1, 8 and 20 on STM32). Complementary outputs of general-purpose timers are not supported due to ChibiOS limitations.
::: :::
## API {#api} ## API {#api}
### `void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds)` {#api-ws2812-setleds} ### `void ws2812_init(void)` {#api-ws2812-init}
Send RGB data to the WS2812 LED chain. Initialize the LED driver. This function should be called first.
#### Arguments {#api-ws2812-setleds-arguments} ---
- `rgb_led_t *ledarray` ### `void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color}
A pointer to the LED array.
- `uint16_t number_of_leds` Set the color of a single LED. This function does not immediately update the LEDs; call `ws2812_flush()` after you are finished.
The length of the LED array.
#### Arguments {#api-ws2812-set-color-arguments}
- `int index`
The LED index in the WS2812 chain.
- `uint8_t red`
The red value to set.
- `uint8_t green`
The green value to set.
- `uint8_t blue`
The blue value to set.
---
### `void ws812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all}
Set the color of all LEDs.
#### Arguments {#api-ws2812-set-color-all-arguments}
- `uint8_t red`
The red value to set.
- `uint8_t green`
The green value to set.
- `uint8_t blue`
The blue value to set.
---
### `void ws2812_flush(void)` {#api-ws2812-flush}
Flush the PWM values to the LED chain.

View File

@ -34,7 +34,7 @@ On first run, the VIA code in the firmware will copy the keymap from flash memor
The simple fix for this is to clear the EEPROM. You can do this in several ways: The simple fix for this is to clear the EEPROM. You can do this in several ways:
* Hold the Bootmagic Lite key (usually top left/Escape) while plugging the board in, which will also place the board into bootloader mode; then unplug and replug the board. * Hold the Bootmagic key (usually top left/Escape) while plugging the board in, which will also place the board into bootloader mode; then unplug and replug the board.
* Press the `QK_CLEAR_EEPROM`/`EE_CLR` keycode if it is accessible on your keymap. * Press the `QK_CLEAR_EEPROM`/`EE_CLR` keycode if it is accessible on your keymap.
* Place the board into bootloader mode and hit the "Clear EEPROM" button. This may not be available for all bootloaders, and you may need to reflash the board afterwards. * Place the board into bootloader mode and hit the "Clear EEPROM" button. This may not be available for all bootloaders, and you may need to reflash the board afterwards.

View File

@ -11,7 +11,7 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|`RCTL(kc)`| |Hold Right Control and press `kc` | |`RCTL(kc)`| |Hold Right Control and press `kc` |
|`RSFT(kc)`| |Hold Right Shift and press `kc` | |`RSFT(kc)`| |Hold Right Shift and press `kc` |
|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` | |`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` |
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` | |`RGUI(kc)`|`RCMD(kc)`, `RWIN(kc)` |Hold Right GUI and press `kc` |
|`LSG(kc)` |`SGUI(kc)`, `SCMD(kc)`, `SWIN(kc)`|Hold Left Shift and GUI and press `kc` | |`LSG(kc)` |`SGUI(kc)`, `SCMD(kc)`, `SWIN(kc)`|Hold Left Shift and GUI and press `kc` |
|`LAG(kc)` | |Hold Left Alt and Left GUI and press `kc` | |`LAG(kc)` | |Hold Left Alt and Left GUI and press `kc` |
|`RSG(kc)` | |Hold Right Shift and Right GUI and press `kc` | |`RSG(kc)` | |Hold Right Shift and Right GUI and press `kc` |

View File

@ -21,6 +21,7 @@ The following converters are available at this time:
| `promicro` | `liatris` | | `promicro` | `liatris` |
| `promicro` | `imera` | | `promicro` | `imera` |
| `promicro` | `michi` | | `promicro` | `michi` |
| `promicro` | `svlinky` |
| `elite_c` | `stemcell` | | `elite_c` | `stemcell` |
| `elite_c` | `rp2040_ce` | | `elite_c` | `rp2040_ce` |
| `elite_c` | `elite_pi` | | `elite_c` | `elite_pi` |
@ -87,6 +88,7 @@ If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.co
| [Liatris](https://splitkb.com/products/liatris) | `liatris` | | [Liatris](https://splitkb.com/products/liatris) | `liatris` |
| [Imera](https://splitkb.com/products/imera) | `imera` | | [Imera](https://splitkb.com/products/imera) | `imera` |
| [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` | | [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` |
| [Svlinky](https://github.com/sadekbaroudi/svlinky) | `svlinky` |
Converter summary: Converter summary:
@ -105,6 +107,7 @@ Converter summary:
| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
| `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` | | `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` |
| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` | | `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
| `svlinky` | `-e CONVERT_TO=svlinky` | `CONVERT_TO=svlinky` | `#ifdef CONVERT_TO_SVLINKY` |
### Proton C {#proton_c} ### Proton C {#proton_c}
@ -170,6 +173,9 @@ The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro
Feature set is identical to [Adafruit KB2040](#kb2040). VBUS detection is enabled by default for superior split keyboard support. For more information, refer to the [Community Edition pinout](platformdev_rp2040#rp2040_ce) docs. Feature set is identical to [Adafruit KB2040](#kb2040). VBUS detection is enabled by default for superior split keyboard support. For more information, refer to the [Community Edition pinout](platformdev_rp2040#rp2040_ce) docs.
### Svlinky {#svlinky}
Feature set is a pro micro equivalent of the [RP2040 Community Edition](#rp2040_ce), except that two of the analog GPIO have been replaced with digital only GPIO. These two were moved to the FPC connector to support the [VIK specification](https://github.com/sadekbaroudi/vik). This means that if you are expecting analog support on all 4 pins as provided on a RP2040 Community Edition pinout, you will not have that. Please see the [Svlinky github page](https://github.com/sadekbaroudi/svlinky) for more details.
## Elite-C ## Elite-C

View File

@ -109,7 +109,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
} }
} }
``` ```
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EE_CLR` keycode or [Bootmagic Lite](features/bootmagic) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued. And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EE_CLR` keycode or [Bootmagic](features/bootmagic) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
```c ```c
void eeconfig_init_user(void) { // EEPROM is getting reset! void eeconfig_init_user(void) { // EEPROM is getting reset!

View File

@ -17,6 +17,9 @@ These functions allow you to activate layers in various ways. Note that layers a
* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed). * `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed).
* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps. * `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps.
See also the [Layer Lock key](features/layer_lock), which locks the highest
active layer until pressed again.
### Caveats {#caveats} ### Caveats {#caveats}
Currently, the `layer` argument of `LT()` is limited to layers 0-15, and the `kc` argument to the [Basic Keycode set](keycodes_basic), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 4 bits are used for the function identifier and 4 bits for the layer, leaving only 8 bits for the keycode. Currently, the `layer` argument of `LT()` is limited to layers 0-15, and the `kc` argument to the [Basic Keycode set](keycodes_basic), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 4 bits are used for the function identifier and 4 bits for the layer, leaving only 8 bits for the keycode.
@ -74,6 +77,7 @@ There are a number of functions (and variables) related to how you can use or ma
| `default_layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing default layer state. | | `default_layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing default layer state. |
| `default_layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing default layer state. | | `default_layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing default layer state. |
| `default_layer_debug(layer_mask)` | Prints out the current bit mask and highest active default layer to debugger console. | | `default_layer_debug(layer_mask)` | Prints out the current bit mask and highest active default layer to debugger console. |
| [`set_single_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer) | Sets the default layer, but does _not_ write it to persistent memory (EEPROM). |
| [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer) | Sets the default layer and writes it to persistent memory (EEPROM). | | [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer) | Sets the default layer and writes it to persistent memory (EEPROM). |
| [`update_tri_layer(x, y, z)`](ref_functions.md#update_tri_layerx-y-z) | Checks if layers `x` and `y` are both on, and sets `z` based on that (on if both on, otherwise off). | | [`update_tri_layer(x, y, z)`](ref_functions.md#update_tri_layerx-y-z) | Checks if layers `x` and `y` are both on, and sets `z` based on that (on if both on, otherwise off). |
| [`update_tri_layer_state(state, x, y, z)`](ref_functions.md#update_tri_layer_statestate-x-y-z) | Does the same as `update_tri_layer(x, y, z)`, but from `layer_state_set_*` functions. | | [`update_tri_layer_state(state, x, y, z)`](ref_functions.md#update_tri_layer_statestate-x-y-z) | Does the same as `update_tri_layer(x, y, z)`, but from `layer_state_set_*` functions. |

View File

@ -42,38 +42,7 @@ You can define up to 32 macros in a `keymap.json` file, as used by [Configurator
### Selecting Your Host Keyboard Layout ### Selecting Your Host Keyboard Layout
If you type in a language other than English, or use a non-QWERTY layout like Colemak, Dvorak, or Workman, you may have set your computer's input language to match this layout. This presents a challenge when creating macros - you may need to type different keys to get the same letters! To address this you can add the `host_language` key to your `keymap.json`, like so: If you type in a language other than English, or use a non-QWERTY layout like Colemak, Dvorak, or Workman, you may have set your computer's input language to match this layout. This presents a challenge when creating macros — you may need to type different keys to get the same letters! To address this you can use [language-specific keycodes](reference_keymap_extras).
```json
{
"keyboard": "handwired/my_macropad",
"keymap": "my_keymap",
"host_language": "dvorak",
"macros": [
["Hello, World!"]
],
"layout": "LAYOUT_all",
"layers": [
["QK_MACRO_0"]
]
}
```
The current list of available languages is:
| belgian | bepo | br_abnt2 | canadian_multilingual |
|:-------:|:----:|:--------:|:---------------------:|
| **colemak** | **croatian** | **czech** | **danish** |
| **dvorak_fr** | **dvorak** | **dvp** | **estonian** |
| **finnish** | **fr_ch** | **french_afnor** | **french** |
| **french_osx** | **german_ch** | **german** | **german_osx** |
| **hungarian** | **icelandic** | **italian** | **italian_osx_ansi** |
| **italian_osx_iso** | **jis** | **latvian** | **lithuanian_azerty** |
| **lithuanian_qwerty** | **norman** | **norwegian** | **portuguese** |
| **portuguese_osx_iso** | **romanian** | **serbian_latin** | **slovak** |
| **slovenian** | **spanish_dvorak** | **spanish_latin_america** | **spanish** |
| **swedish** | **turkish_f** | **turkish_q** | **uk** |
| **us_international** | **workman** | **workman_zxcvm** |
### Macro Basics ### Macro Basics

View File

@ -161,15 +161,23 @@ Note that the choice of timer may conflict with the [Audio](audio) feature.
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like: Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
`halconf.h`: ::: code-group
```c ```c [halconf.h]
#define HAL_USE_PWM TRUE #pragma once
#define HAL_USE_PWM TRUE // [!code focus]
#include_next <halconf.h>
``` ```
`mcuconf.h`: ```c [mcuconf.h]
```c #pragma once
#undef STM32_PWM_USE_TIM4
#define STM32_PWM_USE_TIM4 TRUE #include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM4 // [!code focus]
#define STM32_PWM_USE_TIM4 TRUE // [!code focus]
``` ```
:::
The following `#define`s apply only to the `pwm` driver: The following `#define`s apply only to the `pwm` driver:
@ -187,15 +195,23 @@ Refer to the ST datasheet for your particular MCU to determine these values. For
Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like: Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like:
`halconf.h`: ::: code-group
```c ```c [halconf.h]
#define HAL_USE_GPT TRUE #pragma once
#define HAL_USE_GPT TRUE // [!code focus]
#include_next <halconf.h>
``` ```
`mcuconf.h`: ```c [mcuconf.h]
```c #pragma once
#undef STM32_GPT_USE_TIM15
#define STM32_GPT_USE_TIM15 TRUE #include_next <mcuconf.h>
#undef STM32_GPT_USE_TIM15 // [!code focus]
#define STM32_GPT_USE_TIM15 TRUE // [!code focus]
``` ```
:::
The following `#define`s apply only to the `timer` driver: The following `#define`s apply only to the `timer` driver:

View File

@ -152,14 +152,15 @@ In order to use these features, the following configuration options and function
| Config Flag | Function | Description | | Config Flag | Function | Description |
|-----------------------------|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------| |-----------------------------|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| `COMBO_TERM_PER_COMBO` | uint16_t get_combo_term(uint16_t index, combo_t \*combo) | Optional per-combo timeout window. (default: `COMBO_TERM`) | | `COMBO_TERM_PER_COMBO` | `uint16_t get_combo_term(uint16_t combo_index, combo_t *combo)` | Optional per-combo timeout window. (default: `COMBO_TERM`) |
| `COMBO_MUST_HOLD_PER_COMBO` | bool get_combo_must_hold(uint16_t index, combo_t \*combo) | Controls if a given combo should fire immediately on tap or if it needs to be held. (default: `false`) | | `COMBO_MUST_HOLD_PER_COMBO` | `bool get_combo_must_hold(uint16_t combo_index, combo_t *combo)` | Controls if a given combo should fire immediately on tap or if it needs to be held. (default: `false`) |
| `COMBO_MUST_TAP_PER_COMBO` | bool get_combo_must_tap(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if tapped within `COMBO_HOLD_TERM`. (default: `false`) | | `COMBO_MUST_TAP_PER_COMBO` | `bool get_combo_must_tap(uint16_t combo_index, combo_t *combo)` | Controls if a given combo should fire only if tapped within `COMBO_HOLD_TERM`. (default: `false`) |
| `COMBO_MUST_PRESS_IN_ORDER_PER_COMBO` | bool get_combo_must_press_in_order(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if its keys are pressed in order. (default: `true`) | | `COMBO_MUST_PRESS_IN_ORDER_PER_COMBO` | `bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo)` | Controls if a given combo should fire only if its keys are pressed in order. (default: `true`) |
Examples: Examples:
```c ```c
uint16_t get_combo_term(uint16_t index, combo_t *combo) { #ifdef COMBO_TERM_PER_COMBO
uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) {
// decide by combo->keycode // decide by combo->keycode
switch (combo->keycode) { switch (combo->keycode) {
case KC_X: case KC_X:
@ -167,7 +168,7 @@ uint16_t get_combo_term(uint16_t index, combo_t *combo) {
} }
// or with combo index, i.e. its name from enum. // or with combo index, i.e. its name from enum.
switch (index) { switch (combo_index) {
case COMBO_NAME_HERE: case COMBO_NAME_HERE:
return 9001; return 9001;
} }
@ -182,8 +183,10 @@ uint16_t get_combo_term(uint16_t index, combo_t *combo) {
return COMBO_TERM; return COMBO_TERM;
} }
#endif
bool get_combo_must_hold(uint16_t index, combo_t *combo) { #ifdef COMBO_MUST_HOLD_PER_COMBO
bool get_combo_must_hold(uint16_t combo_index, combo_t *combo) {
// Same as above, decide by keycode, the combo index, or by the keys in the chord. // Same as above, decide by keycode, the combo index, or by the keys in the chord.
if (KEYCODE_IS_MOD(combo->keycode) || if (KEYCODE_IS_MOD(combo->keycode) ||
@ -192,15 +195,17 @@ bool get_combo_must_hold(uint16_t index, combo_t *combo) {
return true; return true;
} }
switch (index) { switch (combo_index) {
case COMBO_NAME_HERE: case COMBO_NAME_HERE:
return true; return true;
} }
return false; return false;
} }
#endif
bool get_combo_must_tap(uint16_t index, combo_t *combo) { #ifdef COMBO_MUST_TAP_PER_COMBO
bool get_combo_must_tap(uint16_t combo_index, combo_t *combo) {
// If you want all combos to be tap-only, just uncomment the next line // If you want all combos to be tap-only, just uncomment the next line
// return true // return true
@ -219,7 +224,9 @@ bool get_combo_must_tap(uint16_t index, combo_t *combo) {
return false; return false;
} }
#endif
#ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO
bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) {
switch (combo_index) { switch (combo_index) {
/* List combos here that you want to only activate if their keys /* List combos here that you want to only activate if their keys
@ -231,6 +238,7 @@ bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) {
return false; return false;
} }
} }
#endif
``` ```
### Generic hook to (dis)allow a combo activation ### Generic hook to (dis)allow a combo activation
@ -307,6 +315,50 @@ bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key
return false; return false;
} }
``` ```
### Customizable key repress
By defining `COMBO_PROCESS_KEY_REPRESS` and implementing `bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode)` you can run your custom code when you repress just released key of a combo. By combining it with custom `process_combo_event` we can for example make special handling for Alt+Tab to switch windows, which, on combo F+G activation, registers Alt and presses Tab - then we can switch windows forward by releasing G and pressing it again, or backwards with F key. Here's the full example:
```c
enum combos {
CMB_ALTTAB
};
const uint16_t PROGMEM combo_alttab[] = {KC_F, KC_G, COMBO_END};
combo_t key_combos[COMBO_LENGTH] = {
[CMB_ALTTAB] = COMBO(combo_alttab, KC_NO), // KC_NO to leave processing for process_combo_event
};
void process_combo_event(uint16_t combo_index, bool pressed) {
switch (combo_index) {
case CMB_ALTTAB:
if (pressed) {
register_mods(MOD_LALT);
tap_code(KC_TAB);
} else {
unregister_mods(MOD_LALT);
}
break;
}
}
bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) {
switch (combo_index) {
case CMB_ALTTAB:
switch (keycode) {
case KC_F:
tap_code16(S(KC_TAB));
return true;
case KC_G:
tap_code(KC_TAB);
return true;
}
}
return false;
}
```
### Layer independent combos ### Layer independent combos
If you, for example, use multiple base layers for different key layouts, one for QWERTY, and another one for Colemak, you might want your combos to work from the same key positions on all layers. Defining the same combos again for another layout is redundant and takes more memory. The solution is to just check the keycodes from one layer. If you, for example, use multiple base layers for different key layouts, one for QWERTY, and another one for Colemak, you might want your combos to work from the same key positions on all layers. Defining the same combos again for another layout is redundant and takes more memory. The solution is to just check the keycodes from one layer.

View File

@ -1,6 +1,6 @@
# Command # Command
Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic Lite](bootmagic). There is a lot of overlap between this functionality and the [Magic Keycodes](../keycodes_magic). Wherever possible we encourage you to use that feature instead of Command. Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic](bootmagic). There is a lot of overlap between this functionality and the [Magic Keycodes](../keycodes_magic). Wherever possible we encourage you to use that feature instead of Command.
On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`: On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`:

View File

@ -1,6 +1,6 @@
# Joystick {#joystick} # Joystick {#joystick}
This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](../drivers/adc), or can be virtual, so that its value is provided by your code. This feature provides game controller input as a joystick device supporting up to 6 axes, 32 buttons and a hat switch. Axes can be read either from an [ADC-capable input pin](../drivers/adc), or can be virtual, so that its value is provided by your code.
An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC. An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC.
@ -18,6 +18,8 @@ By default the joystick driver is `analog`, but you can change this with:
JOYSTICK_DRIVER = digital JOYSTICK_DRIVER = digital
``` ```
When using `analog` with ARM, [you must use 3.3v with your Joystick](../drivers/adc). Although ARM boards such as the [Helios](https://keeb.supply/products/0xcb-helios) have 5v pin output, the ADC driver does not support it.
## Configuration {#configuration} ## Configuration {#configuration}
By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`: By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`:
@ -35,6 +37,42 @@ By default, two axes and eight buttons are defined, with a reported resolution o
You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs. You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs.
::: :::
### Hat Switch {#hat-switch}
To enable the 8-way hat switch, add the following to your `config.h`:
```c
#define JOYSTICK_HAS_HAT
````
The position can be set by calling `joystick_set_hat(value)`. The range of values moves clockwise from the top (ie. north), with the default "center" position represented by a value of `-1`:
```
0
7 N 1
NW .--'--. NE
/ \
6 W | -1 | E 2
\ /
SW '--.--' SE
5 S 3
4
```
Alternatively you can use these predefined names:
|Define |Value|Angle|
|------------------------|-----|-----|
|`JOYSTICK_HAT_CENTER` |`-1` | |
|`JOYSTICK_HAT_NORTH` |`0` |0° |
|`JOYSTICK_HAT_NORTHEAST`|`1` |45° |
|`JOYSTICK_HAT_EAST` |`2` |90° |
|`JOYSTICK_HAT_SOUTHEAST`|`3` |135° |
|`JOYSTICK_HAT_SOUTH` |`4` |180° |
|`JOYSTICK_HAT_SOUTHWEST`|`5` |225° |
|`JOYSTICK_HAT_WEST` |`6` |270° |
|`JOYSTICK_HAT_NORTHWEST`|`7` |315° |
### Axes {#axes} ### Axes {#axes}
When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`. When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`.
@ -147,6 +185,8 @@ Contains the state of the joystick.
A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`. A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`.
- `int16_t axes[]` - `int16_t axes[]`
An array of analog values for each defined axis. An array of analog values for each defined axis.
- `int8_t hat`
The hat switch position.
- `bool dirty` - `bool dirty`
Whether the current state needs to be sent to the host. Whether the current state needs to be sent to the host.
@ -220,3 +260,14 @@ Set the value of the given axis.
The axis to set the value of. The axis to set the value of.
- `int16_t value` - `int16_t value`
The value to set. The value to set.
---
### `void joystick_set_hat(int8_t value)` {#api-joystick-set-hat}
Set the position of the hat switch.
#### Arguments {#api-joystick-set-hat-arguments}
- `int8_t value`
The hat switch position to set.

139
docs/features/layer_lock.md Normal file
View File

@ -0,0 +1,139 @@
# Layer Lock
Some [layer switches](../feature_layers#switching-and-toggling-layers) access
the layer by holding the key, including momentary layer `MO(layer)` and layer
tap `LT(layer, key)` keys. You may sometimes need to stay on the layer for a
long period of time. Layer Lock "locks" the current layer to stay on, supposing
it was accessed by one of:
* `MO(layer)` momentary layer switch
* `LT(layer, key)` layer tap
* `OSL(layer)` one-shot layer
* `TT(layer)` layer tap toggle
* `LM(layer, mod)` layer-mod key (the layer is locked, but not the mods)
Press the Layer Lock key again to unlock the layer. Additionally, when a layer
is locked, layer switch keys that turn off the layer such as `TO(other_layer)`
will unlock it.
## How do I enable Layer Lock
In your rules.mk, add:
```make
LAYER_LOCK_ENABLE = yes
```
Pick a key in your keymap on a layer you intend to lock, and assign it the
keycode `QK_LAYER_LOCK` (short alias `QK_LLCK`). Note that locking the base
layer has no effect, so typically, this key is used on layers above the base
layer.
## Example use
Consider a keymap with the following base layer.
![Base layer with a MO(NAV) key.](https://i.imgur.com/DkEhj9x.png)
The highlighted key is a momentary layer switch `MO(NAV)`. Holding it accesses a
navigation layer.
![Nav layer with a Layer Lock key.](https://i.imgur.com/2wUZNWk.png)
Holding the NAV key is fine for brief use, but awkward to continue holding when
using navigation functions continuously. The Layer Lock key comes to the rescue:
1. Hold the NAV key, activating the navigation layer.
2. Tap Layer Lock.
3. Release NAV. The navigation layer stays on.
4. Make use of the arrow keys, etc.
5. Tap Layer Lock or NAV again to turn the navigation layer back off.
A variation that would also work is to put the Layer Lock key on the base layer
and make other layers transparent (`KC_TRNS`) in that position. Pressing the
Layer Lock key locks (or unlocks) the highest active layer, regardless of which
layer the Layer Lock key is on.
## Idle timeout
Optionally, Layer Lock may be configured to unlock if the keyboard is idle
for some time. In config.h, define `LAYER_LOCK_IDLE_TIMEOUT` in units of
milliseconds:
```c
#define LAYER_LOCK_IDLE_TIMEOUT 60000 // Turn off after 60 seconds.
```
## Functions
Use the following functions to query and manipulate the layer lock state.
| Function | Description |
|----------------------------|------------------------------------|
| `is_layer_locked(layer)` | Checks whether `layer` is locked. |
| `layer_lock_on(layer)` | Locks and turns on `layer`. |
| `layer_lock_off(layer)` | Unlocks and turns off `layer`. |
| `layer_lock_invert(layer)` | Toggles whether `layer` is locked. |
## Representing the current Layer Lock state
There is an optional callback `layer_lock_set_user()` that gets called when a
layer is locked or unlocked. This is useful to represent the current lock state
for instance by setting an LED. In keymap.c, define
```c
bool layer_lock_set_user(layer_state_t locked_layers) {
// Do something like `set_led(is_layer_locked(NAV));`
return true;
}
```
The argument `locked_layers` is a bitfield in which the kth bit is on if the kth
layer is locked. Alternatively, you can use `is_layer_locked(layer)` to check if
a given layer is locked.
## Combine Layer Lock with a mod-tap
It is possible to create a [mod-tap MT key](../mod_tap) that acts as a modifier
on hold and Layer Lock on tap. Since Layer Lock is not a [basic
keycode](../keycodes_basic), attempting `MT(mod, QK_LLCK)` is invalid does not
work directly, yet this effect can be achieved through [changing the tap
function](../mod_tap#changing-tap-function). For example, the following
implements a `SFTLLCK` key that acts as Shift on hold and Layer Lock on tap:
```c
#define SFTLLCK LSFT_T(KC_0)
// Use SFTLLCK in your keymap...
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case SFTLLCK:
if (record->tap.count) {
if (record->event.pressed) {
// Toggle the lock on the highest layer.
layer_lock_invert(get_highest_layer(layer_state));
}
return false;
}
break;
// Other macros...
}
return true;
}
```
In the above, `KC_0` is an arbitrary placeholder for the tapping keycode. This
keycode will never be sent, so any basic keycode will do. In
`process_record_user()`, the tap press event is changed to toggle the lock on
the highest layer. Layer Lock can be combined with a [layer-tap LT
key](../feature_layers#switching-and-toggling-layers) similarly.

View File

@ -70,17 +70,33 @@ The process is done in steps, generating a number of intermediate results until
We therefore resort to debouncing the result until it has been stable for a given amount of milliseconds. We therefore resort to debouncing the result until it has been stable for a given amount of milliseconds.
This amount can be configured, in case your board is not stable within the default debouncing time of 200ms. This amount can be configured, in case your board is not stable within the default debouncing time of 200ms.
## KVM and USB switches
Some KVM and USB switches may not trigger the USB controller on the keyboard to fully reset upon switching machines.
If your keyboard does not redetect the OS in this situation, you can force the keyboard to reset when the USB initialization event is detected, forcing the USB controller to be reconfigured.
## Configuration Options ## Configuration Options
* `#define OS_DETECTION_DEBOUNCE 200` * `#define OS_DETECTION_DEBOUNCE 250`
* defined the debounce time for OS detection, in milliseconds * defined the debounce time for OS detection, in milliseconds
* defaults to 250ms
* `#define OS_DETECTION_KEYBOARD_RESET` * `#define OS_DETECTION_KEYBOARD_RESET`
* enables the keyboard reset upon a USB device reinitilization, such as switching devices on some KVMs * enables the keyboard reset upon a USB device reinitilization
* this setting may help with detection issues when switching between devices on some KVMs (see [Troubleshooting](#troubleshooting))
* `#define OS_DETECTION_SINGLE_REPORT`
* allows the report callbacks to be called only once, when the OS detection result is considered stable
* subsequent changes in the detection results, if any, are ignored
* this setting may help with delayed stability issues when switching devices on some KVMs (see [Troubleshooting](#troubleshooting))
## Troubleshooting
Some KVMs and USB switches may cause issues when the OS detection is turned on.
Here is a list of common issues and how to fix them:
* **Problem**: _keyboard won't redetect the OS when switching between machines using a KVM_
* **Explanation**: some KVMs keep the USB controller powered on during the switch and OS
detection happens when the USB device description is being assembled.
* **Solution**: use `OS_DETECTION_KEYBOARD_RESET` to force the keyboard to reset upon switching.
* **Problem**: _keyboard OS detection callback gets invoked even minuted after startup_
* **Explanation**: some OSes, notably macOS on ARM-based Macs, may cause this behavior.
The actual cause is not known at this time.'
* **Solution**: use `OS_DETECTION_SINGLE_REPORT` to suppress repeated callback invocations.
## Debug ## Debug

View File

@ -394,6 +394,7 @@ Ideally, new sensor hardware should be added to `drivers/sensors/` and `quantum/
| Setting | Description | Default | | Setting | Description | Default |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ | | `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ |
| `WHEEL_EXTENDED_REPORT` | (Optional) Enables support for extended wheel reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ |
| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | | `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_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_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |

View File

@ -90,18 +90,22 @@ PS2_ENABLE = yes
PS2_DRIVER = interrupt PS2_DRIVER = interrupt
``` ```
In your keyboard config.h: In your keyboard `config.h`:
```c ```c
#define PS2_CLOCK_PIN A8 #define PS2_CLOCK_PIN A8
#define PS2_DATA_PIN A9 #define PS2_DATA_PIN A9
``` ```
And in the chibios specifig halconf.h: And in the ChibiOS specific `halconf.h`:
```c
#define PAL_USE_CALLBACKS TRUE
```
```c
#pragma once
#define PAL_USE_CALLBACKS TRUE // [!code focus]
#include_next <halconf.h>
```
### USART Version {#usart-version} ### USART Version {#usart-version}

View File

@ -81,38 +81,21 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
## Keycodes {#keycodes} ## Keycodes {#keycodes}
All RGB keycodes are currently shared with the RGBLIGHT system:
|Key |Aliases |Description | |Key |Aliases |Description |
|-------------------|----------|--------------------------------------------------------------------------------------| |-------------------------------|---------|-----------------------------------|
|`RGB_TOG` | |Toggle RGB lighting on or off | |`QK_RGB_MATRIX_ON` |`RM_ON` |Turn on RGB Matrix |
|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | |`QK_RGB_MATRIX_OFF` |`RM_OFF` |Turn off RGB Matrix |
|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held | |`QK_RGB_MATRIX_TOGGLE` |`RM_TOGG`|Toggle RGB Matrix on or off |
|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | |`QK_RGB_MATRIX_MODE_NEXT` |`RM_NEXT`|Cycle through animations |
|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | |`QK_RGB_MATRIX_MODE_PREVIOUS` |`RM_PREV`|Cycle through animations in reverse|
|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | |`QK_RGB_MATRIX_HUE_UP` |`RM_HUEU`|Cycle through hue |
|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | |`QK_RGB_MATRIX_HUE_DOWN` |`RM_HUED`|Cycle through hue in reverse |
|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | |`QK_RGB_MATRIX_SATURATION_UP` |`RM_SATU`|Increase the saturation |
|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | |`QK_RGB_MATRIX_SATURATION_DOWN`|`RM_SATD`|Decrease the saturation |
|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held| |`QK_RGB_MATRIX_VALUE_UP` |`RM_VALU`|Increase the brightness level |
|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held| |`QK_RGB_MATRIX_VALUE_DOWN` |`RM_VALD`|Decrease the brightness level |
|`RGB_MODE_PLAIN` |`RGB_M_P` |Static (no animation) mode | |`QK_RGB_MATRIX_SPEED_UP` |`RM_SPDU`|Increase the animation speed |
|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | |`QK_RGB_MATRIX_SPEED_DOWN` |`RM_SPDD`|Decrease the animation speed |
|`RGB_MODE_RAINBOW` |`RGB_M_R` |Full gradient scrolling left to right (uses the `RGB_MATRIX_CYCLE_LEFT_RIGHT` mode) |
|`RGB_MODE_SWIRL` |`RGB_M_SW`|Full gradient spinning pinwheel around center of keyboard (uses `RGB_MATRIX_CYCLE_PINWHEEL` mode) |
* `RGB_MODE_*` keycodes will generally work, but not all of the modes are currently mapped to the correct effects for the RGB Matrix system.
`RGB_MODE_PLAIN`, `RGB_MODE_BREATHE`, `RGB_MODE_RAINBOW`, and `RGB_MODE_SWIRL` are the only ones that are mapped properly. The rest don't have a direct equivalent, and are not mapped.
::: tip
`RGB_*` keycodes cannot be used with functions like `tap_code16(RGB_HUD)` as they're not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead.
:::
::: warning
By default, if you have both the [RGB Light](rgblight) and the RGB Matrix feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature.
:::
## RGB Matrix Effects {#rgb-matrix-effects} ## RGB Matrix Effects {#rgb-matrix-effects}
@ -289,7 +272,7 @@ Solid reactive effects will pulse RGB light on key presses with user configurabl
#define RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE #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`). Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RM_SPDU`/`RM_SPDD`).
## Custom RGB Matrix Effects {#custom-rgb-matrix-effects} ## Custom RGB Matrix Effects {#custom-rgb-matrix-effects}
@ -396,7 +379,6 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
#define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set #define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
#define RGB_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set #define RGB_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set
#define RGB_MATRIX_DEFAULT_FLAGS LED_FLAG_ALL // Sets the default LED flags, if none has been set #define RGB_MATRIX_DEFAULT_FLAGS LED_FLAG_ALL // Sets the default LED flags, if none has been set
#define RGB_MATRIX_DISABLE_KEYCODES // disables control of rgb matrix by keycodes (must use code functions to control the feature)
#define RGB_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right. #define RGB_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right.
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR // If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
#define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards #define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards
@ -496,18 +478,18 @@ This example sets the modifiers to be a specific color based on the layer state.
```c ```c
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
HSV hsv = {0, 255, 255}; hsv_t hsv = {0, 255, 255};
if (layer_state_is(layer_state, 2)) { if (layer_state_is(layer_state, 2)) {
hsv = (HSV){130, 255, 255}; hsv = (hsv_t){130, 255, 255};
} else { } else {
hsv = (HSV){30, 255, 255}; hsv = (hsv_t){30, 255, 255};
} }
if (hsv.v > rgb_matrix_get_val()) { if (hsv.v > rgb_matrix_get_val()) {
hsv.v = rgb_matrix_get_val(); hsv.v = rgb_matrix_get_val();
} }
RGB rgb = hsv_to_rgb(hsv); rgb_t rgb = hsv_to_rgb(hsv);
for (uint8_t i = led_min; i < led_max; i++) { for (uint8_t i = led_min; i < led_max; i++) {
if (HAS_FLAGS(g_led_config.flags[i], 0x01)) { // 0x01 == LED_FLAG_MODIFIER if (HAS_FLAGS(g_led_config.flags[i], 0x01)) { // 0x01 == LED_FLAG_MODIFIER
@ -873,13 +855,13 @@ Set the global effect hue, saturation, and value (brightness). New state is not
--- ---
### `HSV rgb_matrix_get_hsv(void)` {#api-rgb-matrix-get-hsv} ### `hsv_t rgb_matrix_get_hsv(void)` {#api-rgb-matrix-get-hsv}
Get the current global effect hue, saturation, and value (brightness). Get the current global effect hue, saturation, and value (brightness).
#### Return Value {#api-rgb-matrix-get-hsv-return} #### Return Value {#api-rgb-matrix-get-hsv-return}
The current effect HSV as an `HSV` struct. The current effect HSV as an `hsv_t` struct.
--- ---

View File

@ -59,6 +59,10 @@ Changing the **Value** sets the overall brightness.<br>
## Keycodes ## Keycodes
::: warning
These keycodes also simultaneously control [RGB Matrix](rgb_matrix), if enabled. This behaviour is in the process of being deprecated, so during this time it is recommended to additionally include the dedicated RGB Matrix keycodes to your keymap, and add `#define RGB_MATRIX_DISABLE_SHARED_KEYCODES` to `config.h`.
:::
|Key |Aliases |Description | |Key |Aliases |Description |
|------------------------------|----------|---------------------------------------------------------------------| |------------------------------|----------|---------------------------------------------------------------------|
|`QK_UNDERGLOW_TOGGLE` |`UG_TOGG` |Toggle RGB lighting on or off | |`QK_UNDERGLOW_TOGGLE` |`UG_TOGG` |Toggle RGB lighting on or off |
@ -87,11 +91,6 @@ Changing the **Value** sets the overall brightness.<br>
These keycodes cannot be used with functions like `tap_code16()` as they are not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead. These keycodes cannot be used with functions like `tap_code16()` as they are not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead.
::: :::
::: warning
By default, if you have both the RGB Light and the [RGB Matrix](rgb_matrix) feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature.
:::
## Configuration ## Configuration
Your RGB lighting can be configured by placing these `#define`s in your `config.h`: Your RGB lighting can be configured by placing these `#define`s in your `config.h`:
@ -104,7 +103,6 @@ Your RGB lighting can be configured by placing these `#define`s in your `config.
|`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level | |`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level |
|`RGBLIGHT_SLEEP` |*Not defined* |If defined, the RGB lighting will be switched off when the host goes to sleep | |`RGBLIGHT_SLEEP` |*Not defined* |If defined, the RGB lighting will be switched off when the host goes to sleep |
|`RGBLIGHT_SPLIT` |*Not defined* |If defined, synchronization functionality for split keyboards is added | |`RGBLIGHT_SPLIT` |*Not defined* |If defined, synchronization functionality for split keyboards is added |
|`RGBLIGHT_DISABLE_KEYCODES`|*Not defined* |If defined, disables the ability to control RGB Light from the keycodes. You must use code functions to control the feature|
|`RGBLIGHT_DEFAULT_MODE` |`RGBLIGHT_MODE_STATIC_LIGHT`|The default mode to use upon clearing the EEPROM | |`RGBLIGHT_DEFAULT_MODE` |`RGBLIGHT_MODE_STATIC_LIGHT`|The default mode to use upon clearing the EEPROM |
|`RGBLIGHT_DEFAULT_HUE` |`0` (red) |The default hue to use upon clearing the EEPROM | |`RGBLIGHT_DEFAULT_HUE` |`0` (red) |The default hue to use upon clearing the EEPROM |
|`RGBLIGHT_DEFAULT_SAT` |`UINT8_MAX` (255) |The default saturation to use upon clearing the EEPROM | |`RGBLIGHT_DEFAULT_SAT` |`UINT8_MAX` (255) |The default saturation to use upon clearing the EEPROM |

View File

@ -1,4 +1,4 @@
# Bluetooth # Wireless / Bluetooth
## Bluetooth Known Supported Hardware ## Bluetooth Known Supported Hardware
@ -40,7 +40,19 @@ BLUETOOTH_DRIVER = bluefruit_le # or rn42
This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both. This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both.
| Key | Aliases | Description | | Key | Aliases | Description |
|---------------------|---------|----------------------------------------------| |-----------------------------|-----------|-----------------------------------------------------------------------------------------------|
|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth| | `QK_OUTPUT_AUTO` | `OU_AUTO` | Automatically switch to USB when plugged in, otherwise use wireless |
|`QK_OUTPUT_USB` |`OU_USB` |USB only | | `QK_OUTPUT_NEXT` | `OU_NEXT` | Cycle forwards through USB, Bluetooth, and 2.4GHz (when available) **(not yet implemented)** |
|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only | | `QK_OUTPUT_PREV` | `OU_PREV` | Cycle backwards through USB, Bluetooth, and 2.4GHz (when available) **(not yet implemented)** |
| `QK_OUTPUT_NONE` | `OU_NONE` | Disable all output **(not yet implemented)** |
| `QK_OUTPUT_USB` | `OU_USB` | Output to USB only |
| `QK_OUTPUT_2P4GHZ` | `OU_2P4G` | Output to 2.4GHz only **(not yet implemented)** |
| `QK_OUTPUT_BLUETOOTH` | `OU_BT` | Output to Bluetooth only |
| `QK_BLUETOOTH_PROFILE_NEXT` | `BT_NEXT` | Move to the next Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE_PREV` | `BT_PREV` | Move to the previous Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_UNPAIR` | `BT_UNPR` | Un-pair the current Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE1` | `BT_PRF1` | Swap to Bluetooth profile #1 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE2` | `BT_PRF2` | Swap to Bluetooth profile #2 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE3` | `BT_PRF3` | Swap to Bluetooth profile #3 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE4` | `BT_PRF4` | Swap to Bluetooth profile #4 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE5` | `BT_PRF5` | Swap to Bluetooth profile #5 **(not yet implemented)** |

View File

@ -53,7 +53,7 @@ QMK maintains [a fork of the LUFA DFU bootloader](https://github.com/qmk/lufa/tr
//#define QMK_LED E6 //#define QMK_LED E6
//#define QMK_SPEAKER C6 //#define QMK_SPEAKER C6
``` ```
Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic Lite](features/bootmagic), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader. Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic](features/bootmagic), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader.
The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string. The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string.
@ -209,7 +209,7 @@ To enable the additional features, add the following defines to your `config.h`:
//#define QMK_SPEAKER C6 //#define QMK_SPEAKER C6
``` ```
Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic Lite](features/bootmagic), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader. Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic](features/bootmagic), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader.
The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string. The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string.
@ -345,6 +345,39 @@ Flashing sequence:
3. Flash a .bin file 3. Flash a .bin file
4. Reset the device into application mode (may be done automatically) 4. Reset the device into application mode (may be done automatically)
## AT32 DFU
All AT32 MCUs come preloaded with a factory bootloader that cannot be modified nor deleted.
To ensure compatibility with the AT32-DFU bootloader, make sure this block is present in your `rules.mk`:
```make
# Bootloader selection
BOOTLOADER = at32-dfu
```
Compatible flashers:
* [dfu-util](https://dfu-util.sourceforge.net/) / `:dfu-util` target in QMK (recommended command line)
```
dfu-util -a 0 -d 2E3C:DF11 -s 0x8000000:leave -D <filename>
```
Flashing sequence:
1. Enter the bootloader using any of the following methods:
* Tap the `QK_BOOT` keycode
* If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
2. Wait for the OS to detect the device
3. Flash a .bin file
4. Reset the device into application mode (may be done automatically)
### `make` Targets
* `:dfu-util`: Waits until an AT32 bootloader device is available, and then flashes the firmware.
* `:dfu-util-split-left` and `:dfu-util-split-right`: Flashes the firmware as with `:dfu-util`, but also sets the handedness setting in EEPROM.
## tinyuf2 ## tinyuf2
Keyboards may opt into supporting the tinyuf2 bootloader. This is currently only supported on F303/F401/F411. Keyboards may opt into supporting the tinyuf2 bootloader. This is currently only supported on F303/F401/F411.

View File

@ -5,6 +5,7 @@ This project includes a Docker workflow that will allow you to build a new firmw
## Requirements ## Requirements
The main prerequisite is a working `docker` or `podman` install. The main prerequisite is a working `docker` or `podman` install.
* [Docker CE](https://docs.docker.com/install/#supported-platforms) * [Docker CE](https://docs.docker.com/install/#supported-platforms)
* [Podman](https://podman.io/getting-started/installation) * [Podman](https://podman.io/getting-started/installation)
@ -18,6 +19,7 @@ cd qmk_firmware
``` ```
Run the following command to build a keymap: Run the following command to build a keymap:
``` ```
util/docker_build.sh <keyboard>:<keymap> util/docker_build.sh <keyboard>:<keymap>
# For example: util/docker_build.sh planck/rev6:default # For example: util/docker_build.sh planck/rev6:default
@ -32,6 +34,8 @@ util/docker_build.sh keyboard:keymap:target
# For example: util/docker_build.sh planck/rev6:default:flash # For example: util/docker_build.sh planck/rev6:default:flash
``` ```
Note that mass storage bootloaders are not supported by the `flash` target. In this case you will have to manually copy the firmware file to the keyboard.
You can also start the script without any parameters, in which case it will ask you to input the build parameters one by one, which you may find easier to use: You can also start the script without any parameters, in which case it will ask you to input the build parameters one by one, which you may find easier to use:
``` ```

View File

@ -290,15 +290,27 @@ See also: [Backlighting](features/backlight)
| `QK_BACKLIGHT_DOWN` | `BL_DOWN` | Decrease the backlight level | | `QK_BACKLIGHT_DOWN` | `BL_DOWN` | Decrease the backlight level |
| `QK_BACKLIGHT_TOGGLE_BREATHING` | `BL_BRTG` | Toggle backlight breathing | | `QK_BACKLIGHT_TOGGLE_BREATHING` | `BL_BRTG` | Toggle backlight breathing |
## Bluetooth {#bluetooth} ## Wireless/Bluetooth {#bluetooth}
See also: [Bluetooth](features/bluetooth) See also: [Wireless](features/wireless)
| Key | Aliases | Description | | Key | Aliases | Description |
|---------------------|---------|----------------------------------------------| |-----------------------------|-----------|-----------------------------------------------------------------------------------------------|
|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth| | `QK_OUTPUT_AUTO` | `OU_AUTO` | Automatically switch to USB when plugged in, otherwise use wireless |
|`QK_OUTPUT_USB` |`OU_USB` |USB only | | `QK_OUTPUT_NEXT` | `OU_NEXT` | Cycle forwards through USB, Bluetooth, and 2.4GHz (when available) **(not yet implemented)** |
|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only | | `QK_OUTPUT_PREV` | `OU_PREV` | Cycle backwards through USB, Bluetooth, and 2.4GHz (when available) **(not yet implemented)** |
| `QK_OUTPUT_NONE` | `OU_NONE` | Disable all output **(not yet implemented)** |
| `QK_OUTPUT_USB` | `OU_USB` | Output to USB only |
| `QK_OUTPUT_2P4GHZ` | `OU_2P4G` | Output to 2.4GHz only **(not yet implemented)** |
| `QK_OUTPUT_BLUETOOTH` | `OU_BT` | Output to Bluetooth only |
| `QK_BLUETOOTH_PROFILE_NEXT` | `BT_NEXT` | Move to the next Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE_PREV` | `BT_PREV` | Move to the previous Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_UNPAIR` | `BT_UNPR` | Un-pair the current Bluetooth profile **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE1` | `BT_PRF1` | Swap to Bluetooth profile #1 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE2` | `BT_PRF2` | Swap to Bluetooth profile #2 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE3` | `BT_PRF3` | Swap to Bluetooth profile #3 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE4` | `BT_PRF4` | Swap to Bluetooth profile #4 **(not yet implemented)** |
| `QK_BLUETOOTH_PROFILE5` | `BT_PRF5` | Swap to Bluetooth profile #5 **(not yet implemented)** |
## Caps Word {#caps-word} ## Caps Word {#caps-word}
@ -375,6 +387,14 @@ See also: [Key Lock](features/key_lock)
|---------|--------------------------------------------------------------| |---------|--------------------------------------------------------------|
|`QK_LOCK`|Hold down the next key pressed, until the key is pressed again| |`QK_LOCK`|Hold down the next key pressed, until the key is pressed again|
## Layer Lock {#layer-lock}
See also: [Layer Lock](features/layer_lock)
|Key |Aliases |Description |
|---------------|---------|----------------------------------|
|`QK_LAYER_LOCK`|`QK_LLCK`|Locks or unlocks the highest layer|
## Layer Switching {#layer-switching} ## Layer Switching {#layer-switching}
See also: [Layer Switching](feature_layers#switching-and-toggling-layers) See also: [Layer Switching](feature_layers#switching-and-toggling-layers)
@ -728,23 +748,25 @@ See also: [RGB Lighting](features/rgblight)
|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode (deprecated) | |`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode (deprecated) |
|`RGB_MODE_TWINKLE` |`RGB_M_TW`|Twinkle animation mode (deprecated) | |`RGB_MODE_TWINKLE` |`RGB_M_TW`|Twinkle animation mode (deprecated) |
## RGB Matrix Lighting {#rgb-matrix-lighting} ## RGB Matrix {#rgb-matrix}
See also: [RGB Matrix Lighting](features/rgb_matrix) See also: [RGB Matrix](features/rgb_matrix)
|Key |Aliases |Description | |Key |Aliases |Description |
|-------------------|----------|--------------------------------------------------------------------------------------| |-------------------------------|---------|-----------------------------------|
|`RGB_TOG` | |Toggle RGB lighting on or off | |`QK_RGB_MATRIX_ON` |`RM_ON` |Turn on RGB Matrix |
|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | |`QK_RGB_MATRIX_OFF` |`RM_OFF` |Turn off RGB Matrix |
|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held | |`QK_RGB_MATRIX_TOGGLE` |`RM_TOGG`|Toggle RGB Matrix on or off |
|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | |`QK_RGB_MATRIX_MODE_NEXT` |`RM_NEXT`|Cycle through animations |
|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | |`QK_RGB_MATRIX_MODE_PREVIOUS` |`RM_PREV`|Cycle through animations in reverse|
|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | |`QK_RGB_MATRIX_HUE_UP` |`RM_HUEU`|Cycle through hue |
|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | |`QK_RGB_MATRIX_HUE_DOWN` |`RM_HUED`|Cycle through hue in reverse |
|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | |`QK_RGB_MATRIX_SATURATION_UP` |`RM_SATU`|Increase the saturation |
|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | |`QK_RGB_MATRIX_SATURATION_DOWN`|`RM_SATD`|Decrease the saturation |
|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held| |`QK_RGB_MATRIX_VALUE_UP` |`RM_VALU`|Increase the brightness level |
|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held| |`QK_RGB_MATRIX_VALUE_DOWN` |`RM_VALD`|Decrease the brightness level |
|`QK_RGB_MATRIX_SPEED_UP` |`RM_SPDU`|Increase the animation speed |
|`QK_RGB_MATRIX_SPEED_DOWN` |`RM_SPDD`|Decrease the animation speed |
## US ANSI Shifted Symbols {#us-ansi-shifted-symbols} ## US ANSI Shifted Symbols {#us-ansi-shifted-symbols}

View File

@ -4,7 +4,7 @@ Your computer keyboard has a processor inside of it, similar to the one inside y
QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful keymaps — you only have to follow a few simple syntax rules. QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful keymaps — you only have to follow a few simple syntax rules.
Not sure if your keyboard can run QMK? If it's a mechanical keyboard you built yourself chances are good it can. We support a [large number of hobbyist boards](https://qmk.fm/keyboards/). If your current keyboard can't run QMK there are a lot of choices out there for boards that do. Not sure if your keyboard can run QMK? If it's a mechanical keyboard you built yourself chances are good it can. We support a [large number of hobbyist boards](https://browse.qmk.fm/). If your current keyboard can't run QMK there are a lot of choices out there for boards that do.
::: tip Is This Guide For Me? ::: tip Is This Guide For Me?
If the thought of programming intimidates you, please [take a look at our online GUI](newbs_building_firmware_configurator) instead. If the thought of programming intimidates you, please [take a look at our online GUI](newbs_building_firmware_configurator) instead.

View File

@ -177,12 +177,13 @@ You'll need to perform some modifications to the file above in order to target y
Windows builds of QMK Firmware are generally compiled using QMK MSYS, and the path to gdb's location (`C:\\QMK_MSYS\\mingw64\\bin`) needs to be specified under `armToolchainPath` for it to be detected. You may also need to change the GDB path to point at `C:\\QMK_MSYS\\mingw64\\bin\\gdb-multiarch.exe` in the VSCode Cortex-Debug user settings: ![VSCode Settings](https://i.imgur.com/EGrPM1L.png) Windows builds of QMK Firmware are generally compiled using QMK MSYS, and the path to gdb's location (`C:\\QMK_MSYS\\mingw64\\bin`) needs to be specified under `armToolchainPath` for it to be detected. You may also need to change the GDB path to point at `C:\\QMK_MSYS\\mingw64\\bin\\gdb-multiarch.exe` in the VSCode Cortex-Debug user settings: ![VSCode Settings](https://i.imgur.com/EGrPM1L.png)
::: :::
Optionally, the following modifications should also be made to the keyboard's `rules.mk` file to disable optimisations -- not strictly required but will ensure breakpoints and variable viewing works correctly: The following modifications must be made to the keyboard's `rules.mk` file to enable debug information and disable optimisations -- this will ensure breakpoints and variable viewing works correctly:
```makefile ```makefile
# Enable debug information in the final binaries
DEBUG_ENABLE = yes
# Disable optimisations for debugging purposes # Disable optimisations for debugging purposes
LTO_ENABLE = no LTO_ENABLE = no
OPT = g OPT = g
DEBUG = 3
``` ```
At this point, you should build and flash your firmware through normal methods (`qmk compile ...` and `qmk flash ...`). At this point, you should build and flash your firmware through normal methods (`qmk compile ...` and `qmk flash ...`).

View File

@ -4,52 +4,51 @@ This page describes the support for [Compatible Microcontrollers](compatible_mic
If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines) to get a sense of how keyboards fit into QMK. If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines) to get a sense of how keyboards fit into QMK.
QMK has a number of features to simplify working with keyboards. For most, you don't have to write a single line of code. To get started, run `qmk new-keyboard`: QMK has a number of features to simplify working with keyboards. For most, you don't have to write a single line of code. To get started, run `qmk new-keyboard`:
``` ```
$ qmk new-keyboard $ qmk new-keyboard
Ψ Generating a new QMK keyboard directory Ψ Generating a new QMK keyboard directory
Name Your Keyboard Project Ψ Name Your Keyboard Project
For more infomation, see: Ψ For more information, see:
https://docs.qmk.fm/hardware_keyboard_guidelines#naming-your-keyboardproject https://docs.qmk.fm/hardware_keyboard_guidelines#naming-your-keyboard-project
Keyboard Name? mycoolkeeb
keyboard Name? mycoolkeeb Ψ Attribution
Ψ Used for maintainer, copyright, etc.
Attribution
Used for maintainer, copyright, etc
Your GitHub Username? [jsmith] Your GitHub Username? [jsmith]
Ψ More Attribution
More Attribution Ψ Used for maintainer, copyright, etc.
Used for maintainer, copyright, etc
Your Real Name? [John Smith] Your Real Name? [John Smith]
Ψ Pick Base Layout
Pick Base Layout Ψ As a starting point, one of the common layouts can be used to
As a starting point, one of the common layouts can be used to bootstrap the process bootstrap the process
Default Layout? Default Layout?
1. 60_ansi 1. 60_abnt2
... ...
50. tkl_iso 65. none of the above
51. none of the above Please enter your choice: [65]
Please enter your choice: [51] Ψ What Powers Your Project
Ψ Is your board using a separate development board, such as a Pro Micro,
or is the microcontroller integrated onto the PCB?
What Powers Your Project For more information, see:
For more infomation, see: https://docs.qmk.fm/compatible_microcontrollers
https://docs.qmk.fm/#/compatible_microcontrollers Using a Development Board? [y/n] y
Ψ Select Development Board
MCU? Ψ For more information, see:
1. atmega32u4 https://docs.qmk.fm/compatible_microcontrollers
Development Board?
1. bit_c_pro
... ...
22. STM32F303 14. promicro
Please enter your choice: [12] ...
18. svlinky
Please enter your choice: [14]
Ψ Created a new keyboard called mycoolkeeb. Ψ Created a new keyboard called mycoolkeeb.
Ψ To start working on things, `cd` into keyboards/mycoolkeeb, Ψ Build Command: qmk compile -kb mycoolkeeb -km default.
Ψ or open the directory in your preferred text editor. Ψ Project Location: /Users/jsmith/qmk_firmware/keyboards/mycoolkeeb.
Ψ And build with qmk compile -kb mycoolkeeb -km default. Ψ Now update the config files to match the hardware!
``` ```
This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard. This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard.
@ -58,13 +57,13 @@ This will create all the files needed to support your new keyboard, and populate
This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](https://imgur.com) to host the images. This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](https://imgur.com) to host the images.
## `info.json` ## `keyboard.json`
The `info.json` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list here. For a complete overview of available options see the [Data Driven Configuration Options](reference_info_json) page. The `keyboard.json` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list here. For a complete overview of available options see the [Data Driven Configuration Options](reference_info_json) page.
### Hardware Configuration ### Hardware Configuration
At the top of the `info.json` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `usb.vid` as `0xFEED`. For the `usb.pid` you should pick a number that is not yet in use. At the top of the `keyboard.json` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `usb.vid` as `0xFEED`. For the `usb.pid` you should pick a number that is not yet in use.
Do change the `manufacturer` and `keyboard_name` lines to accurately reflect your keyboard. Do change the `manufacturer` and `keyboard_name` lines to accurately reflect your keyboard.
@ -82,10 +81,11 @@ Do change the `manufacturer` and `keyboard_name` lines to accurately reflect you
Windows and macOS will display the `manufacturer` and `keyboard_name` in the list of USB devices. `lsusb` on Linux instead prefers the values in the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). By default, it will only use `manufacturer` and `keyboard_name` if the list does not contain that `usb.vid` / `usb.pid`. `sudo lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in. Windows and macOS will display the `manufacturer` and `keyboard_name` in the list of USB devices. `lsusb` on Linux instead prefers the values in the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). By default, it will only use `manufacturer` and `keyboard_name` if the list does not contain that `usb.vid` / `usb.pid`. `sudo lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in.
::: :::
### Matrix Configuration ### Matrix Configuration
The next section of the `info` file deals with your keyboard's matrix. The first thing you should define is which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins: The next section of the `keyboard.json` deals with your keyboard's matrix. The first thing you should define is which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins:
#### Diode Matrix
```json ```json
"matrix_pins": { "matrix_pins": {
@ -94,7 +94,7 @@ The next section of the `info` file deals with your keyboard's matrix. The first
}, },
``` ```
The size of the `matrix_pins.cols` and `matrix_pins.rows` arrays infer the size of the matrix (previously `MATRIX_ROWS` and `MATRIX_COLS`). The matrix dimensions are inferred from the length of the `matrix_pins.cols` and `matrix_pins.rows` arrays (previously specified explicitly in `config.h` with `MATRIX_ROWS` and `MATRIX_COLS`).
Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`. Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`.
@ -103,7 +103,8 @@ Finally, you can specify the direction your diodes point. This can be `COL2ROW`
``` ```
#### Direct Pin Matrix #### Direct Pin Matrix
To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `matrix_pins.direct`. The mapping defines the pins of each switch in rows and columns, from left to right. The size of the `matrix_pins.direct` array infers the size of the matrix. Use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `diode_direction`, `matrix_pins.cols` and `matrix_pins.rows`.
To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `matrix_pins.direct`. This overrides the behaviour of `diode_direction`, `matrix_pins.cols` and `matrix_pins.rows`, and they should not be specified together.
```json ```json
"matrix_pins": { "matrix_pins": {
@ -111,14 +112,16 @@ To configure a keyboard where each switch is connected to a separate pin and gro
["F1", "E6", "B0", "B2", "B3"], ["F1", "E6", "B0", "B2", "B3"],
["F5", "F0", "B1", "B7", "D2"], ["F5", "F0", "B1", "B7", "D2"],
["F6", "F7", "C7", "D5", "D3"], ["F6", "F7", "C7", "D5", "D3"],
["B5", "C6", "B6", "NO_PIN", "NO_PIN"] ["B5", "C6", "B6", null, null]
] ]
}, },
``` ```
### Layout macros Here, the matrix dimensions are inferred directly from the dimensions of the `matrix_pins.direct` array. Since there are no row or column pins to prescribe the matrix dimensions, you can arrange it however you like. Each "row" must contain the same number of "column"s; use `null` to fill in blank spaces, but try to minimize them.
Next is configuring Layout Macro(s). These define the physical arrangement of keys, and its position within the matrix that a switch are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix. ### Layout Macros
Next is configuring layout macro(s). These define the physical arrangement of keys, and their position within the matrix that switches are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix.
```json ```json
"layouts": { "layouts": {
@ -143,14 +146,13 @@ Next is configuring Layout Macro(s). These define the physical arrangement of ke
] ]
} }
} }
``` ```
In the above example, In the above example,
* `LAYOUT_ortho_4x4` defines the name of the layout macro * `LAYOUT_ortho_4x4` defines the name of the layout macro
* It must conform to the [layout guidelines](hardware_keyboard_guidelines#keyboard-name-h) * It must conform to the [layout guidelines](hardware_keyboard_guidelines#keyboard-name-h)
* `"matrix": [0, 0]` defines the electrical position * `"matrix": [0, 0]` defines the matrix row and column that the key is associated with
::: tip ::: tip
See also: [Split Keyboard Layout Macro](features/split_keyboard#layout-macro) and [Matrix to Physical Layout](understanding_qmk#matrix-to-physical-layout-map). See also: [Split Keyboard Layout Macro](features/split_keyboard#layout-macro) and [Matrix to Physical Layout](understanding_qmk#matrix-to-physical-layout-map).
@ -158,9 +160,10 @@ See also: [Split Keyboard Layout Macro](features/split_keyboard#layout-macro) an
## Additional Configuration ## Additional Configuration
There are a lot of features that can be turned on or off, configured or tuned. Some of these have yet to be migrated over to [Data Driven Configuration](data_driven_config). The following sections cover the process for when an `info.json` option is unavailable. There are a lot of features that can be turned on or off, configured or tuned. Some of these have yet to be migrated over to [Data Driven Configuration](data_driven_config). The following sections cover the process for when a data-driven option is unavailable.
### Configuration Options ### Configuration Options
For available options for `config.h`, you should see the [Config Options](config_options#the-configh-file) page for more details. For available options for `config.h`, you should see the [Config Options](config_options#the-configh-file) page for more details.
### Build Options ### Build Options

View File

@ -44,12 +44,14 @@ If there are any inconsistencies with these recommendations, you're best off [cr
Note that personal keymap submissions will no longer be accepted. This section applies to manufacturer-supported keymaps. Please see this [issue](https://github.com/qmk/qmk_firmware/issues/22724) for more information. Note that personal keymap submissions will no longer be accepted. This section applies to manufacturer-supported keymaps. Please see this [issue](https://github.com/qmk/qmk_firmware/issues/22724) for more information.
::: :::
- PRs for vendor specific keymaps will be permitted. The naming convention for these should be `default_${vendor}`, `via_${vendor}` i.e. `via_clueboard`. - PRs for vendor specific keymaps will be permitted. The naming convention for these should be `default_${vendor}` i.e. `default_clueboard`.
- vendor specific keymaps do not necessarily need to be "vanilla" and can be more richly featured than `default` or `via` stock keymaps. - vendor specific keymaps do not necessarily need to be "vanilla" and can be more richly featured than `default` stock keymaps.
- `#include QMK_KEYBOARD_H` preferred to including specific board files - `#include QMK_KEYBOARD_H` preferred to including specific board files
- prefer layer enums to #defines - prefer layer enums to #defines
- custom keycode enums must have first entry = `QK_USER` - custom keycode enums must have first entry = `QK_USER`
- some care with spacing (e.g., alignment on commas or first char of keycodes) makes for a much nicer-looking keymap. Spaces are preferred to tabs - some care with spacing (e.g., alignment on commas or first char of keycodes) makes for a much nicer-looking keymap. Spaces are preferred to tabs
- keymaps should not enable VIA
- keymaps targeting VIA support should be submitted to the [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) repository
## Keyboard PRs ## Keyboard PRs
@ -136,12 +138,12 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard
- `keymaps/default/keymap.c` - `keymaps/default/keymap.c`
- `QMKBEST`/`QMKURL` example macros removed - `QMKBEST`/`QMKURL` example macros removed
- if using `MO(1)` and `MO(2)` keycodes together to access a third layer, the [Tri Layer](features/tri_layer) feature should be used, rather than manually implementing this using `layer_on/off()` and `update_tri_layer()` functions in the keymap's `process_record_user()`. - if using `MO(1)` and `MO(2)` keycodes together to access a third layer, the [Tri Layer](features/tri_layer) feature should be used, rather than manually implementing this using `layer_on/off()` and `update_tri_layer()` functions in the keymap's `process_record_user()`.
- default (and via) keymaps should be "pristine" - default keymaps should be "pristine"
- bare minimum to be used as a "clean slate" for another user to develop their own user-specific keymap - bare minimum to be used as a "clean slate" for another user to develop their own user-specific keymap
- what does pristine mean? no custom keycodes. no advanced features like tap dance or macros. basic mod taps and home row mods would be acceptable where their use is necessary - what does pristine mean? no custom keycodes. no advanced features like tap dance or macros. basic mod taps and home row mods would be acceptable where their use is necessary
- standard layouts preferred in these keymaps, if possible - standard layouts preferred in these keymaps, if possible
- should use [encoder map feature](features/encoders#encoder-map), rather than `encoder_update_user()` - should use [encoder map feature](features/encoders#encoder-map), rather than `encoder_update_user()`
- default keymap should not enable VIA -- the VIA integration documentation requires a keymap called `via` - default keymap should not enable VIA -- keymaps targeting VIA support should be submitted to the [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) repository
- submitters can add an example (or bells-and-whistles) keymap showcasing capabilities in the same PR but it shouldn't be embedded in the 'default' keymap - submitters can add an example (or bells-and-whistles) keymap showcasing capabilities in the same PR but it shouldn't be embedded in the 'default' keymap
- submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board - submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board
- Do not include VIA json files in the PR. These do not belong in the QMK repository as they are not used by QMK firmware -- they belong in the [VIA Keyboard Repo](https://github.com/the-via/keyboards) - Do not include VIA json files in the PR. These do not belong in the QMK repository as they are not used by QMK firmware -- they belong in the [VIA Keyboard Repo](https://github.com/the-via/keyboards)
@ -174,7 +176,7 @@ Also, specific to ChibiOS:
- all core PRs must now target `develop` branch, which will subsequently be merged back to `master` on the breaking changes timeline - all core PRs must now target `develop` branch, which will subsequently be merged back to `master` on the breaking changes timeline
- as indicated above, the smallest set of changes to core components should be included in each PR - as indicated above, the smallest set of changes to core components should be included in each PR
- PRs containing multiple areas of change will be asked to be split up and raised separately - PRs containing multiple areas of change will be asked to be split up and raised separately
- keyboard and keymap changes should only be included if they affect base keyboard builds, or the default-like `default`, `via`, `default_????` keymaps etc. - keyboard and keymap changes should only be included if they affect base keyboard builds, or the default-like `default`, `default_????` keymaps etc.
- keymap modifications for anything other than the default-like keymaps **should not be included in the initial PR** in order to simplify the review process - keymap modifications for anything other than the default-like keymaps **should not be included in the initial PR** in order to simplify the review process
- the core PR submitter should submit a followup PR affecting other keymaps after initial PR merge - the core PR submitter should submit a followup PR affecting other keymaps after initial PR merge
- large-scale refactoring or consolidation PRs that affect other keymaps (such as renaming keycodes) should always be raised separately - large-scale refactoring or consolidation PRs that affect other keymaps (such as renaming keycodes) should always be raised separately

View File

@ -28,6 +28,8 @@ Supported devices:
| ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9341_spi` | | ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9341_spi` |
| ILI9486 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9486_spi` | | ILI9486 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9486_spi` |
| ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9488_spi` | | ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9488_spi` |
| LD7032 (SPI) | Monochrome OLED | 128x40 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ld7032_spi` |
| LD7032 (I2C) | Monochrome OLED | 128x40 | I2C | `QUANTUM_PAINTER_DRIVERS += ld7032_i2c` |
| SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ssd1351_spi` | | SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ssd1351_spi` |
| ST7735 | RGB LCD | 132x162, 80x160 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7735_spi` | | ST7735 | RGB LCD | 132x162, 80x160 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7735_spi` |
| ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7789_spi` | | ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7789_spi` |
@ -478,6 +480,40 @@ Native color format mono2 is compatible with SH1106
SSD1306 and SH1106 are almost entirely identical, to the point of being indisinguishable by Quantum Painter. Enable SH1106 support in Quantum Painter and create SH1106 devices in firmware to perform drawing operations on SSD1306 displays. SSD1306 and SH1106 are almost entirely identical, to the point of being indisinguishable by Quantum Painter. Enable SH1106 support in Quantum Painter and create SH1106 devices in firmware to perform drawing operations on SSD1306 displays.
==== LD7032
Enabling support for the LD7032 in Quantum Painter is done by adding the following to `rules.mk`:
```make
QUANTUM_PAINTER_ENABLE = yes
# For SPI:
QUANTUM_PAINTER_DRIVERS += ld7032_spi
# For I2C:
QUANTUM_PAINTER_DRIVERS += ld7032_i2c
```
Creating a SH1106 device in firmware can then be done with the following APIs:
```c
// SPI-based LD7032:
painter_device_t qp_ld7032_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);
// I2C-based LD7032:
painter_device_t qp_ld7032_make_i2c_device(uint16_t panel_width, uint16_t panel_height, uint8_t i2c_address);
```
The device handle returned from the `qp_ld7032_make_???_device` function can be used to perform all other drawing operations.
The maximum number of displays of each type can be configured by changing the following in your `config.h` (default is 1):
```c
// 3 SPI displays:
#define LD7032_NUM_SPI_DEVICES 3
// 3 I2C displays:
#define LD7032_NUM_I2C_DEVICES 3
```
Native color format mono2 is compatible with LD7032.
::::: :::::
===== Surface ===== Surface

View File

@ -69,7 +69,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you. Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you.
To use this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK). To do this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK).
This will set the default layer, update the persistent settings, and play a tune if you have [Audio](features/audio) enabled on your board, and the default layer sounds set. This will set the default layer, update the persistent settings, and play a tune if you have [Audio](features/audio) enabled on your board, and the default layer sounds set.
@ -82,6 +82,8 @@ To configure the default layer sounds, you would want to define this in your `co
} }
``` ```
If you do not require it to be retained after you unplug the board, use `set_single_default_layer(layer)` instead.
::: tip ::: tip
There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use. There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use.
@ -99,7 +101,7 @@ To reset to the bootloader use `QK_BOOTLOADER` or `QK_BOOT` keycode or `reset_ke
## Wiping the EEPROM (Persistent Storage) ## Wiping the EEPROM (Persistent Storage)
If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). To force an EEPROM reset, use the [`EE_CLR` keycode](quantum_keycodes) or [Bootmagic Lite](features/bootmagic) functionality. If neither of those are an option, then you can use a custom macro to do so. If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). To force an EEPROM reset, use the [`EE_CLR` keycode](quantum_keycodes) or [Bootmagic](features/bootmagic) functionality. If neither of those are an option, then you can use a custom macro to do so.
To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default. To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default.

View File

@ -156,25 +156,25 @@ For more on the `info.json` files, see [`info.json` Format](reference_info_json)
The Configurator's API uses the layout macro and the JSON file we've given it to create a visual representation of the keyboard that has each visual object tied to a specific key, in sequence: The Configurator's API uses the layout macro and the JSON file we've given it to create a visual representation of the keyboard that has each visual object tied to a specific key, in sequence:
key in layout macro | JSON object used | Key in layout macro | JSON object used |
:---: | :---- | ------------------- | ---------------------------------------- |
k00 | {"label":"Num Lock", "x":0, "y":0} | k00 | `{"label":"Num Lock", "x":0, "y":0}` |
k01 | {"label":"/", "x":1, "y":0} | k01 | `{"label":"/", "x":1, "y":0}` |
k02 | {"label":"*", "x":2, "y":0} | k02 | `{"label":"*", "x":2, "y":0}` |
k03 | {"label":"-", "x":3, "y":0} | k03 | `{"label":"-", "x":3, "y":0}` |
k10 | {"label":"7", "x":0, "y":1} | k10 | `{"label":"7", "x":0, "y":1}` |
k11 | {"label":"8", "x":1, "y":1} | k11 | `{"label":"8", "x":1, "y":1}` |
k12 | {"label":"9", "x":2, "y":1} | k12 | `{"label":"9", "x":2, "y":1}` |
k13 | {"label":"+", "x":3, "y":1, "h":2} | k13 | `{"label":"+", "x":3, "y":1, "h":2}` |
k20 | {"label":"4", "x":0, "y":2} | k20 | `{"label":"4", "x":0, "y":2}` |
k21 | {"label":"5", "x":1, "y":2} | k21 | `{"label":"5", "x":1, "y":2}` |
k22 | {"label":"6", "x":2, "y":2} | k22 | `{"label":"6", "x":2, "y":2}` |
k30 | {"label":"1", "x":0, "y":3} | k30 | `{"label":"1", "x":0, "y":3}` |
k31 | {"label":"2", "x":1, "y":3} | k31 | `{"label":"2", "x":1, "y":3}` |
k32 | {"label":"3", "x":2, "y":3} | k32 | `{"label":"3", "x":2, "y":3}` |
k33 | {"label":"Enter", "x":3, "y":3, "h":2} | k33 | `{"label":"Enter", "x":3, "y":3, "h":2}` |
k40 | {"label":"0", "x":0, "y":4, "w":2} | k40 | `{"label":"0", "x":0, "y":4, "w":2}` |
k42 | {"label":".", "x":2, "y":4} | k42 | `{"label":".", "x":2, "y":4}` |
When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the Configurator builds a keymap file with `KC_NUM` as the first key, and so on as the keymap is built. The `label` keys are not used; they are only for the user's reference in identifying specific keys when debugging the `info.json` file. When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the Configurator builds a keymap file with `KC_NUM` as the first key, and so on as the keymap is built. The `label` keys are not used; they are only for the user's reference in identifying specific keys when debugging the `info.json` file.

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,31 @@
Keyboards are able to support a wide range of languages. However, this support is not actually achieved within the keyboard itself - instead, it sends numerical codes, which the operating system maps to the appropriate characters depending on the user's configured keyboard layout. By default (and per the HID spec), this is the US ANSI layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`. Keyboards are able to support a wide range of languages. However, this support is not actually achieved within the keyboard itself - instead, it sends numerical codes, which the operating system maps to the appropriate characters depending on the user's configured keyboard layout. By default (and per the HID spec), this is the US ANSI layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`.
Obviously, this can get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. Obviously, this can get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These are used in place of the `KC_` prefixed ones. They won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. The language-specific keycode aliases are defined in the files listed in the [Keycodes Header](#header-files) column below.
Simply `#include` one of the keycode headers below at the top of your `keymap.c`, and assign the keycodes defined in the header in place of the `KC_` prefixed ones. ## Selecting Your Host Keyboard Layout
To select a host keyboard layout, simply `#include` one of the [keycode headers](#header-files) below at the top of your `keymap.c`. Example:
```c
#include QMK_KEYBOARD_H
#include "keymap_japanese.h" // [!code focus]
```
Alternatively, if using `keymap.json`, add the `host_language` key as shown in the following example. The available languages are those with a _Sendstring LUT Header_ entry in one of the [Header Files](#header-files) tables.
```json
{
"keyboard": "handwired/my_macropad",
"keymap": "my_keymap",
"host_language": "swedish", // [!code focus]
"layout": "LAYOUT_all",
"layers": [
["SE_ARNG"]
]
}
```
## Sendstring Support ## Sendstring Support

View File

@ -55,7 +55,7 @@ Everything below here requires a lot of foundational knowledge. Besides being ab
* **Advanced Features** * **Advanced Features**
* [Unicode](features/unicode) * [Unicode](features/unicode)
* [API](api_overview) * [API](api_overview)
* [Bootmagic Lite](features/bootmagic) * [Bootmagic](features/bootmagic)
* **Hardware** * **Hardware**
* [How Keyboards Work](how_keyboards_work) * [How Keyboards Work](how_keyboards_work)
* [How A Keyboard Matrix Works](how_a_matrix_works) * [How A Keyboard Matrix Works](how_a_matrix_works)

View File

@ -158,7 +158,7 @@ void solenoid_setup(void) {
#endif #endif
gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]); gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]);
gpio_set_pin_output(solenoid_pads[i]); gpio_set_pin_output(solenoid_pads[i]);
if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) { if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED)) {
solenoid_fire(i); solenoid_fire(i);
} }
} }

View File

@ -187,6 +187,8 @@ void st7565_render(void) {
st7565_send_data(&st7565_buffer[ST7565_BLOCK_SIZE * update_start], ST7565_BLOCK_SIZE); st7565_send_data(&st7565_buffer[ST7565_BLOCK_SIZE * update_start], ST7565_BLOCK_SIZE);
spi_stop();
// Turn on display if it is off // Turn on display if it is off
st7565_on(); st7565_on();

View File

@ -53,7 +53,7 @@
io_wait; \ io_wait; \
} while (0) } while (0)
rgb_led_t apa102_leds[APA102_LED_COUNT]; rgb_t apa102_leds[APA102_LED_COUNT];
uint8_t apa102_led_brightness = APA102_DEFAULT_BRIGHTNESS; uint8_t apa102_led_brightness = APA102_DEFAULT_BRIGHTNESS;
static void apa102_send_byte(uint8_t byte) { static void apa102_send_byte(uint8_t byte) {

View File

@ -52,7 +52,7 @@ static bool qp_surface_pixdata_rgb565(painter_device_t device, const void *pixel
// Pixel colour conversion // Pixel colour conversion
static bool qp_surface_palette_convert_rgb565_swapped(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) { static bool qp_surface_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) { 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}); rgb_t rgb = hsv_to_rgb_nocie((hsv_t){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); uint16_t rgb565 = (((uint16_t)rgb.r) >> 3) << 11 | (((uint16_t)rgb.g) >> 2) << 5 | (((uint16_t)rgb.b) >> 3);
palette[i].rgb565 = __builtin_bswap16(rgb565); palette[i].rgb565 = __builtin_bswap16(rgb565);
} }

View File

@ -0,0 +1,411 @@
// Copyright 2023 Nick Brassel (@tzarc)
// Copyright 2023 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "qp_internal.h"
#include "qp_comms.h"
#include "qp_oled_panel.h"
#include "qp_ld7032.h"
#include "qp_ld7032_opcodes.h"
#include "qp_surface.h"
#include "qp_surface_internal.h"
typedef void (*ld7032_driver_comms_send_command_and_data_func)(painter_device_t device, uint8_t cmd, uint8_t data);
typedef uint32_t (*ld7032_driver_comms_send_command_and_databuf_func)(painter_device_t device, uint8_t cmd, const void *data, uint32_t byte_count);
typedef struct ld7032_comms_with_command_vtable_t {
painter_comms_vtable_t base; // must be first, so this object can be cast from the painter_comms_vtable_t* type
painter_driver_comms_send_command_func send_command;
painter_driver_comms_bulk_command_sequence bulk_command_sequence;
ld7032_driver_comms_send_command_and_data_func send_command_data;
ld7032_driver_comms_send_command_and_databuf_func send_command_databuf;
} ld7032_comms_with_command_vtable_t;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LD7032 Internal API
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ld7032_comms_i2c_send_command_and_data(painter_device_t device, uint8_t cmd, uint8_t data) {
uint8_t buf[2] = {cmd, data};
qp_comms_i2c_send_data(device, buf, 2);
}
void ld7032_comms_i2c_bulk_command_sequence(painter_device_t device, const uint8_t *sequence, size_t sequence_len) {
uint8_t buf[32];
for (size_t i = 0; i < sequence_len;) {
uint8_t command = sequence[i];
uint8_t delay = sequence[i + 1];
uint8_t num_bytes = sequence[i + 2];
buf[0] = command;
memcpy(&buf[1], &sequence[i + 3], num_bytes);
qp_comms_i2c_send_data(device, buf, num_bytes + 1);
if (delay > 0) {
wait_ms(delay);
}
i += (3 + num_bytes);
}
}
uint32_t ld7032_comms_i2c_send_command_and_databuf(painter_device_t device, uint8_t cmd, const void *data, uint32_t byte_count) {
uint8_t buf[byte_count + 1];
memset(buf, 0, sizeof(buf));
buf[0] = cmd;
memcpy(&buf[1], data, byte_count);
return qp_comms_send(device, buf, byte_count + 1);
}
// Power control
bool qp_ld7032_power(painter_device_t device, bool power_on) {
painter_driver_t * driver = (painter_driver_t *)device;
ld7032_comms_with_command_vtable_t *comms_vtable = (ld7032_comms_with_command_vtable_t *)driver->comms_vtable;
comms_vtable->send_command_data(device, LD7032_DISP_ON_OFF, power_on ? 0x01 : 0x00);
return true;
}
// Screen clear
bool qp_ld7032_clear(painter_device_t device) {
qp_rect(device, 0, 0, 127, 127, 0, 0, 0, true); // clear memory
painter_driver_t *driver = (painter_driver_t *)device;
driver->driver_vtable->init(device, driver->rotation); // Re-init the display
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Flush helpers
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ld7032_flush_0(painter_device_t device, surface_dirty_data_t *dirty, const uint8_t *framebuffer, bool inverted) {
painter_driver_t * driver = (painter_driver_t *)device;
ld7032_comms_with_command_vtable_t *comms_vtable = (ld7032_comms_with_command_vtable_t *)driver->comms_vtable;
int x_start = dirty->l >> 3;
int x_end = dirty->r >> 3;
int y_start = dirty->t;
int y_end = dirty->b;
int x_length = (x_end - x_start) + 1;
uint8_t x_view_offset = driver->offset_x >> 3;
uint8_t y_view_offset = driver->offset_y;
for (int y_pos = y_start; y_pos <= y_end; y_pos++) {
int y_new_pos = y_pos;
if (inverted) {
y_new_pos = y_end - y_pos;
}
uint8_t packet[x_length];
memcpy(packet, &framebuffer[(y_pos * (driver->panel_width >> 3)) + x_start], x_length);
uint8_t x_write_start = MIN(x_start + x_view_offset, (128 >> 3));
uint8_t x_write_end = MIN(x_end + x_view_offset, (128 >> 3));
uint8_t y_write_start = MIN(y_new_pos + y_view_offset, 39);
uint8_t y_write_end = MIN(y_new_pos + y_view_offset, 39);
comms_vtable->send_command_data(device, LD7032_X_BOX_ADR_START, x_write_start);
comms_vtable->send_command_data(device, LD7032_X_BOX_ADR_END, x_write_end);
comms_vtable->send_command_data(device, LD7032_Y_BOX_ADR_START, y_write_start);
comms_vtable->send_command_data(device, LD7032_Y_BOX_ADR_END, y_write_end);
comms_vtable->send_command_databuf(device, LD7032_DATA_RW, packet, x_length);
}
}
void ld7032_flush_90(painter_device_t device, surface_dirty_data_t *dirty, const uint8_t *framebuffer, bool inverted) {
painter_driver_t * driver = (painter_driver_t *)device;
ld7032_comms_with_command_vtable_t *comms_vtable = (ld7032_comms_with_command_vtable_t *)driver->comms_vtable;
int x_start = dirty->t >> 3;
int x_end = dirty->b >> 3;
int y_start = dirty->l;
int y_end = dirty->r;
int x_length = (x_end - x_start) + 1;
uint8_t x_view_offset = driver->offset_x >> 3;
uint8_t y_view_offset = driver->offset_y;
for (int y_pos = y_start; y_pos <= y_end; y_pos++) {
int y_new_pos = y_pos;
if (inverted) {
y_new_pos = y_end - y_pos;
}
uint8_t packet[x_length];
memset(packet, 0, sizeof(packet));
int count = 0;
for (int x_pos = x_start; x_pos <= x_end; x_pos++) {
for (int x = 0; x < 8; ++x) {
uint32_t pixel_num = (((x_pos << 3) + x) * driver->panel_height) + y_pos;
uint32_t byte_offset = pixel_num / 8;
uint8_t bit_offset = pixel_num % 8;
packet[count] |= ((framebuffer[byte_offset] & (1 << bit_offset)) >> bit_offset) << x;
}
count++;
}
uint8_t x_width = (driver->panel_width >> 3) - 1;
uint8_t x_write_start = MAX((int)x_width - x_end - x_view_offset, 0);
uint8_t x_write_end = MAX((int)x_width - x_start - x_view_offset, 0);
uint8_t y_write_start = MIN(y_new_pos + y_view_offset, 39);
uint8_t y_write_end = MIN(y_new_pos + y_view_offset, 39);
comms_vtable->send_command_data(device, LD7032_X_BOX_ADR_START, x_write_start);
comms_vtable->send_command_data(device, LD7032_X_BOX_ADR_END, x_write_end);
comms_vtable->send_command_data(device, LD7032_Y_BOX_ADR_START, y_write_start);
comms_vtable->send_command_data(device, LD7032_Y_BOX_ADR_END, y_write_end);
comms_vtable->send_command_databuf(device, LD7032_DATA_RW, packet, x_length);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Driver storage
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct ld7032_device_t {
oled_panel_painter_device_t oled;
uint8_t framebuffer[SURFACE_REQUIRED_BUFFER_BYTE_SIZE(128, 40, 1)];
} ld7032_device_t;
static ld7032_device_t ld7032_drivers[LD7032_NUM_DEVICES] = {0};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Quantum Painter API implementations
// Initialisation
__attribute__((weak)) bool qp_ld7032_init(painter_device_t device, painter_rotation_t rotation) {
ld7032_device_t *driver = (ld7032_device_t *)device;
// Change the surface geometry based on the panel rotation
if (rotation == QP_ROTATION_90 || rotation == QP_ROTATION_270) {
driver->oled.surface.base.panel_width = driver->oled.base.panel_height;
driver->oled.surface.base.panel_height = driver->oled.base.panel_width;
} else {
driver->oled.surface.base.panel_width = driver->oled.base.panel_width;
driver->oled.surface.base.panel_height = driver->oled.base.panel_height;
}
// Init the internal surface
if (!qp_init(&driver->oled.surface.base, QP_ROTATION_0)) {
qp_dprintf("Failed to init internal surface in qp_ld7032_init\n");
return false;
}
// clang-format off
const uint8_t ld7032_init_sequence[] = {
// Command, Delay, N, Data[N]
LD7032_DISP_STBY_ON_OFF, 0, 1, 0x00,
LD7032_DISP_ON_OFF, 0, 1, 0x00,
LD7032_DFRAME, 0, 1, 0x05,
//LD7032_WRITE_DIRECTION, 0, 1, 0b00001000, // 0 Right, 1 Up, 2 Vertical, 3 Bit Order, 4-7 Unused
LD7032_DISP_DIRECTION, 0, 1, 0x00,
LD7032_PEAK_WIDTH, 0, 1, 0x1F,
LD7032_PEAK_DELAY, 0, 1, 0x05,
LD7032_SCAN_MODE, 0, 1, 0x01,
LD7032_DOT_CURRENT, 0, 1, 0x1f,
LD7032_VDD_SEL, 0, 1, 0x01,
};
// clang-format on
qp_comms_bulk_command_sequence(device, ld7032_init_sequence, sizeof(ld7032_init_sequence));
uint8_t display_y_start = 40 - driver->oled.base.panel_height;
uint8_t display_x_start = (128 - driver->oled.base.panel_width) / 2;
// clang-format off
uint8_t ld7032_memory_setup[] = {
// Command, Delay, N, Data[N]
LD7032_DISP_SIZE_X, 0, 2, 0x00, 0x7F,
LD7032_DISP_SIZE_Y, 0, 2, 0x00, 0x27,
LD7032_X_DISP_START, 0, 1, 0x0,
LD7032_Y_DISP_START, 0, 1, 0x0,
};
// clang-format on
ld7032_memory_setup[3] = display_x_start;
ld7032_memory_setup[4] = display_x_start + driver->oled.base.panel_width - 1;
ld7032_memory_setup[8] = display_y_start;
ld7032_memory_setup[9] = display_y_start + driver->oled.base.panel_height - 1;
ld7032_memory_setup[13] = ld7032_memory_setup[4] + 1;
ld7032_memory_setup[17] = driver->oled.base.panel_height;
qp_comms_bulk_command_sequence(device, ld7032_memory_setup, sizeof(ld7032_memory_setup));
uint8_t write_direction = 0;
switch (rotation) {
default:
case QP_ROTATION_0:
write_direction = 0b00001000;
break;
case QP_ROTATION_90:
write_direction = 0b00000001;
break;
case QP_ROTATION_180:
write_direction = 0b00000001;
break;
case QP_ROTATION_270:
write_direction = 0b00001000;
break;
}
painter_driver_t * pdriver = (painter_driver_t *)device;
ld7032_comms_with_command_vtable_t *comms_vtable = (ld7032_comms_with_command_vtable_t *)pdriver->comms_vtable;
comms_vtable->send_command_data(device, LD7032_WRITE_DIRECTION, write_direction);
qp_ld7032_power(device, true);
return true;
}
// Screen flush
bool qp_ld7032_flush(painter_device_t device) {
ld7032_device_t *driver = (ld7032_device_t *)device;
if (!driver->oled.surface.dirty.is_dirty) {
return true;
}
switch (driver->oled.base.rotation) {
default:
case QP_ROTATION_0:
ld7032_flush_0(device, &driver->oled.surface.dirty, driver->framebuffer, false);
break;
case QP_ROTATION_180:
ld7032_flush_0(device, &driver->oled.surface.dirty, driver->framebuffer, true);
break;
case QP_ROTATION_90:
ld7032_flush_90(device, &driver->oled.surface.dirty, driver->framebuffer, false);
break;
case QP_ROTATION_270:
ld7032_flush_90(device, &driver->oled.surface.dirty, driver->framebuffer, true);
break;
}
// Clear the dirty area
qp_flush(&driver->oled.surface);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Driver vtable
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const painter_driver_vtable_t ld7032_driver_vtable = {
.init = qp_ld7032_init,
.power = qp_ld7032_power,
.clear = qp_ld7032_clear,
.flush = qp_ld7032_flush,
.pixdata = qp_oled_panel_passthru_pixdata,
.viewport = qp_oled_panel_passthru_viewport,
.palette_convert = qp_oled_panel_passthru_palette_convert,
.append_pixels = qp_oled_panel_passthru_append_pixels,
.append_pixdata = qp_oled_panel_passthru_append_pixdata,
};
#ifdef QUANTUM_PAINTER_LD7032_SPI_ENABLE
const ld7032_comms_with_command_vtable_t ld7032_spi_comms_vtable = {
.base =
{
.comms_init = qp_comms_spi_dc_reset_init,
.comms_start = qp_comms_spi_start,
.comms_send = qp_comms_spi_dc_reset_send_data,
.comms_stop = qp_comms_spi_stop,
},
.send_command = qp_comms_spi_dc_reset_send_command,
.send_command_data = qp_comms_command_databyte,
.send_command_databuf = qp_comms_command_databuf,
.bulk_command_sequence = qp_comms_spi_dc_reset_bulk_command_sequence,
};
// Factory function for creating a handle to the LD7032 device
painter_device_t qp_ld7032_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 < LD7032_NUM_DEVICES; ++i) {
ld7032_device_t *driver = &ld7032_drivers[i];
if (!driver->oled.base.driver_vtable) {
painter_device_t surface = qp_make_mono1bpp_surface_advanced(&driver->oled.surface, 1, panel_width, panel_height, driver->framebuffer);
if (!surface) {
return NULL;
}
// Setup the OLED device
driver->oled.base.driver_vtable = (const painter_driver_vtable_t *)&ld7032_driver_vtable;
driver->oled.base.comms_vtable = (const painter_comms_vtable_t *)&ld7032_spi_comms_vtable;
driver->oled.base.native_bits_per_pixel = 1; // 1bpp mono
driver->oled.base.panel_width = panel_width;
driver->oled.base.panel_height = panel_height;
driver->oled.base.rotation = QP_ROTATION_0;
driver->oled.base.offset_x = 0;
driver->oled.base.offset_y = 0;
// SPI and other pin configuration
driver->oled.base.comms_config = &driver->oled.spi_dc_reset_config;
driver->oled.spi_dc_reset_config.spi_config.chip_select_pin = chip_select_pin;
driver->oled.spi_dc_reset_config.spi_config.divisor = spi_divisor;
driver->oled.spi_dc_reset_config.spi_config.lsb_first = false;
driver->oled.spi_dc_reset_config.spi_config.mode = spi_mode;
driver->oled.spi_dc_reset_config.dc_pin = dc_pin;
driver->oled.spi_dc_reset_config.reset_pin = reset_pin;
driver->oled.spi_dc_reset_config.command_params_uses_command_pin = true;
if (!qp_internal_register_device((painter_device_t)driver)) {
memset(driver, 0, sizeof(ld7032_device_t));
return NULL;
}
return (painter_device_t)driver;
}
}
return NULL;
}
#endif // QUANTUM_PAINTER_LD7032_SPI_ENABLE
#ifdef QUANTUM_PAINTER_LD7032_I2C_ENABLE
const ld7032_comms_with_command_vtable_t ld7032_i2c_comms_vtable = {
.base =
{
.comms_init = qp_comms_i2c_init,
.comms_start = qp_comms_i2c_start,
.comms_send = qp_comms_i2c_send_data,
.comms_stop = qp_comms_i2c_stop,
},
.send_command = NULL,
.send_command_data = ld7032_comms_i2c_send_command_and_data,
.send_command_databuf = ld7032_comms_i2c_send_command_and_databuf,
.bulk_command_sequence = ld7032_comms_i2c_bulk_command_sequence,
};
// Factory function for creating a handle to the LD7032 device
painter_device_t qp_ld7032_make_i2c_device(uint16_t panel_width, uint16_t panel_height, uint8_t i2c_address) {
for (uint32_t i = 0; i < LD7032_NUM_DEVICES; ++i) {
ld7032_device_t *driver = &ld7032_drivers[i];
if (!driver->oled.base.driver_vtable) {
painter_device_t surface = qp_make_mono1bpp_surface_advanced(&driver->oled.surface, 1, panel_width, panel_height, driver->framebuffer);
if (!surface) {
return NULL;
}
// Setup the OLED device
driver->oled.base.driver_vtable = (const painter_driver_vtable_t *)&ld7032_driver_vtable;
driver->oled.base.comms_vtable = (const painter_comms_vtable_t *)&ld7032_i2c_comms_vtable;
driver->oled.base.native_bits_per_pixel = 1; // 1bpp mono
driver->oled.base.panel_width = panel_width;
driver->oled.base.panel_height = panel_height;
driver->oled.base.rotation = QP_ROTATION_0;
driver->oled.base.offset_x = 0;
driver->oled.base.offset_y = 0;
// I2C configuration
driver->oled.base.comms_config = &driver->oled.i2c_config;
driver->oled.i2c_config.chip_address = i2c_address;
if (!qp_internal_register_device((painter_device_t)driver)) {
memset(driver, 0, sizeof(ld7032_device_t));
return NULL;
}
return (painter_device_t)driver;
}
}
return NULL;
}
#endif // QUANTUM_PAINTER_LD7032_SPI_ENABLE

View File

@ -0,0 +1,66 @@
// Copyright 2023 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "gpio.h"
#include "qp_internal.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Quantum Painter LD7032 configurables (add to your keyboard's config.h)
#if defined(QUANTUM_PAINTER_LD7032_SPI_ENABLE) && !defined(LD7032_NUM_SPI_DEVICES)
/**
* @def This controls the maximum number of SPI LD7032 devices that Quantum Painter can communicate with at any one time.
* Increasing this number allows for multiple displays to be used.
*/
# define LD7032_NUM_SPI_DEVICES 1
#else
# define LD7032_NUM_SPI_DEVICES 0
#endif
#if defined(QUANTUM_PAINTER_LD7032_I2C_ENABLE) && !defined(LD7032_NUM_I2C_DEVICES)
/**
* @def This controls the maximum number of I2C LD7032 devices that Quantum Painter can communicate with at any one time.
* Increasing this number allows for multiple displays to be used.
*/
# define LD7032_NUM_I2C_DEVICES 1
#else
# define LD7032_NUM_I2C_DEVICES 0
#endif
#define LD7032_NUM_DEVICES ((LD7032_NUM_SPI_DEVICES) + (LD7032_NUM_I2C_DEVICES))
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Quantum Painter LD7032 device factories
#ifdef QUANTUM_PAINTER_LD7032_SPI_ENABLE
/**
* Factory method for an LD7032 SPI LCD device.
*
* @param panel_width[in] the width of the display in pixels (usually 128)
* @param panel_height[in] the height of the display in pixels (usually 64)
* @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_ld7032_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_LD7032_SPI_ENABLE
#ifdef QUANTUM_PAINTER_LD7032_I2C_ENABLE
/**
* Factory method for an LD7032 I2C LCD device.
*
* @param panel_width[in] the width of the display in pixels (usually 128)
* @param panel_height[in] the height of the display in pixels (usually 64)
* @param i2c_address[in] the I2C address to use
* @return the device handle used with all drawing routines in Quantum Painter
*/
painter_device_t qp_ld7032_make_i2c_device(uint16_t panel_width, uint16_t panel_height, uint8_t i2c_address);
#endif // QUANTUM_PAINTER_LD7032_I2C_ENABLE

View File

@ -0,0 +1,45 @@
// Copyright 2023 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later
typedef enum {
LD7032_SOFTRES = 0x01,
LD7032_DISP_ON_OFF = 0x02,
LD7032_DATA_RW = 0x08,
LD7032_DISP_DIRECTION = 0x09,
LD7032_IFMODE = 0x0D,
LD7032_PEAK_WIDTH = 0x10,
LD7032_DOT_CURRENT = 0x12,
LD7032_SCAN_MODE = 0x13,
LD7032_DISP_STBY_ON_OFF = 0x14,
LD7032_PEAK_DELAY = 0x16,
LD7032_ROW_SCAN = 0x17,
LD7032_PRE_C_WIDTH = 0x18,
LD7032_DFRAME = 0x1A,
LD7032_DATA_REVERSE = 0x1C,
LD7032_WRITE_DIRECTION = 0x1D,
LD7032_READREG = 0x20,
LD7032_DISP_SIZE_X = 0x30,
LD7032_DISP_SIZE_Y = 0x32,
LD7032_X_BOX_ADR_START = 0x34,
LD7032_X_BOX_ADR_END = 0x35,
LD7032_Y_BOX_ADR_START = 0x36,
LD7032_Y_BOX_ADR_END = 0x37,
LD7032_X_DISP_START = 0x38,
LD7032_Y_DISP_START = 0x39,
LD7032_XTALK_EN = 0x3A,
LD7032_XTALK_REF = 0x3B,
LD7032_AGING_EN = 0x3C,
LD7032_VDD_SEL = 0x3D,
LD7032_TESTCNT0 = 0x3E,
LD7032_VCC_R_SEL = 0x3F,
LD7032_PRE_C_SELECT = 0x44,
LD7032_ROW_OVERLAP = 0x48,
LD7032_S_SLEEP_TIMER = 0xC0,
LD7032_S_SLEEP_START = 0xC2,
LD7032_S_STEP_TIMER = 0xC3,
LD7032_S_STEP_UNIT = 0xC4,
LD7032_S_CONDITION = 0xCC,
LD7032_S_START_STOP = 0xCD,
LD7032_S_SELECT = 0xCE,
LD7032_TESTCNT1 = 0xF0, //-0xFF
} ld7032_opcodes;

View File

@ -90,7 +90,7 @@ bool qp_tft_panel_pixdata(painter_device_t device, const void *pixel_data, uint3
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_rgb565_swapped(painter_device_t device, int16_t palette_size, qp_pixel_t *palette) {
for (int16_t i = 0; i < palette_size; ++i) { 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}); rgb_t rgb = hsv_to_rgb_nocie((hsv_t){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); uint16_t rgb565 = (((uint16_t)rgb.r) >> 3) << 11 | (((uint16_t)rgb.g) >> 2) << 5 | (((uint16_t)rgb.b) >> 3);
palette[i].rgb565 = __builtin_bswap16(rgb565); palette[i].rgb565 = __builtin_bswap16(rgb565);
} }
@ -99,7 +99,7 @@ bool qp_tft_panel_palette_convert_rgb565_swapped(painter_device_t device, int16_
bool qp_tft_panel_palette_convert_rgb888(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) {
for (int16_t i = 0; i < palette_size; ++i) { 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}); rgb_t rgb = hsv_to_rgb_nocie((hsv_t){palette[i].hsv888.h, palette[i].hsv888.s, palette[i].hsv888.v});
palette[i].rgb888.r = rgb.r; palette[i].rgb888.r = rgb.r;
palette[i].rgb888.g = rgb.g; palette[i].rgb888.g = rgb.g;
palette[i].rgb888.b = rgb.b; palette[i].rgb888.b = rgb.b;

View File

@ -21,6 +21,7 @@
#include "wait.h" #include "wait.h"
#include "debug.h" #include "debug.h"
#include "gpio.h" #include "gpio.h"
#include "pointing_device_internal.h"
// Registers // Registers
// clang-format off // clang-format off
@ -45,6 +46,15 @@
#define REG_MOTION_BURST 0x63 #define REG_MOTION_BURST 0x63
// clang-format on // clang-format on
const pointing_device_driver_t adns5050_pointing_device_driver = {
.init = adns5050_init,
.get_report = adns5050_get_report,
.set_cpi = adns5050_set_cpi,
.get_cpi = adns5050_get_cpi,
};
static bool powered_down = false;
void adns5050_init(void) { void adns5050_init(void) {
// Initialize the ADNS serial pins. // Initialize the ADNS serial pins.
gpio_set_pin_output(ADNS5050_SCLK_PIN); gpio_set_pin_output(ADNS5050_SCLK_PIN);
@ -59,6 +69,8 @@ void adns5050_init(void) {
// this ensures that the adns is actuall ready after reset. // this ensures that the adns is actuall ready after reset.
wait_ms(55); wait_ms(55);
powered_down = false;
// read a burst from the adns and then discard it. // read a burst from the adns and then discard it.
// gets the adns ready for write commands // gets the adns ready for write commands
// (for example, setting the dpi). // (for example, setting the dpi).
@ -163,6 +175,10 @@ report_adns5050_t adns5050_read_burst(void) {
data.dx = 0; data.dx = 0;
data.dy = 0; data.dy = 0;
if (powered_down) {
return data;
}
adns5050_serial_write(REG_MOTION_BURST); adns5050_serial_write(REG_MOTION_BURST);
// We don't need a minimum tSRAD here. That's because a 4ms wait time is // We don't need a minimum tSRAD here. That's because a 4ms wait time is
@ -211,3 +227,22 @@ bool adns5050_check_signature(void) {
return (pid == 0x12 && rid == 0x01 && pid2 == 0x26); return (pid == 0x12 && rid == 0x01 && pid2 == 0x26);
} }
void adns5050_power_down(void) {
if (!powered_down) {
powered_down = true;
adns5050_write_reg(REG_MOUSE_CONTROL, 0b10);
}
}
report_mouse_t adns5050_get_report(report_mouse_t mouse_report) {
report_adns5050_t data = adns5050_read_burst();
if (data.dx != 0 || data.dy != 0) {
pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
mouse_report.x = (mouse_xy_report_t)data.dx;
mouse_report.y = (mouse_xy_report_t)data.dy;
}
return mouse_report;
}

View File

@ -21,6 +21,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "pointing_device.h"
// CPI values // CPI values
// clang-format off // clang-format off
@ -69,6 +70,8 @@ typedef struct {
int8_t dy; int8_t dy;
} report_adns5050_t; } report_adns5050_t;
const pointing_device_driver_t adns5050_pointing_device_driver;
// A bunch of functions to implement the ADNS5050-specific serial protocol. // A bunch of functions to implement the ADNS5050-specific serial protocol.
// Note that the "serial.h" driver is insufficient, because it does not // Note that the "serial.h" driver is insufficient, because it does not
// manually manipulate a serial clock signal. // manually manipulate a serial clock signal.
@ -83,3 +86,5 @@ void adns5050_set_cpi(uint16_t cpi);
uint16_t adns5050_get_cpi(void); uint16_t adns5050_get_cpi(void);
int8_t convert_twoscomp(uint8_t data); int8_t convert_twoscomp(uint8_t data);
bool adns5050_check_signature(void); bool adns5050_check_signature(void);
void adns5050_power_down(void);
report_mouse_t adns5050_get_report(report_mouse_t mouse_report);

View File

@ -15,7 +15,6 @@
*/ */
#include "spi_master.h" #include "spi_master.h"
#include "adns9800_srom_A6.h"
#include "adns9800.h" #include "adns9800.h"
#include "wait.h" #include "wait.h"
@ -73,10 +72,26 @@
#define CLAMP_CPI(value) value<MIN_CPI ? MIN_CPI : value> MAX_CPI ? MAX_CPI : value #define CLAMP_CPI(value) value<MIN_CPI ? MIN_CPI : value> MAX_CPI ? MAX_CPI : value
#define US_BETWEEN_WRITES 120 #define US_BETWEEN_WRITES 120
#define US_BETWEEN_READS 20 #define US_BETWEEN_READS 20
#define US_DELAY_AFTER_ADDR 100
#define US_BEFORE_MOTION 100 #define US_BEFORE_MOTION 100
#define MSB1 0x80 #define MSB1 0x80
// clang-format on // clang-format on
const pointing_device_driver_t adns9800_pointing_device_driver = {
.init = adns9800_init,
.get_report = adns9800_get_report_driver,
.set_cpi = adns9800_set_cpi,
.get_cpi = adns9800_get_cpi,
};
uint16_t __attribute__((weak)) adns9800_srom_get_length(void) {
return 0;
}
uint8_t __attribute__((weak)) adns9800_srom_get_byte(uint16_t position) {
return 0;
}
void adns9800_spi_start(void) { void adns9800_spi_start(void) {
spi_start(ADNS9800_CS_PIN, false, ADNS9800_SPI_MODE, ADNS9800_SPI_DIVISOR); spi_start(ADNS9800_CS_PIN, false, ADNS9800_SPI_MODE, ADNS9800_SPI_DIVISOR);
} }
@ -92,6 +107,7 @@ void adns9800_write(uint8_t reg_addr, uint8_t data) {
uint8_t adns9800_read(uint8_t reg_addr) { uint8_t adns9800_read(uint8_t reg_addr) {
adns9800_spi_start(); adns9800_spi_start();
spi_write(reg_addr & 0x7f); spi_write(reg_addr & 0x7f);
wait_us(US_DELAY_AFTER_ADDR);
uint8_t data = spi_read(); uint8_t data = spi_read();
spi_stop(); spi_stop();
wait_us(US_BETWEEN_READS); wait_us(US_BETWEEN_READS);
@ -115,7 +131,7 @@ void adns9800_init(void) {
adns9800_read(REG_Delta_Y_L); adns9800_read(REG_Delta_Y_L);
adns9800_read(REG_Delta_Y_H); adns9800_read(REG_Delta_Y_H);
#ifdef ADNS9800_UPLOAD_SROM if (adns9800_srom_get_length() != 0) {
// upload firmware // upload firmware
// 3k firmware mode // 3k firmware mode
@ -138,15 +154,15 @@ void adns9800_init(void) {
wait_us(15); wait_us(15);
// send all bytes of the firmware // send all bytes of the firmware
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) { for (uint16_t i = 0; i < adns9800_srom_get_length(); i++) {
spi_write(pgm_read_byte(firmware_data + i)); spi_write(adns9800_srom_get_byte(i));
wait_us(15); wait_us(15);
} }
spi_stop(); spi_stop();
wait_ms(10); wait_ms(10);
#else } else {
// write reset value to REG_Configuration_IV // write reset value to REG_Configuration_IV
adns9800_write(REG_Configuration_IV, 0x0); adns9800_write(REG_Configuration_IV, 0x0);
@ -155,7 +171,7 @@ void adns9800_init(void) {
// wait a frame // wait a frame
wait_ms(10); wait_ms(10);
#endif }
// enable laser // enable laser
uint8_t laser_ctrl0 = adns9800_read(REG_LASER_CTRL0); uint8_t laser_ctrl0 = adns9800_read(REG_LASER_CTRL0);
@ -227,3 +243,12 @@ report_adns9800_t adns9800_get_report(void) {
return report; return report;
} }
report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report) {
report_adns9800_t sensor_report = adns9800_get_report();
mouse_report.x = CONSTRAIN_HID_XY(sensor_report.x);
mouse_report.y = CONSTRAIN_HID_XY(sensor_report.y);
return mouse_report;
}

View File

@ -17,6 +17,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include "pointing_device.h"
#ifndef ADNS9800_CPI #ifndef ADNS9800_CPI
# define ADNS9800_CPI 1600 # define ADNS9800_CPI 1600
@ -60,6 +61,8 @@ typedef struct {
int16_t y; int16_t y;
} report_adns9800_t; } report_adns9800_t;
const pointing_device_driver_t adns9800_pointing_device_driver;
void adns9800_init(void); void adns9800_init(void);
config_adns9800_t adns9800_get_config(void); config_adns9800_t adns9800_get_config(void);
void adns9800_set_config(config_adns9800_t); void adns9800_set_config(config_adns9800_t);
@ -67,3 +70,4 @@ uint16_t adns9800_get_cpi(void);
void adns9800_set_cpi(uint16_t cpi); void adns9800_set_cpi(uint16_t cpi);
/* Reads and clears the current delta values on the ADNS sensor */ /* Reads and clears the current delta values on the ADNS sensor */
report_adns9800_t adns9800_get_report(void); report_adns9800_t adns9800_get_report(void);
report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report);

View File

@ -1,202 +0,0 @@
#pragma once
#include "progmem.h"
#define FIRMWARE_LENGTH 3070
// clang-format off
const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
0x03, 0xA6, 0x68, 0x1E, 0x7D, 0x10, 0x7E, 0x7E, 0x5F, 0x1C, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74,
0x4B, 0x14, 0x8B, 0x75, 0x66, 0x51, 0x0B, 0x8C, 0x76, 0x74, 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C,
0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x38, 0xD5, 0x02, 0x80, 0x9B, 0x82, 0x6D, 0x58, 0x13, 0xA4, 0xAB,
0xB5, 0xC9, 0x10, 0xA2, 0xC6, 0x0A, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xCE, 0xEB, 0x3E, 0xC9,
0xF1, 0x60, 0x42, 0xE7, 0x4C, 0xFB, 0x74, 0x6A, 0x56, 0x2E, 0xBF, 0xDD, 0x38, 0xD3, 0x05, 0x88,
0x92, 0xA6, 0xCE, 0xFF, 0x5D, 0x38, 0xD1, 0xCF, 0xEF, 0x58, 0xCB, 0x65, 0x48, 0xF0, 0x35, 0x85,
0xA9, 0xB2, 0x8F, 0x5E, 0xF3, 0x80, 0x94, 0x97, 0x7E, 0x75, 0x97, 0x87, 0x73, 0x13, 0xB0, 0x8A,
0x69, 0xD4, 0x0A, 0xDE, 0xC1, 0x79, 0x59, 0x36, 0xDB, 0x9D, 0xD6, 0xB8, 0x15, 0x6F, 0xCE, 0x3C,
0x72, 0x32, 0x45, 0x88, 0xDF, 0x6C, 0xA5, 0x6D, 0xE8, 0x76, 0x96, 0x14, 0x74, 0x20, 0xDC, 0xF4,
0xFA, 0x37, 0x6A, 0x27, 0x32, 0xE3, 0x29, 0xBF, 0xC4, 0xC7, 0x06, 0x9D, 0x58, 0xE7, 0x87, 0x7C,
0x2E, 0x9F, 0x6E, 0x49, 0x07, 0x5D, 0x23, 0x64, 0x54, 0x83, 0x6E, 0xCB, 0xB7, 0x77, 0xF7, 0x2B,
0x6E, 0x0F, 0x2E, 0x66, 0x12, 0x60, 0x55, 0x65, 0xFC, 0x43, 0xB3, 0x58, 0x73, 0x5B, 0xE8, 0x67,
0x04, 0x43, 0x02, 0xDE, 0xB3, 0x89, 0xA0, 0x6D, 0x3A, 0x27, 0x79, 0x64, 0x5B, 0x0C, 0x16, 0x9E,
0x66, 0xB1, 0x8B, 0x87, 0x0C, 0x5D, 0xF2, 0xB6, 0x3D, 0x71, 0xDF, 0x42, 0x03, 0x8A, 0x06, 0x8D,
0xEF, 0x1D, 0xA8, 0x96, 0x5C, 0xED, 0x31, 0x61, 0x5C, 0xA1, 0x34, 0xF6, 0x8C, 0x08, 0x60, 0x33,
0x07, 0x00, 0x3E, 0x79, 0x95, 0x1B, 0x43, 0x7F, 0xFE, 0xB6, 0xA6, 0xD4, 0x9D, 0x76, 0x72, 0xBF,
0xAD, 0xC0, 0x15, 0xE8, 0x37, 0x31, 0xA3, 0x72, 0x63, 0x52, 0x1D, 0x1C, 0x5D, 0x51, 0x1B, 0xE1,
0xA9, 0xED, 0x60, 0x32, 0x3E, 0xA9, 0x50, 0x28, 0x53, 0x06, 0x59, 0xE2, 0xFC, 0xE7, 0x02, 0x64,
0x39, 0x21, 0x56, 0x4A, 0xA5, 0x40, 0x80, 0x81, 0xD5, 0x5A, 0x60, 0x7B, 0x68, 0x84, 0xF1, 0xE0,
0xB1, 0xB6, 0x5B, 0xDF, 0xA8, 0x1D, 0x6D, 0x65, 0x20, 0xC0, 0xA2, 0xB9, 0xD9, 0xBB, 0x00, 0xA6,
0xDB, 0x8B, 0x01, 0x53, 0x91, 0xFE, 0xC4, 0x51, 0x85, 0xB0, 0x96, 0x7F, 0xFD, 0x51, 0xDD, 0x14,
0x03, 0x67, 0x2E, 0x75, 0x1C, 0x76, 0xD3, 0x6E, 0xDD, 0x99, 0x55, 0x76, 0xE5, 0xAB, 0x23, 0xFC,
0x4A, 0xD5, 0xC6, 0xE8, 0x2E, 0xCA, 0x8A, 0xB3, 0xF6, 0x8C, 0x6C, 0xB0, 0xE9, 0xF2, 0xE7, 0x9E,
0x69, 0x41, 0xED, 0xF1, 0x6D, 0xD2, 0x86, 0xD8, 0x7E, 0xCB, 0x5D, 0x47, 0x6C, 0x85, 0x6A, 0x23,
0xED, 0x20, 0x40, 0x93, 0xB4, 0x20, 0xC7, 0xA5, 0xC9, 0xAF, 0x03, 0x15, 0xAC, 0x19, 0xE5, 0x2A,
0x36, 0xDF, 0x6D, 0xC5, 0x8C, 0x80, 0x07, 0xCE, 0x92, 0x0C, 0xD8, 0x06, 0x62, 0x0F, 0xDD, 0x48,
0x46, 0x1A, 0x53, 0xC7, 0x8A, 0x8C, 0x5D, 0x5D, 0xB4, 0xA1, 0x02, 0xD3, 0xA9, 0xB8, 0xF3, 0x94,
0x8F, 0x3F, 0xE5, 0x54, 0xD4, 0x11, 0x65, 0xB2, 0x5E, 0x09, 0x0B, 0x81, 0xE3, 0x75, 0xA7, 0x89,
0x81, 0x39, 0x6C, 0x46, 0xF6, 0x06, 0x9F, 0x27, 0x3B, 0xB6, 0x2D, 0x5F, 0x1D, 0x4B, 0xD4, 0x7B,
0x1D, 0x61, 0x74, 0x89, 0xE4, 0xE3, 0xBD, 0x98, 0x1B, 0xC4, 0x51, 0x3B, 0xA4, 0xFA, 0xE0, 0x92,
0xF7, 0xBE, 0xF2, 0x4D, 0xBB, 0xFF, 0xAD, 0x4F, 0x6D, 0x68, 0xC2, 0x79, 0x40, 0xAA, 0x9B, 0x8F,
0x0C, 0x32, 0x4B, 0x5F, 0x3E, 0xAB, 0x59, 0x98, 0xB3, 0xF5, 0x1D, 0xAC, 0x5E, 0xBC, 0x78, 0xD3,
0x01, 0x6C, 0x64, 0x15, 0x2F, 0xD8, 0x71, 0xA6, 0x2D, 0x45, 0xE1, 0x22, 0x42, 0xE4, 0x4E, 0x04,
0x3C, 0x7D, 0xF4, 0x40, 0x21, 0xB4, 0x67, 0x05, 0xA8, 0xE2, 0xF3, 0x72, 0x87, 0x4C, 0x7D, 0xD9,
0x1B, 0x65, 0x97, 0xF3, 0xC2, 0xE3, 0xE4, 0xC8, 0xD2, 0xDE, 0xF6, 0xEF, 0xDC, 0xBB, 0x44, 0x08,
0x5E, 0xE2, 0x45, 0x27, 0x01, 0xB0, 0xF6, 0x43, 0xE7, 0x3A, 0xF6, 0xDC, 0x9D, 0xED, 0xF3, 0xC5,
0x0C, 0xB8, 0x9C, 0x98, 0x3A, 0xD8, 0x36, 0xEE, 0x96, 0x72, 0x67, 0xE7, 0x81, 0x91, 0xD5, 0x05,
0x0A, 0xE0, 0x82, 0xD5, 0x8F, 0xE8, 0xF9, 0xB0, 0xC9, 0xCF, 0x93, 0xE7, 0x04, 0xC5, 0xBC, 0x2B,
0x43, 0x56, 0x7E, 0xE8, 0x67, 0x7C, 0xE5, 0xFB, 0x49, 0xAD, 0x5E, 0x9F, 0x25, 0x13, 0xDE, 0x6E,
0x6E, 0xE9, 0xF1, 0xEC, 0x87, 0x0B, 0x59, 0x81, 0x76, 0x84, 0x76, 0xB3, 0x24, 0xAF, 0x30, 0xFD,
0x27, 0x8B, 0xAB, 0xD8, 0x00, 0x8B, 0x9B, 0x0C, 0xD2, 0xB2, 0x4E, 0x5E, 0x9D, 0x1D, 0x96, 0x01,
0x00, 0x67, 0xC1, 0x5F, 0x02, 0x20, 0xFD, 0x45, 0x6A, 0x01, 0x60, 0x58, 0x45, 0xCA, 0x47, 0x21,
0x90, 0x5A, 0xC4, 0x43, 0x26, 0x1A, 0xD7, 0xA5, 0x4A, 0xB2, 0x5D, 0x2B, 0x35, 0x49, 0xFB, 0xA5,
0x17, 0x92, 0x21, 0x1E, 0x93, 0x96, 0x67, 0xA2, 0x7E, 0x36, 0x7A, 0xDE, 0x5F, 0xBE, 0x7A, 0x58,
0x9D, 0xF8, 0x78, 0xA3, 0xFA, 0xC8, 0xD5, 0x17, 0xF0, 0x21, 0x97, 0x8C, 0x80, 0xB5, 0x4B, 0x3B,
0xBD, 0xBB, 0x41, 0x21, 0xA8, 0x50, 0x67, 0xF7, 0xE7, 0x19, 0x80, 0x10, 0x8E, 0xCE, 0x04, 0x18,
0x3F, 0x51, 0x6B, 0x77, 0xD8, 0x9E, 0x16, 0xAF, 0xEC, 0xEF, 0x48, 0x16, 0x4D, 0x9E, 0x85, 0x38,
0x18, 0x3E, 0xD4, 0x28, 0x87, 0x60, 0x2A, 0xF6, 0x7F, 0x09, 0x86, 0x6F, 0x9C, 0x3C, 0x3A, 0xFF,
0xAB, 0xD0, 0x61, 0xA2, 0x97, 0x0D, 0x71, 0x94, 0x7E, 0xFD, 0xB9, 0x80, 0x02, 0x89, 0x6A, 0xB3,
0x84, 0x6C, 0x2A, 0x77, 0x62, 0xBE, 0x0B, 0xF4, 0xAF, 0xAC, 0x7B, 0x7C, 0x8E, 0xCA, 0x01, 0xBA,
0x71, 0x78, 0x94, 0xFD, 0xB5, 0x39, 0xA4, 0x4D, 0x2F, 0x78, 0xCF, 0xCA, 0x92, 0x0C, 0x1A, 0x99,
0x48, 0x4C, 0x11, 0x96, 0xB5, 0x4E, 0x41, 0x28, 0xE4, 0xA6, 0xFE, 0x4B, 0x72, 0x91, 0xE7, 0xD4,
0xDD, 0x9F, 0x12, 0xE6, 0x29, 0x38, 0xCE, 0x45, 0xAE, 0x02, 0xB8, 0x24, 0xAE, 0xBD, 0xE9, 0x66,
0x08, 0x62, 0xA2, 0x2C, 0x2B, 0x00, 0xE2, 0x23, 0xD9, 0xC4, 0x48, 0xE4, 0xD3, 0xAC, 0xBB, 0x34,
0xC7, 0xF0, 0xE3, 0x4F, 0xB9, 0x30, 0xEA, 0xA2, 0x12, 0xF1, 0x30, 0x2C, 0x36, 0xDE, 0x48, 0xF2,
0xB0, 0x4C, 0x43, 0x3F, 0x2E, 0x58, 0xE4, 0x20, 0xE3, 0x58, 0xCD, 0x31, 0x22, 0xF0, 0xA2, 0x2A,
0xE6, 0x19, 0x90, 0x55, 0x86, 0xF6, 0x55, 0x79, 0xD1, 0xD7, 0x46, 0x2F, 0xC0, 0xDC, 0x99, 0xE8,
0xF3, 0x6A, 0xDF, 0x7F, 0xEB, 0x24, 0x4A, 0x1E, 0x5A, 0x75, 0xDE, 0x2F, 0x5C, 0x19, 0x61, 0x03,
0x53, 0x54, 0x6A, 0x3B, 0x18, 0x70, 0xB6, 0x4F, 0xF1, 0x9C, 0x0A, 0x59, 0x9D, 0x19, 0x92, 0x65,
0x8C, 0x83, 0x14, 0x2D, 0x44, 0x8A, 0x75, 0xA9, 0xF5, 0x90, 0xD2, 0x66, 0x4E, 0xFA, 0x69, 0x0F,
0x5B, 0x0B, 0x98, 0x65, 0xC8, 0x11, 0x42, 0x59, 0x7F, 0xDD, 0x1B, 0x75, 0x17, 0x31, 0x4C, 0x75,
0x58, 0xEB, 0x58, 0x63, 0x7D, 0xF2, 0xA6, 0xC2, 0x6E, 0xB7, 0x3F, 0x3E, 0x5E, 0x47, 0xAD, 0xB7,
0x04, 0xE8, 0x05, 0xF8, 0xB2, 0xCF, 0x19, 0xF3, 0xD2, 0x85, 0xFE, 0x3E, 0x3E, 0xB1, 0x62, 0x08,
0x2C, 0x10, 0x07, 0x0D, 0x73, 0x90, 0x17, 0xFA, 0x9B, 0x56, 0x02, 0x75, 0xF9, 0x51, 0xE0, 0xE9,
0x1A, 0x7B, 0x9F, 0xB3, 0xF3, 0x98, 0xB8, 0x1C, 0x9C, 0xE1, 0xD5, 0x35, 0xAE, 0xC8, 0x60, 0x48,
0x11, 0x09, 0x94, 0x6B, 0xD0, 0x8B, 0x15, 0xBC, 0x05, 0x68, 0xD3, 0x54, 0x8A, 0x51, 0x39, 0x5C,
0x42, 0x76, 0xCE, 0xD8, 0xAD, 0x89, 0x30, 0xC9, 0x05, 0x1C, 0xCC, 0x94, 0x3F, 0x0F, 0x90, 0x6F,
0x72, 0x2D, 0x85, 0x64, 0x9A, 0xB9, 0x23, 0xF9, 0x0B, 0xC3, 0x7C, 0x39, 0x0F, 0x97, 0x07, 0x97,
0xDA, 0x58, 0x48, 0x33, 0x05, 0x23, 0xB8, 0x82, 0xE8, 0xD3, 0x53, 0x89, 0xAF, 0x33, 0x80, 0x22,
0x84, 0x0C, 0x95, 0x5C, 0x67, 0xB8, 0x77, 0x0C, 0x5C, 0xA2, 0x5F, 0x3D, 0x58, 0x0F, 0x27, 0xF3,
0x2F, 0xAE, 0x48, 0xBD, 0x0B, 0x6F, 0x54, 0xFB, 0x67, 0x4C, 0xEA, 0x32, 0x27, 0xF1, 0xFA, 0xE2,
0xB0, 0xEC, 0x0B, 0x15, 0xB4, 0x70, 0xF6, 0x5C, 0xDD, 0x71, 0x60, 0xC3, 0xC1, 0xA8, 0x32, 0x65,
0xAC, 0x7A, 0x77, 0x41, 0xE5, 0xA9, 0x6B, 0x11, 0x81, 0xFA, 0x34, 0x8D, 0xFB, 0xC1, 0x80, 0x6E,
0xC4, 0x60, 0x30, 0x07, 0xD4, 0x8B, 0x67, 0xBD, 0xAA, 0x8C, 0x9C, 0x64, 0xAC, 0xDB, 0x0B, 0x24,
0x8B, 0x63, 0x6F, 0xE6, 0xBC, 0xE7, 0x33, 0xA4, 0x4A, 0x4C, 0xA7, 0x9F, 0x43, 0x53, 0xD2, 0xBB,
0x8F, 0x43, 0xC7, 0x3D, 0x78, 0x68, 0x3F, 0xA5, 0x3D, 0xCA, 0x69, 0x84, 0xA6, 0x97, 0x2D, 0xC0,
0x7D, 0x31, 0x34, 0x55, 0x1D, 0x07, 0xB1, 0x5F, 0x40, 0x5C, 0x93, 0xB0, 0xBC, 0x7C, 0xB0, 0xBC,
0xE7, 0x12, 0xEE, 0x6B, 0x2B, 0xD3, 0x4D, 0x67, 0x70, 0x3A, 0x9A, 0xF2, 0x3C, 0x7C, 0x81, 0xFA,
0xD7, 0xD9, 0x90, 0x91, 0x81, 0xB8, 0xB1, 0xF3, 0x48, 0x6A, 0x26, 0x4F, 0x0C, 0xCE, 0xB0, 0x9E,
0xFD, 0x4A, 0x3A, 0xAF, 0xAC, 0x5B, 0x3F, 0xBF, 0x44, 0x5A, 0xA3, 0x19, 0x1E, 0x4B, 0xE7, 0x36,
0x6A, 0xD7, 0x20, 0xAE, 0xD7, 0x7D, 0x3B, 0xE7, 0xFF, 0x3A, 0x86, 0x2E, 0xD0, 0x4A, 0x3E, 0xAF,
0x9F, 0x8E, 0x01, 0xBF, 0xF8, 0x4F, 0xC1, 0xE8, 0x6F, 0x74, 0xE1, 0x45, 0xD3, 0xF7, 0x04, 0x6A,
0x4B, 0x9D, 0xEC, 0x33, 0x27, 0x76, 0xD7, 0xC5, 0xE1, 0xB0, 0x3B, 0x0E, 0x23, 0xEC, 0xF0, 0x86,
0xD2, 0x1A, 0xBF, 0x3D, 0x04, 0x62, 0xB3, 0x6C, 0xB2, 0xEB, 0x17, 0x05, 0xA6, 0x0A, 0x8A, 0x7E,
0x83, 0x1C, 0xB6, 0x37, 0x09, 0xC6, 0x0B, 0x70, 0x3C, 0xB5, 0x93, 0x81, 0xD8, 0x93, 0xA0, 0x5F,
0x1E, 0x08, 0xE2, 0xC6, 0xE5, 0xC9, 0x72, 0xF1, 0xF1, 0xC1, 0xED, 0xD5, 0x58, 0x93, 0x83, 0xF8,
0x65, 0x67, 0x2E, 0x0D, 0xA9, 0xF1, 0x64, 0x12, 0xE6, 0x4C, 0xEA, 0x15, 0x3F, 0x8C, 0x1A, 0xB6,
0xBF, 0xF6, 0xB9, 0x52, 0x35, 0x09, 0xB0, 0xE6, 0xF7, 0xCD, 0xF1, 0xA5, 0xAA, 0x81, 0xD1, 0x81,
0x6F, 0xB4, 0xA9, 0x66, 0x1F, 0xFC, 0x48, 0xC0, 0xB6, 0xD1, 0x8B, 0x06, 0x2F, 0xF6, 0xEF, 0x1F,
0x0A, 0xE6, 0xCE, 0x3A, 0x4A, 0x55, 0xBF, 0x6D, 0xF9, 0x4D, 0xD4, 0x08, 0x45, 0x4B, 0xC3, 0x66,
0x19, 0x92, 0x10, 0xE1, 0x17, 0x8E, 0x28, 0x91, 0x16, 0xBF, 0x3C, 0xEE, 0xA3, 0xA6, 0x99, 0x92,
0x10, 0xE1, 0xF6, 0xCC, 0xAC, 0xB8, 0x65, 0x0B, 0x43, 0x66, 0xF8, 0xE3, 0xE5, 0x3F, 0x24, 0x89,
0x47, 0x5D, 0x78, 0x43, 0xD0, 0x61, 0x17, 0xBD, 0x5B, 0x64, 0x54, 0x08, 0x45, 0x59, 0x93, 0xF6,
0x95, 0x8A, 0x41, 0x51, 0x62, 0x4B, 0x51, 0x02, 0x30, 0x73, 0xC7, 0x87, 0xC5, 0x4B, 0xA2, 0x97,
0x0F, 0xE8, 0x46, 0x5F, 0x7E, 0x2A, 0xE1, 0x30, 0x20, 0xB0, 0xFA, 0xE7, 0xCE, 0x61, 0x42, 0x57,
0x6E, 0x21, 0xF3, 0x7A, 0xEC, 0xE3, 0x25, 0xC7, 0x25, 0xF3, 0x67, 0xA7, 0x57, 0x40, 0x00, 0x02,
0xCF, 0x1C, 0x80, 0x77, 0x67, 0xBD, 0x70, 0xA1, 0x19, 0x92, 0x31, 0x75, 0x93, 0x27, 0x27, 0xB6,
0x82, 0xE4, 0xEB, 0x1D, 0x78, 0x48, 0xE7, 0xA5, 0x5E, 0x57, 0xEF, 0x64, 0x28, 0x64, 0x1B, 0xF6,
0x11, 0xB2, 0x03, 0x9D, 0xB9, 0x18, 0x02, 0x27, 0xF7, 0xBE, 0x9D, 0x55, 0xFC, 0x00, 0xD2, 0xC7,
0xAE, 0xAD, 0x0B, 0xC5, 0xE9, 0x42, 0x41, 0x48, 0xD8, 0x32, 0xCF, 0xF6, 0x0F, 0xF5, 0xBC, 0x97,
0xC6, 0x99, 0x47, 0x76, 0xBD, 0x89, 0x06, 0x0F, 0x63, 0x0C, 0x51, 0xD4, 0x5E, 0xEA, 0x48, 0xA8,
0xA2, 0x56, 0x1C, 0x79, 0x84, 0x86, 0x40, 0x88, 0x41, 0x76, 0x55, 0xFC, 0xC2, 0xD7, 0xFD, 0xC9,
0xC7, 0x80, 0x61, 0x35, 0xA7, 0x43, 0x20, 0xF7, 0xEB, 0x6C, 0x66, 0x13, 0xB0, 0xEC, 0x02, 0x75,
0x3E, 0x4B, 0xAF, 0xB9, 0x5D, 0x40, 0xDA, 0xD6, 0x6E, 0x2D, 0x39, 0x54, 0xC2, 0x95, 0x35, 0x54,
0x25, 0x72, 0xE1, 0x78, 0xB8, 0xEB, 0xC1, 0x16, 0x58, 0x0F, 0x9C, 0x9B, 0xB4, 0xEA, 0x37, 0xEC,
0x3B, 0x11, 0xBA, 0xD5, 0x8A, 0xA9, 0xE3, 0x98, 0x00, 0x51, 0x1C, 0x14, 0xE0, 0x40, 0x96, 0xE5,
0xE9, 0xF2, 0x21, 0x22, 0xB1, 0x23, 0x60, 0x78, 0xD3, 0x17, 0xF8, 0x7A, 0xA5, 0xA8, 0xBA, 0x20,
0xD3, 0x15, 0x1E, 0x32, 0xE4, 0x5E, 0x15, 0x48, 0xAE, 0xA9, 0xE5, 0xB8, 0x33, 0xEC, 0xE8, 0xA2,
0x42, 0xAC, 0xBF, 0x10, 0x84, 0x53, 0x87, 0x19, 0xB4, 0x5F, 0x76, 0x4D, 0x01, 0x9D, 0x56, 0x74,
0xD9, 0x5C, 0x97, 0xE7, 0x88, 0xEA, 0x3A, 0xBF, 0xDC, 0x4C, 0x33, 0x8A, 0x16, 0xB9, 0x5B, 0xFA,
0xD8, 0x42, 0xA7, 0xBB, 0x3C, 0x04, 0x27, 0x78, 0x49, 0x81, 0x2A, 0x5A, 0x7D, 0x7C, 0x23, 0xA8,
0xBA, 0xF7, 0x9A, 0x9F, 0xD2, 0x66, 0x3E, 0x38, 0x3C, 0x75, 0xF9, 0xD1, 0x30, 0x26, 0x30, 0x6E,
0x5A, 0x6E, 0xDC, 0x6A, 0x69, 0x32, 0x50, 0x33, 0x47, 0x9E, 0xA4, 0xA8, 0x64, 0x66, 0xF0, 0x8A,
0xE4, 0xFD, 0x27, 0x6F, 0x51, 0x25, 0x8B, 0x43, 0x74, 0xC9, 0x8E, 0xBD, 0x88, 0x31, 0xBE, 0xEC,
0x65, 0xD2, 0xCB, 0x8D, 0x5A, 0x13, 0x48, 0x16, 0x8C, 0x61, 0x0B, 0x11, 0xF6, 0xC6, 0x66, 0xAE,
0xC3, 0xCC, 0x0C, 0xD2, 0xE1, 0x9F, 0x82, 0x41, 0x3F, 0x56, 0xF9, 0x73, 0xEF, 0xDC, 0x30, 0x50,
0xCF, 0xB6, 0x7F, 0xBC, 0xD0, 0xB3, 0x10, 0xAB, 0x24, 0xE4, 0xEC, 0xAD, 0x18, 0x8C, 0x39, 0x2D,
0x30, 0x4C, 0xC5, 0x40, 0x0D, 0xF6, 0xAC, 0xD6, 0x18, 0x5D, 0x96, 0xBF, 0x5F, 0x71, 0x75, 0x96,
0x22, 0x97, 0x0F, 0x02, 0x94, 0x6E, 0xA6, 0xAE, 0x6D, 0x8F, 0x1E, 0xCA, 0x12, 0x9B, 0x2A, 0x1C,
0xCE, 0xA9, 0xEE, 0xFD, 0x12, 0x8E, 0xFC, 0xED, 0x09, 0x33, 0xBA, 0xF4, 0x1A, 0x15, 0xF6, 0x9D,
0x87, 0x16, 0x43, 0x7C, 0x78, 0x57, 0xE1, 0x44, 0xC9, 0xEB, 0x1F, 0x58, 0x4D, 0xC1, 0x49, 0x11,
0x5C, 0xB2, 0x11, 0xA8, 0x55, 0x16, 0xF1, 0xC6, 0x50, 0xE9, 0x87, 0x89, 0xF6, 0xCF, 0xD8, 0x9C,
0x51, 0xA7, 0xBC, 0x5B, 0x31, 0x6D, 0x4D, 0x51, 0xD0, 0x4C, 0xBC, 0x0D, 0x58, 0x2D, 0x7B, 0x88,
0x7A, 0xF9, 0x8E, 0xD6, 0x40, 0x4D, 0xBB, 0xBE, 0xC4, 0xE5, 0x07, 0xFC, 0xD9, 0x7B, 0x6D, 0xA6,
0x42, 0x57, 0x8F, 0x02, 0x94, 0x4F, 0xE4, 0x2A, 0x65, 0xE2, 0x19, 0x5A, 0x50, 0xE1, 0x25, 0x65,
0x4A, 0x60, 0xC2, 0xCD, 0xA8, 0xEC, 0x05, 0x2E, 0x87, 0x7B, 0x95, 0xB7, 0x4F, 0xA0, 0x0B, 0x1B,
0x4A, 0x7F, 0x92, 0xC8, 0x90, 0xEE, 0x89, 0x1E, 0x10, 0xD2, 0x85, 0xE4, 0x9F, 0x63, 0xC8, 0x12,
0xBB, 0x4E, 0xB8, 0xCF, 0x0A, 0xEC, 0x18, 0x4E, 0xE6, 0x7C, 0xB3, 0x33, 0x26, 0xC7, 0x1F, 0xD2,
0x04, 0x23, 0xEA, 0x07, 0x0C, 0x5F, 0x90, 0xBD, 0xA7, 0x6A, 0x0F, 0x4A, 0xD6, 0x10, 0x01, 0x3C,
0x12, 0x29, 0x2E, 0x96, 0xC0, 0x4D, 0xBB, 0xBE, 0xE5, 0xA7, 0x83, 0xD5, 0x6A, 0x3C, 0xE3, 0x5B,
0xB8, 0xF2, 0x5C, 0x6D, 0x1F, 0xA6, 0xF3, 0x12, 0x24, 0xF6, 0xD6, 0x3B, 0x10, 0x14, 0x09, 0x07,
0x82, 0xE8, 0x30, 0x6A, 0x99, 0xDC, 0x95, 0x01, 0x9C, 0xD4, 0x68, 0x3B, 0xCA, 0x98, 0x12, 0xAB,
0x77, 0x25, 0x15, 0x7D, 0x10, 0x32, 0x45, 0x98, 0xCD, 0x7A, 0xDF, 0x71, 0x8A, 0x75, 0xC1, 0x1C,
0xD4, 0x68, 0x25, 0xEB, 0xBB, 0x54, 0x27, 0x6F, 0x2A, 0xF7, 0xB9, 0x98, 0x03, 0x27, 0xDE, 0x24,
0xA8, 0xBB, 0x98, 0xC2, 0x84, 0xFF, 0x9B, 0x51, 0xD8, 0x53, 0x50, 0xDA, 0xF5, 0x88, 0xAA, 0x87,
0x2F, 0xAE, 0xD6, 0xEA, 0x6B, 0xDE, 0xC8, 0xD7, 0xA7, 0x28, 0x65, 0x81, 0xE8, 0xB2, 0x3B, 0x1D,
0x4F, 0x75, 0x8F, 0x9F, 0x7A, 0x74, 0x8E, 0xC1, 0x5F, 0x9A, 0xA8, 0x9D, 0xFA, 0x03, 0xA3, 0x71,
0x9B, 0x37, 0x6D, 0xD5, 0x0B, 0xF5, 0xE1, 0xA1, 0x1B, 0x01, 0x6A, 0xC6, 0x67, 0xAA, 0xEA, 0x2C,
0x9D, 0xA4, 0xD2, 0x6E, 0xFC, 0xDE, 0x2E, 0x7F, 0x94, 0x69, 0xE5, 0x4A, 0xE0, 0x01, 0x48, 0x3C,
0x6B, 0xF7, 0x1E, 0xB6, 0x0B, 0x5F, 0xF9, 0x2E, 0x07, 0xC5, 0xE8, 0xAE, 0x37, 0x1B, 0xBC, 0x3C,
0xD8, 0xD5, 0x0B, 0x91, 0x9E, 0x80, 0x24, 0xF5, 0x06, 0x0C, 0x0E, 0x98, 0x07, 0x96, 0x2D, 0x19,
0xDC, 0x58, 0x93, 0xCC, 0xFB, 0x4E, 0xEB, 0xBD, 0x0F, 0xF5, 0xAF, 0x01, 0xFA, 0xF1, 0x7C, 0x43,
0x8C, 0xB8, 0x56, 0x3E, 0xBE, 0x77, 0x4E, 0x2B, 0xF7, 0xBB, 0xB7, 0x45, 0x47, 0xCD, 0xCC, 0xA6,
0x4C, 0x72, 0x7B, 0x6A, 0x2A, 0x70, 0x13, 0x07, 0xFD, 0xB8, 0x9C, 0x98, 0x3A, 0xD8, 0x23, 0x67,
0x5B, 0x34, 0xD5, 0x14, 0x0C, 0xAB, 0x77, 0x1F, 0xF8, 0x3D, 0x5A, 0x9F, 0x92, 0xB7, 0x2C, 0xAD,
0x31, 0xDE, 0x61, 0x07, 0xB3, 0x6B, 0xF7, 0x38, 0x15, 0x95, 0x46, 0x14, 0x48, 0x53, 0x69, 0x52,
0x66, 0x07, 0x6D, 0x83, 0x71, 0x8A, 0x67, 0x25, 0x20, 0x0F, 0xFE, 0xD7, 0x02, 0xD7, 0x6E, 0x2C,
0xD2, 0x1A, 0x0A, 0x5D, 0xFD, 0x0F, 0x74, 0xE3, 0xA4, 0x36, 0x07, 0x9A, 0xDF, 0xD4, 0x79, 0xBF,
0xEF, 0x59, 0xC0, 0x44, 0x52, 0x87, 0x9A, 0x6E, 0x1D, 0x0E, 0xEE, 0xDE, 0x2E, 0x1A, 0xA9, 0x8F,
0x3A, 0xC9, 0xBA, 0xEC, 0x99, 0x78, 0x2D, 0x55, 0x6B, 0x14, 0xC2, 0x06, 0xD5, 0xFC, 0x93, 0x53,
0x4D, 0x11, 0x8C, 0xF8, 0xFA, 0x79, 0x7C, 0xA6, 0x64, 0xAE, 0x61, 0xB8, 0x7B, 0x94, 0x56, 0xA6,
0x39, 0x78, 0x9A, 0xE5, 0xC7, 0xDF, 0x18, 0x63, 0x23, 0x9C, 0xFA, 0x66, 0xBB, 0xB7, 0x5A, 0x27,
0x4C, 0xD1, 0xA1, 0x83, 0x22, 0xB3, 0x52, 0x49, 0x35, 0xB0, 0x22, 0x83, 0x59, 0x12, 0x00, 0x16,
0x98, 0xDD, 0xAD, 0xC2, 0x94, 0xF9, 0xD3, 0x7B, 0x64, 0x7F, 0x44, 0x3E, 0x3C, 0x8B, 0x9A, 0x83,
0x9C, 0x69, 0x6B, 0xE4, 0xDF, 0x9F, 0xED, 0x54, 0x1F, 0xE5, 0x5D, 0x7A, 0x05, 0x82, 0xB3, 0xDD,
0xEF, 0xFC, 0x53, 0x96, 0xB0, 0x2C, 0x5A, 0xF8, 0xDF, 0x9C, 0x8B, 0x16, 0x4E, 0xDF, 0xDA, 0x4D,
0x09, 0x09, 0x69, 0x50, 0x03, 0x65, 0xD8, 0x73, 0x70, 0xE8, 0x86, 0xBF, 0xBB, 0x35, 0xCE, 0xB2,
0x46, 0xCB, 0x02, 0x00, 0x5B, 0xB4, 0xE2, 0xC6, 0x8F, 0x2F, 0x98, 0xAF, 0x87, 0x4B, 0x48, 0x45,
0xED, 0xCC, 0x1D, 0xE6, 0x58, 0xD6, 0xF2, 0x50, 0x25, 0x9F, 0x52, 0xC7, 0xCB, 0x8A, 0x17, 0x9D,
0x5B, 0xE5, 0xC8, 0xD7, 0x72, 0xB7, 0x52, 0xB2, 0xC4, 0x98, 0xE3, 0x7A, 0x17, 0x3E, 0xC6, 0x60,
0xA7, 0x97, 0xB0, 0xCF, 0x18, 0x81, 0x53, 0x84, 0x4C, 0xD5, 0x17, 0x32, 0x03, 0x13, 0x39, 0x51,
0x09, 0x10, 0xE3, 0x77, 0x49, 0x4F, 0x62, 0x01, 0xBF, 0x8C, 0x9A, 0xE0, 0x41, 0x9E, 0x89, 0x74,
0x36, 0xF9, 0x96, 0x86, 0x2E, 0x96, 0x1C, 0x4A, 0xB7, 0x2B, 0x4A, 0x97, 0xBC, 0x99, 0x40, 0xA3,
0xE0, 0x3D, 0xC8, 0xAD, 0x2F, 0xDF, 0x4F, 0x2C, 0xC4, 0x69, 0x82, 0x9F, 0x9B, 0x81, 0x0C, 0x61,
0x5C, 0xA5, 0x9D, 0x8C, 0x89, 0xC0, 0x2C, 0xB4, 0x4A, 0x33, 0x4E, 0xEB, 0xA2, 0x56, 0x40, 0xC0,
0xC2, 0x46, 0xAF, 0x6A, 0xFC, 0x67, 0xD1, 0x80, 0x5E, 0xC5, 0x6D, 0x84, 0x43, 0x27, 0x3F, 0x55,
0x15, 0x96, 0x6A, 0xA0, 0xA5, 0xDA, 0xB7, 0xFF, 0xB7, 0x75, 0x6E, 0x4C, 0x49, 0x91, 0x9D, 0x22,
0xA3, 0x46, 0xEA, 0xED, 0x9A, 0x00, 0xE2, 0x32, 0xC3, 0xD6, 0xA9, 0x71, 0x20, 0x55, 0xA3, 0x19,
0xED, 0xF8, 0x4F, 0xA7, 0x12, 0x9C, 0x66, 0x87, 0xAF, 0x4E, 0xB7, 0xF0, 0xDB, 0xBF, 0xEF, 0xF0,
0xF6, 0xAF, 0xEA, 0xDA, 0x09, 0xFE, 0xDE, 0x38, 0x5C, 0xA5, 0xA2, 0xDF, 0x99, 0x45, 0xA8, 0xE4,
0xE7, 0x92, 0xAC, 0x67, 0xAA, 0x4F, 0xBF, 0x77, 0x3E, 0xA2, 0x40, 0x49, 0x22, 0x4A, 0x1E, 0x3B,
0xAA, 0x70, 0x7F, 0x95, 0xAF, 0x37, 0x4B, 0xFC, 0x99, 0xE2, 0xE0, 0xBA, 0xD7, 0x34, 0xCE, 0x55,
0x88, 0x5B, 0x84, 0x1B, 0x57, 0xC4, 0x80, 0x03, 0x53, 0xC9, 0x2F, 0x93, 0x04, 0x4D, 0xD5, 0x96,
0xE5, 0x70, 0xA6, 0x6E, 0x63, 0x5D, 0x9D, 0x6C, 0xDB, 0x02, 0x0A, 0xA9, 0xDA, 0x8B, 0x53, 0xDC,
0xD9, 0x9A, 0xC5, 0x94, 0x2C, 0x91, 0x92, 0x2A, 0xDE, 0xBB, 0x8B, 0x13, 0xB9, 0x19, 0x96, 0x64,
0xCC, 0xF2, 0x64, 0x39, 0xB7, 0x75, 0x49, 0xE9, 0x86, 0xC2, 0x86, 0x62, 0xD9, 0x24, 0xD3, 0x81,
0x35, 0x49, 0xFC, 0xA0, 0xA5, 0xA0, 0x93, 0x05, 0x64, 0xB4, 0x1A, 0x57, 0xCE, 0x0C, 0x90, 0x02,
0x27, 0xC5, 0x7A, 0x2B, 0x5D, 0xAE, 0x3E, 0xD5, 0xDD, 0x10, 0x7C, 0x14, 0xEA, 0x3A, 0x08, 0xAC,
0x72, 0x4E, 0x90, 0x3D, 0x3B, 0x7C, 0x86, 0x2E, 0xEB, 0xD4, 0x06, 0x70, 0xE6, 0xC7, 0xFB, 0x5F,
0xBD, 0x18, 0xF4, 0x11, 0xA4, 0x1A, 0x93, 0xC3, 0xBE, 0xD9, 0xFB, 0x26, 0x48, 0x2F, 0x37, 0x3C,
0xD0, 0x03, 0x47, 0x1A, 0xF7, 0x62, 0x19, 0x24, 0x5C, 0xF4, 0xA8, 0x92, 0x20, 0x7A, 0xF2, 0x9E,
0x2A, 0xC5, 0x95, 0xA2, 0xFB, 0xA4, 0xEA, 0x85, 0xD8, 0x56, 0xB7, 0x70, 0xD1, 0x60, 0x30, 0xA5,
0x30, 0x82, 0x70, 0xDC, 0x7A, 0x65, 0x8A, 0x36, 0x3F, 0x5B, 0x0C, 0xAE, 0x54, 0x7C, 0xD3, 0x57,
0x84, 0x7B, 0x3A, 0x65, 0x18, 0x81, 0xEE, 0x05, 0x9B, 0x44, 0x4D, 0xB8, 0xDA, 0xA2, 0xA1, 0xC9,
0x15, 0xD3, 0x73, 0x03, 0x0E, 0x43, 0xE9, 0x8E, 0x15, 0xF9, 0xBE, 0xC6, 0xC5, 0x8A, 0xE5, 0xC0,
0x1E, 0xC2, 0x37, 0x9E, 0x2A, 0x26, 0xA5, 0xA0, 0xBD, 0x24, 0x5F, 0xB9, 0xC1, 0xAB, 0x34, 0x48,
0xB9, 0x5D, 0x98, 0xB4, 0x65, 0x18, 0xF3, 0x63, 0x19, 0x44, 0x1B, 0x11, 0x16, 0xFF, 0xDC, 0xF1,
0x79, 0x08, 0x86, 0x0F, 0x52, 0x98, 0x73, 0xC4, 0x92, 0x90, 0x2B, 0x47, 0x09, 0xD0, 0x43, 0x6C,
0x2F, 0x20, 0xEB, 0xDC, 0xDA, 0xC5, 0x08, 0x7B, 0x94, 0x42, 0x30, 0x6A, 0xC7, 0xDA, 0x8C, 0xC3,
0x76, 0xA7, 0xA5, 0xCC, 0x62, 0x13, 0x00, 0x60, 0x31, 0x58, 0x44, 0x9B, 0xF5, 0x64, 0x14, 0xF5,
0x11, 0xC5, 0x54, 0x52, 0x83, 0xD4, 0x73, 0x01, 0x16, 0x0E, 0xB3, 0x7A, 0x29, 0x69, 0x35, 0x56,
0xD4, 0xEE, 0x8A, 0x17, 0xA2, 0x99, 0x24, 0x9C, 0xD7, 0x8F, 0xDB, 0x55, 0xB5, 0x3E
};

View File

@ -20,6 +20,14 @@
#include "wait.h" #include "wait.h"
#include "timer.h" #include "timer.h"
#include <stdlib.h> #include <stdlib.h>
#include "pointing_device_internal.h"
const pointing_device_driver_t analog_joystick_pointing_device_driver = {
.init = analog_joystick_init,
.get_report = analog_joystick_get_report,
.set_cpi = NULL,
.get_cpi = NULL,
};
// Set Parameters // Set Parameters
#ifndef ANALOG_JOYSTICK_AUTO_AXIS #ifndef ANALOG_JOYSTICK_AUTO_AXIS
@ -145,3 +153,16 @@ void analog_joystick_init(void) {
maxAxisValues[1] = yOrigin + 100; maxAxisValues[1] = yOrigin + 100;
#endif #endif
} }
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {
report_analog_joystick_t data = analog_joystick_read();
pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);
mouse_report.x = data.x;
mouse_report.y = data.y;
mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, data.button, POINTING_DEVICE_BUTTON1);
return mouse_report;
}

View File

@ -18,6 +18,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "pointing_device.h"
#ifndef ANALOG_JOYSTICK_X_AXIS_PIN #ifndef ANALOG_JOYSTICK_X_AXIS_PIN
# error No pin specified for X Axis # error No pin specified for X Axis
@ -42,6 +43,8 @@
# define ANALOG_JOYSTICK_SPEED_MAX 2 # define ANALOG_JOYSTICK_SPEED_MAX 2
#endif #endif
const pointing_device_driver_t analog_joystick_pointing_device_driver;
typedef struct { typedef struct {
int8_t x; int8_t x;
int8_t y; int8_t y;
@ -49,3 +52,4 @@ typedef struct {
} report_analog_joystick_t; } report_analog_joystick_t;
report_analog_joystick_t analog_joystick_read(void); report_analog_joystick_t analog_joystick_read(void);
void analog_joystick_init(void); void analog_joystick_init(void);
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report);

View File

@ -98,6 +98,13 @@
#define AZOTEQ_IQS5XX_INCH_TO_RESOLUTION_Y(inch) (DIVIDE_UNSIGNED_ROUND((inch) * (uint32_t)AZOTEQ_IQS5XX_HEIGHT_MM * 10, 254)) #define AZOTEQ_IQS5XX_INCH_TO_RESOLUTION_Y(inch) (DIVIDE_UNSIGNED_ROUND((inch) * (uint32_t)AZOTEQ_IQS5XX_HEIGHT_MM * 10, 254))
#define AZOTEQ_IQS5XX_RESOLUTION_Y_TO_INCH(px) (DIVIDE_UNSIGNED_ROUND((px) * (uint32_t)254, AZOTEQ_IQS5XX_HEIGHT_MM * 10)) #define AZOTEQ_IQS5XX_RESOLUTION_Y_TO_INCH(px) (DIVIDE_UNSIGNED_ROUND((px) * (uint32_t)254, AZOTEQ_IQS5XX_HEIGHT_MM * 10))
const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver = {
.init = azoteq_iqs5xx_init,
.get_report = azoteq_iqs5xx_get_report,
.set_cpi = azoteq_iqs5xx_set_cpi,
.get_cpi = azoteq_iqs5xx_get_cpi,
};
static uint16_t azoteq_iqs5xx_product_number = AZOTEQ_IQS5XX_UNKNOWN; static uint16_t azoteq_iqs5xx_product_number = AZOTEQ_IQS5XX_UNKNOWN;
static struct { static struct {
@ -312,3 +319,105 @@ void azoteq_iqs5xx_setup_resolution(void) {
azoteq_iqs5xx_device_resolution_t.resolution_y = AZOTEQ_IQS5XX_RESOLUTION_Y; azoteq_iqs5xx_device_resolution_t.resolution_y = AZOTEQ_IQS5XX_RESOLUTION_Y;
#endif #endif
} }
static i2c_status_t azoteq_iqs5xx_init_status = 1;
void azoteq_iqs5xx_init(void) {
i2c_init();
azoteq_iqs5xx_wake();
azoteq_iqs5xx_reset_suspend(true, false, true);
wait_ms(100);
azoteq_iqs5xx_wake();
if (azoteq_iqs5xx_get_product() != AZOTEQ_IQS5XX_UNKNOWN) {
azoteq_iqs5xx_setup_resolution();
azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_ACTIVE, false);
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(false, false);
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_reati(true, false);
#if defined(AZOTEQ_IQS5XX_ROTATION_90)
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, true, true, true, false);
#elif defined(AZOTEQ_IQS5XX_ROTATION_180)
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(true, true, false, true, false);
#elif defined(AZOTEQ_IQS5XX_ROTATION_270)
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(true, false, true, true, false);
#else
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, false, false, true, false);
#endif
azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_gesture_config(true);
wait_ms(AZOTEQ_IQS5XX_REPORT_RATE + 1);
}
};
report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) {
report_mouse_t temp_report = {0};
static uint8_t previous_button_state = 0;
static uint8_t read_error_count = 0;
if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) {
azoteq_iqs5xx_base_data_t base_data = {0};
#if !defined(POINTING_DEVICE_MOTION_PIN)
azoteq_iqs5xx_wake();
#endif
i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data);
bool ignore_movement = false;
if (status == I2C_STATUS_SUCCESS) {
// pd_dprintf("IQS5XX - previous cycle time: %d \n", base_data.previous_cycle_time);
read_error_count = 0;
if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) {
pd_dprintf("IQS5XX - Single tap/hold.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1);
} else if (base_data.gesture_events_1.two_finger_tap) {
pd_dprintf("IQS5XX - Two finger tap.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON2);
} else if (base_data.gesture_events_0.swipe_x_neg) {
pd_dprintf("IQS5XX - X-.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON4);
ignore_movement = true;
} else if (base_data.gesture_events_0.swipe_x_pos) {
pd_dprintf("IQS5XX - X+.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON5);
ignore_movement = true;
} else if (base_data.gesture_events_0.swipe_y_neg) {
pd_dprintf("IQS5XX - Y-.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON6);
ignore_movement = true;
} else if (base_data.gesture_events_0.swipe_y_pos) {
pd_dprintf("IQS5XX - Y+.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON3);
ignore_movement = true;
} else if (base_data.gesture_events_1.zoom) {
if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) < 0) {
pd_dprintf("IQS5XX - Zoom out.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON7);
} else if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) > 0) {
pd_dprintf("IQS5XX - Zoom in.\n");
temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON8);
}
} else if (base_data.gesture_events_1.scroll) {
pd_dprintf("IQS5XX - Scroll.\n");
temp_report.h = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
temp_report.v = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
}
if (base_data.number_of_fingers == 1 && !ignore_movement) {
temp_report.x = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
}
previous_button_state = temp_report.buttons;
} else {
if (read_error_count > 10) {
read_error_count = 0;
previous_button_state = 0;
} else {
read_error_count++;
}
temp_report.buttons = previous_button_state;
pd_dprintf("IQS5XX - get report failed: %d \n", status);
}
} else {
pd_dprintf("IQS5XX - Init failed: %d \n", azoteq_iqs5xx_init_status);
}
return temp_report;
}

View File

@ -176,6 +176,8 @@ typedef struct {
# define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE # define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE
#endif #endif
const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver;
void azoteq_iqs5xx_init(void); void azoteq_iqs5xx_init(void);
i2c_status_t azoteq_iqs5xx_wake(void); i2c_status_t azoteq_iqs5xx_wake(void);
report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report); report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report);

View File

@ -4,6 +4,7 @@
// refer to documentation: Gen2 and Gen3 (Pinnacle ASIC) at https://www.cirque.com/documentation // refer to documentation: Gen2 and Gen3 (Pinnacle ASIC) at https://www.cirque.com/documentation
#include "cirque_pinnacle.h" #include "cirque_pinnacle.h"
#include "cirque_pinnacle_gestures.h"
#include "wait.h" #include "wait.h"
#include "timer.h" #include "timer.h"
@ -350,3 +351,144 @@ pinnacle_data_t cirque_pinnacle_read_data(void) {
result.valid = true; result.valid = true;
return result; return result;
} }
#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
#if CIRQUE_PINNACLE_POSITION_MODE
# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
static bool is_touch_down;
bool auto_mouse_activation(report_mouse_t mouse_report) {
return is_touch_down || mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons;
}
# endif
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
uint16_t scale = cirque_pinnacle_get_scale();
pinnacle_data_t touchData = cirque_pinnacle_read_data();
mouse_xy_report_t report_x = 0, report_y = 0;
static uint16_t x = 0, y = 0, last_scale = 0;
# if defined(CIRQUE_PINNACLE_TAP_ENABLE)
mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
# endif
# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
cursor_glide_t glide_report = {0};
if (cursor_glide_enable) {
glide_report = cursor_glide_check(&glide);
}
# endif
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;
}
if (touchData.touchDown) {
pd_dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue);
}
# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
is_touch_down = touchData.touchDown;
# endif
// Scale coordinates to arbitrary X, Y resolution
cirque_pinnacle_scale_data(&touchData, scale, scale);
if (!cirque_pinnacle_gestures(&mouse_report, touchData)) {
if (last_scale && scale == last_scale && x && y && touchData.xValue && touchData.yValue) {
report_x = CONSTRAIN_HID_XY((int16_t)(touchData.xValue - x));
report_y = CONSTRAIN_HID_XY((int16_t)(touchData.yValue - y));
}
x = touchData.xValue;
y = touchData.yValue;
last_scale = scale;
# 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;
}
}
}
# 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 cirque_pinnacle_pointing_device_driver = {
.init = cirque_pinnacle_init,
.get_report = cirque_pinnacle_get_report,
.set_cpi = cirque_pinnacle_set_cpi,
.get_cpi = cirque_pinnacle_get_cpi
};
// clang-format on
#else
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
pinnacle_data_t touchData = cirque_pinnacle_read_data();
// Scale coordinates to arbitrary X, Y resolution
cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale());
if (touchData.valid) {
mouse_report.buttons = touchData.buttons;
mouse_report.x = CONSTRAIN_HID_XY(touchData.xDelta);
mouse_report.y = CONSTRAIN_HID_XY(touchData.yDelta);
mouse_report.v = touchData.wheelCount;
}
return mouse_report;
}
// clang-format off
const pointing_device_driver_t cirque_pinnacle_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
};
// clang-format on
#endif

View File

@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "pointing_device_internal.h" #include "pointing_device_internal.h"
#include "pointing_device.h"
#ifndef CIRQUE_PINNACLE_TIMEOUT #ifndef CIRQUE_PINNACLE_TIMEOUT
# define CIRQUE_PINNACLE_TIMEOUT 20 // I2C timeout in milliseconds # define CIRQUE_PINNACLE_TIMEOUT 20 // I2C timeout in milliseconds
@ -109,6 +110,10 @@ typedef struct {
#endif #endif
} pinnacle_data_t; } pinnacle_data_t;
#define cirque_pinnacle_i2c_pointing_device_driver cirque_pinnacle_pointing_device_driver
#define cirque_pinnacle_spi_pointing_device_driver cirque_pinnacle_pointing_device_driver
const pointing_device_driver_t cirque_pinnacle_pointing_device_driver;
void cirque_pinnacle_init(void); void cirque_pinnacle_init(void);
void cirque_pinnacle_calibrate(void); void cirque_pinnacle_calibrate(void);
void cirque_pinnacle_cursor_smoothing(bool enable); void cirque_pinnacle_cursor_smoothing(bool enable);
@ -116,3 +121,6 @@ pinnacle_data_t cirque_pinnacle_read_data(void);
void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution); void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution);
uint16_t cirque_pinnacle_get_scale(void); uint16_t cirque_pinnacle_get_scale(void);
void cirque_pinnacle_set_scale(uint16_t scale); void cirque_pinnacle_set_scale(uint16_t scale);
uint16_t cirque_pinnacle_get_cpi(void);
void cirque_pinnacle_set_cpi(uint16_t cpi);
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report);

View File

@ -20,6 +20,7 @@
#include "wait.h" #include "wait.h"
#include "debug.h" #include "debug.h"
#include "gpio.h" #include "gpio.h"
#include "pointing_device_internal.h"
#define REG_PID1 0x00 #define REG_PID1 0x00
#define REG_PID2 0x01 #define REG_PID2 0x01
@ -50,6 +51,13 @@ void paw3204_serial_write(uint8_t reg_addr);
uint8_t paw3204_read_reg(uint8_t reg_addr); uint8_t paw3204_read_reg(uint8_t reg_addr);
void paw3204_write_reg(uint8_t reg_addr, uint8_t data); void paw3204_write_reg(uint8_t reg_addr, uint8_t data);
const pointing_device_driver_t paw3204_pointing_device_driver = {
.init = paw3204_init,
.get_report = paw3204_get_report,
.set_cpi = paw3204_set_cpi,
.get_cpi = paw3204_get_cpi,
};
void paw3204_init(void) { void paw3204_init(void) {
gpio_set_pin_output(PAW3204_SCLK_PIN); // setclockpin to output gpio_set_pin_output(PAW3204_SCLK_PIN); // setclockpin to output
gpio_set_pin_input_high(PAW3204_SDIO_PIN); // set datapin input high gpio_set_pin_input_high(PAW3204_SDIO_PIN); // set datapin input high
@ -170,3 +178,15 @@ uint16_t paw3204_get_cpi(void) {
uint8_t read_pid_paw3204(void) { uint8_t read_pid_paw3204(void) {
return paw3204_read_reg(REG_PID1); return paw3204_read_reg(REG_PID1);
} }
report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {
report_paw3204_t data = paw3204_read();
if (data.isMotion) {
pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);
mouse_report.x = data.x;
mouse_report.y = data.y;
}
return mouse_report;
}

View File

@ -18,6 +18,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "pointing_device.h"
#ifndef PAW3204_SCLK_PIN #ifndef PAW3204_SCLK_PIN
# ifdef POINTING_DEVICE_SCLK_PIN # ifdef POINTING_DEVICE_SCLK_PIN
@ -40,6 +41,8 @@ typedef struct {
bool isMotion; bool isMotion;
} report_paw3204_t; } report_paw3204_t;
const pointing_device_driver_t paw3204_pointing_device_driver;
/** /**
* @brief Initializes the sensor so it is in a working state and ready to * @brief Initializes the sensor so it is in a working state and ready to
* be polled for data. * be polled for data.
@ -74,3 +77,5 @@ void paw3204_set_cpi(uint16_t cpi);
* @return uint16_t Current CPI value of the sensor * @return uint16_t Current CPI value of the sensor
*/ */
uint16_t paw3204_get_cpi(void); uint16_t paw3204_get_cpi(void);
report_mouse_t paw3204_get_report(report_mouse_t mouse_report);

View File

@ -33,6 +33,13 @@
static uint16_t precision = 128; static uint16_t precision = 128;
const pointing_device_driver_t pimoroni_trackball_pointing_device_driver = {
.init = pimoroni_trackball_device_init,
.get_report = pimoroni_trackball_get_report,
.set_cpi = pimoroni_trackball_set_cpi,
.get_cpi = pimoroni_trackball_get_cpi,
};
uint16_t pimoroni_trackball_get_cpi(void) { uint16_t pimoroni_trackball_get_cpi(void) {
return (precision * 125); return (precision * 125);
} }
@ -92,3 +99,50 @@ int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_di
uint16_t magnitude = (scale * offset * offset * precision) >> 7; uint16_t magnitude = (scale * offset * offset * precision) >> 7;
return isnegative ? -(int16_t)(magnitude) : (int16_t)(magnitude); return isnegative ? -(int16_t)(magnitude) : (int16_t)(magnitude);
} }
mouse_xy_report_t pimoroni_trackball_adapt_values(xy_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 xy_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);
if (status == I2C_STATUS_SUCCESS) {
error_count = 0;
if (!(pimoroni_data.click & 128)) {
mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
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);
mouse_report.x = pimoroni_trackball_adapt_values(&x_offset);
mouse_report.y = pimoroni_trackball_adapt_values(&y_offset);
} else {
debounce--;
}
} else {
mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1);
debounce = PIMORONI_TRACKBALL_DEBOUNCE_CYCLES;
}
} else {
error_count++;
}
}
return mouse_report;
}

View File

@ -19,6 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include "report.h" #include "report.h"
#include "i2c_master.h" #include "i2c_master.h"
#include "pointing_device.h"
#ifndef PIMORONI_TRACKBALL_ADDRESS #ifndef PIMORONI_TRACKBALL_ADDRESS
# define PIMORONI_TRACKBALL_ADDRESS 0x0A # define PIMORONI_TRACKBALL_ADDRESS 0x0A
@ -49,9 +50,12 @@ typedef struct {
uint8_t click; uint8_t click;
} pimoroni_data_t; } pimoroni_data_t;
const pointing_device_driver_t pimoroni_trackball_pointing_device_driver;
void pimoroni_trackball_device_init(void); void pimoroni_trackball_device_init(void);
void pimoroni_trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white); 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); int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
uint16_t pimoroni_trackball_get_cpi(void); uint16_t pimoroni_trackball_get_cpi(void);
void pimoroni_trackball_set_cpi(uint16_t cpi); void pimoroni_trackball_set_cpi(uint16_t cpi);
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data); i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report);

View File

@ -21,6 +21,14 @@
#include "wait.h" #include "wait.h"
#include "debug.h" #include "debug.h"
#include "gpio.h" #include "gpio.h"
#include "pointing_device_internal.h"
const pointing_device_driver_t pmw3320_pointing_device_drivera = {
.init = pmw3320_init,
.get_report = pmw3320_get_report,
.set_cpi = pmw3320_set_cpi,
.get_cpi = pmw3320_get_cpi,
};
void pmw3320_init(void) { void pmw3320_init(void) {
// Initialize sensor serial pins. // Initialize sensor serial pins.
@ -190,3 +198,15 @@ bool pmw3320_check_signature(void) {
return (pid == 0x3b && pid2 == 0xc4); return (pid == 0x3b && pid2 == 0xc4);
} }
report_mouse_t pmw3320_get_report(report_mouse_t mouse_report) {
report_pmw3320_t data = pmw3320_read_burst();
if (data.dx != 0 || data.dy != 0) {
pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
mouse_report.x = (mouse_xy_report_t)data.dx;
mouse_report.y = (mouse_xy_report_t)data.dy;
}
return mouse_report;
}

View File

@ -21,6 +21,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "pointing_device.h"
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
@ -54,6 +55,8 @@ typedef struct {
int8_t dy; int8_t dy;
} report_pmw3320_t; } report_pmw3320_t;
const pointing_device_driver_t pmw3320_pointing_device_driver;
// A bunch of functions to implement the PMW3320-specific serial protocol. // A bunch of functions to implement the PMW3320-specific serial protocol.
// Mostly taken from ADNS5050 driver. // Mostly taken from ADNS5050 driver.
// Note that the "serial.h" driver is insufficient, because it does not // Note that the "serial.h" driver is insufficient, because it does not
@ -69,6 +72,7 @@ void pmw3320_set_cpi(uint16_t cpi);
uint16_t pmw3320_get_cpi(void); uint16_t pmw3320_get_cpi(void);
int8_t convert_twoscomp(uint8_t data); int8_t convert_twoscomp(uint8_t data);
bool pmw3320_check_signature(void); bool pmw3320_check_signature(void);
report_mouse_t pmw3320_get_report(report_mouse_t mouse_report);
#if !defined(PMW3320_CPI) #if !defined(PMW3320_CPI)
# define PMW3320_CPI 1000 # define PMW3320_CPI 1000

View File

@ -31,265 +31,4 @@ void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) {
} }
// PID, Inverse PID, SROM version // PID, Inverse PID, SROM version
const uint8_t pmw33xx_firmware_signature[3] PROGMEM = {0x42, 0xBD, 0x04}; const uint8_t pmw33xx_firmware_signature[2] PROGMEM = {0x42, 0xBD};
// 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
};

View File

@ -28,285 +28,5 @@ void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi) {
pmw33xx_write(sensor, REG_Resolution_L, cpival & 0xFF); pmw33xx_write(sensor, REG_Resolution_L, cpival & 0xFF);
} }
// PID, Inverse PID, SROM version // PID, Inverse PID
const uint8_t pmw33xx_firmware_signature[3] PROGMEM = {0x42, 0xBD, 0x04}; const uint8_t pmw33xx_firmware_signature[2] PROGMEM = {0x42, 0xBD};
// 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
};
// clang-format off

View File

@ -17,8 +17,6 @@
#define PMW33XX_CPI_MIN 50 #define PMW33XX_CPI_MIN 50
#define PMW33XX_CPI_MAX 16000 #define PMW33XX_CPI_MAX 16000
#define PMW33XX_FIRMWARE_LENGTH 4094
// PMW3389 register addresses // PMW3389 register addresses
// clang-format off // clang-format off
#define REG_Product_ID 0x00 #define REG_Product_ID 0x00

View File

@ -15,8 +15,7 @@
#include "spi_master.h" #include "spi_master.h"
#include "progmem.h" #include "progmem.h"
extern const uint8_t pmw33xx_firmware_data[PMW33XX_FIRMWARE_LENGTH] PROGMEM; extern const uint8_t pmw33xx_firmware_signature[2] PROGMEM;
extern const uint8_t pmw33xx_firmware_signature[3] PROGMEM;
static const pin_t cs_pins_left[] = PMW33XX_CS_PINS; static const pin_t cs_pins_left[] = PMW33XX_CS_PINS;
static const pin_t cs_pins_right[] = PMW33XX_CS_PINS_RIGHT; static const pin_t cs_pins_right[] = PMW33XX_CS_PINS_RIGHT;
@ -27,6 +26,21 @@ static bool in_burst_right[ARRAY_SIZE(cs_pins_right)] = {0};
bool __attribute__((cold)) pmw33xx_upload_firmware(uint8_t sensor); bool __attribute__((cold)) pmw33xx_upload_firmware(uint8_t sensor);
bool __attribute__((cold)) pmw33xx_check_signature(uint8_t sensor); bool __attribute__((cold)) pmw33xx_check_signature(uint8_t sensor);
const pointing_device_driver_t pmw33xx_pointing_device_driver = {
.init = pmw33xx_init_wrapper,
.get_report = pmw33xx_get_report,
.set_cpi = pmw33xx_set_cpi_wrapper,
.get_cpi = pmw33xx_get_cpi_wrapper,
};
uint16_t __attribute__((weak)) pmw33xx_srom_get_length(void) {
return 0;
}
uint8_t __attribute__((weak)) pmw33xx_srom_get_byte(uint16_t position) {
return 0;
}
void pmw33xx_set_cpi_all_sensors(uint16_t cpi) { void pmw33xx_set_cpi_all_sensors(uint16_t cpi) {
for (uint8_t sensor = 0; sensor < pmw33xx_number_of_sensors; sensor++) { for (uint8_t sensor = 0; sensor < pmw33xx_number_of_sensors; sensor++) {
pmw33xx_set_cpi(sensor, cpi); pmw33xx_set_cpi(sensor, cpi);
@ -89,10 +103,9 @@ uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr) {
} }
bool pmw33xx_check_signature(uint8_t sensor) { bool pmw33xx_check_signature(uint8_t sensor) {
uint8_t signature_dump[3] = { uint8_t signature_dump[2] = {
pmw33xx_read(sensor, REG_Product_ID), pmw33xx_read(sensor, REG_Product_ID),
pmw33xx_read(sensor, REG_Inverse_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; return memcmp(pmw33xx_firmware_signature, signature_dump, sizeof(signature_dump)) == 0;
@ -115,10 +128,12 @@ bool pmw33xx_upload_firmware(uint8_t sensor) {
spi_write(REG_SROM_Load_Burst | 0x80); spi_write(REG_SROM_Load_Burst | 0x80);
wait_us(15); wait_us(15);
for (size_t i = 0; i < PMW33XX_FIRMWARE_LENGTH; i++) { for (size_t i = 0; i < pmw33xx_srom_get_length(); i++) {
spi_write(pgm_read_byte(pmw33xx_firmware_data + i)); spi_write(pmw33xx_srom_get_byte(i));
wait_us(15); wait_us(15);
} }
spi_stop();
wait_us(200); wait_us(200);
pmw33xx_read(sensor, REG_SROM_ID); pmw33xx_read(sensor, REG_SROM_ID);
@ -154,12 +169,14 @@ bool pmw33xx_init(uint8_t sensor) {
pmw33xx_read(sensor, REG_Delta_Y_L); pmw33xx_read(sensor, REG_Delta_Y_L);
pmw33xx_read(sensor, REG_Delta_Y_H); pmw33xx_read(sensor, REG_Delta_Y_H);
#ifdef PMW33XX_UPLOAD_SROM if (pmw33xx_srom_get_length() != 0) {
if (!pmw33xx_upload_firmware(sensor)) { if (!pmw33xx_upload_firmware(sensor)) {
pd_dprintf("PMW33XX (%d): firmware upload failed!\n", sensor); pd_dprintf("PMW33XX (%d): firmware upload failed!\n", sensor);
return false; return false;
} }
#endif } else {
pd_dprintf("PMW33XX (%d): firmware upload skipped.\n", sensor);
}
spi_stop(); spi_stop();
@ -218,3 +235,38 @@ pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor) {
return report; return report;
} }
void pmw33xx_init_wrapper(void) {
pmw33xx_init(0);
}
void pmw33xx_set_cpi_wrapper(uint16_t cpi) {
pmw33xx_set_cpi(0, cpi);
}
uint16_t pmw33xx_get_cpi_wrapper(void) {
return pmw33xx_get_cpi(0);
}
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 (report.motion.b.is_lifted) {
return mouse_report;
}
if (!report.motion.b.is_motion) {
in_motion = false;
return mouse_report;
}
if (!in_motion) {
in_motion = true;
pd_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;
}

View File

@ -14,6 +14,7 @@
#include <stdint.h> #include <stdint.h>
#include "spi_master.h" #include "spi_master.h"
#include "util.h" #include "util.h"
#include "pointing_device.h"
#if defined(POINTING_DEVICE_DRIVER_pmw3360) #if defined(POINTING_DEVICE_DRIVER_pmw3360)
# include "pmw3360.h" # include "pmw3360.h"
@ -102,6 +103,10 @@ _Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.moti
#define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) #define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
#define pmw3360_pointing_device_driver pmw33xx_pointing_device_driver;
#define pmw3389_pointing_device_driver pmw33xx_pointing_device_driver;
const pointing_device_driver_t pmw33xx_pointing_device_driver;
/** /**
* @brief Initializes the given sensor so it is in a working state and ready to * @brief Initializes the given sensor so it is in a working state and ready to
* be polled for data. * be polled for data.
@ -170,3 +175,8 @@ uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr);
* @return false Write failed, do not proceed operation * @return false Write failed, do not proceed operation
*/ */
bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data); bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data);
void pmw33xx_init_wrapper(void);
void pmw33xx_set_cpi_wrapper(uint16_t cpi);
uint16_t pmw33xx_get_cpi_wrapper(void);
report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report);

15
drivers/ws2812.c Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2024 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include "ws2812.h"
#if defined(WS2812_RGBW)
void ws2812_rgb_to_rgbw(ws2812_led_t *led) {
// Determine lowest value in all three colors, put that into
// the white channel and then shift all colors by that amount
led->w = MIN(led->r, MIN(led->g, led->b));
led->r -= led->w;
led->g -= led->w;
led->b -= led->w;
}
#endif

Some files were not shown because too many files have changed in this diff Show More