Compare commits

..

482 Commits

Author SHA1 Message Date
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
jack
aa05fa649f Update PR template (#24397)
Initial
2024-09-14 16:09:01 -06: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
Ryan
0c19eae916 4pplet/waffling80/rev_b_ansi: fix missing keyboard.json (#24390) 2024-09-12 18:30:28 +01: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
Cipulot
e0788d19d4 Update EC60X LED count (#24374)
Update keyboard.json
2024-09-08 12:19:39 -06:00
jack
f043545144 [Docs] Remove references to bootmagic lite (#24369) 2024-09-06 17:30:54 +01:00
Duncan Sutherland
c44f5375ab Correct 2u backspace matrix co-ordinate for Fave65s (#24353) 2024-09-06 07:59:39 -07:00
jack
6d4f8d8963 [Keyboard] Add Klor (#24302) 2024-09-06 07:42:22 -07:00
4pplet
75848477fb Add waffling80 hotswap PCB (#23551)
Co-authored-by: jack <0x6a73@protonmail.com>
2024-09-05 23:35:26 -07:00
Ryan
4a6ba1e808 Fix RGBW for WS2812 SPI driver (#24367) 2024-09-05 23:46:29 +01: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
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
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
Ryan
28b6a8841f Add 60_ansi_tsangan_split_bs_rshift to community layouts (#24186) 2024-09-02 09:13:28 +10: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
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
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
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
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
jack
d4811c19b0 Fix wrong OLED code for a few keyboards (#24344)
* Initial

* Other keyboards too
2024-08-29 20:21:53 -06:00
Ryan
496f448090 Fix two firmware size warnings (#24343) 2024-08-29 20:20:05 -06:00
Antoine Bertin
d95690d89c [Keyboard] Fix splitkb/corne OLED code (#24260) 2024-08-29 19:56:25 -06:00
leyew
fd65bd5ae0 [Keyboard] Add Acid and Co. Stellaron TKL (#24154) 2024-08-28 15:52:02 +01:00
Thanh Son Tran
4b1f916b99 [Keyboard] Add Tyson60s keyboard (#24047) 2024-08-28 15:38:37 +01:00
Nick Brassel
0f43486537 Changelog update with actual qmk_userspace_via link. (#24332) 2024-08-26 23:05:45 +01:00
Joel Challis
530e044762 Update PR Checklist for 'via' keymaps (#24330) 2024-08-27 07:28:23 +10: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
Ryan
c134822486 Update next breaking changes date (#24331) 2024-08-26 15:14:06 +10:00
MrMustardTBC
63206aebcf fixed spelling errors in example 4 (#24318) 2024-08-26 04:34:42 +01:00
Joel Challis
c05cafa3df Add via keymaps to gitignore (#24329) 2024-08-26 04:33:40 +01:00
Joel Challis
7a4f21d340 Reject via keymaps in lint (#24325) 2024-08-26 03:56:03 +01:00
Nick Brassel
5d76c5280d Merge branch 'develop' 2024-08-26 10:01:57 +10:00
Nick Brassel
81dcf2b547 Merge point for 2024q3 breaking change -- take 2 2024-08-26 10:00:11 +10:00
Nick Brassel
5741eb7b10 Fixup python tests for missing via keymaps. 2024-08-26 09:57:35 +10:00
Nick Brassel
9976d0f547 Merge point for 2024q3 breaking change 2024-08-26 09:49:08 +10:00
Nick Brassel
acac787842 2024q3 breaking changes changelog (#24324)
Co-authored-by: Joel Challis <git@zvecr.com>
2024-08-26 09:46:12 +10:00
Nick Brassel
45dc2499dc Remove all via-enabled keymaps, including via. (#24322) 2024-08-26 07:51:22 +10:00
Ryan
8f6d2ac53c Update Underglow keycodes (#23765)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-08-25 22:15:07 +10:00
Nebuleon
fc9d848a77 Fix build failure on zsa/moonlander with DYNAMIC_MACRO_ENABLE (#24316) 2024-08-24 14:10:48 +01:00
QMK Bot
b3bb19a96d Merge remote-tracking branch 'origin/master' into develop 2024-08-21 21:56:55 +00:00
dependabot[bot]
e6a898e3ee Bump tj-actions/changed-files from 44 to 45 (#24313)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 45.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v44...v45)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  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-08-21 22:56:22 +01:00
QMK Bot
048f2ddcbf Merge remote-tracking branch 'origin/master' into develop 2024-08-21 14:16:01 +00:00
Danny
373364afd1 Add Quefrency Rev. 6 (#24291)
* Initial commit of Quefrency Rev. 6

* Use more memory for storing VIA layout options

* Add missing underglow LED

* Set bootmagic keys for each half, split transport matrix for RGB, update pinout for right half

* Enable encoders

* Add/update license headers

* Remove fudge thing

* Remove EEPROM leveling specification now that is the default

* Fix bootmagic position for right half
2024-08-21 10:15:06 -04:00
QMK Bot
31b962b339 Merge remote-tracking branch 'origin/master' into develop 2024-08-19 19:05:10 +00:00
Joel Challis
557e4e7ffc Fix dead link in porting_your_keyboard_to_qmk.md (#24306) 2024-08-19 20:04:37 +01:00
QMK Bot
97a0091bbb Merge remote-tracking branch 'origin/master' into develop 2024-08-19 18:08:45 +00:00
Joel Challis
e910c89e0b Fix auto 'keyboard' label (#24221) 2024-08-19 19:08:11 +01:00
フィルターペーパー
21b84596e7 Enhance overlapping mouse keys control (#23341)
Enhance the overlapping mouse key press acceleration (introduced in #21494) with user preprocessor controls.
2024-08-19 03:18:28 +01:00
Drashna Jaelre
e9cb9f42a5 [Keyboard] Update ZSA Moonlander (#23911) 2024-08-19 01:13:38 +01:00
QMK Bot
48d3edd66f Merge remote-tracking branch 'origin/master' into develop 2024-08-18 21:33:42 +00:00
Joel Challis
1355eb493f Default STM32G431 back to wear_leveling EFL driver (#24299) 2024-08-19 07:33:11 +10:00
Drashna Jaelre
ab4c13e835 Add dynamic macro keyboard callbacks (#24142) 2024-08-18 01:35:10 +01:00
QMK Bot
faf51c7449 Merge remote-tracking branch 'origin/master' into develop 2024-08-17 20:41:16 +00:00
marksard
072947e573 Remove like_jis keymap. (#24292) 2024-08-17 21:40:45 +01:00
QMK Bot
8db800bfba Merge remote-tracking branch 'origin/master' into develop 2024-08-15 14:22:39 +00:00
Wilfried JEANNIARD
fe50774cb4 [Keyboard] Add/Update Pimoroni keybow 2040 (#23986)
* [Keyboard] Add pimoroni/keybow2040

* [Keyboard] Update pimoroni/keybow2040

Co-Authored-By: Less/Rikki <86894501+lesshonor@users.noreply.github.com>
Co-Authored-By: Joel Challis <git@zvecr.com>
Co-Authored-By: Sandy Macdonald <1325593+sandyjmacdonald@users.noreply.github.com>

---------

Co-authored-by: Tony Finch <dot@dotat.at>
Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Sandy Macdonald <1325593+sandyjmacdonald@users.noreply.github.com>
2024-08-15 15:22:07 +01:00
QMK Bot
5f8aaf236f Merge remote-tracking branch 'origin/master' into develop 2024-08-15 13:37:59 +00:00
Joel Challis
39324e642f Update Discord URL (#24283) 2024-08-15 14:37:27 +01:00
QMK Bot
1f02cd45af Merge remote-tracking branch 'origin/master' into develop 2024-08-15 11:11:07 +00:00
Ryan
b07a68230d Fix version check in Fedora install script to be >= 39 (#24281) 2024-08-15 12:10:35 +01:00
Drashna Jaelre
2d2eed9594 [Keyboard] Move Planck EZ to ZSA vendor folder (#23917) 2024-08-14 14:27:37 +01:00
フィルターペーパー
822a4580f4 Refactor starlight RGB matrix effects (#24202)
* Use unsigned integers
* Use lib8tion random8 function
* Test for valid LED flags
* Use rgb_matrix_hsv_to_rgb function
2024-08-14 00:55:00 +01:00
フィルターペーパー
91f293d0c7 Refactor riverflow RGB matrix loop (#24203)
Check for LED flags at the start of loop to skip early
2024-08-14 00:54:01 +01:00
Izumemori
40f2575b56 Fix NKRO and Mouse Emulation on arm_atsam (#23945) 2024-08-13 09:06:24 +10:00
QMK Bot
45397a44e3 Merge remote-tracking branch 'origin/master' into develop 2024-08-12 13:26:02 +00:00
Nick Brassel
dccada95aa Remove debugging prints. (#24271) 2024-08-12 23:25:29 +10:00
QMK Bot
2c6409fdd8 Merge remote-tracking branch 'origin/master' into develop 2024-08-12 12:34:54 +00:00
Nick Brassel
380e0c9cad Userspace: add support for adding environment variables during build (#22887) 2024-08-12 22:34:22 +10:00
Joel Challis
783f97ff32 Remove handling of keyboard level keymap templates (#24234) 2024-08-12 22:29:05 +10:00
QMK Bot
ca6ba30a72 Merge remote-tracking branch 'origin/master' into develop 2024-08-12 10:36:29 +00:00
Nick Brassel
158aaef78c ChibiOS update script updates. (#24267) 2024-08-12 20:35:56 +10:00
Joel Challis
019b6f67b2 Remove keyboard level QK_BOOT implementations (#24231) 2024-08-10 13:50:36 +01:00
jack
339b820520 Fixup handwired/dactyl_minidox (#24253)
* Initial

* Fix missing bracket

* Fix keymap name

* Fix rgb matrix coordinates

* Remove unncessary centre point
2024-08-07 21:48:44 -06:00
QMK Bot
fc209e1c51 Merge remote-tracking branch 'origin/master' into develop 2024-08-07 20:44:32 +00:00
Andrew Kannan
5acc3b2b7b Add extra compatibility to Sat75 HS PCB (#24156) 2024-08-07 14:40:31 -06:00
QMK Bot
c0e2ecb825 Merge remote-tracking branch 'origin/master' into develop 2024-08-07 20:38:19 +00:00
stephen776
78900720fd JJ50 v2 Support (#24212)
* add support for JJ50 V2 PCB

* fix bootloader config

* update mousekey setting

* run format-json

---------

Co-authored-by: Steve Jacobs <sjacobs@truefit.io>
2024-08-07 14:34:21 -06:00
QMK Bot
142128740d Merge remote-tracking branch 'origin/master' into develop 2024-08-07 20:29:11 +00:00
Sắn
c67c3d375b Add support for bunnygirl65 (#24244)
* Add support for bunnygirl65

* Update keyboard.json

* Update keymap.c

* Update keymap.c

* Update keyboards/sawnsprojects/bunnygirl65/readme.md

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

* Update keyboards/sawnsprojects/bunnygirl65/keyboard.json

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

* Update keyboards/sawnsprojects/bunnygirl65/keyboard.json

---------

Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <jack@pngu.org>
2024-08-07 14:28:41 -06:00
Joel Challis
ac1b488170 Refactor printedpad (#24236) 2024-08-04 20:34:57 +01:00
Joel Challis
b5b4e93857 Refactor orthocode (#24237) 2024-08-04 15:14:30 +01:00
Ryan
1f942bb17e Small tweaks to keymap generation (#24240) 2024-08-04 12:28:40 +01:00
Nick Brassel
5c10bd3d8c Fixup changelog entry path. 2024-08-04 11:44:24 +10:00
Joel Challis
0fbe150303 Remove unnecessary RGB Matrix shutdown hooks (#24238) 2024-08-04 02:07:02 +01:00
Ryan
0b4065b50c hs60/v1: separate into ANSI and ISO revisions (#24136) 2024-08-04 02:03:54 +01:00
QMK Bot
b04fee4ff7 Merge remote-tracking branch 'origin/master' into develop 2024-08-03 23:48:33 +00:00
eason
75402109e9 Add Void65h (#24183) 2024-08-04 00:46:12 +01:00
QMK Bot
ddc60da839 Merge remote-tracking branch 'origin/master' into develop 2024-08-03 23:38:27 +00:00
Ryan
fa657fef70 atlantis/ak81_ve: move RGB Matrix LED config to data driven (#24115) 2024-08-04 00:38:26 +01:00
Ryan
eb78ca1c1a handwired/p65rgb: move RGB Matrix LED config to data driven (#24124) 2024-08-04 00:37:57 +01:00
QMK Bot
bb20093b24 Merge remote-tracking branch 'origin/master' into develop 2024-08-03 22:17:52 +00:00
Christian Greene
d28a50e176 FX19 Support (#24220) 2024-08-03 23:11:49 +01:00
Joel Challis
8808fffc2f Refactor opendeck/32 (#24233) 2024-08-03 23:10:09 +01:00
Ryan
9f387f525c Remove handwired/pytest/has_template (#24232) 2024-08-03 16:55:02 +01:00
QMK Bot
807ba71c89 Merge remote-tracking branch 'origin/master' into develop 2024-07-31 00:08:24 +00:00
akyp
c7662e4f36 [Keyboard] Add archerkeyboard/desire65 (#23776)
Co-authored-by: jack <0x6a73@protonmail.com>
2024-07-31 10:07:51 +10:00
QMK Bot
5439507f5e Merge remote-tracking branch 'origin/master' into develop 2024-07-30 21:22:14 +00:00
Cipulot
73cb6fd89f cipulot/ec_60x: Fix VIA layout options (#24217)
This fixes the issue of one layout option not being applied correctly because it was out of bound.
2024-07-30 22:21:42 +01:00
Nick Brassel
8ca082892a Eliminate use of #include "../default/keymap.c". (#24215) 2024-07-30 13:06:15 +10:00
QMK Bot
9c1e1d1fee Merge remote-tracking branch 'origin/master' into develop 2024-07-28 18:16:45 +00:00
Dasky
d538451adb Remove AVR GCC version warning (#24206) 2024-07-28 19:16:15 +01:00
Joel Challis
02b43b4b60 Refactor use of matrix_scan_kb (#24200) 2024-07-26 22:02:51 -07:00
Joel Challis
20ae67ba01 Remove duplicate calls to housekeeping_task_user (#24201) 2024-07-26 21:56:33 -07:00
Less/Rikki
938837e881 refactor: keyboard/ncr80/r2 (#22670)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-07-26 19:14:00 -07:00
QMK Bot
b3d8d5671c Merge remote-tracking branch 'origin/master' into develop 2024-07-26 00:42:26 +00:00
Dasky
cf84ea7662 Fix Reverb lockup when using GCC14 (#24199) 2024-07-26 01:41:54 +01:00
Dasky
56ebd3b829 Rename promicro_rp2040 converter to sparkfun_pm2040 (#24192) 2024-07-25 22:51:32 +01:00
Joel Challis
f98ddf02f4 Remove split.transport.protocol=serial (#24191) 2024-07-24 22:11:18 +01:00
QMK Bot
c25b3bbe90 Merge remote-tracking branch 'origin/master' into develop 2024-07-24 05:17:22 +00:00
Nick Brassel
8c35011d0a [CLI] Only generate files if contents change. (#24038)
Don't overwrite if the content doesn't change.
2024-07-24 06:16:51 +01:00
QMK Bot
c45e75037b Merge remote-tracking branch 'origin/master' into develop 2024-07-24 03:51:08 +00:00
Joel Challis
8c5acdea12 Update to automatic-approve-action fork (#24188) 2024-07-24 04:50:38 +01:00
QMK Bot
783f465cd4 Merge remote-tracking branch 'origin/master' into develop 2024-07-23 23:06:19 +00:00
dependabot[bot]
60c5ad821c Bump actions/labeler from 4 to 5 (#22608)
* Bump actions/labeler from 4 to 5

Bumps [actions/labeler](https://github.com/actions/labeler) from 4 to 5.
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](https://github.com/actions/labeler/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/labeler
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: zvecr <git@zvecr.com>
2024-07-24 00:05:50 +01:00
フィルターペーパー
59c275afbc Check LED flags for Pixel Fractal effect (#23881) 2024-07-23 19:34:00 +01:00
Joel Challis
bcfe3a0718 Migrate split.soft_serial_pin to split.serial.pin H-O (#24185) 2024-07-23 15:49:11 +01:00
QMK Bot
adb884761d Merge remote-tracking branch 'origin/master' into develop 2024-07-23 11:21:45 +00:00
Ryan
622dc56250 kingly_keys/ave: adjust layout names (#24179) 2024-07-23 21:20:17 +10:00
Joel Challis
e8103722bc Migrate split.soft_serial_pin to split.serial.pin 0-H (#24155) 2024-07-23 12:13:05 +01:00
Joel Challis
ce1adce696 Migrate split.soft_serial_pin to split.serial.pin O-Z (#24146)
Migrate split.soft_serial_pin to split.serial.pin
2024-07-23 12:12:52 +01:00
QMK Bot
df2d30fd2c Merge remote-tracking branch 'origin/master' into develop 2024-07-23 11:04:03 +00:00
Ryan
d079372580 meme: adjust layout names (#24178) 2024-07-23 21:03:02 +10:00
Cipulot
883821fa62 Rename EC Type-K (#24180)
Board name order change and default brightness change
2024-07-23 11:38:03 +01:00
QMK Bot
599899c5fb Merge remote-tracking branch 'origin/master' into develop 2024-07-23 10:37:50 +00:00
Ikko Eltociear Ashimine
af70e3759a [docs] update serial.md (#24182)
capabilites -> capabilities
2024-07-23 11:37:19 +01:00
QMK Bot
1eaead3ba4 Merge remote-tracking branch 'origin/master' into develop 2024-07-22 16:13:06 +00:00
Ryan
4bcc80ad46 merge/um80: reduce firmware size (#24177) 2024-07-22 17:12:55 +01:00
Ryan
d09c11dc78 kprepublic/bm40hsrgb/rev2: reduce firmware size (#24176) 2024-07-22 17:12:34 +01:00
fauxpark
9da9b245d3 Merge remote-tracking branch 'upstream/master' into develop 2024-07-23 01:40:23 +10:00
Ryan
82f9019cc9 melgeek/mojo68/rev1: reduce firmware size (#24171) 2024-07-23 01:29:40 +10:00
Ryan
4e2effc538 rubi: reduce firmware size (#24170) 2024-07-23 01:16:00 +10:00
QMK Bot
a9d6825795 Merge remote-tracking branch 'origin/master' into develop 2024-07-22 15:05:12 +00:00
Ryan
8d5517fa63 doro67/rgb: reduce firmware size (#24169) 2024-07-23 01:04:34 +10:00
QMK Bot
8ef275789c Merge remote-tracking branch 'origin/master' into develop 2024-07-22 14:53:04 +00:00
Ryan
ee1505971f handwired/hnah108: reduce firmware size (#24168) 2024-07-23 00:52:31 +10:00
QMK Bot
a5e9926c45 Merge remote-tracking branch 'origin/master' into develop 2024-07-21 20:30:14 +00:00
yiancar
b6e1a20950 Keycult TKL (#24148)
Co-authored-by: yiancar <yiancar@gmail.com>
2024-07-21 13:29:45 -07:00
Dasky
cced3ee622 Fix incorrect conflict resolution 2024-07-21 01:53:11 +01:00
Dasky
4e20740efa Merge branch 'master' into develop 2024-07-21 01:08:51 +01:00
Dasky
f2c789bb4a Fix build failures noticed in #24163 CI log. (#24164) 2024-07-21 09:56:39 +10:00
Dasky
d5cc00ab62 Remove instances of MASTER_LEFT. (#24163) 2024-07-20 23:49:20 +01:00
QMK Bot
1e4435f22d Merge remote-tracking branch 'origin/master' into develop 2024-07-20 22:02:26 +00:00
Ryan
fab50be817 mwstudio/mw75: reduce size (#24161) 2024-07-21 07:59:45 +10:00
Ryan
f04fd13dff mechlovin/delphine/rgb_led: reduce size (#24160) 2024-07-21 07:57:10 +10:00
QMK Bot
23e7d93d0e Merge remote-tracking branch 'origin/master' into develop 2024-07-20 21:53:32 +00:00
Ryan
eb60235cd5 handwired/tractyl_manuform/5x6_right/arduinomicro: reduce size (#24159) 2024-07-21 07:53:04 +10:00
QMK Bot
8a58ad27a2 Merge remote-tracking branch 'origin/master' into develop 2024-07-20 13:04:27 +00:00
Joel Challis
2fb9816c77 Remove incorrect use of split.main (#24158) 2024-07-20 14:03:57 +01:00
QMK Bot
2764e48146 Merge remote-tracking branch 'origin/master' into develop 2024-07-20 09:57:21 +00:00
Ryan
6fbe91aecd keychron/q2: fix RGB Matrix config for JIS variant (#24138) 2024-07-20 10:56:51 +01:00
QMK Bot
a6c8c41c68 Merge remote-tracking branch 'origin/master' into develop 2024-07-19 05:56:43 +00:00
Ryan
a6857872f2 kopibeng/xt60/xt60_singa: reduce firmware size (#24149) 2024-07-19 06:56:00 +01:00
QMK Bot
78fa0f5ca0 Merge remote-tracking branch 'origin/master' into develop 2024-07-19 05:55:19 +00:00
Ryan
56323f75c6 pixelspace/capsule65i: reduce firmware size (#24150) 2024-07-19 06:54:50 +01:00
QMK Bot
ddb679ba88 Merge remote-tracking branch 'origin/master' into develop 2024-07-19 05:54:27 +00:00
Ryan
11031adc1b clueboard/66/rev3: reduce firmware size (#24152) 2024-07-19 06:53:56 +01:00
Ryan
7b4e806c25 Move LED Matrix LED config to data driven (#24122) 2024-07-19 08:13:49 +10:00
QMK Bot
8b46500a74 Merge remote-tracking branch 'origin/master' into develop 2024-07-18 22:05:16 +00:00
Ryan
d79f46e408 vertex/angler2: reduce firmware size (#24140) 2024-07-19 08:04:40 +10:00
Joel Challis
5a0112df08 Migrate half-duplex SERIAL_USART_TX_PIN to DD (#24143) 2024-07-18 22:21:26 +01:00
QMK Bot
7ca0424189 Merge remote-tracking branch 'origin/master' into develop 2024-07-18 07:11:15 +00:00
Ryan
2ddfd60be7 amjkeyboard/amj60: reduce firmware size (#24139) 2024-07-18 08:10:45 +01:00
Joel Challis
4ab36df48f Move split.soft_serial_pin to split.serial.pin (#24127) 2024-07-18 09:02:53 +10:00
Nick Brassel
daa777d6fb [WIP] Adds bus acquire/release semantics to SPI start/stop. (#23439) 2024-07-18 08:59:08 +10:00
QMK Bot
e69be076fc Merge remote-tracking branch 'origin/master' into develop 2024-07-17 19:31:51 +00:00
Joel Challis
63ef6516d3 Avoid path issues with qmk flash on Windows (#24130) 2024-07-17 20:31:18 +01:00
Ryan
275e9de350 Remove pointless RGB_MATRIX_LED_COUNTs (#24133) 2024-07-17 16:13:40 +01:00
QMK Bot
35356c4623 Merge remote-tracking branch 'origin/master' into develop 2024-07-16 04:43:55 +00:00
yiancar
522bf1daf2 Skelett40 (#24121)
Co-authored-by: yiancar <yiancar@gmail.com>
2024-07-15 21:43:26 -07:00
Nick Brassel
8abaa3bc2d Add support for key override introspection. (#24120) 2024-07-16 09:22:17 +10:00
QMK Bot
fef8e7195b Merge remote-tracking branch 'origin/master' into develop 2024-07-15 08:42:14 +00:00
Ryan
a763dd5bbd matrix/noah: move RGB Matrix LED config to data driven (#24117) 2024-07-15 18:41:44 +10:00
QMK Bot
65143b08a3 Merge remote-tracking branch 'origin/master' into develop 2024-07-15 05:30:07 +00:00
Logan Butler
c70c99367a Add matchstickworks normiepad (#23183)
Co-authored-by: jack <0x6a73@protonmail.com>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-07-14 22:29:37 -07:00
QMK Bot
fd44e96110 Merge remote-tracking branch 'origin/master' into develop 2024-07-15 05:06:22 +00:00
Ryan
b5b06f1094 checkerboards/axon40: adjust layout name (#24119) 2024-07-15 06:04:27 +01:00
Ryan
caa7599b83 checkerboards/pursuit40: adjust layout name (#24118) 2024-07-15 06:04:00 +01:00
QMK Bot
40d617f812 Merge remote-tracking branch 'origin/master' into develop 2024-07-15 04:59:04 +00:00
Lex Brugman
c2dbbc060a Add MMkeyboard Class60 (#22972)
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: Joel Challis <git@zvecr.com>
2024-07-14 21:58:35 -07:00
Robbie
d885963e38 [Keyboard] Whitefacemountain Ampersand (#23437)
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-07-14 21:23:13 -07:00
Ryan
85447bd53b LED drivers: extract documentation from LED/RGB Matrix pages (#23630) 2024-07-15 12:03:30 +10:00
Tvrd Rad Keyboards
21b9b70c50 Add TRKeyboard TRK1 keyboard (#23642) 2024-07-13 23:00:26 -07:00
Joel Challis
c0aca9f45c Various fixes for keyboards not implementing callbacks correctly (#24116) 2024-07-14 06:38:04 +01:00
QMK Bot
e76069ea4e Merge remote-tracking branch 'origin/master' into develop 2024-07-13 13:41:12 +00:00
Ryan
875eb43a28 dp60: move RGB Matrix LED config to data driven (#24022) 2024-07-13 23:40:36 +10:00
QMK Bot
2db93b5945 Merge remote-tracking branch 'origin/master' into develop 2024-07-13 13:28:04 +00:00
Alabahuy
2908f0b846 Add Aums Work keyboard (#23600) 2024-07-13 06:24:11 -07:00
QMK Bot
3ebf9880ca Merge remote-tracking branch 'origin/master' into develop 2024-07-13 13:19:36 +00:00
Ryan
a3d938d822 ryanskidmore/rskeys100: move RGB Matrix LED config to data driven (#24114) 2024-07-13 14:19:07 +01:00
QMK Bot
83a7506438 Merge remote-tracking branch 'origin/master' into develop 2024-07-13 12:44:22 +00:00
Yue Wu
6dfd7ed46f Fix i2c received value in georgi and bajjak (#24113) 2024-07-13 22:43:52 +10:00
Joel Challis
f0807ea64f Migrate SPLIT_HAND_PIN to json (#23924) 2024-07-13 13:29:16 +01:00
Joel Challis
26e84c513c Migrate SERIAL_DRIVER to json (#23925) 2024-07-13 13:12:35 +01:00
Ryan
1552cf2ddc Update atomic GPIO macros in keyboard custom matrix (#23796) 2024-07-13 18:41:05 +10:00
QMK Bot
5c43a9bed1 Merge remote-tracking branch 'origin/master' into develop 2024-07-13 02:11:31 +00:00
c0ldbru
7b5d7907df adds veilid SAO macropad (#23868)
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: c0ldbru <c0ldbrusec@gmail.com>
2024-07-12 19:11:00 -07:00
QMK Bot
cfd0ab2198 Merge remote-tracking branch 'origin/master' into develop 2024-07-12 20:47:09 +00:00
paradoxskin
79ad561b67 Fix typo in Keychron comments: "lcok" to "lock" (#24107) 2024-07-12 14:46:38 -06:00
QMK Bot
85cf8b5183 Merge remote-tracking branch 'origin/master' into develop 2024-07-12 09:36:02 +00:00
Ryan
5a5f68038e mechwild/bbpad: fix build (#24106) 2024-07-12 10:35:32 +01:00
Joel Challis
52ee9f2ce1 Convert eeconfig_init_kb implementations to config (#24087) 2024-07-12 08:06:19 +01:00
Joel Challis
2c2885639e Remove broken keymap from keebio/iris (#24094) 2024-07-12 02:42:23 +01:00
QMK Bot
57b7f8534b Merge remote-tracking branch 'origin/master' into develop 2024-07-12 00:20:05 +00:00
Nick Brassel
4d4d7b76b0 [CI] Disable Discord webhook when CI run is cancelled. (#24104)
* Disable Discord webhook when CI run is cancelled.

* Include link to binaries in Discord output.
2024-07-12 01:19:33 +01:00
QMK Bot
6051fc87e3 Merge remote-tracking branch 'origin/master' into develop 2024-07-12 00:19:31 +00:00
zvecr
c58c5fa8fa Fix missing hashbang 2024-07-12 01:18:50 +01:00
QMK Bot
aaf9074e85 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 23:49:18 +00:00
Nick Brassel
565bb704e0 fixup CI exec flag 2024-07-12 09:48:38 +10:00
QMK Bot
1ba4fef711 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 23:19:55 +00:00
Nick Brassel
890909c2d7 [CI] Remove via keymap builds. (#24103) 2024-07-12 09:19:04 +10:00
QMK Bot
3251f4b168 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 23:01:49 +00:00
Nick Brassel
f15fff3258 [CI] Pull full history before generating index (#24102)
For some reason the history generation is way out.
2024-07-12 00:01:20 +01:00
QMK Bot
f7a53df9d4 [CI] Format code according to conventions (#24101) 2024-07-12 09:00:17 +10:00
QMK Bot
f922ed4283 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 22:59:43 +00:00
QMK Bot
7d94db8661 [CI] Format code according to conventions (#24100) 2024-07-12 08:58:57 +10:00
QMK Bot
4827d383a8 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 22:49:15 +00:00
Joel Challis
063f1444c6 Add json index of files to CI uploads (#24097) 2024-07-12 08:48:43 +10:00
QMK Bot
ec5786bdd1 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 13:54:04 +00:00
QMK Bot
2e671cfd8b [CI] Format code according to conventions (#24095)
Format code according to conventions
2024-07-11 14:50:39 +01:00
QMK Bot
2df8046dd0 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 13:44:07 +00:00
Nick Brassel
1b8b6801d4 [CI] Add index page generator. (#23737) 2024-07-11 14:43:26 +01:00
leyew
2623a258f1 [Keyboard] Rename dnworks/9973 to dnworks/tkl87 (#23692) 2024-07-11 14:40:54 +01:00
QMK Bot
ac8759fe74 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 13:40:17 +00:00
jack
cc62eb503d [Keyboard] Add boardsource/sessenta (#23823) 2024-07-11 14:39:45 +01:00
QMK Bot
22f830d67c Merge remote-tracking branch 'origin/master' into develop 2024-07-11 12:52:22 +00:00
4pplet
0c4fd514f1 Adding support for IBE60 (#24075) 2024-07-11 13:51:43 +01:00
Ryan
9be6d76c61 mt/mt64rgb: move RGB Matrix config to data driven (#24089) 2024-07-11 13:50:26 +01:00
QMK Bot
27ea1b1332 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 12:50:20 +00:00
Ryan
3d10171e2c mt/mt84: move RGB Matrix config to data driven (#24090) 2024-07-11 13:49:45 +01:00
Joel Challis
e0809eade5 Various fixes for keyboards not implementing callbacks correctly (#24092) 2024-07-11 13:47:53 +01:00
QMK Bot
23c4704123 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 12:47:41 +00:00
tarxvf
e3ef5b2d9d mntre_v3: fix matrix bottom row (#24077) 2024-07-11 13:46:54 +01:00
QMK Bot
4d4ccdc41a Merge remote-tracking branch 'origin/master' into develop 2024-07-11 12:11:16 +00:00
Dasky
f8cf58a512 Remove a user keymap from crkbd. (#24091)
remove personal keymap
2024-07-11 13:10:28 +01:00
zvecr
b066c86e43 bad_kb_funcs1 2024-07-11 11:03:11 +01:00
jack
494af672ce Fixup boardsource/the_q RGB matrix coordinates (#24086) 2024-07-11 07:14:49 +01:00
QMK Bot
aa8d68036a Merge remote-tracking branch 'origin/master' into develop 2024-07-11 02:50:40 +00:00
era
efa5b30cfd [Keyboard] Add Linx3 FAve65S (#24034)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-07-10 19:50:09 -07:00
Joel Challis
f5319d8911 Remove DEFAULT_FOLDER from maple_computing/lets_split_eh (#24054) 2024-07-10 17:17:08 -07:00
Will Hedges
d69b44e68a refactor bear_face/v1, v2 (#24060)
Co-authored-by: jack <jack@pngu.org>
2024-07-10 17:15:35 -07:00
QMK Bot
f637ff8966 Merge remote-tracking branch 'origin/master' into develop 2024-07-11 00:10:22 +00:00
Ryan
fb54a59bba jadookb/jkb65: move RGB Matrix LED config to data driven (#24080) 2024-07-10 17:09:41 -07:00
jack
c97ec805cd [Keyboard] Add boardsource/the_q (#23782)
* initial unsplit keyboard

* move shared code

* unsplit: fix underglow led x,y & remove unecessary code

* unsplit: remove split code & tidy readme

* unsplit: limit brightness & community layout

* rename keyboard

* the_q: tidy keymap & readme

* lulu: remove accidental build target

* rename file
2024-07-10 13:19:06 -06:00
QMK Bot
07fd206370 Merge remote-tracking branch 'origin/master' into develop 2024-07-08 16:27:41 +00:00
Ryan
fbbc71ec34 kakunpc/rabbit_capture_plan: update keymap layout name (#24079)
`kakunpc/rabbit_capture_plan`: update keymap layout names
2024-07-08 10:27:09 -06:00
fauxpark
83d436581f Merge remote-tracking branch 'upstream/master' into develop 2024-07-08 16:08:57 +10:00
Ryan
a0bb7ff992 latinpad/latin60rgb: move RGB Matrix LED config to data driven (#24076) 2024-07-08 15:57:45 +10:00
Ryan
6eb6e3048a pearlboards/zeuspad: add additional layouts (#24066) 2024-07-08 15:57:29 +10:00
Ryan
d08da05cb8 mechlovin/olly/octagon: move LED Matrix LED config to data driven (#24069) 2024-07-08 15:57:13 +10:00
Ryan
8336b5c72f ash1800: add additional layouts (#24065) 2024-07-08 15:56:57 +10:00
Y.KEISUKE
54f907bfe9 Fix for encoders and support ENCODER_MAP_ENABLE on Planck rev7 (#23967)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-07-08 08:45:35 +10:00
Less/Rikki
b23ddb9ad8 [keyboard] mechwild/bbpad (#24072)
* Initial bbpad commit

* refactor: bbpad

---------

Co-authored-by: Kyle McCreery <mccreery.kyle@gmail.com>
2024-07-07 13:09:48 -06:00
Lex Brugman
67d512e639 Fix enter for two ANSI layouts on the TKD Cycle7 (#24070) 2024-07-07 00:58:04 +01:00
takashicompany
e643fa03ef Fix dogtag/info.json (#23520) 2024-07-07 00:56:57 +01:00
Ryan
4fbb395602 ano: fix layout name (#24067) 2024-07-06 09:21:11 +01:00
Nick Brassel
1c02c3dfad [docs] Fixup home link. (#24068) 2024-07-06 16:19:00 +10:00
Ryan
e4dfbb075e handwired/swiftrax/bumblebee: fix layout name (#24064) 2024-07-06 16:19:00 +10:00
Ryan
2477aa9161 [docs] Update RGBLight (Underglow) keycode names (#23999) 2024-07-06 16:18:59 +10:00
Nick Brassel
300505bd9e [docs] Fixup home link. (#24068) 2024-07-06 16:08:55 +10:00
Ryan
38f07e1fd2 handwired/swiftrax/bumblebee: fix layout name (#24064) 2024-07-06 03:23:54 +01:00
Ryan
b82f6ac402 [docs] Update RGBLight (Underglow) keycode names (#23999) 2024-07-06 11:14:09 +10:00
Nick Brassel
4ae0ca5a11 Tap dance introspection (#24049) 2024-07-06 00:57:54 +01:00
QMK Bot
b9e67347f1 Merge remote-tracking branch 'origin/master' into develop 2024-07-05 22:43:39 +00:00
Ryan
be967d42d2 playkbtw/pk64rgb: move RGB Matrix LED config to data driven (#24062) 2024-07-05 23:41:32 +01:00
QMK Bot
c5e317aad9 Merge remote-tracking branch 'origin/master' into develop 2024-07-05 22:26:17 +00:00
dependabot[bot]
af72a58c8f Bump JamesIves/github-pages-deploy-action from 4.6.1 to 4.6.3 (#24063)
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.1 to 4.6.3.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.1...v4.6.3)

---
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-07-05 23:25:48 +01:00
Joel Challis
d0e89aecca Align LUFA suspend logic (#24055) 2024-07-05 12:02:39 +01:00
QMK Bot
ecf5b26ff0 Merge remote-tracking branch 'origin/master' into develop 2024-07-05 10:58:17 +00:00
Ryan
9fb51cfe2b kbdfans/baguette66: fix layout name (#24061) 2024-07-05 11:57:39 +01:00
QMK Bot
4e8772b5cc Merge remote-tracking branch 'origin/master' into develop 2024-07-05 10:55:55 +00:00
ai03
6d21898c14 Add support for Equinox XL (#23695) 2024-07-05 11:55:25 +01:00
QMK Bot
5078ca651c Merge remote-tracking branch 'origin/master' into develop 2024-07-05 06:36:06 +00:00
Ryan
096dc672c1 kakunpc/rabbit_capture_plan: add additional layouts (#24059) 2024-07-05 16:35:48 +10:00
QMK Bot
10e2f1e29f Merge remote-tracking branch 'origin/master' into develop 2024-07-05 06:35:47 +00:00
Ryan
8e64ff574a kakunpc/angel64: add additional layouts (#24058) 2024-07-05 16:35:35 +10:00
Ryan
5e2368984e ash_xiix: add additional layouts (#24057) 2024-07-05 16:35:15 +10:00
QMK Bot
9dba1cadc9 Merge remote-tracking branch 'origin/master' into develop 2024-07-05 05:25:47 +00:00
Ryan
15af5d7d0d handwired/tkk: fix layout name (#24056) 2024-07-04 23:25:00 -06:00
QMK Bot
443d111403 Merge remote-tracking branch 'origin/master' into develop 2024-07-05 05:10:31 +00:00
Ryan
62c1787d72 dc01/arrow: fix layout name (#24025) 2024-07-05 15:10:02 +10:00
QMK Bot
777db159ac Merge remote-tracking branch 'origin/master' into develop 2024-07-05 01:36:01 +00:00
Coby Sher
8fe667a1a4 Add Sleepy Craft Studios Sleepy Keeb Split (#23844) 2024-07-04 18:35:29 -07:00
Nick Brassel
3a711f4cfa Allow overriding get_hardware_id(). (#24051) 2024-07-05 11:22:08 +10:00
QMK Bot
cd22b8a945 Merge remote-tracking branch 'origin/master' into develop 2024-07-04 23:55:04 +00:00
Ryan
031ccd4887 salicylic_acid3/setta21: fix RGB Matrix LED config (#24041) 2024-07-05 00:49:05 +01:00
QMK Bot
41878d276e Merge remote-tracking branch 'origin/master' into develop 2024-07-04 23:44:53 +00:00
Ryan
43fc7b5a4f kikoslab/kl90: add additional layouts (#24024) 2024-07-05 00:44:23 +01:00
QMK Bot
9536b86a09 Merge remote-tracking branch 'origin/master' into develop 2024-07-04 19:50:25 +00:00
Ryan Neff
4ced8d9371 Fixes duplicate pid/vid for sofle_choc (#24030) 2024-07-04 13:49:55 -06:00
QMK Bot
9adac59c29 Merge remote-tracking branch 'origin/master' into develop 2024-07-04 02:42:11 +00:00
Cipulot
1c6cdb8d74 [Keyboard] Addition of EC 60X (#24028)
* Addition of EC 60X

* Update keyboards/cipulot/ec_60x/keymaps/via/keymap.c

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

* Update keyboards/cipulot/ec_60x/keymaps/default/keymap.c

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

* Update keyboards/cipulot/ec_60x/keyboard.json

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

* Update keyboards/cipulot/ec_60x/keyboard.json

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

* Update keyboards/cipulot/ec_60x/keyboard.json

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

* Update keyboards/cipulot/ec_60x/keyboard.json

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

* Revert "Update keyboards/cipulot/ec_60x/keyboard.json"

This reverts commit 5f49ef63cd.

* Revert "Update keyboards/cipulot/ec_60x/keyboard.json"

This reverts commit 5fb9706acd.

* revert of what was done with the layouts

* Update keyboards/cipulot/ec_60x/mcuconf.h

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

---------

Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-07-03 20:42:07 -06:00
chalex
c663f5e9f3 [Keyboard] Add chlx lfn merro (#24026)
* add previous working files to new branch

* update config files. tested via version

* update per qmk PR requested changes - 1. rename info.json -> keyboard.json, move config.h -> keyamps/via/config.h, remove rules.mk

* update photo link for pcb

* remove redundant community keymaps

* Update keyboards/chlx/lfn_merro60/keymaps/default/keymap.c

correct keycode for iso keys

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

* switch image url to source from imgur instead of github

---------

Co-authored-by: chalex <alejandrelee+magbogbro@gmail.com>
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
2024-07-03 20:40:24 -06:00
QMK Bot
32ec677d8d Merge remote-tracking branch 'origin/master' into develop 2024-07-04 02:39:15 +00:00
Guanzhong Chen
977918982d monsgeek/m5: make numlock and capslock LEDs work (#24027) 2024-07-03 20:38:38 -06:00
Will Hedges
26c114a2b4 [keyboard] added bear_face/v3 (#24032)
* added keyboard.json, default, default_iso, and keymap READMEs
2024-07-03 20:38:03 -06:00
QMK Bot
17c6744c82 Merge remote-tracking branch 'origin/master' into develop 2024-07-04 02:34:47 +00:00
James Gzowski
c2f7974c8e [Keyboard] Add Ashwing66 (#24031)
* Create hello.txt

* Add files via upload

* Create keymap.c

* Ashwing66

* Update readme.md

* Update keymap.c

* Ashwing66 addition

* Ashwing66 addition

* Changes as per request

* Changes as per request

* Changes as per request, Updated repo, fixed filenames

* 02-Jul-11:04:08
2024-07-03 20:34:17 -06:00
Drashna Jaelre
bdca9318f9 Change suspend condition check order on ChibiOS (#24020) 2024-07-04 12:13:00 +10:00
DavidSannier
e07f752a57 [build_test] set CONSOLE_ENABLE=yes if DEBUG > 0 (#23097) 2024-07-04 00:15:44 +01:00
QMK Bot
eed2a74be9 Merge remote-tracking branch 'origin/master' into develop 2024-07-03 12:01:26 +00:00
Nick Brassel
bc8ac86422 Minimum python version listing. (#23989) 2024-07-03 22:00:53 +10:00
QMK Bot
ce9edc94e5 Merge remote-tracking branch 'origin/master' into develop 2024-07-03 10:32:19 +00:00
Ryan
33adb8cba0 vertex/arc60h: add additional layouts (#24023) 2024-07-03 20:31:49 +10:00
QMK Bot
a400c332d2 Merge remote-tracking branch 'origin/master' into develop 2024-07-03 08:46:37 +00:00
kopibeng
e754c9f2b4 Update keymap for KLC x TGR Lena (#23688) 2024-07-03 01:38:57 -07:00
Ryan
f8596b40a4 Normalise mouse keycodes (#23975) 2024-07-03 18:35:54 +10:00
Ryan
bc0c69570b Rename encoder pins defines (#24003) 2024-07-03 17:18:27 +10:00
QMK Bot
8471dcc563 Merge remote-tracking branch 'origin/master' into develop 2024-07-02 21:35:55 +00:00
Cipulot
869b7d9ae6 Fix index EC Dolice (#24033)
* Update keyboard.json

Fixed wrong index in keyboard.json

* Small touch layout
2024-07-02 15:35:26 -06:00
Nick Brassel
7bc3eef8cc SPI flash API cleanup, add async erase capability. (#23894) 2024-07-02 10:16:41 +10:00
QMK Bot
641a1ce568 Merge remote-tracking branch 'origin/master' into develop 2024-06-30 02:40:18 +00:00
Joel Challis
3ffe8d917a Fix 'qmk new-keyboard' processing of development_board (#23996) 2024-06-30 03:39:49 +01:00
QMK Bot
e8e5d11ed8 Merge remote-tracking branch 'origin/master' into develop 2024-06-30 01:58:04 +00:00
Danylo Kondratiev
12379dc1eb Fix ploopy Adept/Madromys link (#24018) 2024-06-30 02:57:35 +01:00
Joel Challis
0947299864 Remove custom keycodes from nullbitsco/snap (#24017) 2024-06-29 14:25:24 +01:00
QMK Bot
bd5da148ec Merge remote-tracking branch 'origin/master' into develop 2024-06-29 10:57:00 +00:00
Ryan
d6bfbdb6b1 horrortroll/handwired_k552: fix RGB Matrix LED config (#24014) 2024-06-29 20:56:29 +10:00
QMK Bot
3e4159bc55 Merge remote-tracking branch 'origin/master' into develop 2024-06-29 09:27:40 +00:00
Ryan
cc0b2f9814 jels/boaty: adjust layout name (#24013) 2024-06-29 10:20:11 +01:00
Ryan
5624804c68 h0oni/deskpad and hotduck: adjust layout names (#24004) 2024-06-29 10:19:51 +01:00
Joel Challis
38f72c5d2b Relocate xelus/pachi/rgb/rev2 VIA logic (#24016) 2024-06-29 10:17:47 +01:00
Joel Challis
07253bfe4a Relocate work_louder VIA logic (#24011) 2024-06-29 09:33:20 +01:00
QMK Bot
62f81cfcc3 Merge remote-tracking branch 'origin/master' into develop 2024-06-29 06:55:21 +00:00
Ryan
2bde8ce206 ez_maker: adjust layout names (#24015) 2024-06-29 07:54:52 +01:00
QMK Bot
b94f70d642 Merge remote-tracking branch 'origin/master' into develop 2024-06-29 06:00:35 +00:00
Ryan
086e8e938e tzarc/djinn: adjust layout name (#24012) 2024-06-29 16:00:05 +10:00
Ryan
af8fe44e0f atreus: misc cleanups (#24010) 2024-06-29 05:50:08 +01:00
Joel Challis
7bc53b8baa Relocate m256ws VIA logic (#24009) 2024-06-29 04:20:08 +01:00
Joel Challis
9ca1f35333 Relocate winry315 VIA logic (#24008) 2024-06-29 04:16:52 +01:00
QMK Bot
2998d20a00 Merge remote-tracking branch 'origin/master' into develop 2024-06-29 03:08:12 +00:00
Ryan
cd374b1500 clueboard/card: Swap layout and alias (#24007) 2024-06-29 04:07:42 +01:00
Joel Challis
be7728ae58 Relocate m256wh VIA logic (#24006) 2024-06-29 03:36:28 +01:00
QMK Bot
ffd9062190 Merge remote-tracking branch 'origin/master' into develop 2024-06-27 17:39:02 +00:00
Danny
9d02ac37f7 Add Nyquist Rev. 5 (#23971)
* Add Nyquist Rev. 5

* Remove unused keymap
2024-06-27 13:37:41 -04:00
Dasky
a7aa58cc81 Change ADNS9800 and PMW33XX SROM uploads to opt in. (#24001)
Make SROM upload optional
2024-06-27 05:10:13 +01:00
QMK Bot
276ecd4693 Merge remote-tracking branch 'origin/master' into develop 2024-06-27 03:56:17 +00:00
David Hoelscher
603586800c [Keyboard] Add Elysian (#23949)
* adding Elysian

* corrections from zvecr
2024-06-26 21:56:16 -06:00
TyraelWasTaken
90b043e01c Add support for Equanimity (#23965)
* Add Equanimity files

* Update keyboard.json format

* Update readme.md

* CRLF to LF

* Force LF and correct rules.mk

* Remove config.h

* Remove rules.mk

* Update keymap.c

* Update keyboard.json

* Update name in readme.md
2024-06-26 21:55:47 -06:00
QMK Bot
5e3b558d5a Merge remote-tracking branch 'origin/master' into develop 2024-06-26 04:36:22 +00:00
Ryan
5f794217b4 xelus/snap96: add matrix diagram and some additional layouts (#23992) 2024-06-26 14:35:45 +10:00
QMK Bot
7c6dbe5e7c Merge remote-tracking branch 'origin/master' into develop 2024-06-26 04:29:16 +00:00
Ryan
b71b81d539 hs60/v2/hhkb: Adjust layout name (#23998) 2024-06-26 05:28:45 +01:00
QMK Bot
8bccabca25 Merge remote-tracking branch 'origin/master' into develop 2024-06-26 03:48:06 +00:00
Ryan
17ae6f9b53 helix/pico and rev2: add keyboard.jsons (#23964) 2024-06-26 13:47:36 +10:00
QMK Bot
2f18d4f449 Merge remote-tracking branch 'origin/master' into develop 2024-06-26 01:34:55 +00:00
Joel Challis
cebe521b11 Fix docker_cmd.sh when userspace is not configured (#23997) 2024-06-26 11:34:24 +10:00
QMK Bot
94586f821c Merge remote-tracking branch 'origin/master' into develop 2024-06-25 06:39:26 +00:00
Joel Challis
0b572a1be6 Remove some redundant 'blank' files (#23995) 2024-06-25 07:38:56 +01:00
Joel Challis
a2176f6a03 Migrate led_update_kb implementations to DD (#23985) 2024-06-25 03:25:05 +01:00
QMK Bot
751482580e Merge remote-tracking branch 'origin/master' into develop 2024-06-24 08:20:17 +00:00
Ryan
378dbd32bd custommk/ergostrafer_rgb: move to keyboard.json (#23990) 2024-06-24 18:19:48 +10:00
QMK Bot
c973ee1445 Merge remote-tracking branch 'origin/master' into develop 2024-06-24 02:30:03 +00:00
Nick Brassel
03e688e91f Add support for userspace to docker build commands. (#23988) 2024-06-24 12:29:30 +10:00
QMK Bot
d4e98e9fda Merge remote-tracking branch 'origin/master' into develop 2024-06-23 18:33:57 +00:00
Ryan
d5e0562a70 Rename layouts containing keyboard name (#23930) 2024-06-23 19:33:26 +01:00
Joel Challis
f0471dd5b4 Remove skipped schema files (#23987) 2024-06-23 09:02:13 +01:00
Ryan
e96d6d9bd4 Migrate RGB Matrix layout for two boards (#23963) 2024-06-23 04:08:57 +01:00
QMK Bot
b4047be3eb Merge remote-tracking branch 'origin/master' into develop 2024-06-23 02:58:22 +00:00
Ryan
191c8cca33 handwired/symmetric70_proto: add keyboard.json (#23966) 2024-06-23 03:57:50 +01:00
Joel Challis
7824e7ed9b Migrate led_update_kb implementations to DD (#23983) 2024-06-22 12:14:17 +01:00
Joel Challis
17498fa48a Migrate led_update_kb implementations to DD (#23981) 2024-06-22 12:14:07 +01:00
Joel Challis
cb39df273d Remove deprecated led_set_user (#23979) 2024-06-22 09:10:58 +01:00
Joel Challis
99aa4f5191 Migrate led_update_kb implementations to DD (#23980) 2024-06-22 09:10:12 +01:00
QMK Bot
35f0a17679 Merge remote-tracking branch 'origin/master' into develop 2024-06-22 04:45:34 +00:00
Joel Challis
7aa2ce2b38 Update documentation suggestion in top level readme (#23978) 2024-06-22 05:45:04 +01:00
QMK Bot
b180a0d415 Merge remote-tracking branch 'origin/master' into develop 2024-06-22 03:28:27 +00:00
Joel Challis
6f03d20a92 Fix 'qmk import-kbfirmware' WS2812 config (#23976) 2024-06-22 04:27:57 +01:00
QMK Bot
cc6bcf9bac Merge remote-tracking branch 'origin/master' into develop 2024-06-22 03:27:46 +00:00
Danny
e5c80fc6b3 Update what's powering QMK docs (#23977) 2024-06-22 04:27:15 +01:00
QMK Bot
05573be7b5 Merge remote-tracking branch 'origin/master' into develop 2024-06-22 00:54:29 +00:00
Kevin Horvat
aa11ef5bcf Fix leftover reference to previous AW20216S EN pin definition (#23974) 2024-06-22 01:53:59 +01:00
Amir
751a6b5bc4 add farsi keymap extras (#23650) 2024-06-20 16:12:16 -07:00
QMK Bot
27455bba6c Merge remote-tracking branch 'origin/master' into develop 2024-06-20 08:10:13 +00:00
Drashna Jaelre
a6ef34cd16 [Keyboard] fixes for ZSA Voyager (#23912) 2024-06-20 09:08:57 +01:00
QMK Bot
92881d38ef Merge remote-tracking branch 'origin/master' into develop 2024-06-20 01:59:59 +00:00
Joel Challis
4fdde75333 Update 'qmk import-kbfirmware' to use 'keyboard.json' (#23960) 2024-06-20 02:59:29 +01:00
Ryan
0a5b892820 [CLI] Force dump_lines() to always use Unix line endings (#23954) 2024-06-19 19:43:23 +01:00
Joel Challis
53a0cdc446 Implement data driven joysticks (#22947) 2024-06-18 03:44:22 +01:00
Joel Challis
938badc3b0 Generate keymap dd keycodes to header (#20273) 2024-06-17 21:51:53 +01:00
QMK Bot
59a3098139 Merge remote-tracking branch 'origin/master' into develop 2024-06-17 19:33:26 +00:00
lizaoreo
dafc46f1d1 Update RGB matrix indicator example (#23947)
Changed the example in indicator-examples-2 to use a compound literal, otherwise the code fails to compile.
2024-06-17 20:30:57 +01:00
QMK Bot
590281f4f2 Merge remote-tracking branch 'origin/master' into develop 2024-06-17 19:24:14 +00:00
Ryan
baa564bddf Remove references to bootloadHID flashing page in keyboard readmes (#23942)
* Remove references to bootloadHID flashing page in keyboard readmes

* Remove bootloadHID flashing page
2024-06-17 20:23:45 +01:00
Joel Challis
51acd35e6f Implement data driven serial driver (#23923) 2024-06-17 19:22:47 +01:00
QMK Bot
9f449246bb Merge remote-tracking branch 'origin/master' into develop 2024-06-17 10:12:58 +00:00
Ryan
3f44231d2d Strip decimals from RGB Matrix layout positions (#23943) 2024-06-17 20:12:26 +10:00
QMK Bot
63848603be Merge remote-tracking branch 'origin/master' into develop 2024-06-17 04:48:03 +00:00
Ryan
4864d5afca Mechwild OBE/Waka60: Fix build warnings (#23929) 2024-06-17 14:47:33 +10:00
QMK Bot
0966901f95 Merge remote-tracking branch 'origin/master' into develop 2024-06-16 20:58:08 +00:00
Ryan
089a819179 keyboard.json schema: set minimum value for key_unit (#23937)
* keyboard.json schema: set minimum value for `key_unit`

* Fix invalid `matrix_size` in keyboard.json

* Fix bad layout for silverbullet44
2024-06-16 21:57:37 +01:00
QMK Bot
fca1417f6b Merge remote-tracking branch 'origin/master' into develop 2024-06-16 18:16:33 +00:00
Danny
751fbd75d3 Add Chiri CE (#23926)
* Add Chiri CE

* Add more layers for dynamic keymap

* Move EEPROM clear

* Convert to keymap.json

* Change bootmagic matrix position
2024-06-16 12:16:05 -06:00
QMK Bot
1317a0732b Merge remote-tracking branch 'origin/master' into develop 2024-06-16 12:53:18 +00:00
Ryan
3c868b9316 ergodox_ez/base: Add missing features object (#23935) 2024-06-16 22:52:47 +10:00
QMK Bot
3ddd20cf51 Merge remote-tracking branch 'origin/master' into develop 2024-06-16 09:53:32 +00:00
Nick Brassel
7ac1a34a34 [CLI] Older python compat. (#23933) 2024-06-16 19:53:03 +10:00
QMK Bot
c43667fa74 Merge remote-tracking branch 'origin/master' into develop 2024-06-16 04:46:54 +00:00
David Hoelscher
ad82c4703a [Keyboard] ErgoStrafer RGB (#22936)
* adding ergostrafer rgb

* removing comment
2024-06-15 21:46:22 -07:00
QMK Bot
faa84a7c90 Merge remote-tracking branch 'origin/master' into develop 2024-06-15 09:38:16 +00:00
Nick Brassel
0262161914 [CLI] Don't exit() when certain exceptions occur. (#23442) 2024-06-15 10:37:47 +01:00
QMK Bot
e31418ee11 Merge remote-tracking branch 'origin/master' into develop 2024-06-14 21:58:43 +00:00
Ryan
d4654ab893 Various keyboard fixes (#23919) 2024-06-14 22:58:13 +01:00
QMK Bot
0c8a968e3d Merge remote-tracking branch 'origin/master' into develop 2024-06-14 20:26:31 +00:00
ai03
aec7569a04 [Keyboard] Add Altair (#23878)
Co-authored-by: jack <0x6a73@protonmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-06-14 13:26:21 -07:00
ai03
0594121b68 [Keyboard] Add Altair-X (#23879)
Co-authored-by: jack <0x6a73@protonmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
2024-06-14 13:26:00 -07:00
QMK Bot
a2f2de7d2c Merge remote-tracking branch 'origin/master' into develop 2024-06-14 07:34:37 +00:00
Myriam
4e8b740dd7 fix keymap for kprepublic bm60hsrgb_iso (#23733)
Co-authored-by: Duncan Sutherland <dunk2k_2000@hotmail.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-06-14 00:34:06 -07:00
QMK Bot
4f8aab748b Merge remote-tracking branch 'origin/master' into develop 2024-06-14 04:10:54 +00:00
adophoxia
c92becc57e [Keyboard] Enable dip switch for Keychron Q4 (#23889) 2024-06-13 21:10:23 -07:00
QMK Bot
e1839238a4 Merge remote-tracking branch 'origin/master' into develop 2024-06-13 23:24:28 +00:00
Joel Challis
cd565a95a0 Remove suggestion of creating issues for unsupported keyboards. (#23918) 2024-06-14 00:23:57 +01:00
QMK Bot
a98aa70f80 Merge remote-tracking branch 'origin/master' into develop 2024-06-13 22:36:55 +00:00
Danny
caf13bb9db Fix order of RGB LEDs to correct one for Iris CE (#23914) 2024-06-13 15:36:26 -07:00
QMK Bot
248a09d545 Merge remote-tracking branch 'origin/master' into develop 2024-06-13 13:01:12 +00:00
Danny
4a4eda4c3c Add missing encode enable for BAMFK-1 (#23821)
Add missing encode enable
2024-06-13 09:00:42 -04:00
Ryan
55538b2e1e APA102: API rework (#23355) 2024-06-13 22:19:45 +10:00
Ryan
c4a74be7f0 Add process_keycode handlers for new RGB Matrix and Underglow keycodes (#23896) 2024-06-13 21:59:46 +10:00
QMK Bot
dafbb92f4e Merge remote-tracking branch 'origin/master' into develop 2024-06-13 03:31:33 +00:00
Ryan
942c2a8d5a Fix nonunique anchors (#23910) 2024-06-13 13:31:03 +10:00
QMK Bot
8fe777adff Merge remote-tracking branch 'origin/master' into develop 2024-06-13 02:56:17 +00:00
Ryan
be9dfe65dd Add API reference section for LED/RGB Matrix docs (#23902) 2024-06-13 12:55:47 +10:00
QMK Bot
49317f058a Merge remote-tracking branch 'origin/master' into develop 2024-06-13 02:02:13 +00:00
Joel Challis
fa40356250 Ensure documentation pull requests build (#23908) 2024-06-13 02:59:37 +01:00
QMK Bot
b3d3a7c46f Merge remote-tracking branch 'origin/master' into develop 2024-06-13 01:56:23 +00:00
Nick Brassel
7247039742 Fixup docs. (#23906) 2024-06-13 02:55:52 +01:00
QMK Bot
9fbf4579a4 Merge remote-tracking branch 'origin/master' into develop 2024-06-12 23:48:54 +00:00
Nick Brassel
e69d30a9e9 VIA keymap deprecation notice. (#23905) 2024-06-13 09:48:24 +10:00
QMK Bot
52b4058ca4 Merge remote-tracking branch 'origin/master' into develop 2024-06-12 07:44:58 +00:00
Nick Brassel
bdd10ef8e7 Remove VIA_ENABLE from default keymaps. (#23903) 2024-06-12 17:43:09 +10:00
QMK Bot
c785584fa5 Merge remote-tracking branch 'origin/master' into develop 2024-06-12 07:12:20 +00:00
4pplet
031ca3b40b [Keyboard] Fix settings for 4pplet/waffling60 (#23862) 2024-06-12 00:11:50 -07:00
Joel Challis
b826877c40 Decouple VIA from STM32 L0/L1 EEPROM implementation (#23901) 2024-06-12 13:00:23 +10:00
QMK Bot
e239d0383a Merge remote-tracking branch 'origin/master' into develop 2024-06-12 00:50:57 +00:00
Ryan
8041a88f5d Slight clarification of LED/RGB Matrix custom effect docs (#23897) 2024-06-12 01:50:25 +01:00
Ryan
354a2e40cf splitkb/kyria: remove CONVERT_TO at keyboard level (#23857) 2024-06-11 13:25:51 +10:00
QMK Bot
e381f91c6e Merge remote-tracking branch 'origin/master' into develop 2024-06-10 00:24:00 +00:00
Joel Challis
8b5cdfabf5 Re-implement eeprom_write_qword as define (#23890) 2024-06-10 01:23:25 +01:00
QMK Bot
d4f8b478aa Merge remote-tracking branch 'origin/master' into develop 2024-06-09 20:15:38 +00:00
Ryan
df4538d894 Fix Iris/Irispad keymaps (#23856) 2024-06-09 13:14:48 -07:00
QMK Bot
c6ecb9ce41 Merge remote-tracking branch 'origin/master' into develop 2024-06-09 19:48:19 +00:00
Alabahuy
e484a3a179 [Keyboard] add jaykeeb jk60 (#23876) 2024-06-09 12:47:48 -07:00
QMK Bot
186dab5619 Merge remote-tracking branch 'origin/master' into develop 2024-06-09 17:58:16 +00:00
Alex Mayer
9dc183afe4 Fix Tri-Layer Keycode Descriptions (#23888) 2024-06-09 10:57:45 -07:00
フィルターペーパー
4926f0de8b [Keyboard] Fixup mt/mt84 (#23883) 2024-06-09 10:57:08 -07:00
Drashna Jaelre
333f8bf0d7 Add STM32F405RG ld script for tinyuf2 (#23885) 2024-06-09 11:08:53 +10:00
QMK Bot
3de5e44f52 Merge remote-tracking branch 'origin/master' into develop 2024-06-07 13:26:23 +00:00
Joel Challis
e7a08ef1a9 Fix broken link in PR checklist (#23877) 2024-06-07 23:25:20 +10:00
QMK Bot
d12f090d1e Merge remote-tracking branch 'origin/master' into develop 2024-06-07 01:17:50 +00:00
Syenasweta a.k.a. Nashrullah Ali Fauzi
950d765370 Add SyenaKeyboards Elaruus (#23870)
* add syenakeyboard elaruus

* add syenakeyboards elaruus

* add syenakeyboards elaruus

* add syenakeyboards elaruus

* add syenakeyboards/elaruus

* add syenakeyboards elaruus

* add syenakeyboards elaruus

* add syenakeyboards elaruus

* Update keyboards/syenakeyboards/elaruus/keyboard.json

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

* Update keyboards/syenakeyboards/elaruus/keymaps/default/keymap.c

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

* Update keyboards/syenakeyboards/elaruus/keymaps/via/keymap.c

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

---------

Co-authored-by: Syenasweta <syenasweta@gmail.com>
Co-authored-by: jack <0x6a73@protonmail.com>
2024-06-06 19:17:21 -06:00
QMK Bot
c561750f73 Merge remote-tracking branch 'origin/master' into develop 2024-06-06 02:10:14 +00:00
Kim Viberti
260e9a546e Fix documentation error (#23872)
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-06-06 12:09:44 +10:00
QMK Bot
0d360b64fa Merge remote-tracking branch 'origin/master' into develop 2024-06-05 02:21:27 +00:00
Nick Brassel
a4da5f219f Fixup build failures. (#23869) 2024-06-05 12:20:57 +10:00
Fernando Birra
a82b0628b3 GC9xxx LCD family drivers (GC9107 and GC9A01) (#23091)
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: jack <0x6A73@pm.me>
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: フィルターペーパー <76888457+filterpaper@users.noreply.github.com>
Co-authored-by: rookiebwoy <81021475+rookiebwoy@users.noreply.github.com>
Fixup boardsource/equals (#23106)
Fix make clean test:os_detection (#23112)
Fix make clean test:os_detection (#23112)"
Fixup boardsource/equals (#23106)"
2024-06-05 08:41:26 +10:00
dexter93
75d11e0421 [wear_leveling] efl updates (#22489)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-06-04 20:16:45 +10:00
QMK Bot
1a343cfaf4 Merge remote-tracking branch 'origin/master' into develop 2024-06-04 02:24:35 +00:00
Nick Brassel
6d365dd8f1 Add helper make targets for formatting and pytest. (#23858) 2024-06-04 12:23:25 +10:00
QMK Bot
c1c7c4f6e0 Merge remote-tracking branch 'origin/master' into develop 2024-06-03 12:36:18 +00:00
Stefan Kerkmann
8253697a63 [FIX] ChibiOS: USB Digitizer and Joystick IN endpoint compilation (#23854)
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-06-03 22:35:46 +10:00
QMK Bot
1c536513b3 Merge remote-tracking branch 'origin/master' into develop 2024-06-02 22:55:36 +00:00
Nick Brassel
282253a7e0 [docs] Add ability to redirect based on input path. (#23851) 2024-06-03 08:55:03 +10:00
QMK Bot
a1b2e0261d Merge remote-tracking branch 'origin/master' into develop 2024-06-02 03:19:50 +00:00
Alex Mayer
41dbb4c86c Fix Vitamins Included Keymap Formatting (#23803) 2024-06-01 20:19:23 -07:00
QMK Bot
c67789b717 Merge remote-tracking branch 'origin/master' into develop 2024-06-02 02:42:52 +00:00
Ryan
78a0adfbb4 [docs] Organize driver & feature docs into subfolders (#23848)
Co-authored-by: Nick Brassel <nick@tzarc.org>
2024-06-02 12:42:24 +10:00
QMK Bot
6c87500231 Merge remote-tracking branch 'origin/master' into develop 2024-06-01 00:38:08 +00:00
Ryan
fa6d23235b [docs] Remove gitbook directory (#23839) 2024-06-01 10:37:40 +10:00
QMK Bot
93f566280e Merge remote-tracking branch 'origin/master' into develop 2024-05-31 00:35:30 +00:00
Joel Challis
119e54e9e3 Docs theme updates (#23832) 2024-05-31 10:34:30 +10:00
QMK Bot
c60554e090 Merge remote-tracking branch 'origin/master' into develop 2024-05-30 09:27:11 +00:00
Ryan
32af90ae84 [docs] Fix old anchor IDs (#23831) 2024-05-30 19:26:32 +10:00
QMK Bot
64098fafa6 Merge remote-tracking branch 'origin/master' into develop 2024-05-30 09:10:50 +00:00
Joel Challis
8a394503c7 [docs] Update "Get Started" blocks (#23830)
Update "Get Started" blocks
2024-05-30 19:10:00 +10:00
QMK Bot
6ca94ae158 Merge remote-tracking branch 'origin/master' into develop 2024-05-30 09:00:58 +00:00
QMK Bot
47356b2201 Merge remote-tracking branch 'origin/master' into develop 2024-05-30 02:01:09 +00:00
QMK Bot
b36c7b99ae Merge remote-tracking branch 'origin/master' into develop 2024-05-30 00:44:13 +00:00
burkfers
4d32073681 BastardKB: remove legacy board tbk (#23818)
remove legacy board `tbk`
2024-05-28 22:53:48 -06:00
QMK Bot
9be50fdce5 Merge remote-tracking branch 'origin/master' into develop 2024-05-29 01:55:15 +00:00
Purdea Andrei
267dffda15 EEPROM: Don't erase if we don't have to. Adding eeprom_driver_format abstraction. (#18332) 2024-05-28 12:49:55 +01:00
Nick Brassel
6921c8a7dd Branch point for 2024q3 Breaking Change. 2024-05-28 14:42:21 +10:00
7924 changed files with 53140 additions and 181116 deletions

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: QMK Discord
url: https://discord.gg/Uq7gcHh
url: https://discord.gg/qmk
about: Ask questions, discuss issues and features. Chill.
- name: OLKB Subreddit
url: https://www.reddit.com/r/olkb

View File

@@ -1,6 +1,5 @@
<!--- 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. -->
## Description
@@ -15,7 +14,7 @@
- [ ] New feature
- [ ] Enhancement/optimization
- [ ] Keyboard (addition or update)
- [ ] Keymap/layout/userspace (addition or update)
- [ ] Keymap/layout (addition or update)
- [ ] Documentation
## Issues Fixed or Closed by This PR

82
.github/labeler.yml vendored
View File

@@ -1,46 +1,56 @@
core:
- quantum/**/*
- tmk_core/**/*
- drivers/**/*
- tests/**/*
- util/**/*
- platforms/**/*
- builddefs/**/*
- Makefile
- '*.mk'
- changed-files:
- any-glob-to-any-file:
- quantum/**
- tmk_core/**
- drivers/**
- tests/**
- util/**
- platforms/**
- builddefs/*.mk
- Makefile
- '*.mk'
dependencies:
- any:
- 'lib/**/*'
- '!lib/python/**/*'
- changed-files:
- all-globs-to-any-file:
- lib/**
- '!lib/python/**'
keyboard:
- any:
- 'keyboards/**/*'
- '!keyboards/**/keymaps/**/*'
- changed-files:
- all-globs-to-any-file:
- keyboards/**
- '!keyboards/**/keymaps/**'
keymap:
- users/**/*
- layouts/**/*
- keyboards/**/keymaps/**/*
- changed-files:
- any-glob-to-any-file:
- users/**
- layouts/**
- keyboards/**/keymaps/**
via:
- keyboards/**/keymaps/via/*
- changed-files:
- any-glob-to-any-file:
- keyboards/**/keymaps/via/*
cli:
- requirements.txt
- lib/python/**/*
- changed-files:
- any-glob-to-any-file:
- requirements.txt
- lib/python/**
python:
- '**/*.py'
- changed-files:
- any-glob-to-any-file:
- '**/*.py'
documentation:
- docs/**/*
translation:
- docs/fr-fr/**/*
- docs/es/**/*
- docs/ja/**/*
- docs/he-il/**/*
- docs/pt-br/**/*
- docs/zh-cn/**/*
- docs/de/**/*
- docs/ru-ru/**/*
- changed-files:
- any-glob-to-any-file:
- docs/**
- builddefs/docsgen/**
CI:
- .github/**/*
- changed-files:
- any-glob-to-any-file:
- .github/**
dd:
- data/constants/**/*
- data/mappings/**/*
- data/schemas/**/*
- changed-files:
- any-glob-to-any-file:
- data/constants/**
- data/mappings/**
- data/schemas/**

View File

@@ -13,8 +13,8 @@ jobs:
if: github.repository == 'qmk/qmk_firmware'
steps:
- uses: mheap/automatic-approve-action@v1
- uses: zvecr/automatic-approve-action@safe_files
with:
token: ${{ secrets.QMK_BOT_TOKEN }}
workflows: "format.yml,lint.yml,unit_test.yml"
dangerous_files: "lib/python/,Makefile,paths.mk,builddefs/"
workflows: "labeler.yml,lint.yml,docs.yml"
safe_files: "keyboards/,docs/"

View File

@@ -52,9 +52,9 @@ jobs:
run: |
target_count=$( {
qmk find -km default 2>/dev/null
qmk find -km via 2>/dev/null
# qmk find -km xap 2>/dev/null
} | sort | uniq | wc -l)
slice_length=$((target_count / ($CONCURRENT_JOBS - 1))) # Err on the side of caution as we're splitting default and via
slice_length=$((target_count / ($CONCURRENT_JOBS - 1))) # Err on the side of caution
echo "slice_length=$slice_length" >> $GITHUB_OUTPUT
build_targets:
@@ -63,7 +63,8 @@ jobs:
strategy:
fail-fast: false
matrix:
keymap: [default, via]
keymap: [default]
# keymap: [default, xap]
uses: ./.github/workflows/ci_build_major_branch_keymap.yml
with:
branch: ${{ inputs.branch || github.ref_name }}
@@ -77,44 +78,59 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Disable safe.directory check
run: |
git config --global --add safe.directory '*'
- name: Checkout QMK Firmware
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download firmwares
uses: actions/download-artifact@v4
with:
pattern: firmware-*
path: firmwares
path: .
merge-multiple: true
- name: Generate index page
run: |
python3 -m pip install -r ./util/ci/requirements.txt
./util/ci/index_generator.py > index.html
./util/ci/firmware_list_generator.py > firmware_list.json
- name: Upload to https://ci.qmk.fm/${{ inputs.branch || github.ref_name }}/${{ github.sha }}
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete
args: --acl public-read --follow-symlinks --delete --exclude '*' --include 'index.html' --include 'firmware_list.json' --include '*.hex' --include '*.bin' --include '*.uf2'
env:
AWS_S3_BUCKET: ${{ vars.CI_QMK_FM_SPACES_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.CI_QMK_FM_SPACES_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_QMK_FM_SPACES_SECRET }}
AWS_REGION: ${{ vars.CI_QMK_FM_SPACES_REGION }}
AWS_S3_ENDPOINT: ${{ vars.CI_QMK_FM_SPACES_ENDPOINT }}
SOURCE_DIR: firmwares
SOURCE_DIR: .
DEST_DIR: ${{ inputs.branch || github.ref_name }}/${{ github.sha }}
- name: Upload to https://ci.qmk.fm/${{ inputs.branch || github.ref_name }}/latest
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks --delete
args: --acl public-read --follow-symlinks --delete --exclude '*' --include 'index.html' --include 'firmware_list.json' --include '*.hex' --include '*.bin' --include '*.uf2'
env:
AWS_S3_BUCKET: ${{ vars.CI_QMK_FM_SPACES_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.CI_QMK_FM_SPACES_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_QMK_FM_SPACES_SECRET }}
AWS_REGION: ${{ vars.CI_QMK_FM_SPACES_REGION }}
AWS_S3_ENDPOINT: ${{ vars.CI_QMK_FM_SPACES_ENDPOINT }}
SOURCE_DIR: firmwares
SOURCE_DIR: .
DEST_DIR: ${{ inputs.branch || github.ref_name }}/latest
- name: Check if failure marker file exists
id: check_failure_marker
uses: andstor/file-existence-action@v3
with:
files: firmwares/.failed
files: ./.failed
- name: Fail build if needed
if: steps.check_failure_marker.outputs.files_exists == 'true'

View File

@@ -172,10 +172,10 @@ jobs:
targets-${{ inputs.keymap }}
- name: 'CI Discord Notification'
if: always()
if: always() && !cancelled()
working-directory: util/ci/
env:
DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
run: |
python3 -m pip install -r requirements.txt
python3 ./discord-results.py --branch ${{ inputs.branch || github.ref_name }} --keymap ${{ inputs.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
python3 ./discord-results.py --branch ${{ inputs.branch || github.ref_name }} --sha $(git rev-parse HEAD) --keymap ${{ inputs.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

View File

@@ -7,7 +7,6 @@ on:
push:
branches:
- master
- vitepress
paths:
- 'builddefs/docsgen/**'
- 'tmk_core/**'
@@ -15,6 +14,11 @@ on:
- 'platforms/**'
- 'docs/**'
- '.github/workflows/docs.yml'
pull_request:
paths:
- 'builddefs/docsgen/**'
- 'docs/**'
- '.github/workflows/docs.yml'
defaults:
run:
@@ -25,9 +29,6 @@ jobs:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_cli
# protect against those who develop with their fork on master
if: github.repository == 'qmk/qmk_firmware' || (github.repository == 'tzarc/qmk_firmware' && github.ref == 'refs/heads/vitepress')
steps:
- uses: actions/checkout@v4
with:
@@ -35,10 +36,10 @@ jobs:
- name: Install dependencies
run: |
apt-get update && apt-get install -y rsync doxygen curl
apt-get update && apt-get install -y rsync doxygen
# install nvm
touch $HOME/.bashrc
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
- name: Install node
run: |
@@ -46,40 +47,19 @@ jobs:
nvm install 20
nvm use 20
corepack enable
npm install -g moxygen
- name: Build docs
run: |
source $HOME/.bashrc
nvm use 20
qmk --verbose generate-docs
touch '.build/docs/.nojekyll'
- name: Set CNAME
if: github.repository == 'qmk/qmk_firmware'
run: |
# Override target CNAME
echo 'docs.qmk.fm' > .build/docs/CNAME
- name: Override CNAME
if: github.repository == 'tzarc/qmk_firmware'
run: |
# Temporarily override target CNAME during development
echo 'vitepress.qmk.fm' > .build/docs/CNAME
- name: Deploy
if: github.repository == 'qmk/qmk_firmware'
uses: JamesIves/github-pages-deploy-action@v4.6.1
if: ${{ github.event_name == 'push' && github.repository == 'qmk/qmk_firmware' }}
uses: JamesIves/github-pages-deploy-action@v4.6.4
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
folder: .build/docs
git-config-name: QMK Bot
git-config-email: hello@qmk.fm
- name: Deploy
if: github.repository == 'tzarc/qmk_firmware'
uses: JamesIves/github-pages-deploy-action@v4.6.1
with:
branch: gh-pages
folder: .build/docs

View File

@@ -35,7 +35,7 @@ jobs:
- name: Get changed files
id: file_changes
uses: tj-actions/changed-files@v44
uses: tj-actions/changed-files@v45
with:
use_rest_api: true

View File

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

View File

@@ -1,18 +1,13 @@
name: "Pull Request Labeler"
permissions:
contents: read
pull-requests: write
on:
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review, locked]
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
configuration-path: '.github/labeler.yml'
- uses: actions/labeler@v5

View File

@@ -27,7 +27,7 @@ jobs:
- name: Get changed files
id: file_changes
uses: tj-actions/changed-files@v44
uses: tj-actions/changed-files@v45
with:
use_rest_api: true

View File

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

3
.gitignore vendored
View File

@@ -25,6 +25,8 @@
*.la
*.stackdump
*.sym
index.html
firmware_list.json
# QMK-specific
api_data/v1
@@ -116,4 +118,5 @@ compile_commands.json
# VIA(L) files that don't belong in QMK repo
via*.json
/keyboards/**/keymaps/via/*
/keyboards/**/keymaps/vial/*

View File

@@ -465,3 +465,18 @@ distclean_userspace: clean
rm -f $(QMK_USERSPACE)/*.bin $(QMK_USERSPACE)/*.hex $(QMK_USERSPACE)/*.uf2
echo 'done.'
endif
# Extra targets for formatting and/or pytest, running within the qmk/qmk_cli container to match GHA.
CONTAINER_PREAMBLE := export HOME="/tmp"; export PATH="/tmp/.local/bin:\$$PATH"; python3 -m pip install --upgrade pip; python3 -m pip install -r requirements-dev.txt
.PHONY: format-core
format-core:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a"
.PHONY: pytest
pytest:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk pytest"
.PHONY: format-and-pytest
format-and-pytest:
RUNTIME=docker ./util/docker_cmd.sh bash -lic "$(CONTAINER_PREAMBLE); qmk format-c --core-only -a && qmk format-python -a && qmk pytest"

View File

@@ -34,10 +34,13 @@ ifeq ($(strip $(DUMP_CI_METADATA)),yes)
endif
# Force expansion
TARGET := $(TARGET)
override TARGET := $(TARGET)
ifneq ($(FORCE_LAYOUT),)
TARGET := $(TARGET)_$(FORCE_LAYOUT)
override TARGET := $(TARGET)_$(FORCE_LAYOUT)
endif
ifneq ($(CONVERT_TO),)
override TARGET := $(TARGET)_$(CONVERT_TO)
endif
# Object files and generated keymap directory
@@ -58,9 +61,6 @@ ifdef SKIP_GIT
VERSION_H_FLAGS += --skip-git
endif
# Generate the board's version.h file.
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
# Determine which subfolders exist.
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
@@ -212,12 +212,20 @@ $(INTERMEDIATE_OUTPUT)/src/config.h: $(KEYMAP_JSON)
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --output $(KEYMAP_H) $(KEYMAP_JSON))
@$(BUILD_CMD)
generated-files: $(INTERMEDIATE_OUTPUT)/src/config.h $(INTERMEDIATE_OUTPUT)/src/keymap.c
$(INTERMEDIATE_OUTPUT)/src/keymap.h: $(KEYMAP_JSON)
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
$(eval CMD=$(QMK_BIN) generate-keymap-h --quiet --output $(INTERMEDIATE_OUTPUT)/src/keymap.h $(KEYMAP_JSON))
@$(BUILD_CMD)
generated-files: $(INTERMEDIATE_OUTPUT)/src/config.h $(INTERMEDIATE_OUTPUT)/src/keymap.c $(INTERMEDIATE_OUTPUT)/src/keymap.h
endif
include $(BUILDDEFS_PATH)/converters.mk
# Generate the board's version.h file.
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(INTERMEDIATE_OUTPUT)/src/version.h)
MCU_ORIG := $(MCU)
include $(wildcard $(PLATFORM_PATH)/*/mcu_selection.mk)

View File

@@ -47,7 +47,8 @@ PLATFORM:=TEST
PLATFORM_KEY:=test
BOOTLOADER_TYPE:=none
ifeq ($(strip $(DEBUG)), 1)
DEBUG ?= 0
ifneq ($(strip $(DEBUG)), 0)
CONSOLE_ENABLE = yes
endif

View File

@@ -282,18 +282,17 @@ ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none)
endif
endif
VALID_FLASH_DRIVER_TYPES := spi
VALID_FLASH_DRIVER_TYPES := spi custom
FLASH_DRIVER ?= none
ifneq ($(strip $(FLASH_DRIVER)), none)
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
$(call CATASTROPHIC_ERROR,Invalid FLASH_DRIVER,FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid flash driver)
else
OPT_DEFS += -DFLASH_ENABLE
OPT_DEFS += -DFLASH_ENABLE -DFLASH_DRIVER -DFLASH_DRIVER_$(strip $(shell echo $(FLASH_DRIVER) | tr '[:lower:]' '[:upper:]'))
COMMON_VPATH += $(DRIVER_PATH)/flash
ifeq ($(strip $(FLASH_DRIVER)),spi)
SPI_DRIVER_REQUIRED = yes
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
COMMON_VPATH += $(DRIVER_PATH)/flash
SRC += flash_spi.c
SPI_DRIVER_REQUIRED = yes
endif
endif
endif

View File

@@ -32,9 +32,6 @@ ifneq ($(CONVERT_TO),)
PLATFORM_KEY = $(shell echo $(CONVERTER) | cut -d "/" -f2)
# force setting as value can be from environment
override TARGET := $(TARGET)_$(CONVERT_TO)
# Configure any defaults
OPT_DEFS += -DCONVERT_TO_$(shell echo $(CONVERT_TO) | tr '[:lower:]' '[:upper:]')
OPT_DEFS += -DCONVERTER_TARGET=\"$(CONVERT_TO)\"

View File

@@ -33,7 +33,7 @@ export default defineConfig(({ mode }) => {
},
title: 'QMK Firmware',
nav: [{ text: "Home", link: "./" }],
nav: [{ text: "Home", link: "/" }],
search: {
provider: "local",

View File

@@ -2,11 +2,22 @@
import DefaultTheme from 'vitepress/theme'
import { useRouter } from 'vitepress'
import { onBeforeMount } from 'vue';
import aliases from "../../../../docs/_aliases.json";
const router = useRouter()
onBeforeMount(async () => {
if (window.location.href.includes('/#/')) {
const newUrl = window.location.href.replace(/\/#\//, '/').replace(/\?id=/, '#');
// Convert from docsify-style to vitepress-style URLs
let newUrl = window.location.href.replace(/\/#\//, '/').replace(/\?id=/, '#');
// Convert any aliases
let testUrl = new URL(newUrl);
while (testUrl.pathname in aliases) {
testUrl.pathname = aliases[testUrl.pathname];
}
newUrl = testUrl.toString();
// Redirect if required
if (newUrl != window.location.href) {
window.history.replaceState({}, '', newUrl);
await router.go(newUrl);
}

View File

@@ -1,7 +1,19 @@
/* Override <kbd> as vitepress doesn't put them with borders */
kbd {
border: 1px solid var(--vp-c-text-1);
border-radius: 0.6em;
border-radius: 5px;
margin: 0.2em;
padding: 0.2em;
}
:root {
--vp-nav-logo-height: 32px;
--vp-layout-max-width: calc(98% + 64px);
--vp-sidebar-width: 300px;
}
.VPDoc.has-aside .content-container {
max-width: unset !important;
}

View File

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

View File

@@ -743,10 +743,10 @@ tabbable@^6.2.0:
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
vite@^5.2.10, vite@^5.2.9:
version "5.2.10"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7"
integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==
vite@^5.2.14, vite@^5.2.9:
version "5.2.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.14.tgz#fd5f60facf6b5f90ec7da6323c467a365d380c3d"
integrity sha512-TFQLuwWLPms+NBNlh0D9LZQ+HXW471COABxw/9TEUBrjuHMo9BrYBPrN/SYAwIuVL+rLerycxiLT41t4f5MZpA==
dependencies:
esbuild "^0.20.1"
postcss "^8.4.38"

View File

@@ -0,0 +1,616 @@
{
"aliases": {
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ │ ۱ │ ۲ │ ۳ │ ۴ │ ۵ │ ۶ │ ۷ │ ۸ │ ۹ │ ۰ │ - │ = │ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │ │ ض │ ص │ ث │ ق │ ف │ غ │ ع │ ه │ خ │ ح │ ج │ چ │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
* │ │ ش │ س │ ی │ ب │ ل │ ا │ ت │ ن │ م │ ک │ گ │ \ │ │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │ │ < │ ظ │ ط │ ز │ ر │ ذ │ د │ پ │ و │ . │ / │ │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │ │ │ │ │ │ │ │ │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
"KC_GRV": {
"key": "FA_ZWJ",
"label": "(zero-width joiner)",
}
"KC_1": {
"key": "FA_1A",
"label": "۱",
}
"KC_2": {
"key": "FA_2A",
"label": "۲",
}
"KC_3": {
"key": "FA_3A",
"label": "۳",
}
"KC_4": {
"key": "FA_4A",
"label": "۴",
}
"KC_5": {
"key": "FA_5A",
"label": "۵",
}
"KC_6": {
"key": "FA_6A",
"label": "۶",
}
"KC_7": {
"key": "FA_7A",
"label": "۷",
}
"KC_8": {
"key": "FA_8A",
"label": "۸",
}
"KC_9": {
"key": "FA_9A",
"label": "۹",
}
"KC_0": {
"key": "FA_0A",
"label": "۰",
}
"KC_MINS": {
"key": "FA_MINS",
"label": "-",
}
"KC_EQL": {
"key": "FA_EQL",
"label": "=",
}
"KC_Q": {
"key": "FA_ZAD",
"label": "ض",
}
"KC_W": {
"key": "FA_SAD",
"label": "ص",
}
"KC_E": {
"key": "FA_SE",
"label": "ث",
}
"KC_R": {
"key": "FA_QAF",
"label": "ق",
}
"KC_T": {
"key": "FA_FE",
"label": "ف",
}
"KC_Y": {
"key": "FA_GHYN",
"label": "غ",
}
"KC_U": {
"key": "FA_EYN",
"label": "ع",
}
"KC_I": {
"key": "FA_HE",
"label": "ه",
}
"KC_O": {
"key": "FA_KHE",
"label": "خ",
}
"KC_P": {
"key": "FA_HEJ",
"label": "ح",
}
"KC_LBRC": {
"key": "FA_JIM",
"label": "ج",
}
"KC_RBRC": {
"key": "FA_CHE",
"label": "چ",
}
"KC_A": {
"key": "FA_SHIN",
"label": "ش",
}
"KC_S": {
"key": "FA_SIN",
"label": "س",
}
"KC_D": {
"key": "FA_YE",
"label": "ی",
}
"KC_F": {
"key": "FA_BE",
"label": "ب",
}
"KC_G": {
"key": "FA_LAM",
"label": "ل",
}
"KC_H": {
"key": "FA_ALEF",
"label": "ا",
}
"KC_J": {
"key": "FA_TE",
"label": "ت",
}
"KC_K": {
"key": "FA_NOON",
"label": "ن",
}
"KC_L": {
"key": "FA_MIM",
"label": "م",
}
"KC_SCLN": {
"key": "FA_KAF",
"label": "ک",
}
"KC_QUOT": {
"key": "FA_GAF",
"label": "گ",
}
"KC_BSLS": {
"key": "FA_BSLS",
"label": "\\",
}
"KC_LT": {
"key": "FA_LT",
"label": "<",
}
"KC_Z": {
"key": "FA_ZA",
"label": "ظ",
}
"KC_X": {
"key": "FA_TA",
"label": "ط",
}
"KC_C": {
"key": "FA_ZE",
"label": "ز",
}
"KC_V": {
"key": "FA_RE",
"label": "ر",
}
"KC_B": {
"key": "FA_ZAL",
"label": "ذ",
}
"KC_N": {
"key": "FA_DAL",
"label": "د",
}
"KC_M": {
"key": "FA_PE",
"label": "پ",
}
"KC_COMM": {
"key": "FA_WAW",
"label": "و",
}
"KC_DOT": {
"key": "FA_DOT",
"label": ".",
}
"KC_SLSH": {
"key": "FA_SLSH",
"label": "/",
}
"KC_SPC": {
"key": "FA_SPC",
"label": " ",
}
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ÷ │ ! │ ٬ │ ٫ │ ﷼ │ ٪ │ × │ ، │ * │ ) │ ( │ ـ │ + │ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │ │ ْ │ ٌ │ ٍ │ ً │ ُ │ ِ │ َ │ ّ │ ] │ [ │ } │ { │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
* │ │ ؤ │ ئ │ ي │ إ │ أ │ آ │ ة │ » │ « │ : │ ؛ │ | │ │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │ │ > │ ك │ ٓ │ ژ │ ٰ │ │ ٔ │ ء │ │ │ ؟ │ │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │ │ │ │ │ │ │ │ │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
"S(FA_ZWJ)": {
"key": "FA_DIV",
"label": "÷",
}
"S(FA_1A)": {
"key": "FA_EXLM",
"label": "!",
}
"S(FA_2A)": {
"key": "FA_THS",
"label": "٬",
}
"S(FA_3A)": {
"key": "FA_DECS",
"label": "٫",
}
"S(FA_4A)": {
"key": "FA_RIAL",
"label": "﷼",
}
"S(FA_5A)": {
"key": "FA_PRCA",
"label": "٪",
}
"S(FA_6A)": {
"key": "FA_MUL",
"label": "×",
}
"S(FA_7A)": {
"key": "FA_COMA",
"label": "،",
}
"S(FA_8A)": {
"key": "FA_ASTR",
"label": "*",
}
"S(FA_9A)": {
"key": "FA_RPRN",
"label": ")",
}
"S(FA_0A)": {
"key": "FA_LPRN",
"label": "(",
}
"S(FA_MINS)": {
"key": "FA_TATW",
"label": "ـ",
}
"S(FA_EQL)": {
"key": "FA_PLUS",
"label": "+",
}
"S(FA_ZAD)": {
"key": "FA_SUK",
"label": "ْ",
}
"S(FA_SAD)": {
"key": "FA_DMTN",
"label": "ٌ",
}
"S(FA_SE)": {
"key": "FA_KSTN",
"label": "ٍ",
}
"S(FA_QAF)": {
"key": "FA_FTHN",
"label": "ً",
}
"S(FA_FE)": {
"key": "FA_DMM",
"label": "ُ",
}
"S(FA_GHYN)": {
"key": "FA_KAS",
"label": "ِ",
}
"S(FA_EYN)": {
"key": "FA_FAT",
"label": "َ",
}
"S(FA_HE)": {
"key": "FA_TSDD",
"label": "",
}
"S(FA_KHE)": {
"key": "FA_RBRC",
"label": "]",
}
"S(FA_HEJ)": {
"key": "FA_LBRC",
"label": "[",
}
"S(FA_JIM)": {
"key": "FA_RCBR",
"label": "}",
}
"S(FA_CHE)": {
"key": "FA_LCBR",
"label": "{",
}
"S(FA_SHIN)": {
"key": "FA_HMZV",
"label": "ؤ",
}
"S(FA_SIN)": {
"key": "FA_HMZY",
"label": "ئ",
}
"S(FA_YE)": {
"key": "FA_YEA",
"label": "ي",
}
"S(FA_BE)": {
"key": "FA_HMZU",
"label": "إ",
}
"S(FA_LAM)": {
"key": "FA_HMZO",
"label": "أ",
}
"S(FA_ALEF)": {
"key": "FA_MALF",
"label": "آ",
}
"S(FA_TE)": {
"key": "FA_TEHM",
"label": "ة",
}
"S(FA_NOON)": {
"key": "FA_RQOT",
"label": "»",
}
"S(FA_MIM)": {
"key": "FA_LQOT",
"label": "«",
}
"S(FA_KAF)": {
"key": "FA_COLN",
"label": ":",
}
"S(FA_GAF)": {
"key": "FA_SCLA",
"label": "؛",
}
"S(FA_LT)": {
"key": "FA_GT",
"label": ">",
}
"S(FA_ZA)": {
"key": "FA_KAFA",
"label": "ك",
}
"S(FA_TA)": {
"key": "FA_MADO",
"label": "ٓ",
}
"S(FA_ZE)": {
"key": "FA_JEH",
"label": "ژ",
}
"S(FA_RE)": {
"key": "FA_SUPA",
"label": "ٰ",
}
"S(FA_ZAL)": {
"key": "FA_ZWNJ",
"label": "(zero-width non-joiner)",
}
"S(FA_DAL)": {
"key": "FA_HMZA",
"label": "ٔ",
}
"S(FA_PE)": {
"key": "FA_HMZ",
"label": "ء",
}
"S(FA_SLSH)": {
"key": "FA_QSA",
"label": "؟",
}
/* AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ~ │ ` │ @ │ # │ $ │ % │ ^ │ & │ • │ │ │ _ │ │ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │ │ ° │ │ € │ │ │ │ │ │ │ │ │ │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
* │ │ │ │ ى │ │ │ ٱ │ │ ﴿ │ ; │ " │ │ │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │ │ | │ │ │ │ ٖ │ │ ٕ │ … │ , │ ' │ ? │ │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │ │ │ │ │ │ │ │ │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
"ALGR(FA_ZWJ)": {
"key": "FA_TILD",
"label": "~",
}
"ALGR(FA_1A)": {
"key": "FA_GRV",
"label": "`",
}
"ALGR(FA_2A)": {
"key": "FA_AT",
"label": "@",
}
"ALGR(FA_3A)": {
"key": "FA_HASH",
"label": "#",
}
"ALGR(FA_4A)": {
"key": "FA_DLR",
"label": "$",
}
"ALGR(FA_5A)": {
"key": "FA_PERC",
"label": "%",
}
"ALGR(FA_6A)": {
"key": "FA_CIRC",
"label": "^",
}
"ALGR(FA_7A)": {
"key": "FA_AMPR",
"label": "&",
}
"ALGR(FA_8A)": {
"key": "FA_BULT",
"label": "•",
}
"ALGR(FA_9A)": {
"key": "FA_LRM",
"label": "(left-to-right mark)",
}
"ALGR(FA_0A)": {
"key": "FA_RLM",
"label": "(right-to-left mark)",
}
"ALGR(FA_MINS)": {
"key": "FA_UNDS",
"label": "_",
}
"ALGR(FA_EQL)": {
"key": "FA_DMNS",
"label": " (dead)",
}
"ALGR(FA_ZAD)": {
"key": "FA_DEG",
"label": "°",
}
"ALGR(FA_SE)": {
"key": "FA_EURO",
"label": "€",
}
"ALGR(FA_HE)": {
"key": "FA_LRO",
"label": "(left-to-right override)",
}
"ALGR(FA_KHE)": {
"key": "FA_RLO",
"label": "(right-to-left override)",
}
"ALGR(FA_HEJ)": {
"key": "FA_PDF",
"label": "(pop directional formatting)",
}
"ALGR(FA_JIM)": {
"key": "FA_LRE",
"label": "(left-to-right embedding)",
}
"ALGR(FA_CHE)": {
"key": "FA_RLE",
"label": "(right-to-left embedding)",
}
"ALGR(FA_YE)": {
"key": "FA_ALFM",
"label": "ى",
}
"ALGR(FA_ALEF)": {
"key": "FA_ALFW",
"label": "ٱ",
}
"ALGR(FA_NOON)": {
"key": "FA_LORP",
"label": "",
}
"ALGR(FA_MIM)": {
"key": "FA_RORP",
"label": "﴿",
}
"ALGR(FA_KAF)": {
"key": "FA_SCLN",
"label": ";",
}
"ALGR(FA_GAF)": {
"key": "FA_DQT",
"label": "\"",
}
"ALGR(FA_BSLS)": {
"key": "FA_MINA",
"label": "-",
}
"ALGR(FA_ZA)": {
"key": "FA_PIPE",
"label": "|",
}
"ALGR(FA_RA)": {
"key": "FA_SUBA",
"label": "ٖ",
}
"ALGR(FA_DAL)": {
"key": "FA_HMZB",
"label": "ء",
}
"ALGR(FA_PE)": {
"key": "FA_ELLP",
"label": "…",
}
"ALGR(FA_WAW)": {
"key": "FA_COMM",
"label": ",",
}
"ALGR(FA_DOT)": {
"key": "FA_QUOT",
"label": "'",
}
"ALGR(FA_SLSH)": {
"key": "FA_QUES",
"label": "?",
}
/* Shift+AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ │ │ │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │ │ ¦ │ │ │ │ │ │ │ │ │ │ │ │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │ │ │ │ │ │ │ │ │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
"S(ALGR(FA_1A))": {
"key": "FA_1",
"label": "1",
}
"S(ALGR(FA_2A))": {
"key": "FA_2",
"label": "2",
}
"S(ALGR(FA_3A))": {
"key": "FA_3",
"label": "3",
}
"S(ALGR(FA_4A))": {
"key": "FA_4",
"label": "4",
}
"S(ALGR(FA_5A))": {
"key": "FA_5",
"label": "5",
}
"S(ALGR(FA_6A))": {
"key": "FA_6",
"label": "6",
}
"S(ALGR(FA_7A))": {
"key": "FA_7",
"label": "7",
}
"S(ALGR(FA_8A))": {
"key": "FA_8",
"label": "8",
}
"S(ALGR(FA_9A))": {
"key": "FA_9",
"label": "9",
}
"S(ALGR(FA_0A))": {
"key": "FA_0",
"label": "0",
}
"S(ALGR(FA_LT))": {
"key": "FA_BRKP",
"label": "¦",
}
"S(ALGR(FA_SPC))": {
"key": "FA_NNBS",
"label": "(narrow non-breaking space)",
}
}
}

View File

@@ -0,0 +1,175 @@
{
"keycodes": {
"0x00CD": {
"group": "mouse",
"key": "QK_MOUSE_CURSOR_UP",
"label": "Mouse cursor up",
"aliases": [
"!reset!",
"MS_UP"
]
},
"0x00CE": {
"group": "mouse",
"key": "QK_MOUSE_CURSOR_DOWN",
"label": "Mouse cursor down",
"aliases": [
"!reset!",
"MS_DOWN"
]
},
"0x00CF": {
"group": "mouse",
"key": "QK_MOUSE_CURSOR_LEFT",
"label": "Mouse cursor left",
"aliases": [
"!reset!",
"MS_LEFT"
]
},
"0x00D0": {
"group": "mouse",
"key": "QK_MOUSE_CURSOR_RIGHT",
"label": "Mouse cursor right",
"aliases": [
"!reset!",
"MS_RGHT"
]
},
"0x00D1": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_1",
"label": "Mouse button 1",
"aliases": [
"!reset!",
"MS_BTN1"
]
},
"0x00D2": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_2",
"label": "Mouse button 2",
"aliases": [
"!reset!",
"MS_BTN2"
]
},
"0x00D3": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_3",
"label": "Mouse button 3",
"aliases": [
"!reset!",
"MS_BTN3"
]
},
"0x00D4": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_4",
"label": "Mouse button 4",
"aliases": [
"!reset!",
"MS_BTN4"
]
},
"0x00D5": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_5",
"label": "Mouse button 5",
"aliases": [
"!reset!",
"MS_BTN5"
]
},
"0x00D6": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_6",
"label": "Mouse button 6",
"aliases": [
"!reset!",
"MS_BTN6"
]
},
"0x00D7": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_7",
"label": "Mouse button 7",
"aliases": [
"!reset!",
"MS_BTN7"
]
},
"0x00D8": {
"group": "mouse",
"key": "QK_MOUSE_BUTTON_8",
"label": "Mouse button 8",
"aliases": [
"!reset!",
"MS_BTN8"
]
},
"0x00D9": {
"group": "mouse",
"key": "QK_MOUSE_WHEEL_UP",
"label": "Mouse wheel up",
"aliases": [
"!reset!",
"MS_WHLU"
]
},
"0x00DA": {
"group": "mouse",
"key": "QK_MOUSE_WHEEL_DOWN",
"label": "Mouse wheel down",
"aliases": [
"!reset!",
"MS_WHLD"
]
},
"0x00DB": {
"group": "mouse",
"key": "QK_MOUSE_WHEEL_LEFT",
"label": "Mouse wheel left",
"aliases": [
"!reset!",
"MS_WHLL"
]
},
"0x00DC": {
"group": "mouse",
"key": "QK_MOUSE_WHEEL_RIGHT",
"label": "Mouse wheel right",
"aliases": [
"!reset!",
"MS_WHLR"
]
},
"0x00DD": {
"group": "mouse",
"key": "QK_MOUSE_ACCELERATION_0",
"label": "Set mouse acceleration to 0",
"aliases": [
"!reset!",
"MS_ACL0"
]
},
"0x00DE": {
"group": "mouse",
"key": "QK_MOUSE_ACCELERATION_1",
"label": "Set mouse acceleration to 1",
"aliases": [
"!reset!",
"MS_ACL1"
]
},
"0x00DF": {
"group": "mouse",
"key": "QK_MOUSE_ACCELERATION_2",
"label": "Set mouse acceleration to 2",
"aliases": [
"!reset!",
"MS_ACL2"
]
}
}
}

View File

@@ -72,6 +72,11 @@
"LED_KANA_PIN": {"info_key": "indicators.kana"},
"LED_PIN_ON_STATE": {"info_key": "indicators.on_state", "value_type": "int"},
// Joystick
"JOYSTICK_AXIS_COUNT": {"info_key": "joystick.axis_count", "value_type": "int"},
"JOYSTICK_AXIS_RESOLUTION": {"info_key": "joystick.axis_resolution", "value_type": "int"},
"JOYSTICK_BUTTON_COUNT": {"info_key": "joystick.button_count", "value_type": "int"},
// Leader Key
"LEADER_PER_KEY_TIMING": {"info_key": "leader_key.timing", "value_type": "flag"},
"LEADER_KEY_STRICT_KEY_PROCESSING": {"info_key": "leader_key.strict_processing", "value_type": "flag"},
@@ -171,7 +176,7 @@
"SECURE_UNLOCK_TIMEOUT": {"info_key": "secure.unlock_timeout", "value_type": "int"},
// Split Keyboard
"SOFT_SERIAL_PIN": {"info_key": "split.soft_serial_pin"},
"SOFT_SERIAL_PIN": {"info_key": "split.serial.pin"},
"SOFT_SERIAL_SPEED": {"info_key": "split.soft_serial_speed"},
"SPLIT_HAND_MATRIX_GRID": {"info_key": "split.handedness.matrix_grid", "value_type": "array", "to_c": false},
"SPLIT_HAND_PIN": {"info_key": "split.handedness.pin"},

View File

@@ -25,6 +25,8 @@
"ENCODER_DRIVER": {"info_key": "encoder.driver"},
"FIRMWARE_FORMAT": {"info_key": "build.firmware_format"},
"HAPTIC_DRIVER": {"info_key": "haptic.driver"},
"JOYSTICK_DRIVER": {"info_key": "joystick.driver"},
"JOYSTICK_ENABLE": {"info_key": "joystick.enabled", "value_type": "bool"},
"KEYBOARD_SHARED_EP": {"info_key": "usb.shared_endpoint.keyboard", "value_type": "bool"},
"LAYOUTS": {"info_key": "community_layouts", "value_type": "list"},
"LED_MATRIX_DRIVER": {"info_key": "led_matrix.driver"},
@@ -41,6 +43,7 @@
"RGB_MATRIX_DRIVER": {"info_key": "rgb_matrix.driver"},
"RGBLIGHT_DRIVER": {"info_key": "rgblight.driver"},
"SECURE_ENABLE": {"info_key": "secure.enabled", "value_type": "bool"},
"SERIAL_DRIVER": {"info_key": "split.serial.driver"},
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
"STENO_ENABLE": {"info_key": "stenography.enabled", "value_type": "bool"},

View File

@@ -563,6 +563,15 @@
"plain60": {
"target": "evyd13/plain60"
},
"planck/ez": {
"target": "zsa/planck_ez/base"
},
"planck/ez/base": {
"target": "zsa/planck_ez/base"
},
"planck/ez/glow": {
"target": "zsa/planck_ez/glow"
},
"ploopyco/trackball": {
"target": "ploopyco/trackball/rev1_005"
},
@@ -1060,7 +1069,7 @@
"target": "lyso1/lefishe"
},
"lets_split_eh/eh": {
"target": "maple_computing/lets_split_eh/eh"
"target": "maple_computing/lets_split_eh"
},
"ls_60": {
"target": "weirdo/ls_60"
@@ -1080,6 +1089,9 @@
"macro1": {
"target": "laneware/macro1"
},
"maple_computing/lets_split_eh/eh": {
"target": "maple_computing/lets_split_eh"
},
"massdrop/thekey": {
"target": "drop/thekey/v1"
},
@@ -1137,6 +1149,12 @@
"mt980": {
"target": "mt/mt980"
},
"mt/ncr80/hotswap": {
"target": "mt/ncr80/r2/hotswap"
},
"mt/ncr80/solder": {
"target": "mt/ncr80/r2/solder"
},
"nafuda": {
"target": "salicylic_acid3/nafuda"
},
@@ -1525,5 +1543,8 @@
},
"kprepublic/jj50": {
"target": "kprepublic/jj50/rev1"
},
"dnworks/9973": {
"target": "dnworks/tkl87"
}
}

View File

@@ -16,12 +16,6 @@
"type": "object",
"additionalProperties": {"type": "boolean"}
},
"build_target": {
"oneOf": [
{"$ref": "#/keyboard_keymap_tuple"},
{"$ref": "#/json_file_path"}
]
},
"filename": {
"type": "string",
"minLength": 1,
@@ -40,7 +34,8 @@
"pattern": "^[0-9a-z_/\\-]+\\.json$"
},
"key_unit": {
"type": "number"
"type": "number",
"minimum": 0
},
"keyboard": {
"type": "string",
@@ -52,6 +47,19 @@
{"$ref": "#/keyboard"},
{"$ref": "#/filename"}
],
"minItems": 2,
"maxItems": 2,
"unevaluatedItems": false
},
"keyboard_keymap_env": {
"type": "array",
"prefixItems": [
{"$ref": "#/keyboard"},
{"$ref": "#/filename"},
{"$ref": "#/kvp_object"}
],
"minItems": 3,
"maxItems": 3,
"unevaluatedItems": false
},
"keycode": {
@@ -86,6 +94,10 @@
"maxLength": 7,
"pattern": "^[A-Z][A-Zs_0-9]*$"
},
"kvp_object": {
"type": "object",
"additionalProperties": {"type": "string"}
},
"layout_macro": {
"oneOf": [
{

View File

@@ -1 +0,0 @@
false

View File

@@ -342,6 +342,36 @@
"on_state": {"$ref": "qmk.definitions.v1#/bit"}
}
},
"joystick": {
"type": "object",
"properties": {
"enabled": {"type": "boolean"},
"driver": {"type": "string"},
"button_count": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"axis_resolution": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"axes": {
"type": "object",
"propertyNames": {"enum": ["x", "y", "z", "rx", "ry", "rz"]}
"additionalProperties": {
"oneOf": [
{
"type": "object",
"properties": {
"input_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
"low": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"rest": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"high": {"$ref": "qmk.definitions.v1#/unsigned_int"}
}
},
{
"type": "string",
"enum": ["virtual"]
}
]
}
}
}
},
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
"layout_aliases": {
"type": "object",
@@ -515,8 +545,8 @@
"minimum": 0
}
},
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
"x": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"y": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
}
}
@@ -601,8 +631,8 @@
"minimum": 0
}
},
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
"x": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"y": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
}
}
@@ -793,12 +823,26 @@
}
}
},
"soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
"soft_serial_pin": {
"$ref": "qmk.definitions.v1#/mcu_pin",
"$comment": "Deprecated: use split.serial.pin instead"
},
"soft_serial_speed": {
"type": "integer",
"minimum": 0,
"maximum": 5
},
"serial": {
"type": "object",
"additionalProperties": false,
"properties": {
"driver": {
"type": "string",
"enum": ["bitbang", "usart", "vendor"]
},
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}
}
},
"transport": {
"type": "object",
"additionalProperties": false,

View File

@@ -1 +0,0 @@
true

View File

@@ -3,6 +3,14 @@
"$id": "qmk.user_repo.v1",
"title": "User Repository Information",
"type": "object",
"definitions": {
"build_target": {
"oneOf": [
{"$ref": "qmk.definitions.v1#/keyboard_keymap_tuple"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
},
},
"required": [
"userspace_version",
"build_targets"
@@ -15,7 +23,7 @@
"build_targets": {
"type": "array",
"items": {
"$ref": "qmk.definitions.v1#/build_target"
"$ref": "#/definitions/build_target"
}
}
}

View File

@@ -0,0 +1,31 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "qmk.user_repo.v1_1",
"title": "User Repository Information",
"type": "object",
"definitions": {
"build_target": {
"oneOf": [
{"$ref": "qmk.definitions.v1#/keyboard_keymap_tuple"},
{"$ref": "qmk.definitions.v1#/keyboard_keymap_env"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
},
},
"required": [
"userspace_version",
"build_targets"
],
"properties": {
"userspace_version": {
"type": "string",
"enum": ["1.1"]
},
"build_targets": {
"type": "array",
"items": {
"$ref": "#/definitions/build_target"
}
}
}
}

View File

@@ -2,8 +2,6 @@
"keyboard_name": "%KEYBOARD%",
"maintainer": "%USER_NAME%",
"manufacturer": "%REAL_NAME%",
"processor": "%MCU%",
"bootloader": "%BOOTLOADER%",
"diode_direction": "COL2ROW",
"matrix_pins": {
"cols": ["C2"],

View File

@@ -10,11 +10,11 @@ It is also now possible to define combos that have keys overlapping with other c
### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) {#key-overrides}
QMK now has a new feature: [key overrides](../feature_key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
QMK now has a new feature: [key overrides](../features/key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
To illustrate, it's now possible to use the key overrides feature to translate <kbd>Shift + Backspace</kbd> into <kbd>Delete</kbd> -- an often-requested example of where this functionality comes in handy.
There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](../feature_key_overrides) for more examples and info.
There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](../features/key_overrides) for more examples and info.
### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851))

View File

@@ -31,7 +31,7 @@ QMK now has core-supplied support for the following pointing device peripherals:
| `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball |
| `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 |
See the new documentation for the [Pointing Device](../feature_pointing_device) feature for more information on specific configuration for each driver.
See the new documentation for the [Pointing Device](../features/pointing_device) feature for more information on specific configuration for each driver.
### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) {#dynamic-tapping-term}
@@ -116,7 +116,7 @@ Related to the previous section -- RGB Matrix modes have now been made to be opt
Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available.
The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](../feature_rgb_matrix#rgb-matrix-effects) page.
The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](../features/rgb_matrix#rgb-matrix-effects) page.
### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) {#oled-task-refactor}

View File

@@ -12,7 +12,7 @@ Something something *Lets go gamers!*
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
See the [Pointing Device](../feature_pointing_device) documentation for further configuration options.
See the [Pointing Device](../features/pointing_device) documentation for further configuration options.
## Changes Requiring User Action {#changes-requiring-user-action}

View File

@@ -8,7 +8,7 @@ This is a new feature that allows for capslock-like functionality that turns its
For instance, if you wish to type "QMK" without holding shift the entire time, you can either tap both left and right shift, or double-tap shift, to turn on _Caps Word_ -- then type `qmk` (lowercase) without holding shift. Once you hit any key other than `a`--`z`, `0`--`9`, `-`, `_`, delete, or backspace, this will go back to normal typing!
There are other activation mechanisms as well as configurable options like timeout and the like -- see the [Caps Word documentation](../feature_caps_word) for more information.
There are other activation mechanisms as well as configurable options like timeout and the like -- see the [Caps Word documentation](../features/caps_word) for more information.
### Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) {#quantum-painter}
@@ -26,7 +26,7 @@ Quantum Painter is not supported on AVR due to complexity and size constraints.
### Encoder Mapping ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) {#encoder-mapping}
One of the long-standing complaints with Encoders is that there has been no easy way to configure them in user keymaps. [#13286](https://github.com/qmk/qmk_firmware/pull/13286) added support for [Encoder Mapping](../feature_encoders#encoder-map), which allows users to define encoder functionality in a similar way to their normal keymap.
One of the long-standing complaints with Encoders is that there has been no easy way to configure them in user keymaps. [#13286](https://github.com/qmk/qmk_firmware/pull/13286) added support for [Encoder Mapping](../features/encoders#encoder-map), which allows users to define encoder functionality in a similar way to their normal keymap.
::: warning
This is not yet supported by QMK Configurator. It is also unlikely to ever be supported by VIA.

View File

@@ -83,7 +83,7 @@ The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to
QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash.
See the [EEPROM Driver](../eeprom_driver) documentation for more information.
See the [EEPROM Driver](../drivers/eeprom) documentation for more information.
### Pointing Device Improvements ([#16371](https://github.com/qmk/qmk_firmware/pull/16371), [#17111](https://github.com/qmk/qmk_firmware/pull/17111), [#17176](https://github.com/qmk/qmk_firmware/pull/17176), [#17482](https://github.com/qmk/qmk_firmware/pull/17482), [#17776](https://github.com/qmk/qmk_firmware/pull/17776), [#17613](https://github.com/qmk/qmk_firmware/pull/17613)) {#pointing-device-improvements}

View File

@@ -4,7 +4,7 @@
### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) {#autocorrect}
_@getreuer_ in their infinite wisdom decided that autocorrect was a feature needed by QMK. As is customary, _@drashna_ adapted it to core and got it into a state that everyone else can use it. See [Feature: Autocorrect](../feature_autocorrect) for more ifnormation (grin).
_@getreuer_ in their infinite wisdom decided that autocorrect was a feature needed by QMK. As is customary, _@drashna_ adapted it to core and got it into a state that everyone else can use it. See [Feature: Autocorrect](../features/autocorrect) for more ifnormation (grin).
## Changes Requiring User Action {#changes-requiring-user-action}
@@ -132,7 +132,7 @@ The equivalent transformations should be done for LED Matrix boards.
### Unicode mode refactoring {#unicode-mode-renaming}
Unicode modes were renamed in order to prevent collision with equivalent keycodes. The available values for `UNICODE_SELECTED_MODES` changed -- see [Feature: Unicode](../feature_unicode#setting-the-input-mode) for the new list of values and how to configure them.
Unicode modes were renamed in order to prevent collision with equivalent keycodes. The available values for `UNICODE_SELECTED_MODES` changed -- see [Feature: Unicode](../features/unicode#setting-the-input-mode) for the new list of values and how to configure them.
## Notable core changes {#notable-core}

View File

@@ -106,7 +106,7 @@ void leader_end_user(void) {
}
```
For more information please see the [Leader Key documentation](../feature_leader_key).
For more information please see the [Leader Key documentation](../features/leader_key).
### Updated Keyboard Codebases {#updated-keyboard-codebases}

View File

@@ -24,7 +24,7 @@ Of note for keyboard designers:
A new pair of keys has been added to QMK -- namely `QK_REPEAT_KEY` and `QK_ALT_REPEAT_KEY` (shortened: `QK_REP`/`QK_AREP`). These allow you to repeat the last key pressed, or in the case of the alternate key, press the "opposite" of the last key. For example, if you press `KC_LEFT`, pressing `QK_REPEAT_KEY` afterwards repeats `KC_LEFT`, but pressing `QK_ALT_REPEAT_KEY` instead sends `KC_RIGHT`.
The full list of default alternate keys is available on the [Repeat Key](../feature_repeat_key) documentation.
The full list of default alternate keys is available on the [Repeat Key](../features/repeat_key) documentation.
To enable these keys, in your keymap's `rules.mk`, add:
@@ -93,7 +93,7 @@ Additionally, this ensures that builds on QMK Configurator produce some sort of
The "classic" OLED driver picked up support for additional sizes of OLED displays, support for the SH1107 controller, and SPI-based OLED support.
Other configurable items are available and can be found on the [OLED Driver page](../feature_oled_driver).
Other configurable items are available and can be found on the [OLED Driver page](../features/oled_driver).
## Full changelist {#full-changelist}

View File

@@ -42,7 +42,7 @@ AVR sees minimal (if any) benefit -- `double` was interpreted as `float` on AVR
### Remove encoder in-matrix workaround code ([#20389](https://github.com/qmk/qmk_firmware/pull/20389)) {#remove-encoder-in-matrix-workaround-code}
Some keyboards "hacked" encoder support into spare slots in the key matrix in order to interoperate with VIA. This workaround is no longer necessary, and the code has been removed. If you have a keyboard that uses this workaround, you will need to update your keymap to use the new [Encoder Map](../feature_encoders#encoder-map) API instead.
Some keyboards "hacked" encoder support into spare slots in the key matrix in order to interoperate with VIA. This workaround is no longer necessary, and the code has been removed. If you have a keyboard that uses this workaround, you will need to update your keymap to use the new [Encoder Map](../features/encoders#encoder-map) API instead.
### Unicodemap keycodes rename ([#21092](https://github.com/qmk/qmk_firmware/pull/21092)) {#unicodemap-keycodes-rename}

View File

@@ -120,7 +120,7 @@ In some cases, accidental automatic activation of the mouse layer made it diffic
### DIP Switch Mapping ([#22543](https://github.com/qmk/qmk_firmware/pull/22543)) {#dip-switch-map}
Much like Encoder Mapping, DIP Switch Mapping allows for specifying a table of actions to execute when a DIP switch state changes. See the [DIP Switch Documentation](../feature_dip_switch#dip-switch-map) for more information.
Much like Encoder Mapping, DIP Switch Mapping allows for specifying a table of actions to execute when a DIP switch state changes. See the [DIP Switch Documentation](../features/dip_switch#dip-switch-map) for more information.
```c
#if defined(DIP_SWITCH_MAP_ENABLE)

View File

@@ -109,6 +109,16 @@ Essentially, changes were made in the internals of how QMK interacts with USB fo
Compliance checks were run against QMK firmwares for the most popular ARM microcontrollers, as well as suspend/resume tests. As far as we can tell, a whole host of hard-to-reproduce issues are mitigated by this change.
## Deprecation Notices
In line with the [notice period](../support_deprecation_policy#how-much-advance-notice-will-be-given), deprecation notices for larger items are listed here.
### Migration of VIA keymaps to VIA team control
The QMK team has been in discussion with the VIA maintainers and all VIA-related keymaps in the `qmk_firmware` repository will transition to a `qmk_userspace`-style repository under the VIA team's control at the end of the next breaking changes period. This allows the VIA team to support many more custom keyboard configurations, as well as reduces the turnaround time for any changes to the VIA protocol they wish to make.
At the end of the breaking changes cycle ending 2024-08-25, VIA-enabled keymaps will no longer be accepted into the QMK repository. At the time of migration, any open PRs against `qmk_firmware` which include new VIA-related keymaps will be subsequently be asked to remove those keymaps and instead raise a PR against the userspace repository containing all VIA keymaps.
## Full changelist {#full-changelist}
Core:

198
docs/ChangeLog/20240825.md Normal file
View File

@@ -0,0 +1,198 @@
# QMK Breaking Changes - 2024 August 25 Changelog
## Notable Features
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 [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) repository.
## Changes Requiring User Action
### Updated Keyboard Codebases
One note with updated keyboard names -- historical keyboard names are still considered valid when using [External Userspace](../newbs_external_userspace) for builds. If you're already using External Userspace, you do not need to move your keymap inside your repository.
| Old Keyboard Name | New Keyboard Name |
|----------------------------------|-------------------------------|
| dnworks/9973 | dnworks/tkl87 |
| maple_computing/lets_split_eh/eh | maple_computing/lets_split_eh |
| planck/ez/base | zsa/planck_ez/base |
### SparkFun Pro Micro RP2040 converter renamed ([#24192](https://github.com/qmk/qmk_firmware/pull/24192))
The converter for the SparkFun Pro Micro RP2040 has been renamed.
| Old | New |
|-------------------|-------------------|
| `promicro_rp2040` | `sparkfun_rp2040` |
This change was made to avoid confusion between the clones named ProMicro RP2040 and the SparkFun Pro Micro RP2040. The clones should be using the `rp2040_ce` option.
### Key Override `keymap.c` signature change ([#24120](https://github.com/qmk/qmk_firmware/pull/24120))
Changes were made to key overrides in order to hook them into the keymap introspection system.
If you're using key overrides, your `keymap.c` will need a change to the signature of your list of key overrides, as well as removing the `NULL` terminator.
For example, you'll need to change existing code from (note the highlighted lines):
```c{1,4-5}
const key_override_t **key_overrides = (const key_override_t *[]){
&my_override_1,
&my_override_2,
NULL
};
```
to:
```c{1,4}
const key_override_t *key_overrides[] = {
&my_override_1,
&my_override_2,
};
```
### ADNS9800 and PMW33xx firmware upload now opt-in ([#24001](https://github.com/qmk/qmk_firmware/pull/24001))
Due to ambiguity with licensing compatibility, QMK has made the firmware ROM uploads for the ADNS9800 and PMW33xx lines of pointing device sensors temporarily opt-in with the view to removing them. Historically they were included by default, but as of this PR this is now no longer the case.
Please get in touch with the QMK team if your sensor no longer functions without the firmware upload -- so far we've tested each device type and they still seem to function without a new firmware, but this has not been a 100% exhaustive validation.
To re-enable firmware upload for your own builds, add the following to your keymap's `config.h`:
| Sensor | Define |
|----------|--------------------------------|
| ADNS9800 | `#define ADNS9800_UPLOAD_SROM` |
| PMW33xx | `#define PMW33XX_UPLOAD_SROM` |
:::info Note
If no issues arise during this current breaking changes cycle, these sensor firmware ROMs will be removed from QMK entirely.
:::
## Deprecation Notices
In line with the [notice period](../support_deprecation_policy#how-much-advance-notice-will-be-given), deprecation notices for larger items are listed here.
### 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 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.
### ADNS9800 and PMW33xx sensor firmware ROM removal
As mentioned above, there's license compatibility issues between QMK and the firmware blobs historically uploaded for the ADNS9800 and PMW33xx sensors. This notice is to inform users that these firmware blobs will almost certainly be removed from QMK in the next breaking changes merge.
As previously noted this does not seem to have any detrimental effect to any of those devices, as they seem to include firmware on-chip without requiring one to be uploaded. Please get in touch with the QMK team on Discord if your sensor is no longer functional.
## Full changelist
Core:
* EEPROM: Don't erase if we don't have to. Adding eeprom_driver_format abstraction. ([#18332](https://github.com/qmk/qmk_firmware/pull/18332))
* Generate keymap dd keycodes to header ([#20273](https://github.com/qmk/qmk_firmware/pull/20273))
* [wear_leveling] efl updates ([#22489](https://github.com/qmk/qmk_firmware/pull/22489))
* GC9xxx LCD family drivers (GC9107 and GC9A01) ([#23091](https://github.com/qmk/qmk_firmware/pull/23091))
* [build_test] set CONSOLE_ENABLE=yes if DEBUG > 0 ([#23097](https://github.com/qmk/qmk_firmware/pull/23097))
* Enhance overlapping mouse keys control ([#23341](https://github.com/qmk/qmk_firmware/pull/23341))
* APA102: API rework ([#23355](https://github.com/qmk/qmk_firmware/pull/23355))
* [WIP] Adds bus acquire/release semantics to SPI start/stop. ([#23439](https://github.com/qmk/qmk_firmware/pull/23439))
* add farsi keymap extras ([#23650](https://github.com/qmk/qmk_firmware/pull/23650))
* Update atomic GPIO macros in keyboard custom matrix ([#23796](https://github.com/qmk/qmk_firmware/pull/23796))
* Check LED flags for Pixel Fractal effect ([#23881](https://github.com/qmk/qmk_firmware/pull/23881))
* Add STM32F405RG ld script for tinyuf2 ([#23885](https://github.com/qmk/qmk_firmware/pull/23885))
* SPI flash API cleanup, add async erase capability. ([#23894](https://github.com/qmk/qmk_firmware/pull/23894))
* Add process_keycode handlers for new RGB Matrix and Underglow keycodes ([#23896](https://github.com/qmk/qmk_firmware/pull/23896))
* Decouple VIA from STM32 L0/L1 EEPROM implementation ([#23901](https://github.com/qmk/qmk_firmware/pull/23901))
* Normalise mouse keycodes ([#23975](https://github.com/qmk/qmk_firmware/pull/23975))
* Remove deprecated `led_set_user` ([#23979](https://github.com/qmk/qmk_firmware/pull/23979))
* Change ADNS9800 and PMW33XX SROM uploads to opt in. ([#24001](https://github.com/qmk/qmk_firmware/pull/24001))
* Rename encoder pins defines ([#24003](https://github.com/qmk/qmk_firmware/pull/24003))
* Change suspend condition check order on ChibiOS ([#24020](https://github.com/qmk/qmk_firmware/pull/24020))
* Tap dance introspection ([#24049](https://github.com/qmk/qmk_firmware/pull/24049))
* Allow overriding `get_hardware_id()`. ([#24051](https://github.com/qmk/qmk_firmware/pull/24051))
* Align LUFA suspend logic ([#24055](https://github.com/qmk/qmk_firmware/pull/24055))
* Add support for key override introspection. ([#24120](https://github.com/qmk/qmk_firmware/pull/24120))
* Dynamic macro callbacks ([#24142](https://github.com/qmk/qmk_firmware/pull/24142))
* Rename promicro_rp2040 converter to sparkfun_pm2040 ([#24192](https://github.com/qmk/qmk_firmware/pull/24192))
* Refactor starlight RGB matrix effects ([#24202](https://github.com/qmk/qmk_firmware/pull/24202))
* Refactor riverflow RGB matrix loop ([#24203](https://github.com/qmk/qmk_firmware/pull/24203))
CLI:
* Remove handling of keyboard level keymap templates ([#24234](https://github.com/qmk/qmk_firmware/pull/24234))
* Small tweaks to keymap generation ([#24240](https://github.com/qmk/qmk_firmware/pull/24240))
Keyboards:
* refactor: keyboard/ncr80/r2 ([#22670](https://github.com/qmk/qmk_firmware/pull/22670))
* Implement data driven joysticks ([#22947](https://github.com/qmk/qmk_firmware/pull/22947))
* Whitefacemountain Ampersand ([#23437](https://github.com/qmk/qmk_firmware/pull/23437))
* Add TRKeyboard TRK1 keyboard ([#23642](https://github.com/qmk/qmk_firmware/pull/23642))
* Rename dnworks/9973 to dnworks/tkl87 ([#23692](https://github.com/qmk/qmk_firmware/pull/23692))
* Update Underglow keycodes ([#23765](https://github.com/qmk/qmk_firmware/pull/23765))
* Add boardsource/the_q ([#23782](https://github.com/qmk/qmk_firmware/pull/23782))
* BastardKB: remove legacy board `tbk` ([#23818](https://github.com/qmk/qmk_firmware/pull/23818))
* Update ZSA Moonlander ([#23911](https://github.com/qmk/qmk_firmware/pull/23911))
* Move Planck EZ to ZSA vendor folder ([#23917](https://github.com/qmk/qmk_firmware/pull/23917))
* Migrate SPLIT_HAND_PIN to json ([#23924](https://github.com/qmk/qmk_firmware/pull/23924))
* Migrate SERIAL_DRIVER to json ([#23925](https://github.com/qmk/qmk_firmware/pull/23925))
* Migrate RGB Matrix layout for two boards ([#23963](https://github.com/qmk/qmk_firmware/pull/23963))
* Migrate `led_update_kb` implementations to DD ([#23980](https://github.com/qmk/qmk_firmware/pull/23980))
* Migrate `led_update_kb` implementations to DD ([#23981](https://github.com/qmk/qmk_firmware/pull/23981))
* Migrate `led_update_kb` implementations to DD ([#23983](https://github.com/qmk/qmk_firmware/pull/23983))
* Migrate `led_update_kb` implementations to DD ([#23985](https://github.com/qmk/qmk_firmware/pull/23985))
* Relocate m256wh VIA logic ([#24006](https://github.com/qmk/qmk_firmware/pull/24006))
* Relocate winry315 VIA logic ([#24008](https://github.com/qmk/qmk_firmware/pull/24008))
* Relocate m256ws VIA logic ([#24009](https://github.com/qmk/qmk_firmware/pull/24009))
* `atreus`: misc cleanups ([#24010](https://github.com/qmk/qmk_firmware/pull/24010))
* Relocate work_louder VIA logic ([#24011](https://github.com/qmk/qmk_firmware/pull/24011))
* Relocate xelus/pachi/rgb/rev2 VIA logic ([#24016](https://github.com/qmk/qmk_firmware/pull/24016))
* Remove custom keycodes from nullbitsco/snap ([#24017](https://github.com/qmk/qmk_firmware/pull/24017))
* added bear_face/v3 ([#24032](https://github.com/qmk/qmk_firmware/pull/24032))
* Remove DEFAULT_FOLDER from maple_computing/lets_split_eh ([#24054](https://github.com/qmk/qmk_firmware/pull/24054))
* refactor bear_face/v1, v2 ([#24060](https://github.com/qmk/qmk_firmware/pull/24060))
* Convert `eeconfig_init_kb` implementations to config ([#24087](https://github.com/qmk/qmk_firmware/pull/24087))
* Remove broken keymap from keebio/iris ([#24094](https://github.com/qmk/qmk_firmware/pull/24094))
* Move LED Matrix LED config to data driven ([#24122](https://github.com/qmk/qmk_firmware/pull/24122))
* Move split.soft_serial_pin to split.serial.pin ([#24127](https://github.com/qmk/qmk_firmware/pull/24127))
* Remove pointless `RGB_MATRIX_LED_COUNT`s ([#24133](https://github.com/qmk/qmk_firmware/pull/24133))
* `hs60/v1`: separate into ANSI and ISO revisions ([#24136](https://github.com/qmk/qmk_firmware/pull/24136))
* Migrate half-duplex `SERIAL_USART_TX_PIN` to DD ([#24143](https://github.com/qmk/qmk_firmware/pull/24143))
* Migrate split.soft_serial_pin to split.serial.pin O-Z ([#24146](https://github.com/qmk/qmk_firmware/pull/24146))
* Migrate split.soft_serial_pin to split.serial.pin 0-H ([#24155](https://github.com/qmk/qmk_firmware/pull/24155))
* Remove instances of MASTER_LEFT. ([#24163](https://github.com/qmk/qmk_firmware/pull/24163))
* Rename EC Type-K ([#24180](https://github.com/qmk/qmk_firmware/pull/24180))
* Migrate split.soft_serial_pin to split.serial.pin H-O ([#24185](https://github.com/qmk/qmk_firmware/pull/24185))
* Remove split.transport.protocol=serial ([#24191](https://github.com/qmk/qmk_firmware/pull/24191))
* Refactor use of `matrix_scan_kb` ([#24200](https://github.com/qmk/qmk_firmware/pull/24200))
* Eliminate use of `#include "../default/keymap.c"`. ([#24215](https://github.com/qmk/qmk_firmware/pull/24215))
* Remove keyboard level `QK_BOOT` implementations ([#24231](https://github.com/qmk/qmk_firmware/pull/24231))
* Remove `handwired/pytest/has_template` ([#24232](https://github.com/qmk/qmk_firmware/pull/24232))
* Refactor opendeck/32 ([#24233](https://github.com/qmk/qmk_firmware/pull/24233))
* Refactor printedpad ([#24236](https://github.com/qmk/qmk_firmware/pull/24236))
* Refactor orthocode ([#24237](https://github.com/qmk/qmk_firmware/pull/24237))
* Remove unnecessary RGB Matrix shutdown hooks ([#24238](https://github.com/qmk/qmk_firmware/pull/24238))
* Remove all via-enabled keymaps, including `via`. ([#24322](https://github.com/qmk/qmk_firmware/pull/24322))
Keyboard fixes:
* Fix dogtag/info.json ([#23520](https://github.com/qmk/qmk_firmware/pull/23520))
* splitkb/kyria: remove `CONVERT_TO` at keyboard level ([#23857](https://github.com/qmk/qmk_firmware/pull/23857))
* Fixup mt/mt84 ([#23883](https://github.com/qmk/qmk_firmware/pull/23883))
* Fix for encoders and support ENCODER_MAP_ENABLE on Planck rev7 ([#23967](https://github.com/qmk/qmk_firmware/pull/23967))
* `handwired/swiftrax/bumblebee`: fix layout name ([#24064](https://github.com/qmk/qmk_firmware/pull/24064))
* Fixup boardsource/the_q RGB matrix coordinates ([#24086](https://github.com/qmk/qmk_firmware/pull/24086))
* Various fixes for keyboards not implementing callbacks correctly ([#24092](https://github.com/qmk/qmk_firmware/pull/24092))
* Various fixes for keyboards not implementing callbacks correctly ([#24116](https://github.com/qmk/qmk_firmware/pull/24116))
* Remove duplicate calls to `housekeeping_task_user` ([#24201](https://github.com/qmk/qmk_firmware/pull/24201))
* Fixup `handwired/dactyl_minidox` ([#24253](https://github.com/qmk/qmk_firmware/pull/24253))
* Fix build failure on zsa/moonlander with DYNAMIC_MACRO_ENABLE ([#24316](https://github.com/qmk/qmk_firmware/pull/24316))
Others:
* LED drivers: extract documentation from LED/RGB Matrix pages ([#23630](https://github.com/qmk/qmk_firmware/pull/23630))
* Implement data driven serial driver ([#23923](https://github.com/qmk/qmk_firmware/pull/23923))
* Remove skipped schema files ([#23987](https://github.com/qmk/qmk_firmware/pull/23987))
* Update RGBLight (Underglow) keycode names ([#23999](https://github.com/qmk/qmk_firmware/pull/23999))
Bugs:
* Fix NKRO and Mouse Emulation on arm_atsam ([#23945](https://github.com/qmk/qmk_firmware/pull/23945))
* Force `dump_lines()` to always use Unix line endings ([#23954](https://github.com/qmk/qmk_firmware/pull/23954))
* Fixup home link. ([#24068](https://github.com/qmk/qmk_firmware/pull/24068))

View File

@@ -41,7 +41,7 @@ Unrelated to styling, high-level tech.
![QMK Light](./public/badge-community-light.svg)
![QMK Dark](./public/badge-community-dark.svg)
<img src="./gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
<img src="./public/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
### Lists
@@ -84,7 +84,7 @@ Nested mixed:
* `lib/python/qmk/cli/generate/config_h.py`
* `lib/python/qmk/cli/generate/rules_mk.py`
### Emoji :id=emoji
### Emoji {#emoji}
#### Direct:

75
docs/_aliases.json Normal file
View File

@@ -0,0 +1,75 @@
{
"/adding_a_keyboard_to_qmk": "/hardware_keyboard_guidelines",
"/build_environment_setup": "/newbs_getting_started",
"/cli_dev_configuration": "/cli_configuration",
"/dynamic_macros": "/feature_dynamic_macros",
"/feature_common_shortcuts": "/feature_advanced_keycodes",
"/flashing_bootloadhid": "/flashing",
"/getting_started_build_tools": "/newbs_getting_started",
"/getting_started_getting_help": "/support",
"/glossary": "/reference_glossary",
"/key_lock": "/feature_key_lock",
"/make_instructions": "/getting_started_make_guide",
"/python_development": "/cli_development",
"/space_cadet_shift": "/feature_space_cadet_shift",
"/tap_dance": "/feature_tap_dance",
"/tutorial": "/newbs",
"/unicode": "/feature_unicode",
"/adc_driver": "/drivers/adc",
"/apa102_driver": "/drivers/apa102",
"/audio_driver": "/drivers/audio",
"/eeprom_driver": "/drivers/eeprom",
"/feature_audio": "/features/audio",
"/feature_auto_shift": "/features/auto_shift",
"/feature_autocorrect": "/features/autocorrect",
"/feature_backlight": "/features/backlight",
"/feature_bluetooth": "/features/bluetooth",
"/feature_bootmagic": "/features/bootmagic",
"/feature_caps_word": "/features/caps_word",
"/feature_combo": "/features/combo",
"/feature_command": "/features/command",
"/feature_digitizer": "/features/digitizer",
"/feature_dip_switch": "/features/dip_switch",
"/feature_dynamic_macros": "/features/dynamic_macros",
"/feature_encoders": "/features/encoders",
"/feature_grave_esc": "/features/grave_esc",
"/feature_haptic_feedback": "/features/haptic_feedback",
"/feature_hd44780": "/features/hd44780",
"/feature_joystick": "/features/joystick",
"/feature_key_lock": "/features/key_lock",
"/feature_key_overrides": "/features/key_overrides",
"/feature_leader_key": "/features/leader_key",
"/feature_led_indicators": "/features/led_indicators",
"/feature_led_matrix": "/features/led_matrix",
"/feature_midi": "/features/midi",
"/feature_mouse_keys": "/features/mouse_keys",
"/feature_oled_driver": "/features/oled_driver",
"/feature_os_detection": "/features/os_detection",
"/feature_pointing_device": "/features/pointing_device",
"/feature_programmable_button": "/features/programmable_button",
"/feature_ps2_mouse": "/features/ps2_mouse",
"/feature_rawhid": "/features/rawhid",
"/feature_repeat_key": "/features/repeat_key",
"/feature_rgb_matrix": "/features/rgb_matrix",
"/feature_rgblight": "/features/rgblight",
"/feature_secure": "/features/secure",
"/feature_send_string": "/features/send_string",
"/feature_sequencer": "/features/sequencer",
"/feature_space_cadet": "/features/space_cadet",
"/feature_split_keyboard": "/features/split_keyboard",
"/feature_st7565": "/features/st7565",
"/feature_stenography": "/features/stenography",
"/feature_swap_hands": "/features/swap_hands",
"/feature_tap_dance": "/features/tap_dance",
"/feature_tri_layer": "/features/tri_layer",
"/feature_unicode": "/features/unicode",
"/feature_wpm": "/features/wpm",
"/flash_driver": "/drivers/flash",
"/gpio_control": "/drivers/gpio",
"/i2c_driver": "/drivers/i2c",
"/serial_driver": "/drivers/serial",
"/spi_driver": "/drivers/spi",
"/uart_driver": "/drivers/uart",
"/ws2812_driver": "/drivers/ws2812"
}

View File

@@ -64,13 +64,7 @@
"text": "Development Environments",
"items": [{ "text": "Docker Guide", "link": "/getting_started_docker" }]
},
{
"text": "Flashing",
"items": [
{ "text": "Flashing", "link": "/flashing" },
{ "text": "Flashing ATmega32A (ps2avrgb)", "link": "/flashing_bootloadhid" }
]
},
{ "text": "Flashing", "link": "/flashing" },
{
"text": "IDEs",
"items": [
@@ -103,45 +97,45 @@
{
"text": "Advanced Keycodes",
"items": [
{ "text": "Command", "link": "/feature_command" },
{ "text": "Dynamic Macros", "link": "/feature_dynamic_macros" },
{ "text": "Grave Escape", "link": "/feature_grave_esc" },
{ "text": "Leader Key", "link": "/feature_leader_key" },
{ "text": "Command", "link": "/features/command" },
{ "text": "Dynamic Macros", "link": "/features/dynamic_macros" },
{ "text": "Grave Escape", "link": "/features/grave_esc" },
{ "text": "Leader Key", "link": "/features/leader_key" },
{ "text": "Mod-Tap", "link": "/mod_tap" },
{ "text": "Macros", "link": "/feature_macros" },
{ "text": "Mouse Keys", "link": "/feature_mouse_keys" },
{ "text": "Programmable Button", "link": "/feature_programmable_button" },
{ "text": "Repeat Key", "link": "/feature_repeat_key" },
{ "text": "Space Cadet Shift", "link": "/feature_space_cadet" },
{ "text": "Mouse Keys", "link": "/features/mouse_keys" },
{ "text": "Programmable Button", "link": "/features/programmable_button" },
{ "text": "Repeat Key", "link": "/features/repeat_key" },
{ "text": "Space Cadet Shift", "link": "/features/space_cadet" },
{ "text": "US ANSI Shifted Keys", "link": "/keycodes_us_ansi_shifted" }
]
},
{
"text": "Software Features",
"items": [
{ "text": "Auto Shift", "link": "/feature_auto_shift" },
{ "text": "Autocorrect", "link": "/feature_autocorrect" },
{ "text": "Caps Word", "link": "/feature_caps_word" },
{ "text": "Combos", "link": "/feature_combo" },
{ "text": "Auto Shift", "link": "/features/auto_shift" },
{ "text": "Autocorrect", "link": "/features/autocorrect" },
{ "text": "Caps Word", "link": "/features/caps_word" },
{ "text": "Combos", "link": "/features/combo" },
{ "text": "Debounce API", "link": "/feature_debounce_type" },
{ "text": "Digitizer", "link": "/feature_digitizer" },
{ "text": "Digitizer", "link": "/features/digitizer" },
{ "text": "EEPROM", "link": "/feature_eeprom" },
{ "text": "Key Lock", "link": "/feature_key_lock" },
{ "text": "Key Overrides", "link": "/feature_key_overrides" },
{ "text": "Key Lock", "link": "/features/key_lock" },
{ "text": "Key Overrides", "link": "/features/key_overrides" },
{ "text": "Layers", "link": "/feature_layers" },
{ "text": "One Shot Keys", "link": "/one_shot_keys" },
{ "text": "OS Detection", "link": "/feature_os_detection" },
{ "text": "Raw HID", "link": "/feature_rawhid" },
{ "text": "Secure", "link": "/feature_secure" },
{ "text": "Send String", "link": "/feature_send_string" },
{ "text": "Sequencer", "link": "/feature_sequencer" },
{ "text": "Swap Hands", "link": "/feature_swap_hands" },
{ "text": "Tap Dance", "link": "/feature_tap_dance" },
{ "text": "OS Detection", "link": "/features/os_detection" },
{ "text": "Raw HID", "link": "/features/rawhid" },
{ "text": "Secure", "link": "/features/secure" },
{ "text": "Send String", "link": "/features/send_string" },
{ "text": "Sequencer", "link": "/features/sequencer" },
{ "text": "Swap Hands", "link": "/features/swap_hands" },
{ "text": "Tap Dance", "link": "/features/tap_dance" },
{ "text": "Tap-Hold Configuration", "link": "/tap_hold" },
{ "text": "Tri Layer", "link": "/feature_tri_layer" },
{ "text": "Unicode", "link": "/feature_unicode" },
{ "text": "Tri Layer", "link": "/features/tri_layer" },
{ "text": "Unicode", "link": "/features/unicode" },
{ "text": "Userspace", "link": "/feature_userspace" },
{ "text": "WPM Calculation", "link": "/feature_wpm" }
{ "text": "WPM Calculation", "link": "/features/wpm" }
]
},
{
@@ -157,35 +151,35 @@
{ "text": "Quantum Painter LVGL Integration", "link": "/quantum_painter_lvgl" }
]
},
{ "text": "HD44780 LCD Driver", "link": "/feature_hd44780" },
{ "text": "ST7565 LCD Driver", "link": "/feature_st7565" },
{ "text": "OLED Driver", "link": "/feature_oled_driver" }
{ "text": "HD44780 LCD Driver", "link": "/features/hd44780" },
{ "text": "ST7565 LCD Driver", "link": "/features/st7565" },
{ "text": "OLED Driver", "link": "/features/oled_driver" }
]
},
{
"text": "Lighting",
"items": [
{ "text": "Backlight", "link": "/feature_backlight" },
{ "text": "LED Matrix", "link": "/feature_led_matrix" },
{ "text": "RGB Lighting", "link": "/feature_rgblight" },
{ "text": "RGB Matrix", "link": "/feature_rgb_matrix" }
{ "text": "Backlight", "link": "/features/backlight" },
{ "text": "LED Matrix", "link": "/features/led_matrix" },
{ "text": "RGB Lighting", "link": "/features/rgblight" },
{ "text": "RGB Matrix", "link": "/features/rgb_matrix" }
]
},
{ "text": "Audio", "link": "/feature_audio" },
{ "text": "Bluetooth", "link": "/feature_bluetooth" },
{ "text": "Bootmagic Lite", "link": "/feature_bootmagic" },
{ "text": "Audio", "link": "/features/audio" },
{ "text": "Bluetooth", "link": "/features/bluetooth" },
{ "text": "Bootmagic", "link": "/features/bootmagic" },
{ "text": "Converters", "link": "/feature_converters" },
{ "text": "Custom Matrix", "link": "/custom_matrix" },
{ "text": "DIP Switch", "link": "/feature_dip_switch" },
{ "text": "Encoders", "link": "/feature_encoders" },
{ "text": "Haptic Feedback", "link": "/feature_haptic_feedback" },
{ "text": "Joystick", "link": "/feature_joystick" },
{ "text": "LED Indicators", "link": "/feature_led_indicators" },
{ "text": "MIDI", "link": "/feature_midi" },
{ "text": "Pointing Device", "link": "/feature_pointing_device" },
{ "text": "PS/2 Mouse", "link": "/feature_ps2_mouse" },
{ "text": "Split Keyboard", "link": "/feature_split_keyboard" },
{ "text": "Stenography", "link": "/feature_stenography" }
{ "text": "DIP Switch", "link": "/features/dip_switch" },
{ "text": "Encoders", "link": "/features/encoders" },
{ "text": "Haptic Feedback", "link": "/features/haptic_feedback" },
{ "text": "Joystick", "link": "/features/joystick" },
{ "text": "LED Indicators", "link": "/features/led_indicators" },
{ "text": "MIDI", "link": "/features/midi" },
{ "text": "Pointing Device", "link": "/features/pointing_device" },
{ "text": "PS/2 Mouse", "link": "/features/ps2_mouse" },
{ "text": "Split Keyboard", "link": "/features/split_keyboard" },
{ "text": "Stenography", "link": "/features/stenography" }
]
},
{
@@ -210,9 +204,10 @@
{ "text": "My Pull Request Was Flagged", "link": "/breaking_changes_instructions" },
{
"text": "Most Recent ChangeLog",
"link": "/ChangeLog/20240526"
"link": "/ChangeLog/20240825"
},
{ "text": "Past Breaking Changes", "link": "/breaking_changes_history" }
{ "text": "Past Breaking Changes", "link": "/breaking_changes_history" },
{ "text": "Deprecation Policy", "link": "/support_deprecation_policy" }
]
},
@@ -226,19 +221,19 @@
"text": "Drivers",
"link": "hardware_drivers",
"items": [
{ "text": "ADC Driver", "link": "/adc_driver" },
{ "text": "APA102 Driver", "link": "/apa102_driver" },
{ "text": "Audio Driver", "link": "/audio_driver" },
{ "text": "I2C Driver", "link": "/i2c_driver" },
{ "text": "SPI Driver", "link": "/spi_driver" },
{ "text": "WS2812 Driver", "link": "/ws2812_driver" },
{ "text": "EEPROM Driver", "link": "/eeprom_driver" },
{ "text": "Flash Driver", "link": "/flash_driver" },
{ "text": "'serial' Driver", "link": "/serial_driver" },
{ "text": "UART Driver", "link": "/uart_driver" }
{ "text": "ADC Driver", "link": "/drivers/adc" },
{ "text": "APA102 Driver", "link": "/drivers/apa102" },
{ "text": "Audio Driver", "link": "/drivers/audio" },
{ "text": "EEPROM Driver", "link": "/drivers/eeprom" },
{ "text": "Flash Driver", "link": "/drivers/flash" },
{ "text": "I2C Driver", "link": "/drivers/i2c" },
{ "text": "'serial' Driver", "link": "/drivers/serial" },
{ "text": "SPI Driver", "link": "/drivers/spi" },
{ "text": "UART Driver", "link": "/drivers/uart" },
{ "text": "WS2812 Driver", "link": "/drivers/ws2812" }
]
},
{ "text": "GPIO Controls", "link": "/gpio_control" },
{ "text": "GPIO Controls", "link": "/drivers/gpio" },
{ "text": "Keyboard Guidelines", "link": "/hardware_keyboard_guidelines" }
]
},

View File

@@ -1,173 +0,0 @@
# ADC Driver
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders).
This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision.
## Usage
To use this driver, add the following to your `rules.mk`:
```make
ANALOG_DRIVER_REQUIRED = yes
```
Then place this include at the top of your code:
```c
#include "analog.h"
```
## Channels
### AVR
|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P|
|-------|-------------|-------------|---------|----------|
|0 |`F0` |`F0` |`A0` |`C0` |
|1 |`F1` |`F1` |`A1` |`C1` |
|2 |`F2` | |`A2` |`C2` |
|3 |`F3` | |`A3` |`C3` |
|4 |`F4` |`F4` |`A4` |`C4` |
|5 |`F5` |`F5` |`A5` |`C5` |
|6 |`F6` |`F6` |`A6` |* |
|7 |`F7` |`F7` |`A7` |* |
|8 | |`D4` | | |
|9 | |`D6` | | |
|10 | |`D7` | | |
|11 | |`B4` | | |
|12 | |`B5` | | |
|13 | |`B6` | | |
<sup>\* The ATmega328/P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these.</sup>
### ARM
#### STM32
Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC.
Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-indexed, whereas the F3 has 4 ADCs and the channels are 1-indexed. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation.
|ADC|Channel|STM32F0xx|STM32F1xx|STM32F3xx|STM32F4xx|
|---|-------|---------|---------|---------|---------|
|1 |0 |`A0` |`A0` | |`A0` |
|1 |1 |`A1` |`A1` |`A0` |`A1` |
|1 |2 |`A2` |`A2` |`A1` |`A2` |
|1 |3 |`A3` |`A3` |`A2` |`A3` |
|1 |4 |`A4` |`A4` |`A3` |`A4` |
|1 |5 |`A5` |`A5` |`F4` |`A5` |
|1 |6 |`A6` |`A6` |`C0` |`A6` |
|1 |7 |`A7` |`A7` |`C1` |`A7` |
|1 |8 |`B0` |`B0` |`C2` |`B0` |
|1 |9 |`B1` |`B1` |`C3` |`B1` |
|1 |10 |`C0` |`C0` |`F2` |`C0` |
|1 |11 |`C1` |`C1` | |`C1` |
|1 |12 |`C2` |`C2` | |`C2` |
|1 |13 |`C3` |`C3` | |`C3` |
|1 |14 |`C4` |`C4` | |`C4` |
|1 |15 |`C5` |`C5` | |`C5` |
|1 |16 | | | | |
|2 |0 | |`A0`¹ | |`A0`² |
|2 |1 | |`A1`¹ |`A4` |`A1`² |
|2 |2 | |`A2`¹ |`A5` |`A2`² |
|2 |3 | |`A3`¹ |`A6` |`A3`² |
|2 |4 | |`A4`¹ |`A7` |`A4`² |
|2 |5 | |`A5`¹ |`C4` |`A5`² |
|2 |6 | |`A6`¹ |`C0` |`A6`² |
|2 |7 | |`A7`¹ |`C1` |`A7`² |
|2 |8 | |`B0`¹ |`C2` |`B0`² |
|2 |9 | |`B1`¹ |`C3` |`B1`² |
|2 |10 | |`C0`¹ |`F2` |`C0`² |
|2 |11 | |`C1`¹ |`C5` |`C1`² |
|2 |12 | |`C2`¹ |`B2` |`C2`² |
|2 |13 | |`C3`¹ | |`C3`² |
|2 |14 | |`C4`¹ | |`C4`² |
|2 |15 | |`C5`¹ | |`C5`² |
|2 |16 | | | | |
|3 |0 | |`A0`¹ | |`A0`² |
|3 |1 | |`A1`¹ |`B1` |`A1`² |
|3 |2 | |`A2`¹ |`E9` |`A2`² |
|3 |3 | |`A3`¹ |`E13` |`A3`² |
|3 |4 | |`F6`¹ | |`F6`² |
|3 |5 | |`F7`¹ |`B13` |`F7`² |
|3 |6 | |`F8`¹ |`E8` |`F8`² |
|3 |7 | |`F9`¹ |`D10` |`F9`² |
|3 |8 | |`F10`¹ |`D11` |`F10`² |
|3 |9 | | |`D12` |`F3`² |
|3 |10 | |`C0`¹ |`D13` |`C0`² |
|3 |11 | |`C1`¹ |`D14` |`C1`² |
|3 |12 | |`C2`¹ |`B0` |`C2`² |
|3 |13 | |`C3`¹ |`E7` |`C3`² |
|3 |14 | | |`E10` |`F4`² |
|3 |15 | | |`E11` |`F5`² |
|3 |16 | | |`E12` | |
|4 |1 | | |`E14` | |
|4 |2 | | |`E15` | |
|4 |3 | | |`B12` | |
|4 |4 | | |`B14` | |
|4 |5 | | |`B15` | |
|4 |6 | | |`E8` | |
|4 |7 | | |`D10` | |
|4 |8 | | |`D11` | |
|4 |9 | | |`D12` | |
|4 |10 | | |`D13` | |
|4 |11 | | |`D14` | |
|4 |12 | | |`D8` | |
|4 |13 | | |`D9` | |
|4 |14 | | | | |
|4 |15 | | | | |
|4 |16 | | | | |
<sup>¹ As of ChibiOS 20.3.4, the ADC driver for STM32F1xx devices supports only ADC1, therefore any configurations involving ADC2 or ADC3 cannot actually be used. In particular, pins `F6``F10`, which are present at least on some STM32F103x[C-G] devices, cannot be used as ADC inputs because of this driver limitation.</sup>
<sup>² Not all STM32F4xx devices have ADC2 and/or ADC3, therefore some configurations shown in this table may be unavailable; in particular, pins `F4``F10` cannot be used as ADC inputs on devices which do not have ADC3. Check the device datasheet to confirm which pin functions are supported.</sup>
#### RP2040
RP2040 has only a single ADC (`ADCD1` in ChibiOS); in the QMK API the index for that ADC is 0.
|Channel|Pin |
|-------|-------------------|
|0 |`GP26` |
|1 |`GP27` |
|2 |`GP28` |
|3 |`GP29` |
|4 |Temperature sensor*|
<sup>* The temperature sensor is disabled by default and needs to be enabled by the RP2040-specific function: `adcRPEnableTS(&ADCD1)`. The ADC must be initialized before calling that function; an easy way to ensure that is to perform a dummy conversion.</sup>
## Functions
### AVR
|Function |Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------|
|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `F6` for ADC6 on the ATmega32U4. |
|`pinToMux(pin)` |Translates a given pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. |
### ARM
|Function |Description |
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.|
|`analogReadPinAdc(pin, adc)`|Reads the value from the specified pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function. |
|`pinToMux(pin)` |Translates a given pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and ADC combination. See your MCU's datasheet for more information. |
## Configuration
## ARM
The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options.
|`#define` |Type |Default |Description |
|---------------------|------|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |If `true`, then the implementation will use a circular buffer. |
|`ADC_NUM_CHANNELS` |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`. |
|`ADC_BUFFER_DEPTH` |`int` |`2` |Sets the depth of each result. Since we are only getting a 10-bit result by default, we set this to 2 bytes so we can contain our one value. This could be set to 1 if you opt for an 8-bit or lower result.|
|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. |
|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_10BIT` or `ADC_CFGR_RES_10BITS`|The resolution of your result. We choose 10 bit by default, but you can opt for 12, 10, 8, or 6 bit. Different MCUs use slightly different names for the resolution constants. |

View File

@@ -1,49 +0,0 @@
# APA102 Driver {#apa102-driver}
This driver provides support for APA102 addressable RGB LEDs. They are similar to the [WS2812](ws2812_driver) LEDs, but have increased data and refresh rates.
## Usage {#usage}
In most cases, the APA102 driver code is automatically included if you are using either the [RGBLight](feature_rgblight) or [RGB Matrix](feature_rgb_matrix) feature with the `apa102` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
APA102_DRIVER_REQUIRED = yes
```
You can then call the APA102 API by including `apa102.h` in your code.
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|---------------------------|-------------|------------------------------------------------------------------|
|`APA102_DI_PIN` |*Not defined*|The GPIO pin connected to the DI pin of the first LED in the chain|
|`APA102_CI_PIN` |*Not defined*|The GPIO pin connected to the CI pin of the first LED in the chain|
|`APA102_DEFAULT_BRIGHTNESS`|`31` |The default global brightness level of the LEDs, from 0 to 31 |
## API {#api}
### `void apa102_setleds(rgb_led_t *start_led, uint16_t num_leds)`
Send RGB data to the APA102 LED chain.
#### Arguments {#api-apa102-setleds-arguments}
- `rgb_led_t *start_led`
A pointer to the LED array.
- `uint16_t num_leds`
The length of the LED array.
---
### `void apa102_set_brightness(uint8_t brightness)`
Set the global brightness.
#### Arguments {#api-apa102-set-brightness-arguments}
- `uint8_t brightness`
The brightness level to set, from 0 to 31.

View File

@@ -1,239 +0,0 @@
# Audio Driver {#audio-driver}
The [Audio feature](feature_audio) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.
Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.
## AVR {#avr}
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
The possible configurations are:
| | Timer3 | Timer1 |
|--------------|-------------|--------------|
| one speaker | C4,C5 or C6 | |
| one speaker | | B4, B5 or B7 |
| two speakers | C4,C5 or C6 | B4, B5 or B7 |
Currently there is only one/default driver for AVR based boards, which is automatically configured to:
```make
AUDIO_DRIVER = pwm_hardware
```
## ARM {#arm}
For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.
Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below;
piezo speakers are marked with :one: for the first/primary and :two: for the secondary.
| driver | GPTD6<br>Tim6 | GPTD7<br>Tim7 | GPTD8<br>Tim8 | PWMD1<sup>1</sup><br>Tim1_Ch1 |
|--------------|------------------------------------------|------------------------|---------------|-------------------------------|
| dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | |
| | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | |
| | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | |
| | A4+DACD1 = :one: + Gnd | | state | |
| | | A5+DACD2 = :one: + Gnd | state | |
| dac_additive | A4+DACD1 = :one: + Gnd | | | |
| | A5+DACD2 = :one: + Gnd | | | |
| | A4+DACD1 + A5+DACD2 = :one: <sup>2</sup> | | | |
| pwm_software | state-update | | | any = :one: |
| pwm hardware | state-update | | | A8 = :one: <sup>3</sup> |
<sup>1</sup>: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet
<sup>2</sup>: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set
<sup>3</sup>: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL
### DAC basic {#dac-basic}
The default driver for ARM boards, in absence of an overriding configuration.
This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
#undef STM32_GPT_USE_TIM7
#define STM32_GPT_USE_TIM7 TRUE
#undef STM32_GPT_USE_TIM8
#define STM32_GPT_USE_TIM8 TRUE
```
::: tip
Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
:::
You can also change the timer used for the overall audio state by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD9
```
### DAC additive {#dac-additive}
only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
```
### DAC Config
| Define | Defaults | Description |
| -------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. |
| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when not playing anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. |
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
| `AUDIO_DAC_BUFFER_SIZE` | __see next table__ | Number of samples generated every refill. Too few may cause excessive CPU load; too many may cause freezes, RAM or flash exhaustion or lags during matrix scanning. |
There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate, number of simultaneous tones and buffer size, instead of using one of the listed presets.
| Define | Sample Rate | Simultaneous tones | Buffer size |
| --------------------------------- | ----------- | ------------------- | ----------- |
| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` | `64U` |
| `AUDIO_DAC_QUALITY_LOW` | `22050U` | `4` | `128U` |
| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` | `256U` |
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | `256U` |
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | `64U` |
#### Notes on buffer size {#buffer-size}
By default, the buffer size attempts to keep to these constraints:
* The interval between buffer refills can't be too short, since the microcontroller would then only be servicing buffer refills and would freeze up.
* On the additive driver, the interval between buffer refills can't be too long, since matrix scanning would suffer lengthy pauses every so often, which would delay key presses or releases or lose some short taps altogether.
* The interval between buffer refills is kept to a minimum, which allows notes to stop as soon as possible after they should.
* For greater compatibility, the buffer size should be a power of 2.
* The buffer size being too large causes resource exhaustion leading to build failures or freezing at runtime: RAM usage (on the additive driver) or flash usage (on the basic driver).
You can lower the buffer size if you need a bit more space in your firmware, or raise it if your keyboard freezes up.
```c
/* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX)
* ============================*=*========================== AUDIO_DAC_SAMPLE_MAX
* * *
* * *
* ---------------------------------------------------------
* * * } AUDIO_DAC_SAMPLE_MAX/100
* --------------------------------------------------------- AUDIO_DAC_OFF_VALUE
* * * } AUDIO_DAC_SAMPLE_MAX/100
* ---------------------------------------------------------
* *
* * *
* * *
* =====*=*================================================= 0x0
*/
```
### PWM hardware {#pwm-hardware}
This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware.
The hardware directly toggles the pin via its alternate function. See your 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:
```c
//halconf.h:
#define HAL_USE_PWM TRUE
#define HAL_USE_PAL TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE
```
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_CH2 = PA9
- TIM1_CH3 = PA10
- TIM1_CH4 = PA11
with all this information, the configuration would contain these lines:
```c
//config.h:
#define AUDIO_PIN A8
#define AUDIO_PWM_DRIVER PWMD1
#define AUDIO_PWM_CHANNEL 1
```
ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function.
On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PAL_MODE` to the correct alternate function for the selected pin, timer and timer-channel.
You can also use the Complementary output (`TIMx_CHyN`) for PWM on supported controllers. To enable this functionality, you will need to make the following changes:
```c
// config.h:
#define AUDIO_PWM_COMPLEMENTARY_OUTPUT
```
### PWM software {#pwm-software}
This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software.
During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).
You can also change the timer used for software PWM by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD8
```
### Testing Notes {#testing-notes}
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | DAC basic | DAC additive | PWM hardware | PWM software |
| ------------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: |
| RP2040 | :x: | :x: | :heavy_check_mark: | ? |
| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: |
| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| L0xx | :x: (no Tim8) | ? | ? | ? |
:heavy_check_mark: : works and was tested
:o: : does not apply
:x: : not supported by MCU
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*

View File

@@ -10,25 +10,25 @@ Practically, this means QMK merges the `develop` branch into the `master` branch
## What has been included in past Breaking Changes?
* [2024 Aug 25](ChangeLog/20240825)
* [2024 May 26](ChangeLog/20240526)
* [2024 Feb 25](ChangeLog/20240225)
* [2023 Nov 26](ChangeLog/20231126)
* [Older Breaking Changes](breaking_changes_history)
## When is the next Breaking Change?
The next Breaking Change is scheduled for August 25, 2024.
The next Breaking Change is scheduled for November 24, 2024.
### Important Dates
* 2024 May 26 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
* 2024 Jul 28 - `develop` closed to new PRs.
* 2024 Jul 28 - Call for testers.
* 2024 Aug 4 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
* 2024 Aug 18 - `develop` is locked, only critical bugfix PRs merged.
* 2024 Aug 22 - `master` is locked, no PRs merged.
* 2024 Aug 25 - Merge `develop` to `master`.
* 2024 Aug 25 - `master` is unlocked. PRs can be merged again.
* 2024 Aug 25 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
* 2024 Oct 27 - `develop` closed to new PRs.
* 2024 Oct 27 - Call for testers.
* 2024 Nov 10 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
* 2024 Nov 17 - `develop` is locked, only critical bugfix PRs merged.
* 2024 Nov 22 - `master` is locked, no PRs merged.
* 2024 Nov 24 - Merge `develop` to `master`.
* 2024 Nov 24 - `master` is unlocked. PRs can be merged again.
## What changes will be included?
@@ -48,7 +48,7 @@ Criteria for acceptance:
Strongly suggested:
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20240526`.
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20241124`.
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PRs ID.
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.

View File

@@ -2,6 +2,7 @@
This page links to all previous changelogs from the QMK Breaking Changes process.
* [2024 Aug 25](ChangeLog/20240825) - version 0.26.0
* [2024 May 26](ChangeLog/20240526) - version 0.25.0
* [2024 Feb 25](ChangeLog/20240225) - version 0.24.0
* [2023 Nov 26](ChangeLog/20231126) - version 0.23.0

View File

@@ -31,4 +31,4 @@ Commenting on your pull request and being responsive to questions, comments, and
### Ask for Help
Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/Uq7gcHh).
Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/qmk).

View File

@@ -749,7 +749,7 @@ options:
## `qmk generate-rgb-breathe-table`
This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
This command generates a lookup table (LUT) header file for the [RGB Lighting](features/rgblight) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
**Usage**:

View File

@@ -207,7 +207,7 @@ qmk format-python
We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`.
::: tip
Tip- Many editors can use yapf as a plugin to automatically format code as you type.
Many editors can use yapf as a plugin to automatically format code as you type.
:::
## Testing Details
@@ -217,7 +217,7 @@ Our tests can be found in `lib/python/qmk/tests/`. You will find both unit and i
If your PR does not include a comprehensive set of tests please add comments like this to your code so that other people know where they can help:
```python
# TODO(unassigned/<your_github_username>): Write <unit|integration> tests
# TODO(unassigned/<your_github_username>): Write <unit|integration> tests
```
We use [nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) to run our tests. You can refer to the nose2 documentation for more details on what you can do in your test functions.

View File

@@ -207,7 +207,7 @@ If you define these options you will enable the associated feature, which may in
* `#define TAP_HOLD_CAPS_DELAY 80`
* Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPS_LOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher.
* `#define KEY_OVERRIDE_REPEAT_DELAY 500`
* Sets the key repeat interval for [key overrides](feature_key_overrides).
* Sets the key repeat interval for [key overrides](features/key_overrides).
* `#define LEGACY_MAGIC_HANDLING`
* Enables magic configuration handling for advanced keycodes (such as Mod Tap and Layer Tap)
@@ -217,14 +217,14 @@ If you define these options you will enable the associated feature, which may in
* `#define WS2812_DI_PIN D7`
* pin the DI on the WS2812 is hooked-up to
* `#define RGBLIGHT_LAYERS`
* Lets you define [lighting layers](feature_rgblight#lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
* Lets you define [lighting layers](features/rgblight#lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
* `#define RGBLIGHT_MAX_LAYERS`
* Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight#lighting-layers) are needed.
* Defaults to 8. Can be expanded up to 32 if more [lighting layers](features/rgblight#lighting-layers) are needed.
* Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards.
* `#define RGBLIGHT_LAYER_BLINK`
* Adds ability to [blink](feature_rgblight#lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
* Adds ability to [blink](features/rgblight#lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF`
* If defined, then [lighting layers](feature_rgblight#overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off.
* If defined, then [lighting layers](features/rgblight#overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off.
* `#define RGBLIGHT_LED_COUNT 12`
* number of LEDs
* `#define RGBLIGHT_SPLIT`
@@ -358,7 +358,7 @@ There are a few different ways to set handedness for split keyboards (listed in
* `#define SPLIT_TRANSACTION_IDS_KB .....`
* `#define SPLIT_TRANSACTION_IDS_USER .....`
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard#custom-data-sync) for more information.
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](features/split_keyboard#custom-data-sync) for more information.
# The `rules.mk` File
@@ -413,7 +413,7 @@ Use these to enable or disable building certain features. The more you have enab
* `MAGIC_ENABLE`
* MAGIC actions (BOOTMAGIC without the boot)
* `BOOTMAGIC_ENABLE`
* Enable Bootmagic Lite
* Enable Bootmagic
* `MOUSEKEY_ENABLE`
* Mouse keys
* `EXTRAKEY_ENABLE`

View File

@@ -16,7 +16,9 @@ I'll say that again because it's important:
**MAKE SURE YOU SELECT THE RIGHT VERSION!**
:::
If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
Unfortunately if your keyboard has been advertised to be powered by QMK but is not in the list, you will **not** be able to use Configurator to customize your keyboard.
Chances are a developer hasn't gotten round to adding support or we haven't had a chance to merge it in yet. If there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard), contact the manufacturer and encourage them to add support.
## Step 2: Select Your Keyboard Layout

View File

@@ -11,7 +11,7 @@ Third-party contributions help us grow and improve QMK. We want to make the pull
## I Don't Want to Read This Whole Thing! I Just Have a Question!
If you'd like to ask questions about QMK you can do so on the [OLKB Subreddit](https://reddit.com/r/olkb) or on [Discord](https://discord.gg/Uq7gcHh).
If you'd like to ask questions about QMK you can do so on the [OLKB Subreddit](https://reddit.com/r/olkb) or on [Discord](https://discord.gg/qmk).
Please keep these things in mind:
@@ -29,7 +29,7 @@ QMK is largely written in C, with specific features and parts written in C++. It
# Where Can I Go for Help?
If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/issues) or [chat on Discord](https://discord.gg/Uq7gcHh).
If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/issues) or [chat on Discord](https://discord.gg/qmk).
# How Do I Make a Contribution?
@@ -105,7 +105,9 @@ enum my_keycodes {
Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder:
qmk docs
```
qmk docs
```
and navigating to `http://localhost:5173/`.
@@ -126,7 +128,7 @@ We also ask that you follow these guidelines:
Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this:
* [Chat on Discord](https://discord.gg/Uq7gcHh)
* [Chat on Discord](https://discord.gg/qmk)
* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new)
Feature and Bug Fix PRs affect all keyboards. We are also in the process of restructuring QMK. For this reason it is especially important for significant changes to be discussed before implementation has happened. If you open a PR without talking to us first please be prepared to do some significant rework if your choices do not mesh well with our planned direction.

View File

@@ -184,7 +184,7 @@ Whenever possible you should customize your keyboard by using `process_record_*(
### Example `matrix_scan_*` Implementation
This example has been deliberately omitted. You should understand enough about QMK internals to write this without an example before hooking into such a performance sensitive area. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/Uq7gcHh).
This example has been deliberately omitted. You should understand enough about QMK internals to write this without an example before hooking into such a performance sensitive area. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/qmk).
### `matrix_scan_*` Function Documentation
@@ -206,7 +206,7 @@ Similar to `matrix_scan_*`, these are called as often as the MCU can handle. To
### Example `void housekeeping_task_user(void)` implementation
This example will show you how to use `void housekeeping_task_user(void)` to turn off [RGB Light](feature_rgblight). For RGB Matrix, the [builtin](feature_rgb_matrix#additional-configh-options) `RGB_MATRIX_TIMEOUT` should be used.
This example will show you how to use `void housekeeping_task_user(void)` to turn off [RGB Light](features/rgblight). For RGB Matrix, the [builtin](features/rgb_matrix#additional-configh-options) `RGB_MATRIX_TIMEOUT` should be used.
First, add the following lines to your keymap's `config.h`:

View File

@@ -69,4 +69,4 @@ This page describes my cool feature. You can use my cool feature to make coffee
|KC_SUGAR||Order Sugar|
```
Place your documentation into `docs/feature_<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_sidebar.json`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.
Place your documentation into `docs/features/<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_sidebar.json`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.

View File

@@ -8,8 +8,8 @@ We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have
## 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](feature_bootmagic) docs for more details). Some boards use [Command](feature_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](feature_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.
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](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.
Alternatively, hold `BOOT` while inserting the USB cable.
@@ -65,7 +65,7 @@ Run `pnputil /delete-driver oemXX.inf /uninstall`. This will delete the driver a
As with the previous section, this process may need to be repeated multiple times, as multiple drivers can be applicable to the same device.
::: warning
**WARNING:** Be *extremely careful* when doing this! You could potentially uninstall the driver for some other critical device. If you are unsure, double check the output of `/enum-drivers`, and omit the `/uninstall` flag when running `/delete-driver`.
Be *extremely careful* when doing this! You could potentially uninstall the driver for some other critical device. If you are unsure, double check the output of `/enum-drivers`, and omit the `/uninstall` flag when running `/delete-driver`.
:::
## List of Known Bootloaders

173
docs/drivers/adc.md Normal file
View File

@@ -0,0 +1,173 @@
# ADC Driver
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](../features/encoders).
This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision.
## Usage
To use this driver, add the following to your `rules.mk`:
```make
ANALOG_DRIVER_REQUIRED = yes
```
Then place this include at the top of your code:
```c
#include "analog.h"
```
## Channels
### AVR
|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P|
|-------|-------------|-------------|---------|----------|
|0 |`F0` |`F0` |`A0` |`C0` |
|1 |`F1` |`F1` |`A1` |`C1` |
|2 |`F2` | |`A2` |`C2` |
|3 |`F3` | |`A3` |`C3` |
|4 |`F4` |`F4` |`A4` |`C4` |
|5 |`F5` |`F5` |`A5` |`C5` |
|6 |`F6` |`F6` |`A6` |* |
|7 |`F7` |`F7` |`A7` |* |
|8 | |`D4` | | |
|9 | |`D6` | | |
|10 | |`D7` | | |
|11 | |`B4` | | |
|12 | |`B5` | | |
|13 | |`B6` | | |
<sup>\* The ATmega328/P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these.</sup>
### ARM
#### STM32
Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC.
Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-indexed, whereas the F3 has 4 ADCs and the channels are 1-indexed. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation.
|ADC|Channel|STM32F0xx|STM32F1xx|STM32F3xx|STM32F4xx|
|---|-------|---------|---------|---------|---------|
|1 |0 |`A0` |`A0` | |`A0` |
|1 |1 |`A1` |`A1` |`A0` |`A1` |
|1 |2 |`A2` |`A2` |`A1` |`A2` |
|1 |3 |`A3` |`A3` |`A2` |`A3` |
|1 |4 |`A4` |`A4` |`A3` |`A4` |
|1 |5 |`A5` |`A5` |`F4` |`A5` |
|1 |6 |`A6` |`A6` |`C0` |`A6` |
|1 |7 |`A7` |`A7` |`C1` |`A7` |
|1 |8 |`B0` |`B0` |`C2` |`B0` |
|1 |9 |`B1` |`B1` |`C3` |`B1` |
|1 |10 |`C0` |`C0` |`F2` |`C0` |
|1 |11 |`C1` |`C1` | |`C1` |
|1 |12 |`C2` |`C2` | |`C2` |
|1 |13 |`C3` |`C3` | |`C3` |
|1 |14 |`C4` |`C4` | |`C4` |
|1 |15 |`C5` |`C5` | |`C5` |
|1 |16 | | | | |
|2 |0 | |`A0`¹ | |`A0`² |
|2 |1 | |`A1`¹ |`A4` |`A1`² |
|2 |2 | |`A2`¹ |`A5` |`A2`² |
|2 |3 | |`A3`¹ |`A6` |`A3`² |
|2 |4 | |`A4`¹ |`A7` |`A4`² |
|2 |5 | |`A5`¹ |`C4` |`A5`² |
|2 |6 | |`A6`¹ |`C0` |`A6`² |
|2 |7 | |`A7`¹ |`C1` |`A7`² |
|2 |8 | |`B0`¹ |`C2` |`B0`² |
|2 |9 | |`B1`¹ |`C3` |`B1`² |
|2 |10 | |`C0`¹ |`F2` |`C0`² |
|2 |11 | |`C1`¹ |`C5` |`C1`² |
|2 |12 | |`C2`¹ |`B2` |`C2`² |
|2 |13 | |`C3`¹ | |`C3`² |
|2 |14 | |`C4`¹ | |`C4`² |
|2 |15 | |`C5`¹ | |`C5`² |
|2 |16 | | | | |
|3 |0 | |`A0`¹ | |`A0`² |
|3 |1 | |`A1`¹ |`B1` |`A1`² |
|3 |2 | |`A2`¹ |`E9` |`A2`² |
|3 |3 | |`A3`¹ |`E13` |`A3`² |
|3 |4 | |`F6`¹ | |`F6`² |
|3 |5 | |`F7`¹ |`B13` |`F7`² |
|3 |6 | |`F8`¹ |`E8` |`F8`² |
|3 |7 | |`F9`¹ |`D10` |`F9`² |
|3 |8 | |`F10`¹ |`D11` |`F10`² |
|3 |9 | | |`D12` |`F3`² |
|3 |10 | |`C0`¹ |`D13` |`C0`² |
|3 |11 | |`C1`¹ |`D14` |`C1`² |
|3 |12 | |`C2`¹ |`B0` |`C2`² |
|3 |13 | |`C3`¹ |`E7` |`C3`² |
|3 |14 | | |`E10` |`F4`² |
|3 |15 | | |`E11` |`F5`² |
|3 |16 | | |`E12` | |
|4 |1 | | |`E14` | |
|4 |2 | | |`E15` | |
|4 |3 | | |`B12` | |
|4 |4 | | |`B14` | |
|4 |5 | | |`B15` | |
|4 |6 | | |`E8` | |
|4 |7 | | |`D10` | |
|4 |8 | | |`D11` | |
|4 |9 | | |`D12` | |
|4 |10 | | |`D13` | |
|4 |11 | | |`D14` | |
|4 |12 | | |`D8` | |
|4 |13 | | |`D9` | |
|4 |14 | | | | |
|4 |15 | | | | |
|4 |16 | | | | |
<sup>¹ As of ChibiOS 20.3.4, the ADC driver for STM32F1xx devices supports only ADC1, therefore any configurations involving ADC2 or ADC3 cannot actually be used. In particular, pins `F6``F10`, which are present at least on some STM32F103x[C-G] devices, cannot be used as ADC inputs because of this driver limitation.</sup>
<sup>² Not all STM32F4xx devices have ADC2 and/or ADC3, therefore some configurations shown in this table may be unavailable; in particular, pins `F4``F10` cannot be used as ADC inputs on devices which do not have ADC3. Check the device datasheet to confirm which pin functions are supported.</sup>
#### RP2040
RP2040 has only a single ADC (`ADCD1` in ChibiOS); in the QMK API the index for that ADC is 0.
|Channel|Pin |
|-------|-------------------|
|0 |`GP26` |
|1 |`GP27` |
|2 |`GP28` |
|3 |`GP29` |
|4 |Temperature sensor*|
<sup>* The temperature sensor is disabled by default and needs to be enabled by the RP2040-specific function: `adcRPEnableTS(&ADCD1)`. The ADC must be initialized before calling that function; an easy way to ensure that is to perform a dummy conversion.</sup>
## Functions
### AVR
|Function |Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------|
|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `F6` for ADC6 on the ATmega32U4. |
|`pinToMux(pin)` |Translates a given pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. |
### ARM
|Function |Description |
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.|
|`analogReadPinAdc(pin, adc)`|Reads the value from the specified pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function. |
|`pinToMux(pin)` |Translates a given pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and ADC combination. See your MCU's datasheet for more information. |
## Configuration
## ARM
The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options.
|`#define` |Type |Default |Description |
|---------------------|------|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |If `true`, then the implementation will use a circular buffer. |
|`ADC_NUM_CHANNELS` |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`. |
|`ADC_BUFFER_DEPTH` |`int` |`2` |Sets the depth of each result. Since we are only getting a 10-bit result by default, we set this to 2 bytes so we can contain our one value. This could be set to 1 if you opt for an 8-bit or lower result.|
|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. |
|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_10BIT` or `ADC_CFGR_RES_10BITS`|The resolution of your result. We choose 10 bit by default, but you can opt for 12, 10, 8, or 6 bit. Different MCUs use slightly different names for the resolution constants. |

80
docs/drivers/apa102.md Normal file
View File

@@ -0,0 +1,80 @@
# APA102 Driver {#apa102-driver}
This driver provides support for APA102 addressable RGB LEDs. They are similar to the [WS2812](ws2812) LEDs, but have increased data and refresh rates.
## Usage {#usage}
In most cases, the APA102 driver code is automatically included if you are using either the [RGBLight](../features/rgblight) or [RGB Matrix](../features/rgb_matrix) feature with the `apa102` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
APA102_DRIVER_REQUIRED = yes
```
You can then call the APA102 API by including `apa102.h` in your code.
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|---------------------------|-------------|------------------------------------------------------------------|
|`APA102_DI_PIN` |*Not defined*|The GPIO pin connected to the DI pin of the first LED in the chain|
|`APA102_CI_PIN` |*Not defined*|The GPIO pin connected to the CI pin of the first LED in the chain|
|`APA102_DEFAULT_BRIGHTNESS`|`31` |The default global brightness level of the LEDs, from 0 to 31 |
## API {#api}
### `void apa102_init(void)` {#api-apa102-init}
Initialize the LED driver. This function should be called first.
---
### `void apa102_set_color(uint16_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-apa102-set-color}
Set the color of a single LED. This function does not immediately update the LEDs; call `apa102_flush()` after you are finished.
#### Arguments {#api-apa102-set-color-arguments}
- `uint16_t index`
The LED index in the APA102 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 apa102_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-apa102-set-color-all}
Set the color of all LEDs.
#### Arguments {#api-apa102-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 apa102_flush(void)` {#api-apa102-flush}
Flush the PWM values to the LED chain.
---
### `void apa102_set_brightness(uint8_t brightness)` {#api-apa102-set-brightness}
Set the global brightness.
#### Arguments {#api-apa102-set-brightness-arguments}
- `uint8_t brightness`
The brightness level to set, from 0 to 31.

239
docs/drivers/audio.md Normal file
View File

@@ -0,0 +1,239 @@
# Audio Driver {#audio-driver}
The [Audio feature](../features/audio) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.
Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.
## AVR {#avr}
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
The possible configurations are:
| | Timer3 | Timer1 |
|--------------|-------------|--------------|
| one speaker | C4,C5 or C6 | |
| one speaker | | B4, B5 or B7 |
| two speakers | C4,C5 or C6 | B4, B5 or B7 |
Currently there is only one/default driver for AVR based boards, which is automatically configured to:
```make
AUDIO_DRIVER = pwm_hardware
```
## ARM {#arm}
For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.
Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below;
piezo speakers are marked with :one: for the first/primary and :two: for the secondary.
| driver | GPTD6<br>Tim6 | GPTD7<br>Tim7 | GPTD8<br>Tim8 | PWMD1<sup>1</sup><br>Tim1_Ch1 |
|--------------|------------------------------------------|------------------------|---------------|-------------------------------|
| dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | |
| | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | |
| | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | |
| | A4+DACD1 = :one: + Gnd | | state | |
| | | A5+DACD2 = :one: + Gnd | state | |
| dac_additive | A4+DACD1 = :one: + Gnd | | | |
| | A5+DACD2 = :one: + Gnd | | | |
| | A4+DACD1 + A5+DACD2 = :one: <sup>2</sup> | | | |
| pwm_software | state-update | | | any = :one: |
| pwm hardware | state-update | | | A8 = :one: <sup>3</sup> |
<sup>1</sup>: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet
<sup>2</sup>: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set
<sup>3</sup>: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL
### DAC basic {#dac-basic}
The default driver for ARM boards, in absence of an overriding configuration.
This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
#undef STM32_GPT_USE_TIM7
#define STM32_GPT_USE_TIM7 TRUE
#undef STM32_GPT_USE_TIM8
#define STM32_GPT_USE_TIM8 TRUE
```
::: tip
Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
:::
You can also change the timer used for the overall audio state by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD9
```
### DAC additive {#dac-additive}
only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.
Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6:
```c
//halconf.h:
#define HAL_USE_DAC TRUE
#define HAL_USE_GPT TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_DAC_USE_DAC1_CH1
#define STM32_DAC_USE_DAC1_CH1 TRUE
#undef STM32_DAC_USE_DAC1_CH2
#define STM32_DAC_USE_DAC1_CH2 TRUE
#undef STM32_GPT_USE_TIM6
#define STM32_GPT_USE_TIM6 TRUE
```
### DAC Config
| Define | Defaults | Description |
| -------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. |
| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when not playing anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. |
| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. |
| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. |
| `AUDIO_DAC_BUFFER_SIZE` | __see next table__ | Number of samples generated every refill. Too few may cause excessive CPU load; too many may cause freezes, RAM or flash exhaustion or lags during matrix scanning. |
There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate, number of simultaneous tones and buffer size, instead of using one of the listed presets.
| Define | Sample Rate | Simultaneous tones | Buffer size |
| --------------------------------- | ----------- | ------------------- | ----------- |
| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` | `64U` |
| `AUDIO_DAC_QUALITY_LOW` | `22050U` | `4` | `128U` |
| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` | `256U` |
| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | `256U` |
| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | `64U` |
#### Notes on buffer size {#buffer-size}
By default, the buffer size attempts to keep to these constraints:
* The interval between buffer refills can't be too short, since the microcontroller would then only be servicing buffer refills and would freeze up.
* On the additive driver, the interval between buffer refills can't be too long, since matrix scanning would suffer lengthy pauses every so often, which would delay key presses or releases or lose some short taps altogether.
* The interval between buffer refills is kept to a minimum, which allows notes to stop as soon as possible after they should.
* For greater compatibility, the buffer size should be a power of 2.
* The buffer size being too large causes resource exhaustion leading to build failures or freezing at runtime: RAM usage (on the additive driver) or flash usage (on the basic driver).
You can lower the buffer size if you need a bit more space in your firmware, or raise it if your keyboard freezes up.
```c
/* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX)
* ============================*=*========================== AUDIO_DAC_SAMPLE_MAX
* * *
* * *
* ---------------------------------------------------------
* * * } AUDIO_DAC_SAMPLE_MAX/100
* --------------------------------------------------------- AUDIO_DAC_OFF_VALUE
* * * } AUDIO_DAC_SAMPLE_MAX/100
* ---------------------------------------------------------
* *
* * *
* * *
* =====*=*================================================= 0x0
*/
```
### PWM hardware {#pwm-hardware}
This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware.
The hardware directly toggles the pin via its alternate function. See your 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:
```c
//halconf.h:
#define HAL_USE_PWM TRUE
#define HAL_USE_PAL TRUE
#include_next <halconf.h>
```
```c
// mcuconf.h:
#include_next <mcuconf.h>
#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE
```
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_CH2 = PA9
- TIM1_CH3 = PA10
- TIM1_CH4 = PA11
with all this information, the configuration would contain these lines:
```c
//config.h:
#define AUDIO_PIN A8
#define AUDIO_PWM_DRIVER PWMD1
#define AUDIO_PWM_CHANNEL 1
```
ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function.
On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PAL_MODE` to the correct alternate function for the selected pin, timer and timer-channel.
You can also use the Complementary output (`TIMx_CHyN`) for PWM on supported controllers. To enable this functionality, you will need to make the following changes:
```c
// config.h:
#define AUDIO_PWM_COMPLEMENTARY_OUTPUT
```
### PWM software {#pwm-software}
This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software.
During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).
You can also change the timer used for software PWM by defining the driver. For instance:
```c
#define AUDIO_STATE_TIMER GPTD8
```
### Testing Notes {#testing-notes}
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | DAC basic | DAC additive | PWM hardware | PWM software |
| ------------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: |
| RP2040 | :x: | :x: | :heavy_check_mark: | ? |
| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: |
| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| L0xx | :x: (no Tim8) | ? | ? | ? |
:heavy_check_mark: : works and was tested
:o: : does not apply
:x: : not supported by MCU
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*

133
docs/drivers/aw20216s.md Normal file
View File

@@ -0,0 +1,133 @@
# AW20216S Driver {#aw20216s-driver}
SPI 18x12 LED matrix driver by Awinic. Supports a maximum of four drivers, each controlling up to 216 single-color LEDs, or 72 RGB LEDs.
[AW20216S Datasheet](https://doc.awinic.com/doc/20230609wm/b6a9c70b-e1bd-495b-925f-bcbed3fc2620.pdf)
## Usage {#usage}
The AW20216S driver code is automatically included if you are using the [RGB Matrix](../features/rgb_matrix) feature with the `aw20216s` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led
SRC += aw20216s.c
SPI_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|-----------------------------|-------------|-------------------------------------------------------------|
|`AW20216S_CS_PIN_1` |*Not defined*|The GPIO pin connected to the first driver's Chip Select pin |
|`AW20216S_CS_PIN_2` |*Not defined*|The GPIO pin connected to the second driver's Chip Select pin|
|`AW20216S_EN_PIN` |*Not defined*|The GPIO pin connected to the drivers' Enable pins |
|`AW20216S_SPI_MODE` |`0` |The SPI mode to use |
|`AW20216S_SPI_DIVISOR` |`4` |The SPI divisor to use |
|`AW20216S_SCALING_MAX` |`150` |The scaling value |
|`AW20216S_GLOBAL_CURRENT_MAX`|`150` |The global current control value |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. To adjust it, add the following to your `config.h`:
```c
#define AW20216S_GLOBAL_CURRENT_MAX 150
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure SPI](spi#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const aw20216s_led_t PROGMEM g_aw20216s_leds[AW20216S_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the first LED index on driver 0 has its red channel on `SW1_CS1`, green on `SW1_CS2` and blue on `SW1_CS3`.
These values correspond to the matrix locations as shown in the datasheet on page 16, figure 16.
## API {#api}
### `struct aw20216s_led_t` {#api-aw20216s-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-aw20216s-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel.
- `uint8_t g`
The output PWM register address for the LED's green channel.
- `uint8_t b`
The output PWM register address for the LED's blue channel.
---
### `void aw20216s_init(pin_t cs_pin)` {#api-aw20216s-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-aw20216s-init-arguments}
- `pin_t cs_pin`
The GPIO connected to the Chip Select pin of the LED driver to initialize.
---
### `void aw20216s_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-aw20216s-set-color}
Set the color of a single LED. This function does not immediately update the LEDs; call `aw20216s_update_pwm_buffers()` after you are finished.
#### Arguments {#api-aw20216s-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_aw20216s_leds` array).
- `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 aw20216s_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-aw20216s-set-color-all}
Set the color of all LEDs.
#### Arguments {#api-aw20216s-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 aw20216s_update_pwm_buffers(pin_t cs_pin, uint8_t index)` {#api-aw20216s-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-aw20216s-update-pwm-buffers-arguments}
- `pin_t cs_pin`
The GPIO connected to the Chip Select pin of the driver.
- `uint8_t index`
The index of the driver.

181
docs/drivers/eeprom.md Normal file
View File

@@ -0,0 +1,181 @@
# EEPROM Driver Configuration {#eeprom-driver-configuration}
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
Selecting the EEPROM driver is done in your keyboard's `rules.mk`:
Driver | Description
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
## Vendor Driver Configuration {#vendor-eeprom-driver-configuration}
#### STM32 L0/L1 Configuration {#stm32l0l1-eeprom-driver-configuration}
::: warning
Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
:::
`config.h` override | Description | Default Value
------------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------
`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled.
## I2C Driver Configuration {#i2c-eeprom-driver-configuration}
Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
`config.h` override | Description | Default Value
------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------
`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000
`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)`
`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
`#define EXTERNAL_EEPROM_WP_PIN` | If defined the WP pin will be toggled appropriately when writing to the EEPROM. | _none_
Some I2C EEPROM manufacturers explicitly recommend against hardcoding the WP pin to ground. This is in order to protect the eeprom memory content during power-up/power-down/brown-out conditions at low voltage where the eeprom is still operational, but the i2c master output might be unpredictable. If a WP pin is configured, then having an external pull-up on the WP pin is recommended.
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
Alternatively, there are pre-defined hardware configurations for available chips/modules:
Module | Equivalent `#define` | Source
-----------------|---------------------------------|------------------------------------------
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
24LC32A EEPROM | `#define EEPROM_I2C_24LC32A` | <https://www.microchip.com/en-us/product/24LC32A>
24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/en-us/product/24LC64>
24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/en-us/product/24LC128>
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
::: tip
If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
:::
## SPI Driver Configuration {#spi-eeprom-driver-configuration}
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
`config.h` override | Default Value | Description
-----------------------------------------------|---------------|-------------------------------------------------------------------------------------
`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | _none_ | SPI Slave select pin in order to inform that the EEPROM is currently being addressed
`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | `64` | Clock divisor used to divide the peripheral clock to derive the SPI frequency
`#define EXTERNAL_EEPROM_BYTE_COUNT` | `8192` | Total size of the EEPROM in bytes
`#define EXTERNAL_EEPROM_PAGE_SIZE` | `32` | Page size of the EEPROM in bytes, as specified in the datasheet
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | `2` | The number of bytes to transmit for the memory location within the EEPROM
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_spi.h`.
Alternatively, there are pre-defined hardware configurations for available chips/modules:
Module | Equivalent `#define` | Source
-----------------|---------------------------------|------------------------------------------
MB85RS64V FRAM | `define EEPROM_SPI_MB85RS64V` | <https://www.adafruit.com/product/1897>
::: warning
There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
:::
## Transient Driver configuration {#transient-eeprom-driver-configuration}
The only configurable item for the transient EEPROM driver is its size:
`config.h` override | Description | Default Value
------------------------------- | ----------------------------------------- | -------------
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
## Wear-leveling Driver Configuration {#wear_leveling-eeprom-driver-configuration}
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
# Wear-leveling Configuration {#wear_leveling-configuration}
The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
Driver | Description
----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU.
`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals.
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
::: warning
All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
:::
## Wear-leveling Embedded Flash Driver Configuration {#wear_leveling-efl-driver-configuration}
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
---------------------------------------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration.
`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting.
`#define WEAR_LEVELING_EFL_OMIT_LAST_SECTOR_COUNT` | `0` | Number of sectors to omit at the end of the flash. These sectors will not be allocated to the driver and the usable flash block will be offset, but keeping the set flash size. Useful on devices with bootloaders requiring a check flag at the end of flash to be present in order to confirm a valid, bootable firmware.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `(backing_size/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
::: warning
If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
:::
## Wear-leveling SPI Flash Driver Configuration {#wear_leveling-flash_spi-driver-configuration}
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash) documentation for more information.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
----------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB.
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
::: warning
There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
:::
## Wear-leveling RP2040 Driver Configuration {#wear_leveling-rp2040-driver-configuration}
This driver performs writes to the same underlying storage that the RP2040 executes its code.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
------------------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board.
`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `(backing_size/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
## Wear-leveling Legacy EEPROM Emulation Driver Configuration {#wear_leveling-legacy-driver-configuration}
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
By default, `1024` bytes of emulated EEPROM is provided:
MCU | EEPROM Provided | Flash Used
----------|-----------------|--------------
STM32F042 | `1024` bytes | `2048` bytes
STM32F070 | `1024` bytes | `2048` bytes
STM32F072 | `1024` bytes | `2048` bytes
STM32F401 | `1024` bytes | `16384` bytes
STM32F411 | `1024` bytes | `16384` bytes
Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code.

290
docs/drivers/i2c.md Normal file
View File

@@ -0,0 +1,290 @@
# I2C Master Driver {#i2c-master-driver}
The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
## Usage {#usage}
In most cases, the I2C Master driver code is automatically included if you are using a feature or driver which requires it, such as [OLED](../features/oled_driver).
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
I2C_DRIVER_REQUIRED = yes
```
You can then call the I2C API by including `i2c_master.h` in your code.
## I2C Addressing {#note-on-i2c-addresses}
All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed
on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be
shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`.
You can either do this on each call to the functions below, or once in your definition of the address. For example, if your device has an address of `0x18`:
```c
#define MY_I2C_ADDRESS (0x18 << 1)
```
See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
## AVR Configuration {#avr-configuration}
The following defines can be used to configure the I2C master driver:
|`config.h` Override|Description |Default |
|-------------------|---------------------|--------|
|`F_SCL` |Clock frequency in Hz|`400000`|
No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU:
|MCU |`SCL`|`SDA`|
|------------------|-----|-----|
|ATmega16/32U4 |`D0` |`D1` |
|AT90USB64/128 |`D0` |`D1` |
|ATmega32A |`C0` |`C1` |
|ATmega328/P |`C5` |`C4` |
::: tip
The ATmega16/32U2 does not possess I2C functionality, and so cannot use this driver.
:::
## ChibiOS/ARM Configuration {#arm-configuration}
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:
```c
#define HAL_USE_I2C TRUE
```
Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example:
```c
#undef STM32_I2C_USE_I2C2
#define STM32_I2C_USE_I2C2 TRUE
```
|`mcuconf.h` Setting |Description |Default|
|----------------------------|----------------------------------------------------------------------------------|-------|
|`STM32_I2C_BUSY_TIMEOUT` |Time in milliseconds until the I2C command is aborted if no response is received |`50` |
|`STM32_I2C_XXX_IRQ_PRIORITY`|Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING) |`10` |
|`STM32_I2C_USE_DMA` |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit|`TRUE` |
|`STM32_I2C_XXX_DMA_PRIORITY`|Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING) |`1` |
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.
|`config.h` Overrride |Description |Default|
|------------------------|--------------------------------------------------------------|-------|
|`I2C_DRIVER` |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc. |`I2CD1`|
|`I2C1_SCL_PIN` |The pin definition for SCL |`B6` |
|`I2C1_SCL_PAL_MODE` |The alternate function mode for SCL |`4` |
|`I2C1_SDA_PIN` |The pin definition for SDA |`B7` |
|`I2C1_SDA_PAL_MODE` |The alternate function mode for SDA |`4` |
The following configuration values depend on the specific MCU in use.
### I2Cv1 {#arm-configuration-i2cv1}
* STM32F1xx
* STM32F2xx
* STM32F4xx
* STM32L0xx
* STM32L1xx
See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#7_I2Cv1_configuration_structure) for the I2Cv1 configuration structure.
|`config.h` Override|Default |
|-------------------|----------------|
|`I2C1_OPMODE` |`OPMODE_I2C` |
|`I2C1_CLOCK_SPEED` |`100000` |
|`I2C1_DUTY_CYCLE` |`STD_DUTY_CYCLE`|
### I2Cv2 {#arm-configuration-i2cv2}
* STM32F0xx
* STM32F3xx
* STM32F7xx
* STM32L4xx
See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#8_I2Cv2_I2Cv3_configuration_structure) for the I2Cv2 configuration structure.
|`config.h` Override |Default|
|---------------------|-------|
|`I2C1_TIMINGR_PRESC` |`0U` |
|`I2C1_TIMINGR_SCLDEL`|`7U` |
|`I2C1_TIMINGR_SDADEL`|`0U` |
|`I2C1_TIMINGR_SCLH` |`38U` |
|`I2C1_TIMINGR_SCLL` |`129U` |
## API {#api}
### `void i2c_init(void)` {#api-i2c-init}
Initialize the I2C driver. This function must be called only once, before any of the below functions can be called.
This function is weakly defined, meaning it can be overridden if necessary for your particular use case:
```c
void i2c_init(void) {
gpio_set_pin_input(B6); // Try releasing special pins for a short time
gpio_set_pin_input(B7);
wait_ms(10); // Wait for the release to happen
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function
}
```
---
### `i2c_status_t i2c_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)` {#api-i2c-transmit}
Send multiple bytes to the selected I2C device.
#### Arguments {#api-i2c-transmit-arguments}
- `uint8_t address`
The 7-bit I2C address of the device.
- `uint8_t *data`
A pointer to the data to transmit.
- `uint16_t length`
The number of bytes to write. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-transmit-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-receive}
Receive multiple bytes from the selected I2C device.
#### Arguments {#api-i2c-receive-arguments}
- `uint8_t address`
The 7-bit I2C address of the device.
- `uint8_t *data`
A pointer to the buffer to read into.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-receive-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register}
Writes to a register with an 8-bit address on the I2C device.
#### Arguments {#api-i2c-write-register-arguments}
- `uint8_t devaddr`
The 7-bit I2C address of the device.
- `uint8_t regaddr`
The register address to write to.
- `uint8_t *data`
A pointer to the data to transmit.
- `uint16_t length`
The number of bytes to write. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-write-register-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-write-register16}
Writes to a register with a 16-bit address (big endian) on the I2C device.
#### Arguments {#api-i2c-write-register16-arguments}
- `uint8_t devaddr`
The 7-bit I2C address of the device.
- `uint16_t regaddr`
The register address to write to.
- `uint8_t *data`
A pointer to the data to transmit.
- `uint16_t length`
The number of bytes to write. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-write-register16-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-read-register}
Reads from a register with an 8-bit address on the I2C device.
#### Arguments {#api-i2c-read-register-arguments}
- `uint8_t devaddr`
The 7-bit I2C address of the device.
- `uint8_t regaddr`
The register address to read from.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-read-register-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` {#api-i2c-read-register16}
Reads from a register with a 16-bit address (big endian) on the I2C device.
#### Arguments {#api-i2c-read-register16-arguments}
- `uint8_t devaddr`
The 7-bit I2C address of the device.
- `uint16_t regaddr`
The register address to read from.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value {#api-i2c-read-register16-return}
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.
---
### `i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout)` {#api-i2c-ping-address}
Pings the I2C bus for a specific address.
On ChibiOS a "best effort" attempt is made by reading a single byte from register 0 at the requested address. This should generally work except for I2C devices that do not not respond to a register 0 read request, which will result in a false negative result (unsucessful response to ping attempt).
This function is weakly defined, meaning it can be overridden if necessary for your particular use case:
#### Arguments
- `uint8_t address`
The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically).
- `uint16_t timeout`
The time in milliseconds to wait for a response from the target device.
#### Return Value
`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`.

194
docs/drivers/is31fl3218.md Normal file
View File

@@ -0,0 +1,194 @@
# IS31FL3218 Driver {#is31fl3218-driver}
I²C LED driver by Lumissil. Supports up to 18 single-color LEDs, or 6 RGB LEDs.
[IS31FL3218 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3218_DS.pdf)
## Usage {#usage}
The IS31FL3218 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3218` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3218-mono.c # For single-color
SRC += is31fl3218.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|-------------|---------------------------------------------------|
|`IS31FL3218_SDB_PIN` |*Not defined*|The GPIO pin connected to the driver's shutdown pin|
|`IS31FL3218_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3218_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
### I²C Addressing {#i2c-addressing}
The IS31FL3218's 7-bit I²C address is `0x54`, available as `IS31FL3218_I2C_ADDRESS`.
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3218_led_t PROGMEM g_is31fl3218_leds[IS31FL3218_LED_COUNT] = {
/* R G B */
{OUT1, OUT2, OUT3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index all have their anodes connected to `VCC`, and their cathodes on the `OUT1`, `OUT2` and `OUT3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3218_led_t PROGMEM g_is31fl3218_leds[IS31FL3218_LED_COUNT] = {
/* V */
{OUT1},
// etc...
};
```
## API {#api}
### `struct is31fl3218_led_t` {#api-is31fl3218-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3218-led-t-members}
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3218_init(void)` {#api-is31fl3218-init}
Initialize the LED driver. This function should be called first.
---
### `void is31fl3218_write_register(uint8_t reg, uint8_t data)` {#api-is31fl3218-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3218-write-register-arguments}
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3218-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3218_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3218-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3218_leds` array).
- `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 is31fl3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3218-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3218-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 is31fl3218_set_value(int index, uint8_t value)` {#api-is31fl3218-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3218_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3218-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3218_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3218_set_value_all(uint8_t value)` {#api-is31fl3218-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3218-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3218_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3218-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3218_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3218-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3218_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3218_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3218-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3218_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3218-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3218_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3218_update_pwm_buffers(void)` {#api-is31fl3218-update-pwm-buffers}
Flush the PWM values to the LED driver.
---
### `void is31fl3218_update_led_control_registers(void)` {#api-is31fl3218-update-led-control-registers}
Flush the LED control register values to the LED driver.

228
docs/drivers/is31fl3236.md Normal file
View File

@@ -0,0 +1,228 @@
# IS31FL3236 Driver {#is31fl3236-driver}
I²C LED driver by Lumissil. Supports a maximum of four drivers, each controlling up to 36 single-color LEDs, or 12 RGB LEDs.
[IS31FL3236 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3236_DS.pdf)
## Usage {#usage}
The IS31FL3236 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3236` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3236-mono.c # For single-color
SRC += is31fl3236.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|-------------|----------------------------------------------------|
|`IS31FL3236_SDB_PIN` |*Not defined*|The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3236_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3236_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3236_I2C_ADDRESS_1` |*Not defined*|The I²C address of driver 0 |
|`IS31FL3236_I2C_ADDRESS_2` |*Not defined*|The I²C address of driver 1 |
|`IS31FL3236_I2C_ADDRESS_3` |*Not defined*|The I²C address of driver 2 |
|`IS31FL3236_I2C_ADDRESS_4` |*Not defined*|The I²C address of driver 3 |
### I²C Addressing {#i2c-addressing}
The IS31FL3236 has four possible 7-bit I²C addresses, depending on how the `AD` pin is connected.
To configure this, set the `IS31FL3236_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|----------------------------|------|
|`IS31FL3236_I2C_ADDRESS_GND`|`0x3C`|
|`IS31FL3236_I2C_ADDRESS_SCL`|`0x3D`|
|`IS31FL3236_I2C_ADDRESS_SDA`|`0x3E`|
|`IS31FL3236_I2C_ADDRESS_VCC`|`0x3F`|
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3236_led_t PROGMEM g_is31fl3236_leds[IS31FL3236_LED_COUNT] = {
/* Driver
| R G B */
{0, OUT1, OUT2, OUT3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to `VCC`, and their cathodes on the `OUT1`, `OUT2` and `OUT3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3236_led_t PROGMEM g_is31fl3236_leds[IS31FL3236_LED_COUNT] = {
/* Driver
| V */
{0, OUT1},
// etc...
};
```
## API {#api}
### `struct is31fl3236_led_t` {#api-is31fl3236-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3236-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3236_init(uint8_t index)` {#api-is31fl3236-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3236-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3236_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3236-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3236-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3236_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3236-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3236_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3236-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3236_leds` array).
- `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 is31fl3236_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3236-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3236-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 is31fl3236_set_value(int index, uint8_t value)` {#api-is31fl3236-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3236_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3236-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3236_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3236_set_value_all(uint8_t value)` {#api-is31fl3236-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3236-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3236_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3236-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3236_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3236-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3236_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3236_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3236-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3236_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3236-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3236_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3236_update_pwm_buffers(uint8_t index)` {#api-is31fl3236-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3236-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3236_update_led_control_registers(uint8_t index)` {#api-is31fl3236-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3236-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

300
docs/drivers/is31fl3729.md Normal file
View File

@@ -0,0 +1,300 @@
# IS31FL3729 Driver {#is31fl3729-driver}
I²C 16x8/15x9 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 135 single-color LEDs, or 45 RGB LEDs.
[IS31FL3729 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3729_DS.pdf)
## Usage {#usage}
The IS31FL3729 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3729` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3729-mono.c # For single-color
SRC += is31fl3729.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|--------------------------------------|----------------------------------------------------|
|`IS31FL3729_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3729_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3729_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3729_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3729_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3729_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3729_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3729_PWM_FREQUENCY` |`IS31FL3729_PWM_FREQUENCY_32K_HZ` |The PWM frequency of the LEDs |
|`IS31FL3729_SW_PULLDOWN` |`IS31FL3729_SW_PULLDOWN_2K_OHM_SW_OFF`|The `SWx` pullup resistor value |
|`IS31FL3729_CS_PULLUP` |`IS31FL3729_CS_PULLUP_2K_OHM_CS_OFF` |The `CSx` pulldown resistor value |
|`IS31FL3729_GLOBAL_CURRENT` |`0x40` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3729 has four possible 7-bit I²C addresses, depending on how the `AD` pin is connected.
To configure this, set the `IS31FL3729_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|----------------------------|------|
|`IS31FL3729_I2C_ADDRESS_GND`|`0x34`|
|`IS31FL3729_I2C_ADDRESS_SCL`|`0x35`|
|`IS31FL3729_I2C_ADDRESS_SDA`|`0x36`|
|`IS31FL3729_I2C_ADDRESS_VCC`|`0x37`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted by adding the following to your `config.h`:
```c
#define IS31FL3729_PWM_FREQUENCY IS31FL3729_PWM_FREQUENCY_32K_HZ
```
Valid values are:
|Define |Frequency |
|----------------------------------|----------------|
|`IS31FL3729_PWM_FREQUENCY_55K_HZ` |55 kHz |
|`IS31FL3729_PWM_FREQUENCY_32K_HZ` |32 kHz (default)|
|`IS31FL3729_PWM_FREQUENCY_4K_HZ` |4 kHz |
|`IS31FL3729_PWM_FREQUENCY_2K_HZ` |2 kHz |
|`IS31FL3729_PWM_FREQUENCY_1K_HZ` |1 kHz |
|`IS31FL3729_PWM_FREQUENCY_500_HZ` |500 Hz |
|`IS31FL3729_PWM_FREQUENCY_250_HZ` |250 Hz |
|`IS31FL3729_PWM_FREQUENCY_80K_HZ` |80 kHz |
### De-Ghosting {#de-ghosting}
These settings control the pulldown and pullup resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 18) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3729_SW_PULLDOWN IS31FL3729_SW_PULLDOWN_2K_OHM_SW_OFF
#define IS31FL3729_CS_PULLUP IS31FL3729_CS_PULLUP_2K_OHM_CS_OFF
```
Valid values for `IS31FL3729_SW_PULLDOWN` are:
|Define |Resistance |
|---------------------------------------|------------------------------|
|`IS31FL3729_SW_PULLDOWN_0_OHM` |None |
|`IS31FL3729_SW_PULLDOWN_0K5_OHM_SW_OFF`|0.5 kΩ in SWy off time |
|`IS31FL3729_SW_PULLDOWN_1K_OHM_SW_OFF` |1 kΩ in SWy off time |
|`IS31FL3729_SW_PULLDOWN_2K_OHM_SW_OFF` |2 kΩ in SWy off time (default)|
|`IS31FL3729_SW_PULLDOWN_1K_OHM` |1 kΩ |
|`IS31FL3729_SW_PULLDOWN_2K_OHM` |2 kΩ |
|`IS31FL3729_SW_PULLDOWN_4K_OHM` |4 kΩ |
|`IS31FL3729_SW_PULLDOWN_8K_OHM` |8 kΩ |
Valid values for `IS31FL3729_CS_PULLUP` are:
|Define |Resistance |
|-------------------------------------|------------------------------|
|`IS31FL3729_CS_PULLUP_0_OHM` |None |
|`IS31FL3729_CS_PULLUP_0K5_OHM_CS_OFF`|0.5 kΩ in CSx off time |
|`IS31FL3729_CS_PULLUP_1K_OHM_CS_OFF` |1 kΩ in CSx off time |
|`IS31FL3729_CS_PULLUP_2K_OHM_CS_OFF` |2 kΩ in CSx off time (default)|
|`IS31FL3729_CS_PULLUP_1K_OHM` |1 kΩ |
|`IS31FL3729_CS_PULLUP_2K_OHM` |2 kΩ |
|`IS31FL3729_CS_PULLUP_4K_OHM` |4 kΩ |
|`IS31FL3729_CS_PULLUP_8K_OHM` |8 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is 64, but if you need to adjust it, add the following to your `config.h`:
```c
#define IS31FL3729_GLOBAL_CURRENT 0x40
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3729_led_t PROGMEM g_is31fl3729_leds[IS31FL3729_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3729_led_t PROGMEM g_is31fl3729_leds[IS31FL3729_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 12, figure 9.
## API {#api}
### `struct is31fl3729_led_t` {#api-is31fl3729-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3729-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3729_init(uint8_t index)` {#api-is31fl3729-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3729-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3729_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3729-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3729-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3729_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3729-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3729_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3729-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3729_leds` array).
- `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 is31fl3729_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3729-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3729-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 is31fl3729_set_value(int index, uint8_t value)` {#api-is31fl3729-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3729_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3729-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3729_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3729_set_value_all(uint8_t value)` {#api-is31fl3729-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3729-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3729_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3729-set-scaling-register-rgb}
Configure the scaling registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3729_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3729-set-scaling-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3729_leds` array).
- `uint8_t red`
The scaling value for the red channel.
- `uint8_t green`
The scaling value for the green channel.
- `uint8_t blue`
The scaling value for the blue channel.
---
### `void is31fl3729_set_scaling_register(uint8_t index, uint8_t value)` {#api-is31fl3729-set-scaling-register-mono}
Configure the scaling registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3729_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3729-set-scaling-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3729_leds` array).
- `uint8_t value`
The scaling value for the LED.
---
### `void is31fl3729_update_pwm_buffers(uint8_t index)` {#api-is31fl3729-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3729-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3729_update_scaling_registers(uint8_t index)` {#api-is31fl3729-update-scaling-registers}
Flush the scaling register values to the LED driver.
#### Arguments {#api-is31fl3729-update-scaling-registers-arguments}
- `uint8_t index`
The driver index.

254
docs/drivers/is31fl3731.md Normal file
View File

@@ -0,0 +1,254 @@
# IS31FL3731 Driver {#is31fl3731-driver}
I²C Charlieplexed 16x9 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 144 single-color LEDs, or 48 RGB LEDs.
[IS31FL3731 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3731_DS.pdf)
## Usage {#usage}
The IS31FL3731 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3731` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3731-mono.c # For single-color
SRC += is31fl3731.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|-------------|----------------------------------------------------|
|`IS31FL3731_SDB_PIN` |*Not defined*|The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3731_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3731_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3731_I2C_ADDRESS_1` |*Not defined*|The I²C address of driver 0 |
|`IS31FL3731_I2C_ADDRESS_2` |*Not defined*|The I²C address of driver 1 |
|`IS31FL3731_I2C_ADDRESS_3` |*Not defined*|The I²C address of driver 2 |
|`IS31FL3731_I2C_ADDRESS_4` |*Not defined*|The I²C address of driver 3 |
|`IS31FL3731_DEGHOST` |*Not defined*|Enable ghost image prevention |
### I²C Addressing {#i2c-addressing}
The IS31FL3731 has four possible 7-bit I²C addresses, depending on how the `AD` pin is connected.
To configure this, set the `IS31FL3731_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|----------------------------|------|
|`IS31FL3731_I2C_ADDRESS_GND`|`0x74`|
|`IS31FL3731_I2C_ADDRESS_SCL`|`0x75`|
|`IS31FL3731_I2C_ADDRESS_SDA`|`0x76`|
|`IS31FL3731_I2C_ADDRESS_VCC`|`0x77`|
### De-Ghosting {#de-ghosting}
This setting enables the de-ghosting feature on the IS31FL3731. See this [Application Note](https://www.lumissil.com/assets/pdf/core/IS31FL3731_AN.pdf) (p. 15) for more information.
To enable, add the following to your `config.h`:
```c
#define IS31FL3731_DEGHOST
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
/* Driver
* | R G B */
{0, C1_1, C1_2, C1_3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their cathodes connected to the `CA1` pin, and their anodes on the `CA2`, `CA3` and `CA4` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
/* Driver
* | V */
{0, C1_1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 11, figure 8.
## API {#api}
### `struct is31fl3731_led_t` {#api-is31fl3731-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3731-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3731_init(uint8_t index)` {#api-is31fl3731-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3731-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3731-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3731-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3731_select_page(uint8_t index, uint8_t page)` {#api-is31fl3731-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3731-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3731-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3731_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3731-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3731_leds` array).
- `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 is31fl3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3731-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3731-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 is31fl3731_set_value(int index, uint8_t value)` {#api-is31fl3731-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3731_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3731-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3731_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3731_set_value_all(uint8_t value)` {#api-is31fl3731-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3731-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3731-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3731_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3731-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3731_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3731_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3731-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3731_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3731-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3731_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3731_update_pwm_buffers(uint8_t index)` {#api-is31fl3731-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3731-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3731_update_led_control_registers(uint8_t index)` {#api-is31fl3731-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3731-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

338
docs/drivers/is31fl3733.md Normal file
View File

@@ -0,0 +1,338 @@
# IS31FL3733 Driver {#is31fl3733-driver}
I²C 12x16 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 192 single-color LEDs, or 64 RGB LEDs.
[IS31FL3733 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3733_DS.pdf)
## Usage {#usage}
The IS31FL3733 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3733` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3733-mono.c # For single-color
SRC += is31fl3733.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|---------------------------------|----------------------------------------------------|
|`IS31FL3733_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3733_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3733_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3733_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3733_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3733_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3733_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3733_SYNC_1` |`IS31FL3733_SYNC_NONE` |The sync configuration for driver 0 |
|`IS31FL3733_SYNC_2` |`IS31FL3733_SYNC_NONE` |The sync configuration for driver 1 |
|`IS31FL3733_SYNC_3` |`IS31FL3733_SYNC_NONE` |The sync configuration for driver 2 |
|`IS31FL3733_SYNC_4` |`IS31FL3733_SYNC_NONE` |The sync configuration for driver 3 |
|`IS31FL3733_PWM_FREQUENCY` |`IS31FL3733_PWM_FREQUENCY_8K4_HZ`|The PWM frequency of the LEDs (IS31FL3733B only) |
|`IS31FL3733_SW_PULLUP` |`IS31FL3733_PUR_0_OHM` |The `SWx` pullup resistor value |
|`IS31FL3733_CS_PULLDOWN` |`IS31FL3733_PDR_0_OHM` |The `CSx` pulldown resistor value |
|`IS31FL3733_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3733 has 16 possible 7-bit I²C addresses, depending on how the `ADDR1` and `ADDR2` pins are connected.
To configure this, set the `IS31FL3733_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|--------------------------------|------|
|`IS31FL3733_I2C_ADDRESS_GND_GND`|`0x50`|
|`IS31FL3733_I2C_ADDRESS_GND_SCL`|`0x51`|
|`IS31FL3733_I2C_ADDRESS_GND_SDA`|`0x52`|
|`IS31FL3733_I2C_ADDRESS_GND_VCC`|`0x53`|
|`IS31FL3733_I2C_ADDRESS_SCL_GND`|`0x54`|
|`IS31FL3733_I2C_ADDRESS_SCL_SCL`|`0x55`|
|`IS31FL3733_I2C_ADDRESS_SCL_SDA`|`0x56`|
|`IS31FL3733_I2C_ADDRESS_SCL_VCC`|`0x57`|
|`IS31FL3733_I2C_ADDRESS_SDA_GND`|`0x58`|
|`IS31FL3733_I2C_ADDRESS_SDA_SCL`|`0x59`|
|`IS31FL3733_I2C_ADDRESS_SDA_SDA`|`0x5A`|
|`IS31FL3733_I2C_ADDRESS_SDA_VCC`|`0x5B`|
|`IS31FL3733_I2C_ADDRESS_VCC_GND`|`0x5C`|
|`IS31FL3733_I2C_ADDRESS_VCC_SCL`|`0x5D`|
|`IS31FL3733_I2C_ADDRESS_VCC_SDA`|`0x5E`|
|`IS31FL3733_I2C_ADDRESS_VCC_VCC`|`0x5F`|
### Multi-Driver Synchronization {#multi-driver-synchronization}
Multiple IS31FL3733 drivers can be synchronized by connecting the `SYNC` pins together. One driver must be designated as the "master", and the others configured as "slave".
To do this, set the `IS31FL3733_SYNC_n` defines accordingly in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|------------------------|---------------------------|
|`IS31FL3733_SYNC_NONE` |No synchronization |
|`IS31FL3733_SYNC_MASTER`|Driver configured as master|
|`IS31FL3733_SYNC_SLAVE` |Driver configured as slave |
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted (for IS31FL3733B only) by adding the following to your `config.h`:
```c
#define IS31FL3733_PWM_FREQUENCY IS31FL3733_PWM_FREQUENCY_8K4_HZ
```
Valid values are:
|Define |Frequency |
|----------------------------------|-----------------|
|`IS31FL3733_PWM_FREQUENCY_8K4_HZ` |8.4 kHz (default)|
|`IS31FL3733_PWM_FREQUENCY_4K2_HZ` |4.2 kHz |
|`IS31FL3733_PWM_FREQUENCY_26K7_HZ`|26.7 kHz |
|`IS31FL3733_PWM_FREQUENCY_2K1_HZ` |2.1 kHz |
|`IS31FL3733_PWM_FREQUENCY_1K05_HZ`|1.05 kHz |
### De-Ghosting {#de-ghosting}
These settings control the pullup and pulldown resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3733_SW_PULLUP IS31FL3733_PUR_0_OHM
#define IS31FL3733_CS_PULLDOWN IS31FL3733_PUR_0_OHM
```
Valid values for `IS31FL3733_SW_PULLUP` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3733_PUR_0_OHM` |None (default)|
|`IS31FL3733_PUR_0K5_OHM`|0.5 kΩ |
|`IS31FL3733_PUR_1K_OHM` |1 kΩ |
|`IS31FL3733_PUR_2K_OHM` |2 kΩ |
|`IS31FL3733_PUR_4K_OHM` |4 kΩ |
|`IS31FL3733_PUR_8K_OHM` |8 kΩ |
|`IS31FL3733_PUR_16K_OHM`|16 kΩ |
|`IS31FL3733_PUR_32K_OHM`|32 kΩ |
Valid values for `IS31FL3733_CS_PULLDOWN` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3733_PDR_0_OHM` |None (default)|
|`IS31FL3733_PDR_0K5_OHM`|0.5 kΩ |
|`IS31FL3733_PDR_1K_OHM` |1 kΩ |
|`IS31FL3733_PDR_2K_OHM` |2 kΩ |
|`IS31FL3733_PDR_4K_OHM` |4 kΩ |
|`IS31FL3733_PDR_8K_OHM` |8 kΩ |
|`IS31FL3733_PDR_16K_OHM`|16 kΩ |
|`IS31FL3733_PDR_32K_OHM`|32 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3733_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their cathodes connected to the `SW1` pin, and their anodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 15, figure 9.
## API {#api}
### `struct is31fl3733_led_t` {#api-is31fl3733-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3733-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3733_init(uint8_t index)` {#api-is31fl3733-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3733-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3733_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3733-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3733-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3733_select_page(uint8_t index, uint8_t page)` {#api-is31fl3733-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3733-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3733-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3733_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3733-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3733_leds` array).
- `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 is31fl3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3733-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3733-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 is31fl3733_set_value(int index, uint8_t value)` {#api-is31fl3733-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3733_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3733-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3733_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3733_set_value_all(uint8_t value)` {#api-is31fl3733-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3733-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3733-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3733_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3733-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3733_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3733_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3733-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3733_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3733-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3733_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3733_update_pwm_buffers(uint8_t index)` {#api-is31fl3733-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3733-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3733_update_led_control_registers(uint8_t index)` {#api-is31fl3733-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3733-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

322
docs/drivers/is31fl3736.md Normal file
View File

@@ -0,0 +1,322 @@
# IS31FL3736 Driver {#is31fl3736-driver}
I²C 12x8 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 96 single-color LEDs, or 32 RGB LEDs.
[IS31FL3736 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3736_DS.pdf)
## Usage {#usage}
The IS31FL3736 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3736` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3736-mono.c # For single-color
SRC += is31fl3736.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|---------------------------------|----------------------------------------------------|
|`IS31FL3736_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3736_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3736_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3736_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3736_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3736_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3736_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3736_PWM_FREQUENCY` |`IS31FL3736_PWM_FREQUENCY_8K4_HZ`|The PWM frequency of the LEDs (IS31FL3736B only) |
|`IS31FL3736_SW_PULLUP` |`IS31FL3736_PUR_0_OHM` |The `SWx` pullup resistor value |
|`IS31FL3736_CS_PULLDOWN` |`IS31FL3736_PDR_0_OHM` |The `CSx` pulldown resistor value |
|`IS31FL3736_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3736 has 16 possible 7-bit I²C addresses, depending on how the `ADDR1` and `ADDR2` pins are connected.
To configure this, set the `IS31FL3736_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|--------------------------------|------|
|`IS31FL3736_I2C_ADDRESS_GND_GND`|`0x50`|
|`IS31FL3736_I2C_ADDRESS_GND_SCL`|`0x51`|
|`IS31FL3736_I2C_ADDRESS_GND_SDA`|`0x52`|
|`IS31FL3736_I2C_ADDRESS_GND_VCC`|`0x53`|
|`IS31FL3736_I2C_ADDRESS_SCL_GND`|`0x54`|
|`IS31FL3736_I2C_ADDRESS_SCL_SCL`|`0x55`|
|`IS31FL3736_I2C_ADDRESS_SCL_SDA`|`0x56`|
|`IS31FL3736_I2C_ADDRESS_SCL_VCC`|`0x57`|
|`IS31FL3736_I2C_ADDRESS_SDA_GND`|`0x58`|
|`IS31FL3736_I2C_ADDRESS_SDA_SCL`|`0x59`|
|`IS31FL3736_I2C_ADDRESS_SDA_SDA`|`0x5A`|
|`IS31FL3736_I2C_ADDRESS_SDA_VCC`|`0x5B`|
|`IS31FL3736_I2C_ADDRESS_VCC_GND`|`0x5C`|
|`IS31FL3736_I2C_ADDRESS_VCC_SCL`|`0x5D`|
|`IS31FL3736_I2C_ADDRESS_VCC_SDA`|`0x5E`|
|`IS31FL3736_I2C_ADDRESS_VCC_VCC`|`0x5F`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted (for IS31FL3736B only) by adding the following to your `config.h`:
```c
#define IS31FL3736_PWM_FREQUENCY IS31FL3736_PWM_FREQUENCY_8K4_HZ
```
Valid values are:
|Define |Frequency |
|----------------------------------|-----------------|
|`IS31FL3736_PWM_FREQUENCY_8K4_HZ` |8.4 kHz (default)|
|`IS31FL3736_PWM_FREQUENCY_4K2_HZ` |4.2 kHz |
|`IS31FL3736_PWM_FREQUENCY_26K7_HZ`|26.7 kHz |
|`IS31FL3736_PWM_FREQUENCY_2K1_HZ` |2.1 kHz |
|`IS31FL3736_PWM_FREQUENCY_1K05_HZ`|1.05 kHz |
### De-Ghosting {#de-ghosting}
These settings control the pullup and pulldown resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 25) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3736_SW_PULLUP IS31FL3736_PUR_0_OHM
#define IS31FL3736_CS_PULLDOWN IS31FL3736_PDR_0_OHM
```
Valid values for `IS31FL3736_SW_PULLUP` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3736_PUR_0_OHM` |None (default)|
|`IS31FL3736_PUR_0K5_OHM`|0.5 kΩ |
|`IS31FL3736_PUR_1K_OHM` |1 kΩ |
|`IS31FL3736_PUR_2K_OHM` |2 kΩ |
|`IS31FL3736_PUR_4K_OHM` |4 kΩ |
|`IS31FL3736_PUR_8K_OHM` |8 kΩ |
|`IS31FL3736_PUR_16K_OHM`|16 kΩ |
|`IS31FL3736_PUR_32K_OHM`|32 kΩ |
Valid values for `IS31FL3736_CS_PULLDOWN` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3736_PDR_0_OHM` |None (default)|
|`IS31FL3736_PDR_0K5_OHM`|0.5 kΩ |
|`IS31FL3736_PDR_1K_OHM` |1 kΩ |
|`IS31FL3736_PDR_2K_OHM` |2 kΩ |
|`IS31FL3736_PDR_4K_OHM` |4 kΩ |
|`IS31FL3736_PDR_8K_OHM` |8 kΩ |
|`IS31FL3736_PDR_16K_OHM`|16 kΩ |
|`IS31FL3736_PDR_32K_OHM`|32 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3736_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their cathodes connected to the `SW1` pin, and their anodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 16, figure 9.
## API {#api}
### `struct is31fl3736_led_t` {#api-is31fl3736-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3736-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3736_init(uint8_t index)` {#api-is31fl3736-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3736-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3736_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3736-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3736-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3736_select_page(uint8_t index, uint8_t page)` {#api-is31fl3736-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3736-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3736-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3736_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3736-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3736_leds` array).
- `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 is31fl3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3736-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3736-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 is31fl3736_set_value(int index, uint8_t value)` {#api-is31fl3736-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3736_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3736-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3736_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3736_set_value_all(uint8_t value)` {#api-is31fl3736-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3736-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3736-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3736_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3736-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3736_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3736_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3736-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3736_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3736-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3736_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3736_update_pwm_buffers(uint8_t index)` {#api-is31fl3736-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3736-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3736_update_led_control_registers(uint8_t index)` {#api-is31fl3736-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3736-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

310
docs/drivers/is31fl3737.md Normal file
View File

@@ -0,0 +1,310 @@
# IS31FL3737 Driver {#is31fl3737-driver}
I²C 12x12 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 144 single-color LEDs, or 48 RGB LEDs.
[IS31FL3737 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3737_DS.pdf)
## Usage {#usage}
The IS31FL3737 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3737` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3737-mono.c # For single-color
SRC += is31fl3737.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|---------------------------------|----------------------------------------------------|
|`IS31FL3737_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3737_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3737_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3737_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3737_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3737_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3737_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3737_PWM_FREQUENCY` |`IS31FL3737_PWM_FREQUENCY_8K4_HZ`|The PWM frequency of the LEDs (IS31FL3737B only) |
|`IS31FL3737_SW_PULLUP` |`IS31FL3737_PUR_0_OHM` |The `SWx` pullup resistor value |
|`IS31FL3737_CS_PULLDOWN` |`IS31FL3737_PDR_0_OHM` |The `CSx` pulldown resistor value |
|`IS31FL3737_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3737 has four possible 7-bit I²C addresses, depending on how the `ADDR` pin is connected.
To configure this, set the `IS31FL3737_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|----------------------------|------|
|`IS31FL3737_I2C_ADDRESS_GND`|`0x50`|
|`IS31FL3737_I2C_ADDRESS_SCL`|`0x55`|
|`IS31FL3737_I2C_ADDRESS_SDA`|`0x5A`|
|`IS31FL3737_I2C_ADDRESS_VCC`|`0x5F`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted (for IS31FL3737B only) by adding the following to your `config.h`:
```c
#define IS31FL3737_PWM_FREQUENCY IS31FL3737_PWM_FREQUENCY_8K4_HZ
```
Valid values are:
|Define |Frequency |
|----------------------------------|-----------------|
|`IS31FL3737_PWM_FREQUENCY_8K4_HZ` |8.4 kHz (default)|
|`IS31FL3737_PWM_FREQUENCY_4K2_HZ` |4.2 kHz |
|`IS31FL3737_PWM_FREQUENCY_26K7_HZ`|26.7 kHz |
|`IS31FL3737_PWM_FREQUENCY_2K1_HZ` |2.1 kHz |
|`IS31FL3737_PWM_FREQUENCY_1K05_HZ`|1.05 kHz |
### De-Ghosting {#de-ghosting}
These settings control the pullup and pulldown resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3737_SW_PULLUP IS31FL3737_PUR_0_OHM
#define IS31FL3737_CS_PULLDOWN IS31FL3737_PDR_0_OHM
```
Valid values for `IS31FL3737_SW_PULLUP` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3737_PUR_0_OHM` |None (default)|
|`IS31FL3737_PUR_0K5_OHM`|0.5 kΩ |
|`IS31FL3737_PUR_1K_OHM` |1 kΩ |
|`IS31FL3737_PUR_2K_OHM` |2 kΩ |
|`IS31FL3737_PUR_4K_OHM` |4 kΩ |
|`IS31FL3737_PUR_8K_OHM` |8 kΩ |
|`IS31FL3737_PUR_16K_OHM`|16 kΩ |
|`IS31FL3737_PUR_32K_OHM`|32 kΩ |
Valid values for `IS31FL3737_CS_PULLDOWN` are:
|Define |Resistance |
|------------------------|--------------|
|`IS31FL3737_PDR_0_OHM` |None (default)|
|`IS31FL3737_PDR_0K5_OHM`|0.5 kΩ |
|`IS31FL3737_PDR_1K_OHM` |1 kΩ |
|`IS31FL3737_PDR_2K_OHM` |2 kΩ |
|`IS31FL3737_PDR_4K_OHM` |4 kΩ |
|`IS31FL3737_PDR_8K_OHM` |8 kΩ |
|`IS31FL3737_PDR_16K_OHM`|16 kΩ |
|`IS31FL3737_PDR_32K_OHM`|32 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3737_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their cathodes connected to the `SW1` pin, and their anodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 15, figure 9.
## API {#api}
### `struct is31fl3737_led_t` {#api-is31fl3737-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3737-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3737_init(uint8_t index)` {#api-is31fl3737-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3737-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3737_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3737-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3737-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3737_select_page(uint8_t index, uint8_t page)` {#api-is31fl3737-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3737-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3737-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3737_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3737-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3737_leds` array).
- `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 is31fl3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3737-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3737-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 is31fl3737_set_value(int index, uint8_t value)` {#api-is31fl3737-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3737_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3737-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3737_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3737_set_value_all(uint8_t value)` {#api-is31fl3737-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3737-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3737-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3737_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3737-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3737_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3737_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3737-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3737_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3737-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3737_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3737_update_pwm_buffers(uint8_t index)` {#api-is31fl3737-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3737-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3737_update_led_control_registers(uint8_t index)` {#api-is31fl3737-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3737-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

310
docs/drivers/is31fl3741.md Normal file
View File

@@ -0,0 +1,310 @@
# IS31FL3741 Driver {#is31fl3741-driver}
I²C 39x9 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 351 single-color LEDs, or 117 RGB LEDs.
[IS31FL3741A Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3741A_DS.pdf)
## Usage {#usage}
The IS31FL3741 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3741` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3741-mono.c # For single-color
SRC += is31fl3741.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|---------------------------------|----------------------------------------------------|
|`IS31FL3741_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3741_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3741_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3741_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3741_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3741_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3741_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3741_CONFIGURATION` |`1` |The value of the configuration register |
|`IS31FL3741_PWM_FREQUENCY` |`IS31FL3741_PWM_FREQUENCY_29K_HZ`|The PWM frequency of the LEDs (IS31FL3741A only) |
|`IS31FL3741_SW_PULLUP` |`IS31FL3741_PUR_32K_OHM` |The `SWx` pullup resistor value |
|`IS31FL3741_CS_PULLDOWN` |`IS31FL3741_PDR_32K_OHM` |The `CSx` pulldown resistor value |
|`IS31FL3741_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3741 has four possible 7-bit I²C addresses, depending on how the `ADDR` pin is connected.
To configure this, set the `IS31FL3741_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|----------------------------|------|
|`IS31FL3741_I2C_ADDRESS_GND`|`0x30`|
|`IS31FL3741_I2C_ADDRESS_SCL`|`0x31`|
|`IS31FL3741_I2C_ADDRESS_SDA`|`0x32`|
|`IS31FL3741_I2C_ADDRESS_VCC`|`0x33`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted (for IS31FL3741A only) by adding the following to your `config.h`:
```c
#define IS31FL3741_PWM_FREQUENCY IS31FL3741_PWM_FREQUENCY_29K_HZ
```
Valid values are:
|Define |Frequency |
|---------------------------------|----------------|
|`IS31FL3741_PWM_FREQUENCY_29K_HZ`|29 kHz (default)|
|`IS31FL3741_PWM_FREQUENCY_3K6_HZ`|3.6 kHz |
|`IS31FL3741_PWM_FREQUENCY_1K8_HZ`|1.8 kHz |
|`IS31FL3741_PWM_FREQUENCY_900_HZ`|900 Hz |
### De-Ghosting {#de-ghosting}
These settings control the pullup and pulldown resistor values on the `CSx` and `SWy` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 18) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3741_SW_PULLUP IS31FL3741_PUR_32K_OHM
#define IS31FL3741_CS_PULLDOWN IS31FL3741_PDR_32K_OHM
```
Valid values for `IS31FL3741_SW_PULLUP` are:
|Define |Resistance |
|------------------------|---------------|
|`IS31FL3741_PUR_0_OHM` |None |
|`IS31FL3741_PUR_0K5_OHM`|0.5 kΩ |
|`IS31FL3741_PUR_1K_OHM` |1 kΩ |
|`IS31FL3741_PUR_2K_OHM` |2 kΩ |
|`IS31FL3741_PUR_4K_OHM` |4 kΩ |
|`IS31FL3741_PUR_8K_OHM` |8 kΩ |
|`IS31FL3741_PUR_16K_OHM`|16 kΩ |
|`IS31FL3741_PUR_32K_OHM`|32 kΩ (default)|
Valid values for `IS31FL3741_CS_PULLDOWN` are:
|Define |Resistance |
|------------------------|---------------|
|`IS31FL3741_PDR_0_OHM` |None |
|`IS31FL3741_PDR_0K5_OHM`|0.5 kΩ |
|`IS31FL3741_PDR_1K_OHM` |1 kΩ |
|`IS31FL3741_PDR_2K_OHM` |2 kΩ |
|`IS31FL3741_PDR_4K_OHM` |4 kΩ |
|`IS31FL3741_PDR_8K_OHM` |8 kΩ |
|`IS31FL3741_PDR_16K_OHM`|16 kΩ |
|`IS31FL3741_PDR_32K_OHM`|32 kΩ (default)|
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3741_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 12, figure 8.
## API {#api}
### `struct is31fl3741_led_t` {#api-is31fl3741-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3741-led-t-members}
- `uint32_t driver`
The driver index of the LED, from 0 to 3.
- `uint32_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint32_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint32_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint32_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3741_init(uint8_t index)` {#api-is31fl3741-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3741-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3741_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3741-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3741-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3741_select_page(uint8_t index, uint8_t page)` {#api-is31fl3741-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3741-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3741-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3741_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3741-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3741_leds` array).
- `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 is31fl3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3741-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3741-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 is31fl3741_set_value(int index, uint8_t value)` {#api-is31fl3741-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3741_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3741-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3741_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3741_set_value_all(uint8_t value)` {#api-is31fl3741-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3741-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-is31fl3741-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3741_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3741-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3741_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void is31fl3741_set_led_control_register(uint8_t index, bool value)` {#api-is31fl3741-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3741_update_led_control_registers()` after you are finished.
#### Arguments {#api-is31fl3741-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3741_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void is31fl3741_update_pwm_buffers(uint8_t index)` {#api-is31fl3741-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3741-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3741_update_led_control_registers(uint8_t index)` {#api-is31fl3741-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-is31fl3741-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

310
docs/drivers/is31fl3742a.md Normal file
View File

@@ -0,0 +1,310 @@
# IS31FL3742A Driver {#is31fl3742a-driver}
I²C 30x6 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 180 single-color LEDs, or 60 RGB LEDs.
[IS31FL3742A Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3742A_DS.pdf)
## Usage {#usage}
The IS31FL3742A driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3742a` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3742a-mono.c # For single-color
SRC += is31fl3742a.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|-----------------------------|----------------------------------|----------------------------------------------------|
|`IS31FL3742A_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3742A_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3742A_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3742A_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3742A_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3742A_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3742A_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3742A_CONFIGURATION` |`0x31` |The value of the configuration register |
|`IS31FL3742A_PWM_FREQUENCY` |`IS31FL3742A_PWM_FREQUENCY_29K_HZ`|The PWM frequency of the LEDs |
|`IS31FL3742A_SW_PULLDOWN` |`IS31FL3742A_PDR_8K_OHM` |The `SWx` pulldown resistor value |
|`IS31FL3742A_CS_PULLUP` |`IS31FL3742A_PUR_8K_OHM` |The `CSx` pullup resistor value |
|`IS31FL3742A_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3742A has four possible 7-bit I²C addresses, depending on how the `ADDR` pin is connected.
To configure this, set the `IS31FL3742A_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|-----------------------------|------|
|`IS31FL3742A_I2C_ADDRESS_GND`|`0x30`|
|`IS31FL3742A_I2C_ADDRESS_SCL`|`0x31`|
|`IS31FL3742A_I2C_ADDRESS_SDA`|`0x32`|
|`IS31FL3742A_I2C_ADDRESS_VCC`|`0x33`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted by adding the following to your `config.h`:
```c
#define IS31FL3742A_PWM_FREQUENCY IS31FL3742A_PWM_FREQUENCY_29K_HZ
```
Valid values are:
|Define |Frequency |
|----------------------------------|----------------|
|`IS31FL3742A_PWM_FREQUENCY_29K_HZ`|29 kHz (default)|
|`IS31FL3742A_PWM_FREQUENCY_3K6_HZ`|3.6 kHz |
|`IS31FL3742A_PWM_FREQUENCY_1K8_HZ`|1.8 kHz |
|`IS31FL3742A_PWM_FREQUENCY_900_HZ`|900 Hz |
### De-Ghosting {#de-ghosting}
These settings control the pulldown and pullup resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3742A_SW_PULLDOWN IS31FL3742A_PDR_8K_OHM
#define IS31FL3742A_CS_PULLUP IS31FL3742A_PUR_8K_OHM
```
Valid values for `IS31FL3742A_SW_PULLDOWN` are:
|Define |Resistance |
|-------------------------|--------------|
|`IS31FL3742A_PDR_0_OHM` |None |
|`IS31FL3742A_PDR_0K5_OHM`|0.5 kΩ |
|`IS31FL3742A_PDR_1K_OHM` |1 kΩ |
|`IS31FL3742A_PDR_2K_OHM` |2 kΩ |
|`IS31FL3742A_PDR_4K_OHM` |4 kΩ |
|`IS31FL3742A_PDR_8K_OHM` |8 kΩ (default)|
|`IS31FL3742A_PDR_16K_OHM`|16 kΩ |
|`IS31FL3742A_PDR_32K_OHM`|32 kΩ |
Valid values for `IS31FL3742A_CS_PULLUP` are:
|Define |Resistance |
|-------------------------|--------------|
|`IS31FL3742A_PUR_0_OHM` |None |
|`IS31FL3742A_PUR_0K5_OHM`|0.5 kΩ |
|`IS31FL3742A_PUR_1K_OHM` |1 kΩ |
|`IS31FL3742A_PUR_2K_OHM` |2 kΩ |
|`IS31FL3742A_PUR_4K_OHM` |4 kΩ |
|`IS31FL3742A_PUR_8K_OHM` |8 kΩ (default)|
|`IS31FL3742A_PUR_16K_OHM`|16 kΩ |
|`IS31FL3742A_PUR_32K_OHM`|32 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSx` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3742A_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 12, figure 8.
## API {#api}
### `struct is31fl3742a_led_t` {#api-is31fl3742a-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3742a-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3742a_init(uint8_t index)` {#api-is31fl3742a-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3742a-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3742a_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3742a-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3742a-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3742a_select_page(uint8_t index, uint8_t page)` {#api-is31fl3742a-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3742a-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3742a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3742a-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3742a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3742a-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3742a_leds` array).
- `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 is31fl3742a_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3742a-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3742a-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 is31fl3742a_set_value(int index, uint8_t value)` {#api-is31fl3742a-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3742a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3742a-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3742a_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3742a_set_value_all(uint8_t value)` {#api-is31fl3742a-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3742a-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3742a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3742a-set-scaling-register-rgb}
Configure the scaling registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3742a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3742a-set-scaling-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3742a_leds` array).
- `uint8_t red`
The scaling value for the red channel.
- `uint8_t green`
The scaling value for the green channel.
- `uint8_t blue`
The scaling value for the blue channel.
---
### `void is31fl3742a_set_scaling_register(uint8_t index, uint8_t value)` {#api-is31fl3742a-set-scaling-register-mono}
Configure the scaling register for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3742a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3742a-set-scaling-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3742a_leds` array).
- `uint8_t value`
The scaling value for the LED.
---
### `void is31fl3742a_update_pwm_buffers(uint8_t index)` {#api-is31fl3742a-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3742a-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3742a_update_scaling_registers(uint8_t index)` {#api-is31fl3742a-update-scaling-registers}
Flush the scaling register values to the LED driver.
#### Arguments {#api-is31fl3742a-update-scaling-registers-arguments}
- `uint8_t index`
The driver index.

320
docs/drivers/is31fl3743a.md Normal file
View File

@@ -0,0 +1,320 @@
# IS31FL3743A Driver {#is31fl3743a-driver}
I²C 18x11 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 198 single-color LEDs, or 66 RGB LEDs.
[IS31FL3743A Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3743A_DS.pdf)
## Usage {#usage}
The IS31FL3743A driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3743a` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3743a-mono.c # For single-color
SRC += is31fl3743a.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|-----------------------------|-------------------------------|----------------------------------------------------|
|`IS31FL3743A_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3743A_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3743A_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3743A_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3743A_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3743A_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3743A_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3743A_SYNC_1` |`IS31FL3743A_SYNC_NONE` |The sync configuration for driver 0 |
|`IS31FL3743A_SYNC_2` |`IS31FL3743A_SYNC_NONE` |The sync configuration for driver 1 |
|`IS31FL3743A_SYNC_3` |`IS31FL3743A_SYNC_NONE` |The sync configuration for driver 2 |
|`IS31FL3743A_SYNC_4` |`IS31FL3743A_SYNC_NONE` |The sync configuration for driver 3 |
|`IS31FL3743A_CONFIGURATION` |`0x01` |The value of the configuration register |
|`IS31FL3743A_SW_PULLDOWN` |`IS31FL3743A_PDR_2K_OHM_SW_OFF`|The `SWx` pulldown resistor value |
|`IS31FL3743A_CS_PULLUP` |`IS31FL3743A_PUR_2K_OHM_CS_OFF`|The `CSx` pullup resistor value |
|`IS31FL3743A_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3743A has 16 possible 7-bit I²C addresses, depending on how the `ADDR1` and `ADDR2` pins are connected.
To configure this, set the `IS31FL3743A_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|---------------------------------|------|
|`IS31FL3743A_I2C_ADDRESS_GND_GND`|`0x20`|
|`IS31FL3743A_I2C_ADDRESS_GND_SCL`|`0x21`|
|`IS31FL3743A_I2C_ADDRESS_GND_SDA`|`0x22`|
|`IS31FL3743A_I2C_ADDRESS_GND_VCC`|`0x23`|
|`IS31FL3743A_I2C_ADDRESS_SCL_GND`|`0x24`|
|`IS31FL3743A_I2C_ADDRESS_SCL_SCL`|`0x25`|
|`IS31FL3743A_I2C_ADDRESS_SCL_SDA`|`0x26`|
|`IS31FL3743A_I2C_ADDRESS_SCL_VCC`|`0x27`|
|`IS31FL3743A_I2C_ADDRESS_SDA_GND`|`0x28`|
|`IS31FL3743A_I2C_ADDRESS_SDA_SCL`|`0x29`|
|`IS31FL3743A_I2C_ADDRESS_SDA_SDA`|`0x2A`|
|`IS31FL3743A_I2C_ADDRESS_SDA_VCC`|`0x2B`|
|`IS31FL3743A_I2C_ADDRESS_VCC_GND`|`0x2C`|
|`IS31FL3743A_I2C_ADDRESS_VCC_SCL`|`0x2D`|
|`IS31FL3743A_I2C_ADDRESS_VCC_SDA`|`0x2E`|
|`IS31FL3743A_I2C_ADDRESS_VCC_VCC`|`0x2F`|
### Multi-Driver Synchronization {#multi-driver-synchronization}
Multiple IS31FL3743A drivers can be synchronized by connecting the `SYNC` pins together. One driver must be designated as the "master", and the others configured as "slave".
To do this, set the `IS31FL3743A_SYNC_n` defines accordingly in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|-------------------------|---------------------------|
|`IS31FL3743A_SYNC_NONE` |No synchronization |
|`IS31FL3743A_SYNC_MASTER`|Driver configured as master|
|`IS31FL3743A_SYNC_SLAVE` |Driver configured as slave |
### De-Ghosting {#de-ghosting}
These settings control the pulldown and pullup resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3743A_SW_PULLDOWN IS31FL3743A_PDR_2K_OHM_SW_OFF
#define IS31FL3743A_CS_PULLUP IS31FL3743A_PUR_2K_OHM_CS_OFF
```
Valid values for `IS31FL3743A_SW_PULLDOWN` are:
|Define |Resistance |
|--------------------------------|------------------------------|
|`IS31FL3743A_PDR_0_OHM` |None (default) |
|`IS31FL3743A_PDR_0K5_OHM_SW_OFF`|0.5 kΩ in SWx off time |
|`IS31FL3743A_PDR_1K_OHM_SW_OFF` |1 kΩ in SWx off time |
|`IS31FL3743A_PDR_2K_OHM_SW_OFF` |2 kΩ in SWx off time (default)|
|`IS31FL3743A_PDR_1K_OHM` |1 kΩ |
|`IS31FL3743A_PDR_2K_OHM` |2 kΩ |
|`IS31FL3743A_PDR_4K_OHM` |4 kΩ |
|`IS31FL3743A_PDR_8K_OHM` |8 kΩ |
Valid values for `IS31FL3743A_CS_PULLUP` are:
|Define |Resistance |
|--------------------------------|------------------------------|
|`IS31FL3743A_PUR_0_OHM` |None (default) |
|`IS31FL3743A_PUR_0K5_OHM_CS_OFF`|0.5 kΩ in CSy off time |
|`IS31FL3743A_PUR_1K_OHM_CS_OFF` |1 kΩ in CSy off time |
|`IS31FL3743A_PUR_2K_OHM_CS_OFF` |2 kΩ in CSy off time (default)|
|`IS31FL3743A_PUR_1K_OHM` |1 kΩ |
|`IS31FL3743A_PUR_2K_OHM` |2 kΩ |
|`IS31FL3743A_PUR_4K_OHM` |4 kΩ |
|`IS31FL3743A_PUR_8K_OHM` |8 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSy` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3743A_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 12, figure 8.
## API {#api}
### `struct is31fl3743a_led_t` {#api-is31fl3743a-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3743a-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3743a_init(uint8_t index)` {#api-is31fl3743a-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3743a-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3743a_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3743a-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3743a-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3743a_select_page(uint8_t index, uint8_t page)` {#api-is31fl3743a-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3743a-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3743a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3743a-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3743a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3743a-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3743a_leds` array).
- `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 is31fl3743a_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3743a-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3743a-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 is31fl3743a_set_value(int index, uint8_t value)` {#api-is31fl3743a-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3743a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3743a-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3743a_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3743a_set_value_all(uint8_t value)` {#api-is31fl3743a-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3743a-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3743a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3743a-set-scaling-register-rgb}
Configure the scaling registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3743a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3743a-set-scaling-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3743a_leds` array).
- `uint8_t red`
The scaling value for the red channel.
- `uint8_t green`
The scaling value for the green channel.
- `uint8_t blue`
The scaling value for the blue channel.
---
### `void is31fl3743a_set_scaling_register(uint8_t index, uint8_t value)` {#api-is31fl3743a-set-scaling-register-mono}
Configure the scaling register for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3743a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3743a-set-scaling-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3743a_leds` array).
- `uint8_t value`
The scaling value for the LED.
---
### `void is31fl3743a_update_pwm_buffers(uint8_t index)` {#api-is31fl3743a-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3743a-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3743a_update_scaling_registers(uint8_t index)` {#api-is31fl3743a-update-scaling-registers}
Flush the scaling register values to the LED driver.
#### Arguments {#api-is31fl3743a-update-scaling-registers-arguments}
- `uint8_t index`
The driver index.

320
docs/drivers/is31fl3745.md Normal file
View File

@@ -0,0 +1,320 @@
# IS31FL3745 Driver {#is31fl3745-driver}
I²C 18x8 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 144 single-color LEDs, or 48 RGB LEDs.
[IS31FL3745 Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf)
## Usage {#usage}
The IS31FL3745 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3745` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3745-mono.c # For single-color
SRC += is31fl3745.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|------------------------------|----------------------------------------------------|
|`IS31FL3745_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3745_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3745_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3745_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3745_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3745_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3745_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3745_SYNC_1` |`IS31FL3745_SYNC_NONE` |The sync configuration for driver 0 |
|`IS31FL3745_SYNC_2` |`IS31FL3745_SYNC_NONE` |The sync configuration for driver 1 |
|`IS31FL3745_SYNC_3` |`IS31FL3745_SYNC_NONE` |The sync configuration for driver 2 |
|`IS31FL3745_SYNC_4` |`IS31FL3745_SYNC_NONE` |The sync configuration for driver 3 |
|`IS31FL3745_CONFIGURATION` |`0x31` |The value of the configuration register |
|`IS31FL3745_SW_PULLDOWN` |`IS31FL3745_PDR_2K_OHM_SW_OFF`|The `SWx` pulldown resistor value |
|`IS31FL3745_CS_PULLUP` |`IS31FL3745_PUR_2K_OHM_CS_OFF`|The `CSx` pullup resistor value |
|`IS31FL3745_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3745 has 16 possible 7-bit I²C addresses, depending on how the `ADDR1` and `ADDR2` pins are connected.
To configure this, set the `IS31FL3745_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|--------------------------------|------|
|`IS31FL3745_I2C_ADDRESS_GND_GND`|`0x20`|
|`IS31FL3745_I2C_ADDRESS_GND_SCL`|`0x21`|
|`IS31FL3745_I2C_ADDRESS_GND_SDA`|`0x22`|
|`IS31FL3745_I2C_ADDRESS_GND_VCC`|`0x23`|
|`IS31FL3745_I2C_ADDRESS_SCL_GND`|`0x24`|
|`IS31FL3745_I2C_ADDRESS_SCL_SCL`|`0x25`|
|`IS31FL3745_I2C_ADDRESS_SCL_SDA`|`0x26`|
|`IS31FL3745_I2C_ADDRESS_SCL_VCC`|`0x27`|
|`IS31FL3745_I2C_ADDRESS_SDA_GND`|`0x28`|
|`IS31FL3745_I2C_ADDRESS_SDA_SCL`|`0x29`|
|`IS31FL3745_I2C_ADDRESS_SDA_SDA`|`0x2A`|
|`IS31FL3745_I2C_ADDRESS_SDA_VCC`|`0x2B`|
|`IS31FL3745_I2C_ADDRESS_VCC_GND`|`0x2C`|
|`IS31FL3745_I2C_ADDRESS_VCC_SCL`|`0x2D`|
|`IS31FL3745_I2C_ADDRESS_VCC_SDA`|`0x2E`|
|`IS31FL3745_I2C_ADDRESS_VCC_VCC`|`0x2F`|
### Multi-Driver Synchronization {#multi-driver-synchronization}
Multiple IS31FL3745 drivers can be synchronized by connecting the `SYNC` pins together. One driver must be designated as the "master", and the others configured as "slave".
To do this, set the `IS31FL3745_SYNC_n` defines accordingly in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|------------------------|---------------------------|
|`IS31FL3745_SYNC_NONE` |No synchronization |
|`IS31FL3745_SYNC_MASTER`|Driver configured as master|
|`IS31FL3745_SYNC_SLAVE` |Driver configured as slave |
### De-Ghosting {#de-ghosting}
These settings control the pulldown and pullup resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3745_SW_PULLDOWN IS31FL3745_PDR_2K_OHM_SW_OFF
#define IS31FL3745_CS_PULLUP IS31FL3745_PUR_2K_OHM_CS_OFF
```
Valid values for `IS31FL3745_SW_PULLDOWN` are:
|Define |Resistance |
|-------------------------------|------------------------------|
|`IS31FL3745_PDR_0_OHM` |None (default) |
|`IS31FL3745_PDR_0K5_OHM_SW_OFF`|0.5 kΩ in SWx off time |
|`IS31FL3745_PDR_1K_OHM_SW_OFF` |1 kΩ in SWx off time |
|`IS31FL3745_PDR_2K_OHM_SW_OFF` |2 kΩ in SWx off time (default)|
|`IS31FL3745_PDR_1K_OHM` |1 kΩ |
|`IS31FL3745_PDR_2K_OHM` |2 kΩ |
|`IS31FL3745_PDR_4K_OHM` |4 kΩ |
|`IS31FL3745_PDR_8K_OHM` |8 kΩ |
Valid values for `IS31FL3745_CS_PULLUP` are:
|Define |Resistance |
|-------------------------------|------------------------------|
|`IS31FL3745_PUR_0_OHM` |None (default) |
|`IS31FL3745_PUR_0K5_OHM_CS_OFF`|0.5 kΩ in CSy off time |
|`IS31FL3745_PUR_1K_OHM_CS_OFF` |1 kΩ in CSy off time |
|`IS31FL3745_PUR_2K_OHM_CS_OFF` |2 kΩ in CSy off time (default)|
|`IS31FL3745_PUR_1K_OHM` |1 kΩ |
|`IS31FL3745_PUR_2K_OHM` |2 kΩ |
|`IS31FL3745_PUR_4K_OHM` |4 kΩ |
|`IS31FL3745_PUR_8K_OHM` |8 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSy` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3745_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 12, figure 9.
## API {#api}
### `struct is31fl3745_led_t` {#api-is31fl3745-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3745-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3745_init(uint8_t index)` {#api-is31fl3745-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3745-init-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3745_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3745-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3745-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3745_select_page(uint8_t index, uint8_t page)` {#api-is31fl3745-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3745-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3745_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3745-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3745_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3745-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3745_leds` array).
- `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 is31fl3745_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3745-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3745-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 is31fl3745_set_value(int index, uint8_t value)` {#api-is31fl3745-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3745_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3745-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3745_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3745_set_value_all(uint8_t value)` {#api-is31fl3745-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3745-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3745_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3745-set-scaling-register-rgb}
Configure the scaling registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3745_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3745-set-scaling-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3745_leds` array).
- `uint8_t red`
The scaling value for the red channel.
- `uint8_t green`
The scaling value for the green channel.
- `uint8_t blue`
The scaling value for the blue channel.
---
### `void is31fl3745_set_scaling_register(uint8_t index, uint8_t value)` {#api-is31fl3745-set-scaling-register-mono}
Configure the scaling register for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3745_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3745-set-scaling-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3745_leds` array).
- `uint8_t value`
The scaling value for the LED.
---
### `void is31fl3745_update_pwm_buffers(uint8_t index)` {#api-is31fl3745-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3745-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3745_update_scaling_registers(uint8_t index)` {#api-is31fl3745-update-scaling-registers}
Flush the scaling register values to the LED driver.
#### Arguments {#api-is31fl3745-update-scaling-registers-arguments}
- `uint8_t index`
The driver index.

327
docs/drivers/is31fl3746a.md Normal file
View File

@@ -0,0 +1,327 @@
# IS31FL3746A Driver {#is31fl3746a-driver}
I²C 18x4 LED matrix driver by Lumissil. Supports a maximum of four drivers, each controlling up to 72 single-color LEDs, or 24 RGB LEDs.
[IS31FL3746A Datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf)
## Usage {#usage}
The IS31FL3746A driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `is31fl3746a` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led/issi
SRC += is31fl3746a-mono.c # For single-color
SRC += is31fl3746a.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|-----------------------------|----------------------------------|----------------------------------------------------|
|`IS31FL3746A_SDB_PIN` |*Not defined* |The GPIO pin connected to the drivers' shutdown pins|
|`IS31FL3746A_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`IS31FL3746A_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`IS31FL3746A_I2C_ADDRESS_1` |*Not defined* |The I²C address of driver 0 |
|`IS31FL3746A_I2C_ADDRESS_2` |*Not defined* |The I²C address of driver 1 |
|`IS31FL3746A_I2C_ADDRESS_3` |*Not defined* |The I²C address of driver 2 |
|`IS31FL3746A_I2C_ADDRESS_4` |*Not defined* |The I²C address of driver 3 |
|`IS31FL3746A_CONFIGURATION` |`0x01` |The value of the configuration register |
|`IS31FL3746A_PWM_FREQUENCY` |`IS31FL3746A_PWM_FREQUENCY_29K_HZ`|The PWM frequency of the LEDs |
|`IS31FL3746A_SW_PULLDOWN` |`IS31FL3746A_PDR_2K_OHM_SW_OFF` |The `SWx` pulldown resistor value |
|`IS31FL3746A_CS_PULLUP` |`IS31FL3746A_PUR_2K_OHM_CS_OFF` |The `CSx` pullup resistor value |
|`IS31FL3746A_GLOBAL_CURRENT` |`0xFF` |The global current control value |
### I²C Addressing {#i2c-addressing}
The IS31FL3746A has 16 possible 7-bit I²C addresses, depending on how the `ADDR1` and `ADDR2` pins are connected.
To configure this, set the `IS31FL3746A_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|---------------------------------|------|
|`IS31FL3746A_I2C_ADDRESS_GND_GND`|`0x60`|
|`IS31FL3746A_I2C_ADDRESS_GND_SCL`|`0x61`|
|`IS31FL3746A_I2C_ADDRESS_GND_SDA`|`0x62`|
|`IS31FL3746A_I2C_ADDRESS_GND_VCC`|`0x63`|
|`IS31FL3746A_I2C_ADDRESS_SCL_GND`|`0x64`|
|`IS31FL3746A_I2C_ADDRESS_SCL_SCL`|`0x65`|
|`IS31FL3746A_I2C_ADDRESS_SCL_SDA`|`0x66`|
|`IS31FL3746A_I2C_ADDRESS_SCL_VCC`|`0x67`|
|`IS31FL3746A_I2C_ADDRESS_SDA_GND`|`0x68`|
|`IS31FL3746A_I2C_ADDRESS_SDA_SCL`|`0x69`|
|`IS31FL3746A_I2C_ADDRESS_SDA_SDA`|`0x6A`|
|`IS31FL3746A_I2C_ADDRESS_SDA_VCC`|`0x6B`|
|`IS31FL3746A_I2C_ADDRESS_VCC_GND`|`0x6C`|
|`IS31FL3746A_I2C_ADDRESS_VCC_SCL`|`0x6D`|
|`IS31FL3746A_I2C_ADDRESS_VCC_SDA`|`0x6E`|
|`IS31FL3746A_I2C_ADDRESS_VCC_VCC`|`0x6F`|
### PWM Frequency {#pwm-frequency}
The PWM frequency can be adjusted by adding the following to your `config.h`:
```c
#define IS31FL3746A_PWM_FREQUENCY IS31FL3746A_PWM_FREQUENCY_29K_HZ
```
Valid values are:
|Define |Frequency |
|-----------------------------------|----------------|
|`IS31FL3746A_PWM_FREQUENCY_29K_HZ` |29 kHz (default)|
|`IS31FL3746A_PWM_FREQUENCY_14K5_HZ`|14.5 kHz |
|`IS31FL3746A_PWM_FREQUENCY_7K25_HZ`|7.25 kHz |
|`IS31FL3746A_PWM_FREQUENCY_3K63_HZ`|3.63 kHz |
|`IS31FL3746A_PWM_FREQUENCY_1K81_HZ`|1.81 kHz |
|`IS31FL3746A_PWM_FREQUENCY_906_HZ` |906 Hz |
|`IS31FL3746A_PWM_FREQUENCY_453_HZ` |453 Hz |
### De-Ghosting {#de-ghosting}
These settings control the pulldown and pullup resistor values on the `SWy` and `CSx` pins respectively, for the purposes of eliminating ghosting. Refer to the datasheet (p. 23) for more information on how and why this occurs.
To adjust the resistor values, add the following to your `config.h`:
```c
#define IS31FL3746A_SW_PULLDOWN IS31FL3746A_PDR_2K_OHM_SW_OFF
#define IS31FL3746A_CS_PULLUP IS31FL3746A_PUR_2K_OHM_CS_OFF
```
Valid values for `IS31FL3746A_SW_PULLDOWN` are:
|Define |Resistance |
|--------------------------------|------------------------------|
|`IS31FL3746A_PDR_0_OHM` |None |
|`IS31FL3746A_PDR_0K5_OHM_SW_OFF`|0.5 kΩ in SWx off time |
|`IS31FL3746A_PDR_1K_OHM_SW_OFF` |1 kΩ in SWx off time |
|`IS31FL3746A_PDR_2K_OHM_SW_OFF` |2 kΩ in SWx off time (default)|
|`IS31FL3746A_PDR_1K_OHM` |1 kΩ |
|`IS31FL3746A_PDR_2K_OHM` |2 kΩ |
|`IS31FL3746A_PDR_4K_OHM` |4 kΩ |
|`IS31FL3746A_PDR_8K_OHM` |8 kΩ |
Valid values for `IS31FL3746A_CS_PULLUP` are:
|Define |Resistance |
|--------------------------------|------------------------------|
|`IS31FL3746A_PUR_0_OHM` |None (default) |
|`IS31FL3746A_PUR_0K5_OHM_CS_OFF`|0.5 kΩ in CSy off time |
|`IS31FL3746A_PUR_1K_OHM_CS_OFF` |1 kΩ in CSy off time |
|`IS31FL3746A_PUR_2K_OHM_CS_OFF` |2 kΩ in CSy off time (default)|
|`IS31FL3746A_PUR_1K_OHM` |1 kΩ |
|`IS31FL3746A_PUR_2K_OHM` |2 kΩ |
|`IS31FL3746A_PUR_4K_OHM` |4 kΩ |
|`IS31FL3746A_PUR_8K_OHM` |8 kΩ |
### Global Current Control {#global-current-control}
This setting controls the current sunk by the `CSy` pins, from 0 to 255. By default, the value is the maximum (255), but if you need to lower it, add the following to your `config.h`:
```c
#define IS31FL3746A_GLOBAL_CURRENT 0xFF
```
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT] = {
/* Driver
* | R G B */
{0, SW1_CS1, SW1_CS2, SW1_CS3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their anodes connected to the `SW1` pin, and their cathodes on the `CS1`, `CS2` and `CS3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT] = {
/* Driver
* | V */
{0, SW1_CS1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 13, figure 8.
## API {#api}
### `struct is31fl3746a_led_t` {#api-is31fl3746a-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-is31fl3746a-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void is31fl3746a_init(uint8_t index)` {#api-is31fl3746a-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-is31fl3746a-init-arguments}
- `uint8_t index`
The driver index.
- `uint8_t sync`
Sync configuration of the LED driver.
---
### `void is31fl3746a_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-is31fl3746a-write-register}
Set the value of the given register.
#### Arguments {#api-is31fl3746a-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void is31fl3746a_select_page(uint8_t index, uint8_t page)` {#api-is31fl3746a-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-is31fl3746a-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void is31fl3746a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3746a-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3746a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3746a-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3746a_leds` array).
- `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 is31fl3746a_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3746a-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-is31fl3746a-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 is31fl3746a_set_value(int index, uint8_t value)` {#api-is31fl3746a-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3746a_update_pwm_buffers()` after you are finished.
#### Arguments {#api-is31fl3746a-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_is31fl3746a_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3746a_set_value_all(uint8_t value)` {#api-is31fl3746a-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-is31fl3746a-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue)` {#api-is31fl3746a-set-scaling-register-rgb}
Configure the scaling registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `is31fl3746a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3746a-set-scaling-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3746a_leds` array).
- `uint8_t red`
The scaling value for the red channel.
- `uint8_t green`
The scaling value for the green channel.
- `uint8_t blue`
The scaling value for the blue channel.
---
### `void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value)` {#api-is31fl3746a-set-scaling-register-mono}
Configure the scaling register for a single LED (single-color driver only). This function does not immediately update the LEDs; call `is31fl3746a_update_scaling_registers()` after you are finished.
#### Arguments {#api-is31fl3746a-set-scaling-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_is31fl3746a_leds` array).
- `uint8_t value`
The scaling value for the LED.
---
### `void is31fl3746a_update_pwm_buffers(uint8_t index)` {#api-is31fl3746a-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-is31fl3746a-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void is31fl3746a_update_scaling_registers(uint8_t index)` {#api-is31fl3746a-update-scaling-registers}
Flush the scaling register values to the LED driver.
#### Arguments {#api-is31fl3746a-update-scaling-registers-arguments}
- `uint8_t index`
The driver index.

397
docs/drivers/serial.md Normal file
View File

@@ -0,0 +1,397 @@
# 'serial' Driver
The Serial driver powers the [Split Keyboard](../features/split_keyboard) feature. Several implementations are available that cater to the platform and capabilities of MCU in use. Note that none of the drivers support split keyboards with more than two halves.
| Driver | AVR | ARM | Connection between halves |
| --------------------------------------- | ------------------ | ------------------ | --------------------------------------------------------------------------------------------- |
| [Bitbang](#bitbang) | :heavy_check_mark: | :heavy_check_mark: | Single wire communication. One wire is used for reception and transmission. |
| [USART Half-duplex](#usart-half-duplex) | | :heavy_check_mark: | Efficient single wire communication. One wire is used for reception and transmission. |
| [USART Full-duplex](#usart-full-duplex) | | :heavy_check_mark: | Efficient two wire communication. Two distinct wires are used for reception and transmission. |
::: tip
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
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.
::: warning
On ARM platforms the bitbang driver causes connection issues when using it together with the bitbang WS2812 driver. Choosing alternate drivers for both serial and WS2812 (instead of bitbang) is strongly recommended.
:::
### Pin configuration
```
LEFT RIGHT
+-------+ SERIAL +-------+
| SSP |-----------------| SSP |
| | VDD | |
| |-----------------| |
| | GND | |
| |-----------------| |
+-------+ +-------+
```
One GPIO pin is needed for the bitbang driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SOFT_SERIAL_PIN` (SSP) in the configuration. A TRS or USB cable provides enough conductors for this driver to function.
### Setup
To use the bitbang driver follow these steps to activate it.
1. Change the `SERIAL_DRIVER` to `bitbang` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = bitbang
```
2. Configure the GPIO pin of your keyboard via the `config.h` file:
```c
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
```
3. On ARM platforms you must turn on ChibiOS `PAL_USE_CALLBACKS` feature:
* In `halconf.h` add the line `#define PAL_USE_CALLBACKS TRUE`.
<hr>
## USART Half-duplex
Targeting ARM boards based on ChibiOS, where communication is offloaded to a USART hardware device that supports Half-duplex operation. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose Half-duplex over Bitbang if MCU is capable of utilising Half-duplex, and Full-duplex can't be used instead (e.g. lack of available GPIO pins, or imcompatible PCB design).
### Pin configuration
```
LEFT RIGHT
+-------+ | | +-------+
| | R R | |
| | | SERIAL | | |
| TX |-----------------| TX |
| | VDD | |
| |-----------------| |
| | GND | |
| |-----------------| |
+-------+ +-------+
```
Only one GPIO pin is needed for the Half-duplex driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SERIAL_USART_TX_PIN` in the configuration. Ensure that the pin chosen for split communication can operate as the TX pin of the contoller's USART peripheral. A TRS or USB cable provides enough conductors for this driver to function. As the split connection is configured to operate in open-drain mode, an **external pull-up resistor is needed to keep the line high**. Resistor values of 1.5kΩ to 8.2kΩ are known to work.
::: warning
***Note:*** A pull-up resistor isn't required for RP2040 controllers configured with PIO subsystem.
:::
### Setup
To use the Half-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation, start at step 2.
1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = usart
```
Skip to step 3.
2. (RP2040 + PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = vendor
```
3. Configure the hardware of your keyboard via the `config.h` file:
```c
#define SERIAL_USART_TX_PIN B6 // The GPIO pin that is used split communication.
```
For STM32 MCUs several GPIO configuration options can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus).
```c
#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
```
4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
<hr>
## 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.
### Pin configuration
```
LEFT RIGHT
+-------+ +-------+
| | SERIAL | |
| TX |-----------------| RX |
| | SERIAL | |
| RX |-----------------| TX |
| | VDD | |
| |-----------------| |
| | GND | |
| |-----------------| |
+-------+ +-------+
```
Two GPIO pins are needed for the Full-duplex driver, as two distinct wires are used for receiving and transmitting data. The pin transmitting data is the `TX` pin and refereed to as the `SERIAL_USART_TX_PIN`, the pin receiving data is the `RX` pin and refereed to as the `SERIAL_USART_RX_PIN` in this configuration. Please note that `TX` pin of the master half has to be connected with the `RX` pin of the slave half and the `RX` pin of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the PCB. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU. A TRRS or USB cable provides enough conductors for this driver to function.
To use this driver the USART peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C development board everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refer to the corresponding datasheets of your MCU or find those settings in the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus).
### Setup
To use the Full-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation, start at step 2
1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = usart
```
Skip to step 3
2. (RP2040 + PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
```make
SERIAL_DRIVER = vendor
```
3. Configure the hardware of your keyboard via the `config.h` file:
```c
#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode.
#define SERIAL_USART_TX_PIN B6 // USART TX pin
#define SERIAL_USART_RX_PIN B7 // USART RX pin
```
For STM32 MCUs several GPIO configuration options, including the ability for `TX` to `RX` pin swapping, can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus).
```c
#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve. (Only available on some MCUs)
#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
```
4. Decide either for `SERIAL`, `SIO`, or `PIO` subsystem. See section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
<hr>
## Choosing a driver subsystem
### The `SERIAL` driver
The `SERIAL` Subsystem is supported for the majority of ChibiOS MCUs and should be used whenever supported. Follow these steps in order to activate it:
1. In your keyboards `halconf.h` add:
```c
#define HAL_USE_SERIAL TRUE
```
2. In your keyboards `mcuconf.h`: activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
Just below `#include_next <mcuconf.h>` add:
```c
#include_next <mcuconf.h>
#undef STM32_SERIAL_USE_USARTn
#define STM32_SERIAL_USE_USARTn TRUE
```
Where 'n' matches the peripheral number of your selected USART on the MCU.
3. In you keyboards `config.h`: override the default USART `SERIAL` driver if you use a USART peripheral that does not belong to the default selected `SD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SD3`.
```c
#define SERIAL_USART_DRIVER SD3
```
### The `SIO` driver
The `SIO` Subsystem was added to ChibiOS with the 21.11 release and is only supported on selected MCUs. It should only be chosen when the `SERIAL` subsystem is not supported by your MCU.
Follow these steps in order to activate it:
1. In your keyboards `halconf.h` add:
```c
#define HAL_USE_SIO TRUE
```
2. In your keyboards `mcuconf.h:` activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
Just below `#include_next <mcuconf.h>` add:
```c
#include_next <mcuconf.h>
#undef STM32_SIO_USE_USARTn
#define STM32_SIO_USE_USARTn TRUE
```
Where 'n' matches the peripheral number of your selected USART on the MCU.
3. In 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`.
```c
#define SERIAL_USART_DRIVER SIOD3
```
### The `PIO` driver
The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using an integrated PIO peripheral and is therefore only available on this MCU. Because of the flexible nature of PIO peripherals, **any** GPIO pin can be used as a `TX` or `RX` pin. Half-duplex and Full-duplex operation modes are fully supported with this driver. Half-duplex uses the built-in pull-ups and GPIO manipulation of the RP2040 to drive the line high by default, thus an external pull-up resistor **is not required**.
Optionally, the PIO peripheral utilized for split communication can be changed with the following define in config.h:
```c
#define SERIAL_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the Serial implementation uses the PIO0 peripheral
```
The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on.
<hr>
## Advanced Configuration
There are several advanced configuration options that can be defined in your keyboards `config.h` file:
### Baudrate
If you're having issues or need a higher baudrate with serial communication, you can change the baudrate which in turn controls the communication speed for serial. You want to lower the baudrate if you experience failed transactions.
```c
#define SELECT_SOFT_SERIAL_SPEED {#}
```
| Speed | Bitbang | Half-duplex and Full-duplex |
| ----- | -------------------------- | --------------------------- |
| `0` | 189000 baud (experimental) | 460800 baud |
| `1` | 137000 baud (default) | 230400 baud (default) |
| `2` | 75000 baud | 115200 baud |
| `3` | 39000 baud | 57600 baud |
| `4` | 26000 baud | 38400 baud |
| `5` | 20000 baud | 19200 baud |
Alternatively you can specify the baudrate directly by defining `SERIAL_USART_SPEED`.
### Timeout
This is the default time window in milliseconds in which a successful communication has to complete. Usually you don't want to change this value. But you can do so anyways by defining an alternate one in your keyboards `config.h` file:
```c
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
```
<hr>
## Troubleshooting
If you're having issues withe serial communication, you can enable debug messages that will give you insights which part of the communication failed. The enable these messages add to your keyboards `config.h` file:
```c
#define SERIAL_DEBUG
```
::: tip
The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](../faq_debug).
:::
## Alternate Functions for selected STM32 MCUs
Pins for USART Peripherals with
### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf)
Pin Swap available: :heavy_check_mark:
| Pin | Function | Mode |
| ---------- | -------- | ---- |
| **USART1** | | |
| PA9 | TX | AF7 |
| PA10 | RX | AF7 |
| PB6 | TX | AF7 |
| PB7 | RX | AF7 |
| PC4 | TX | AF7 |
| PC5 | RX | AF7 |
| PE0 | TX | AF7 |
| PE1 | RX | AF7 |
| **USART2** | | |
| PA2 | TX | AF7 |
| PA3 | RX | AF7 |
| PA14 | TX | AF7 |
| PA15 | RX | AF7 |
| PB3 | TX | AF7 |
| PB4 | RX | AF7 |
| PD5 | TX | AF7 |
| PD6 | RX | AF7 |
| **USART3** | | |
| PB10 | TX | AF7 |
| PB11 | RX | AF7 |
| PC10 | TX | AF7 |
| PC11 | RX | AF7 |
| PD8 | TX | AF7 |
| PD9 | RX | AF7 |
### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf)
Pin Swap available: :heavy_check_mark:
| Pin | Function | Mode |
| ------ | -------- | ---- |
| USART1 | | |
| PA9 | TX | AF1 |
| PA10 | RX | AF1 |
| PB6 | TX | AF0 |
| PB7 | RX | AF0 |
| USART2 | | |
| PA2 | TX | AF1 |
| PA3 | RX | AF1 |
| PA14 | TX | AF1 |
| PA15 | RX | AF1 |
| USART3 | | |
| PB10 | TX | AF4 |
| PB11 | RX | AF4 |
| PC4 | TX | AF1 |
| PC5 | RX | AF1 |
| PC10 | TX | AF1 |
| PC11 | RX | AF1 |
| PD8 | TX | AF0 |
| PD9 | RX | AF0 |
| USART4 | | |
| PA0 | TX | AF4 |
| PA1 | RX | AF4 |
### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)
Pin Swap available: N/A
TX Pin is always Alternate Function Push-Pull, RX Pin is always regular input pin for any USART peripheral. **For STM32F103 no additional Alternate Function configuration is necessary. QMK is already configured.**
Pin remapping:
The pins of USART Peripherals use default Pins that can be remapped to use other pins using the AFIO registers. Default pins are marked **bold**. Add the appropriate defines to your config.h file.
| Pin | Function | Mode | USART_REMAP |
| ---------- | -------- | ---- | ------------------- |
| **USART1** | | | |
| **PA9** | TX | AFPP | |
| **PA10** | RX | IN | |
| PB6 | TX | AFPP | USART1_REMAP |
| PB7 | RX | IN | USART1_REMAP |
| **USART2** | | | |
| **PA2** | TX | AFPP | |
| **PA3** | RX | IN | |
| PD5 | TX | AFPP | USART2_REMAP |
| PD6 | RX | IN | USART2_REMAP |
| **USART3** | | | |
| **PB10** | TX | AFPP | |
| **PB11** | RX | IN | |
| PC10 | TX | AFPP | USART3_PARTIALREMAP |
| PC11 | RX | IN | USART3_PARTIALREMAP |
| PD8 | TX | AFPP | USART3_FULLREMAP |
| PD9 | RX | IN | USART3_FULLREMAP |

245
docs/drivers/snled27351.md Normal file
View File

@@ -0,0 +1,245 @@
# SNLED27351 Driver {#snled27351-driver}
I²C 16x12 LED matrix driver by Sonix. Supports a maximum of four drivers, each controlling up to 192 single-color LEDs, or 64 RGB LEDs.
A slightly modified version of this IC is also known as "CKLED2001".
[SNLED27351 Datasheet](https://www.sonix.com.tw/files/1/D235860C0C037C28E050007F01001CBE)
## Usage {#usage}
The SNLED27351 driver code is automatically included if you are using the [LED Matrix](../features/led_matrix) or [RGB Matrix](../features/rgb_matrix) feature with the `snled27351` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add this to your `rules.mk`:
```make
COMMON_VPATH += $(DRIVER_PATH)/led
SRC += snled27351-mono.c # For single-color
SRC += snled27351.c # For RGB
I2C_DRIVER_REQUIRED = yes
```
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|----------------------------|-------------|----------------------------------------------------|
|`SNLED27351_SDB_PIN` |*Not defined*|The GPIO pin connected to the drivers' shutdown pins|
|`SNLED27351_I2C_TIMEOUT` |`100` |The I²C timeout in milliseconds |
|`SNLED27351_I2C_PERSISTENCE`|`0` |The number of times to retry I²C transmissions |
|`SNLED27351_I2C_ADDRESS_1` |*Not defined*|The I²C address of driver 0 |
|`SNLED27351_I2C_ADDRESS_2` |*Not defined*|The I²C address of driver 1 |
|`SNLED27351_I2C_ADDRESS_3` |*Not defined*|The I²C address of driver 2 |
|`SNLED27351_I2C_ADDRESS_4` |*Not defined*|The I²C address of driver 3 |
### I²C Addressing {#i2c-addressing}
The SNLED27351 has four possible 7-bit I²C addresses, depending on how the `ADDR` pin is connected.
To configure this, set the `SNLED27351_I2C_ADDRESS_n` defines to one of the following in your `config.h`, where *n* denotes the driver index:
|Define |Value |
|------------------------------|------|
|`SNLED27351_I2C_ADDRESS_GND` |`0x74`|
|`SNLED27351_I2C_ADDRESS_SCL` |`0x75`|
|`SNLED27351_I2C_ADDRESS_SDA` |`0x76`|
|`SNLED27351_I2C_ADDRESS_VDDIO`|`0x77`|
## ARM/ChibiOS Configuration {#arm-configuration}
Depending on the ChibiOS board configuration, you may need to [enable and configure I²C](i2c#arm-configuration) at the keyboard level.
## LED Mapping {#led-mapping}
In order to use this driver, each output must be mapped to an LED index, by adding the following to your `<keyboardname>.c`:
```c
const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
/* Driver
* | R G B */
{0, CB1_CA1, CB1_CA2, CB1_CA3},
// etc...
};
```
In this example, the red, green and blue channels for the first LED index on driver 0 all have their cathodes connected to the `CB1` pin, and their anodes on the `CA1`, `CA2` and `CA3` pins respectively.
For the single-color driver, the principle is the same, but there is only one channel:
```c
const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
/* Driver
* | V */
{0, CB1_CA1},
// etc...
};
```
These values correspond to the register indices as shown in the datasheet on page 13.
## API {#api}
### `struct snled27351_led_t` {#api-snled27351-led-t}
Contains the PWM register addresses for a single RGB LED.
#### Members {#api-snled27351-led-t-members}
- `uint8_t driver`
The driver index of the LED, from 0 to 3.
- `uint8_t r`
The output PWM register address for the LED's red channel (RGB driver only).
- `uint8_t g`
The output PWM register address for the LED's green channel (RGB driver only).
- `uint8_t b`
The output PWM register address for the LED's blue channel (RGB driver only).
- `uint8_t v`
The output PWM register address for the LED (single-color driver only).
---
### `void snled27351_init(uint8_t index)` {#api-snled27351-init}
Initialize the LED driver. This function should be called first.
#### Arguments {#api-snled27351-init-arguments}
- `uint8_t index`
The driver index.
---
### `void snled27351_write_register(uint8_t index, uint8_t reg, uint8_t data)` {#api-snled27351-write-register}
Set the value of the given register.
#### Arguments {#api-snled27351-write-register-arguments}
- `uint8_t index`
The driver index.
- `uint8_t reg`
The register address.
- `uint8_t data`
The value to set.
---
### `void snled27351_select_page(uint8_t index, uint8_t page)` {#api-snled27351-select-page}
Change the current page for configuring the LED driver.
#### Arguments {#api-snled27351-select-page-arguments}
- `uint8_t index`
The driver index.
- `uint8_t page`
The page number to select.
---
### `void snled27351_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-snled27351-set-color}
Set the color of a single LED (RGB driver only). This function does not immediately update the LEDs; call `snled27351_update_pwm_buffers()` after you are finished.
#### Arguments {#api-snled27351-set-color-arguments}
- `int index`
The LED index (ie. the index into the `g_snled27351_leds` array).
- `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 snled27351_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-snled27351-set-color-all}
Set the color of all LEDs (RGB driver only).
#### Arguments {#api-snled27351-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 snled27351_set_value(int index, uint8_t value)` {#api-snled27351-set-value}
Set the brightness of a single LED (single-color driver only). This function does not immediately update the LEDs; call `snled27351_update_pwm_buffers()` after you are finished.
#### Arguments {#api-snled27351-set-value-arguments}
- `int index`
The LED index (ie. the index into the `g_snled27351_leds` array).
- `uint8_t value`
The brightness value to set.
---
### `void snled27351_set_value_all(uint8_t value)` {#api-snled27351-set-value-all}
Set the brightness of all LEDs (single-color driver only).
#### Arguments {#api-snled27351-set-value-all-arguments}
- `uint8_t value`
The brightness value to set.
---
### `void snled27351_set_led_control_register(uint8_t index, bool red, bool green, bool blue)` {#api-snled27351-set-led-control-register-rgb}
Configure the LED control registers for a single LED (RGB driver only). This function does not immediately update the LEDs; call `snled27351_update_led_control_registers()` after you are finished.
#### Arguments {#api-snled27351-set-led-control-register-rgb-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_snled27351_leds` array).
- `bool red`
Enable or disable the red channel.
- `bool green`
Enable or disable the green channel.
- `bool blue`
Enable or disable the blue channel.
---
### `void snled27351_set_led_control_register(uint8_t index, bool value)` {#api-snled27351-set-led-control-register-mono}
Configure the LED control registers for a single LED (single-color driver only). This function does not immediately update the LEDs; call `snled27351_update_led_control_registers()` after you are finished.
#### Arguments {#api-snled27351-set-led-control-register-mono-arguments}
- `uint8_t index`
The LED index (ie. the index into the `g_snled27351_leds` array).
- `bool value`
Enable or disable the LED.
---
### `void snled27351_update_pwm_buffers(uint8_t index)` {#api-snled27351-update-pwm-buffers}
Flush the PWM values to the LED driver.
#### Arguments {#api-snled27351-update-pwm-buffers-arguments}
- `uint8_t index`
The driver index.
---
### `void snled27351_update_led_control_registers(uint8_t index)` {#api-snled27351-update-led-control-registers}
Flush the LED control register values to the LED driver.
#### Arguments {#api-snled27351-update-led-control-registers-arguments}
- `uint8_t index`
The driver index.

167
docs/drivers/spi.md Normal file
View File

@@ -0,0 +1,167 @@
# SPI Master Driver {#spi-master-driver}
The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs.
## Usage {#usage}
In most cases, the SPI Master driver code is automatically included if you are using a feature or driver which requires it, such as [OLED](../features/oled_driver).
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
SPI_DRIVER_REQUIRED = yes
```
You can then call the SPI API by including `spi_master.h` in your code.
## AVR Configuration {#avr-configuration}
No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU:
|MCU |`SS`|`SCK`|`MOSI`|`MISO`|
|-----------------|----|-----|------|------|
|ATmega16/32U2/4 |`B0`|`B1` |`B2` |`B3` |
|AT90USB64/128/162|`B0`|`B1` |`B2` |`B3` |
|ATmega32A |`B4`|`B7` |`B5` |`B6` |
|ATmega328/P |`B2`|`B5` |`B3` |`B4` |
You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually.
`SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`.
## ChibiOS/ARM Configuration {#arm-configuration}
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:
```c
#define HAL_USE_SPI TRUE
#define SPI_USE_WAIT TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
```
Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example:
```c
#undef STM32_SPI_USE_SPI2
#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.
|`config.h` Override|Description |Default|
|-------------------|-------------------------------------------------------------|-------|
|`SPI_DRIVER` |SPI peripheral to use - SPI1 -> `SPID1`, SPI2 -> `SPID2` etc.|`SPID2`|
|`SPI_SCK_PIN` |The pin to use for SCK |`B13` |
|`SPI_SCK_PAL_MODE` |The alternate function mode for SCK |`5` |
|`SPI_MOSI_PIN` |The pin to use for MOSI |`B15` |
|`SPI_MOSI_PAL_MODE`|The alternate function mode for MOSI |`5` |
|`SPI_MISO_PIN` |The pin to use for MISO |`B14` |
|`SPI_MISO_PAL_MODE`|The alternate function mode for MISO |`5` |
As per the AVR configuration, you may choose any other standard GPIO as a slave select pin, which should be supplied to `spi_start()`.
If a complete SPI interface is not required, then the following can be done to disable certain SPI pins, so they don't occupy a GPIO unnecessarily:
- in `config.h`: `#define SPI_MISO_PIN NO_PIN`
- in `config.h`: `#define SPI_MOSI_PIN NO_PIN`
- in `mcuconf.h`: `#define SPI_SELECT_MODE SPI_SELECT_MODE_NONE`, in this case the `slavePin` argument passed to `spi_start()` may be `NO_PIN` if the slave select pin is not used.
## API {#api}
### `void spi_init(void)` {#api-spi-init}
Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
---
### `bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)` {#api-spi-start}
Start an SPI transaction.
#### Arguments {#api-spi-start-arguments}
- `pin_t slavePin`
The QMK pin to assert as the slave select pin, eg. `B4`.
- `bool lsbFirst`
Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
- `uint8_t mode`
The SPI mode to use:
|Mode|Clock Polarity |Clock Phase |
|----|--------------------|-----------------------|
|`0` |Leading edge rising |Sample on leading edge |
|`1` |Leading edge rising |Sample on trailing edge|
|`2` |Leading edge falling|Sample on leading edge |
|`3` |Leading edge falling|Sample on trailing edge|
- `uint16_t divisor`
The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`.
#### Return Value {#api-spi-start-return}
`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`.
---
### `spi_status_t spi_write(uint8_t data)` {#api-spi-write}
Write a byte to the selected SPI device.
#### Arguments {#api-spi-write-arguments}
- `uint8_t data`
The byte to write.
#### Return Value {#api-spi-write-return}
`SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`.
---
### `spi_status_t spi_read(void)` {#api-spi-read}
Read a byte from the selected SPI device.
#### Return Value {#api-spi-read-return}
`SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device.
---
### `spi_status_t spi_transmit(const uint8_t *data, uint16_t length)` {#api-spi-transmit}
Send multiple bytes to the selected SPI device.
#### Arguments {#api-spi-transmit-arguments}
- `const uint8_t *data`
A pointer to the data to write from.
- `uint16_t length`
The number of bytes to write. Take care not to overrun the length of `data`.
#### Return Value {#api-spi-transmit-return}
`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
---
### `spi_status_t spi_receive(uint8_t *data, uint16_t length)` {#api-spi-receive}
Receive multiple bytes from the selected SPI device.
#### Arguments {#api-spi-receive-arguments}
- `uint8_t *data`
A pointer to the buffer to read into.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
#### Return Value {#api-spi-receive-return}
`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`.
---
### `void spi_stop(void)` {#api-spi-stop}
End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`.

253
docs/drivers/ws2812.md Normal file
View File

@@ -0,0 +1,253 @@
# WS2812 Driver {#ws2812-driver}
This driver provides support for WorldSemi addressable RGB(W) LEDs, and compatible equivalents:
* WS2811, WS2812, WS2812B, WS2812C, etc.
* SK6812, SK6812MINI, SK6805
These LEDs are often called "addressable" because instead of using a wire per color (and per LED), each LED contains a small microchip that understands a special protocol sent over a single wire.
The LEDs can be chained together, and the remaining data is passed on to the next. In this way, you can easily control the color of many LEDs using a single GPIO.
## Usage {#usage}
In most cases, the WS2812 driver code is automatically included if you are using either the [RGBLight](../features/rgblight) or [RGB Matrix](../features/rgb_matrix) feature with the `ws2812` driver set, and you would use those APIs instead.
However, if you need to use the driver standalone, add the following to your `rules.mk`:
```make
WS2812_DRIVER_REQUIRED = yes
```
You can then call the WS2812 API by including `ws2812.h` in your code.
## Basic Configuration {#basic-configuration}
Add the following to your `config.h`:
|Define |Default |Description |
|-------------------|-----------------------|------------------------------------------------------------------------------------------------|
|`WS2812_DI_PIN` |*Not defined* |The GPIO pin connected to the DI pin of the first LED in the chain |
|`WS2812_LED_COUNT` |*Not defined* |Number of LEDs in the WS2812 chain - automatically set when RGBLight or RGB Matrix is configured|
|`WS2812_TIMING` |`1250` |The total length of a bit (TH+TL) in nanoseconds |
|`WS2812_T1H` |`900` |The length of a "1" bit's high phase in nanoseconds |
|`WS2812_T0H` |`350` |The length of a "0" bit's high phase in nanoseconds |
|`WS2812_TRST_US` |`280` |The length of the reset phase in microseconds |
|`WS2812_BYTE_ORDER`|`WS2812_BYTE_ORDER_GRB`|The byte order of the RGB data |
|`WS2812_RGBW` |*Not defined* |Enables RGBW support (except `i2c` driver) |
### Timing Adjustment {#timing-adjustment}
The WS2812 LED communication protocol works by encoding a "1" bit with a long high pulse (T<sub>1</sub>H), and a "0" bit with a shorter pulse (T<sub>0</sub>H). The total cycle length of a bit is the same.
The "reset" pulse (T<sub>RST</sub>) latches the sent RGB data to all of the LEDs and denotes a completed "frame".
Some WS2812 variants have slightly different timing parameter requirements, which can be accounted for if necessary using the above `#define`s in your `config.h`.
### Byte Order {#byte-order}
Some WS2812 variants may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB.
If you find your LED colors are consistently swapped, you may need to change the byte order by adding the following to your `config.h`:
```c
#define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
```
Where the byte order may be one of:
|Byte Order|Known Devices |
|----------|----------------------------|
|`GRB` |Most WS2812s, SK6812, SK6805|
|`RGB` |WS2812B-2020 |
|`BGR` |TM1812 |
### RGBW Support {#rgbw-support}
Rendering the color white with RGB LEDs is typically inconsistent due to inherent variations between each individual LED die. However, some WS2812 variants (such as SK6812RGBW) also possess a white LED along with the red, green, and blue channels, which allows for a more accurate white to be displayed.
QMK can automatically convert the RGB data to be sent to the LEDs to mix in the white channel:
```
w = min(r, g, b)
r -= w
g -= w
b -= w
```
Thus, an RGB triplet of `255,255,255` will simply turn on the white LED fully (`0,0,0,255`).
To enable RGBW conversion, add the following to your `config.h`:
```c
#define WS2812_RGBW
```
## Driver Configuration {#driver-configuration}
Driver selection can be configured in `rules.mk` as `WS2812_DRIVER`, or in `info.json` as `ws2812.driver`. Valid values are `bitbang` (default), `i2c`, `spi`, `pwm`, `vendor`, or `custom`. See below for information on individual drivers.
### Bitbang Driver {#bitbang-driver}
This is the default WS2812 driver. It operates by "bit-banging" ie. directly toggling the GPIO.
Please note that on AVR devices, due to the tight timing requirements longer chains and/or heavy CPU loads may cause visible lag. Unfortunately this driver is usually the only option for AVR.
```make
WS2812_DRIVER = bitbang
```
### I2C Driver {#i2c-driver}
A specialized driver mainly used for PS2AVRGB (Bootmapper Client) boards, which possess an ATtiny85 that handles the WS2812 LEDs.
```make
WS2812_DRIVER = i2c
```
The following `#define`s apply only to the `i2c` driver:
|Define |Default|Description |
|--------------------|-------|---------------------------------|
|`WS2812_I2C_ADDRESS`|`0xB0` |The I2C address of the ATtiny85. |
|`WS2812_I2C_TIMEOUT`|`100` |The I2C timeout, in milliseconds.|
### PIO Driver {#pio-driver}
This driver is RP2040-only, and leverages the onboard PIO (programmable I/O) system and DMA to offload processing from the CPU.
The WS2812 PIO program uses one state machine, six instructions and one DMA interrupt handler callback. Due to the implementation the time resolution for this driver is 50 ns - any value not specified in this interval will be rounded to the next matching interval.
```make
WS2812_DRIVER = vendor
```
### PWM Driver {#pwm-driver}
This driver is ARM-only, and leverages the onboard PWM peripheral and DMA to offload processing from the CPU.
```make
WS2812_DRIVER = pwm
```
### SPI Driver {#spi-driver}
This driver is ARM-only, and leverages the onboard SPI peripheral and DMA to offload processing from the CPU. The DI pin **must** be connected to the MOSI pin on the MCU, and all other SPI pins **must** be left unused. This is also very dependent on your MCU's SPI peripheral clock speed, and may or may not be possible depending on the MCU selected.
```make
WS2812_DRIVER = spi
```
## ChibiOS/ARM Configuration {#arm-configuration}
The following defines apply only to ARM devices:
|Define |Default |Description |
|------------|------------------------------|---------------------------------------------------------------------------------|
|`WS2812_T1L`|`(WS2812_TIMING - WS2812_T1H)`|The length of a "1" bit's low phase in nanoseconds (bitbang and PIO drivers only)|
|`WS2812_T0L`|`(WS2812_TIMING - WS2812_T0H)`|The length of a "0" bit's low phase in nanoseconds (bitbang and PIO drivers only)|
### Push-Pull and Open Drain {#push-pull-open-drain}
By default, the GPIO used for data transmission is configured as a *push-pull* output, meaning the pin is effectively always driven either to VCC or to ground.
For situations where the logic level voltage is lower than the power supply voltage, however, this can pose an issue. The solution is to configure the pin for *open drain* mode instead, and use a pullup resistor between the DI pin and VCC. In this mode, the MCU can only pull the GPIO *low*, or leave it floating. The pullup resistor is then responsible for pulling the line high, when the MCU is not driving the GPIO.
To configure the DI pin for open drain configuration, add the following to your `config.h`:
```c
#define WS2812_EXTERNAL_PULLUP
```
### SPI Driver {#arm-spi-driver}
Depending on the ChibiOS board configuration, you may need to enable SPI at the keyboard level. For STM32, this would look like:
`halconf.h`:
```c
#define HAL_USE_SPI TRUE
```
`mcuconf.h`:
```c
#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE
```
The following `define`s apply only to the `spi` driver:
|Define |Default |Description |
|--------------------------------|-------------|-------------------------------------------------------------------------------|
|`WS2812_SPI_DRIVER` |`SPID1` |The SPI driver to use |
|`WS2812_SPI_MOSI_PAL_MODE` |`5` |The MOSI pin alternative function to use |
|`WS2812_SPI_SCK_PIN` |*Not defined*|The SCK pin - required for F072 and possibly others |
|`WS2812_SPI_SCK_PAL_MODE` |`5` |The SCK pin alternative function to use - required for F072 and possibly others|
|`WS2812_SPI_DIVISOR` |`16` |The divisor used to adjust the baudrate |
|`WS2812_SPI_USE_CIRCULAR_BUFFER`|*Not defined*|Enable a circular buffer for improved rendering |
#### Setting the Baudrate {#arm-spi-baudrate}
To adjust the SPI baudrate, you will need to derive the target baudrate from the clock tree provided by STM32CubeMX, and add the following to your `config.h`:
```c
#define WS2812_SPI_DIVISOR 16
```
Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported on STM32 devices. Other MCUs may have similar constraints -- check the reference manual for your respective MCU for specifics.
#### Circular Buffer {#arm-spi-circular-buffer}
A circular buffer can be enabled if you experience flickering.
To enable the circular buffer, add the following to your `config.h`:
```c
#define WS2812_SPI_USE_CIRCULAR_BUFFER
```
### PIO Driver {#arm-pio-driver}
The following `#define`s apply only to the PIO driver:
|Define |Default |Description |
|---------------------|-------------|---------------------------------------|
|`WS2812_PIO_USE_PIO1`|*Not defined*|Use the PIO1 peripheral instead of PIO0|
### PWM Driver {#arm-pwm-driver}
Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:
`halconf.h`:
```c
#define HAL_USE_PWM TRUE
```
`mcuconf.h`:
```c
#undef STM32_PWM_USE_TIM2
#define STM32_PWM_USE_TIM2 TRUE
```
The following `#define`s apply only to the `pwm` driver:
|Define |Default |Description |
|---------------------------------|--------------------|------------------------------------------------------------------------------------------|
|`WS2812_PWM_DRIVER` |`PWMD2` |The PWM driver to use |
|`WS2812_PWM_CHANNEL` |`2` |The PWM channel to use |
|`WS2812_PWM_PAL_MODE` |`2` |The pin alternative function to use |
|`WS2812_PWM_DMA_STREAM` |`STM32_DMA1_STREAM2`|The DMA Stream for `TIMx_UP` |
|`WS2812_PWM_DMA_CHANNEL` |`2` |The DMA Channel for `TIMx_UP` |
|`WS2812_PWM_DMAMUX_ID` |*Not defined* |The DMAMUX configuration for `TIMx_UP` - only required if your MCU has a DMAMUX peripheral|
|`WS2812_PWM_COMPLEMENTARY_OUTPUT`|*Not defined* |Whether the PWM output is complementary (`TIMx_CHyN`) |
::: 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.
:::
## API {#api}
### `void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds)` {#api-ws2812-setleds}
Send RGB data to the WS2812 LED chain.
#### Arguments {#api-ws2812-setleds-arguments}
- `rgb_led_t *ledarray`
A pointer to the LED array.
- `uint16_t number_of_leds`
The length of the LED array.

View File

@@ -5,7 +5,7 @@ Have you ever needed an easy way to program a controller, such as a Proton C or
There are different styles of Easy Maker available depending on your needs:
* [Direct Pin](https://config.qmk.fm/#/?filter=ez_maker/direct) - Connect a single switch to a single pin
* Direct Pin + Backlight (Coming Soon) - Like Direct Pin but dedicates a single pin to [Backlight](feature_backlight) control
* Direct Pin + Backlight (Coming Soon) - Like Direct Pin but dedicates a single pin to [Backlight](features/backlight) control
* Direct Pin + Numlock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Numlock LED
* Direct Pin + Capslock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Capslock LED
* Direct Pin + Encoder (Coming Soon) - Like Direct Pin but uses 2 pins to add a single rotary encoder

View File

@@ -1,180 +0,0 @@
# EEPROM Driver Configuration {#eeprom-driver-configuration}
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
Selecting the EEPROM driver is done in your keyboard's `rules.mk`:
Driver | Description
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash.
## Vendor Driver Configuration {#vendor-eeprom-driver-configuration}
#### STM32 L0/L1 Configuration {#stm32l0l1-eeprom-driver-configuration}
::: warning
Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
:::
`config.h` override | Description | Default Value
------------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------
`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled.
## I2C Driver Configuration {#i2c-eeprom-driver-configuration}
Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
`config.h` override | Description | Default Value
------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------
`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000
`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)`
`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
`#define EXTERNAL_EEPROM_WP_PIN` | If defined the WP pin will be toggled appropriately when writing to the EEPROM. | _none_
Some I2C EEPROM manufacturers explicitly recommend against hardcoding the WP pin to ground. This is in order to protect the eeprom memory content during power-up/power-down/brown-out conditions at low voltage where the eeprom is still operational, but the i2c master output might be unpredictable. If a WP pin is configured, then having an external pull-up on the WP pin is recommended.
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
Alternatively, there are pre-defined hardware configurations for available chips/modules:
Module | Equivalent `#define` | Source
-----------------|---------------------------------|------------------------------------------
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
24LC32A EEPROM | `#define EEPROM_I2C_24LC32A` | <https://www.microchip.com/en-us/product/24LC32A>
24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/en-us/product/24LC64>
24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/en-us/product/24LC128>
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
::: tip
If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
:::
## SPI Driver Configuration {#spi-eeprom-driver-configuration}
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
`config.h` override | Default Value | Description
-----------------------------------------------|---------------|-------------------------------------------------------------------------------------
`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | _none_ | SPI Slave select pin in order to inform that the EEPROM is currently being addressed
`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | `64` | Clock divisor used to divide the peripheral clock to derive the SPI frequency
`#define EXTERNAL_EEPROM_BYTE_COUNT` | `8192` | Total size of the EEPROM in bytes
`#define EXTERNAL_EEPROM_PAGE_SIZE` | `32` | Page size of the EEPROM in bytes, as specified in the datasheet
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | `2` | The number of bytes to transmit for the memory location within the EEPROM
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_spi.h`.
Alternatively, there are pre-defined hardware configurations for available chips/modules:
Module | Equivalent `#define` | Source
-----------------|---------------------------------|------------------------------------------
MB85RS64V FRAM | `define EEPROM_SPI_MB85RS64V` | <https://www.adafruit.com/product/1897>
::: warning
There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
:::
## Transient Driver configuration {#transient-eeprom-driver-configuration}
The only configurable item for the transient EEPROM driver is its size:
`config.h` override | Description | Default Value
------------------------------- | ----------------------------------------- | -------------
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
## Wear-leveling Driver Configuration {#wear_leveling-eeprom-driver-configuration}
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
# Wear-leveling Configuration {#wear_leveling-configuration}
The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
Driver | Description
----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU.
`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals.
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
::: warning
All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
:::
## Wear-leveling Embedded Flash Driver Configuration {#wear_leveling-efl-driver-configuration}
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
-----------------------------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration.
`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `(backing_size/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
::: warning
If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
:::
## Wear-leveling SPI Flash Driver Configuration {#wear_leveling-flash_spi-driver-configuration}
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver) documentation for more information.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
----------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB.
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
::: warning
There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
:::
## Wear-leveling RP2040 Driver Configuration {#wear_leveling-rp2040-driver-configuration}
This driver performs writes to the same underlying storage that the RP2040 executes its code.
Configurable options in your keyboard's `config.h`:
`config.h` override | Default | Description
------------------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------
`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board.
`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located.
`#define WEAR_LEVELING_LOGICAL_SIZE` | `(backing_size/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
## Wear-leveling Legacy EEPROM Emulation Driver Configuration {#wear_leveling-legacy-driver-configuration}
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
By default, `1024` bytes of emulated EEPROM is provided:
MCU | EEPROM Provided | Flash Used
----------|-----------------|--------------
STM32F042 | `1024` bytes | `2048` bytes
STM32F070 | `1024` bytes | `2048` bytes
STM32F072 | `1024` bytes | `2048` bytes
STM32F401 | `1024` bytes | `16384` bytes
STM32F411 | `1024` bytes | `16384` bytes
Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code.

View File

@@ -66,4 +66,4 @@ Due to how EEPROM works on ARM based chips, saved settings may no longer be vali
[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) can be used to force an eeprom reset. After flashing this image, flash your normal firmware again which should restore your keyboard to _normal_ working order.
[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin)
If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](feature_bootmagic) and keyboard info for specifics on how to do this).
If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](features/bootmagic) and keyboard info for specifics on how to do this).

View File

@@ -4,7 +4,7 @@ This page details various common questions people have about troubleshooting the
## Debugging {#debugging}
Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DB_TOGG` keycode in your keymap, use the [Command](feature_command) feature to enable debug mode, or add the following code to your keymap.
Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DB_TOGG` keycode in your keymap, use the [Command](features/command) feature to enable debug mode, or add the following code to your keymap.
```c
void keyboard_post_init_user(void) {

View File

@@ -40,7 +40,7 @@ That's amazing! We would love to assist you with that!
In fact, we have a [whole page](https://qmk.fm/powered/) dedicated to adding QMK Branding to your page and keyboard. This covers pretty much everything you need (knowledge and images) to officially support QMK.
If you have any questions about this, open an issue or head to [Discord](https://discord.gg/Uq7gcHh).
If you have any questions about this, open an issue or head to [Discord](https://discord.gg/qmk).
## What Differences Are There Between QMK and TMK?

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:
* 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.
* 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.
@@ -45,7 +45,7 @@ QMK has a couple of features which allow you to change the behavior of your keyb
Refer to the EEPROM clearing methods above, which should return those keys to normal operation. If that doesn't work, look here:
* [Magic Keycodes](keycodes_magic)
* [Command](feature_command)
* [Command](features/command)
## The Menu Key Isn't Working
@@ -86,7 +86,7 @@ Old vintage mechanical keyboards occasionally have lock switches but modern ones
## Input Special Characters Other Than ASCII like Cédille 'Ç'
See the [Unicode](feature_unicode) feature.
See the [Unicode](features/unicode) feature.
## `Fn` Key on macOS
@@ -130,7 +130,7 @@ https://github.com/tekezo/Karabiner/issues/403
## Esc and <code>&#96;</code> on a Single Key
See the [Grave Escape](feature_grave_esc) feature.
See the [Grave Escape](features/grave_esc) feature.
## Eject on Mac OSX

View File

@@ -160,7 +160,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
};
```
Alternatively, this can be done with [Key Overrides](feature_key_overrides#simple-example).
Alternatively, this can be done with [Key Overrides](features/key_overrides#simple-example).
# Advanced topics {#advanced-topics}
@@ -184,4 +184,4 @@ This page used to encompass a large set of features. We have moved many sections
## Key Overrides {#key-overrides}
* [Key Overrides](feature_key_overrides)
* [Key Overrides](features/key_overrides)

View File

@@ -1,377 +0,0 @@
# Audio
Your keyboard can make sounds! If you've got a spare pin you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes.
To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`.
## AVR based boards
On Atmega32U4 based boards, up to two simultaneous tones can be rendered.
With one speaker connected to a PWM capable pin on PORTC driven by timer 3 and the other on one of the PWM pins on PORTB driven by timer 1.
The following pins can be configured as audio outputs in `config.h` - for one speaker set either one out of:
* `#define AUDIO_PIN C4`
* `#define AUDIO_PIN C5`
* `#define AUDIO_PIN C6`
* `#define AUDIO_PIN B5`
* `#define AUDIO_PIN B6`
* `#define AUDIO_PIN B7`
and *optionally*, for a second speaker, one of:
* `#define AUDIO_PIN_ALT B5`
* `#define AUDIO_PIN_ALT B6`
* `#define AUDIO_PIN_ALT B7`
### Wiring
per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary.
## ARM based boards
for more technical details, see the notes on [Audio driver](audio_driver).
<!-- because I'm not sure where to fit this in: https://waveeditonline.com/ -->
### DAC (basic)
Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either:
`#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`
the other DAC channel can optionally be used with a secondary speaker, just set:
`#define AUDIO_PIN_ALT A4` or `#define AUDIO_PIN_ALT A5`
Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver.
#### Wiring:
for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black
another alternative is to drive *one* piezo with both DAC pins - for an extra "push".
wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h`
##### Proton-C Example:
The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5.
For this board `config.h` would include these defines:
```c
#define AUDIO_PIN A5
#define AUDIO_PIN_ALT A4
#define AUDIO_PIN_ALT_AS_NEGATIVE
```
### DAC (additive)
Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis.
With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly.
To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`.
The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`:
* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE`
* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE`
* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID`
* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE`
Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable
### PWM (software)
if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); PWM can be an alternative.
Note that there is currently only one speaker/pin supported.
set in `rules.mk`:
`AUDIO_DRIVER = pwm_software` and in `config.h`:
`#define AUDIO_PIN C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software.
#### Wiring
the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground.
OR if you can chose to drive one piezo with two pins, for example `#define AUDIO_PIN B1`, `#define AUDIO_PIN_ALT B2` in `config.h`, with `#define AUDIO_PIN_ALT_AS_NEGATIVE` - then the red lead could go to B1, the black to B2.
### PWM (hardware)
STM32F1xx have to fall back to using PWM, but can do so in hardware; but again on currently only one speaker/pin.
`AUDIO_DRIVER = pwm_hardware` in `rules.mk`, and in `config.h`:
`#define AUDIO_PIN A8`
`#define AUDIO_PWM_DRIVER PWMD1`
`#define AUDIO_PWM_CHANNEL 1`
(as well as `#define AUDIO_PWM_PAL_MODE 42` if you are on STM32F2 or larger)
which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8).
Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function.
## Tone Multiplexing
Since most drivers can only render one tone per speaker at a time (with the one exception: arm dac-additive) there also exists a "workaround-feature" that does time-slicing/multiplexing - which does what the name implies: cycle through a set of active tones (e.g. when playing chords in Music Mode) at a given rate, and put one tone at a time out through the one/few speakers that are available.
To enable this feature, and configure a starting-rate, add the following defines to `config.h`:
```c
#define AUDIO_ENABLE_TONE_MULTIPLEXING
#define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 10
```
The audio core offers interface functions to get/set/change the tone multiplexing rate from within `keymap.c`.
## Songs
There's a couple of different sounds that will automatically be enabled without any other configuration:
```
STARTUP_SONG // plays when the keyboard starts up (audio.c)
GOODBYE_SONG // plays when you press the QK_BOOT key (quantum.c)
AG_NORM_SONG // plays when you press AG_NORM (quantum.c)
AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c)
CG_NORM_SONG // plays when you press CG_NORM (quantum.c)
CG_SWAP_SONG // plays when you press CG_SWAP (quantum.c)
MUSIC_ON_SONG // plays when music mode is activated (process_music.c)
MUSIC_OFF_SONG // plays when music mode is deactivated (process_music.c)
CHROMATIC_SONG // plays when the chromatic music mode is selected (process_music.c)
GUITAR_SONG // plays when the guitar music mode is selected (process_music.c)
VIOLIN_SONG // plays when the violin music mode is selected (process_music.c)
MAJOR_SONG // plays when the major music mode is selected (process_music.c)
```
You can override the default songs by doing something like this in your `config.h`:
```c
#ifdef AUDIO_ENABLE
# define STARTUP_SONG SONG(STARTUP_SOUND)
#endif
```
A full list of sounds can be found in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) - feel free to add your own to this list! All available notes can be seen in [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h).
Additionally, if you with to maintain your own list of songs (such as ones that may be copyrighted) and not have them added to the repo, you can create a `user_song_list.h` file and place it in your keymap (or userspace) folder. This file will be automatically included, it just needs to exist.
To play a custom sound at a particular time, you can define a song like this (near the top of the file):
```c
float my_song[][2] = SONG(QWERTY_SOUND);
```
And then play your song like this:
```c
PLAY_SONG(my_song);
```
Alternatively, you can play it in a loop like this:
```c
PLAY_LOOP(my_song);
```
It's advised that you wrap all audio features in `#ifdef AUDIO_ENABLE` / `#endif` to avoid causing problems when audio isn't built into the keyboard.
The available keycodes for audio are:
|Key |Aliases |Description |
|-------------------------|---------|-------------------------------------------|
|`QK_AUDIO_ON` |`AU_ON` |Turns on Audio Feature |
|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature |
|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state |
::: warning
These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely.
:::
## Audio Config
| Settings | Default | Description |
|----------------------------------|----------------------|---------------------------------------------------------------------------------------------|
|`AUDIO_PIN` | *Not defined* |Configures the pin that the speaker is connected to. |
|`AUDIO_PIN_ALT` | *Not defined* |Configures the pin for a second speaker or second pin connected to one speaker. |
|`AUDIO_PIN_ALT_AS_NEGATIVE` | *Not defined* |Enables support for one speaker connected to two pins. |
|`AUDIO_INIT_DELAY` | *Not defined* |Enables delay during startup song to accomidate for USB startup issues. |
|`AUDIO_ENABLE_TONE_MULTIPLEXING` | *Not defined* |Enables time splicing/multiplexing to create multiple tones simutaneously. |
|`AUDIO_POWER_CONTROL_PIN` | *Not defined* |Enables power control code to enable or cut off power to speaker (such as with PAM8302 amp). |
|`AUDIO_POWER_CONTROL_PIN_ON_STATE`| `1` |The state of the audio power control pin when audio is "on" - `1` for high, `0` for low. |
|`STARTUP_SONG` | `STARTUP_SOUND` |Plays when the keyboard starts up (audio.c) |
|`GOODBYE_SONG` | `GOODBYE_SOUND` |Plays when you press the QK_BOOT key (quantum.c) |
|`AG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press AG_NORM (process_magic.c) |
|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) |
|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) |
|`CG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press CG_SWAP (process_magic.c) |
|`MUSIC_ON_SONG` | `MUSIC_ON_SOUND` |Plays when music mode is activated (process_music.c) |
|`MUSIC_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when music mode is deactivated (process_music.c) |
|`MIDI_ON_SONG` | `MUSIC_ON_SOUND` |Plays when midi mode is activated (process_music.c) |
|`MIDI_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when midi mode is deactivated (process_music.c) |
|`CHROMATIC_SONG` | `CHROMATIC_SOUND` |Plays when the chromatic music mode is selected (process_music.c) |
|`GUITAR_SONG` | `GUITAR_SOUND` |Plays when the guitar music mode is selected (process_music.c) |
|`VIOLIN_SONG` | `VIOLIN_SOUND` |Plays when the violin music mode is selected (process_music.c) |
|`MAJOR_SONG` | `MAJOR_SOUND` |Plays when the major music mode is selected (process_music.c) |
|`DEFAULT_LAYER_SONGS` | *Not defined* |Plays song when switched default layers with [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer)(quantum.c). |
|`SENDSTRING_BELL` | *Not defined* |Plays chime when the "enter" ("\a") character is sent (send_string.c) |
## Tempo
the 'speed' at which SONGs are played is dictated by the set Tempo, which is measured in beats-per-minute. Note lengths are defined relative to that.
The initial/default tempo is set to 120 bpm, but can be configured by setting `TEMPO_DEFAULT` in `config.c`.
There is also a set of functions to modify the tempo from within the user/keymap code:
```c
void audio_set_tempo(uint8_t tempo);
void audio_increase_tempo(uint8_t tempo_change);
void audio_decrease_tempo(uint8_t tempo_change);
```
## ARM Audio Volume
For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `AUDIO_DAC_SAMPLE_MAX` in your `config.h`:
```c
#define AUDIO_DAC_SAMPLE_MAX 4095U
```
the DAC usually runs in 12Bit mode, hence a volume of 100% = 4095U
Note: this only adjusts the volume aka 'works' if you stick to WAVEFORM_SQUARE, since its samples are generated on the fly - any other waveform uses a hardcoded/precomputed sample-buffer.
## Voices
Aka "audio effects", different ones can be enabled by setting in `config.h` these defines:
`#define AUDIO_VOICES` to enable the feature, and `#define AUDIO_VOICE_DEFAULT something` to select a specific effect
for details see quantum/audio/voices.h and .c
Keycodes available:
|Key |Aliases |Description |
|-------------------------|---------|-------------------------------------------|
|`QK_AUDIO_VOICE_NEXT` |`AU_NEXT`|Cycles through the audio voices |
|`QK_AUDIO_VOICE_PREVIOUS`|`AU_PREV`|Cycles through the audio voices in reverse |
## Music Mode
The music mode maps your columns to a chromatic scale, and your rows to octaves. This works best with ortholinear keyboards, but can be made to work with others. All keycodes less than `0xFF` get blocked, so you won't type while playing notes - if you have special keys/mods, those will still work. A work-around for this is to jump to a different layer with KC_NOs before (or after) enabling music mode.
Recording is experimental due to some memory issues - if you experience some weird behavior, unplugging/replugging your keyboard will fix things.
Keycodes available:
|Key |Aliases |Description |
|-------------------------|---------|-------------------------------------------|
|`QK_MUSIC_ON` |`MU_ON` |Turns on Music Mode |
|`QK_MUSIC_OFF` |`MU_OFF` |Turns off Music Mode |
|`QK_MUSIC_TOGGLE` |`MU_TOGG`|Toggles Music Mode |
|`QK_MUSIC_MODE_NEXT` |`MU_NEXT`|Cycles through the music modes |
Available Modes:
* `CHROMATIC_MODE` - Chromatic scale, row changes the octave
* `GUITAR_MODE` - Chromatic scale, but the row changes the string (+5 st)
* `VIOLIN_MODE` - Chromatic scale, but the row changes the string (+7 st)
* `MAJOR_MODE` - Major scale
In music mode, the following keycodes work differently, and don't pass through:
* `LCTL` - start a recording
* `LALT` - stop recording/stop playing
* `LGUI` - play recording
* `KC_UP` - speed-up playback
* `KC_DOWN` - slow-down playback
The pitch standard (`PITCH_STANDARD_A`) is 440.0f by default - to change this, add something like this to your `config.h`:
```c
#define PITCH_STANDARD_A 432.0f
```
You can completely disable Music Mode as well. This is useful, if you're pressed for space on your controller. To disable it, add this to your `config.h`:
```c
#define NO_MUSIC_MODE
```
### Music Mask
By default, `MUSIC_MASK` is set to `keycode < 0xFF` which means keycodes less than `0xFF` are turned into notes, and don't output anything. You can change this by defining this in your `config.h` like this:
```c
#define MUSIC_MASK keycode != KC_NO
```
Which will capture all keycodes - be careful, this will get you stuck in music mode until you restart your keyboard!
For a more advanced way to control which keycodes should still be processed, you can use `music_mask_kb(keycode)` in `<keyboard>.c` and `music_mask_user(keycode)` in your `keymap.c`:
```c
bool music_mask_user(uint16_t keycode) {
switch (keycode) {
case RAISE:
case LOWER:
return false;
default:
return true;
}
}
```
Things that return false are not part of the mask, and are always processed.
### Music Map
By default, the Music Mode uses the columns and row to determine the scale for the keys. For a board that uses a rectangular matrix that matches the keyboard layout, this is just fine. However, for boards that use a more complicated matrix (such as the Planck Rev6, or many split keyboards) this would result in a very skewed experience.
However, the Music Map option allows you to remap the scaling for the music mode, so it fits the layout, and is more natural.
To enable this feature, add `#define MUSIC_MAP` to your `config.h` file, and then you will want to add a `uint8_t music_map` to your keyboard's `c` file, or your `keymap.c`.
```c
const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x12(
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
);
```
You will want to use whichever `LAYOUT` macro that your keyboard uses here. This maps it to the correct key location. Start in the bottom left of the keyboard layout, and move to the right, and then upwards. Fill in all the entries until you have a complete matrix.
You can look at the [Planck Keyboard](https://github.com/qmk/qmk_firmware/blob/e9ace1487887c1f8b4a7e8e6d87c322988bec9ce/keyboards/planck/planck.c#L24-L29) as an example of how to implement this.
## Audio Click
This adds a click sound each time you hit a button, to simulate click sounds from the keyboard. And the sounds are slightly different for each keypress, so it doesn't sound like a single long note, if you type rapidly.
Keycodes available:
|Key |Aliases |Description |
|-------------------------|---------|-------------------------------------------|
|`QK_AUDIO_CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode |
|`QK_AUDIO_CLICKY_ON` |`CK_ON` |Turns on Audio clicky mode |
|`QK_AUDIO_CLICKY_OFF` |`CK_OFF` |Turns on Audio clicky mode |
|`QK_AUDIO_CLICKY_UP` |`CK_UP` |Increases frequency of the clicks |
|`QK_AUDIO_CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks |
|`QK_AUDIO_CLICKY_RESET` |`CK_RST` |Resets frequency to default |
The feature is disabled by default, to save space. To enable it, add this to your `config.h`:
```c
#define AUDIO_CLICKY
```
You can configure the default, min and max frequencies, the stepping and built in randomness by defining these values:
| Option | Default Value | Description |
|--------|---------------|-------------|
| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | Sets the default/starting audio frequency for the clicky sounds. |
| `AUDIO_CLICKY_FREQ_MIN` | 65.0f | Sets the lowest frequency (under 60f are a bit buggy). |
| `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | Sets the highest frequency. Too high may result in coworkers attacking you. |
| `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f| Sets the stepping of UP/DOWN key codes. This is a multiplicative factor. The default steps the frequency up/down by a musical minor third. |
| `AUDIO_CLICKY_FREQ_RANDOMNESS` | 0.05f | Sets a factor of randomness for the clicks, Setting this to `0f` will make each click identical, and `1.0f` will make this sound much like the 90's computer screen scrolling/typing effect. |
| `AUDIO_CLICKY_DELAY_DURATION` | 1 | An integer note duration where 1 is 1/16th of the tempo, or a sixty-fourth note (see `quantum/audio/musical_notes.h` for implementation details). The main clicky effect will be delayed by this duration. Adjusting this to values around 6-12 will help compensate for loud switches. |
## MIDI Functionality
See [MIDI](feature_midi)
## Audio Keycodes
|Key |Aliases |Description |
|-------------------------|---------|-------------------------------------------|
|`QK_AUDIO_ON` |`AU_ON` |Turns on Audio Feature |
|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature |
|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state |
|`QK_AUDIO_CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode |
|`QK_AUDIO_CLICKY_ON` |`CK_ON` |Turns on Audio clicky mode |
|`QK_AUDIO_CLICKY_OFF` |`CK_OFF` |Turns on Audio clicky mode |
|`QK_AUDIO_CLICKY_UP` |`CK_UP` |Increases frequency of the clicks |
|`QK_AUDIO_CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks |
|`QK_AUDIO_CLICKY_RESET` |`CK_RST` |Resets frequency to default |
|`QK_MUSIC_ON` |`MU_ON` |Turns on Music Mode |
|`QK_MUSIC_OFF` |`MU_OFF` |Turns off Music Mode |
|`QK_MUSIC_TOGGLE` |`MU_TOGG`|Toggles Music Mode |
|`QK_MUSIC_MODE_NEXT` |`MU_NEXT`|Cycles through the music modes |
|`QK_AUDIO_VOICE_NEXT` |`AU_NEXT`|Cycles through the audio voices |
|`QK_AUDIO_VOICE_PREVIOUS`|`AU_PREV`|Cycles through the audio voices in reverse |

View File

@@ -1,398 +0,0 @@
# Auto Shift: Why Do We Need a Shift Key?
Tap a key and you get its character. Tap a key, but hold it *slightly* longer
and you get its shifted state. Voilà! No shift key needed!
## Why Auto Shift?
Many people suffer from various forms of RSI. A common cause is stretching your
fingers repetitively long distances. For us on the keyboard, the pinky does that
all too often when reaching for the shift key. Auto Shift looks to alleviate that
problem.
## How Does It Work?
When you tap a key, it stays depressed for a short period of time before it is
then released. This depressed time is a different length for everyone. Auto Shift
defines a constant `AUTO_SHIFT_TIMEOUT` which is typically set to twice your
normal pressed state time. When you press a key, a timer starts, and if you
have not released the key after the `AUTO_SHIFT_TIMEOUT` period, then a shifted
version of the key is emitted. If the time is less than the `AUTO_SHIFT_TIMEOUT`
time, or you press another key, then the normal state is emitted.
If `AUTO_SHIFT_REPEAT` is defined, there is keyrepeat support. Holding the key
down will repeat the shifted key, though this can be disabled with
`AUTO_SHIFT_NO_AUTO_REPEAT`. If you want to repeat the normal key, then tap it
once then immediately (within `TAPPING_TERM`) hold it down again (this works
with the shifted value as well if auto-repeat is disabled).
There are also the `get_auto_shift_repeat` and `get_auto_shift_no_auto_repeat`
functions for more granular control. Neither will have an effect unless
`AUTO_SHIFT_REPEAT_PER_KEY` or `AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY` respectively
are defined.
## Are There Limitations to Auto Shift?
Yes, unfortunately.
1. You will have characters that are shifted when you did not intend on shifting, and
other characters you wanted shifted, but were not. This simply comes down to
practice. As we get in a hurry, we think we have hit the key long enough for a
shifted version, but we did not. On the other hand, we may think we are tapping
the keys, but really we have held it for a little longer than anticipated.
2. Additionally, with keyrepeat the desired shift state can get mixed up. It will
always 'belong' to the last key pressed. For example, keyrepeating a capital
and then tapping something lowercase (whether or not it's an Auto Shift key)
will result in the capital's *key* still being held, but shift not.
3. Auto Shift does not apply to Tap Hold keys. For automatic shifting of Tap Hold
keys see [Retro Shift](#retro-shift).
## How Do I Enable Auto Shift?
Add to your `rules.mk` in the keymap folder:
```
AUTO_SHIFT_ENABLE = yes
```
If no `rules.mk` exists, you can create one.
Then compile and install your new firmware with Auto Key enabled! That's it!
## Modifiers
By default, Auto Shift is disabled for any key press that is accompanied by one or more
modifiers. Thus, Ctrl+A that you hold for a really long time is not the same
as Ctrl+Shift+A.
You can re-enable Auto Shift for modifiers by adding a define to your `config.h`
```c
#define AUTO_SHIFT_MODIFIERS
```
In which case, Ctrl+A held past the `AUTO_SHIFT_TIMEOUT` will be sent as Ctrl+Shift+A
## Configuring Auto Shift
If desired, there is some configuration that can be done to change the
behavior of Auto Shift. This is done by setting various variables the
`config.h` file located in your keymap folder. If no `config.h` file exists, you can create one.
A sample is
```c
#pragma once
#define AUTO_SHIFT_TIMEOUT 150
#define NO_AUTO_SHIFT_SPECIAL
```
### AUTO_SHIFT_TIMEOUT (Value in ms)
This controls how long you have to hold a key before you get the shifted state.
Obviously, this is different for everyone. For the common person, a setting of
135 to 150 works great. However, one should start with a value of at least 175, which
is the default value. Then work down from there. The idea is to have the shortest time required to get the shifted state without having false positives.
Play with this value until things are perfect. Many find that all will work well
at a given value, but one or two keys will still emit the shifted state on
occasion. This is simply due to habit and holding some keys a little longer
than others. Once you find this value, work on tapping your problem keys a little
quicker than normal and you will be set.
::: tip
Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details!
:::
For more granular control of this feature, you can add the following to your `config.h`:
```c
#define AUTO_SHIFT_TIMEOUT_PER_KEY
```
You can then add the following function to your keymap:
```c
uint16_t get_autoshift_timeout(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case AUTO_SHIFT_NUMERIC:
return 2 * get_generic_autoshift_timeout();
case AUTO_SHIFT_SPECIAL:
return get_generic_autoshift_timeout() + 50;
case AUTO_SHIFT_ALPHA:
default:
return get_generic_autoshift_timeout();
}
}
```
Note that you cannot override individual keys that are in one of those groups
if you are using them; trying to add a case for `KC_A` in the above example will
not compile as `AUTO_SHIFT_ALPHA` is there. A possible solution is a second switch
above to handle individual keys with no default case and only referencing the
groups in the below fallback switch.
### NO_AUTO_SHIFT_SPECIAL (simple define)
Do not Auto Shift special keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
/?, and the KC_TAB.
### NO_AUTO_SHIFT_TAB (simple define)
Do not Auto Shift KC_TAB but leave Auto Shift enabled for the other special
characters.
### NO_AUTO_SHIFT_SYMBOLS (simple define)
Do not Auto Shift symbol keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
and /?.
### NO_AUTO_SHIFT_NUMERIC (simple define)
Do not Auto Shift numeric keys, zero through nine.
### NO_AUTO_SHIFT_ALPHA (simple define)
Do not Auto Shift alpha characters, which include A through Z.
### AUTO_SHIFT_ENTER (simple define)
Auto Shift the enter key.
### Auto Shift Per Key
There are functions that allows you to determine which keys should be autoshifted, much like the tap-hold keys.
The first of these, used to simply add a key to Auto Shift, is `get_custom_auto_shifted_key`:
```c
bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case KC_DOT:
return true;
default:
return false;
}
}
```
For more granular control, there is `get_auto_shifted_key`. The default function looks like this:
```c
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
# ifndef NO_AUTO_SHIFT_ALPHA
case AUTO_SHIFT_ALPHA:
# endif
# ifndef NO_AUTO_SHIFT_NUMERIC
case AUTO_SHIFT_NUMERIC:
# endif
# ifndef NO_AUTO_SHIFT_SPECIAL
# ifndef NO_AUTO_SHIFT_TAB
case KC_TAB:
# endif
# ifndef NO_AUTO_SHIFT_SYMBOLS
case AUTO_SHIFT_SYMBOLS:
# endif
# endif
# ifdef AUTO_SHIFT_ENTER
case KC_ENT:
# endif
return true;
}
return get_custom_auto_shifted_key(keycode, record);
}
```
This functionality is enabled by default, and does not need a define.
### AUTO_SHIFT_REPEAT (simple define)
Enables keyrepeat.
### AUTO_SHIFT_NO_AUTO_REPEAT (simple define)
Disables automatically keyrepeating when `AUTO_SHIFT_TIMEOUT` is exceeded.
### AUTO_SHIFT_ALPHA (predefined key group)
A predefined group of keys representing A through Z.
### AUTO_SHIFT_NUMERIC (predefined key group)
A predefined group of keys representing 0 through 9. Note, these are defined as
1 through 0 since that is the order they normally appear in.
### AUTO_SHIFT_SYMBOLS (predefined key group)
A predefined group of keys representing symbolic characters which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
and /?.
### AUTO_SHIFT_SPECIAL (predefined key group)
A predefined group of keys that combines AUTO_SHIFT_SYMBOLS and KC_TAB.
## Custom Shifted Values
Especially on small keyboards, the default shifted value for many keys is not
optimal. To provide more customizability, there are two user-definable
functions, `autoshift_press/release_user`. These register or unregister the
correct value for the passed key. Below is an example adding period to Auto
Shift and making its shifted value exclamation point. Make sure to use weak
mods - setting real would make any keys following it use their shifted values
as if you were holding the key. Clearing of modifiers is handled by Auto Shift,
and the OS-sent shift value if keyrepeating multiple keys is always that of
the last key pressed (whether or not it's an Auto Shift key).
You can also have non-shifted keys for the shifted values (or even no shifted
value), just don't set a shift modifier!
```c
bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case KC_DOT:
return true;
default:
return false;
}
}
void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) {
switch(keycode) {
case KC_DOT:
register_code16((!shifted) ? KC_DOT : KC_EXLM);
break;
default:
if (shifted) {
add_weak_mods(MOD_BIT(KC_LSFT));
}
// & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift
register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode);
}
}
void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) {
switch(keycode) {
case KC_DOT:
unregister_code16((!shifted) ? KC_DOT : KC_EXLM);
break;
default:
// & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift
// The IS_RETRO check isn't really necessary here, always using
// keycode & 0xFF would be fine.
unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode);
}
}
```
## Retro Shift
Holding and releasing a Tap Hold key without pressing another key will ordinarily
result in only the hold. With `retro shift` enabled this action will instead
produce a shifted version of the tap keycode on release.
It does not require [Retro Tapping](tap_hold#retro-tapping) to be enabled, and
if both are enabled the state of `retro tapping` will only apply if the tap keycode
is not matched by Auto Shift. `RETRO_TAPPING_PER_KEY` and its corresponding
function, however, are checked before `retro shift` is applied.
To enable `retro shift`, add the following to your `config.h`:
```c
#define RETRO_SHIFT
```
If `RETRO_SHIFT` is defined to a value, hold times greater than that value will
not produce a tap on release for Mod Taps, and instead triggers the hold action.
This enables modifiers to be held for combining with mouse clicks without
generating taps on release. For example:
```c
#define RETRO_SHIFT 500
```
Without a value set, holds of any length without an interrupting key will produce the shifted value.
This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
must be designated as a 'hold' by `process_tapping` before we send the modifier.
[Per-key tapping terms](tap_hold#tapping-term) can be used as a workaround.
There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
**Note:** Tap Holds must be added to Auto Shift, see [here.](feature_auto_shift#auto-shift-per-key)
`IS_RETRO` may be helpful if one wants all Tap Holds retro shifted.
### Retro Shift and Tap Hold Configurations
Tap Hold Configurations work a little differently when using Retro Shift.
Referencing `TAPPING_TERM` makes little sense, as holding longer would result in
shifting one of the keys.
`RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](tap_hold#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies.
## Using Auto Shift Setup
This will enable you to define three keys temporarily to increase, decrease and report your `AUTO_SHIFT_TIMEOUT`.
### Setup
Map three keys temporarily in your keymap:
|Keycode |Aliases |Description |
|----------------------|---------|--------------------------------------------|
|`QK_AUTO_SHIFT_DOWN` |`AS_DOWN`|Lower the Auto Shift timeout variable (down)|
|`QK_AUTO_SHIFT_UP` |`AS_UP` |Raise the Auto Shift timeout variable (up) |
|`QK_AUTO_SHIFT_REPORT`|`AS_RPT` |Report your current Auto Shift timeout value|
|`QK_AUTO_SHIFT_ON` |`AS_ON` |Turns on the Auto Shift Function |
|`QK_AUTO_SHIFT_OFF` |`AS_OFF` |Turns off the Auto Shift Function |
|`QK_AUTO_SHIFT_TOGGLE`|`AS_TOGG`|Toggles the state of the Auto Shift feature |
Compile and upload your new firmware.
### Use
It is important to note that during these tests, you should be typing
completely normal and with no intention of shifted keys.
1. Type multiple sentences of alphabetical letters.
2. Observe any upper case letters.
3. If there are none, press the key you have mapped to `AS_DOWN` to decrease
time Auto Shift timeout value and go back to step 1.
4. If there are some upper case letters, decide if you need to work on tapping
those keys with less down time, or if you need to increase the timeout.
5. If you decide to increase the timeout, press the key you have mapped to
`AS_UP` and go back to step 1.
6. Once you are happy with your results, press the key you have mapped to
`AS_RPT`. The keyboard will type by itself the value of your
`AUTO_SHIFT_TIMEOUT`.
7. Update `AUTO_SHIFT_TIMEOUT` in your `config.h` with the value reported.
8. Add `AUTO_SHIFT_NO_SETUP` to your `config.h`.
9. Remove the key bindings `AS_DOWN`, `AS_UP` and `AS_RPT`.
10. Compile and upload your new firmware.
#### An Example Run
```
hello world. my name is john doe. i am a computer programmer playing with
keyboards right now.
[PRESS AS_DOWN quite a few times]
heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH
KEYboArDS RiGHT NOw.
[PRESS AS_UP a few times]
hello world. my name is john Doe. i am a computer programmer playing with
keyboarDs right now.
[PRESS AS_RPT]
115
```
The keyboard typed `115` which represents your current `AUTO_SHIFT_TIMEOUT`
value. You are now set! Practice on the *D* key a little bit that showed up
in the testing and you'll be golden.

View File

@@ -1,324 +0,0 @@
# Autocorrect
There are a lot of words that are prone to being typed incorrectly, due to habit, sequence or just user error. This feature leverages your firmware to automatically correct these errors, to help reduce typos.
## How does it work? {#how-does-it-work}
The feature maintains a small buffer of recent key presses. On each key press, it checks whether the buffer ends in a recognized typo, and if so, automatically sends keystrokes to correct it.
The tricky part is how to efficiently check the buffer for typos. We dont want to spend too much memory or time on storing or searching the typos. A good solution is to represent the typos with a trie data structure. A trie is a tree data structure where each node is a letter, and words are formed by following a path to one of the leaves.
![An example trie](https://i.imgur.com/HL5DP8H.png)
Since we search whether the buffer ends in a typo, we store the trie writing in reverse. The trie is queried starting from the last letter, then second to last letter, and so on, until either a letter doesnt match or we reach a leaf, meaning a typo was found.
## How do I enable Autocorrection {#how-do-i-enable-autocorrection}
In your `rules.mk`, add this:
```make
AUTOCORRECT_ENABLE = yes
```
Additionally, you will need a library for autocorrection. A small sample library is included by default, so that you can get up and running right away, but you can provide a customized library.
By default, autocorrect is disabled. To enable it, you need to use the `AC_TOGG` keycode to enable it. The status is stored in persistent memory, so you shouldn't need to enabled it again.
## Customizing autocorrect library {#customizing-autocorrect-library}
To provide a custom library, you need to create a text file with the corrections. For instance:
```text
:thier -> their
fitler -> filter
lenght -> length
ouput -> output
widht -> width
```
The syntax is `typo -> correction`. Typos and corrections are case insensitive, and any whitespace before or after the typo and correction is ignored. The typo must be only the letters az, or the special character : representing a word break. The correction may have any non-unicode characters.
Then, run:
```sh
qmk generate-autocorrect-data autocorrect_dictionary.txt
```
This will process the file and produce an `autocorrect_data.h` file with the trie library, in the folder that you are at. You can specify the keyboard and keymap (eg `-kb planck/rev6 -km jackhumbert`), and it will place the file in that folder instead. But as long as the file is located in your keymap folder, or user folder, it should be picked up automatically.
This file will look like this:
```c
// :thier -> their
// fitler -> filter
// lenght -> length
// ouput -> output
// widht -> width
#define AUTOCORRECT_MIN_LENGTH 5 // "ouput"
#define AUTOCORRECT_MAX_LENGTH 6 // ":thier"
#define DICTIONARY_SIZE 74
static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {85, 7, 0, 23, 35, 0, 0, 8, 0, 76, 16, 0, 15, 25, 0, 0,
11, 23, 44, 0, 130, 101, 105, 114, 0, 23, 12, 9, 0, 131, 108, 116, 101, 114, 0, 75, 42, 0, 24, 64, 0, 0, 71, 49, 0,
10, 56, 0, 0, 12, 26, 0, 129, 116, 104, 0, 17, 8, 15, 0, 129, 116, 104, 0, 19, 24, 18, 0, 130, 116, 112, 117, 116,
0};
```
### Avoiding false triggers {#avoiding-false-triggers}
By default, typos are searched within words, to find typos within longer identifiers like maxFitlerOuput. While this is useful, a consequence is that autocorrection will falsely trigger when a typo happens to be a substring of a correctly-spelled word. For instance, if we had thier -> their as an entry, it would falsely trigger on (correct, though relatively uncommon) words like “wealthier” and “filthier.”
The solution is to set a word break : before and/or after the typo to constrain matching. : matches space, period, comma, underscore, digits, and most other non-alpha characters.
|Text |thier |:thier |thier: |:thier: |
|-----------------|:------:|:------:|:------:|:------:|
|see `thier` typo |matches |matches |matches |matches |
|its `thiers` |matches |matches |no |no |
|wealthier words |matches |no |matches |no |
:thier: is most restrictive, matching only when thier is a whole word.
The `qmk generate-autocorrect-data` commands can make an effort to check for entries that would false trigger as substrings of correct words. It searches each typo against a dictionary of 25K English words from the english_words Python package, provided its installed. (run `python3 -m pip install english_words` to install it.)
::: tip
Unfortunately, this is limited to just english words, at this point.
:::
## Overriding Autocorrect
Occasionally you might actually want to type a typo (for instance, while editing autocorrect_dict.txt) without being autocorrected. There are a couple of ways to do this:
1. Begin typing the typo.
2. Before typing the last letter, press and release the Ctrl or Alt key.
3. Type the remaining letters.
This works because the autocorrection implementation doesnt understand hotkeys, so it resets itself whenever a modifier other than shift is held.
Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for Autocorrect.
### Keycodes {#keycodes}
|Keycode |Aliases |Description |
|-----------------------|---------|----------------------------------------------|
|`QK_AUTOCORRECT_ON` |`AC_ON` |Turns on the Autocorrect feature. |
|`QK_AUTOCORRECT_OFF` |`AC_OFF` |Turns off the Autocorrect feature. |
|`QK_AUTOCORRECT_TOGGLE`|`AC_TOGG`|Toggles the status of the Autocorrect feature.|
## User Callback Functions
### Process Autocorrect
Callback function `bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods)` is available to customise incoming keycodes and handle exceptions. You can use this function to sanitise input before they are passed onto the autocorrect engine
::: tip
Sanitisation of input is required because autocorrect will only match 8-bit [basic keycodes](keycodes_basic) for typos. If valid modifier keys or 16-bit keycodes that are part of a user's word input (such as Shift + A) is passed through, they will fail typo letter detection. For example a [Mod-Tap](mod_tap) key such as `LCTL_T(KC_A)` is 16-bit and should be masked for the 8-bit `KC_A`.
:::
The default user callback function is found inside `quantum/process_keycode/process_autocorrect.c`. It covers most use-cases for QMK special functions and quantum keycodes, including [overriding autocorrect](#overriding-autocorrect) with a modifier other than shift. The `process_autocorrect_user` function is `weak` defined to allow user's copy inside `keymap.c` (or code files) to overwrite it.
#### Process Autocorrect Example
If you have a custom keycode `QMKBEST` that should be ignored as part of a word, and another custom keycode `QMKLAYER` that should override autocorrect, both can be added to the bottom of the `process_autocorrect_user` `switch` statement in your source code:
```c
bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) {
// See quantum_keycodes.h for reference on these matched ranges.
switch (*keycode) {
// Exclude these keycodes from processing.
case KC_LSFT:
case KC_RSFT:
case KC_CAPS:
case QK_TO ... QK_ONE_SHOT_LAYER_MAX:
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX:
case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
return false;
// Mask for base keycode from shifted keys.
case QK_LSFT ... QK_LSFT + 255:
case QK_RSFT ... QK_RSFT + 255:
if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) {
*mods |= MOD_LSFT;
} else {
*mods |= MOD_RSFT;
}
*keycode &= 0xFF; // Get the basic keycode.
return true;
#ifndef NO_ACTION_TAPPING
// Exclude tap-hold keys when they are held down
// and mask for base keycode when they are tapped.
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
# ifdef NO_ACTION_LAYER
// Exclude Layer Tap, if layers are disabled
// but action tapping is still enabled.
return false;
# endif
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
// Exclude hold if mods other than Shift is not active
if (!record->tap.count) {
return false;
}
*keycode &= 0xFF;
break;
#else
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Exclude if disabled
return false;
#endif
// Exclude swap hands keys when they are held down
// and mask for base keycode when they are tapped.
case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
#ifdef SWAP_HANDS_ENABLE
if (*keycode >= 0x56F0 || !record->tap.count) {
return false;
}
*keycode &= 0xFF;
break;
#else
// Exclude if disabled
return false;
#endif
// Handle custom keycodes
case QMKBEST:
return false;
case QMKLAYER:
*typo_buffer_size = 0;
return false;
}
// Disable autocorrect while a mod other than shift is active.
if ((*mods & ~MOD_MASK_SHIFT) != 0) {
*typo_buffer_size = 0;
return false;
}
return true;
}
```
::: tip
In this callback function, `return false` will skip processing of that keycode for autocorrect. Adding `*typo_buffer_size = 0` will also reset the autocorrect buffer at the same time, cancelling any current letters already stored in the buffer.
:::
### Apply Autocorrect
Additionally, `apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word), and the typo and corrected strings (complete words).
::: tip
Due to the way code works (no notion of words, just a stream of letters), the `typo` and `correct` strings are a best bet and could be "wrong". For example you may get `wordtpyo` & `wordtypo` instead of the expected `tpyo` & `typo`.
:::
#### Apply Autocorrect Example
This following example will play a sound when a typo is autocorrected and execute the autocorrection itself:
```c
#ifdef AUDIO_ENABLE
float autocorrect_song[][2] = SONG(TERMINAL_SOUND);
#endif
bool apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct) {
#ifdef AUDIO_ENABLE
PLAY_SONG(autocorrect_song);
#endif
for (uint8_t i = 0; i < backspaces; ++i) {
tap_code(KC_BSPC);
}
send_string_P(str);
return false;
}
```
::: tip
In this callback function, `return false` will stop the normal processing of autocorrect, which requires manually handling of removing the "bad" characters and typing the new characters.
:::
::: warning
***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string` nor `SEND_STRING`.
:::
You can also use `apply_autocorrect` to detect and display the event but allow internal code to execute the autocorrection with `return true`:
```c
bool apply_autocorrect(uint8_t backspaces, const char *str, char *typo, char *correct) {
#ifdef OLED_ENABLE
oled_write_P(PSTR("Auto-corrected"), false);
#endif
#ifdef CONSOLE_ENABLE
printf("'%s' was corrected to '%s'\n", typo, correct);
#endif
return true;
}
```
### Autocorrect Status
Additional user callback functions to manipulate Autocorrect:
| Function | Description |
|----------------------------|----------------------------------------------|
| `autocorrect_enable()` | Turns Autocorrect on. |
| `autocorrect_disable()` | Turns Autocorrect off. |
| `autocorrect_toggle()` | Toggles Autocorrect. |
| `autocorrect_is_enabled()` | Returns true if Autocorrect is currently on. |
## Appendix: Trie binary data format {#appendix}
This section details how the trie is serialized to byte data in autocorrect_data. You dont need to care about this to use this autocorrection implementation. But it is documented for the record in case anyone is interested in modifying the implementation, or just curious how it works.
What I did here is fairly arbitrary, but it is simple to decode and gets the job done.
### Encoding {#encoding}
All autocorrection data is stored in a single flat array autocorrect_data. Each trie node is associated with a byte offset into this array, where data for that node is encoded, beginning with root at offset 0. There are three kinds of nodes. The highest two bits of the first byte of the node indicate what kind:
* 00 ⇒ chain node: a trie node with a single child.
* 01 ⇒ branching node: a trie node with multiple children.
* 10 ⇒ leaf node: a leaf, corresponding to a typo and storing its correction.
![An example trie](https://i.imgur.com/HL5DP8H.png)
**Branching node**. Each branch is encoded with one byte for the keycode (KC_AKC_Z) followed by a link to the child node. Links between nodes are 16-bit byte offsets relative to the beginning of the array, serialized in little endian order.
All branches are serialized this way, one after another, and terminated with a zero byte. As described above, the node is identified as a branch by setting the two high bits of the first byte to 01, done by bitwise ORing the first keycode with 64. keycode. The root node for the above figure would be serialized like:
```
+-------+-------+-------+-------+-------+-------+-------+
| R|64 | node 2 | T | node 3 | 0 |
+-------+-------+-------+-------+-------+-------+-------+
```
**Chain node**. Tries tend to have long chains of single-child nodes, as seen in the example above with f-i-t-l in fitler. So to save space, we use a different format to encode chains than branching nodes. A chain is encoded as a string of keycodes, beginning with the node closest to the root, and terminated with a zero byte. The child of the last node in the chain is encoded immediately after. That child could be either a branching node or a leaf.
In the figure above, the f-i-t-l chain is encoded as
```
+-------+-------+-------+-------+-------+
| L | T | I | F | 0 |
+-------+-------+-------+-------+-------+
```
If we were to encode this chain using the same format used for branching nodes, we would encode a 16-bit node link with every node, costing 8 more bytes in this example. Across the whole trie, this adds up. Conveniently, we can point to intermediate points in the chain and interpret the bytes in the same way as before. E.g. starting at the i instead of the l, and the subchain has the same format.
**Leaf node**. A leaf node corresponds to a particular typo and stores data to correct the typo. The leaf begins with a byte for the number of backspaces to type, and is followed by a null-terminated ASCII string of the replacement text. The idea is, after tapping backspace the indicated number of times, we can simply pass this string to the `send_string_P` function. For fitler, we need to tap backspace 3 times (not 4, because we catch the typo as the final r is pressed) and replace it with lter. To identify the node as a leaf, the two high bits are set to 10 by ORing the backspace count with 128:
```
+-------+-------+-------+-------+-------+-------+
| 3|128 | 'l' | 't' | 'e' | 'r' | 0 |
+-------+-------+-------+-------+-------+-------+
```
### Decoding {#decoding}
This format is by design decodable with fairly simple logic. A 16-bit variable state represents our current position in the trie, initialized with 0 to start at the root node. Then, for each keycode, test the highest two bits in the byte at state to identify the kind of node.
* 00 ⇒ **chain node**: If the nodes byte matches the keycode, increment state by one to go to the next byte. If the next byte is zero, increment again to go to the following node.
* 01 ⇒ **branching node**: Search the branches for one that matches the keycode, and follow its node link.
* 10 ⇒ **leaf node**: a typo has been found! We read its first byte for the number of backspaces to type, then pass its following bytes to send_string_P to type the correction.
## Credits
Credit goes to [getreuer](https://github.com/getreuer) for originally implementing this [here](https://getreuer.info/posts/keyboards/autocorrection/#how-does-it-work). As well as to [filterpaper](https://github.com/filterpaper) for converting the code to use PROGMEM, and additional improvements.

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