@ -1,38 +0,0 @@ | |||
os: linux | |||
dist: trusty | |||
group: edge | |||
language: c | |||
branches: | |||
except: | |||
- /^.*-automated-build$/ | |||
- /^[0-9]+\.[0-9]+\.[0-9]+/ | |||
env: | |||
global: | |||
- secure: vBTSL34BDPxDilKUuTXqU4CJ26Pv5hogD2nghatkxSQkI1/jbdnLj/DQdPUrMJFDIY6TK3AltsBx72MaMsLQ1JO/Ou24IeHINHXzUC1FlS9yQa48cpxnhX5kzXNyGs3oa0qaFbvnr7RgYRWtmD52n4bIZuSuW+xpBv05x2OCizdT2ZonH33nATaHGFasxROm4qYZ241VfzcUv766V6RVHgL4x9V08warugs+RENVkfzxxwhk3NmkrISabze0gSVJLHBPHxroZC6EUcf/ocobcuDrCwFqtEt90i7pNIAFUE7gZsN2uE75LmpzAWin21G7lLPcPL2k4FJVd8an1HiP2WmscJU6U89fOfMb2viObnKcCzebozBCmKGtHEuXZo9FcReOx49AnQSpmESJGs+q2dL/FApkTjQiyT4J6O5dJpoww0/r57Wx0cmmqjETKBb5rSgXM51Etk3wO09mvcPHsEwrT7qH8r9XWdyCDoEn7FCLX3/LYnf/D4SmZ633YPl5gv3v9XEwxR5+04akjgnvWDSNIaDbWBdxHNb7l4pMc+WR1bwCyMyA7KXj0RrftEGOrm9ZRLe6BkbT4cycA+j77nbPOMcyZChliV9pPQos+4TOJoTzcK2L8yWVoY409aDNVuAjdP6Yum0R2maBGl/etLmIMpJC35C5/lZ+dUNjJAM= | |||
- MAKEFLAGS="-j3 --output-sync" | |||
services: | |||
- docker | |||
addons: | |||
apt: | |||
sources: | |||
- ubuntu-toolchain-r-test | |||
- llvm-toolchain-trusty-7 | |||
packages: | |||
- diffutils | |||
- clang-format-7 | |||
- libstdc++-7-dev | |||
script: | |||
- git fetch --depth=50 origin $TRAVIS_BRANCH:$TRAVIS_BRANCH | |||
- git rev-parse --short HEAD | |||
- git diff --name-only HEAD $TRAVIS_BRANCH | |||
- bash util/travis_test.sh | |||
- bash util/travis_build.sh | |||
after_script: | |||
bash util/travis_compiled_push.sh | |||
notifications: | |||
webhooks: | |||
urls: | |||
- https://webhooks.gitter.im/e/afce403d65f143dfac09 | |||
on_success: always # options: [always|never|change] default: always | |||
on_failure: always # options: [always|never|change] default: always | |||
on_start: never # options: [always|never|change] default: always |
@ -1,24 +0,0 @@ | |||
# Code Of Conduct | |||
QMK strives to be an inclusive, tolerant, and welcoming community. We encourage participation from anyone regardless of age, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, political belief, race, religion, or sexual identity and orientation. | |||
> “A gentle word turns away wrath, but a harsh word stirs up anger." | |||
Our users, contributors, and collaborators are expected to treat each other with kindness and respect, to assume good intentions, and to gently correct, where possible, rather than react with escalation. While our goal is to be as accurate as possible, kindness and understanding are more valuable than correctness. Some examples of behavior we will not tolerate include, but is not limited to: | |||
* The use of sexualized language or imagery | |||
* Unwelcome advances, sexual or otherwise | |||
* Deliberate intimidation, stalking, or following | |||
* Insults or derogatory comments, or personal or political attacks | |||
* Publishing others’ private information without explicit permission | |||
* Sustained disruption of talks or other events | |||
* Other conduct which could reasonably be considered inappropriate in a professional setting | |||
* Advocating for, or encouraging, any of the above behaviour | |||
# Reporting | |||
If someone is violating this Code of Conduct, please email hello@qmk.fm or reach out to one of the Collaborators to bring it to our attention. All complaints will be reviewed and investigated. | |||
QMK will seek to use the least punitive means available to resolve an issue. If the circumstances require asking an offender to leave, we will do that. | |||
Reports will be taken and kept in strict confidence. You will not be required to confront an offender directly. |
@ -0,0 +1,61 @@ | |||
# QMK Configurator Architecture | |||
This page describes the web architecture behind QMK Configurator at a high level. If you are interested in the architecture of the QMK Configurator code itself you should start at the [qmk_configurator](https://github.com/qmk/qmk_configurator) repository. | |||
# Overview | |||
![QMK Configurator Architecture Diagram](configurator_diagram.svg) | |||
# Detailed Description | |||
QMK Configurator is a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) that allows users to create custom keymaps for their QMK-compatible keyboard. They can export JSON representation of their keymaps and compile firmware binaries that can be flashed to their keyboard using a tool like [QMK Toolbox](https://github.com/qmk/qmk_toolbox). | |||
Configurator gets metadata about keyboards from the Keyboard Metadata store and submits compile requests to the QMK API. The results of those compile requests will be made available on [Digital Ocean Spaces](https://www.digitalocean.com/products/spaces/), an S3-compatible data store. | |||
## Configurator Frontend | |||
Address: <https://config.qmk.fm> | |||
The [Configurator Frontend](https://config.qmk.fm) is compiled into a set of static files that are served by Github Pages. This action happens every time a commit is pushed to the [qmk_configurator `master`](https://github.com/qmk/qmk_configurator) branch. You can view the status of these jobs on the [qmk_configurator actions tab](https://github.com/qmk/qmk_configurator/actions/workflows/build.yml). | |||
## Keyboard Metadata | |||
Address: <https://keyboards.qmk.fm> | |||
The Keyboard Metadata is generated every time a keyboard in [qmk_firmware](https://github.com/qmk/qmk_firmware) changes. The resulting JSON files are uploaded to Spaces and used by Configurator to generate UI for each keyboard. You can view the status of this job on the [qmk_firmware actions tab](https://github.com/qmk/qmk_firmware/actions/workflows/api.yml). If you are a QMK Collaborator you can manually run this job using the `workflow_dispatch` event trigger. | |||
## QMK API | |||
Address: <http://api.qmk.fm> | |||
The QMK API accepts `keymap.json` files for compilation. These are the same files you can use directly with `qmk compile` and `qmk flash`. When a `keymap.json` is submitted the browser will poll the status of the job periodically (every 2 seconds or longer, preferably) until the job has completed. The final status JSON will contain pointers to source and binary downloads for the keymap. | |||
QMK API always presents the source and binary downloads side-by-side to comply with the GPL. | |||
There are 3 non-error status responses from the API- | |||
1. Compile Job Queued | |||
2. Compile Job Running | |||
3. Compile Job Finished | |||
### Compile Job Queued | |||
This status indicates that the job has not yet been picked up by a [QMK Compiler](#qmk-compiler) node. Configurator shows this status as "Waiting for an oven". | |||
### Compile Job Running | |||
This status indicates that the job has started compiling. Configurator shows this status as "Baking". | |||
### Compile Job Finished | |||
This status indicates that the job has completed. There will be keys in the status JSON for source and binary downloads. | |||
## Redis/RQ | |||
QMK API uses RQ to distribute jobs to the available [QMK Compiler](#qmk-compiler) nodes. When a `keymap.json` is received it's put into the RQ queue, where a `qmk_compiler` node will pick it up from. | |||
## QMK Compiler | |||
[QMK Compiler](https://github.com/qmk/qmk_compiler) is what actually performs the compilation of the `keymap.json`. It does so by checking out the requested `qmk_firmware` branch, running `qmk compile keymap.json`, and then uploading the resulting source and binary to Digital Ocean Spaces. | |||
When users download their source/binary, API will redirect them to the authenticated Spaces download URL. |
@ -0,0 +1 @@ | |||
<mxfile host="Electron" modified="2021-08-09T19:46:29.036Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="PQ2r34UrZa0TfW4Fw0EV" version="14.6.13" type="device"><diagram id="NEtccoSKIy4HskWlhJpu" name="Page-1">5VvbcqM4EP2a1O4+hOLqy2Ni5zKX1CTxzszOU0oG2dZEIBZEYu/XbwuEDQg7csZ2vFlXjQca0RLdR+eohXPiDML5VYLi2Q0LMD2xzWB+4gxPbNvqezb8JywLaTFtr7BMExJI28owIv/gsqG0ZiTAaa0hZ4xyEteNPosi7POaDSUJe643mzBa7zVGU6wYRj6iqvU7CfissPY8c2W/xmQ6K3u2THklRGVjaUhnKGDPFZNzceIMEsZ4cRTOB5iK6JVxKe67XHN1ObAER1znhgfT76Zzxxp3Z49j5+7zjw/z+NSS+XlCNJNPLEfLF2UIcAARkacs4TM2ZRGiFyvrecKyKMCiHxPOVm0+MxaD0QLjT8z5QqYXZZyBacZDKq/iKDgTyYLTiEW4sFwSSqXLAKWz3L9orD64jEXKssTHG57WlQBCyRTzTVGRDsWTV3qQcb3CLMQ8WUCDBFPEyVMdK0hCbrpst8oKHMjEbJEk9+UckTDHcTWm0jQk4RR6pWQM3z4l8QNKuDhkYZxxnKRw/J0ljymHJ2HRg2X35vDPiKPp2kA/4YTj+cbIyKunjmv0zMpHeljSQXH6XJla0jSrzKrStvPIei9Hdgm9HNoZpyTCgyXZmPWYI0qmERz7EDGcgIGiMaa3LCUittULIoQEaOZzo8GYcc7CSoMz6ZKLqXQOJBKLgYXzqSBc4xmPKcy11JgSPsvG0GLCIn6JQkJFiK8xfcLCjbwgJyDM+uJ8wChL8ud0ivSILnjCHnHblQlMyIp9kn/ADkMJCK55G14OL4YXmybrFhhyOzXQtKEGdMVwVeBUzDvHTjmKjdS54jWfojQlfpP3YCR/CRwZXnn6o3ptOJcgK84W8gwma8JVz7lZ0qZVI9Ff401PkzddTdqsJM5rme6lTZtdZQ+3jMCTLXFjlRkqyaZJI8Vzy7uqytl01Gk4chqOisAojnJYLR/7F5BWTpkV0gZUTDjgbnOUxTEorqCosxO7QyGG5+MEjqbiaDBLoPsTGzo2L0mCJ2yuNhri9FHQi21+iehCAfHzjHA8ilEOkWegnTqGm0QVkiDIVwU5950j/3Garw9Kdsjd7YYZlmurkhlUYrDNFoB19qUnltPCCUW40xhFZcBnnIvl65noTChxNCFT4+/w0ZiEZXOwV+9Qk9bmd0SiKYTeNm+F9AM2RKTX3tno4iN6QiM/IbFYHXz7eqHeOJI8AeM2YbTQDL4fiuFnCeIs0RvmNUt54eWqUK1iwOnaZ28Asr7cfC0894E/q2PYehDs7w2CGqtFdbndqklVRaoI1BpN2tEaXVdryql2JGKzTKiEgvdasXHchqNDi01XAz/vpiK0tOHW0YTbYUpC6/1ULj9TuH0XlWZ93riOuhjotsz/rmf09pWkjpKkuvI/4sWYoSRIG+K/ks9PsgV4ucEcBYgjXV2ekCR8hoiq7a+uoeGZX+RN3PQ1BsdiwXB2+wG+h629rFR7SKDaRPSLj4VIm7n2ptsuG2voPKRIu7Zt9N9apHtbiXRr7VirASVHVgtAc4cFoDZNekclypZnWK5p9Tp9y+v1up1y73nRQMbWBWHdz3LP90ASbav14HuW6L4m9spsHotE95Us3d18Kkm2mS5KSZziik76lGXBy+XNLpTTq8O5Y6rKadkts3Rv27JlZ2uFE8VkrWTeX4z+nGS0DLSeWILDTYp3jyJ/Bqsf2xRrFXP4Bb6+3fy2tegdUuc6pqenct29pVFjkfryDulhtzDLWXskCnbarCtd75WadaoUlpqqBelBi0qzWDRINwzZanTkOObmkTVv8Pq1G+CgGMNuRVSl53csonZXV0R7RyWitrobIasPMMoCRGF4WY807b+PnD+OS3idXh347fuHrdrbt8qWu4+5WpzU1RcE81QocLTwHcMPIiMoUsJEPtI8+obPWqRZRlNK7+kLoqskejut3UWCeg1msh3L6PYrn54qsf2WbO3thYOjrpTeTGK1Oea4ikSQ/EaSX7t1qwiZfeC9W6ft9dO71TSn/D3YS3hz7KPSNEct3+/vlDyVciS2/FLOEnwYSWpskXS7ai3YOSjB2WqwcEDEm+9cjEwRuqaGfGTineJdhrOW3c/2AjApnO6/BNxBkpqVXrfz1pWes91Lx73KkPZ+UTkP31qHyiw26zFt2fEacGiWiPtWHXWNXvwuIIwpETNmDbPhuZhhAcvG+RWrJj3Wm2x99Vt+QXLYrS9XXdAVu4YDCCehIpztbHefRVH+a07dX22sc/efoLy+/daU5+pswh+I8vRXQt3joDyZVbeW015ztaxLgHU3/eZbnT3Tn6uuULYGwoF/z+lo7wYdF16AHes00GuuO/V3Qxui2bP0ULP1bqjTYK5yS2Gvm5vu/6sQ1IVzKa67KwTXEJK3GVu6KLWd14H0ZRjB6eovj4rmqz/gci7+BQ==</diagram></mxfile> |
@ -1,86 +1,91 @@ | |||
# Language-specific Keycodes | |||
Keyboards are able to support a wide range of languages. However, they do not send the actual characters produced by pressing their keys - instead, they send numerical codes. In the USB HID spec, these are called "usages", although they are more often referred to as "scancodes" or "keycodes" when in the context of keyboards. | |||
Less than 256 usages are defined in the HID Keyboard/Keypad usage page, and some of those do nothing on modern operating systems. So, how is this language support achieved? | |||
Keyboards are able to support a wide range of languages. However, this support is not actually achieved within the keyboard itself - instead, it sends numerical codes, which the operating system maps to the appropriate characters depending on the user's configured keyboard layout. By default (and per the HID spec), this is the US ANSI layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`. | |||
In a nutshell, the operating system maps the usages it receives to the appropriate character based on the user's configured keyboard layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`. | |||
Obviously, this can get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. | |||
Obviously, this could get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. | |||
Simply `#include` one of the keycode headers below at the top of your `keymap.c`, and assign the keycodes defined in the header in place of the `KC_` prefixed ones. | |||
To use these, simply `#include` the corresponding [header file](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras) in your `keymap.c`, and add the keycodes defined in them in place of the `KC_` prefixed ones: | |||
## Sendstring Support | |||
|Layout |Header | | |||
|---------------------------|--------------------------------| | |||
|Canadian Multilingual (CSA)|`keymap_canadian_multilingual.h`| | |||
|Croatian |`keymap_croatian.h` | | |||
|Czech |`keymap_czech.h` | | |||
|Danish |`keymap_danish.h` | | |||
|Dutch (Belgium) |`keymap_belgian.h` | | |||
|English (Ireland) |`keymap_irish.h` | | |||
|English (UK) |`keymap_uk.h` | | |||
|English (US Extended) |`keymap_us_extended.h` | | |||
|English (US International) |`keymap_us_international.h` | | |||
|English (US International, Linux)|`keymap_us_international_linux.h`| | |||
|Estonian |`keymap_estonian.h` | | |||
|Finnish |`keymap_finnish.h` | | |||
|French |`keymap_french.h` | | |||
|French (AFNOR) |`keymap_french_afnor.h` | | |||
|French (BÉPO) |`keymap_bepo.h` | | |||
|French (Belgium) |`keymap_belgian.h` | | |||
|French (Switzerland) |`keymap_fr_ch.h` | | |||
|French (macOS, ISO) |`keymap_french_osx.h` | | |||
|German |`keymap_german.h` | | |||
|German (Switzerland) |`keymap_german_ch.h` | | |||
|German (macOS) |`keymap_german_osx.h` | | |||
|German (Neo2)* |`keymap_neo2.h` | | |||
|Greek* |`keymap_greek.h` | | |||
|Hebrew* |`keymap_hebrew.h` | | |||
|Hungarian |`keymap_hungarian.h` | | |||
|Icelandic |`keymap_icelandic.h` | | |||
|Italian |`keymap_italian.h` | | |||
|Italian (macOS, ANSI) |`keymap_italian_osx_ansi.h` | | |||
|Italian (macOS, ISO) |`keymap_italian_osx_iso.h` | | |||
|Japanese |`keymap_jp.h` | | |||
|Korean |`keymap_korean.h` | | |||
|Latvian |`keymap_latvian.h` | | |||
|Lithuanian (ĄŽERTY) |`keymap_lithuanian_azerty.h` | | |||
|Lithuanian (QWERTY) |`keymap_lithuanian_qwerty.h` | | |||
|Norwegian |`keymap_norwegian.h` | | |||
|Polish |`keymap_polish.h` | | |||
|Portuguese |`keymap_portuguese.h` | | |||
|Portuguese (macOS, ISO) |`keymap_portuguese_osx_iso.h` | | |||
|Portuguese (Brazil) |`keymap_br_abnt2.h` | | |||
|Romanian |`keymap_romanian.h` | | |||
|Russian* |`keymap_russian.h` | | |||
|Serbian* |`keymap_serbian.h` | | |||
|Serbian (Latin) |`keymap_serbian_latin.h` | | |||
|Slovak |`keymap_slovak.h` | | |||
|Slovenian |`keymap_slovenian.h` | | |||
|Spanish |`keymap_spanish.h` | | |||
|Spanish (Dvorak) |`keymap_spanish_dvorak.h` | | |||
|Swedish |`keymap_swedish.h` | | |||
|Turkish (F) |`keymap_turkish_f.h` | | |||
|Turkish (Q) |`keymap_turkish_q.h` | | |||
By default, `SEND_STRING()` assumes a US ANSI keyboard layout is set. If you are using a different layout, you can include one of the Sendstring LUT headers below in your `keymap.c` to override the lookup tables used for mapping ASCII characters to keycodes. You do not need to include the corresponding `keymap_*.h` header, as it is implicit when including the Sendstring header. | |||
There are also a few which are not quite language-specific, but useful if you are not using a QWERTY layout: | |||
An important thing to note here is that `SEND_STRING()` only operates on [ASCII text](https://en.wikipedia.org/wiki/ASCII#Character_set). This means that you cannot pass it a string containing Unicode characters - this unfortunately includes accented characters that may be present in your desired layout. | |||
Many layouts make certain characters, such as Grave or Tilde, available only as [dead keys](https://en.wikipedia.org/wiki/Dead_key), so you must add a space immediately after it in the string you want to send, to prevent it from potentially combining with the next character. | |||
Certain other layouts have no Sendstring header as they do not use a Latin-derived alphabet (for example Greek and Russian), and thus there is no way to input most of the ASCII character set. | |||
|Layout |Header | | |||
|-------------------|------------------------| | |||
|Colemak |`keymap_colemak.h` | | |||
|Dvorak |`keymap_dvorak.h` | | |||
|Dvorak (French) |`keymap_dvorak_fr.h` | | |||
|Dvorak (Programmer)|`keymap_dvp.h` | | |||
|Norman |`keymap_norman.h` | | |||
|Plover* |`keymap_plover.h` | | |||
|Plover (Dvorak)* |`keymap_plover_dvorak.h`| | |||
|Steno* |`keymap_steno.h` | | |||
|Workman |`keymap_workman.h` | | |||
|Workman (ZXCVM) |`keymap_workman_zxcvm.h`| | |||
## Header Files | |||
## Sendstring Support | |||
These headers are located in [`quantum/keymap_extras/`](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras). | |||
By default, `SEND_STRING()` assumes a US ANSI keyboard layout is set. If you are using a different layout, you can also `#include "sendstring_*.h"` (as above) in your keymap to override the lookup tables used for mapping ASCII characters to keycodes. | |||
|Layout |Keycodes Header |Sendstring LUT Header | | |||
|---------------------------------|---------------------------------|------------------------------------| | |||
|Canadian Multilingual (CSA) |`keymap_canadian_multilingual.h` |`sendstring_canadian_multilingual.h`| | |||
|Croatian |`keymap_croatian.h` |`sendstring_croatian.h` | | |||
|Czech |`keymap_czech.h` |`sendstring_czech.h` | | |||
|Danish |`keymap_danish.h` |`sendstring_danish.h` | | |||
|Dutch (Belgium) |`keymap_belgian.h` |`sendstring_belgian.h` | | |||
|English (Ireland) |`keymap_irish.h` | | | |||
|English (UK) |`keymap_uk.h` |`sendstring_uk.h` | | |||
|English (US Extended) |`keymap_us_extended.h` | | | |||
|English (US International) |`keymap_us_international.h` |`sendstring_us_international.h` | | |||
|English (US International, Linux)|`keymap_us_international_linux.h`| | | |||
|Estonian |`keymap_estonian.h` |`sendstring_estonian.h` | | |||
|Finnish |`keymap_finnish.h` |`sendstring_finnish.h` | | |||
|French |`keymap_french.h` |`sendstring_french.h` | | |||
|French (AFNOR) |`keymap_french_afnor.h` |`sendstring_french_afnor.h` | | |||
|French (BÉPO) |`keymap_bepo.h` |`sendstring_bepo.h` | | |||
|French (Belgium) |`keymap_belgian.h` |`sendstring_belgian.h` | | |||
|French (Switzerland) |`keymap_fr_ch.h` |`sendstring_fr_ch.h` | | |||
|French (macOS, ISO) |`keymap_french_osx.h` |`sendstring_french_osx.h` | | |||
|German |`keymap_german.h` |`sendstring_german.h` | | |||
|German (Switzerland) |`keymap_german_ch.h` |`sendstring_german_ch.h` | | |||
|German (macOS) |`keymap_german_osx.h` |`sendstring_german_osx.h` | | |||
|German (Neo2) |`keymap_neo2.h` | | | |||
|Greek |`keymap_greek.h` | | | |||
|Hebrew |`keymap_hebrew.h` | | | |||
|Hungarian |`keymap_hungarian.h` |`sendstring_hungarian.h` | | |||
|Icelandic |`keymap_icelandic.h` |`sendstring_icelandic.h` | | |||
|Italian |`keymap_italian.h` |`sendstring_italian.h` | | |||
|Italian (macOS, ANSI) |`keymap_italian_osx_ansi.h` |`sendstring_italian_osx_ansi.h` | | |||
|Italian (macOS, ISO) |`keymap_italian_osx_iso.h` |`sendstring_italian_osx_iso.h` | | |||
|Japanese |`keymap_jp.h` |`sendstring_jis.h` | | |||
|Korean |`keymap_korean.h` | | | |||
|Latvian |`keymap_latvian.h` |`sendstring_latvian.h` | | |||
|Lithuanian (ĄŽERTY) |`keymap_lithuanian_azerty.h` |`sendstring_lithuanian_azerty.h` | | |||
|Lithuanian (QWERTY) |`keymap_lithuanian_qwerty.h` |`sendstring_lithuanian_qwerty.h` | | |||
|Norwegian |`keymap_norwegian.h` |`sendstring_norwegian.h` | | |||
|Polish |`keymap_polish.h` | | | |||
|Portuguese |`keymap_portuguese.h` |`sendstring_portuguese.h` | | |||
|Portuguese (macOS, ISO) |`keymap_portuguese_osx_iso.h` |`sendstring_portuguese_osx_iso.h` | | |||
|Portuguese (Brazil) |`keymap_br_abnt2.h` |`sendstring_br_abnt2.h` | | |||
|Romanian |`keymap_romanian.h` |`sendstring_romanian.h` | | |||
|Russian |`keymap_russian.h` | | | |||
|Serbian |`keymap_serbian.h` | | | |||
|Serbian (Latin) |`keymap_serbian_latin.h` |`sendstring_serbian_latin.h` | | |||
|Slovak |`keymap_slovak.h` |`sendstring_slovak.h` | | |||
|Slovenian |`keymap_slovenian.h` |`sendstring_slovenian.h` | | |||
|Spanish |`keymap_spanish.h` |`sendstring_spanish.h` | | |||
|Spanish (Dvorak) |`keymap_spanish_dvorak.h` |`sendstring_spanish_dvorak.h` | | |||
|Swedish |`keymap_swedish.h` |`sendstring_swedish.h` | | |||
|Swedish (macOS, ANSI) |`keymap_swedish_osx_ansi.h` | | | |||
|Swedish (macOS, ISO) |`keymap_swedish_osx_iso.h` | | | |||
|Swedish Pro (macOS, ANSI) |`keymap_swedish_pro_osx_ansi.h` | | | |||
|Swedish Pro (macOS, ISO) |`keymap_swedish_pro_osx_iso.h` | | | |||
|Turkish (F) |`keymap_turkish_f.h` |`sendstring_turkish_f.h` | | |||
|Turkish (Q) |`keymap_turkish_q.h` |`sendstring_turkish_q.h` | | |||
An important thing to note here is that `SEND_STRING()` only operates on [ASCII text](https://en.wikipedia.org/wiki/ASCII#Character_set). This means that you cannot pass it a string containing Unicode characters - this unfortunately includes accented characters that may be present in your desired layout. | |||
Many layouts make certain characters, such as Grave or Tilde, available only as [dead keys](https://en.wikipedia.org/wiki/Dead_key), so you must add a space immediately after it in the string you want to send, to prevent it from potentially combining with the next character. | |||
Certain other layouts have no Sendstring header as they do not use a Latin-derived alphabet (for example Greek and Russian), and thus there is no way to input most of the ASCII character set. These are marked above with a `*`. | |||
There are also a few which are not quite language-specific, but useful if you are not using a QWERTY layout: | |||
|Layout |Keycodes Header |Sendstring LUT Header | | |||
|-------------------|------------------------|----------------------------| | |||
|Colemak |`keymap_colemak.h` |`sendstring_colemak.h` | | |||
|Dvorak |`keymap_dvorak.h` |`sendstring_dvorak.h` | | |||
|Dvorak (French) |`keymap_dvorak_fr.h` |`sendstring_dvorak_fr.h` | | |||
|Dvorak (Programmer)|`keymap_dvp.h` |`sendstring_dvp.h` | | |||
|Norman |`keymap_norman.h` |`sendstring_norman.h` | | |||
|Plover |`keymap_plover.h` | | | |||
|Plover (Dvorak) |`keymap_plover_dvorak.h`| | | |||
|Steno |`keymap_steno.h` | | | |||
|Workman |`keymap_workman.h` |`sendstring_workman.h` | | |||
|Workman (ZXCVM) |`keymap_workman_zxcvm.h`|`sendstring_workman_zxcvm.h`| |
@ -0,0 +1,185 @@ | |||
/* | |||
Copyright 2021 0xCB - Conor Burns | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
// clang-format off | |||
enum layer_names { | |||
_HOME, | |||
_MISC, | |||
_RGB, | |||
_BLED | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_HOME] = LAYOUT( | |||
KC_MPRV, KC_MNXT, KC_MPLY, | |||
KC_PGUP, KC_PGDN, TO(3), | |||
KC_HOME, KC_END, TO(1) | |||
), | |||
[_MISC] = LAYOUT( | |||
_______, _______, _______, | |||
_______, _______, TO(0), | |||
_______, _______, TO(2) | |||
), | |||
[_RGB] = LAYOUT( | |||
RGB_HUI, RGB_HUD, RGB_MOD, | |||
RGB_SAI, RGB_SAD, TO(1), | |||
RGB_SPI, RGB_SPD, TO(3) | |||
), | |||
[_BLED] = LAYOUT( | |||
BL_STEP, BL_BRTG, BL_TOGG, | |||
BL_ON, BL_OFF, TO(2), | |||
BL_INC, BL_DEC, TO(0) | |||
) | |||
}; | |||
// clang-format on | |||
/* rotary encoder (SW3) - add more else if blocks for more granular layer control */ | |||
#ifdef ENCODER_ENABLE | |||
bool encoder_update_user(uint8_t index, bool clockwise) { | |||
if (IS_LAYER_ON(_RGB)) { | |||
#ifdef RGBLIGHT_ENABLE | |||
if (clockwise) { | |||
rgblight_increase_val(); | |||
} else { | |||
rgblight_decrease_val(); | |||
} | |||
#endif | |||
} else if (IS_LAYER_ON(_BLED)) { | |||
if (clockwise) { | |||
backlight_increase(); | |||
} else { | |||
backlight_decrease(); | |||
} | |||
} else { | |||
if (clockwise) { | |||
tap_code(KC_VOLU); | |||
} else { | |||
tap_code(KC_VOLD); | |||
} | |||
} | |||
return true; | |||
} | |||
#endif | |||
/* oled stuff :) */ | |||
#ifdef OLED_DRIVER_ENABLE | |||
uint16_t startup_timer; | |||
oled_rotation_t oled_init_user(oled_rotation_t rotation) { | |||
startup_timer = timer_read(); | |||
return rotation; | |||
} | |||
static void render_logo(void) { | |||
static const char PROGMEM raw_logo[] = { | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 64,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 1, 2, 4, 2, 1, 1, 1, 1, 1, 1,255, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,248, 5, 2, 0, 0, 0, 0, 0, 0,128,192,192,224,224,112,120, 56, 63, 28, 14, 14, 14,254, 14, 14, 30, 28, 63, 56,120,112,224,224,192,128, 0, 0, 0, 0, 0, 0, 0, 2, 5,248, 5, 2, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,160, 19,162, 66, 66, 66, 66, 66, 66, 66,255,255,255, 0, 0, 0,252,254,254,192,192,192,192,255, 0, 0, 0, 62, 62, 60, 60, 0, 0, 1,255,255,255, 66, 66, 66, 66, 66, 66, 66,162, 19,160, 64, 0, | |||
0, 0, 0,128, 64, 64, 64,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,192, 64, 64,192,128, 0, 0,192, 64, 64,192,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 64,192, 0, 0, 0, 0, 0,128,192, 64, 64,192,128, 0, 0,128,192, 64, 64,192,128, 0, 0, 64, 64, 64, 64, 64,192, 0, 0, 0, 0, 0,249, 8, 8, 8, 8, 8, 8, 8, 8,127,255,255,192,128,128, 15, 31, 31, 1, 1, 1, 1,255, 0, 0, 0, 30, 30, 14, 14,128,192,192,255,255,127, 8, 8, 8, 8, 8, 8, 8, 8,249, 0, 0, 0, | |||
0, 0, 31, 49, 64, 78, 64, 49, 31, 0, 0, 97, 22, 8, 22, 97, 0, 0, 31, 49, 96, 64, 64, 96, 32, 0, 0,127, 68, 68,100, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64,127, 64, 64, 0, 0, 0, 32,100, 68, 68,110, 59, 0, 0, 32,100, 68, 68,110, 59, 0, 0, 0, 0, 0,126, 3, 1, 0, 0, 0, 8, 20, 35, 20, 8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 7, 7, 15,254, 30, 28, 28, 28,255, 28, 28, 28, 30,254, 15, 7, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 10, 17, 10, 4, 0, | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 68, 40, 16, 16, 16, 16, 16, 16, 31, 0, 0, 16, 40, 71, 40, 16, 0, 0, 31, 16, 16, 16, 16, 16, 16, 40, 68, 40, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
}; | |||
oled_write_raw_P(raw_logo, sizeof(raw_logo)); | |||
} | |||
static void render_logo_font(void) { | |||
static const char PROGMEM qmk_logo[] = { | |||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xCB, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0xCB, 0xCB, 0xCB, 0x9C, 0x9D, 0xCB, 0xCB, | |||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xCB, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xCB, 0xCB, 0xBB, 0xBC, 0xBD, 0xBE, 0xCB, | |||
0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xCB, 0x88, 0x89, 0x8A, 0x8B, 0x8A, 0x8B, 0x8C, 0x8D, 0xCB, 0xCB, 0xDB, 0xDC, 0xDD, 0xDE, 0xCB, | |||
0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xCB, 0xA8, 0xA9, 0xAA, 0xAB, 0xAA, 0xAB, 0xAC, 0xAD, 0xCB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00 | |||
}; | |||
oled_write_P(qmk_logo, false); | |||
} | |||
/* Shows the name of the current layer and locks for the host (CAPS etc.) */ | |||
static void render_info(void) { | |||
oled_write_P(PSTR("Layer: "), false); | |||
switch (get_highest_layer(layer_state)) { | |||
case _HOME: | |||
oled_write_ln_P(PSTR("HOME"), false); | |||
break; | |||
case _MISC: | |||
oled_write_ln_P(PSTR("MISC"), false); | |||
break; | |||
case _RGB: | |||
oled_write_ln_P(PSTR("RGB"), false); | |||
break; | |||
case _BLED: | |||
oled_write_ln_P(PSTR("Backlight"), false); | |||
break; | |||
default: | |||
oled_write_ln_P(PSTR("Undefined"), false); | |||
} | |||
led_t led_state = host_keyboard_led_state(); | |||
oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); | |||
oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false); | |||
oled_write_ln_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false); | |||
} | |||
static void render_rgbled_status(bool) { | |||
char string[4]; | |||
if (RGBLIGHT_MODES > 1 && rgblight_is_enabled() && get_highest_layer(layer_state) == _RGB) { | |||
uint16_t m = rgblight_get_mode(); | |||
string[3] = '\0'; | |||
string[2] = '0' + m % 10; | |||
string[1] = ( m /= 10) % 10 ? '0' + (m) % 10 : (m / 10) % 10 ? '0' : ' '; | |||
string[0] = m / 10 ? '0' + m / 10 : ' '; | |||
oled_write_P(PSTR("Conf:"), false); | |||
oled_write(string, false); | |||
uint16_t h = rgblight_get_hue()/RGBLIGHT_HUE_STEP; | |||
string[3] = '\0'; | |||
string[2] = '0' + h % 10; | |||
string[1] = ( h /= 10) % 10 ? '0' + (h) % 10 : (h / 10) % 10 ? '0' : ' '; | |||
string[0] = h / 10 ? '0' + h / 10 : ' '; | |||
oled_write_P(PSTR(","), false); | |||
oled_write(string, false); | |||
uint16_t s = rgblight_get_sat()/RGBLIGHT_SAT_STEP; | |||
string[3] = '\0'; | |||
string[2] = '0' + s % 10; | |||
string[1] = ( s /= 10) % 10 ? '0' + (s) % 10 : (s / 10) % 10 ? '0' : ' '; | |||
string[0] = s / 10 ? '0' + s / 10 : ' '; | |||
oled_write_P(PSTR(","), false); | |||
oled_write(string, false); | |||
uint16_t v = rgblight_get_val()/RGBLIGHT_VAL_STEP; | |||
string[3] = '\0'; | |||
string[2] = '0' + v % 10; | |||
string[1] = ( v /= 10) % 10 ? '0' + (v) % 10 : (v / 10) % 10 ? '0' : ' '; | |||
string[0] = v / 10 ? '0' + v / 10 : ' '; | |||
oled_write_P(PSTR(","), false); | |||
oled_write(string, false); | |||
oled_write_ln_P(PSTR("\n MOD HUE SAT VAR"), false); | |||
} else { | |||
oled_write_ln_P(PSTR("\n"), false); | |||
} | |||
} | |||
void oled_task_user(void) { | |||
static bool finished_timer = false; | |||
if (!finished_timer && (timer_elapsed(startup_timer) < 1000)) { | |||
render_logo(); | |||
} else { | |||
if (!finished_timer) { | |||
oled_clear(); | |||
finished_timer = true; | |||
} | |||
render_info(); | |||
render_rgbled_status(true); | |||
render_logo_font(); | |||
} | |||
} | |||
#endif |
@ -0,0 +1,297 @@ | |||
/* | |||
Copyright 2021 0xCB - Conor Burns | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
// clang-format off | |||
enum my_keycodes { | |||
WPM = SAFE_RANGE, | |||
}; | |||
enum layer_names { | |||
_HOME, | |||
_FN2, | |||
_FN3, | |||
_FN4 | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_HOME] = LAYOUT_all( | |||
KC_MPLY, | |||
KC_GESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, | |||
KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_ENT, | |||
KC_LSPO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_RSPC, | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), MO(2) | |||
), | |||
[_FN2] = LAYOUT_all( | |||
RESET, | |||
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, | |||
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN3] = LAYOUT_all( | |||
EEP_RST, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LBRC, KC_RBRC, KC_BSLS, | |||
_______, _______, _______, _______, _______, _______, _______, _______, KC_SCLN, KC_QUOT, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_SLSH, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
[_FN4] = LAYOUT_all( | |||
_______, | |||
WPM, KC_MUTE, KC_VOLD, KC_VOLU, KC_MPRV, KC_MNXT, KC_MSTP, KC_INS, KC_HOME, KC_DEL, KC_END, _______, | |||
_______, _______, KC_BRID, KC_BRIU, _______, _______, _______, KC_PGUP, KC_UP, KC_PGDN, _______, | |||
_______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
}; | |||
// clang-format on | |||
/* WPM toggle key bongocat hehe */ | |||
bool wpm = false; | |||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
switch (keycode) { | |||
case WPM: | |||
if (record->event.pressed) { | |||
wpm = !wpm; | |||
} | |||
return false; | |||
default: | |||
return true; | |||
} | |||
} | |||
/*layer switcher */ | |||
layer_state_t layer_state_set_user(layer_state_t state) { | |||
state = update_tri_layer_state(state, _FN2, _FN3, _FN4); | |||
return state; | |||
} | |||
/* rotary encoder (MX12) - add different functions for layers here */ | |||
#ifdef ENCODER_ENABLE | |||
bool encoder_update_user(uint8_t index, bool clockwise) { | |||
if (IS_LAYER_ON(_FN4)) { | |||
if (clockwise) { | |||
tap_code(KC_VOLU); | |||
} else { | |||
tap_code(KC_VOLD); | |||
} | |||
} else if (IS_LAYER_ON(_FN3)) { | |||
if (clockwise) { | |||
tap_code(KC_VOLU); | |||
} else { | |||
tap_code(KC_VOLD); | |||
} | |||
} else if (IS_LAYER_ON(_FN2)) { | |||
if (clockwise) { | |||
tap_code(KC_VOLU); | |||
} else { | |||
tap_code(KC_VOLD); | |||
} | |||
} else { | |||
if (clockwise) { | |||
tap_code(KC_VOLU); | |||
} else { | |||
tap_code(KC_VOLD); | |||
} | |||
} | |||
return true; | |||
} | |||
#endif | |||
/* oled stuff :) */ | |||
#ifdef OLED_DRIVER_ENABLE | |||
#define IDLE_FRAMES 5 | |||
#define IDLE_SPEED 20 // below this wpm value your animation will idle | |||
#define TAP_FRAMES 2 | |||
#define TAP_SPEED 40 // above this wpm value typing animation to trigger | |||
#define ANIM_FRAME_DURATION 200 // how long each frame lasts in ms | |||
#define ANIM_SIZE 636 // number of bytes in array | |||
uint32_t anim_timer = 0; | |||
uint32_t anim_sleep = 0; | |||
uint8_t current_idle_frame = 0; | |||
uint8_t current_tap_frame = 0; | |||
uint16_t startup_timer = 0; | |||
oled_rotation_t oled_init_user(oled_rotation_t rotation) { | |||
startup_timer = timer_read(); | |||
return rotation; | |||
} | |||
static void render_logo(void) { | |||
static const char PROGMEM raw_logo[] = { | |||
0, 8, 0,192,194,192,192, 60, 60, 44, 60,188, 60, 60, 60, 60, 44, 61, 60,192,192,192,208, 1, 0,252,252,180,252, 60, 60, 44, 60,252,253,252,252, 60, 60, 44, 60,244,220,252,252, 0, 0, 16, 0, 0, 0,192,192, 65,192, 60, 60, 52, 60,192,193,192,192, 16, 0, 0,144, 4, 0,252,125,244, 60, 60, 60, 60, 61,252,252,244,252, 60, 60, 60, 61,248,108,252, 0, 0, 61, 60,188, 60, 52,252,252,220,252, 61, 60, 60, 52, 0, 0,192,210, 64,192, 60, 60, 44, 61, 60, 60, 60, 61, 52, 60, 60, 60,192,192, 64,196, 0, 4, 0, | |||
0, 16, 0, 61, 63, 55, 63,192, 64,192,196,192,192,192,200,192,196,192,192, 3, 3, 2, 11, 0, 0, 35, 3, 3, 3, 0, 64, 2, 0,255,255,253,247, 0, 0, 0, 32, 1, 0, 1, 65, 8, 0,189,244,252,236, 3,130, 3, 1, 0, 68, 0, 0, 3, 34,131, 3,252,252,236,252, 0, 32, 17, 1, 1, 0, 0, 32, 0, 2,255,255,127,247, 0, 1, 0, 8, 1, 1, 1, 0, 0, 0, 16, 0, 64, 0,255,191,255,251, 0,129, 0, 2, 32, 0,255,255,239,255, 0, 0, 2, 0, 0, 0, 8, 64, 0, 1, 0, 0, 3, 35, 3, 3, 0, 8, 0, | |||
1, 16, 0,192, 64,194,192, 3, 67, 3, 3, 9, 3, 3, 3, 3, 2, 83, 3,252,252,188,244, 0, 2, 32, 0, 0, 2, 0,144, 0, 0,255,255,237,255, 0, 16, 0, 0, 0, 64, 2, 0,128, 0,255,123,255,255, 60, 52, 60, 60, 60, 60, 60, 60, 44, 60, 56, 60,239,255,126,255, 0, 2, 32, 0, 0, 34, 0, 0, 16, 0,255,255,255,223, 0, 0, 4, 0, 0, 0, 33, 0, 0, 17, 0, 0, 0, 0,255,255,239,255, 0,128, 0, 0, 72, 0,255,253,247,255, 0, 0, 1, 0,144, 0, 4, 0, 32, 0, 0, 2,192,192,192,200, 0, 16, 0, | |||
64, 4, 0, 3, 7, 3, 3, 60, 60, 52,188, 60, 61, 60, 60, 60, 60, 44, 60, 67, 3, 3, 3, 0, 0, 64, 0, 0, 4, 0, 0, 16, 0, 47, 63, 62, 63, 0, 0,132, 0, 0, 0, 0,128, 8, 0,255,255,111,127, 0, 0, 0, 2,128, 0, 0, 0, 64, 4, 0,128,127,127,107,127, 0, 32, 0, 0, 0, 66, 0, 0, 0,136, 55, 63, 61, 63, 0, 0, 0, 2, 0, 64, 0,136, 0, 0, 60, 44,189, 60, 63, 63, 63, 59, 60, 60,172, 60, 0, 64, 3, 2, 3,131, 60, 44, 60, 60, 60, 60,188, 60, 56, 44, 60, 60, 3, 3,131, 2, 0, 32, 2, | |||
}; | |||
oled_write_raw_P(raw_logo, sizeof(raw_logo)); | |||
} | |||
/* Shows the name of the current layer and locks for the host (CAPS etc.) */ | |||
static void render_layer(void) { | |||
led_t led_state = host_keyboard_led_state(); | |||
// clang-format off | |||
static const char PROGMEM logo[][3][7] = { | |||
{{0x97, 0x98, 0x99, 0x9A, 0}, {0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0}, {0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0}}, /* l num CB */ | |||
{{0xB7, 0xB8, 0xB9, 0xBA, 0}, {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0}, {0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0}}, /* 1 num CB */ | |||
{{0xD7, 0xD8, 0xD9, 0xDA, 0}, {0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0}, {0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0}}, /* 1 cap CB */ | |||
{{0xF7, 0xF8, 0xF9, 0xFA, 0}, {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0}, {0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0}}, /* l cap CB */ | |||
{{0xB7, 0xC0, 0xC1, 0xBA, 0}, {0xB7, 0xC2, 0xC3, 0xBA, 0}, {0xB7, 0xC4, 0xC5, 0xBA, 0}}, /* 2 3 4 */ | |||
{{0xD7, 0xE0, 0xE1, 0xDA, 0}, {0xD7, 0xE2, 0xE3, 0xDA, 0}, {0xD7, 0xE4, 0xE5, 0xDA, 0}}, /* 2 3 4 */ | |||
}; | |||
// clang-format on | |||
oled_set_cursor(0, 0); | |||
oled_write_P(logo[0][0], false); | |||
oled_set_cursor(0, 3); | |||
oled_write_P(logo[3][0], false); | |||
switch (get_highest_layer(layer_state)) { | |||
case _HOME: | |||
oled_set_cursor(0, 1); | |||
oled_write_P(logo[1][0], false); | |||
oled_set_cursor(0, 2); | |||
oled_write_P(logo[2][0], false); | |||
break; | |||
case _FN2: | |||
oled_set_cursor(0, 1); | |||
oled_write_P(logo[4][0], false); | |||
oled_set_cursor(0, 2); | |||
oled_write_P(logo[5][0], false); | |||
break; | |||
case _FN3: | |||
oled_set_cursor(0, 1); | |||
oled_write_P(logo[4][1], false); | |||
oled_set_cursor(0, 2); | |||
oled_write_P(logo[5][1], false); | |||
break; | |||
case _FN4: | |||
oled_set_cursor(0, 1); | |||
oled_write_P(logo[4][2], false); | |||
oled_set_cursor(0, 2); | |||
oled_write_P(logo[5][2], false); | |||
break; | |||
default: | |||
oled_set_cursor(0, 1); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(0, 2); | |||
oled_write_P(PSTR(" "), false); | |||
} | |||
oled_set_cursor(8, 0); | |||
oled_write_P(led_state.num_lock ? logo[0][1] : PSTR(" "), false); | |||
oled_set_cursor(8, 1); | |||
oled_write_P(led_state.num_lock ? logo[1][1] : PSTR(" "), false); | |||
oled_set_cursor(8, 2); | |||
oled_write_P(led_state.caps_lock ? logo[2][1] : PSTR(" "), false); | |||
oled_set_cursor(8, 3); | |||
oled_write_P(led_state.caps_lock ? logo[3][1] : PSTR(" "), false); | |||
oled_set_cursor(16, 0); | |||
oled_write_P(logo[0][2], false); | |||
oled_set_cursor(16, 1); | |||
oled_write_P(logo[1][2], false); | |||
oled_set_cursor(16, 2); | |||
oled_write_P(logo[2][2], false); | |||
oled_set_cursor(16, 3); | |||
oled_write_P(logo[3][2], false); | |||
/* Fill empty space to clear animation */ | |||
oled_set_cursor(4, 0); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(4, 1); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(4, 2); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(4, 3); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(14, 0); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(14, 1); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(14, 2); | |||
oled_write_P(PSTR(" "), false); | |||
oled_set_cursor(14, 3); | |||
oled_write_P(PSTR(" "), false); | |||
} | |||
static void render_cat(void) { | |||
static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = { | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x34, 0xc4, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x31, 0xc1, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; | |||
static const char PROGMEM prep[][ANIM_SIZE] = { | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; | |||
static const char PROGMEM tap[TAP_FRAMES][ANIM_SIZE] = { | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x98, 0xc0, 0x88, 0x88, 0x8c, 0x9c, 0x1c, 0x1e, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x0f, 0x07, 0x03, 0x03, 0x61, 0xf0, 0xf8, 0xfc, 0x60, 0x01, 0x01, 0x01, 0x3c, 0x78, 0xf8, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | |||
}; | |||
void animation_phase(void) { | |||
if (get_current_wpm() <= IDLE_SPEED) { | |||
current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES; | |||
oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE); | |||
} | |||
if (get_current_wpm() > IDLE_SPEED && get_current_wpm() < TAP_SPEED) { | |||
oled_write_raw_P(prep[0], ANIM_SIZE); | |||
} | |||
if (get_current_wpm() >= TAP_SPEED) { | |||
current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES; | |||
oled_write_raw_P(tap[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIM_SIZE); | |||
} | |||
} | |||
if (get_current_wpm() != 000) { | |||
if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { | |||
anim_timer = timer_read32(); | |||
animation_phase(); | |||
} | |||
anim_sleep = timer_read32(); | |||
} else { | |||
if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { | |||
anim_timer = timer_read32(); | |||
animation_phase(); | |||
} | |||
} | |||
} | |||
void oled_task_user(void) { | |||
static bool finished_timer = false; | |||
if (!finished_timer && (timer_elapsed(startup_timer) < 3000)) { | |||
render_logo(); | |||
} else { | |||
if (!finished_timer) { | |||
oled_clear(); | |||
finished_timer = true; | |||
} | |||
if (wpm) { | |||
render_cat(); | |||
oled_set_cursor(0, 0); | |||
char string[10]; | |||
uint16_t m = get_current_wpm(); | |||
string[3] = '\0'; | |||
string[2] = '0' + m % 10; | |||
string[1] = ( m /= 10) % 10 ? '0' + (m) % 10 : (m / 10) % 10 ? '0' : ' '; | |||
string[0] = m / 10 ? '0' + m / 10 : ' '; | |||
oled_write_P(PSTR("WPM:"), false); | |||
oled_write(string, false); | |||
} else { | |||
render_layer(); | |||
} | |||
} | |||
} | |||
#endif | |||
/* Resets via on eep reset - thank you drashna! */ | |||
void eeconfig_init_kb(void) { | |||
via_eeprom_set_valid(false); | |||
via_init(); | |||
eeconfig_init_user(); | |||
} |
@ -0,0 +1,2 @@ | |||
VIA_ENABLE = yes | |||
WPM_ENABLE = yes |
@ -0,0 +1,56 @@ | |||
{ | |||
"keyboard_name": "3w6", | |||
"url": "https://github.com/weteor/3W6/", | |||
"maintainer": "weteor", | |||
"width": 13, | |||
"height": 5, | |||
"layouts": { | |||
"LAYOUT": { | |||
"layout": [ | |||
{"label": "k00", "x": 0, "y": 0.8}, | |||
{"label": "k01", "x": 1, "y": 0.2}, | |||
{"label": "k02", "x": 2, "y": 0}, | |||
{"label": "k03", "x": 3, "y": 0.2}, | |||
{"label": "k04", "x": 4, "y": 0.4}, | |||
{"label": "k05", "x": 8, "y": 0.4}, | |||
{"label": "k06", "x": 9, "y": 0.2}, | |||
{"label": "k07", "x": 10, "y": 0}, | |||
{"label": "k08", "x": 11, "y": 0.2}, | |||
{"label": "k09", "x": 12, "y": 0.8}, | |||
{"label": "k10", "x": 0, "y": 1.8}, | |||
{"label": "k11", "x": 1, "y": 1.2}, | |||
{"label": "k12", "x": 2, "y": 1}, | |||
{"label": "k13", "x": 3, "y": 1.2}, | |||
{"label": "k14", "x": 4, "y": 1.4}, | |||
{"label": "k15", "x": 8, "y": 1.4}, | |||
{"label": "k16", "x": 9, "y": 1.2}, | |||
{"label": "k17", "x": 10, "y": 1}, | |||
{"label": "k18", "x": 11, "y": 1.2}, | |||
{"label": "k19", "x": 12, "y": 1.8}, | |||
{"label": "k20", "x": 0, "y": 2.8}, | |||
{"label": "k21", "x": 1, "y": 2.2}, | |||
{"label": "k22", "x": 2, "y": 2}, | |||
{"label": "k23", "x": 3, "y": 2.2}, | |||
{"label": "k24", "x": 4, "y": 2.4}, | |||
{"label": "k25", "x": 8, "y": 2.4}, | |||
{"label": "k26", "x": 9, "y": 2.2}, | |||
{"label": "k27", "x": 10, "y": 2}, | |||
{"label": "k28", "x": 11, "y": 2.2}, | |||
{"label": "k29", "x": 12, "y": 2.8}, | |||
{"label": "k32", "x": 3.2, "y": 3.6}, | |||
{"label": "k33", "x": 4.2, "y": 3.6}, | |||
{"label": "k34", "x": 5.2, "y": 3.8}, | |||
{"label": "k35", "x": 6.8, "y": 3.8}, | |||
{"label": "k36", "x": 7.8, "y": 3.6}, | |||
{"label": "k37", "x": 8.8, "y": 3.6} | |||
] | |||
} | |||
} | |||
} |
@ -0,0 +1,69 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
enum layers | |||
{ | |||
_ALPHA_QWERTY = 0, | |||
_ALPHA_COLEMAK, | |||
_SYM, | |||
_NAV, | |||
_NUM, | |||
_CFG, | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_ALPHA_QWERTY] = LAYOUT( | |||
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, | |||
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), | |||
LCTL_T(KC_ESC), LT(_NUM,KC_SPC), LT(_NAV, KC_TAB), LT(_SYM, KC_BSPC), KC_ENT, LALT_T(KC_DEL) | |||
), | |||
[_ALPHA_COLEMAK] = LAYOUT( | |||
KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, | |||
KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SCLN), | |||
LCTL_T(KC_ENT), LT(_NUM,KC_SPC), LT(_NAV, KC_TAB), LT(_SYM, KC_BSPC), KC_ENT, LALT_T(KC_DEL) | |||
), | |||
[_SYM] = LAYOUT( | |||
KC_GRV , KC_CIRC, KC_AT, KC_DLR, KC_TILD, KC_AMPR, KC_EXLM, KC_PIPE, KC_UNDS, KC_HASH, | |||
KC_SLSH, KC_LBRC, KC_LCBR, KC_LPRN, KC_EQL, KC_ASTR, KC_RPRN, KC_RCBR, KC_RBRC, KC_BSLS, | |||
_______, KC_QUES, KC_PLUS, KC_PERC, XXXXXXX, XXXXXXX, XXXXXXX, KC_MINS, XXXXXXX, _______, | |||
XXXXXXX, MO(_CFG), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX | |||
), | |||
[_NAV] = LAYOUT( | |||
XXXXXXX, KC_VOLD, KC_MUTE, KC_VOLU, XXXXXXX, XXXXXXX, KC_PGDN, KC_UP, KC_PGUP, KC_DEL, | |||
KC_MPRV, KC_MPLY, KC_MSTP, KC_MNXT, XXXXXXX, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MO(_CFG), XXXXXXX | |||
), | |||
[_NUM] = LAYOUT( | |||
XXXXXXX, KC_F9, KC_F10, KC_F11, KC_F12, KC_PPLS, KC_P7, KC_P8, KC_P9, KC_PSLS, | |||
XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8, KC_P0, KC_P4, KC_P5, KC_P6, KC_PDOT, | |||
XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, KC_PMNS, KC_P1, KC_P2, KC_P3, KC_PAST, | |||
XXXXXXX, XXXXXXX, XXXXXXX, KC_PEQL, KC_PENT, XXXXXXX | |||
), | |||
[_CFG] = LAYOUT( | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,DF(_ALPHA_QWERTY), DF(_ALPHA_COLEMAK), | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX | |||
), | |||
}; |
@ -0,0 +1,32 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
// generated from users/manna-harbour_miryoku/miryoku.org -*- buffer-read-only: t -*- | |||
#pragma once | |||
#define LAYOUT_miryoku( \ | |||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, \ | |||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, \ | |||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, \ | |||
N30, N31, K32, K33, K34, K35, K36, K37, N38, N39 \ | |||
) \ | |||
LAYOUT( \ | |||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, \ | |||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, \ | |||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, \ | |||
K32, K33, K34, K35, K36, K37 \ | |||
) |
@ -0,0 +1,17 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
// generated from users/manna-harbour_miryoku/miryoku.org -*- buffer-read-only: t -*- |
@ -0,0 +1,45 @@ | |||
# 3W6 | |||
![3W6](https://raw.githubusercontent.com/weteor/3W6/main/images/3w6_rev2_1s.jpg) | |||
The 3w6 is a low profile, split ortholinear keyboard with 36 keys. | |||
I needed a keyboard for work and wasn't really satisfied with the available alternatives (namely Corne, Kyria and Ferris), mostly because they are either rather large and/or don't have the spacing I would like. | |||
The 3w6 is designed to be a simple, realiable, cheap and small keyboard to be taken everywhere. | |||
There are currently two revisions: | |||
* Rev1: | |||
- onboard microcontroller (ATMega32U4) | |||
- USB-C connector Board <-> PC | |||
- USB-C connectors between both split halfs | |||
- choc spacing (18x17mm) | |||
- aggressive pinky stagger | |||
- support for Choc V1 switches | |||
* Rev2: | |||
- everything Rev1 did | |||
- additional middle plate (2mm) | |||
- support for [Pimoroni Trackball](https://shop.pimoroni.com/products/trackball-breakout) instead of outer thumb switch on right half, needs midplate | |||
- mounting holes for [Tenting Puck](https://splitkb.com/collections/keyboard-parts/products/tenting-puck), only usable without mid or switchplate | |||
--- | |||
* Keyboard Maintainer: [weteor](https://github.com/weteor) | |||
* Hardware Supported: | |||
* 3w6 rev1 | |||
* 3w6 rev2 (with Pimoroni support) | |||
* Hardware Availability: | |||
* make one yourself: [Design and Productionfiles](https://github.com/weteor/3w6) | |||
* maintainer is selling kits when available | |||
--- | |||
To reach the bootloader, connect the board to the PC and push the reset button on left half. | |||
Make examples for this keyboard (after setting up your build environment): | |||
make 3w6/rev1:default | |||
make 3w6/rev2:default | |||
make 3w6/rev2:default_pimoroni | |||
--- | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). |
@ -0,0 +1,63 @@ | |||
/* | |||
Copyright 2021 weteor | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
/* USB Device descriptor parameter */ | |||
#define VENDOR_ID 0xFEED | |||
#define PRODUCT_ID 0x4658 | |||
#define DEVICE_VER 0x0001 | |||
#define MANUFACTURER weteor | |||
#define PRODUCT 3w6 | |||
/* key matrix size */ | |||
#define MATRIX_ROWS 8 | |||
#define MATRIX_COLS 10 | |||
#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2) | |||
#define MATRIX_COLS_PER_SIDE (MATRIX_COLS / 2) | |||
/* | |||
* Keyboard Matrix Assignments | |||
* | |||
* Change this to how you wired your keyboard | |||
* COLS: AVR pins used for columns, left to right | |||
* ROWS: AVR pins used for rows, top to bottom | |||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) | |||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) | |||
* | |||
*/ | |||
#define MATRIX_ROW_PINS_L { B0, B1, B2, B4} | |||
#define MATRIX_COL_PINS_L { B3, E6, F7, B6, B5 } | |||
#define UNUSED_PINS_L { B7, C6, C7, D2, D3, D4, D5, D6, D7, F0, F1, F4, F5, F6 } | |||
#define MATRIX_ROW_PINS_R { P10, P11, P12, P05 } | |||
#define MATRIX_COL_PINS_R { P06, P13, P14, P01, P00 } | |||
#define UNUSED_PINS_R { P02, P03, P04, P07, P15, P16, P17 } | |||
/* COL2ROW, ROW2COL */ | |||
#define DIODE_DIRECTION COL2ROW | |||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ | |||
#define DEBOUNCE 5 | |||
/* disable these deprecated features by default */ | |||
#define NO_ACTION_MACRO | |||
#define NO_ACTION_FUNCTION | |||
@ -0,0 +1,280 @@ | |||
/* | |||
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com> | |||
2020 Pierre Chevalier <pierrechevalier83@gmail.com> | |||
2021 weteor | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
/* | |||
* This code was heavily inspired by the ergodox_ez keymap, and modernized | |||
* to take advantage of the quantum.h microcontroller agnostics gpio control | |||
* abstractions and use the macros defined in config.h for the wiring as opposed | |||
* to repeating that information all over the place. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
#include "i2c_master.h" | |||
extern i2c_status_t tca9555_status; | |||
#define I2C_TIMEOUT 1000 | |||
// I2C address: | |||
// All address pins of the tca9555 are connected to the ground | |||
// | 0 | 1 | 0 | 0 | A2 | A1 | A0 | | |||
// | 0 | 1 | 0 | 0 | 0 | 0 | 0 | | |||
#define I2C_ADDR 0b0100000 | |||
#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) | |||
#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) | |||
// Register addresses | |||
#define IODIRA 0x06 // i/o direction register | |||
#define IODIRB 0x07 | |||
#define IREGP0 0x00 // GPIO pull-up resistor register | |||
#define IREGP1 0x01 | |||
#define OREGP0 0x02 // general purpose i/o port register (write modifies OLAT) | |||
#define OREGP1 0x03 | |||
bool i2c_initialized = 0; | |||
i2c_status_t tca9555_status = I2C_ADDR; | |||
uint8_t init_tca9555(void) { | |||
print("starting init"); | |||
tca9555_status = I2C_ADDR; | |||
// I2C subsystem | |||
if (i2c_initialized == 0) { | |||
i2c_init(); // on pins D(1,0) | |||
i2c_initialized = true; | |||
wait_ms(I2C_TIMEOUT); | |||
} | |||
// set pin direction | |||
// - unused : input : 1 | |||
// - input : input : 1 | |||
// - driving : output : 0 | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(IODIRA, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
// This means: write on pin 5 of port 0, read on rest | |||
tca9555_status = i2c_write(0b11011111, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
// This means: we will write on pins 0 to 2 on port 1. read rest | |||
tca9555_status = i2c_write(0b11111000, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
out: | |||
i2c_stop(); | |||
return tca9555_status; | |||
} | |||
/* matrix state(1:on, 0:off) */ | |||
static matrix_row_t matrix[MATRIX_ROWS]; // debounced values | |||
static matrix_row_t read_cols(uint8_t row); | |||
static void init_cols(void); | |||
static void unselect_rows(void); | |||
static void select_row(uint8_t row); | |||
static uint8_t tca9555_reset_loop; | |||
void matrix_init_custom(void) { | |||
// initialize row and col | |||
tca9555_status = init_tca9555(); | |||
unselect_rows(); | |||
init_cols(); | |||
// initialize matrix state: all keys off | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = 0; | |||
} | |||
} | |||
void matrix_power_up(void) { | |||
tca9555_status = init_tca9555(); | |||
unselect_rows(); | |||
init_cols(); | |||
// initialize matrix state: all keys off | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = 0; | |||
} | |||
} | |||
// Reads and stores a row, returning | |||
// whether a change occurred. | |||
static inline bool store_matrix_row(matrix_row_t current_matrix[], uint8_t index) { | |||
matrix_row_t temp = read_cols(index); | |||
if (current_matrix[index] != temp) { | |||
current_matrix[index] = temp; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool matrix_scan_custom(matrix_row_t current_matrix[]) { | |||
if (tca9555_status) { // if there was an error | |||
if (++tca9555_reset_loop == 0) { | |||
// since tca9555_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans | |||
// this will be approx bit more frequent than once per second | |||
dprint("trying to reset tca9555\n"); | |||
tca9555_status = init_tca9555(); | |||
if (tca9555_status) { | |||
dprint("right side not responding\n"); | |||
} else { | |||
dprint("right side attached\n"); | |||
} | |||
} | |||
} | |||
bool changed = false; | |||
for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { | |||
// select rows from left and right hands | |||
uint8_t left_index = i; | |||
uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; | |||
select_row(left_index); | |||
select_row(right_index); | |||
// we don't need a 30us delay anymore, because selecting a | |||
// left-hand row requires more than 30us for i2c. | |||
changed |= store_matrix_row(current_matrix, left_index); | |||
changed |= store_matrix_row(current_matrix, right_index); | |||
unselect_rows(); | |||
} | |||
return changed; | |||
} | |||
static void init_cols(void) { | |||
// init on tca9555 | |||
// not needed, already done as part of init_tca9555() | |||
// init on mcu | |||
pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_L; | |||
for (int pin_index = 0; pin_index < MATRIX_COLS_PER_SIDE; pin_index++) { | |||
pin_t pin = matrix_col_pins_mcu[pin_index]; | |||
setPinInput(pin); | |||
writePinHigh(pin); | |||
} | |||
} | |||
static matrix_row_t read_cols(uint8_t row) { | |||
if (row < MATRIX_ROWS_PER_SIDE) { | |||
pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_L; | |||
matrix_row_t current_row_value = 0; | |||
// For each col... | |||
for (uint8_t col_index = 0; col_index < MATRIX_COLS_PER_SIDE; col_index++) { | |||
// Select the col pin to read (active low) | |||
uint8_t pin_state = readPin(matrix_col_pins_mcu[col_index]); | |||
// Populate the matrix row with the state of the col pin | |||
current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); | |||
} | |||
return current_row_value; | |||
} else { | |||
if (tca9555_status) { // if there was an error | |||
return 0; | |||
} else { | |||
uint8_t data = 0; | |||
uint8_t port0 = 0; | |||
uint8_t port1 = 0; | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(IREGP0, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_read_ack(I2C_TIMEOUT); | |||
if (tca9555_status < 0) goto out; | |||
port0 = (uint8_t)tca9555_status; | |||
tca9555_status = i2c_read_nack(I2C_TIMEOUT); | |||
if (tca9555_status < 0) goto out; | |||
port1 = (uint8_t)tca9555_status; | |||
// The initial state was all ones and any depressed key at a given column for the currently selected row will have its bit flipped to zero. | |||
// The return value is a row as represented in the generic matrix code were the rightmost bits represent the lower columns and zeroes represent non-depressed keys while ones represent depressed keys. | |||
// Since the pins are not ordered sequentially, we have to build the correct dataset from the two ports. Refer to the schematic to see where every pin is connected. | |||
data |= ( port0 & 0x01 ); | |||
data |= ( port0 & 0x02 ); | |||
data |= ( port1 & 0x10 ) >> 2; | |||
data |= ( port1 & 0x08 ); | |||
data |= ( port0 & 0x40 ) >> 2; | |||
data = ~(data); | |||
tca9555_status = I2C_STATUS_SUCCESS; | |||
out: | |||
i2c_stop(); | |||
return data; | |||
} | |||
} | |||
} | |||
static void unselect_rows(void) { | |||
// no need to unselect on tca9555, because the select step sets all | |||
// the other row bits high, and it's not changing to a different | |||
// direction | |||
// unselect rows on microcontroller | |||
pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_L; | |||
for (int pin_index = 0; pin_index < MATRIX_ROWS_PER_SIDE; pin_index++) { | |||
pin_t pin = matrix_row_pins_mcu[pin_index]; | |||
setPinInput(pin); | |||
writePinLow(pin); | |||
} | |||
} | |||
static void select_row(uint8_t row) { | |||
uint8_t port0 = 0xff; | |||
uint8_t port1 = 0xff; | |||
if (row < MATRIX_ROWS_PER_SIDE) { | |||
// select on atmega32u4 | |||
pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_L; | |||
pin_t pin = matrix_row_pins_mcu[row]; | |||
setPinOutput(pin); | |||
writePinLow(pin); | |||
} else { | |||
// select on tca9555 | |||
if (tca9555_status) { // if there was an error | |||
// do nothing | |||
} else { | |||
switch(row) { | |||
case 4: port1 &= ~(1 << 0); break; | |||
case 5: port1 &= ~(1 << 1); break; | |||
case 6: port1 &= ~(1 << 2); break; | |||
case 7: port0 &= ~(1 << 5); break; | |||
default: break; | |||
} | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(OREGP0, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(port0, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(port1, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
// Select the desired row by writing a byte for the entire GPIOB bus where only the bit representing the row we want to select is a zero (write instruction) and every other bit is a one. | |||
// Note that the row - MATRIX_ROWS_PER_SIDE reflects the fact that being on the right hand, the columns are numbered from MATRIX_ROWS_PER_SIDE to MATRIX_ROWS, but the pins we want to write to are indexed from zero up on the GPIOB bus. | |||
out: | |||
i2c_stop(); | |||
} | |||
} | |||
} |
@ -0,0 +1,32 @@ | |||
# 3W6 | |||
![3W6](https://raw.githubusercontent.com/weteor/3W6/main/images/3w6_1s.jpg) | |||
![3W6](https://raw.githubusercontent.com/weteor/3W6/main/images/3w6_3s.jpg) | |||
The 3w6 is a low profile, split ortholinear keyboard with 36 keys. | |||
* Rev1: | |||
- onboard microcontroller (ATMega32U4) | |||
- USB-C connector Board <-> PC | |||
- USB-C connectors between both split halfs | |||
- choc spacing (18x17mm) | |||
- aggressive pinky stagger | |||
- support for Choc V1 switches | |||
--- | |||
* Keyboard Maintainer: [weteor](https://github.com/weteor) | |||
* Hardware Supported: | |||
* 3w6 rev1 | |||
* Hardware Availability (this is an older version, current revision is rev2): | |||
* make one yourself: [Design and Productionfiles](https://github.com/weteor/3w6) | |||
--- | |||
To reach the bootloader, connect the board to the PC and push the reset button on left half. | |||
Make examples for this keyboard (after setting up your build environment): | |||
make 3w6/rev1:default | |||
--- | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). |
@ -0,0 +1,17 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "rev1.h" |
@ -0,0 +1,44 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "quantum.h" | |||
/* This is a shortcut to help you visually see your layout. | |||
* | |||
* The first section contains all of the arguments representing the physical | |||
* layout of the board and position of the keys. | |||
* | |||
* The second converts the arguments into a two-dimensional array which | |||
* represents the switch matrix. | |||
*/ | |||
#define LAYOUT( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09,\ | |||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19,\ | |||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29,\ | |||
k32, k33, k34, k35, k36, k37\ | |||
) { \ | |||
{ k00, k01, k02, k03, k04 }, \ | |||
{ k10, k11, k12, k13, k14 }, \ | |||
{ k20, k21, k22, k23, k24 }, \ | |||
{ KC_NO, KC_NO, k32, k33, k34 }, \ | |||
\ | |||
{ k05, k06, k07, k08, k09 }, \ | |||
{ k15, k16, k17, k18, k19 }, \ | |||
{ k25, k26, k27, k28, k29 }, \ | |||
{ k35, k36, k37, KC_NO, KC_NO }, \ | |||
} |
@ -0,0 +1,29 @@ | |||
# MCU name | |||
MCU = atmega32u4 | |||
# Bootloader selection | |||
BOOTLOADER = atmel-dfu | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = no # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | |||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | |||
NKRO_ENABLE = no # USB Nkey Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
BLUETOOTH_ENABLE = no # Enable Bluetooth | |||
AUDIO_ENABLE = no # Audio output | |||
UNICODE_ENABLE = yes | |||
CUSTOM_MATRIX = lite | |||
NO_USB_STARTUP_CHECK = yes | |||
LTO_ENABLE = no | |||
SRC += matrix.c | |||
QUANTUM_LIB_SRC += i2c_master.c |
@ -0,0 +1,63 @@ | |||
/* | |||
Copyright 2021 weteor | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
/* USB Device descriptor parameter */ | |||
#define VENDOR_ID 0xFEED | |||
#define PRODUCT_ID 0x4658 | |||
#define DEVICE_VER 0x0002 | |||
#define MANUFACTURER weteor | |||
#define PRODUCT 3w6 | |||
/* key matrix size */ | |||
#define MATRIX_ROWS 8 | |||
#define MATRIX_COLS 10 | |||
#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2) | |||
#define MATRIX_COLS_PER_SIDE (MATRIX_COLS / 2) | |||
/* | |||
* Keyboard Matrix Assignments | |||
* | |||
* Change this to how you wired your keyboard | |||
* COLS: AVR pins used for columns, left to right | |||
* ROWS: AVR pins used for rows, top to bottom | |||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) | |||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) | |||
* | |||
*/ | |||
#define MATRIX_ROW_PINS_L { B0, B1, B2, B4} | |||
#define MATRIX_COL_PINS_L { B3, E6, F7, B6, B5 } | |||
#define UNUSED_PINS_L { B7, C6, C7, D2, D3, D4, D5, D6, D7, F0, F1, F4, F5, F6 } | |||
#define MATRIX_ROW_PINS_R { P10, P11, P12, P05 } | |||
#define MATRIX_COL_PINS_R { P06, P13, P14, P01, P00 } | |||
#define UNUSED_PINS_R { P02, P03, P04, P07, P15, P16, P17 } | |||
/* COL2ROW, ROW2COL */ | |||
#define DIODE_DIRECTION COL2ROW | |||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ | |||
#define DEBOUNCE 5 | |||
/* disable these deprecated features by default */ | |||
#define NO_ACTION_MACRO | |||
#define NO_ACTION_FUNCTION | |||
@ -0,0 +1,21 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#define PIMORONI_TRACKBALL_INVERT_Y | |||
#define PIMORONI_TRACKBALL_ROTATE | |||
@ -0,0 +1,70 @@ | |||
/* | |||
Copyright 2021 weteor | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
enum layers | |||
{ | |||
_ALPHA_QWERTY = 0, | |||
_ALPHA_COLEMAK, | |||
_SYM, | |||
_NAV, | |||
_NUM, | |||
_CFG, | |||
}; | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_ALPHA_QWERTY] = LAYOUT( | |||
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, | |||
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), | |||
LCTL_T(KC_ESC), LT(_NUM,KC_SPC), LT(_NAV, KC_TAB), LT(_SYM, KC_BSPC), KC_ENT, LALT_T(KC_DEL) | |||
), | |||
[_ALPHA_COLEMAK] = LAYOUT( | |||
KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, | |||
KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, | |||
LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SCLN), | |||
LCTL_T(KC_ENT), LT(_NUM,KC_SPC), LT(_NAV, KC_TAB), LT(_SYM, KC_BSPC), KC_ENT, LALT_T(KC_DEL) | |||
), | |||
[_SYM] = LAYOUT( | |||
KC_GRV , KC_CIRC, KC_AT, KC_DLR, KC_TILD, KC_AMPR, KC_EXLM, KC_PIPE, KC_UNDS, KC_HASH, | |||
KC_SLSH, KC_LBRC, KC_LCBR, KC_LPRN, KC_EQL, KC_ASTR, KC_RPRN, KC_RCBR, KC_RBRC, KC_BSLS, | |||
_______, KC_QUES, KC_PLUS, KC_PERC, XXXXXXX, XXXXXXX, XXXXXXX, KC_MINS, XXXXXXX, _______, | |||
XXXXXXX, MO(_CFG), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX | |||
), | |||
[_NAV] = LAYOUT( | |||
XXXXXXX, KC_VOLD, KC_MUTE, KC_VOLU, XXXXXXX, XXXXXXX, KC_PGDN, KC_UP, KC_PGUP, KC_DEL, | |||
KC_MPRV, KC_MPLY, KC_MSTP, KC_MNXT, XXXXXXX, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MO(_CFG), XXXXXXX | |||
), | |||
[_NUM] = LAYOUT( | |||
XXXXXXX, KC_F9, KC_F10, KC_F11, KC_F12, KC_PPLS, KC_P7, KC_P8, KC_P9, KC_PSLS, | |||
XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8, KC_P0, KC_P4, KC_P5, KC_P6, KC_PDOT, | |||
XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, KC_PMNS, KC_P1, KC_P2, KC_P3, KC_PAST, | |||
XXXXXXX, XXXXXXX, XXXXXXX, KC_PEQL, KC_PENT, XXXXXXX | |||
), | |||
[_CFG] = LAYOUT( | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,DF(_ALPHA_QWERTY), DF(_ALPHA_COLEMAK), | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX | |||
), | |||
}; |
@ -0,0 +1,177 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "pimoroni_trackball.h" | |||
#include "i2c_master.h" | |||
static uint8_t scrolling = 0; | |||
static int16_t x_offset = 0; | |||
static int16_t y_offset = 0; | |||
static int16_t h_offset = 0; | |||
static int16_t v_offset = 0; | |||
static float precisionSpeed = 1; | |||
static uint16_t i2c_timeout_timer; | |||
#ifndef I2C_TIMEOUT | |||
# define I2C_TIMEOUT 100 | |||
#endif | |||
#ifndef I2C_WAITCHECK | |||
# define I2C_WAITCHECK 1000 | |||
#endif | |||
#ifndef MOUSE_DEBOUNCE | |||
# define MOUSE_DEBOUNCE 5 | |||
#endif | |||
void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { | |||
uint8_t data[] = {0x00, red, green, blue, white}; | |||
i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), I2C_TIMEOUT); | |||
} | |||
int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) { | |||
int16_t offset = (int16_t)positive - (int16_t)negative; | |||
int16_t magnitude = (int16_t)(scale * offset * offset * precisionSpeed); | |||
return offset < 0 ? -magnitude : magnitude; | |||
} | |||
void update_member(int8_t* member, int16_t* offset) { | |||
if (*offset > 127) { | |||
*member = 127; | |||
*offset -= 127; | |||
} else if (*offset < -127) { | |||
*member = -127; | |||
*offset += 127; | |||
} else { | |||
*member = *offset; | |||
*offset = 0; | |||
} | |||
} | |||
__attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* mouse) { | |||
if (pressed) { | |||
mouse->buttons |= MOUSE_BTN1; | |||
} else { | |||
mouse->buttons &= ~MOUSE_BTN1; | |||
} | |||
} | |||
bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | |||
if (true) { | |||
xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); | |||
} | |||
if (!process_record_user(keycode, record)) { return false; } | |||
/* If Mousekeys is disabled, then use handle the mouse button | |||
* keycodes. This makes things simpler, and allows usage of | |||
* the keycodes in a consistent manner. But only do this if | |||
* Mousekeys is not enable, so it's not handled twice. | |||
*/ | |||
#ifndef MOUSEKEY_ENABLE | |||
if (IS_MOUSEKEY_BUTTON(keycode)) { | |||
report_mouse_t currentReport = pointing_device_get_report(); | |||
if (record->event.pressed) { | |||
currentReport.buttons |= 1 << (keycode - KC_MS_BTN1); | |||
} else { | |||
currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1)); | |||
} | |||
pointing_device_set_report(currentReport); | |||
pointing_device_send(); | |||
} | |||
#endif | |||
return true; | |||
} | |||
void trackball_register_button(bool pressed, enum mouse_buttons button) { | |||
report_mouse_t currentReport = pointing_device_get_report(); | |||
if (pressed) { | |||
currentReport.buttons |= button; | |||
} else { | |||
currentReport.buttons &= ~button; | |||
} | |||
pointing_device_set_report(currentReport); | |||
} | |||
float trackball_get_precision(void) { return precisionSpeed; } | |||
void trackball_set_precision(float precision) { precisionSpeed = precision; } | |||
bool trackball_is_scrolling(void) { return scrolling; } | |||
void trackball_set_scrolling(bool scroll) { scrolling = scroll; } | |||
__attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x80, 0x00, 0x00, 0x00); } | |||
void pointing_device_task(void) { | |||
static bool debounce; | |||
static uint16_t debounce_timer; | |||
uint8_t state[5] = {}; | |||
if (timer_elapsed(i2c_timeout_timer) > I2C_WAITCHECK) { | |||
if (i2c_readReg(TRACKBALL_WRITE, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { | |||
if (!state[4] && !debounce) { | |||
if (scrolling) { | |||
#ifdef PIMORONI_TRACKBALL_INVERT_X | |||
h_offset += mouse_offset(state[2], state[3], 1); | |||
#else | |||
h_offset -= mouse_offset(state[2], state[3], 1); | |||
#endif | |||
#ifdef PIMORONI_TRACKBALL_INVERT_Y | |||
v_offset += mouse_offset(state[1], state[0], 1); | |||
#else | |||
v_offset -= mouse_offset(state[1], state[0], 1); | |||
#endif | |||
} else { | |||
#ifdef PIMORONI_TRACKBALL_INVERT_X | |||
x_offset -= mouse_offset(state[2], state[3], 5); | |||
#else | |||
x_offset += mouse_offset(state[2], state[3], 5); | |||
#endif | |||
#ifdef PIMORONI_TRACKBALL_INVERT_Y | |||
y_offset -= mouse_offset(state[1], state[0], 5); | |||
#else | |||
y_offset += mouse_offset(state[1], state[0], 5); | |||
#endif | |||
} | |||
} else { | |||
if (state[4]) { | |||
debounce = true; | |||
debounce_timer = timer_read(); | |||
} | |||
} | |||
} else { | |||
i2c_timeout_timer = timer_read(); | |||
} | |||
} | |||
if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false; | |||
report_mouse_t mouse = pointing_device_get_report(); | |||
// trackball_check_click(state[4] & (1 << 7), &mouse); | |||
#ifndef PIMORONI_TRACKBALL_ROTATE | |||
update_member(&mouse.x, &x_offset); | |||
update_member(&mouse.y, &y_offset); | |||
update_member(&mouse.h, &h_offset); | |||
update_member(&mouse.v, &v_offset); | |||
#else | |||
update_member(&mouse.x, &y_offset); | |||
update_member(&mouse.y, &x_offset); | |||
update_member(&mouse.h, &v_offset); | |||
update_member(&mouse.v, &h_offset); | |||
#endif | |||
pointing_device_set_report(mouse); | |||
pointing_device_send(); | |||
} |
@ -0,0 +1,35 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "quantum.h" | |||
#include "pointing_device.h" | |||
#ifndef TRACKBALL_ADDRESS | |||
# define TRACKBALL_ADDRESS 0x0A | |||
#endif | |||
#define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE) | |||
#define TRACKBALL_READ ((TRACKBALL_ADDRESS << 1) | I2C_READ) | |||
void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white); | |||
void trackball_check_click(bool pressed, report_mouse_t *mouse); | |||
void trackball_register_button(bool pressed, enum mouse_buttons button); | |||
float trackball_get_precision(void); | |||
void trackball_set_precision(float precision); | |||
bool trackball_is_scrolling(void); | |||
void trackball_set_scrolling(bool scroll); |
@ -0,0 +1,3 @@ | |||
POINTING_DEVICE_ENABLE = yes | |||
SRC += pimoroni_trackball.c | |||
MOUSEKEY_ENABLE = no |
@ -0,0 +1,275 @@ | |||
/* | |||
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com> | |||
2020 Pierre Chevalier <pierrechevalier83@gmail.com> | |||
2021 weteor | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
/* | |||
* This code was heavily inspired by the ergodox_ez keymap, and modernized | |||
* to take advantage of the quantum.h microcontroller agnostics gpio control | |||
* abstractions and use the macros defined in config.h for the wiring as opposed | |||
* to repeating that information all over the place. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
#include "i2c_master.h" | |||
extern i2c_status_t tca9555_status; | |||
#define I2C_TIMEOUT 1000 | |||
// I2C address: | |||
// All address pins of the tca9555 are connected to the ground | |||
// | 0 | 1 | 0 | 0 | A2 | A1 | A0 | | |||
// | 0 | 1 | 0 | 0 | 0 | 0 | 0 | | |||
#define I2C_ADDR 0b0100000 | |||
#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) | |||
#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) | |||
// Register addresses | |||
#define IODIRA 0x06 // i/o direction register | |||
#define IODIRB 0x07 | |||
#define IREGP0 0x00 // GPIO pull-up resistor register | |||
#define IREGP1 0x01 | |||
#define OREGP0 0x02 // general purpose i/o port register (write modifies OLAT) | |||
#define OREGP1 0x03 | |||
bool i2c_initialized = 0; | |||
i2c_status_t tca9555_status = I2C_ADDR; | |||
uint8_t init_tca9555(void) { | |||
print("starting init"); | |||
tca9555_status = I2C_ADDR; | |||
// I2C subsystem | |||
if (i2c_initialized == 0) { | |||
i2c_init(); // on pins D(1,0) | |||
i2c_initialized = true; | |||
wait_ms(I2C_TIMEOUT); | |||
} | |||
// set pin direction | |||
// - unused : input : 1 | |||
// - input : input : 1 | |||
// - driving : output : 0 | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(IODIRA, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
// This means: read all pins of port 0 | |||
tca9555_status = i2c_write(0b11111111, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
// This means: we will write on pins 0 to 3 on port 1. read rest | |||
tca9555_status = i2c_write(0b11110000, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
out: | |||
i2c_stop(); | |||
return tca9555_status; | |||
} | |||
/* matrix state(1:on, 0:off) */ | |||
static matrix_row_t matrix[MATRIX_ROWS]; // debounced values | |||
static matrix_row_t read_cols(uint8_t row); | |||
static void init_cols(void); | |||
static void unselect_rows(void); | |||
static void select_row(uint8_t row); | |||
static uint8_t tca9555_reset_loop; | |||
void matrix_init_custom(void) { | |||
// initialize row and col | |||
tca9555_status = init_tca9555(); | |||
unselect_rows(); | |||
init_cols(); | |||
// initialize matrix state: all keys off | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = 0; | |||
} | |||
} | |||
void matrix_power_up(void) { | |||
tca9555_status = init_tca9555(); | |||
unselect_rows(); | |||
init_cols(); | |||
// initialize matrix state: all keys off | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = 0; | |||
} | |||
} | |||
// Reads and stores a row, returning | |||
// whether a change occurred. | |||
static inline bool store_matrix_row(matrix_row_t current_matrix[], uint8_t index) { | |||
matrix_row_t temp = read_cols(index); | |||
if (current_matrix[index] != temp) { | |||
current_matrix[index] = temp; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool matrix_scan_custom(matrix_row_t current_matrix[]) { | |||
if (tca9555_status) { // if there was an error | |||
if (++tca9555_reset_loop == 0) { | |||
// since tca9555_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans | |||
// this will be approx bit more frequent than once per second | |||
dprint("trying to reset tca9555\n"); | |||
tca9555_status = init_tca9555(); | |||
if (tca9555_status) { | |||
dprint("right side not responding\n"); | |||
} else { | |||
dprint("right side attached\n"); | |||
} | |||
} | |||
} | |||
bool changed = false; | |||
for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { | |||
// select rows from left and right hands | |||
uint8_t left_index = i; | |||
uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; | |||
select_row(left_index); | |||
select_row(right_index); | |||
// we don't need a 30us delay anymore, because selecting a | |||
// left-hand row requires more than 30us for i2c. | |||
changed |= store_matrix_row(current_matrix, left_index); | |||
changed |= store_matrix_row(current_matrix, right_index); | |||
unselect_rows(); | |||
} | |||
return changed; | |||
} | |||
static void init_cols(void) { | |||
// init on tca9555 | |||
// not needed, already done as part of init_tca9555() | |||
// init on mcu | |||
pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_L; | |||
for (int pin_index = 0; pin_index < MATRIX_COLS_PER_SIDE; pin_index++) { | |||
pin_t pin = matrix_col_pins_mcu[pin_index]; | |||
setPinInput(pin); | |||
writePinHigh(pin); | |||
} | |||
} | |||
static matrix_row_t read_cols(uint8_t row) { | |||
if (row < MATRIX_ROWS_PER_SIDE) { | |||
pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_L; | |||
matrix_row_t current_row_value = 0; | |||
// For each col... | |||
for (uint8_t col_index = 0; col_index < MATRIX_COLS_PER_SIDE; col_index++) { | |||
// Select the col pin to read (active low) | |||
uint8_t pin_state = readPin(matrix_col_pins_mcu[col_index]); | |||
// Populate the matrix row with the state of the col pin | |||
current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); | |||
} | |||
return current_row_value; | |||
} else { | |||
if (tca9555_status) { // if there was an error | |||
return 0; | |||
} else { | |||
uint8_t data = 0; | |||
uint8_t port0 = 0; | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(IREGP0, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_read_nack(I2C_TIMEOUT); | |||
if (tca9555_status < 0) goto out; | |||
port0 = ~(uint8_t)tca9555_status; | |||
// We read all the pins on GPIOA. | |||
// The initial state was all ones and any depressed key at a given column for the currently selected row will have its bit flipped to zero. | |||
// The return value is a row as represented in the generic matrix code were the rightmost bits represent the lower columns and zeroes represent non-depressed keys while ones represent depressed keys. | |||
// the pins connected to eact columns are sequential, but in reverse order, and counting from zero down (col 5 -> GPIO04, col6 -> GPIO03 and so on). | |||
data |= ( port0 & 0x01 ) << 4; | |||
data |= ( port0 & 0x02 ) << 2; | |||
data |= ( port0 & 0x04 ); | |||
data |= ( port0 & 0x08 ) >> 2; | |||
data |= ( port0 & 0x10 ) >> 4; | |||
tca9555_status = I2C_STATUS_SUCCESS; | |||
out: | |||
i2c_stop(); | |||
return data; | |||
} | |||
} | |||
} | |||
static void unselect_rows(void) { | |||
// no need to unselect on tca9555, because the select step sets all | |||
// the other row bits high, and it's not changing to a different | |||
// direction | |||
// unselect rows on microcontroller | |||
pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_L; | |||
for (int pin_index = 0; pin_index < MATRIX_ROWS_PER_SIDE; pin_index++) { | |||
pin_t pin = matrix_row_pins_mcu[pin_index]; | |||
setPinInput(pin); | |||
writePinLow(pin); | |||
} | |||
} | |||
static void select_row(uint8_t row) { | |||
uint8_t port1 = 0xff; | |||
if (row < MATRIX_ROWS_PER_SIDE) { | |||
// select on atmega32u4 | |||
pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_L; | |||
pin_t pin = matrix_row_pins_mcu[row]; | |||
setPinOutput(pin); | |||
writePinLow(pin); | |||
} else { | |||
// select on tca9555 | |||
if (tca9555_status) { // if there was an error | |||
// do nothing | |||
} else { | |||
switch(row) { | |||
case 4: port1 &= ~(1 << 0); break; | |||
case 5: port1 &= ~(1 << 1); break; | |||
case 6: port1 &= ~(1 << 2); break; | |||
case 7: port1 &= ~(1 << 3); break; | |||
default: break; | |||
} | |||
// Select the desired row by writing a byte for the entire GPIOB bus where only the bit representing the row we want to select is a zero (write instruction) and every other bit is a one. | |||
// Note that the row - MATRIX_ROWS_PER_SIDE reflects the fact that being on the right hand, the columns are numbered from MATRIX_ROWS_PER_SIDE to MATRIX_ROWS, but the pins we want to write to are indexed from zero up on the GPIOB bus. | |||
tca9555_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(OREGP1, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
tca9555_status = i2c_write(port1, I2C_TIMEOUT); | |||
if (tca9555_status) goto out; | |||
out: | |||
i2c_stop(); | |||
} | |||
} | |||
} |
@ -0,0 +1,38 @@ | |||
# 3W6 | |||
![3W6_rev2](https://raw.githubusercontent.com/weteor/3W6/main/images/3w6_rev2_2s.jpg) | |||
![3W6_rev2](https://raw.githubusercontent.com/weteor/3W6/main/images/3w6_rev2_1s.jpg) | |||
The 3w6 is a low profile, split ortholinear keyboard with 36 keys. | |||
* Rev2: | |||
- onboard microcontroller (ATMega32U4) | |||
- USB-C connector Board <-> PC | |||
- USB-C connectors between both split halfs | |||
- choc spacing (18x17mm) | |||
- aggressive pinky stagger | |||
- support for Choc V1 switches | |||
- files for midplate (1.6 to 2mm) | |||
- support for [Pimoroni Trackball](https://shop.pimoroni.com/products/trackball-breakout) instead of outer thumb switch on right half, needs midplate | |||
- mounting holes for [Tenting Puck](https://splitkb.com/collections/keyboard-parts/products/tenting-puck), only usable without mid or switchplate | |||
--- | |||
* Keyboard Maintainer: [weteor](https://github.com/weteor) | |||
* Hardware Supported: | |||
* 3w6 rev2 (with Pimoroni support) | |||
* Hardware Availability: | |||
* make one yourself: [Design and Productionfiles](https://github.com/weteor/3w6) | |||
* maintainer is selling kits when available | |||
--- | |||
To reach the bootloader, connect the board to the PC and push the reset button on left half. | |||
Make examples for this keyboard (after setting up your build environment): | |||
make 3w6/rev2:default | |||
make 3w6/rev2:default_pimoroni | |||
--- | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). |
@ -0,0 +1,17 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "rev2.h" |
@ -0,0 +1,44 @@ | |||
/* Copyright 2021 weteor | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#pragma once | |||
#include "quantum.h" | |||
/* This is a shortcut to help you visually see your layout. | |||
* | |||
* The first section contains all of the arguments representing the physical | |||
* layout of the board and position of the keys. | |||
* | |||
* The second converts the arguments into a two-dimensional array which | |||
* represents the switch matrix. | |||
*/ | |||
#define LAYOUT( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09,\ | |||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19,\ | |||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29,\ | |||
k32, k33, k34, k35, k36, k37\ | |||
) { \ | |||
{ k00, k01, k02, k03, k04 }, \ | |||
{ k10, k11, k12, k13, k14 }, \ | |||
{ k20, k21, k22, k23, k24 }, \ | |||
{ KC_NO, KC_NO, k32, k33, k34 }, \ | |||
\ | |||
{ k05, k06, k07, k08, k09 }, \ | |||
{ k15, k16, k17, k18, k19 }, \ | |||
{ k25, k26, k27, k28, k29 }, \ | |||
{ k35, k36, k37, KC_NO, KC_NO }, \ | |||
} |
@ -0,0 +1,29 @@ | |||
# MCU name | |||
MCU = atmega32u4 | |||
# Bootloader selection | |||
BOOTLOADER = atmel-dfu | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = no # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | |||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | |||
NKRO_ENABLE = no # USB Nkey Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
BLUETOOTH_ENABLE = no # Enable Bluetooth | |||
AUDIO_ENABLE = no # Audio output | |||
UNICODE_ENABLE = yes | |||
CUSTOM_MATRIX = lite | |||
NO_USB_STARTUP_CHECK = yes | |||
LTO_ENABLE = no | |||
SRC += matrix.c | |||
QUANTUM_LIB_SRC += i2c_master.c |
@ -0,0 +1,70 @@ | |||
/* Copyright 2021 alittlepeace | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT_default( | |||
KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, KC_INS, KC_HOME, KC_PGUP, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_DEL, KC_END, KC_PGDN, | |||
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(1), KC_UP, | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT), | |||
[1] = LAYOUT_default( | |||
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______), | |||
[2] = LAYOUT_default( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______), | |||
[3] = LAYOUT_default( | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______) | |||
}; | |||
bool encoder_update_user(uint8_t index, bool clockwise) { | |||
if (index == 0) { /* First encoder */ | |||
switch(get_highest_layer(layer_state)){ | |||
case 1: | |||
if (clockwise){ | |||
tap_code(KC_VOLU); | |||
} else{ | |||
tap_code(KC_VOLD); | |||
} | |||
break; | |||
default: | |||
if (clockwise) { | |||
tap_code(KC_WH_D); | |||
} else { | |||
tap_code(KC_WH_U); | |||
} | |||
break; | |||
} | |||
} | |||
return true; | |||
} | |||
@ -0,0 +1,2 @@ | |||
VIA_ENABLE = yes | |||
MOUSEKEY_ENABLE = yes |
@ -1,28 +1,17 @@ | |||
#include "acr60.h" | |||
#include "led.h" | |||
void matrix_init_kb(void) { | |||
// Keyboard start-up code goes here | |||
// Runs once when the firmware starts up | |||
matrix_init_user(); | |||
led_init_ports(); | |||
}; | |||
void matrix_scan_kb(void) { | |||
// Looping keyboard code goes here | |||
// This runs every cycle (a lot) | |||
matrix_scan_user(); | |||
}; | |||
/* Copyright 2017 Ryan Mitchell (@newtmitch) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
void led_init_ports(void) { | |||
// Set caps lock LED pin as output | |||
DDRB |= (1 << 2); | |||
// Default to off | |||
PORTB |= (1 << 2); | |||
} | |||
void led_set_kb(uint8_t usb_led) { | |||
// Code for caps lock LED as reported by the OS | |||
// Set this per keymap, instead of globally | |||
led_set_user(usb_led); | |||
} | |||
#include "acr60.h" |
@ -1,33 +1,448 @@ | |||
{ | |||
"keyboard_name": "ACR60", | |||
"url": "", | |||
"maintainer": "qmk", | |||
"width": 15, | |||
"height": 5, | |||
"layouts": { | |||
"LAYOUT": { | |||
"key_count": 67, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K013", "x":13, "y":0}, {"label":"K014", "x":14, "y":0}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3, "w":1.25}, {"label":"K301", "x":1.25, "y":3}, {"label":"K302", "x":2.25, "y":3}, {"label":"K303", "x":3.25, "y":3}, {"label":"K304", "x":4.25, "y":3}, {"label":"K305", "x":5.25, "y":3}, {"label":"K306", "x":6.25, "y":3}, {"label":"K307", "x":7.25, "y":3}, {"label":"K308", "x":8.25, "y":3}, {"label":"K309", "x":9.25, "y":3}, {"label":"K310", "x":10.25, "y":3}, {"label":"K311", "x":11.25, "y":3}, {"label":"K313", "x":12.25, "y":3, "w":1.75}, {"label":"K314", "x":14, "y":3}, {"label":"K400", "x":0, "y":4, "w":1.25}, {"label":"K401", "x":1.25, "y":4, "w":1.25}, {"label":"K403", "x":2.5, "y":4, "w":1.25}, {"label":"K404", "x":3.75, "y":4, "w":2.25}, {"label":"K406", "x":6, "y":4, "w":1.25}, {"label":"K408", "x":7.25, "y":4, "w":2.75}, {"label":"K410", "x":10, "y":4}, {"label":"K411", "x":11, "y":4}, {"label":"K412", "x":12, "y":4}, {"label":"K413", "x":13, "y":4}, {"label":"K414", "x":14, "y":4}] | |||
"keyboard_name": "ACR60", | |||
"url": "", | |||
"maintainer": "qmk", | |||
"width": 15, | |||
"height": 5, | |||
"layout_aliases": { | |||
"LAYOUT_2_shifts": "LAYOUT_all" | |||
}, | |||
"LAYOUT_hhkb": { | |||
"key_count": 61, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K013", "x":13, "y":0}, {"label":"K014", "x":14, "y":0}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3, "w":1.25}, {"label":"K301", "x":1.25, "y":3}, {"label":"K302", "x":2.25, "y":3}, {"label":"K303", "x":3.25, "y":3}, {"label":"K304", "x":4.25, "y":3}, {"label":"K305", "x":5.25, "y":3}, {"label":"K306", "x":6.25, "y":3}, {"label":"K307", "x":7.25, "y":3}, {"label":"K308", "x":8.25, "y":3}, {"label":"K309", "x":9.25, "y":3}, {"label":"K310", "x":10.25, "y":3}, {"label":"K311", "x":11.25, "y":3}, {"label":"K313", "x":12.25, "y":3, "w":1.75}, {"label":"K314", "x":14, "y":3}, {"label":"K401", "x":1.5, "y":4}, {"label":"K403", "x":2.5, "y":4, "w":1.5}, {"label":"K406", "x":4, "y":4, "w":7}, {"label":"K411", "x":11, "y":4, "w":1.5}, {"label":"K413", "x":12.5, "y":4}] | |||
}, | |||
"LAYOUT_true_hhkb": { | |||
"key_count": 61, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K013", "x":13, "y":0}, {"label":"K014", "x":14, "y":0}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3, "w":1.25}, {"label":"K301", "x":1.25, "y":3}, {"label":"K302", "x":2.25, "y":3}, {"label":"K303", "x":3.25, "y":3}, {"label":"K304", "x":4.25, "y":3}, {"label":"K305", "x":5.25, "y":3}, {"label":"K306", "x":6.25, "y":3}, {"label":"K307", "x":7.25, "y":3}, {"label":"K308", "x":8.25, "y":3}, {"label":"K309", "x":9.25, "y":3}, {"label":"K310", "x":10.25, "y":3}, {"label":"K311", "x":11.25, "y":3}, {"label":"K313", "x":12.25, "y":3, "w":1.75}, {"label":"K314", "x":14, "y":3}, {"label":"K401", "x":1.5, "y":4}, {"label":"K403", "x":2.5, "y":4, "w":1.5}, {"label":"K406", "x":4, "y":4, "w":6}, {"label":"K410", "x":10, "y":4, "w":1.5}, {"label":"K411", "x":11.5, "y":4}] | |||
}, | |||
"LAYOUT_2_shifts": { | |||
"key_count": 68, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K013", "x":13, "y":0}, {"label":"K014", "x":14, "y":0}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3}, {"label":"K301", "x":1, "y":3}, {"label":"K302", "x":2, "y":3}, {"label":"K303", "x":3, "y":3}, {"label":"K304", "x":4, "y":3}, {"label":"K305", "x":5, "y":3}, {"label":"K306", "x":6, "y":3}, {"label":"K307", "x":7, "y":3}, {"label":"K308", "x":8, "y":3}, {"label":"K309", "x":9, "y":3}, {"label":"K310", "x":10, "y":3}, {"label":"K311", "x":11, "y":3}, {"label":"K312", "x":12, "y":3}, {"label":"K313", "x":13, "y":3}, {"label":"K314", "x":14, "y":3}, {"label":"K400", "x":0, "y":4, "w":1.25}, {"label":"K401", "x":1.25, "y":4, "w":1.25}, {"label":"K403", "x":2.5, "y":4, "w":1.25}, {"label":"K404", "x":3.75, "y":4, "w":2.25}, {"label":"K406", "x":6, "y":4, "w":1.25}, {"label":"K408", "x":7.25, "y":4, "w":2.75}, {"label":"K410", "x":10, "y":4}, {"label":"K411", "x":11, "y":4}, {"label":"K412", "x":12, "y":4}, {"label":"K413", "x":13, "y":4}, {"label":"K414", "x":14, "y":4}] | |||
}, | |||
"LAYOUT_directional": { | |||
"key_count": 67, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K013", "x":13, "y":0}, {"label":"K014", "x":14, "y":0}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3, "w":1.25}, {"label":"K301", "x":1.25, "y":3}, {"label":"K302", "x":2.25, "y":3}, {"label":"K303", "x":3.25, "y":3}, {"label":"K304", "x":4.25, "y":3}, {"label":"K305", "x":5.25, "y":3}, {"label":"K306", "x":6.25, "y":3}, {"label":"K307", "x":7.25, "y":3}, {"label":"K308", "x":8.25, "y":3}, {"label":"K309", "x":9.25, "y":3}, {"label":"K310", "x":10.25, "y":3}, {"label":"K312", "x":11.25, "y":3, "w":1.75}, {"label":"K313", "x":13, "y":3}, {"label":"K314", "x":14, "y":3}, {"label":"K400", "x":0, "y":4, "w":1.25}, {"label":"K401", "x":1.25, "y":4, "w":1.25}, {"label":"K403", "x":2.5, "y":4, "w":1.25}, {"label":"K404", "x":3.75, "y":4, "w":2.25}, {"label":"K406", "x":6, "y":4, "w":1.25}, {"label":"K408", "x":7.25, "y":4, "w":2.75}, {"label":"K410", "x":10, "y":4}, {"label":"K411", "x":11, "y":4}, {"label":"K412", "x":12, "y":4}, {"label":"K413", "x":13, "y":4}, {"label":"K414", "x":14, "y":4}] | |||
}, | |||
"LAYOUT_mitchsplit": { | |||
"key_count": 64, | |||
"layout": [{"label":"K000", "x":0, "y":0}, {"label":"K001", "x":1, "y":0}, {"label":"K002", "x":2, "y":0}, {"label":"K003", "x":3, "y":0}, {"label":"K004", "x":4, "y":0}, {"label":"K005", "x":5, "y":0}, {"label":"K006", "x":6, "y":0}, {"label":"K007", "x":7, "y":0}, {"label":"K008", "x":8, "y":0}, {"label":"K009", "x":9, "y":0}, {"label":"K010", "x":10, "y":0}, {"label":"K011", "x":11, "y":0}, {"label":"K012", "x":12, "y":0}, {"label":"K014", "x":13, "y":0, "w":2}, {"label":"K100", "x":0, "y":1, "w":1.5}, {"label":"K102", "x":1.5, "y":1}, {"label":"K103", "x":2.5, "y":1}, {"label":"K104", "x":3.5, "y":1}, {"label":"K105", "x":4.5, "y":1}, {"label":"K106", "x":5.5, "y":1}, {"label":"K107", "x":6.5, "y":1}, {"label":"K108", "x":7.5, "y":1}, {"label":"K109", "x":8.5, "y":1}, {"label":"K110", "x":9.5, "y":1}, {"label":"K111", "x":10.5, "y":1}, {"label":"K112", "x":11.5, "y":1}, {"label":"K113", "x":12.5, "y":1}, {"label":"K114", "x":13.5, "y":1, "w":1.5}, {"label":"K200", "x":0, "y":2, "w":1.75}, {"label":"K202", "x":1.75, "y":2}, {"label":"K203", "x":2.75, "y":2}, {"label":"K204", "x":3.75, "y":2}, {"label":"K205", "x":4.75, "y":2}, {"label":"K206", "x":5.75, "y":2}, {"label":"K207", "x":6.75, "y":2}, {"label":"K208", "x":7.75, "y":2}, {"label":"K209", "x":8.75, "y":2}, {"label":"K210", "x":9.75, "y":2}, {"label":"K211", "x":10.75, "y":2}, {"label":"K212", "x":11.75, "y":2}, {"label":"K213", "x":12.75, "y":2, "w":2.25}, {"label":"K300", "x":0, "y":3, "w":2.25}, {"label":"K302", "x":2.25, "y":3}, {"label":"K303", "x":3.25, "y":3}, {"label":"K304", "x":4.25, "y":3}, {"label":"K305", "x":5.25, "y":3}, {"label":"K306", "x":6.25, "y":3}, {"label":"K307", "x":7.25, "y":3}, {"label":"K308", "x":8.25, "y":3}, {"label":"K309", "x":9.25, "y":3}, {"label":"K310", "x":10.25, "y":3}, {"label":"K311", "x":11.25, "y":3}, {"label":"K313", "x":12.25, "y":3, "w":1.75}, {"label":"K314", "x":14, "y":3}, {"label":"K400", "x":0, "y":4, "w":1.25}, {"label":"K401", "x":1.25, "y":4, "w":1.25}, {"label":"K403", "x":2.5, "y":4, "w":1.25}, {"label":"K404", "x":3.75, "y":4, "w":2.75}, {"label":"K406", "x":6.5, "y":4, "w":1.25}, {"label":"K408", "x":7.75, "y":4, "w":2.25}, {"label":"K410", "x":10, "y":4, "w":1.25}, {"label":"K411", "x":11.25, "y":4, "w":1.25}, {"label":"K413", "x":12.5, "y":4, "w":1.25}, {"label":"K414", "x":13.75, "y":4, "w":1.25}] | |||
"layouts": { | |||
"LAYOUT_all": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0D", "x":13, "y":0}, | |||
{"label":"K0E", "x":14, "y":0}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3}, | |||
{"label":"K31", "x":1, "y":3}, | |||
{"label":"K32", "x":2, "y":3}, | |||
{"label":"K33", "x":3, "y":3}, | |||
{"label":"K34", "x":4, "y":3}, | |||
{"label":"K35", "x":5, "y":3}, | |||
{"label":"K36", "x":6, "y":3}, | |||
{"label":"K37", "x":7, "y":3}, | |||
{"label":"K38", "x":8, "y":3}, | |||
{"label":"K39", "x":9, "y":3}, | |||
{"label":"K3A", "x":10, "y":3}, | |||
{"label":"K3B", "x":11, "y":3}, | |||
{"label":"K3C", "x":12, "y":3}, | |||
{"label":"K3D", "x":13, "y":3}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K40", "x":0, "y":4, "w":1.25}, | |||
{"label":"K41", "x":1.25, "y":4, "w":1.25}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.25}, | |||
{"label":"K44", "x":3.75, "y":4, "w":2.25}, | |||
{"label":"K46", "x":6, "y":4, "w":1.25}, | |||
{"label":"K48", "x":7.25, "y":4, "w":2.75}, | |||
{"label":"K4A", "x":10, "y":4}, | |||
{"label":"K4B", "x":11, "y":4}, | |||
{"label":"K4C", "x":12, "y":4}, | |||
{"label":"K4D", "x":13, "y":4}, | |||
{"label":"K4E", "x":14, "y":4} | |||
] | |||
}, | |||
"LAYOUT": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0D", "x":13, "y":0}, | |||
{"label":"K0E", "x":14, "y":0}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3, "w":1.25}, | |||
{"label":"K31", "x":1.25, "y":3}, | |||
{"label":"K32", "x":2.25, "y":3}, | |||
{"label":"K33", "x":3.25, "y":3}, | |||
{"label":"K34", "x":4.25, "y":3}, | |||
{"label":"K35", "x":5.25, "y":3}, | |||
{"label":"K36", "x":6.25, "y":3}, | |||
{"label":"K37", "x":7.25, "y":3}, | |||
{"label":"K38", "x":8.25, "y":3}, | |||
{"label":"K39", "x":9.25, "y":3}, | |||
{"label":"K3A", "x":10.25, "y":3}, | |||
{"label":"K3B", "x":11.25, "y":3}, | |||
{"label":"K3D", "x":12.25, "y":3, "w":1.75}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K40", "x":0, "y":4, "w":1.25}, | |||
{"label":"K41", "x":1.25, "y":4, "w":1.25}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.25}, | |||
{"label":"K44", "x":3.75, "y":4, "w":2.25}, | |||
{"label":"K46", "x":6, "y":4, "w":1.25}, | |||
{"label":"K48", "x":7.25, "y":4, "w":2.75}, | |||
{"label":"K4A", "x":10, "y":4}, | |||
{"label":"K4B", "x":11, "y":4}, | |||
{"label":"K4C", "x":12, "y":4}, | |||
{"label":"K4D", "x":13, "y":4}, | |||
{"label":"K4E", "x":14, "y":4} | |||
] | |||
}, | |||
"LAYOUT_hhkb": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0D", "x":13, "y":0}, | |||
{"label":"K0E", "x":14, "y":0}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3, "w":1.25}, | |||
{"label":"K31", "x":1.25, "y":3}, | |||
{"label":"K32", "x":2.25, "y":3}, | |||
{"label":"K33", "x":3.25, "y":3}, | |||
{"label":"K34", "x":4.25, "y":3}, | |||
{"label":"K35", "x":5.25, "y":3}, | |||
{"label":"K36", "x":6.25, "y":3}, | |||
{"label":"K37", "x":7.25, "y":3}, | |||
{"label":"K38", "x":8.25, "y":3}, | |||
{"label":"K39", "x":9.25, "y":3}, | |||
{"label":"K3A", "x":10.25, "y":3}, | |||
{"label":"K3B", "x":11.25, "y":3}, | |||
{"label":"K3D", "x":12.25, "y":3, "w":1.75}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K41", "x":1.5, "y":4}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.5}, | |||
{"label":"K46", "x":4, "y":4, "w":7}, | |||
{"label":"K4B", "x":11, "y":4, "w":1.5}, | |||
{"label":"K4D", "x":12.5, "y":4} | |||
] | |||
}, | |||
"LAYOUT_true_hhkb": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0D", "x":13, "y":0}, | |||
{"label":"K0E", "x":14, "y":0}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3, "w":1.25}, | |||
{"label":"K31", "x":1.25, "y":3}, | |||
{"label":"K32", "x":2.25, "y":3}, | |||
{"label":"K33", "x":3.25, "y":3}, | |||
{"label":"K34", "x":4.25, "y":3}, | |||
{"label":"K35", "x":5.25, "y":3}, | |||
{"label":"K36", "x":6.25, "y":3}, | |||
{"label":"K37", "x":7.25, "y":3}, | |||
{"label":"K38", "x":8.25, "y":3}, | |||
{"label":"K39", "x":9.25, "y":3}, | |||
{"label":"K3A", "x":10.25, "y":3}, | |||
{"label":"K3B", "x":11.25, "y":3}, | |||
{"label":"K3D", "x":12.25, "y":3, "w":1.75}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K41", "x":1.5, "y":4}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.5}, | |||
{"label":"K46", "x":4, "y":4, "w":6}, | |||
{"label":"K4A", "x":10, "y":4, "w":1.5}, | |||
{"label":"K4B", "x":11.5, "y":4} | |||
] | |||
}, | |||
"LAYOUT_directional": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0D", "x":13, "y":0}, | |||
{"label":"K0E", "x":14, "y":0}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3, "w":1.25}, | |||
{"label":"K31", "x":1.25, "y":3}, | |||
{"label":"K32", "x":2.25, "y":3}, | |||
{"label":"K33", "x":3.25, "y":3}, | |||
{"label":"K34", "x":4.25, "y":3}, | |||
{"label":"K35", "x":5.25, "y":3}, | |||
{"label":"K36", "x":6.25, "y":3}, | |||
{"label":"K37", "x":7.25, "y":3}, | |||
{"label":"K38", "x":8.25, "y":3}, | |||
{"label":"K39", "x":9.25, "y":3}, | |||
{"label":"K3A", "x":10.25, "y":3}, | |||
{"label":"K3C", "x":11.25, "y":3, "w":1.75}, | |||
{"label":"K3D", "x":13, "y":3}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K40", "x":0, "y":4, "w":1.25}, | |||
{"label":"K41", "x":1.25, "y":4, "w":1.25}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.25}, | |||
{"label":"K44", "x":3.75, "y":4, "w":2.25}, | |||
{"label":"K46", "x":6, "y":4, "w":1.25}, | |||
{"label":"K48", "x":7.25, "y":4, "w":2.75}, | |||
{"label":"K4A", "x":10, "y":4}, | |||
{"label":"K4B", "x":11, "y":4}, | |||
{"label":"K4C", "x":12, "y":4}, | |||
{"label":"K4D", "x":13, "y":4}, | |||
{"label":"K4E", "x":14, "y":4} | |||
] | |||
}, | |||
"LAYOUT_mitchsplit": { | |||
"layout": [ | |||
{"label":"K00", "x":0, "y":0}, | |||
{"label":"K01", "x":1, "y":0}, | |||
{"label":"K02", "x":2, "y":0}, | |||
{"label":"K03", "x":3, "y":0}, | |||
{"label":"K04", "x":4, "y":0}, | |||
{"label":"K05", "x":5, "y":0}, | |||
{"label":"K06", "x":6, "y":0}, | |||
{"label":"K07", "x":7, "y":0}, | |||
{"label":"K08", "x":8, "y":0}, | |||
{"label":"K09", "x":9, "y":0}, | |||
{"label":"K0A", "x":10, "y":0}, | |||
{"label":"K0B", "x":11, "y":0}, | |||
{"label":"K0C", "x":12, "y":0}, | |||
{"label":"K0E", "x":13, "y":0, "w":2}, | |||
{"label":"K10", "x":0, "y":1, "w":1.5}, | |||
{"label":"K12", "x":1.5, "y":1}, | |||
{"label":"K13", "x":2.5, "y":1}, | |||
{"label":"K14", "x":3.5, "y":1}, | |||
{"label":"K15", "x":4.5, "y":1}, | |||
{"label":"K16", "x":5.5, "y":1}, | |||
{"label":"K17", "x":6.5, "y":1}, | |||
{"label":"K18", "x":7.5, "y":1}, | |||
{"label":"K19", "x":8.5, "y":1}, | |||
{"label":"K1A", "x":9.5, "y":1}, | |||
{"label":"K1B", "x":10.5, "y":1}, | |||
{"label":"K1C", "x":11.5, "y":1}, | |||
{"label":"K1D", "x":12.5, "y":1}, | |||
{"label":"K1E", "x":13.5, "y":1, "w":1.5}, | |||
{"label":"K20", "x":0, "y":2, "w":1.75}, | |||
{"label":"K22", "x":1.75, "y":2}, | |||
{"label":"K23", "x":2.75, "y":2}, | |||
{"label":"K24", "x":3.75, "y":2}, | |||
{"label":"K25", "x":4.75, "y":2}, | |||
{"label":"K26", "x":5.75, "y":2}, | |||
{"label":"K27", "x":6.75, "y":2}, | |||
{"label":"K28", "x":7.75, "y":2}, | |||
{"label":"K29", "x":8.75, "y":2}, | |||
{"label":"K2A", "x":9.75, "y":2}, | |||
{"label":"K2B", "x":10.75, "y":2}, | |||
{"label":"K2C", "x":11.75, "y":2}, | |||
{"label":"K2D", "x":12.75, "y":2, "w":2.25}, | |||
{"label":"K30", "x":0, "y":3, "w":2.25}, | |||
{"label":"K32", "x":2.25, "y":3}, | |||
{"label":"K33", "x":3.25, "y":3}, | |||
{"label":"K34", "x":4.25, "y":3}, | |||
{"label":"K35", "x":5.25, "y":3}, | |||
{"label":"K36", "x":6.25, "y":3}, | |||
{"label":"K37", "x":7.25, "y":3}, | |||
{"label":"K38", "x":8.25, "y":3}, | |||
{"label":"K39", "x":9.25, "y":3}, | |||
{"label":"K3A", "x":10.25, "y":3}, | |||
{"label":"K3B", "x":11.25, "y":3}, | |||
{"label":"K3D", "x":12.25, "y":3, "w":1.75}, | |||
{"label":"K3E", "x":14, "y":3}, | |||
{"label":"K40", "x":0, "y":4, "w":1.25}, | |||
{"label":"K41", "x":1.25, "y":4, "w":1.25}, | |||
{"label":"K43", "x":2.5, "y":4, "w":1.25}, | |||
{"label":"K44", "x":3.75, "y":4, "w":2.75}, | |||
{"label":"K46", "x":6.5, "y":4, "w":1.25}, | |||
{"label":"K48", "x":7.75, "y":4, "w":2.25}, | |||
{"label":"K4A", "x":10, "y":4, "w":1.25}, | |||
{"label":"K4B", "x":11.25, "y":4, "w":1.25}, | |||
{"label":"K4D", "x":12.5, "y":4, "w":1.25}, | |||
{"label":"K4E", "x":13.75, "y":4, "w":1.25} | |||
] | |||
} | |||
} | |||
} | |||
} |
@ -1,67 +1,38 @@ | |||
#include QMK_KEYBOARD_H | |||
#define MODS_SHIFT_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)) | |||
/* Copyright 2017 Ryan Mitchell (@newtmitch) | |||
* 2021 James Young for QMK (@noroadsleft) | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
enum custom_keycodes { | |||
SFT_ESC = SAFE_RANGE | |||
}; | |||
#include QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
/* | |||
* Default keymap with standard 60% layout. Split space possible but entirely optional with this layout, as this | |||
* layout covers all three split space keys as space keycodes. This also has alt right next to the space bar | |||
* on both sides (Windows keyboard layout), no right-side system/GUI key, and momentary layer switching on | |||
* the right modifiers into the 3rd (macro) and 2nd (function/sfx) layers, respectively. This also has the grave | |||
* accent key set up on the 2nd layer, although on the first layer it includes grave key (tilde) when shift is held down, | |||
* via the function actions code at the bottom. | |||
*/ | |||
LAYOUT( | |||
SFT_ESC,KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_NO, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_NO, | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(2), KC_NO, MO(1), KC_RCTL), | |||
LAYOUT( | |||
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_DEL, | |||
KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_TOGG, BL_INC, BL_STEP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), | |||
[0] = LAYOUT_all( | |||
KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, XXXXXXX, KC_BSPC, | |||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, | |||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, | |||
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, MO(1), | |||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT | |||
), | |||
[1] = LAYOUT_all( | |||
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_DEL, | |||
_______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, RESET, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, BL_DEC, BL_TOGG, BL_INC, BL_STEP, _______, _______, _______, _______, _______, _______, _______, | |||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ | |||
), | |||
LAYOUT( | |||
KC_TRNS, M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8), M(9), M(10), M(11), M(12), KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, | |||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), | |||
}; | |||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
switch (keycode) { | |||
case SFT_ESC: | |||
if (record->event.pressed) { | |||
if (get_mods() & MODS_SHIFT_MASK) { | |||
add_key(KC_GRV); | |||
send_keyboard_report(); | |||
} else { | |||
add_key(KC_ESC); | |||
send_keyboard_report(); | |||
} | |||
} else { | |||
if (get_mods() & MODS_SHIFT_MASK) { | |||
del_key(KC_GRV); | |||
send_keyboard_report(); | |||
} else { | |||
del_key(KC_ESC); | |||
send_keyboard_report(); | |||
} | |||
} | |||
return false; | |||
default: | |||
return true; | |||
} | |||
} |
@ -1,18 +1,24 @@ | |||
ACR60 | |||
===== | |||
# ACR60 | |||
![acr60](https://cdn.shopify.com/s/files/1/1697/5323/products/20170522001035_1024x1024.jpg?v=1504725199) | |||
A customizable 60% keyboard made and sold by mechkeys.ca [More info on MECHKEYS](https://mechkeys.ca) | |||
Keyboard Maintainer: [TurboMech](https://github.com/TurboMech) | |||
Hardware Supported: ACR60 | |||
Hardware Availability: [MECHKEYS](https://mechkeys.ca/products/acr60) | |||
* Keyboard Maintainer: [TurboMech](https://github.com/TurboMech) | |||
* Hardware Supported: ACR60 | |||
* Hardware Availability: [~~MECHKEYS~~](https://mechkeys.ca/products/acr60) (no longer available) | |||
Make example for this keyboard (after setting up your build environment): | |||
make acr60:default | |||
See [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) then the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. | |||
Flashing example for this keyboard: | |||
make acr60:default:flash | |||
To reset the board into bootloader mode, do one of the following: | |||
* Tap the Reset switch mounted on the bottom side of the PCB | |||
* Hold Space+B while connecting the USB cable | |||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).` |