From 8479dd65d404ff5e401ea80dfb16160d65247307 Mon Sep 17 00:00:00 2001 From: noroadsleft <18669334+noroadsleft@users.noreply.github.com> Date: Wed, 7 Aug 2019 19:00:45 -0700 Subject: [PATCH 01/61] [Keyboard] Southpole: add Configurator layout data (#6498) --- keyboards/southpole/info.json | 98 +++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 keyboards/southpole/info.json diff --git a/keyboards/southpole/info.json b/keyboards/southpole/info.json new file mode 100644 index 00000000000..4078824aeb7 --- /dev/null +++ b/keyboards/southpole/info.json @@ -0,0 +1,98 @@ +{ + "keyboard_name": "southpole", + "url": "", + "maintainer": "qmk", + "width": 20.5, + "height": 5, + "layouts": { + "LAYOUT": { + "key_count": 84, + "layout": [ + {"label":"Num Lock", "x":0, "y":0}, + {"label":"/", "x":1, "y":0}, + {"label":"*", "x":2, "y":0}, + {"label":"-", "x":3, "y":0}, + {"label":"Esc", "x":4.5, "y":0}, + {"label":"1", "x":5.5, "y":0}, + {"label":"2", "x":6.5, "y":0}, + {"label":"3", "x":7.5, "y":0}, + {"label":"4", "x":8.5, "y":0}, + {"label":"5", "x":9.5, "y":0}, + {"label":"6", "x":10.5, "y":0}, + {"label":"7", "x":11.5, "y":0}, + {"label":"8", "x":12.5, "y":0}, + {"label":"9", "x":13.5, "y":0}, + {"label":"0", "x":14.5, "y":0}, + {"label":"-", "x":15.5, "y":0}, + {"label":"=", "x":16.5, "y":0}, + {"label":"\\", "x":17.5, "y":0}, + {"label":"Delete", "x":18.5, "y":0}, + {"label":"Insert", "x":19.5, "y":0}, + {"label":"7", "x":0, "y":1}, + {"label":"8", "x":1, "y":1}, + {"label":"9", "x":2, "y":1}, + {"label":"+", "x":3, "y":1, "h":2}, + {"label":"Tab", "x":4.5, "y":1, "w":1.5}, + {"label":"Q", "x":6, "y":1}, + {"label":"W", "x":7, "y":1}, + {"label":"E", "x":8, "y":1}, + {"label":"R", "x":9, "y":1}, + {"label":"T", "x":10, "y":1}, + {"label":"Y", "x":11, "y":1}, + {"label":"U", "x":12, "y":1}, + {"label":"I", "x":13, "y":1}, + {"label":"O", "x":14, "y":1}, + {"label":"P", "x":15, "y":1}, + {"label":"[", "x":16, "y":1}, + {"label":"]", "x":17, "y":1}, + {"label":"Backspace", "x":18, "y":1, "w":1.5}, + {"label":"Vol +", "x":19.5, "y":1}, + {"label":"4", "x":0, "y":2}, + {"label":"5", "x":1, "y":2}, + {"label":"6", "x":2, "y":2}, + {"label":"Enter", "x":3, "y":3, "h":2}, + {"label":"Caps Lock", "x":4.5, "y":2, "w":1.75}, + {"label":"A", "x":6.25, "y":2}, + {"label":"S", "x":7.25, "y":2}, + {"label":"D", "x":8.25, "y":2}, + {"label":"F", "x":9.25, "y":2}, + {"label":"G", "x":10.25, "y":2}, + {"label":"H", "x":11.25, "y":2}, + {"label":"J", "x":12.25, "y":2}, + {"label":"K", "x":13.25, "y":2}, + {"label":"L", "x":14.25, "y":2}, + {"label":";", "x":15.25, "y":2}, + {"label":"'", "x":16.25, "y":2}, + {"label":"Enter", "x":17.25, "y":2, "w":2.25}, + {"label":"Vol -", "x":19.5, "y":2}, + {"label":"1", "x":0, "y":3}, + {"label":"2", "x":1, "y":3}, + {"label":"3", "x":2, "y":3}, + {"label":"Shift", "x":4.5, "y":3, "w":2.25}, + {"label":"Z", "x":6.75, "y":3}, + {"label":"X", "x":7.75, "y":3}, + {"label":"C", "x":8.75, "y":3}, + {"label":"V", "x":9.75, "y":3}, + {"label":"B", "x":10.75, "y":3}, + {"label":"N", "x":11.75, "y":3}, + {"label":"M", "x":12.75, "y":3}, + {"label":",", "x":13.75, "y":3}, + {"label":".", "x":14.75, "y":3}, + {"label":"/", "x":15.75, "y":3}, + {"label":"Shift", "x":16.75, "y":3, "w":1.75}, + {"label":"Up", "x":18.5, "y":3}, + {"label":"Mute", "x":19.5, "y":3}, + {"label":"0", "x":0, "y":4, "w":2}, + {"label":".", "x":2, "y":4}, + {"label":"Ctrl", "x":4.5, "y":4, "w":1.25}, + {"label":"GUI", "x":5.75, "y":4, "w":1.25}, + {"label":"Alt", "x":7, "y":4, "w":1.25}, + {"label":"Space", "x":8.25, "y":4, "w":7}, + {"label":"Fn", "x":15.25, "y":4, "w":1.5}, + {"label":"Left", "x":17.5, "y":4}, + {"label":"Down", "x":18.5, "y":4}, + {"label":"Right", "x":19.5, "y":4} + ] + } + } +} From 2c0c25d0140d75e0cd005b10aa5bc35837c363f5 Mon Sep 17 00:00:00 2001 From: MechMerlin <30334081+mechmerlin@users.noreply.github.com> Date: Wed, 7 Aug 2019 19:02:27 -0700 Subject: [PATCH 02/61] Move Alice to TGR Directory (#6502) * git mv alice into the tgr directory * update readme with new build instructions --- keyboards/alice/readme.md | 60 ------------------- keyboards/{ => tgr}/alice/alice.c | 0 keyboards/{ => tgr}/alice/alice.h | 0 keyboards/{ => tgr}/alice/config.h | 0 keyboards/{ => tgr}/alice/info.json | 0 .../{ => tgr}/alice/keymaps/default/keymap.c | 0 .../{ => tgr}/alice/keymaps/mrkeebs/keymap.c | 0 keyboards/tgr/alice/readme.md | 48 +++++++++++++++ keyboards/{ => tgr}/alice/rules.mk | 0 keyboards/{ => tgr}/alice/usbconfig.h | 0 10 files changed, 48 insertions(+), 60 deletions(-) delete mode 100644 keyboards/alice/readme.md rename keyboards/{ => tgr}/alice/alice.c (100%) rename keyboards/{ => tgr}/alice/alice.h (100%) rename keyboards/{ => tgr}/alice/config.h (100%) rename keyboards/{ => tgr}/alice/info.json (100%) rename keyboards/{ => tgr}/alice/keymaps/default/keymap.c (100%) rename keyboards/{ => tgr}/alice/keymaps/mrkeebs/keymap.c (100%) create mode 100644 keyboards/tgr/alice/readme.md rename keyboards/{ => tgr}/alice/rules.mk (100%) rename keyboards/{ => tgr}/alice/usbconfig.h (100%) diff --git a/keyboards/alice/readme.md b/keyboards/alice/readme.md deleted file mode 100644 index 8e901ae7e44..00000000000 --- a/keyboards/alice/readme.md +++ /dev/null @@ -1,60 +0,0 @@ -# TGR Alice - -![TGR Alice](https://i.imgur.com/cJohEqS.jpg) - -An ergonomic 60% keyboard. - -Keyboard Maintainer: [Felipe Coury](https://github.com/fcoury) -Hardware Supported: TGR Alice -Hardware Availability: Group buy finished - -Make example for this keyboard (after setting up your build environment): - - make alice: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. - - -ps2avrGB keyboard firmware -========================== - -This keyboard uses the port of the QMK firmware for boards that are based on the -ps2avrGB firmware. - -Note that this is a complete replacement for the firmware, so you won't be -using Bootmapper Client to change any keyboard settings, since not all the -USB report options are supported. - -## Installing - -First, install the requirements. These commands are for OSX, but all you -need is the AVR toolchain and `bootloadHID` for flashing: - -``` -$ brew cask install crosspack-avr -$ brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb -$ pip install pyusb -``` - -Then, with the keyboard plugged in, simply run this command from the -`qmk_firmware` directory: - -``` -$ make alice -$ bootloadHID -r alice_default.hex -``` - -## Setting the board to bootloader mode - -Hold the ESC key (the one before the 1! key, in case you remaped it). - -## Troubleshooting - -From my experience, it's really hard to brick these boards. But these -tricks have been useful when it got stuck in a weird scenario. - -1. Try plugging the board in while holding the bootloader key. This will force - it to boot only the bootloader without loading the firmware. Once this is - done, just reflash the board with the original firmware. -2. Sometimes USB hubs can act weird, so try connecting the board directly - to your computer or plugging/unplugging the USB hub. diff --git a/keyboards/alice/alice.c b/keyboards/tgr/alice/alice.c similarity index 100% rename from keyboards/alice/alice.c rename to keyboards/tgr/alice/alice.c diff --git a/keyboards/alice/alice.h b/keyboards/tgr/alice/alice.h similarity index 100% rename from keyboards/alice/alice.h rename to keyboards/tgr/alice/alice.h diff --git a/keyboards/alice/config.h b/keyboards/tgr/alice/config.h similarity index 100% rename from keyboards/alice/config.h rename to keyboards/tgr/alice/config.h diff --git a/keyboards/alice/info.json b/keyboards/tgr/alice/info.json similarity index 100% rename from keyboards/alice/info.json rename to keyboards/tgr/alice/info.json diff --git a/keyboards/alice/keymaps/default/keymap.c b/keyboards/tgr/alice/keymaps/default/keymap.c similarity index 100% rename from keyboards/alice/keymaps/default/keymap.c rename to keyboards/tgr/alice/keymaps/default/keymap.c diff --git a/keyboards/alice/keymaps/mrkeebs/keymap.c b/keyboards/tgr/alice/keymaps/mrkeebs/keymap.c similarity index 100% rename from keyboards/alice/keymaps/mrkeebs/keymap.c rename to keyboards/tgr/alice/keymaps/mrkeebs/keymap.c diff --git a/keyboards/tgr/alice/readme.md b/keyboards/tgr/alice/readme.md new file mode 100644 index 00000000000..f5db63814b9 --- /dev/null +++ b/keyboards/tgr/alice/readme.md @@ -0,0 +1,48 @@ +# Alice + +![TGR Alice](https://i.imgur.com/cJohEqS.jpg) + +An ergonomic 60% keyboard. + +Keyboard Maintainer: [Felipe Coury](https://github.com/fcoury) +Hardware Supported: TGR Alice +Hardware Availability: Group buy finished + +Make example for this keyboard (after setting up your build environment): + + make tgr/alice:default + +Flashing + +ps2avr(GB) boards use an atmega32a microcontroller and a different bootloader. It is not flashable using the regular QMK methods. + +**Reset Key:** Hold down the key located at `K00`, commonly programmed as `Esc` while plugging in the keyboard. + +Windows: +1. Download [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash). +2. Place your keyboard into reset. +3. Press the `Find Device` button and ensure that your keyboard is found. +4. Press the `Open .hex File` button and locate the `.hex` file you created. +5. Press the `Flash Device` button and wait for the process to complete. + +macOS: +1. Install homebrew by typing the following: + ``` + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + ``` +2. Install `crosspack-avr`. + ``` + brew cask install crosspack-avr + ``` +3. Install the following packages: + ``` + brew install python3 + pip3 install pyusb + brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb + ``` + +4. Place your keyboard into reset. +5. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file. + + +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). diff --git a/keyboards/alice/rules.mk b/keyboards/tgr/alice/rules.mk similarity index 100% rename from keyboards/alice/rules.mk rename to keyboards/tgr/alice/rules.mk diff --git a/keyboards/alice/usbconfig.h b/keyboards/tgr/alice/usbconfig.h similarity index 100% rename from keyboards/alice/usbconfig.h rename to keyboards/tgr/alice/usbconfig.h From 57540af102d034396c9f41a5a6e69ead8b10ba99 Mon Sep 17 00:00:00 2001 From: Michael Clayton Date: Thu, 8 Aug 2019 13:10:16 -0400 Subject: [PATCH 03/61] Change "yu" to "you" in combo docs (#6510) --- docs/feature_combo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/feature_combo.md b/docs/feature_combo.md index 9db7be5119e..d3eb896b286 100644 --- a/docs/feature_combo.md +++ b/docs/feature_combo.md @@ -2,7 +2,7 @@ The Combo feature is a chording type solution for adding custom actions. It lets you hit multiple keys at once and produce a different effect. For instance, hitting `A` and `S` within the tapping term would hit `ESC` instead, or have it perform even more complex tasks. -To enable this feature, yu need to add `COMBO_ENABLE = yes` to your `rules.mk`. +To enable this feature, you need to add `COMBO_ENABLE = yes` to your `rules.mk`. Additionally, in your `config.h`, you'll need to specify the number of combos that you'll be using, by adding `#define COMBO_COUNT 1` (replacing 1 with the number that you're using). From 4d72aa428fb8dc72634bded428f78ffba2284fdc Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 9 Aug 2019 06:12:12 +1000 Subject: [PATCH 04/61] Improve backlight PWM pin support (#6202) * Improve backlight PWM pin support * I accidentally an equals sign * Another typo * Order by pin number * Throw an error if backlight pin is C4 or C5 on 16/32U4 * Use else for clarity * Minor alignment adjustments --- docs/config_options.md | 2 +- docs/feature_backlight.md | 41 ++- docs/getting_started_make_guide.md | 2 +- docs/hardware_avr.md | 4 +- ...ard_to_qmk_(arm_and_other_chibios_cpus).md | 2 +- quantum/quantum.c | 237 +++++++++++------- 6 files changed, 164 insertions(+), 124 deletions(-) diff --git a/docs/config_options.md b/docs/config_options.md index 3be294db894..d2ae5617987 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -76,7 +76,7 @@ This is a C header file that is one of the first things included, and will persi * `#define B7_AUDIO` * enables audio on pin B7 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) * `#define BACKLIGHT_PIN B7` - * pin of the backlight - `B5`, `B6`, `B7` and `C6` (and `D4` on ATmega32A) use hardware PWM, others use software implementation + * pin of the backlight * `#define BACKLIGHT_LEVELS 3` * number of levels your backlight will have (maximum 15 excluding off) * `#define BACKLIGHT_BREATHING` diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md index 64c663076ba..2d9eea67bfa 100644 --- a/docs/feature_backlight.md +++ b/docs/feature_backlight.md @@ -30,32 +30,31 @@ You should then be able to use the keycodes below to change the backlight level. This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously use multiple different coloured LEDs on a keyboard. -Hardware PWM is only supported on certain pins of the MCU, so if the backlighting is not connected to one of them, a software PWM implementation triggered by hardware timer interrupts will be used. - Hardware PWM is supported according to the following table: -| Backlight Pin | Hardware timer | -|---------------|-------------------------| -|`B5` | Timer 1 | -|`B6` | Timer 1 | -|`B7` | Timer 1 | -|`C6` | Timer 3 | -|`D4` | Timer 1 (ATmega32A only)| -| other | Software PWM | +|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A| +|-------------|-------------|-------------|-------------|---------| +|`B5` |Timer 1 |Timer 1 | | | +|`B6` |Timer 1 |Timer 1 | | | +|`B7` |Timer 1 |Timer 1 |Timer 1 | | +|`C4` |Timer 3 | | | | +|`C5` |Timer 3 | |Timer 1 | | +|`C6` |Timer 3 |Timer 3 |Timer 1 | | +|`D4` | | | |Timer 1 | +|`D5` | | | |Timer 1 | -The [audio feature](feature_audio.md) also uses hardware timers. Please refer to the following table to know what hardware timer the software PWM will use depending on the audio configuration: +All other pins will use software PWM. If the [Audio](feature_audio.md) feature is disabled or only using one timer, the backlight PWM can be triggered by a hardware timer: -| Audio Pin(s) | Audio Timer | Software PWM Timer | -|--------------|-------------|--------------------| -| `C4` | Timer 3 | Timer 1 | -| `C5` | Timer 3 | Timer 1 | -| `C6` | Timer 3 | Timer 1 | -| `B5` | Timer 1 | Timer 3 | -| `B6` | Timer 1 | Timer 3 | -| `B7` | Timer 1 | Timer 3 | -| `Bx` & `Cx` | Timer 1 & 3 | None | +|Audio Pin|Audio Timer|Software PWM Timer| +|---------|-----------|------------------| +|`C4` |Timer 3 |Timer 1 | +|`C5` |Timer 3 |Timer 1 | +|`C6` |Timer 3 |Timer 1 | +|`B5` |Timer 1 |Timer 3 | +|`B6` |Timer 1 |Timer 3 | +|`B7` |Timer 1 |Timer 3 | -When all timers are in use for [audio](feature_audio.md), the backlight software PWM will not use a hardware timer, but instead will be triggered during the matrix scan. In this case the backlight doesn't support breathing and might show lighting artifacts (for instance flickering), because the PWM computation might not be called with enough timing precision. +When both timers are in use for Audio, the backlight PWM will not use a hardware timer, but will instead be triggered during the matrix scan. In this case, breathing is not supported, and the backlight might flicker, because the PWM computation may not be called with enough timing precision. ## Configuration diff --git a/docs/getting_started_make_guide.md b/docs/getting_started_make_guide.md index 75eafd42ccc..4fe3f184df4 100644 --- a/docs/getting_started_make_guide.md +++ b/docs/getting_started_make_guide.md @@ -83,7 +83,7 @@ This allows the keyboard to tell the host OS that up to 248 keys are held down a `BACKLIGHT_ENABLE` -This enables your backlight on Timer1 and ports B5, B6, or B7 (for now). You can specify your port by putting this in your `config.h`: +This enables the in-switch LED backlighting. You can specify the backlight pin by putting this in your `config.h`: #define BACKLIGHT_PIN B7 diff --git a/docs/hardware_avr.md b/docs/hardware_avr.md index 7c28ab6dbcc..c6987d1bdf9 100644 --- a/docs/hardware_avr.md +++ b/docs/hardware_avr.md @@ -125,7 +125,7 @@ To configure a keyboard where each switch is connected to a separate pin and gro ### Backlight Configuration -By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are using one of those you can simply enable it here. For more details see the [Backlight Documentation](feature_backlight.md). +QMK supports backlighting on most GPIO pins. A select few of these can be driven by the MCU in hardware. For more details see the [Backlight Documentation](feature_backlight.md). ```c #define BACKLIGHT_PIN B7 @@ -134,8 +134,6 @@ By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are us #define BREATHING_PERIOD 6 ``` -?> You can use backlighting on any pin you like, but you will have to do more work to support that. See the [Backlight Documentation](feature_backlight.md) for more details. - ### Other Configuration Options There are a lot of features that can be configured or tuned in `config.h`. You should see the [Config Options](config_options.md) page for more details. diff --git a/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md b/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md index 979eafbc80f..bce9f9dc9bc 100644 --- a/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md +++ b/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md @@ -34,7 +34,7 @@ For the `DIODE_DIRECTION`, most hand-wiring guides will instruct you to wire the To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`. -`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. Currently only B5, B6, and B7 are supported. +`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. `BACKLIGHT_BREATHING` is a fancier backlight feature that adds breathing/pulsing/fading effects to the backlight. It uses the same timer as the normal backlight. These breathing effects must be called by code in your keymap. diff --git a/quantum/quantum.c b/quantum/quantum.c index d98c601d991..77cbbb2e77d 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1034,104 +1034,147 @@ void matrix_scan_quantum() { } #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)) -// The logic is a bit complex, we support 3 setups: -// 1. hardware PWM when backlight is wired to a PWM pin -// depending on this pin, we use a different output compare unit -// 2. software PWM with hardware timers, but the used timer depends -// on the audio setup (audio wins other backlight) -// 3. full software PWM +// This logic is a bit complex, we support 3 setups: +// +// 1. Hardware PWM when backlight is wired to a PWM pin. +// Depending on this pin, we use a different output compare unit. +// 2. Software PWM with hardware timers, but the used timer +// depends on the Audio setup (Audio wins over Backlight). +// 3. Full software PWM, driven by the matrix scan, if both timers are used by Audio. -#if BACKLIGHT_PIN == B7 -# define HARDWARE_PWM -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define COMxx1 COM1C1 -# define OCRxx OCR1C -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TOIEx TOIE1 -# define ICRx ICR1 -# define TIMSKx TIMSK1 -#elif BACKLIGHT_PIN == B6 -# define HARDWARE_PWM -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TOIEx TOIE1 -# define ICRx ICR1 -# define TIMSKx TIMSK1 -#elif BACKLIGHT_PIN == B5 -# define HARDWARE_PWM -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define COMxx1 COM1A1 -# define OCRxx OCR1A -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TOIEx TOIE1 -# define ICRx ICR1 -# define TIMSKx TIMSK1 -#elif BACKLIGHT_PIN == C6 -# define HARDWARE_PWM -# define TCCRxA TCCR3A -# define TCCRxB TCCR3B -# define COMxx1 COM3A1 -# define OCRxx OCR3A -# define TIMERx_OVF_vect TIMER3_OVF_vect -# define TOIEx TOIE3 -# define ICRx ICR3 -# define TIMSKx TIMSK3 -#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TOIEx TOIE1 -# define ICRx ICR1 -# define TIMSKx TIMSK1 +#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) \ + || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) \ + || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) \ + && (BACKLIGHT_PIN == B5 || BACKLIGHT_PIN == B6 || BACKLIGHT_PIN == B7) + #define HARDWARE_PWM + #define ICRx ICR1 + #define TCCRxA TCCR1A + #define TCCRxB TCCR1B + #define TIMERx_OVF_vect TIMER1_OVF_vect + #define TIMSKx TIMSK1 + #define TOIEx TOIE1 + + #if BACKLIGHT_PIN == B5 + #define COMxx1 COM1A1 + #define OCRxx OCR1A + #elif BACKLIGHT_PIN == B6 + #define COMxx1 COM1B1 + #define OCRxx OCR1B + #elif BACKLIGHT_PIN == B7 + #define COMxx1 COM1C1 + #define OCRxx OCR1C + #endif +#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) \ + || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) \ + || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) \ + && (BACKLIGHT_PIN == C4 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) + #define HARDWARE_PWM + #define ICRx ICR3 + #define TCCRxA TCCR3A + #define TCCRxB TCCR3B + #define TIMERx_OVF_vect TIMER3_OVF_vect + #define TIMSKx TIMSK3 + #define TOIEx TOIE3 + + #if BACKLIGHT_PIN == C4 + #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + #error This MCU has no C4 pin! + #else + #define COMxx1 COM3C1 + #define OCRxx OCR3C + #endif + #elif BACKLIGHT_PIN == C5 + #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + #error This MCU has no C5 pin! + #else + #define COMxx1 COM3B1 + #define OCRxx OCR3B + #endif + #elif BACKLIGHT_PIN == C6 + #define COMxx1 COM3A1 + #define OCRxx OCR3A + #endif +#elif (defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) \ + && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) + #define HARDWARE_PWM + #define ICRx ICR1 + #define TCCRxA TCCR1A + #define TCCRxB TCCR1B + #define TIMERx_OVF_vect TIMER1_OVF_vect + #define TIMSKx TIMSK1 + #define TOIEx TOIE1 + + #if BACKLIGHT_PIN == B7 + #define COMxx1 COM1C1 + #define OCRxx OCR1C + #elif BACKLIGHT_PIN == C5 + #define COMxx1 COM1B1 + #define OCRxx OCR1B + #elif BACKLIGHT_PIN == C6 + #define COMxx1 COM1A1 + #define OCRxx OCR1A + #endif +#elif defined(__AVR_ATmega32A__) \ + && (BACKLIGHT_PIN == D4 || BACKLIGHT_PIN == D5) + #define HARDWARE_PWM + #define ICRx ICR1 + #define TCCRxA TCCR1A + #define TCCRxB TCCR1B + #define TIMERx_OVF_vect TIMER1_OVF_vect + #define TIMSKx TIMSK + #define TOIEx TOIE1 + + #if BACKLIGHT_PIN == D4 + #define COMxx1 COM1B1 + #define OCRxx OCR1B + #elif BACKLIGHT_PIN == D5 + #define COMxx1 COM1A1 + #define OCRxx OCR1A + #endif #else -# if !defined(BACKLIGHT_CUSTOM_DRIVER) -# if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) - // timer 1 is not used by audio , backlight can use it -#pragma message "Using hardware timer 1 with software PWM" -# define HARDWARE_PWM -# define BACKLIGHT_PWM_TIMER -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define OCRxx OCR1A -# define TIMERx_COMPA_vect TIMER1_COMPA_vect -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define OCIExA OCIE1A -# define TOIEx TOIE1 -# define ICRx ICR1 -# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register -# define TIMSKx TIMSK -# else -# define TIMSKx TIMSK1 -# endif -# elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) -#pragma message "Using hardware timer 3 with software PWM" -// timer 3 is not used by audio, backlight can use it -# define HARDWARE_PWM -# define BACKLIGHT_PWM_TIMER -# define TCCRxA TCCR3A -# define TCCRxB TCCR3B -# define OCRxx OCR3A -# define TIMERx_COMPA_vect TIMER3_COMPA_vect -# define TIMERx_OVF_vect TIMER3_OVF_vect -# define OCIExA OCIE3A -# define TOIEx TOIE3 -# define ICRx ICR1 -# define TIMSKx TIMSK3 -# else -#pragma message "Audio in use - using pure software PWM" -#define NO_HARDWARE_PWM -# endif -# else -#pragma message "Custom driver defined - using pure software PWM" -#define NO_HARDWARE_PWM -# endif + #if !defined(BACKLIGHT_CUSTOM_DRIVER) + #if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) + // Timer 1 is not in use by Audio feature, Backlight can use it + #pragma message "Using hardware timer 1 with software PWM" + #define HARDWARE_PWM + #define BACKLIGHT_PWM_TIMER + #define ICRx ICR1 + #define TCCRxA TCCR1A + #define TCCRxB TCCR1B + #define TIMERx_COMPA_vect TIMER1_COMPA_vect + #define TIMERx_OVF_vect TIMER1_OVF_vect + #if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register + #define TIMSKx TIMSK + #else + #define TIMSKx TIMSK1 + #endif + #define TOIEx TOIE1 + + #define OCIExA OCIE1A + #define OCRxx OCR1A + #elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) + #pragma message "Using hardware timer 3 with software PWM" + // Timer 3 is not in use by Audio feature, Backlight can use it + #define HARDWARE_PWM + #define BACKLIGHT_PWM_TIMER + #define ICRx ICR1 + #define TCCRxA TCCR3A + #define TCCRxB TCCR3B + #define TIMERx_COMPA_vect TIMER3_COMPA_vect + #define TIMERx_OVF_vect TIMER3_OVF_vect + #define TIMSKx TIMSK3 + #define TOIEx TOIE3 + + #define OCIExA OCIE3A + #define OCRxx OCR3A + #else + #pragma message "Audio in use - using pure software PWM" + #define NO_HARDWARE_PWM + #endif + #else + #pragma message "Custom driver defined - using pure software PWM" + #define NO_HARDWARE_PWM + #endif #endif #ifndef BACKLIGHT_ON_STATE @@ -1300,7 +1343,7 @@ static uint16_t cie_lightness(uint16_t v) { // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val. static inline void set_pwm(uint16_t val) { - OCRxx = val; + OCRxx = val; } #ifndef BACKLIGHT_CUSTOM_DRIVER From b4c03070de81bdcf1b20822e56d44dbba8e64a20 Mon Sep 17 00:00:00 2001 From: Daniel Shields Date: Thu, 8 Aug 2019 21:21:55 +0100 Subject: [PATCH 05/61] [Keymap] Fix rgb matrix effects on dshields keymaps. (#6505) --- keyboards/model01/keymaps/dshields/config.h | 2 +- keyboards/model01/keymaps/dshields/keymap.c | 6 ++++++ keyboards/planck/keymaps/dshields/config.h | 2 +- keyboards/planck/keymaps/dshields/keymap.c | 6 ++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/keyboards/model01/keymaps/dshields/config.h b/keyboards/model01/keymaps/dshields/config.h index 1c78217f2fa..0896a1f45e0 100644 --- a/keyboards/model01/keymaps/dshields/config.h +++ b/keyboards/model01/keymaps/dshields/config.h @@ -1,6 +1,6 @@ #pragma once -#define RGB_MATRIX_KEYPRESSES +#define RGB_MATRIX_FRAMEBUFFER_EFFECTS #define RGB_DIGITAL_RAIN_DROPS 18 #define USB_MAX_POWER_CONSUMPTION 100 #define ONESHOT_TAP_TOGGLE 2 diff --git a/keyboards/model01/keymaps/dshields/keymap.c b/keyboards/model01/keymaps/dshields/keymap.c index 3a89d062b5b..dedfd69b483 100644 --- a/keyboards/model01/keymaps/dshields/keymap.c +++ b/keyboards/model01/keymaps/dshields/keymap.c @@ -44,6 +44,12 @@ uint32_t layer_state_set_user(uint32_t state) { return state; } +/* +void matrix_init_user(void) { + eeconfig_init(); +}; +*/ + bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!process_record_dynamic_macro(keycode, record)) { return false; diff --git a/keyboards/planck/keymaps/dshields/config.h b/keyboards/planck/keymaps/dshields/config.h index 7f9cf746728..8d90d0d2cee 100644 --- a/keyboards/planck/keymaps/dshields/config.h +++ b/keyboards/planck/keymaps/dshields/config.h @@ -1,6 +1,6 @@ #pragma once -#define RGB_MATRIX_KEYPRESSES +#define RGB_MATRIX_FRAMEBUFFER_EFFECTS #define RGB_DIGITAL_RAIN_DROPS 24 #define USB_MAX_POWER_CONSUMPTION 100 #define ONESHOT_TAP_TOGGLE 2 diff --git a/keyboards/planck/keymaps/dshields/keymap.c b/keyboards/planck/keymaps/dshields/keymap.c index 11abaa6b071..18e246a3eaf 100644 --- a/keyboards/planck/keymaps/dshields/keymap.c +++ b/keyboards/planck/keymaps/dshields/keymap.c @@ -43,6 +43,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ) }; +/* +void matrix_init_user(void) { + eeconfig_init(); +}; +*/ + bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!process_record_dynamic_macro(keycode, record)) { return false; From f3e73965f061ed21111ca5ae89b046b1efbd894d Mon Sep 17 00:00:00 2001 From: x1 Date: Fri, 9 Aug 2019 05:30:21 +0900 Subject: [PATCH 06/61] [Keymap] Add kudox japanese keymap (#6508) * Add a JIS keymap for kudox. * Remove unnecessary codes. --- keyboards/kudox/keymaps/default/keymap.c | 2 +- keyboards/kudox/keymaps/jis/config.h | 17 +++++++++ keyboards/kudox/keymaps/jis/keymap.c | 47 ++++++++++++++++++++++++ keyboards/kudox/keymaps/jis/readme.md | 1 + keyboards/kudox/keymaps/jis/rules.mk | 0 keyboards/kudox/keymaps/x1/keymap.c | 2 +- 6 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 keyboards/kudox/keymaps/jis/config.h create mode 100644 keyboards/kudox/keymaps/jis/keymap.c create mode 100644 keyboards/kudox/keymaps/jis/readme.md create mode 100644 keyboards/kudox/keymaps/jis/rules.mk diff --git a/keyboards/kudox/keymaps/default/keymap.c b/keyboards/kudox/keymaps/default/keymap.c index 9078b65c1eb..4c245768240 100644 --- a/keyboards/kudox/keymaps/default/keymap.c +++ b/keyboards/kudox/keymaps/default/keymap.c @@ -32,7 +32,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_ALES ,KC_QUOT ,KC_MINS ,KC_EQL ,KC_ENT ,KC_LGUI ,KC_SPC , KC_RGENT,KC_DEL ,SYM_L ,KC_LEFT ,KC_DOWN ,KC_UP ,KC_RGHT //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘ ), -//KC_EQL + [_SYMB] = LAYOUT( //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ KC_GRV ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ , diff --git a/keyboards/kudox/keymaps/jis/config.h b/keyboards/kudox/keymaps/jis/config.h new file mode 100644 index 00000000000..f5bf85cca0a --- /dev/null +++ b/keyboards/kudox/keymaps/jis/config.h @@ -0,0 +1,17 @@ +/* Copyright 2019 Kumao Kobo + * + * 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 . + */ + +#pragma once diff --git a/keyboards/kudox/keymaps/jis/keymap.c b/keyboards/kudox/keymaps/jis/keymap.c new file mode 100644 index 00000000000..c8305dd9f09 --- /dev/null +++ b/keyboards/kudox/keymaps/jis/keymap.c @@ -0,0 +1,47 @@ +#include QMK_KEYBOARD_H + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +#define _QWERTY 0 +#define _SYMB 1 + +// Shortcut to make keymap more readable +#define SYM_L MO(_SYMB) + +#define KC_ALES LALT_T(KC_ESC) + +#define KC_L1SYM LT(_SYMB, KC_LANG1) +#define KC_L2SYM LT(_SYMB, KC_LANG2) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[_QWERTY] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + KC_GRV ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 , KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_BSPC , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_L2SYM, KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_AT ,KC_BSLS , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LCTL ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G , KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_ENT , + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B , KC_SLSH ,KC_N ,KC_M ,KC_MINS ,KC_UP ,SYM_L , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤ + KC_ALES ,KC_LGUI ,KC_LALT ,KC_ENT ,KC_LANG2,KC_SPC ,KC_SPC , KC_COMM ,KC_DOT ,KC_L1SYM,KC_LEFT ,KC_DOWN ,KC_RGHT ,KC_COLN + //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘ + ), + + [_SYMB] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + KC_ESC ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , XXXXXXX ,KC_CIRC ,KC_JYEN ,KC_TILD ,KC_PIPE ,KC_DEL , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + _______ ,KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ , KC_LT ,KC_GT ,KC_LBRC ,KC_RBRC ,KC_LCBR ,KC_RCBR ,XXXXXXX , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + _______ ,KC_F11 ,KC_F12 ,XXXXXXX ,XXXXXXX ,XXXXXXX , XXXXXXX ,KC_PLUS ,KC_ASTR ,KC_SCLN ,KC_COLN ,_______ , + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + _______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , _______ ,XXXXXXX ,XXXXXXX ,_______ ,KC_VOLU ,_______ , + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤ + _______ ,_______ ,_______ ,_______ ,_______ ,_______ ,_______ , _______ ,_______ ,_______ ,KC_MUTE ,KC_VOLD ,_______,_______ + //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘ + ) +}; diff --git a/keyboards/kudox/keymaps/jis/readme.md b/keyboards/kudox/keymaps/jis/readme.md new file mode 100644 index 00000000000..0f3fae39f71 --- /dev/null +++ b/keyboards/kudox/keymaps/jis/readme.md @@ -0,0 +1 @@ +# The JIS keymap for Kudox Keyboard diff --git a/keyboards/kudox/keymaps/jis/rules.mk b/keyboards/kudox/keymaps/jis/rules.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/keyboards/kudox/keymaps/x1/keymap.c b/keyboards/kudox/keymaps/x1/keymap.c index 42f507ddfbe..1c08349b015 100644 --- a/keyboards/kudox/keymaps/x1/keymap.c +++ b/keyboards/kudox/keymaps/x1/keymap.c @@ -41,7 +41,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_ALES ,KC_QUOT ,KC_MINS ,KC_EQL ,KC_ENNUM,KC_LGUI ,KC_SPC , KC_RGENT,KC_DEL ,SYM_L ,KC_LEFT ,KC_DOWN ,KC_UP ,KC_RGHT //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘ ), -//KC_EQL + [_SYMB] = LAYOUT( //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ KC_GRV ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ , From 2a534e87acfa8391d88dac6df02ae1a14da6c18e Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 9 Aug 2019 06:32:30 +1000 Subject: [PATCH 07/61] Rename QK_TMK(_MAX) to QK_BASIC (#6509) --- quantum/quantum_keycodes.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 207e0a8261b..b5c6783e5e7 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -31,9 +31,9 @@ #define XXXXXXX KC_NO enum quantum_keycodes { - // Ranges used in shortucuts - not to be used directly - QK_TMK = 0x0000, - QK_TMK_MAX = 0x00FF, + // Ranges used in shortcuts - not to be used directly + QK_BASIC = 0x0000, + QK_BASIC_MAX = 0x00FF, QK_MODS = 0x0100, QK_LCTL = 0x0100, QK_LSFT = 0x0200, From 2f6c068e0dd7abc3cec1bb72df0b1e96032246f8 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 9 Aug 2019 06:58:05 +1000 Subject: [PATCH 08/61] Extend allowed range of tappable keycodes to include modifiers (#5809) * Extend allowed range of tappable keycodes to include modifiers * Get rid of the magic numbers altogether * Remove some more magic numbers * Extract LM() functionality from ACT_LAYER_TAP * Use ACTION() macro everywhere --- tmk_core/common/action.c | 25 +++++++++++++------------ tmk_core/common/action_code.h | 16 ++++++++++++---- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index 5172e8650ad..f47fd20fc96 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -437,20 +437,19 @@ void process_action(keyrecord_t *record, action_t action) } } break; + case ACT_LAYER_MODS: + if (event.pressed) { + layer_on(action.layer_mods.layer); + register_mods(action.layer_mods.mods); + } else { + unregister_mods(action.layer_mods.mods); + layer_off(action.layer_mods.layer); + } + break; #ifndef NO_ACTION_TAPPING case ACT_LAYER_TAP: case ACT_LAYER_TAP_EXT: switch (action.layer_tap.code) { - case 0xe0 ... 0xef: - /* layer On/Off with modifiers(left only) */ - if (event.pressed) { - layer_on(action.layer_tap.val); - register_mods(action.layer_tap.code & 0x0f); - } else { - layer_off(action.layer_tap.val); - unregister_mods(action.layer_tap.code & 0x0f); - } - break; case OP_TAP_TOGGLE: /* tap toggle */ if (event.pressed) { @@ -652,6 +651,7 @@ void process_action(keyrecord_t *record, action_t action) // if this event is a layer action, update the leds switch (action.kind.id) { case ACT_LAYER: + case ACT_LAYER_MODS: #ifndef NO_ACTION_TAPPING case ACT_LAYER_TAP: case ACT_LAYER_TAP_EXT: @@ -957,7 +957,7 @@ bool is_tap_action(action_t action) case ACT_LAYER_TAP: case ACT_LAYER_TAP_EXT: switch (action.layer_tap.code) { - case 0x00 ... 0xdf: + case KC_NO ... KC_RGUI: case OP_TAP_TOGGLE: case OP_ONESHOT: return true; @@ -965,7 +965,7 @@ bool is_tap_action(action_t action) return false; case ACT_SWAP_HANDS: switch (action.swap.code) { - case 0x00 ... 0xdf: + case KC_NO ... KC_RGUI: case OP_SH_TAP_TOGGLE: return true; } @@ -1014,6 +1014,7 @@ void debug_action(action_t action) case ACT_USAGE: dprint("ACT_USAGE"); break; case ACT_MOUSEKEY: dprint("ACT_MOUSEKEY"); break; case ACT_LAYER: dprint("ACT_LAYER"); break; + case ACT_LAYER_MODS: dprint("ACT_LAYER_MODS"); break; case ACT_LAYER_TAP: dprint("ACT_LAYER_TAP"); break; case ACT_LAYER_TAP_EXT: dprint("ACT_LAYER_TAP_EXT"); break; case ACT_MACRO: dprint("ACT_MACRO"); break; diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index d836b7a8a39..5b5d0e56604 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h @@ -66,7 +66,8 @@ along with this program. If not, see . * EBBBB: bits and extra bit * ee: on event(01:press, 10:release, 11:both) * - * 1001|xxxx|xxxx xxxx (reserved) + * ACT_LAYER_MODS(1001): + * 1001|LLLL| mods Layer with modifiers held * * ACT_LAYER_TAP(101x): * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP] @@ -110,6 +111,7 @@ enum action_kind_id { ACT_SWAP_HANDS = 0b0110, /* Layer Actions */ ACT_LAYER = 0b1000, + ACT_LAYER_MODS = 0b1001, ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ /* Extensions */ @@ -153,6 +155,12 @@ typedef union { uint8_t op :2; uint8_t kind :4; } layer_bitop; + struct action_layer_mods + { + uint8_t mods :8; + uint8_t layer :4; + uint8_t kind :4; + } layer_mods; struct action_layer_tap { uint8_t code :8; uint8_t val :5; @@ -261,8 +269,8 @@ enum layer_param_tap_op { OP_SET_CLEAR, OP_ONESHOT, }; -#define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) -#define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key)) +#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) +#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer)<<8 | (key)) /* Default Layer */ #define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4)) /* Layer Operation */ @@ -277,7 +285,7 @@ enum layer_param_tap_op { #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) #define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT) -#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f)) +#define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods)) /* With Tapping */ #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) #define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) From 405dea01bef215a0b79524e4ff74364f1bcfeadf Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 9 Aug 2019 07:09:54 +1000 Subject: [PATCH 09/61] Add some defaults for ATmega32A to mcu_selection.mk (#6253) * Add some defaults for ATmega32A to mcu_selection.mk * Remove boilerplate from templates * Relax INTERRUPT_CONTROL_ENDPOINT and PROGRAM_CMD * Apply suggestions from code review Co-Authored-By: Drashna Jaelre --- quantum/mcu_selection.mk | 26 +++++++++++++++++++-- quantum/template/avr/rules.mk | 36 ------------------------------ quantum/template/ps2avrgb/rules.mk | 11 --------- 3 files changed, 24 insertions(+), 49 deletions(-) diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index fa6dc8b53ca..cca7720e9c7 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -1,4 +1,3 @@ - ifneq ($(findstring STM32F303, $(MCU)),) ## chip/board settings # - the next two should match the directories in @@ -54,7 +53,7 @@ ifneq (,$(filter $(MCU),atmega32u4 at90usb1286)) # LUFA specific # # Target architecture (see library "Board Types" documentation). - ARCH ?= AVR8 + ARCH = AVR8 # Input clock frequency. # This will define a symbol, F_USB, in all source code files equal to the @@ -68,4 +67,27 @@ ifneq (,$(filter $(MCU),atmega32u4 at90usb1286)) # If no clock division is performed on the input clock inside the AVR (via the # CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. F_USB ?= $(F_CPU) + + # Interrupt driven control endpoint task + ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes)) + OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + endif +endif + +ifneq (,$(filter $(MCU),atmega32a)) + PROTOCOL = VUSB + + # Processor frequency. + # This will define a symbol, F_CPU, in all source code files equal to the + # processor frequency in Hz. You can then use this symbol in your source code to + # calculate timings. Do NOT tack on a 'UL' at the end, this will be done + # automatically to create a 32-bit value in your source code. + F_CPU ?= 12000000 + + # unsupported features for now + NO_UART ?= yes + NO_SUSPEND_POWER_DOWN ?= yes + + # Programming options + PROGRAM_CMD ?= ./util/atmega32a_program.py $(TARGET).hex endif diff --git a/quantum/template/avr/rules.mk b/quantum/template/avr/rules.mk index 133c9e363b9..50deba92cf9 100644 --- a/quantum/template/avr/rules.mk +++ b/quantum/template/avr/rules.mk @@ -1,42 +1,6 @@ # MCU name MCU = atmega32u4 -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency in Hz. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# -# This will be an integer division of F_USB below, as it is sourced by -# F_USB after it has run through any CPU prescalers. Note that this value -# does not *change* the processor frequency - it should merely be updated to -# reflect the processor speed set externally so that the code can use accurate -# software delays. -F_CPU = 16000000 - - -# -# LUFA specific -# -# Target architecture (see library "Board Types" documentation). -ARCH = AVR8 - -# Input clock frequency. -# This will define a symbol, F_USB, in all source code files equal to the -# input clock frequency (before any prescaling is performed) in Hz. This value may -# differ from F_CPU if prescaling is used on the latter, and is required as the -# raw input clock is fed directly to the PLL sections of the AVR for high speed -# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -# at the end, this will be done automatically to create a 32-bit value in your -# source code. -# -# If no clock division is performed on the input clock inside the AVR (via the -# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -F_USB = $(F_CPU) - -# Interrupt driven control endpoint task(+60) -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - # Bootloader selection # Teensy halfkay diff --git a/quantum/template/ps2avrgb/rules.mk b/quantum/template/ps2avrgb/rules.mk index 98a920e1828..a3ac9bd75ac 100644 --- a/quantum/template/ps2avrgb/rules.mk +++ b/quantum/template/ps2avrgb/rules.mk @@ -1,13 +1,5 @@ # MCU name MCU = atmega32a -PROTOCOL = VUSB - -# unsupported features for now -NO_UART = yes -NO_SUSPEND_POWER_DOWN = yes - -# processor frequency -F_CPU = 12000000 # Bootloader # This definition is optional, and if your keyboard supports multiple bootloaders of @@ -28,6 +20,3 @@ RGBLIGHT_CUSTOM_DRIVER = yes OPT_DEFS = -DDEBUG_LEVEL=0 SRC += i2c_master.c - -# programming options -PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex From 406f03bb0ceeaf7fda7d04da2379c1f197b5cc6d Mon Sep 17 00:00:00 2001 From: fauxpark Date: Fri, 9 Aug 2019 07:15:34 +1000 Subject: [PATCH 10/61] Mask off TD() parameter properly (#6143) * Mask off TD() parameter properly * More parentheses --- quantum/process_keycode/process_tap_dance.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index ca12f4746e3..00d70cbc59d 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -34,7 +34,7 @@ typedef struct bool finished; } qk_tap_dance_state_t; -#define TD(n) (QK_TAP_DANCE + n) +#define TD(n) (QK_TAP_DANCE | ((n) & 0xFF)) typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state, void *user_data); From c0e6734d3fc7f777d60ad7bb31002521e9a1ee26 Mon Sep 17 00:00:00 2001 From: Florian B Date: Thu, 8 Aug 2019 23:17:49 +0200 Subject: [PATCH 11/61] [Keymap] removes gamelayer, finally got rgb working (#5817) * removes gamelayer, finally got rgb working * lowercasing readme * changed to layout_ortho_4x12 * rules.mk: Removed BACKLIGHT_CUSTOM_DRIVER --- keyboards/jj40/keymaps/waples/keymap.c | 35 ++++++------------- .../keymaps/waples/{README.md => readme.md} | 16 +++------ keyboards/jj40/keymaps/waples/rules.mk | 1 - 3 files changed, 15 insertions(+), 37 deletions(-) rename keyboards/jj40/keymaps/waples/{README.md => readme.md} (81%) diff --git a/keyboards/jj40/keymaps/waples/keymap.c b/keyboards/jj40/keymaps/waples/keymap.c index 79acada28c0..1c8d58f7926 100644 --- a/keyboards/jj40/keymaps/waples/keymap.c +++ b/keyboards/jj40/keymaps/waples/keymap.c @@ -4,15 +4,13 @@ extern keymap_config_t keymap_config; #define _QWERTY 0 #define _DVORAK 1 -#define _GAME 2 -#define _LEFTY 3 -#define _RIGHTY 4 -#define _DUAL 5 +#define _LEFTY 2 +#define _RIGHTY 3 +#define _DUAL 4 enum jj40_keycodes { QWERTY = SAFE_RANGE, DVORAK, - GAME, LEFTY, RIGHTY, DUAL, @@ -28,21 +26,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \ CTLESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, SHFTENT, \ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_QUOT, \ - KC_PSCR, KC_BSPC, KC_LALT, _______, LEFTY, KC_LGUI, KC_SPC, RIGHTY, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ + KC_PSCR, KC_BSPC, KC_CAPS, KC_LALT, LEFTY, KC_LGUI, KC_SPC, RIGHTY, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ ), [_DVORAK] = LAYOUT_ortho_4x12( \ KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \ CTLESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, SHFTENT, \ KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_SLSH, \ - KC_PSCR, KC_LGUI, KC_LALT, KC_CAPS, LEFTY, KC_BSPC, KC_SPC, RIGHTY, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ -), - -[_GAME] = LAYOUT_ortho_4x12( \ - KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, _______, _______, _______, _______, _______, QWERTY, \ - CTLESC, KC_A, KC_S, KC_D, KC_F, KC_G, _______, _______, _______, _______, _______, _______, \ - KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, _______, _______, _______, _______, _______, _______, \ - KC_LCTL, KC_1, KC_2, KC_3, LEFTY, KC_SPC, KC_BSPC, RIGHTY, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT \ + KC_PSCR, KC_BSPC, KC_CAPS, KC_LALT, LEFTY, KC_LGUI, KC_SPC, RIGHTY, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ ), [_LEFTY] = LAYOUT_ortho_4x12( \ @@ -59,11 +50,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______, KC_F9, KC_F10, KC_F11, _______, _______, _______, _______, _______, _______, _______, _______ \ ), -[_DUAL] = LAYOUT_ortho_4x12( \ - RESET, _______, _______, _______, _______, QWERTY, GAME, _______, _______, _______, BL_BRTG, RESET, \ - _______, KC_MPRV, KC_MSTP, KC_MPLY, KC_MNXT, AG_NORM, AG_SWAP, _______, _______, _______, BL_TOGG, _______, \ - _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, TG_NKRO, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, DVORAK, _______, _______, _______, _______, _______ \ +[_DUAL] = LAYOUT_ortho_4x12( \ + RESET, _______, _______, _______, _______, QWERTY, DVORAK, _______, _______, RGB_HUD, RGB_TOG, RESET, \ + _______, KC_MPRV, KC_MSTP, KC_MPLY, KC_MNXT, AG_NORM, AG_SWAP, _______, _______, RGB_HUI, RGB_MOD, _______, \ + _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, TG_NKRO, _______, _______, RGB_SAD, RGB_VAD, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, RGB_VAI, _______ \ ) }; @@ -86,12 +77,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { } return false; break; - case GAME: - if (record->event.pressed) { - persistent_default_layer_set(1UL<<_GAME); - } - return false; - break; case LEFTY: if (record->event.pressed) { layer_on(_LEFTY); diff --git a/keyboards/jj40/keymaps/waples/README.md b/keyboards/jj40/keymaps/waples/readme.md similarity index 81% rename from keyboards/jj40/keymaps/waples/README.md rename to keyboards/jj40/keymaps/waples/readme.md index 3394971b965..91b1094e573 100644 --- a/keyboards/jj40/keymaps/waples/README.md +++ b/keyboards/jj40/keymaps/waples/readme.md @@ -6,11 +6,15 @@ I currently have the following layers in my keymap: * Qwerty (as default) * Dvorak (still learning this type of layout, so not really used much) -* Gaming (WIP! I tried some I found, but didn't like them, so I'm in the progress of making my own) * Lefty (lower) * Righty (raise) * Dual (adjust) +### Note to self: +YOU NEED TO USE [bootloadHID -r jj40_waples.hex](https://github.com/qmk/qmk_firmware/tree/master/keyboards/jj40) + +## the stuff below is out of date and I think about removing them from this readme + #### QWERTY | Tab | Q | W | E | R | T | Y | U | I | O | P | Bsp | |C_Esc| A | S | D | F | G | H | J | K | L | ; |S_Ent| @@ -24,14 +28,6 @@ I currently have the following layers in my keymap: | Sft | ; | Q | J | K | X | B | M | W | V | Z | / | |P_SCR| GUI | Alt | Cps | ^L^ | Bsp | Spc | ^R^ | Lft | Dwn | Up! | Rgt | - -#### GAMING - | Tab | Q | W | E | R | T | | | | | |QWERT| - | Esc | A | S | D | F | G | | | | | | | - | Sft | Z | X | C | V | B | | | | | | | - | Ctl | 1 | 2 | 3 | ^L^ | Spc | Bsp | ^R^ | Lft | Dwn | Up | Rgt | - - #### LEFTY (lower) | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bsp | | Del | | | | | | | ( | ) | [ | ] | | @@ -51,5 +47,3 @@ I currently have the following layers in my keymap: | | Prv | Stp | Tog | Nxt | Nrm | Swp | | | | | | | | | Mte | Vol-| Vol+| | NKRO| | | | | | | | | | | | |DVORK| | | | | | - - diff --git a/keyboards/jj40/keymaps/waples/rules.mk b/keyboards/jj40/keymaps/waples/rules.mk index 18c5638d005..69b7c18d4ea 100644 --- a/keyboards/jj40/keymaps/waples/rules.mk +++ b/keyboards/jj40/keymaps/waples/rules.mk @@ -5,7 +5,6 @@ EXTRAKEY_ENABLE = yes CONSOLE_ENABLE = no COMMAND_ENABLE = yes BACKLIGHT_ENABLE = yes -BACKLIGHT_CUSTOM_DRIVER = yes RGBLIGHT_ENABLE = yes RGBLIGHT_CUSTOM_DRIVER = yes KEY_LOCK_ENABLE = yes From 9114d6ebe9edfa03f0cf3f902ab3040c4fe57872 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Sat, 10 Aug 2019 02:20:43 +0200 Subject: [PATCH 12/61] Update keymap (#6515) Signed-off-by: Sascha Grunert --- keyboards/planck/keymaps/sascha/keymap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/planck/keymaps/sascha/keymap.c b/keyboards/planck/keymaps/sascha/keymap.c index 684b61f3668..665598c9b58 100644 --- a/keyboards/planck/keymaps/sascha/keymap.c +++ b/keyboards/planck/keymaps/sascha/keymap.c @@ -24,14 +24,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * ├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤ * │ ` │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ü │ ö │ ä │ * ├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤ - * │ SINS │ ♥ │ ≈ │ ✓ │ ✗ │ ← │ → │ € │ ß │ Ü │ Ö │ Ä │ + * │ SINS │ ♥ │ ’ │ “ │ ” │ ← │ → │ € │ ß │ Ü │ Ö │ Ä │ * ├──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤ * │ Rset │ BLSt │ F1 │ Home │ End │ PgUp │ PgDn │ Left │ Down │ Up │ Rght │ │ * └──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘ */ KC_TILD , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_DEL, KC_GRV , KC_EXLM , KC_AT , KC_HASH , KC_DLR , KC_PERC , KC_CIRC , KC_AMPR , KC_ASTR , UC(L'ü') , UC(L'ö') , UC(L'ä'), - S(KC_INS) , UC(L'♥') , UC(L'≈') , UC(L'✓') , UC(L'✗') , UC(L'←') , UC(L'→') , UC(L'€') , UC(L'ß') , UC(L'Ü') , UC(L'Ö') , UC(L'Ä'), + S(KC_INS) , UC(L'♥') , UC(L'’') , UC(L'“') , UC(L'”') , UC(L'←') , UC(L'→') , UC(L'€') , UC(L'ß') , UC(L'Ü') , UC(L'Ö') , UC(L'Ä'), RESET , BL_STEP , KC_F1 , KC_HOME , KC_END , KC_PGUP , KC_PGDN , KC_LEFT , KC_DOWN , KC_UP , KC_RGHT , KC_TRNS ) }; From b93e1309e5fbc0438485e5eb18af666ad3508d4a Mon Sep 17 00:00:00 2001 From: Luciano Malavasi Date: Fri, 9 Aug 2019 18:38:13 -0700 Subject: [PATCH 13/61] [Keyboard] Add meson keyboard (#6482) * Add meson keyboard * Apply suggestions from code review Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Added soft reset and layer 3 * bootmagic light Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> --- keyboards/meson/config.h | 172 ++++++++++++++++++++++ keyboards/meson/info.json | 108 ++++++++++++++ keyboards/meson/keymaps/default/config.h | 19 +++ keyboards/meson/keymaps/default/keymap.c | 78 ++++++++++ keyboards/meson/keymaps/default/readme.md | 1 + keyboards/meson/meson.c | 51 +++++++ keyboards/meson/meson.h | 56 +++++++ keyboards/meson/readme.md | 13 ++ keyboards/meson/rules.mk | 81 ++++++++++ 9 files changed, 579 insertions(+) create mode 100644 keyboards/meson/config.h create mode 100644 keyboards/meson/info.json create mode 100644 keyboards/meson/keymaps/default/config.h create mode 100644 keyboards/meson/keymaps/default/keymap.c create mode 100644 keyboards/meson/keymaps/default/readme.md create mode 100644 keyboards/meson/meson.c create mode 100644 keyboards/meson/meson.h create mode 100644 keyboards/meson/readme.md create mode 100644 keyboards/meson/rules.mk diff --git a/keyboards/meson/config.h b/keyboards/meson/config.h new file mode 100644 index 00000000000..3e37c89fd75 --- /dev/null +++ b/keyboards/meson/config.h @@ -0,0 +1,172 @@ +/* +Copyright 2019 Luciano M + +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 . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x0000 +#define DEVICE_VER 0x0001 +#define MANUFACTURER Luciano M +#define PRODUCT Meson +#define DESCRIPTION 3x14 split keyboard with two thumb keys per side + +/* key matrix size */ +#define MATRIX_ROWS 8 // 4 rows each half +#define MATRIX_COLS 7 + +#define MATRIX_ROW_PINS { F7, C6, F6, F5 } +#define MATRIX_COL_PINS { D4, D7, E6, B3, B2, B6, F4 } +// #define UNUSED_PINS + +/* COL2ROW, ROW2COL*/ +#define DIODE_DIRECTION COL2ROW + +#define USE_I2C +#define SOFT_SERIAL_PIN D0 + +#define RGB_DI_PIN B5 +#ifdef RGB_DI_PIN + #define RGBLED_NUM 10 + #define RGBLIGHT_SPLIT + #define RGBLED_SPLIT { 5, 5 } + #define RGBLIGHT_HUE_STEP 8 + #define RGBLIGHT_SAT_STEP 8 + #define RGBLIGHT_VAL_STEP 8 + #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ + #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */ + /*== all animations enable ==*/ + #define RGBLIGHT_ANIMATIONS + /*== customize breathing effect ==*/ + /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/ + #define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64 + /*==== use exp() and sin() ====*/ + #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7 + #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 +#endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is userful for the Windows task manager shortcut (ctrl+shift+esc). + */ +// #define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Magic Key Options + * + * Magic keys are hotkey commands that allow control over firmware functions of + * the keyboard. They are best used in combination with the HID Listen program, + * found here: https://www.pjrc.com/teensy/hid_listen.html + * + * The options below allow the magic key functionality to be changed. This is + * useful if your keyboard/keypad is missing keys and you want magic key support. + * + */ + +/* key combination for magic key command */ +/* defined by default; to change, uncomment and set to the combination you want */ +// #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) + +/* control how magic key switches layers */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false + +/* override magic key keymap */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM +//#define MAGIC_KEY_HELP H +//#define MAGIC_KEY_HELP_ALT SLASH +//#define MAGIC_KEY_DEBUG D +//#define MAGIC_KEY_DEBUG_MATRIX X +//#define MAGIC_KEY_DEBUG_KBD K +//#define MAGIC_KEY_DEBUG_MOUSE M +//#define MAGIC_KEY_VERSION V +//#define MAGIC_KEY_STATUS S +//#define MAGIC_KEY_CONSOLE C +//#define MAGIC_KEY_LAYER0 0 +//#define MAGIC_KEY_LAYER0_ALT GRAVE +//#define MAGIC_KEY_LAYER1 1 +//#define MAGIC_KEY_LAYER2 2 +//#define MAGIC_KEY_LAYER3 3 +//#define MAGIC_KEY_LAYER4 4 +//#define MAGIC_KEY_LAYER5 5 +//#define MAGIC_KEY_LAYER6 6 +//#define MAGIC_KEY_LAYER7 7 +//#define MAGIC_KEY_LAYER8 8 +//#define MAGIC_KEY_LAYER9 9 +//#define MAGIC_KEY_BOOTLOADER B +//#define MAGIC_KEY_BOOTLOADER_ALT ESC +//#define MAGIC_KEY_LOCK CAPS +//#define MAGIC_KEY_EEPROM E +//#define MAGIC_KEY_EEPROM_CLEAR BSPACE +//#define MAGIC_KEY_NKRO N +//#define MAGIC_KEY_SLEEP_LED Z + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + + +/* Bootmagic Lite key configuration */ +// #define BOOTMAGIC_LITE_ROW 0 +// #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/keyboards/meson/info.json b/keyboards/meson/info.json new file mode 100644 index 00000000000..3d7eab847f3 --- /dev/null +++ b/keyboards/meson/info.json @@ -0,0 +1,108 @@ +{ + "keyboard_name": "Meson", + "keyboard_folder": "meson", + "maintainer": "qmk", + "width": 15.5, + "height": 4, + "layouts": { + "LAYOUT": { + "layout": [ + {"label": "", "x": 0, "y": 0}, + {"label": "", "x": 1, "y": 0}, + {"label": "", "x": 2, "y": 0}, + {"label": "", "x": 3, "y": 0}, + {"label": "", "x": 4, "y": 0}, + {"label": "", "x": 5, "y": 0}, + {"label": "", "x": 6, "y": 0}, + {"label": "", "x": 8.5, "y": 0}, + {"label": "", "x": 9.5, "y": 0}, + {"label": "", "x": 10.5, "y": 0}, + {"label": "", "x": 11.5, "y": 0}, + {"label": "", "x": 12.5, "y": 0}, + {"label": "", "x": 13.5, "y": 0}, + {"label": "", "x": 14.5, "y": 0}, + {"label": "", "x": 0, "y": 1}, + {"label": "", "x": 1, "y": 1}, + {"label": "", "x": 2, "y": 1}, + {"label": "", "x": 3, "y": 1}, + {"label": "", "x": 4, "y": 1}, + {"label": "", "x": 5, "y": 1}, + {"label": "", "x": 6, "y": 1}, + {"label": "", "x": 8.5, "y": 1}, + {"label": "", "x": 9.5, "y": 1}, + {"label": "", "x": 10.5, "y": 1}, + {"label": "", "x": 11.5, "y": 1}, + {"label": "", "x": 12.5, "y": 1}, + {"label": "", "x": 13.5, "y": 1}, + {"label": "", "x": 14.5, "y": 1}, + {"label": "", "x": 0, "y": 2}, + {"label": "", "x": 1, "y": 2}, + {"label": "", "x": 2, "y": 2}, + {"label": "", "x": 3, "y": 2}, + {"label": "", "x": 4, "y": 2}, + {"label": "", "x": 5, "y": 2}, + {"label": "", "x": 6, "y": 2}, + {"label": "", "x": 8.5, "y": 2}, + {"label": "", "x": 9.5, "y": 2}, + {"label": "", "x": 10.5, "y": 2}, + {"label": "", "x": 11.5, "y": 2}, + {"label": "", "x": 12.5, "y": 2}, + {"label": "", "x": 13.5, "y": 2}, + {"label": "", "x": 14.5, "y": 2}, + {"label": "", "x": 4, "y": 3}, + {"label": "", "x": 5, "y": 3}, + {"label": "", "x": 9.5, "y": 3}, + {"label": "", "x": 10.5, "y": 3} + ] + }, + "LAYOUT_2u": { + "layout": [ + {"label": "", "x": 0, "y": 0}, + {"label": "", "x": 1, "y": 0}, + {"label": "", "x": 2, "y": 0}, + {"label": "", "x": 3, "y": 0}, + {"label": "", "x": 4, "y": 0}, + {"label": "", "x": 5, "y": 0}, + {"label": "", "x": 6, "y": 0}, + {"label": "", "x": 8.5, "y": 0}, + {"label": "", "x": 9.5, "y": 0}, + {"label": "", "x": 10.5, "y": 0}, + {"label": "", "x": 11.5, "y": 0}, + {"label": "", "x": 12.5, "y": 0}, + {"label": "", "x": 13.5, "y": 0}, + {"label": "", "x": 14.5, "y": 0}, + {"label": "", "x": 0, "y": 1}, + {"label": "", "x": 1, "y": 1}, + {"label": "", "x": 2, "y": 1}, + {"label": "", "x": 3, "y": 1}, + {"label": "", "x": 4, "y": 1}, + {"label": "", "x": 5, "y": 1}, + {"label": "", "x": 6, "y": 1}, + {"label": "", "x": 8.5, "y": 1}, + {"label": "", "x": 9.5, "y": 1}, + {"label": "", "x": 10.5, "y": 1}, + {"label": "", "x": 11.5, "y": 1}, + {"label": "", "x": 12.5, "y": 1}, + {"label": "", "x": 13.5, "y": 1}, + {"label": "", "x": 14.5, "y": 1}, + {"label": "", "x": 0, "y": 2}, + {"label": "", "x": 1, "y": 2}, + {"label": "", "x": 2, "y": 2}, + {"label": "", "x": 3, "y": 2}, + {"label": "", "x": 4, "y": 2}, + {"label": "", "x": 5, "y": 2}, + {"label": "", "x": 6, "y": 2}, + {"label": "", "x": 8.5, "y": 2}, + {"label": "", "x": 9.5, "y": 2}, + {"label": "", "x": 10.5, "y": 2}, + {"label": "", "x": 11.5, "y": 2}, + {"label": "", "x": 12.5, "y": 2}, + {"label": "", "x": 13.5, "y": 2}, + {"label": "", "x": 14.5, "y": 2}, + {"label": "", "x": 4, "y": 3, "w": 2}, + {"label": "", "x": 9.5, "y": 3, "w": 2} + ] + } + } + } + diff --git a/keyboards/meson/keymaps/default/config.h b/keyboards/meson/keymaps/default/config.h new file mode 100644 index 00000000000..cb72945366d --- /dev/null +++ b/keyboards/meson/keymaps/default/config.h @@ -0,0 +1,19 @@ +/* Copyright 2019 Luciano M + * + * 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 . + */ + +#pragma once + +// place overrides here \ No newline at end of file diff --git a/keyboards/meson/keymaps/default/keymap.c b/keyboards/meson/keymaps/default/keymap.c new file mode 100644 index 00000000000..002fc79775d --- /dev/null +++ b/keyboards/meson/keymaps/default/keymap.c @@ -0,0 +1,78 @@ +/* Copyright 2019 Luciano M + * + * 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 . + */ +#include QMK_KEYBOARD_H + +// Defines the keycodes used by our macros in process_record_user +enum custom_keycodes { + MESON = SAFE_RANGE, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( /* Base */ + KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_TAB, KC_BSLS, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_LALT, KC_GRV, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LGUI, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_QUOT, + MO(1), KC_SPC, KC_SPC, MO(2) + ), + + [1] = LAYOUT( /* Symbols */ + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_TAB, KC_BSLS, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, RGB_VAI, + KC_LCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, RGB_VAD, + KC_LSFT, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, KC_LGUI, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS, MESON, RGB_MOD, + MO(1), KC_SPC, KC_SPC, MO(3) + ), + + [2] = LAYOUT( /* Numbers */ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TAB, KC_BSLS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_VOLU, + KC_LCTL, 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_VOLD, + KC_LSFT, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, KC_LGUI, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_MPRV, KC_MNXT, KC_MPLY, + MO(3), KC_SPC, KC_SPC, MO(2) + ), + + [3] = LAYOUT( /* Reset, other functions if you want */ + 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, 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 MESON: + if (record->event.pressed) { + // when keycode MESON is pressed + SEND_STRING("Meson macro working"); + } else { + // when keycode MESON is released + } + break; + } + return true; +} + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +void led_set_user(uint8_t usb_led) { + +} diff --git a/keyboards/meson/keymaps/default/readme.md b/keyboards/meson/keymaps/default/readme.md new file mode 100644 index 00000000000..04d94252beb --- /dev/null +++ b/keyboards/meson/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for meson diff --git a/keyboards/meson/meson.c b/keyboards/meson/meson.c new file mode 100644 index 00000000000..9dc6f6a2e66 --- /dev/null +++ b/keyboards/meson/meson.c @@ -0,0 +1,51 @@ +/* Copyright 2019 Luciano M + * + * 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 . + */ +#include "meson.h" + +// Optional override functions below. +// You can leave any or all of these undefined. +// These are only required if you want to perform custom actions. + +/* + +void matrix_init_kb(void) { + // put your keyboard start-up code here + // runs once when the firmware starts up + + matrix_init_user(); +} + +void matrix_scan_kb(void) { + // put your looping keyboard code here + // runs every cycle (a lot) + + matrix_scan_user(); +} + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + // put your per-action keyboard code here + // runs for every action, just before processing by the firmware + + return process_record_user(keycode, record); +} + +void led_set_kb(uint8_t usb_led) { + // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here + + led_set_user(usb_led); +} + +*/ diff --git a/keyboards/meson/meson.h b/keyboards/meson/meson.h new file mode 100644 index 00000000000..5344d5410c1 --- /dev/null +++ b/keyboards/meson/meson.h @@ -0,0 +1,56 @@ +/* Copyright 2019 Luciano M + * + * 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 . + */ + +#pragma once +#include "quantum.h" + +#define ___ KC_NO + +#define LAYOUT( \ + L00, L01, L02, L03, L04, L05, L06, R06, R05, R04, R03, R02, R01, R00, \ + L10, L11, L12, L13, L14, L15, L16, R16, R15, R14, R13, R12, R11, R10, \ + L20, L21, L22, L23, L24, L25, L26, R26, R25, R24, R23, R22, R21, R20, \ + L30, L31, R31, R30 \ +) \ +{ \ + { L00, L01, L02, L03, L04, L05, L06}, \ + { L10, L11, L12, L13, L14, L15, L16}, \ + { L20, L21, L22, L23, L24, L25, L26}, \ + { ___, ___, ___, ___, L30, L31, ___}, \ + { R00, R01, R02, R03, R04, R05, R06}, \ + { R10, R11, R12, R13, R14, R15, R16}, \ + { R20, R21, R22, R23, R24, R25, R26}, \ + { ___, ___, ___, ___, R30, R31, ___}, \ +} + +// 2u SPACEBAR LAYOUT, DON'T FORGET TO CHANGE NAME OF LAYOUTS IN KEYMAP.C + +#define LAYOUT_2u( \ + L00, L01, L02, L03, L04, L05, L06, R06, R05, R04, R03, R02, R01, R00, \ + L10, L11, L12, L13, L14, L15, L16, R16, R15, R14, R13, R12, R11, R10, \ + L20, L21, L22, L23, L24, L25, L26, R26, R25, R24, R23, R22, R21, R20, \ + L30, R30 \ +) \ +{ \ + { L00, L01, L02, L03, L04, L05, L06}, \ + { L10, L11, L12, L13, L14, L15, L16}, \ + { L20, L21, L22, L23, L24, L25, L26}, \ + { ___, ___, ___, ___, L30, ___, ___},\ + { R00, R01, R02, R03, R04, R05, R06}, \ + { R10, R11, R12, R13, R14, R15, R16}, \ + { R20, R21, R22, R23, R24, R25, R26}, \ + { ___, ___, ___, ___, R30, ___, ___},\ +} diff --git a/keyboards/meson/readme.md b/keyboards/meson/readme.md new file mode 100644 index 00000000000..3824690c121 --- /dev/null +++ b/keyboards/meson/readme.md @@ -0,0 +1,13 @@ +# meson + +A 3x14 split keyboard with two thumb keys on each half. Supports MX, Alps, and Choc reversible. + +Keyboard Maintainer: [PyroL](https://github.com/PyrooL) +Hardware Supported: Meson PCBs, Pro Micro +Hardware Availability: [open source at PyroL's Github](https://github.com/PyrooL/Meson) + +Make example for this keyboard (after setting up your build environment): + + make meson: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). diff --git a/keyboards/meson/rules.mk b/keyboards/meson/rules.mk new file mode 100644 index 00000000000..4b585e8291a --- /dev/null +++ b/keyboards/meson/rules.mk @@ -0,0 +1,81 @@ +# MCU name +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Interrupt driven control endpoint task(+60) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + + +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# atmega32a bootloadHID +BOOTLOADER = caterina + + +# If you don't know the bootloader type, then you can specify the +# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +# OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Build Options +# change yes to no to disable +# +SPLIT_KEYBOARD = yes +BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = no # Console for debug(+400) +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 = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default +RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow +MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config) +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE = no # Audio output on port C6 +FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches +HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) From ed6588156536a268ca088b5bbc0191eb3cc36054 Mon Sep 17 00:00:00 2001 From: George Petri Date: Sun, 11 Aug 2019 02:08:53 +0300 Subject: [PATCH 14/61] update arrows on lower layer (#6517) --- keyboards/keebio/nyquist/keymaps/georgepetri/keymap.c | 4 ++-- keyboards/keebio/nyquist/keymaps/georgepetri/readme.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri/keymap.c b/keyboards/keebio/nyquist/keymaps/georgepetri/keymap.c index 6564e2a7f40..6b427e06d57 100644 --- a/keyboards/keebio/nyquist/keymaps/georgepetri/keymap.c +++ b/keyboards/keebio/nyquist/keymaps/georgepetri/keymap.c @@ -34,9 +34,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ _______, 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_F11 , KC_F12 , _______, _______, _______, _______, KC_MINS, KC_EQL , KC_LBRC, KC_RBRC, KC_BSLS, //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ - _______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL , KC_LBRC, KC_RBRC, KC_BSLS, + _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, _______, //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ _______, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_PGUP, KC_HOME, KC_END , _______, //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri/readme.md b/keyboards/keebio/nyquist/keymaps/georgepetri/readme.md index a773c989472..a659905f8f9 100644 --- a/keyboards/keebio/nyquist/keymaps/georgepetri/readme.md +++ b/keyboards/keebio/nyquist/keymaps/georgepetri/readme.md @@ -26,9 +26,9 @@ Features a dedicated navigation layer on rise and current layer status on rgb un ┌──────┬──────┬──────┬──────┬──────┬──────┐ ┌──────┬──────┬──────┬──────┬──────┬──────┐ │ │ F1 │ F2 │ F3 │ F4 │ F5 │ │ F6 │ F7 │ F8 │ F9 │ F10 │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤ -│ │ F11 │ F12 │ │ │ │ │ │ │ │ │ │ │ +│ │ F11 │ F12 │ │ │ │ │ │ MINS│ EQL │ LBRC│ RBRC│ BSLS │ ├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤ -│ │ │ │ │ │ │ │ │ MINS│ EQL │ LBRC│ RBRC│ BSLS │ +│ │ │ │ │ │ │ │ LEFT │ DOWN │ UP │ RGHT │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │ │ │ │ │ │ │ PGDN│ PGUP │ HOME│ END │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤ From 38ad0d2673c29b639c11003b495e10a9dad1f499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8F=E3=81=BE=E3=81=8A=E5=B7=A5=E6=88=BF?= <52371962+kumaokobo@users.noreply.github.com> Date: Tue, 13 Aug 2019 11:56:25 +0900 Subject: [PATCH 15/61] Modified imcomplete keymap for kudox jis. (#6524) --- keyboards/kudox/keymaps/jis/keymap.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/keyboards/kudox/keymaps/jis/keymap.c b/keyboards/kudox/keymaps/jis/keymap.c index c8305dd9f09..5de27ff8d42 100644 --- a/keyboards/kudox/keymaps/jis/keymap.c +++ b/keyboards/kudox/keymaps/jis/keymap.c @@ -1,4 +1,5 @@ #include QMK_KEYBOARD_H +#include"keymap_jp.h" // Each layer gets a name for readability, which is then used in the keymap matrix below. // The underscores don't mean anything - you can have a layer called STUFF or any other name. @@ -21,23 +22,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ KC_GRV ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 , KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_BSPC , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ - KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_L2SYM, KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_AT ,KC_BSLS , + KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_L2SYM, KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,JP_AT ,JP_COLN , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤ KC_LCTL ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G , KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_ENT , //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B , KC_SLSH ,KC_N ,KC_M ,KC_MINS ,KC_UP ,SYM_L , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤ - KC_ALES ,KC_LGUI ,KC_LALT ,KC_ENT ,KC_LANG2,KC_SPC ,KC_SPC , KC_COMM ,KC_DOT ,KC_L1SYM,KC_LEFT ,KC_DOWN ,KC_RGHT ,KC_COLN + KC_ALES ,KC_LGUI ,KC_LALT ,KC_ENT ,KC_LANG2,KC_SPC ,KC_SPC , KC_COMM ,KC_DOT ,KC_L1SYM,KC_LEFT ,KC_DOWN ,KC_RGHT ,JP_BSLS //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘ ), [_SYMB] = LAYOUT( //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ - KC_ESC ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , XXXXXXX ,KC_CIRC ,KC_JYEN ,KC_TILD ,KC_PIPE ,KC_DEL , + KC_ESC ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , XXXXXXX ,JP_CIRC ,JP_YEN ,JP_TILD ,JP_PIPE ,KC_DEL , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ - _______ ,KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ , KC_LT ,KC_GT ,KC_LBRC ,KC_RBRC ,KC_LCBR ,KC_RCBR ,XXXXXXX , + _______ ,KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ , KC_LT ,KC_GT ,JP_LBRC ,JP_RBRC ,JP_LCBR ,JP_RCBR ,XXXXXXX , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤ - _______ ,KC_F11 ,KC_F12 ,XXXXXXX ,XXXXXXX ,XXXXXXX , XXXXXXX ,KC_PLUS ,KC_ASTR ,KC_SCLN ,KC_COLN ,_______ , + _______ ,KC_F11 ,KC_F12 ,XXXXXXX ,XXXXXXX ,XXXXXXX , XXXXXXX ,JP_PLUS ,JP_ASTR ,KC_SCLN ,JP_COLN ,_______ , //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ _______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , _______ ,XXXXXXX ,XXXXXXX ,_______ ,KC_VOLU ,_______ , //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤ From 576b138c6e1e1835acae6cf15dba07f3813db25d Mon Sep 17 00:00:00 2001 From: Jarred Steenvoorden Date: Tue, 13 Aug 2019 12:57:00 +1000 Subject: [PATCH 16/61] Add romac keymap (#6523) --- keyboards/romac/keymaps/jarred/keymap.c | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 keyboards/romac/keymaps/jarred/keymap.c diff --git a/keyboards/romac/keymaps/jarred/keymap.c b/keyboards/romac/keymaps/jarred/keymap.c new file mode 100644 index 00000000000..472e99004f0 --- /dev/null +++ b/keyboards/romac/keymaps/jarred/keymap.c @@ -0,0 +1,37 @@ +/* Copyright 2019 Jarred Steenvoorden + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +#define _BASE 0 +#define _FN1 1 + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_BASE] = LAYOUT( + KC_7, KC_8, KC_9, \ + KC_4, KC_5, KC_6, \ + KC_1, KC_2, KC_3, \ + LT(_FN1, KC_0), KC_ENT, KC_DOT \ + ), + + [_FN1] = LAYOUT( + KC_HOME, KC_UP , KC_PGUP , \ + KC_LEFT, KC_DOWN, KC_RIGHT, \ + KC_END , KC_BSPC, KC_PGDN , \ + KC_TRNS, XXXXXXX, KC_DEL \ + ) +}; From d8d2a096742f611e3ade527e7224e8281867c563 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 13 Aug 2019 18:23:14 +0100 Subject: [PATCH 17/61] Fix LT() crashing some ARM keyboards (#6529) --- tmk_core/common/wait.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h index a77840bcef9..9aed372b7f2 100644 --- a/tmk_core/common/wait.h +++ b/tmk_core/common/wait.h @@ -13,8 +13,8 @@ extern "C" { # define wait_us(us) _delay_us(us) #elif defined PROTOCOL_CHIBIOS # include "ch.h" -# define wait_ms(ms) chThdSleepMilliseconds(ms) -# define wait_us(us) chThdSleepMicroseconds(us) +# define wait_ms(ms) do { if (ms != 0) { chThdSleepMilliseconds(ms); } else { chThdSleepMicroseconds(1); } } while (0) +# define wait_us(us) do { if (us != 0) { chThdSleepMicroseconds(us); } else { chThdSleepMicroseconds(1); } } while (0) #elif defined PROTOCOL_ARM_ATSAM # include "clks.h" # define wait_ms(ms) CLK_delay_ms(ms) From 0ec0d29e9f4d83af724d69efbaefeece57faddd9 Mon Sep 17 00:00:00 2001 From: Seth Barberee Date: Tue, 13 Aug 2019 12:25:51 -0500 Subject: [PATCH 18/61] [Keymap] Adding my userspace and keymaps (#6496) * add Userspace and keymaps * Adding keymaps for zeal60 and iris * Created my own tap dance that toggles RGB Mode based on whether I toggled caps lock or not * parent 578ed42a7f8f986147cad040d50d4ae1d24a32e2 author Seth Barberee 1565065903 -0500 committer Seth Barberee 1565065903 -0500 move to userspace add zeal60 * update based on review * move userspace to github name --- .../keebio/iris/keymaps/sethBarberee/config.h | 60 ++++++ .../keebio/iris/keymaps/sethBarberee/keymap.c | 179 ++++++++++++++++++ .../keebio/iris/keymaps/sethBarberee/rules.mk | 8 + .../zeal60/keymaps/sethBarberee/config.h | 37 ++++ .../zeal60/keymaps/sethBarberee/keymap.c | 46 +++++ .../zeal60/keymaps/sethBarberee/rules.mk | 1 + users/sethBarberee/config.h | 8 + users/sethBarberee/readme.md | 6 + users/sethBarberee/rules.mk | 1 + users/sethBarberee/sethBarberee.c | 45 +++++ users/sethBarberee/sethBarberee.h | 20 ++ 11 files changed, 411 insertions(+) create mode 100644 keyboards/keebio/iris/keymaps/sethBarberee/config.h create mode 100644 keyboards/keebio/iris/keymaps/sethBarberee/keymap.c create mode 100644 keyboards/keebio/iris/keymaps/sethBarberee/rules.mk create mode 100644 keyboards/wilba_tech/zeal60/keymaps/sethBarberee/config.h create mode 100644 keyboards/wilba_tech/zeal60/keymaps/sethBarberee/keymap.c create mode 100644 keyboards/wilba_tech/zeal60/keymaps/sethBarberee/rules.mk create mode 100644 users/sethBarberee/config.h create mode 100644 users/sethBarberee/readme.md create mode 100644 users/sethBarberee/rules.mk create mode 100644 users/sethBarberee/sethBarberee.c create mode 100644 users/sethBarberee/sethBarberee.h diff --git a/keyboards/keebio/iris/keymaps/sethBarberee/config.h b/keyboards/keebio/iris/keymaps/sethBarberee/config.h new file mode 100644 index 00000000000..fd5bda86663 --- /dev/null +++ b/keyboards/keebio/iris/keymaps/sethBarberee/config.h @@ -0,0 +1,60 @@ +/* +Copyright 2017 Danny Nguyen + +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 . +*/ + +#pragma once + +/* Use I2C or Serial, not both */ + +#define USE_SERIAL +//#define USE_I2C + +/* Select hand configuration */ + +//#define MASTER_LEFT +//#define MASTER_RIGHT +#define EE_HANDS + +#undef RGBLED_NUM +#define RGBLED_NUM 8 +#define RGBLIGHT_ANIMATIONS +#define RGBLIGHT_SLEEP +#define RGBLIGHT_HUE_STEP 8 +#define RGBLIGHT_SAT_STEP 8 +#define RGBLIGHT_VAL_STEP 8 +#define RGBLED_SPLIT { RGBLED_NUM, 0} // defined to sync animations + +#define FORCE_NKRO // force NKRO on by default + +#undef TAPPING_TERM +#define TAPPING_TERM 200 + + +#if !defined(NO_DEBUG) && !defined(CONSOLE_ENABLE) +#define NO_DEBUG +#endif // !NO_DEBUG +#if !defined(NO_PRINT) && !defined(CONSOLE_ENABLE) +#define NO_PRINT +#endif // !NO_PRINT + +#define NO_MUSIC_MODE + +// Override caps lock indication from my userspace +//#undef NORMAL_MODE +//#define NORMAL_MODE 1 + +//#undef CAPS_LOCK_MODE +//#define CAPS_LOCK_MODE 28 diff --git a/keyboards/keebio/iris/keymaps/sethBarberee/keymap.c b/keyboards/keebio/iris/keymaps/sethBarberee/keymap.c new file mode 100644 index 00000000000..1e39c33d180 --- /dev/null +++ b/keyboards/keebio/iris/keymaps/sethBarberee/keymap.c @@ -0,0 +1,179 @@ +#include QMK_KEYBOARD_H +#include "sethBarberee.h" + +extern backlight_config_t backlight_config; + +enum layers { + _QWERTY, + _LOWER, + _RAISE, + _ADJUST +}; + +enum custom_keycodes { + QWERTY = SAFE_RANGE, + LOWER, + RAISE, + ADJUST, +}; + +#define KC_ KC_TRNS + +#define KC_LOWR LOWER +#define KC_RASE RAISE +#define KC_RST RESET +#define KC_BL_S BL_STEP +#define KC_RTOG RGB_TOG +#define KC_RMOD RGB_MOD +#define KC_RHUI RGB_HUI +#define KC_RHUD RGB_HUD +#define KC_RSAI RGB_SAI +#define KC_RSAD RGB_SAD +#define KC_RVAI RGB_VAI +#define KC_RVAD RGB_VAD +#define KC_VK VLK_TOG + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_QWERTY] = LAYOUT_kc( + //,----+----+----+----+----+----. ,----+----+----+----+----+----. + ECAP, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,MINS, + //|----+----+----+----+----+----| |----+----+----+----+----+----| + TAB , Q , W , E , R , T , Y , U , I , O , P ,DEL , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + LSFT, A , S , D , F , G , H , J , K , L ,SCLN,QUOT, + //|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----| + LCTL, Z , X , C , V , B , SPC, RASE, N , M ,COMM,DOT ,SLSH,RSFT, + //`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----' + LGUI,LOWR, SPC, BSPC ,ENT,LALT + // `----+----+----' `----+----+----' + ), + + [_LOWER] = LAYOUT_kc( + //,----+----+----+----+----+----. ,----+----+----+----+----+----. + TILD,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,BSPC, + //|----+----+----+----+----+----| |----+----+----+----+----+----| + RST , , , UP , , , GRV , P7 , P8 , P9 , , , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + DEL , ,LEFT,DOWN,RGHT,LBRC, RBRC, P4 , P5 , P6 ,PLUS,PIPE, + //|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----| + BL_S, , , , ,LCBR,LPRN, RPRN,RCBR, P1 , P2 , P3 ,MINS, , + //`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----' + , ,LPRN , DEL , , P0 + // `----+----+----' `----+----+----' + ), + + [_RAISE] = LAYOUT_kc( + //,----+----+----+----+----+----. ,----+----+----+----+----+----. + F12 , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + , , , , , , , , , , , , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + ,MPRV,MNXT,VOLU,PGUP,UNDS, EQL ,HOME, , , ,BSLS, + //|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----| + MUTE,MSTP,MPLY,VOLD,PGDN,MINS, , ,PLUS,END , , , , , + //`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----' + , , , , , + // `----+----+----' `----+----+----' + ), + + [_ADJUST] = LAYOUT_kc( + //,----+----+----+----+----+----. ,----+----+----+----+----+----. + , , , , , , , , , , , , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + RTOG,RMOD,RHUI,RSAI,RVAI, , , , , , , , + //|----+----+----+----+----+----| |----+----+----+----+----+----| + VK, ,RHUD,RSAD,RVAD, , , , , , , , + //|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----| + BL_S,RST , , , , , , , , , , , , , + //`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----' + , , , , , + // `----+----+----' `----+----+----' + ) + +}; + +void keyboard_pre_init_user(void) { + // Make sure the red LEDs don't light + setPinOutput(D5); + writePinHigh(D5); + + setPinOutput(B0); + writePinHigh(B0); +} + +void keyboard_post_init_user(void){ + rgblight_enable_noeeprom(); // enable the RGBs + rgblight_sethsv_noeeprom_red(); // set to red + rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // set to breathing +} + +void suspend_power_down_user(void){ + backlight_config.enable = false; // disable LED backlight +} + +void suspend_wakeup_init_user(void){ + backlight_config.enable = true; // enable LED backlight +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case RAISE: + if (record->event.pressed) { + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case ADJUST: + if (record->event.pressed) { + layer_on(_ADJUST); + } else { + layer_off(_ADJUST); + } + return false; + break; + } + return true; +} + +uint32_t layer_state_set_user(uint32_t state){ + switch(biton32(state)) { + case _QWERTY: + rgblight_sethsv_noeeprom(HSV_RED); + break; + case _LOWER: + rgblight_sethsv_noeeprom(HSV_GREEN); + break; + case _RAISE: + rgblight_sethsv_noeeprom(HSV_BLUE); + break; + case _ADJUST: + rgblight_sethsv_noeeprom(HSV_ORANGE); + break; + default: + rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_GRADIENT + 3); + break; + + } + return state; +} diff --git a/keyboards/keebio/iris/keymaps/sethBarberee/rules.mk b/keyboards/keebio/iris/keymaps/sethBarberee/rules.mk new file mode 100644 index 00000000000..d7bc1927dcd --- /dev/null +++ b/keyboards/keebio/iris/keymaps/sethBarberee/rules.mk @@ -0,0 +1,8 @@ +BOOTMAGIC_ENABLE = no +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +BACKLIGHT_ENABLE = yes # Enable my Red LEDS +RGBLIGHT_ENABLE = yes # Enable my RGBS +VELOCIKEY_ENABLE = yes # I like RGB +TAP_DANCE_ENABLE = yes # fancy fancy Caps +LINK_TIME_OPTIMIZATION = yes # Enable link time optimization diff --git a/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/config.h b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/config.h new file mode 100644 index 00000000000..68c4b9ed334 --- /dev/null +++ b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/config.h @@ -0,0 +1,37 @@ +#pragma once + +/* enable/disable LEDs based on layout */ +#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE +#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1 + +#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT +#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0 + +#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT +#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1 + +#undef RGB_BACKLIGHT_USE_7U_SPACEBAR +#define RGB_BACKLIGHT_USE_7U_SPACEBAR 1 + +#undef RGB_BACKLIGHT_USE_ISO_ENTER +#define RGB_BACKLIGHT_USE_ISO_ENTER 0 + +#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS +#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0 + +// disable backlight when USB suspended (PC sleep/hibernate/shutdown) +// +#undef RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED +#define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 1 + +#undef RGB_BACKLIGHT_EFFECT +#define RGB_BACKLIGHT_EFFECT 5 + +#undef RGB_BACKLIGHT_CAPS_LOCK_INDICATOR +#undef RGB_BACKLIGHT_LAYER_2_INDICATOR +#undef RGB_BACKLIGHT_LAYER_3_INDICATOR + +#define RGB_BACKLIGHT_CAPS_LOCK_INDICATOR { .color = { .h = 0, .s= 255}, .index = 254} +#define RGB_BACKLIGHT_LAYER_2_INDICATOR { .color = { .h = 150, .s = 255 }, .index = 60-1 } //blue +#define RGB_BACKLIGHT_LAYER_3_INDICATOR { .color = { .h = 100, .s = 255 }, .index = 60-1 } //blue + diff --git a/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/keymap.c b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/keymap.c new file mode 100644 index 00000000000..ea36880e297 --- /dev/null +++ b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/keymap.c @@ -0,0 +1,46 @@ +// ANSI split backspace/right shift layout for Zeal60 +#include QMK_KEYBOARD_H + +#define KC_CAFN LT(1,KC_CAPS) +#define KC_ENFN LT(3,KC_ENT) +#define KC_RSUP RSFT_T(KC_UP) +#define KC_RGLT RALT_T(KC_LEFT) +#define KC_RGDN RGUI_T(KC_DOWN) +#define KC_RCRT RCTL_T(KC_RIGHT) + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +// Default layer +[0] = LAYOUT_60_ansi_split_bs_rshift( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, + 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_CAFN, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENFN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSUP, FN_MO13, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_RGLT, KC_RGDN, KC_RCRT), + +// Fn1 Layer +[1] = LAYOUT_60_ansi_split_bs_rshift( + 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_INS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_UP, KC_END, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, KC_PGUP, KC_LEFT, KC_DOWN, KC_RGHT, KC_DEL, KC_INS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGDN, KC_TRNS, KC_TRNS, KC_TRNS, KC_DOWN, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), + +// Fn2 Layer +[2] = LAYOUT_60_ansi_split_bs_rshift( + 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, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), + +// Fn3 Layer (zeal60 Configuration) +[3] = LAYOUT_60_ansi_split_bs_rshift( + RESET, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, 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), + +}; diff --git a/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/rules.mk b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/rules.mk new file mode 100644 index 00000000000..fcf3767e166 --- /dev/null +++ b/keyboards/wilba_tech/zeal60/keymaps/sethBarberee/rules.mk @@ -0,0 +1 @@ +BOOTMAGIC_ENABLE = lite diff --git a/users/sethBarberee/config.h b/users/sethBarberee/config.h new file mode 100644 index 00000000000..a849ac0e775 --- /dev/null +++ b/users/sethBarberee/config.h @@ -0,0 +1,8 @@ +#ifdef RGBLIGHT_ENABLE +# ifndef CAPS_LOCK_MODE +# define CAPS_LOCK_MODE 1 +# endif +# ifndef NORMAL_MODE +# define NORMAL_MODE 4 +# endif +#endif diff --git a/users/sethBarberee/readme.md b/users/sethBarberee/readme.md new file mode 100644 index 00000000000..75d892cb855 --- /dev/null +++ b/users/sethBarberee/readme.md @@ -0,0 +1,6 @@ +# seth's userspace + +## Features +* Escape/Caps Lock tap dance (1 for Escape / 2 for Caps Lock) + * RGB Mode indication for Caps Lock + * Solid Mode for Caps On diff --git a/users/sethBarberee/rules.mk b/users/sethBarberee/rules.mk new file mode 100644 index 00000000000..d8aef605235 --- /dev/null +++ b/users/sethBarberee/rules.mk @@ -0,0 +1 @@ +SRC += sethBarberee.c diff --git a/users/sethBarberee/sethBarberee.c b/users/sethBarberee/sethBarberee.c new file mode 100644 index 00000000000..10f78f63b50 --- /dev/null +++ b/users/sethBarberee/sethBarberee.c @@ -0,0 +1,45 @@ +#include "sethBarberee.h" +#ifdef RGBLIGHT_ENABLE +#ifdef TAP_DANCE_ENABLE + +// Initialize it now +tap caps_status = { + .toggled = false, + .toggle_mode = CAPS_LOCK_MODE, + .normal_mode = NORMAL_MODE +}; + +void dance_ecap_finished (qk_tap_dance_state_t *state, void *user_data){ + if(state->count == 1){ + register_code(KC_ESC); + } else { + register_code(KC_CAPS); + if(!caps_status.toggled){ + // Toggling caps so indicate + caps_status.toggled = true; + rgblight_mode_noeeprom(caps_status.toggle_mode); + } else { + // Turning off so return to normal mode + caps_status.toggled = false; + rgblight_mode_noeeprom(caps_status.normal_mode); + } + } +} + +void dance_ecap_reset (qk_tap_dance_state_t *state, void *user_data){ + if(state->count == 1){ + unregister_code(KC_ESC); + } else { + unregister_code(KC_CAPS); + } +} + +//Tap Dance Definitions +qk_tap_dance_action_t tap_dance_actions[] = { + //Tap once for Esc, twice for Caps Lock + [TD_ECAP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_ecap_finished, dance_ecap_reset), +// Other declarations would go here, separated by commas, if you have them +}; + +#endif +#endif diff --git a/users/sethBarberee/sethBarberee.h b/users/sethBarberee/sethBarberee.h new file mode 100644 index 00000000000..23774ba4eb0 --- /dev/null +++ b/users/sethBarberee/sethBarberee.h @@ -0,0 +1,20 @@ +#ifndef USERSPACE +#define USERSPACE + +#include "quantum.h" + +#ifdef TAP_DANCE_ENABLE // only enable for tap dances + enum { + TD_ECAP = 0, + }; + + #define KC_ECAP TD(TD_ECAP) + + typedef struct { + bool toggled; // store whether we have toggled caps lock + int toggle_mode; // idk why but maybe do something with this.. + int normal_mode; + } tap; +#endif + +#endif From 50045624411df31968f7e2d2996ad342d689fe4f Mon Sep 17 00:00:00 2001 From: John M Daly Date: Tue, 13 Aug 2019 13:26:54 -0400 Subject: [PATCH 19/61] [Keyboard] Add: Initial steamvan firmware code (#6501) * Add: Initial steamvan firmware code * Apply suggestions from code review Co-Authored-By: fauxpark * Update: Remove old macro commands, per reviewer comments * Apply suggestions from code review Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update: Remove redundant backlight struct * Update: Replace preprocessor defines with enum --- keyboards/handwired/steamvan/info.json | 24 + .../steamvan/keymaps/default/config.h | 3 + .../steamvan/keymaps/default/keymap.c | 93 ++++ .../steamvan/keymaps/default/readme.md | 1 + .../steamvan/keymaps/jmdaly/config.h | 3 + .../steamvan/keymaps/jmdaly/keymap.c | 80 +++ .../steamvan/keymaps/jmdaly/readme.md | 1 + keyboards/handwired/steamvan/readme.md | 24 + keyboards/handwired/steamvan/rev1/chconf.h | 520 ++++++++++++++++++ keyboards/handwired/steamvan/rev1/config.h | 70 +++ keyboards/handwired/steamvan/rev1/halconf.h | 388 +++++++++++++ keyboards/handwired/steamvan/rev1/led.c | 242 ++++++++ .../handwired/steamvan/rev1/led_custom.h | 22 + keyboards/handwired/steamvan/rev1/mcuconf.h | 257 +++++++++ keyboards/handwired/steamvan/rev1/rev1.c | 36 ++ keyboards/handwired/steamvan/rev1/rev1.h | 90 +++ keyboards/handwired/steamvan/rev1/rules.mk | 58 ++ 17 files changed, 1912 insertions(+) create mode 100644 keyboards/handwired/steamvan/info.json create mode 100644 keyboards/handwired/steamvan/keymaps/default/config.h create mode 100644 keyboards/handwired/steamvan/keymaps/default/keymap.c create mode 100644 keyboards/handwired/steamvan/keymaps/default/readme.md create mode 100644 keyboards/handwired/steamvan/keymaps/jmdaly/config.h create mode 100644 keyboards/handwired/steamvan/keymaps/jmdaly/keymap.c create mode 100644 keyboards/handwired/steamvan/keymaps/jmdaly/readme.md create mode 100644 keyboards/handwired/steamvan/readme.md create mode 100644 keyboards/handwired/steamvan/rev1/chconf.h create mode 100644 keyboards/handwired/steamvan/rev1/config.h create mode 100644 keyboards/handwired/steamvan/rev1/halconf.h create mode 100644 keyboards/handwired/steamvan/rev1/led.c create mode 100644 keyboards/handwired/steamvan/rev1/led_custom.h create mode 100644 keyboards/handwired/steamvan/rev1/mcuconf.h create mode 100644 keyboards/handwired/steamvan/rev1/rev1.c create mode 100644 keyboards/handwired/steamvan/rev1/rev1.h create mode 100644 keyboards/handwired/steamvan/rev1/rules.mk diff --git a/keyboards/handwired/steamvan/info.json b/keyboards/handwired/steamvan/info.json new file mode 100644 index 00000000000..1a057e5ca29 --- /dev/null +++ b/keyboards/handwired/steamvan/info.json @@ -0,0 +1,24 @@ +{ + "keyboard_name": "steamvan", + "url": "", + "maintainer": "qmk", + "width": 12.75, + "height": 4, + "layouts": { + "LAYOUT_standard": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"|", "x":11, "y":0, "w":1.75}, {"label":"Caps Lock", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"\"", "x":11.25, "y":1, "w":1.5}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"x":11.75, "y":2}, {"label":"Ctrl", "x":0, "y":3, "w":1.25}, {"label":"Win", "x":1.25, "y":3, "w":1.5}, {"label":"Alt", "x":2.75, "y":3, "w":1.25}, {"x":4, "y":3, "w":2.25}, {"x":6.25, "y":3, "w":2}, {"label":"Alt", "x":8.25, "y":3, "w":1.25}, {"label":"Win", "x":9.5, "y":3, "w":1.5}, {"label":"Menu", "x":11, "y":3, "w":1.75}] + }, + + "LAYOUT_arrow": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"|", "x":11, "y":0, "w":1.75}, {"label":"Caps Lock", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"\"", "x":11.25, "y":1, "w":1.5}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"x":11.75, "y":2}, {"label":"Ctrl", "x":0, "y":3, "w":1.25}, {"label":"Win", "x":1.25, "y":3, "w":1.5}, {"label":"Alt", "x":2.75, "y":3, "w":1.25}, {"x":4, "y":3, "w":2.25}, {"x":6.25, "y":3, "w":2}, {"x":8.25, "y":3, "w":1.5}, {"label":"Alt", "x":9.75, "y":3}, {"label":"Win", "x":10.75, "y":3}, {"label":"Menu", "x":11.75, "y":3}] + }, + + "LAYOUT_command": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"|", "x":11, "y":0, "w":1.75}, {"label":"Caps Lock", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"\"", "x":11.25, "y":1, "w":1.5}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"x":11.75, "y":2}, {"label":"Ctrl", "x":0, "y":3}, {"label":"Win", "x":1, "y":3}, {"label":"Alt", "x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3, "w":2.25}, {"x":6.25, "y":3, "w":2}, {"x":8.25, "y":3, "w":1.5}, {"label":"Alt", "x":9.75, "y":3, "w":1.5}, {"label":"Win", "x":11.25, "y":3, "w":1.5}] + }, + + "LAYOUT_arrow_command": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"|", "x":11, "y":0, "w":1.75}, {"label":"Caps Lock", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"\"", "x":11.25, "y":1, "w":1.5}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"x":11.75, "y":2}, {"label":"Ctrl", "x":0, "y":3}, {"label":"Win", "x":1, "y":3}, {"label":"Alt", "x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3, "w":2.25}, {"x":6.25, "y":3, "w":2}, {"x":8.25, "y":3, "w":1.5}, {"label":"Alt", "x":9.75, "y":3}, {"label":"Win", "x":10.75, "y":3}, {"label":"Menu", "x":11.75, "y":3}] + } + } +} diff --git a/keyboards/handwired/steamvan/keymaps/default/config.h b/keyboards/handwired/steamvan/keymaps/default/config.h new file mode 100644 index 00000000000..271f48d0011 --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/default/config.h @@ -0,0 +1,3 @@ +#pragma once + +// place overrides here diff --git a/keyboards/handwired/steamvan/keymaps/default/keymap.c b/keyboards/handwired/steamvan/keymaps/default/keymap.c new file mode 100644 index 00000000000..e796f094092 --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/default/keymap.c @@ -0,0 +1,93 @@ +/* Copyright 2019 John M Daly + * + * 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 . + */ +#include QMK_KEYBOARD_H + +// This file is based on the default keyman the the MiniVan. + + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. + +enum layer_names { + _QW, + _DV, + _CM, + _L1, + _L2, + _L3, +}; + +// Curly braces have their own keys. These are defined to make them not mess up +// the grid in layer 2. +#define L_CURBR LSFT(KC_LBRC) +#define R_CURBR LSFT(KC_RBRC) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_QW] = LAYOUT_standard( /* Qwerty */ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + MO(_L1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, MO(_L1), + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MO(_L2), + KC_LCTL, MO(_L2), KC_LGUI, KC_ENT, KC_SPC, KC_RALT, KC_ESC, TG(_L3) + ), + [_DV] = LAYOUT_standard( /* Dvorak */ + KC_TAB, KC_SLSH, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, + MO(_L1), KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, MO(_L1), + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, MO(_L2), + KC_LCTL, MO(_L2), KC_LGUI, KC_ENT, KC_SPC, KC_RALT, KC_ESC, TG(_L3) + ), + [_CM] = LAYOUT_standard( /* Colemak */ + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + MO(_L1), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, MO(_L1), + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, MO(_L2), + KC_LCTL, MO(_L2), KC_LGUI, KC_ENT, KC_SPC, KC_RALT, KC_ESC, TG(_L3) + ), + [_L1] = LAYOUT_standard( /* LAYER 1 */ + KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, + _______, KC_BSLS, KC_QUOT, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_DOWN, KC_UP, KC_LEFT, KC_RGHT, _______, + _______, KC_ESC, _______, KC_PSCR, _______, _______, _______, KC_MSTP, KC_MPLY, KC_MPRV, KC_MNXT, KC_RSFT, + _______, KC_LGUI, _______, _______, _______, _______, _______, _______ + ), + [_L2] = LAYOUT_standard( /* LAYER 2 */ + _______, DF(_QW), DF(_DV), DF(_CM), _______, _______, _______, KC_7, KC_8, KC_9, KC_0, _______, + KC_ESC, KC_PIPE, KC_DQUO, KC_UNDS, KC_PLUS, L_CURBR, R_CURBR, KC_4, KC_5, KC_6, KC_VOLU, KC_ENT, + _______, _______, _______, _______, _______, _______, KC_0, KC_1, KC_2, KC_3, KC_VOLD, _______, + _______, _______, _______, _______, _______, _______, _______, _______ + ), + [_L3] = LAYOUT_standard( /* LAYER 3 */ + _______, _______, _______, _______, _______, _______, _______, KC_F1, KC_F2, KC_F3, KC_F4, _______, + KC_ESC, _______, _______, _______, _______, _______, _______, KC_F5, KC_F6, KC_F7, KC_F8, _______, + KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_F9, KC_F10, KC_F11, KC_F12, _______, + _______, KC_LSFT, KC_B, KC_SPC, KC_C, _______, _______, _______ + ) +}; + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + return true; +} + +void led_set_user(uint8_t usb_led) { + +} diff --git a/keyboards/handwired/steamvan/keymaps/default/readme.md b/keyboards/handwired/steamvan/keymaps/default/readme.md new file mode 100644 index 00000000000..efc21654823 --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for the SteamVan, based on the MiniVan default layout. diff --git a/keyboards/handwired/steamvan/keymaps/jmdaly/config.h b/keyboards/handwired/steamvan/keymaps/jmdaly/config.h new file mode 100644 index 00000000000..271f48d0011 --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/jmdaly/config.h @@ -0,0 +1,3 @@ +#pragma once + +// place overrides here diff --git a/keyboards/handwired/steamvan/keymaps/jmdaly/keymap.c b/keyboards/handwired/steamvan/keymaps/jmdaly/keymap.c new file mode 100644 index 00000000000..2bc5432712a --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/jmdaly/keymap.c @@ -0,0 +1,80 @@ +/* Copyright 2019 John M Daly + * + * 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 . + */ +#include QMK_KEYBOARD_H + + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. + +enum { + // Layers + _L1, + _L2, + _L3, + _L4, + _L5 +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_L1] = LAYOUT_standard( /* Qwerty */ + LT(_L5, KC_TAB), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + CTL_T(KC_ESC), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, LT(_L2, KC_QUOT), + KC_LSPO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSPC, + MO(_L2), KC_LGUI, MO(_L3), KC_ENT, LT(_L2, KC_SPC), KC_RALT, KC_BSLS, MO(_L4) + ), + [_L2] = LAYOUT_standard( /* LAYER 2 */ + KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, + _______, KC_BSLS, KC_QUOT, KC_MINS, KC_EQL, KC_LBRC, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, + _______, KC_ESC, _______, KC_PSCR, _______, _______, _______, KC_MSTP, KC_LBRC, KC_RBRC, KC_MNXT, _______, + _______, KC_LGUI, _______, _______, _______, _______, _______, MO(_L4) + ), + [_L3] = LAYOUT_standard( /* LAYER 3 */ + KC_MINS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, + KC_EQL, KC_PIPE, KC_TILD, KC_UNDS, KC_PLUS, LSFT(KC_LBRC), LSFT(KC_RBRC), KC_4, KC_5, KC_6, KC_VOLU, KC_INS, + _______, _______, _______, KC_DQUO, _______, _______, KC_0, KC_1, KC_2, KC_3, KC_VOLD, _______, + _______, _______, _______, _______, _______, _______, _______, _______ + ), + [_L4] = LAYOUT_standard( /* LAYER 4 */ + RESET, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_PGUP, _______, + KC_ESC, _______, _______, _______, _______, _______, _______, KC_F5, KC_F6, KC_HOME, KC_END, _______, + KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_F9, KC_F10, KC_PGDN, KC_F12, _______, + _______, KC_LSFT, KC_B, KC_SPC, KC_C, _______, _______, _______ + ), + [_L5] = LAYOUT_standard( /* LAYER 5 */ + _______, LGUI(KC_1), LGUI(KC_2), LGUI(KC_3), LGUI(KC_4), LGUI(KC_5), LGUI(KC_6), LGUI(KC_7), LGUI(KC_8), LGUI(KC_9), LGUI(KC_0), LGUI(KC_MINS), + KC_ESC, _______, _______, _______, _______, _______, _______, KC_F5, KC_F6, KC_HOME, KC_END, _______, + KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_F9, KC_F10, KC_PGDN, KC_F12, _______, + _______, KC_LSFT, KC_B, KC_SPC, KC_C, _______, _______, _______ + ) +}; + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + return true; +} + +void led_set_user(uint8_t usb_led) { + +} diff --git a/keyboards/handwired/steamvan/keymaps/jmdaly/readme.md b/keyboards/handwired/steamvan/keymaps/jmdaly/readme.md new file mode 100644 index 00000000000..5aeae7064f1 --- /dev/null +++ b/keyboards/handwired/steamvan/keymaps/jmdaly/readme.md @@ -0,0 +1 @@ +# jmdaly's keymap for the steamvan diff --git a/keyboards/handwired/steamvan/readme.md b/keyboards/handwired/steamvan/readme.md new file mode 100644 index 00000000000..508d67f2347 --- /dev/null +++ b/keyboards/handwired/steamvan/readme.md @@ -0,0 +1,24 @@ +# SteamVan + +The SteamVan is a 40% PCB that aims to meet the following goals: + +* Switches oriented such that the LEDs are South-facing, for + compatibility with Cherry profile keycaps. +* USB Type-C support in both A to C and C to C configurations. +* QMK support. +* ESD protection circuitry, including data line protection and a + polyfuse on the VCC line. +* Support for per-switch LED backlighting. +* Fits in MiniVan keyboard cases. + +More info on the project, including all of the design files, can be found [here](https://github.com/jmdaly/steamvan). + +Keyboard Maintainer: [jmdaly](https://github.com/jmdaly) +Hardware Supported: SteamVan PCB rev1 +Hardware Availability: Through group buys. + +Make example for this keyboard (after setting up your build environment): + + make handwired/steamvan/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). diff --git a/keyboards/handwired/steamvan/rev1/chconf.h b/keyboards/handwired/steamvan/rev1/chconf.h new file mode 100644 index 00000000000..1d9f12ff1f8 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/chconf.h @@ -0,0 +1,520 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 32 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 100000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 2 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 0 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM TRUE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY TRUE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS TRUE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS FALSE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS FALSE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_BUFFER_SIZE 128 + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK TRUE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS FALSE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/keyboards/handwired/steamvan/rev1/config.h b/keyboards/handwired/steamvan/rev1/config.h new file mode 100644 index 00000000000..f10f42966b4 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/config.h @@ -0,0 +1,70 @@ +/* +Copyright 2019 John M Daly + +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 . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x0000 +#define DEVICE_VER 0x0001 +#define MANUFACTURER John M Daly +#define PRODUCT SteamVan rev1 +#define DESCRIPTION An open hardware forty percent PCB + +/* Address for jumping to bootloader on STM32 chips. */ +/* It is chip dependent, the correct number can be looked up here: + * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf + */ +#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800 + +/* key matrix size */ +#define MATRIX_ROWS 4 +#define MATRIX_COLS 12 + +/* ROWS: Top to bottom, COLS: Left to right +*/ +#define MATRIX_ROW_PINS { A6, A5, A4, A3 } +#define MATRIX_COL_PINS { A9, A8, B15, B14, B13, A10, B9, B6, B5, B4, B3, A15 } +#define UNUSED_PINS + +/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */ +#define DIODE_DIRECTION COL2ROW + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* Backlight configuration + * Backlight LEDs on B8 + */ +#define BACKLIGHT_LEVELS 24 +#define BACKLIGHT_BREATHING +#define BREATHING_PERIOD 6 + +#define RGBLIGHT_ANIMATIONS + +#define RGBLED_NUM 16 +#define RGB_DI_PIN A7 +#define DRIVER_LED_TOTAL RGBLED_NUM + +#define RGB_MATRIX_KEYPRESSES diff --git a/keyboards/handwired/steamvan/rev1/halconf.h b/keyboards/handwired/steamvan/rev1/halconf.h new file mode 100644 index 00000000000..5e5d70219e2 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/halconf.h @@ -0,0 +1,388 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC TRUE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT TRUE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM TRUE +#endif + +/** + * @brief Enables the QSPI subsystem. + */ +#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__) +#define HAL_USE_QSPI FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB TRUE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 1 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/keyboards/handwired/steamvan/rev1/led.c b/keyboards/handwired/steamvan/rev1/led.c new file mode 100644 index 00000000000..1b78fa2f86c --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/led.c @@ -0,0 +1,242 @@ +/* +Copyright 2012 Jun Wako + +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 . +*/ + +#include "hal.h" +#include "led_custom.h" +#include "rev1.h" +#include "printf.h" + +static void breathing_callback(PWMDriver *pwmp); + +static PWMConfig pwmCFG = { + 0xFFFF, /* PWM clock frequency */ + 256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + NULL, /* No Callback */ + { + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* Enable Channel 3 */ + {PWM_OUTPUT_DISABLED, NULL} + }, + 0, /* HW dependent part.*/ + 0 +}; + +static PWMConfig pwmCFG_breathing = { + 0xFFFF, /* 10kHz PWM clock frequency */ + 256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + breathing_callback, /* Breathing Callback */ + { + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* Enable Channel 3 */ + {PWM_OUTPUT_DISABLED, NULL} + }, + 0, /* HW dependent part.*/ + 0 +}; + +// See http://jared.geek.nz/2013/feb/linear-led-pwm +static uint16_t cie_lightness(uint16_t v) { + if (v <= 5243) // if below 8% of max + return v / 9; // same as dividing by 900% + else { + uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare + // to get a useful result with integer division, we shift left in the expression above + // and revert what we've done again after squaring. + y = y * y * y >> 8; + if (y > 0xFFFFUL) // prevent overflow + return 0xFFFFU; + else + return (uint16_t) y; + } +} + + +void backlight_init_ports(void) { + palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(2)); + pwmStart(&PWMD4, &pwmCFG); + if(kb_backlight_config.enable){ + if(kb_backlight_config.breathing){ + breathing_enable(); + } else{ + backlight_set(kb_backlight_config.level); + } + } else { + backlight_set(0); + } +} + +void backlight_set(uint8_t level) { + uint32_t duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / BACKLIGHT_LEVELS)); + if (level == 0) { + // Turn backlight off + // Disable channel 3 on PWM4 + pwmDisableChannel(&PWMD4, 2); + } else { + // Turn backlight on + if(!is_breathing()){ + // Enable channel 3 on PWM4 + pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,duty)); + } + } +} + + +uint8_t backlight_tick = 0; + +void backlight_task(void) { +} + +#define BREATHING_NO_HALT 0 +#define BREATHING_HALT_OFF 1 +#define BREATHING_HALT_ON 2 +#define BREATHING_STEPS 128 + +static uint8_t breathing_period = BREATHING_PERIOD; +static uint8_t breathing_halt = BREATHING_NO_HALT; +static uint16_t breathing_counter = 0; + +bool is_breathing(void) { + return PWMD4.config == &pwmCFG_breathing; +} + +#define breathing_min() do {breathing_counter = 0;} while (0) +#define breathing_max() do {breathing_counter = breathing_period * 256 / 2;} while (0) + + +void breathing_interrupt_enable(void){ + pwmStop(&PWMD4); + pwmStart(&PWMD4, &pwmCFG_breathing); + chSysLockFromISR(); + pwmEnablePeriodicNotification(&PWMD4); + pwmEnableChannelI( + &PWMD4, + 2, + PWM_FRACTION_TO_WIDTH( + &PWMD4, + 0xFFFF, + 0xFFFF + ) + ); + chSysUnlockFromISR(); +} + +void breathing_interrupt_disable(void){ + pwmStop(&PWMD4); + pwmStart(&PWMD4, &pwmCFG); +} + +void breathing_enable(void) +{ + breathing_counter = 0; + breathing_halt = BREATHING_NO_HALT; + breathing_interrupt_enable(); +} + +void breathing_pulse(void) +{ + if (kb_backlight_config.level == 0) + breathing_min(); + else + breathing_max(); + breathing_halt = BREATHING_HALT_ON; + breathing_interrupt_enable(); +} + +void breathing_disable(void) +{ + breathing_interrupt_disable(); + // Restore backlight level + backlight_set(kb_backlight_config.level); +} + +void breathing_self_disable(void) +{ + if (kb_backlight_config.level == 0) + breathing_halt = BREATHING_HALT_OFF; + else + breathing_halt = BREATHING_HALT_ON; +} + +void breathing_toggle(void) { + if (is_breathing()){ + breathing_disable(); + } else { + breathing_enable(); + } +} + +void breathing_period_set(uint8_t value) +{ + if (!value) + value = 1; + breathing_period = value; +} + +void breathing_period_default(void) { + breathing_period_set(BREATHING_PERIOD); +} + +void breathing_period_inc(void) +{ + breathing_period_set(breathing_period+1); +} + +void breathing_period_dec(void) +{ + breathing_period_set(breathing_period-1); +} + +/* To generate breathing curve in python: + * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] + */ +static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// Use this before the cie_lightness function. +static inline uint16_t scale_backlight(uint16_t v) { + return v / BACKLIGHT_LEVELS * kb_backlight_config.level; +} + +static void breathing_callback(PWMDriver *pwmp) +{ + (void)pwmp; + uint16_t interval = (uint16_t) breathing_period * 256 / BREATHING_STEPS; + // resetting after one period to prevent ugly reset at overflow. + breathing_counter = (breathing_counter + 1) % (breathing_period * 256); + uint8_t index = breathing_counter / interval % BREATHING_STEPS; + + if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) || + ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1))) + { + breathing_interrupt_disable(); + } + + uint32_t duty = cie_lightness(scale_backlight(breathing_table[index] * 256)); + + chSysLockFromISR(); + pwmEnableChannelI( + &PWMD4, + 2, + PWM_FRACTION_TO_WIDTH( + &PWMD4, + 0xFFFF, + duty + ) + ); + chSysUnlockFromISR(); +} diff --git a/keyboards/handwired/steamvan/rev1/led_custom.h b/keyboards/handwired/steamvan/rev1/led_custom.h new file mode 100644 index 00000000000..56e723db8f7 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/led_custom.h @@ -0,0 +1,22 @@ +/* +Copyright 2019 John M Daly + +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 . +*/ + +#pragma once + +void backlight_task(void); +void breathing_interrupt_disable(void); +void breathing_interrupt_enable(void); diff --git a/keyboards/handwired/steamvan/rev1/mcuconf.h b/keyboards/handwired/steamvan/rev1/mcuconf.h new file mode 100644 index 00000000000..69bf9185d17 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/mcuconf.h @@ -0,0 +1,257 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef MCUCONF_H +#define MCUCONF_H + +/* + * STM32F3xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define STM32F3xx_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED FALSE +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_PREDIV_VALUE 1 +#define STM32_PLLMUL_VALUE 9 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_ADC12PRES STM32_ADC12PRES_DIV1 +#define STM32_ADC34PRES STM32_ADC34PRES_DIV1 +#define STM32_USART1SW STM32_USART1SW_PCLK +#define STM32_USART2SW STM32_USART2SW_PCLK +#define STM32_USART3SW STM32_USART3SW_PCLK +#define STM32_UART4SW STM32_UART4SW_PCLK +#define STM32_UART5SW STM32_UART5SW_PCLK +#define STM32_I2C1SW STM32_I2C1SW_SYSCLK +#define STM32_I2C2SW STM32_I2C2SW_SYSCLK +#define STM32_TIM1SW STM32_TIM1SW_PCLK2 +#define STM32_TIM8SW STM32_TIM8SW_PCLK2 +#define STM32_RTCSEL STM32_RTCSEL_LSI +#define STM32_USB_CLOCK_REQUIRED TRUE +#define STM32_USBPRE STM32_USBPRE_DIV1P5 + +#undef STM32_HSE_BYPASS +// #error "oh no" +// #endif + +/* + * ADC driver system settings. + */ +#define STM32_ADC_DUAL_MODE FALSE +#define STM32_ADC_COMPACT_SAMPLES FALSE +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_USE_ADC2 FALSE +#define STM32_ADC_USE_ADC3 FALSE +#define STM32_ADC_USE_ADC4 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_ADC_ADC4_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_ADC4_DMA_PRIORITY 2 +#define STM32_ADC_ADC12_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_IRQ_PRIORITY 5 +#define STM32_ADC_ADC4_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC4_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 +#define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 TRUE +#define STM32_DAC_USE_DAC1_CH2 TRUE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 + +/* + * EXT driver system settings. + */ +#define STM32_EXT_EXTI0_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI1_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI2_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI3_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI4_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI16_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI17_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI18_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI19_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI20_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI21_22_29_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI30_32_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI33_IRQ_PRIORITY 6 + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM6 TRUE +#define STM32_GPT_USE_TIM7 TRUE +#define STM32_GPT_USE_TIM8 TRUE +#define STM32_GPT_TIM1_IRQ_PRIORITY 7 +#define STM32_GPT_TIM2_IRQ_PRIORITY 7 +#define STM32_GPT_TIM3_IRQ_PRIORITY 7 +#define STM32_GPT_TIM4_IRQ_PRIORITY 7 +#define STM32_GPT_TIM6_IRQ_PRIORITY 7 +#define STM32_GPT_TIM7_IRQ_PRIORITY 7 +#define STM32_GPT_TIM8_IRQ_PRIORITY 7 + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_IRQ_PRIORITY 10 +#define STM32_I2C_I2C2_IRQ_PRIORITY 10 +#define STM32_I2C_USE_DMA TRUE +#define STM32_I2C_I2C1_DMA_PRIORITY 1 +#define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_TIM1_IRQ_PRIORITY 7 +#define STM32_ICU_TIM2_IRQ_PRIORITY 7 +#define STM32_ICU_TIM3_IRQ_PRIORITY 7 +#define STM32_ICU_TIM4_IRQ_PRIORITY 7 +#define STM32_ICU_TIM8_IRQ_PRIORITY 7 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 TRUE +#define STM32_PWM_USE_TIM8 FALSE +#define STM32_PWM_TIM1_IRQ_PRIORITY 7 +#define STM32_PWM_TIM2_IRQ_PRIORITY 7 +#define STM32_PWM_TIM3_IRQ_PRIORITY 7 +#define STM32_PWM_TIM4_IRQ_PRIORITY 7 +#define STM32_PWM_TIM8_IRQ_PRIORITY 7 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 TRUE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_USART3_PRIORITY 12 +#define STM32_SERIAL_UART4_PRIORITY 12 +#define STM32_SERIAL_UART5_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USART1_IRQ_PRIORITY 12 +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_USB1 TRUE +#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE +#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 +#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +#endif /* MCUCONF_H */ diff --git a/keyboards/handwired/steamvan/rev1/rev1.c b/keyboards/handwired/steamvan/rev1/rev1.c new file mode 100644 index 00000000000..3188649494b --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/rev1.c @@ -0,0 +1,36 @@ +/* Copyright 2019 John M Daly + * + * 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 . + */ +#include "rev1.h" + +#include "led.h" +#include "printf.h" + +backlight_config_t kb_backlight_config = { + .enable = true, + .breathing = true, + .level = BACKLIGHT_LEVELS +}; + + + +void matrix_init_kb(void) { + matrix_init_user(); + backlight_init_ports(); +} + +void matrix_scan_kb(void) { + matrix_scan_user(); +} diff --git a/keyboards/handwired/steamvan/rev1/rev1.h b/keyboards/handwired/steamvan/rev1/rev1.h new file mode 100644 index 00000000000..83f7ecb9ca0 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/rev1.h @@ -0,0 +1,90 @@ +/* Copyright 2019 Jack Humbert + * + * 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 . + */ +#pragma once + +#include "quantum.h" +#include "backlight.h" + +// This a shortcut to help you visually see your layout. +// There are a number of variations depending on the layout of your bottom row. +// The arrow variant adds an additional key on the bottom-right, while the +// command variant adds an additional key on the bottom-left. arrow-command is a +// combination of both of those, having an additional key on both sides. +// +// Please note that the numbering of the macro arguments are based on the +// numbers of the keys on the PCB. + +#define LAYOUT_standard( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ + K30, K31, K33, K34, K36, K38, K39, K3B \ +) \ +{ \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ + { K30, K31, KC_NO, K33, K34, KC_NO, K36, KC_NO, K38, K39, KC_NO, K3B } \ +} + +#define LAYOUT_arrow( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ + K30, K31, K33, K34, K36, K38, K39, K3A, K3B \ +) \ +{ \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ + { K30, K31, KC_NO, K33, K34, KC_NO, K36, KC_NO, K38, K39, K3A, K3B } \ +} + +#define LAYOUT_command( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ + K30, K31, K32, K33, K34, K36, K38, K39, K3B \ +) \ +{ \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ + { K30, K31, K32, K33, K34, KC_NO, K36, KC_NO, K38, K39, KC_NO, K3B } \ +} + +#define LAYOUT_arrow_command( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \ + K30, K31, K32, K33, K34, K36, K38, K39, K3A, K3B \ +) \ +{ \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \ + { K30, K31, K32, K33, K34, KC_NO, K36, KC_NO, K38, K39, K3A, K3B } \ +} + +// Backlighting +extern backlight_config_t kb_backlight_config; +extern bool kb_backlight_breathing; + +void backlight_init_ports(void); +void backlight_set(uint8_t level); +bool is_breathing(void); +void breathing_enable(void); +void breathing_disable(void); diff --git a/keyboards/handwired/steamvan/rev1/rules.mk b/keyboards/handwired/steamvan/rev1/rules.mk new file mode 100644 index 00000000000..3a91a7c6092 --- /dev/null +++ b/keyboards/handwired/steamvan/rev1/rules.mk @@ -0,0 +1,58 @@ +# project specific files + +## chip/board settings +# - the next two should match the directories in +# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +MCU_FAMILY = STM32 +MCU_SERIES = STM32F3xx + +# Linker script to use +# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +MCU_LDSCRIPT = STM32F303xC + +# Startup code to use +# - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ +MCU_STARTUP = stm32f3xx + +# Board: it should exist either in /os/hal/boards/ +# or /boards +BOARD = GENERIC_STM32_F303XC + +# Cortex version +MCU = cortex-m4 + +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +ARMV = 7 + +USE_FPU = yes + +# Vector table for application +# 0x00000000-0x00001000 area is occupied by bootlaoder.*/ +# The CORTEX_VTOR... is needed only for MCHCK/Infinity KB +# OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000 + +# Options to pass to dfu-util when flashing +DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave +DFU_SUFFIX_ARGS = -v 0483 -p df11 + +# Code for backlight breathing: +SRC += led.c + +# Build Options +# comment out to disable the options. +# +BACKLIGHT_ENABLE = yes +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = no # Console for debug(+400) +COMMAND_ENABLE = no # Commands for debug and configuration +NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +AUDIO_ENABLE = no +RGBLIGHT_ENABLE = no # Enable keyboard underlight functionality +MIDI_ENABLE = no # MIDI controls +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +LEADER_ENABLE = yes + From 547fbe769c684745195a53baf9f62730ceea804d Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 13 Aug 2019 10:28:12 -0700 Subject: [PATCH 20/61] Enable PWM Support for Planck EZ Indicator Lights (#6473) * remove led layer code * enable PWM on STM32F303 * Unusable PWM code * Updated PWM Stuff? * PWM Semi-working * Both LEDs working at the same time * Update names * Add led level functions * Add LED levels and persistent settings * Revert change due to issues with timing related code * Review feedback and minor cleanup --- keyboards/planck/ez/ez.c | 167 ++++++++++++++++++++++++++++++++------- keyboards/planck/ez/ez.h | 21 +++++ quantum/stm32/halconf.h | 2 +- quantum/stm32/mcuconf.h | 4 +- 4 files changed, 164 insertions(+), 30 deletions(-) diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c index e739b90b8c9..8734042a429 100644 --- a/keyboards/planck/ez/ez.c +++ b/keyboards/planck/ez/ez.c @@ -14,6 +14,10 @@ * along with this program. If not, see . */ #include "ez.h" +#include "ch.h" +#include "hal.h" + keyboard_config_t keyboard_config; + #ifdef RGB_MATRIX_ENABLE const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { @@ -112,39 +116,148 @@ void suspend_power_down_kb(void) { } #endif -void matrix_init_kb(void) { - matrix_init_user(); +/* Left B9 Right B8 */ - palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL); - - palClearPad(GPIOB, 8); - palClearPad(GPIOB, 9); +// See http://jared.geek.nz/2013/feb/linear-led-pwm +static uint16_t cie_lightness(uint16_t v) { + if (v <= 5243) // if below 8% of max + return v / 9; // same as dividing by 900% + else { + uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare + // to get a useful result with integer division, we shift left in the expression above + // and revert what we've done again after squaring. + y = y * y * y >> 8; + if (y > 0xFFFFUL) // prevent overflow + return 0xFFFFU; + else + return (uint16_t) y; + } } -void matrix_scan_kb(void) { - matrix_scan_user(); +static PWMConfig pwmCFG = { + 0xFFFF,/* PWM clock frequency */ + 256,/* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + NULL, + { + {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL} + }, + 0, /* HW dependent part.*/ + 0 +}; + +static uint32_t planck_ez_right_led_duty; +static uint32_t planck_ez_left_led_duty; + +void planck_ez_right_led_level(uint8_t level) { + planck_ez_right_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); + if (level == 0) { + // Turn backlight off + pwmDisableChannel(&PWMD4, 2); + } else { + // Turn backlight on + pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); + } } -uint32_t layer_state_set_kb(uint32_t state) { - palClearPad(GPIOB, 8); - palClearPad(GPIOB, 9); - state = layer_state_set_user(state); - uint8_t layer = biton32(state); - switch (layer) { - case 3: - palSetPad(GPIOB, 9); - break; - case 4: - palSetPad(GPIOB, 8); - break; - case 6: - palSetPad(GPIOB, 9); - palSetPad(GPIOB, 8); - break; - default: - break; +void planck_ez_right_led_on(void){ + pwmEnableChannel(&PWMD4, 2, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_right_led_duty)); +} + +void planck_ez_right_led_off(void){ + pwmDisableChannel(&PWMD4, 2); +} + +void planck_ez_left_led_level(uint8_t level) { + planck_ez_left_led_duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / 255)); + if (level == 0) { + // Turn backlight off + pwmDisableChannel(&PWMD4, 3); + } else { + // Turn backlight on + pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); + } +} + +void planck_ez_left_led_on(void){ + pwmEnableChannel(&PWMD4, 3, PWM_FRACTION_TO_WIDTH(&PWMD4,0xFFFF,planck_ez_left_led_duty)); +} + +void planck_ez_left_led_off(void){ + pwmDisableChannel(&PWMD4, 3); +} + + +void led_initialize_hardware(void) { + pwmStart(&PWMD4, &pwmCFG); + + // set up defaults + planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(2)); + planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(2)); + + + // turn LEDs off by default + planck_ez_left_led_off(); + planck_ez_right_led_off(); +} + +void keyboard_pre_init_kb(void) { + // read kb settings from eeprom + keyboard_config.raw = eeconfig_read_kb(); + + // initialize settings for front LEDs + led_initialize_hardware(); +} + +void eeconfig_init_kb(void) { // EEPROM is getting reset! + keyboard_config.raw = 0; + keyboard_config.led_level = 4; + eeconfig_update_kb(keyboard_config.raw); + eeconfig_init_user(); +} + +layer_state_t layer_state_set_kb(layer_state_t state) { + planck_ez_left_led_off(); + planck_ez_right_led_off(); + state = layer_state_set_user(state); + uint8_t layer = biton32(state); + switch (layer) { + case 3: + planck_ez_left_led_on(); + break; + case 4: + planck_ez_right_led_on(); + break; + case 6: + planck_ez_right_led_on(); + planck_ez_left_led_on(); + break; + default: + break; } return state; } + + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LED_LEVEL: + if (record->event.pressed) { + keyboard_config.led_level++; + if (keyboard_config.led_level > 4) { + keyboard_config.led_level = 0; + } + planck_ez_right_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + planck_ez_left_led_level((uint8_t)keyboard_config.led_level * 255 / 4 ); + eeconfig_update_kb(keyboard_config.raw); + layer_state_set_kb(layer_state); + } + break; + } + return true; +} diff --git a/keyboards/planck/ez/ez.h b/keyboards/planck/ez/ez.h index 55c4032422a..e2ddaf3cecb 100644 --- a/keyboards/planck/ez/ez.h +++ b/keyboards/planck/ez/ez.h @@ -50,3 +50,24 @@ LAYOUT_planck_1x2uC( \ #define KEYMAP LAYOUT_ortho_4x12 #define LAYOUT_planck_mit LAYOUT_planck_1x2uC #define LAYOUT_planck_grid LAYOUT_ortho_4x12 + +void planck_ez_right_led_on(void); +void planck_ez_right_led_off(void); +void planck_ez_right_led_level(uint8_t level); +void planck_ez_left_led_on(void); +void planck_ez_left_led_off(void); +void planck_ez_left_led_level(uint8_t level); + +enum planck_ez_keycodes { + LED_LEVEL = SAFE_RANGE, + EZ_SAFE_RANGE, +}; + +typedef union { + uint32_t raw; + struct { + uint8_t led_level :3; + }; +} keyboard_config_t; + +extern keyboard_config_t keyboard_config; diff --git a/quantum/stm32/halconf.h b/quantum/stm32/halconf.h index c3e0cbb728c..a14ace02b4b 100644 --- a/quantum/stm32/halconf.h +++ b/quantum/stm32/halconf.h @@ -111,7 +111,7 @@ * @brief Enables the PWM subsystem. */ #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE +#define HAL_USE_PWM TRUE #endif /** diff --git a/quantum/stm32/mcuconf.h b/quantum/stm32/mcuconf.h index 36f8ca2252a..32a73fb38ea 100644 --- a/quantum/stm32/mcuconf.h +++ b/quantum/stm32/mcuconf.h @@ -183,9 +183,9 @@ */ #define STM32_PWM_USE_ADVANCED FALSE #define STM32_PWM_USE_TIM1 FALSE -#define STM32_PWM_USE_TIM2 TRUE +#define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 TRUE -#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM4 TRUE #define STM32_PWM_USE_TIM8 FALSE #define STM32_PWM_TIM1_IRQ_PRIORITY 7 #define STM32_PWM_TIM2_IRQ_PRIORITY 7 From 41482e02a6ac06bd9d0fa31c42d372c9d73c5d2b Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 14 Aug 2019 20:07:26 +0100 Subject: [PATCH 21/61] [Keyboard] Align xd84 and xd96 with moon (#6465) * Refactor xd84 to use LINK_TIME_OPTIMIZATION_ENABLE * Refactor xd96 to use LINK_TIME_OPTIMIZATION_ENABLE * Align xd84 and xd96 with moon * Update keyboards/xd96/rules.mk Co-Authored-By: Drashna Jaelre * Update keyboards/xd84/rules.mk Co-Authored-By: Drashna Jaelre --- keyboards/xd84/config.h | 4 --- keyboards/xd84/custom_matrix_helper.c | 15 ++++++++++++ keyboards/xd84/matrix.c | 2 +- keyboards/xd84/pca9555.c | 35 +++++++++++++++++++-------- keyboards/xd84/pca9555.h | 22 ++++++++--------- keyboards/xd84/readme.md | 2 +- keyboards/xd84/rules.mk | 8 +++--- keyboards/xd96/config.h | 4 --- keyboards/xd96/matrix.c | 2 +- keyboards/xd96/pca9555.c | 20 +++++++-------- keyboards/xd96/pca9555.h | 22 ++++++++--------- keyboards/xd96/readme.md | 2 +- keyboards/xd96/rules.mk | 6 ++--- 13 files changed, 83 insertions(+), 61 deletions(-) diff --git a/keyboards/xd84/config.h b/keyboards/xd84/config.h index 138c2c4c853..1ff5e1cfd7c 100644 --- a/keyboards/xd84/config.h +++ b/keyboards/xd84/config.h @@ -237,7 +237,3 @@ /* Bootmagic Lite key configuration */ // #define BOOTMAGIC_LITE_ROW 0 // #define BOOTMAGIC_LITE_COLUMN 0 - -// LTO options -#define NO_ACTION_MACRO -#define NO_ACTION_FUNCTION diff --git a/keyboards/xd84/custom_matrix_helper.c b/keyboards/xd84/custom_matrix_helper.c index a6a0a041d9d..a4c5b6afa54 100644 --- a/keyboards/xd84/custom_matrix_helper.c +++ b/keyboards/xd84/custom_matrix_helper.c @@ -1,3 +1,18 @@ +/* Copyright 2019 + * + * 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 . + */ #include #include #include "wait.h" diff --git a/keyboards/xd84/matrix.c b/keyboards/xd84/matrix.c index a3590504777..4cb5544ca48 100644 --- a/keyboards/xd84/matrix.c +++ b/keyboards/xd84/matrix.c @@ -65,7 +65,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) // Clear data in matrix row current_matrix[current_row] = 0; - // Select row and wait for row selecton to stabilize + // Select row and wait for row selection to stabilize select_row(current_row); wait_us(30); diff --git a/keyboards/xd84/pca9555.c b/keyboards/xd84/pca9555.c index df4631e9d74..b0e542d8def 100644 --- a/keyboards/xd84/pca9555.c +++ b/keyboards/xd84/pca9555.c @@ -1,9 +1,24 @@ +/* Copyright 2019 + * + * 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 . + */ #include "i2c_master.h" #include "pca9555.h" #include "debug.h" -#define SLAVE_TO_ADDR(n) (n<<1) +#define SLAVE_TO_ADDR(n) (n << 1) #define TIMEOUT 100 enum { @@ -14,7 +29,7 @@ enum { CMD_INVERSION_0, CMD_INVERSION_1, CMD_CONFIG_0, - CMD_CONFIG_1 + CMD_CONFIG_1, }; void pca9555_init(uint8_t slave_addr) { @@ -22,17 +37,17 @@ void pca9555_init(uint8_t slave_addr) { if (!s_init) { i2c_init(); - s_init=1; + s_init = 1; } // TODO: could check device connected - //i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - //i2c_stop(); + // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); + // i2c_stop(); } void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; + uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { @@ -42,7 +57,7 @@ void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; + uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { @@ -52,10 +67,10 @@ void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; + uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; - uint8_t data = 0; - i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); + uint8_t data = 0; + i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { print("pca9555_readPins::FAILED\n"); } diff --git a/keyboards/xd84/pca9555.h b/keyboards/xd84/pca9555.h index 6aaee8a6f88..ebb97e2f301 100644 --- a/keyboards/xd84/pca9555.h +++ b/keyboards/xd84/pca9555.h @@ -18,15 +18,15 @@ /* PCA9555 ,----------. - SDA --| SDA P00 |-- P1 - SCL --| SCL P01 |-- P2 - INT --| INT P02 |-- P3 - | P03 |-- P4 - A0 --| A0 P04 |-- P5 - A1 --| A1 P05 |-- P6 - A2 --| A2 P06 |-- P7 - | P07 |-- P8 - | | + SDA --| SDA P00 |-- P00 + SCL --| SCL P01 |-- P01 + INT --| INT P02 |-- P02 + | P03 |-- P03 + A0 --| A0 P04 |-- P04 + A1 --| A1 P05 |-- P05 + A2 --| A2 P06 |-- P06 + | P07 |-- P07 + | | | P10 |-- P10 | P11 |-- P11 | P12 |-- P12 @@ -35,7 +35,7 @@ | P15 |-- P15 | P16 |-- P16 | P17 |-- P17 - `----------' + `----------' */ #define PCA9555_PORT0 0 @@ -52,4 +52,4 @@ void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); \ No newline at end of file +uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); diff --git a/keyboards/xd84/readme.md b/keyboards/xd84/readme.md index 38b4efcba29..b8d9c5dbb80 100644 --- a/keyboards/xd84/readme.md +++ b/keyboards/xd84/readme.md @@ -2,7 +2,7 @@ ![XD84](https://cdn.shopify.com/s/files/1/2711/4238/products/HTB17eeJSXXXXXbIXFXXq6xXFXXXp_1024x1024.jpg?v=1515505994) -Compact With 84 Keys & RGB LED Underglow +Keyboard with 84 Keys & RGB LED Underglow - Designed by Xiudi - Up to 87 keys - iso and ansi support diff --git a/keyboards/xd84/rules.mk b/keyboards/xd84/rules.mk index 283d4babc7a..e0982e0401c 100644 --- a/keyboards/xd84/rules.mk +++ b/keyboards/xd84/rules.mk @@ -78,11 +78,11 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) +LINK_TIME_OPTIMIZATION_ENABLE = yes # custom matrix setup CUSTOM_MATRIX = yes -SRC = i2c_master.c custom_matrix_helper.c pca9555.c matrix.c +SRC += custom_matrix_helper.c pca9555.c matrix.c +QUANTUM_LIB_SRC += i2c_master.c -EXTRAFLAGS += -flto - -LAYOUTS = 75_ansi 75_iso \ No newline at end of file +LAYOUTS = 75_ansi 75_iso diff --git a/keyboards/xd96/config.h b/keyboards/xd96/config.h index ea6c878e9e3..b0fa4779523 100644 --- a/keyboards/xd96/config.h +++ b/keyboards/xd96/config.h @@ -238,7 +238,3 @@ /* Bootmagic Lite key configuration */ // #define BOOTMAGIC_LITE_ROW 0 // #define BOOTMAGIC_LITE_COLUMN 0 - -// LTO options -#define NO_ACTION_MACRO -#define NO_ACTION_FUNCTION diff --git a/keyboards/xd96/matrix.c b/keyboards/xd96/matrix.c index 550dae4d02e..e8fd850edbf 100644 --- a/keyboards/xd96/matrix.c +++ b/keyboards/xd96/matrix.c @@ -67,7 +67,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) // Clear data in matrix row current_matrix[current_row] = 0; - // Select row and wait for row selecton to stabilize + // Select row and wait for row selection to stabilize select_row(current_row); wait_us(30); diff --git a/keyboards/xd96/pca9555.c b/keyboards/xd96/pca9555.c index 960df4f4e52..b0e542d8def 100644 --- a/keyboards/xd96/pca9555.c +++ b/keyboards/xd96/pca9555.c @@ -18,7 +18,7 @@ #include "debug.h" -#define SLAVE_TO_ADDR(n) (n<<1) +#define SLAVE_TO_ADDR(n) (n << 1) #define TIMEOUT 100 enum { @@ -29,7 +29,7 @@ enum { CMD_INVERSION_0, CMD_INVERSION_1, CMD_CONFIG_0, - CMD_CONFIG_1 + CMD_CONFIG_1, }; void pca9555_init(uint8_t slave_addr) { @@ -37,17 +37,17 @@ void pca9555_init(uint8_t slave_addr) { if (!s_init) { i2c_init(); - s_init=1; + s_init = 1; } // TODO: could check device connected - //i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - //i2c_stop(); + // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); + // i2c_stop(); } void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; + uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { @@ -57,7 +57,7 @@ void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; + uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { @@ -67,10 +67,10 @@ void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; + uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; - uint8_t data = 0; - i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); + uint8_t data = 0; + i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); if (ret != I2C_STATUS_SUCCESS) { print("pca9555_readPins::FAILED\n"); } diff --git a/keyboards/xd96/pca9555.h b/keyboards/xd96/pca9555.h index 6aaee8a6f88..ebb97e2f301 100644 --- a/keyboards/xd96/pca9555.h +++ b/keyboards/xd96/pca9555.h @@ -18,15 +18,15 @@ /* PCA9555 ,----------. - SDA --| SDA P00 |-- P1 - SCL --| SCL P01 |-- P2 - INT --| INT P02 |-- P3 - | P03 |-- P4 - A0 --| A0 P04 |-- P5 - A1 --| A1 P05 |-- P6 - A2 --| A2 P06 |-- P7 - | P07 |-- P8 - | | + SDA --| SDA P00 |-- P00 + SCL --| SCL P01 |-- P01 + INT --| INT P02 |-- P02 + | P03 |-- P03 + A0 --| A0 P04 |-- P04 + A1 --| A1 P05 |-- P05 + A2 --| A2 P06 |-- P06 + | P07 |-- P07 + | | | P10 |-- P10 | P11 |-- P11 | P12 |-- P12 @@ -35,7 +35,7 @@ | P15 |-- P15 | P16 |-- P16 | P17 |-- P17 - `----------' + `----------' */ #define PCA9555_PORT0 0 @@ -52,4 +52,4 @@ void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); \ No newline at end of file +uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); diff --git a/keyboards/xd96/readme.md b/keyboards/xd96/readme.md index 237d7a05165..bf01db8bb7e 100644 --- a/keyboards/xd96/readme.md +++ b/keyboards/xd96/readme.md @@ -2,7 +2,7 @@ ![XD96](https://cdn.shopify.com/s/files/1/2711/4238/products/xd96_pcb_1024x1024.jpg?v=1515425370) -Compact With 96 Keys & RGB LED Underglow +Keyboard with 96 Keys & RGB LED Underglow - Designed by Xiudi - ISO and ANSI support - Uses Kimera core diff --git a/keyboards/xd96/rules.mk b/keyboards/xd96/rules.mk index c9f80447129..91736bd8785 100644 --- a/keyboards/xd96/rules.mk +++ b/keyboards/xd96/rules.mk @@ -78,9 +78,9 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) +LINK_TIME_OPTIMIZATION_ENABLE = yes # custom matrix setup CUSTOM_MATRIX = yes -SRC = i2c_master.c custom_matrix_helper.c pca9555.c matrix.c - -EXTRAFLAGS += -flto +SRC += custom_matrix_helper.c pca9555.c matrix.c +QUANTUM_LIB_SRC += i2c_master.c From d14ef52b804115bd07f2c22de7d354d6e9e94c58 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 14 Aug 2019 20:08:01 +0100 Subject: [PATCH 22/61] [Keymap] Update gherkin to use gpio (#6520) --- .../gherkin/keymaps/default/keymap.c | 44 +++++-------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/keyboards/40percentclub/gherkin/keymaps/default/keymap.c b/keyboards/40percentclub/gherkin/keymaps/default/keymap.c index ae6f1586271..9d1a67bd38b 100644 --- a/keyboards/40percentclub/gherkin/keymaps/default/keymap.c +++ b/keyboards/40percentclub/gherkin/keymaps/default/keymap.c @@ -18,46 +18,24 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { }; -void matrix_init_user(void) { -} +void keyboard_pre_init_user(void) { + // Call the keyboard pre init code. -void matrix_scan_user(void) { -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - return true; + // Set our LED pins as output + setPinOutput(D5); + setPinOutput(B0); } void led_set_user(uint8_t usb_led) { - - if (usb_led & (1 << USB_LED_NUM_LOCK)) { - DDRD |= (1 << 5); PORTD &= ~(1 << 5); + if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { + writePinLow(D5); } else { - DDRD &= ~(1 << 5); PORTD &= ~(1 << 5); + writePinHigh(D5); } - if (usb_led & (1 << USB_LED_CAPS_LOCK)) { - DDRB |= (1 << 0); PORTB &= ~(1 << 0); + if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) { + writePinLow(B0); } else { - DDRB &= ~(1 << 0); PORTB &= ~(1 << 0); + writePinHigh(B0); } - - if (usb_led & (1 << USB_LED_SCROLL_LOCK)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_COMPOSE)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_KANA)) { - - } else { - - } - } From 5d23fb1e3afec56f6bac159138b0bb33fddc4c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vince=20Gell=C3=A1r?= Date: Wed, 14 Aug 2019 21:10:44 +0200 Subject: [PATCH 23/61] [Keymap] Xd75 bulbizarre keymap (#6525) * Added Bulbizarre keymap for the XD75 * Fixed no newline at the end of file * Update keyboards/xd75/keymaps/bulbizarre/readme.md Co-Authored-By: MechMerlin <30334081+mechmerlin@users.noreply.github.com> * Update led status check Co-Authored-By: fauxpark * Remove unnecessary define Co-Authored-By: fauxpark --- keyboards/xd75/keymaps/bulbizarre/config.h | 19 +++ keyboards/xd75/keymaps/bulbizarre/keymap.c | 152 ++++++++++++++++++++ keyboards/xd75/keymaps/bulbizarre/readme.md | 4 + keyboards/xd75/keymaps/bulbizarre/rules.mk | 16 +++ 4 files changed, 191 insertions(+) create mode 100644 keyboards/xd75/keymaps/bulbizarre/config.h create mode 100644 keyboards/xd75/keymaps/bulbizarre/keymap.c create mode 100644 keyboards/xd75/keymaps/bulbizarre/readme.md create mode 100644 keyboards/xd75/keymaps/bulbizarre/rules.mk diff --git a/keyboards/xd75/keymaps/bulbizarre/config.h b/keyboards/xd75/keymaps/bulbizarre/config.h new file mode 100644 index 00000000000..e6975da8a20 --- /dev/null +++ b/keyboards/xd75/keymaps/bulbizarre/config.h @@ -0,0 +1,19 @@ +/* Copyright 2017 Benjamin Kesselring + * + * 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 . + */ + +#pragma once + +// place overrides here diff --git a/keyboards/xd75/keymaps/bulbizarre/keymap.c b/keyboards/xd75/keymaps/bulbizarre/keymap.c new file mode 100644 index 00000000000..f35eea73c47 --- /dev/null +++ b/keyboards/xd75/keymaps/bulbizarre/keymap.c @@ -0,0 +1,152 @@ +/* Copyright 2017 Wunder + * + * 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 . + */ +#include QMK_KEYBOARD_H + + +// Layer shorthand +#define _QW 0 +#define _FN 1 +#define _FS 2 + +// Defines the keycodes used by our macros in process_record_user +enum custom_keycodes { + SWITCH_FN = SAFE_RANGE, + SWITCH_FS +}; + +uint16_t lt12_timer; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* QWERTY + * .--------------------------------------------------------------------------------------------------------------------------------------. + * | ESC | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BACKSP | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------| + * | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | ENTER | DEL | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------| + * | CAP LK | A | S | D | F | G | H | J | K | L | : | @ | ~ | ENTER | HOME | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------| + * | LSHIFT | Z | X | C | V | B | B | N | M | , | . | / | RSHIFT | UP | END | + * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------| + * | LCTRL | DEL | LALT | PSCR | SPACE | SPACE | SPACE | SPACE | ALTGR | FN | FX | RCTRL | LEFT | DOWN | RIGHT | + * '--------------------------------------------------------------------------------------------------------------------------------------' + */ + + [_QW] = LAYOUT_ortho_5x15( /* QWERTY */ + KC_ESC, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_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_ENT, KC_DEL, + 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_NUHS, KC_ENT, KC_HOME, + KC_LSFT, KC_BSLS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_DEL, KC_LALT, KC_PSCR, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_ALGR, SWITCH_FN, SWITCH_FS, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + +/* FUNCTION + * .--------------------------------------------------------------------------------------------------------------------------------------. + * | ESC | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | = | BACKSP | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------| + * | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | ENTER | DEL | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------| + * | CAP LK | A | S | D | F | G | H | J | K | L | : | @ | ~ | ENTER | HOME | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------| + * | LSHIFT | Z | X | C | V | B | B | N | M | , | . | / | RSHIFT | UP | END | + * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------| + * | LCTRL | DEL | LALT | PSCR | SPACE | SPACE | SPACE | SPACE | ALTGR | FN | FX | RCTRL | LEFT | DOWN | RIGHT | + * '--------------------------------------------------------------------------------------------------------------------------------------' + */ + + [_FN] = LAYOUT_ortho_5x15( /* FUNCTION */ + KC_ESC, 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_EQL, KC_BSPC, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, TO(_QW), TO(_FS), _______, _______, _______, _______ + ), + +/* FUNCTIONS + * .--------------------------------------------------------------------------------------------------------------------------------------. + * | ESC | RGB+ | BL_BRT | F3 | F4 | F5 | F6 | F7 | F8 | F9 | / | * | - | + | BACKSP | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------| + * | RGB_H+ | RGB- | BL- | E | R | T | Y | U | I | O | 7 | 8 | 9 | ENTER | DEL | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------| + * | RGB_H- | RGB_M+ | BL+ | VOL+ | F | G | H | J | K | L | 4 | 5 | 6 | ENTER | RESET | + * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------| + * | RGB_S+ | RGB_M- | BL_S | VOL- | V | B | B | N | M | , | 1 | 2 | 3 | UP | END | + * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------| + * | RGB_S- | RGB_T | BL_T | MUTE | SPACE | SPACE | SPACE | SPACE | ALTGR | FN | FX | 0 | . | . | RIGHT | + * '--------------------------------------------------------------------------------------------------------------------------------------' + */ + + [_FS] = LAYOUT_ortho_5x15( /* FUNCTION */ + _______, RGB_VAI, BL_BRTG, _______, _______, _______, _______, _______, _______, _______, KC_PSLS, KC_PAST, KC_PMNS, KC_PPLS, _______, + RGB_HUI, RGB_VAD, BL_INC, _______, _______, _______, _______, _______, _______, _______, KC_P7, KC_P8, KC_P9, _______, _______, + RGB_HUD, RGB_RMOD,BL_DEC, KC_VOLU, _______, _______, _______, _______, _______, _______, KC_P4, KC_P5, KC_P6, _______, RESET, + RGB_SAI, RGB_MOD, BL_STEP, KC_VOLD, _______, _______, _______, _______, _______, _______, KC_P1, KC_P2, KC_P3, _______, _______, + RGB_SAD, RGB_TOG, BL_TOGG, KC_MUTE, _______, _______, _______, _______, _______, TO(_FN), TO(_QW), KC_P0, KC_PDOT, KC_DOT, _______ + ) +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SWITCH_FN: + if (record->event.pressed) { + lt12_timer = timer_read(); + layer_on(_FN); + gp100_led_on(); + } else { + if (timer_elapsed(lt12_timer) > 200) { + layer_off(_FN); + gp100_led_off(); + } + } + return false; + break; + case SWITCH_FS: + if (record->event.pressed) { + lt12_timer = timer_read(); + layer_on(_FS); + gp100_led_on(); + } else { + if (timer_elapsed(lt12_timer) > 200) { + layer_off(_FS); + gp100_led_off(); + } + } + return false; + break; + } + return true; +} + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +void led_set_user(uint8_t usb_led) { + if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) { + capslock_led_on(); + } else { + capslock_led_off(); + } + if (IS_LAYER_ON(_FN) || IS_LAYER_ON(_FS)) { + gp100_led_on(); + } else { + gp100_led_off(); + } +} diff --git a/keyboards/xd75/keymaps/bulbizarre/readme.md b/keyboards/xd75/keymaps/bulbizarre/readme.md new file mode 100644 index 00000000000..87ee9d7055a --- /dev/null +++ b/keyboards/xd75/keymaps/bulbizarre/readme.md @@ -0,0 +1,4 @@ +# Bulbizarre keymap + +Modified full layout, F-key layer, numpad and function layer. +Uses backlight, RGB underglow, and tap or hold layer switching keys. diff --git a/keyboards/xd75/keymaps/bulbizarre/rules.mk b/keyboards/xd75/keymaps/bulbizarre/rules.mk new file mode 100644 index 00000000000..e20fde4ed09 --- /dev/null +++ b/keyboards/xd75/keymaps/bulbizarre/rules.mk @@ -0,0 +1,16 @@ +# Copyright 2013 Jun Wako +# +# 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 . + +BACKLIGHT_ENABLE = yes From 75b28225db91b6dc449d76314a85fdedb154758e Mon Sep 17 00:00:00 2001 From: fauxpark Date: Thu, 15 Aug 2019 05:18:30 +1000 Subject: [PATCH 24/61] [Keymap] Cosmetic fix for default Wasdat keymaps (#6531) --- keyboards/maartenwut/wasdat/keymaps/default/keymap.c | 4 ++-- keyboards/maartenwut/wasdat/keymaps/default_iso/keymap.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/keyboards/maartenwut/wasdat/keymaps/default/keymap.c b/keyboards/maartenwut/wasdat/keymaps/default/keymap.c index 967947ada4d..715bbd31330 100644 --- a/keyboards/maartenwut/wasdat/keymaps/default/keymap.c +++ b/keyboards/maartenwut/wasdat/keymaps/default/keymap.c @@ -21,9 +21,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * │Esc│   │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Slk│Pse│ * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐ - * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp| |Ins|Hom|PgU| |Num| / | * | - | + * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│ │Num│ / │ * │ - │ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤ - * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │ |Del|End|PgD| │ 7 │ 8 │ 9 │   │ + * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │ │Del│End│PgD│ │ 7 │ 8 │ 9 │   │ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │               │ 4 │ 5 │ 6 │   │ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤ diff --git a/keyboards/maartenwut/wasdat/keymaps/default_iso/keymap.c b/keyboards/maartenwut/wasdat/keymaps/default_iso/keymap.c index 00a45d746ac..8bdad483120 100644 --- a/keyboards/maartenwut/wasdat/keymaps/default_iso/keymap.c +++ b/keyboards/maartenwut/wasdat/keymaps/default_iso/keymap.c @@ -21,9 +21,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * │Esc│   │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Slk│Pse│ * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐ - * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp| |Ins|Hom|PgU| |Num| / | * | - | + * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│ │Num│ / │ * │ - │ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤ - * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │     │ |Del|End|PgD| │ 7 │ 8 │ 9 │   │ + * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │     │ │Del│End│PgD│ │ 7 │ 8 │ 9 │   │ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ Ent│ └───┴───┴───┘ ├───┼───┼───┤ + │ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │    │               │ 4 │ 5 │ 6 │   │ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤     ┌───┐     ├───┼───┼───┼───┤ From d578aaefcd70ce7cfa69049fac57a2a5fb1c3571 Mon Sep 17 00:00:00 2001 From: Joe Wasson Date: Wed, 14 Aug 2019 12:31:18 -0700 Subject: [PATCH 25/61] [Keymap] Fix include following Wilba refactor (#6538) --- users/talljoe/talljoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/talljoe/talljoe.c b/users/talljoe/talljoe.c index 345b5604bb0..a533ff61032 100644 --- a/users/talljoe/talljoe.c +++ b/users/talljoe/talljoe.c @@ -2,7 +2,7 @@ #include "talljoe.h" #ifdef ZEAL_RGB -#include "../../../keyboards/zeal60/rgb_backlight.h" +#include "../../../keyboards/wilba_tech/wt_rgb_backlight.h" #endif const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { From ee8d9bd40ad4f5b8d23be951d652143582d42938 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 15 Aug 2019 14:57:43 +0100 Subject: [PATCH 26/61] Remove duplicate test keyboards (#6539) * Remove test keyboards now onekey and splittest have been extended * Add f072 for testing --- .../boards/GENERIC_STM32_F103/board.c | 49 - .../boards/GENERIC_STM32_F103/board.h | 166 ---- .../boards/GENERIC_STM32_F103/board.mk | 5 - .../GENERIC_STM32_F103/mini_stm32_mapping.png | Bin 162908 -> 0 bytes .../boards/ST_STM32F072B_DISCOVERY/board.c | 111 --- .../boards/ST_STM32F072B_DISCOVERY/board.h | 923 ------------------ .../boards/ST_STM32F072B_DISCOVERY/board.mk | 5 - .../boards/maple_mini_mapping.png | Bin 237977 -> 0 bytes keyboards/chibios_test/chibios_test.c | 1 - keyboards/chibios_test/chibios_test.h | 8 - keyboards/chibios_test/config.h | 65 -- .../chibios_test/keymaps/default/keymap.c | 22 - keyboards/chibios_test/ld/MKL26Z64.ld | 105 -- .../ld/STM32F103x8_stm32duino_bootloader.ld | 88 -- keyboards/chibios_test/readme.md | 3 - keyboards/chibios_test/rules.mk | 10 - .../stm32_f072_onekey/bootloader_defs.h | 7 - .../chibios_test/stm32_f072_onekey/config.h | 7 - .../chibios_test/stm32_f072_onekey/led.c | 34 - .../chibios_test/stm32_f072_onekey/matrix.c | 163 ---- .../chibios_test/stm32_f072_onekey/readme.md | 3 - .../stm32_f072_onekey/stm32_f072_onekey.c | 1 - .../stm32_f072_onekey/stm32_f072_onekey.h | 7 - .../stm32_f103_onekey/bootloader_defs.h | 10 - .../chibios_test/stm32_f103_onekey/chconf.h | 524 ---------- .../chibios_test/stm32_f103_onekey/config.h | 6 - .../chibios_test/stm32_f103_onekey/flash.sh | 2 - .../chibios_test/stm32_f103_onekey/halconf.h | 353 ------- .../chibios_test/stm32_f103_onekey/led.c | 43 - .../chibios_test/stm32_f103_onekey/matrix.c | 177 ---- .../chibios_test/stm32_f103_onekey/mcuconf.h | 209 ---- .../chibios_test/stm32_f103_onekey/readme.md | 3 - .../chibios_test/stm32_f103_onekey/rules.mk | 47 - .../stm32_f103_onekey/stm32_f103_onekey.c | 1 - .../stm32_f103_onekey/stm32_f103_onekey.h | 7 - .../chibios_test/teensy_lc_onekey/chconf.h | 524 ---------- .../chibios_test/teensy_lc_onekey/config.h | 6 - .../chibios_test/teensy_lc_onekey/halconf.h | 354 ------- .../teensy_lc_onekey/instructions.md | 97 -- keyboards/chibios_test/teensy_lc_onekey/led.c | 32 - .../chibios_test/teensy_lc_onekey/matrix.c | 163 ---- .../chibios_test/teensy_lc_onekey/mcuconf.h | 55 -- .../chibios_test/teensy_lc_onekey/readme.md | 3 - .../chibios_test/teensy_lc_onekey/rules.mk | 45 - .../teensy_lc_onekey/teensy_lc_onekey.c | 1 - .../teensy_lc_onekey/teensy_lc_onekey.h | 7 - .../onekey/stm32f0_disco}/chconf.h | 0 .../onekey/stm32f0_disco/config.h} | 9 +- .../onekey/stm32f0_disco}/halconf.h | 2 +- .../onekey/stm32f0_disco}/mcuconf.h | 2 +- .../handwired/onekey/stm32f0_disco/readme.md | 5 + .../onekey/stm32f0_disco}/rules.mk | 10 +- keyboards/proton_c/config.h | 114 --- keyboards/proton_c/keymaps/default/keymap.c | 21 - keyboards/proton_c/proton_c.c | 25 - keyboards/proton_c/readme.md | 16 - keyboards/proton_c/rules.mk | 17 - 57 files changed, 17 insertions(+), 4656 deletions(-) delete mode 100644 keyboards/chibios_test/boards/GENERIC_STM32_F103/board.c delete mode 100644 keyboards/chibios_test/boards/GENERIC_STM32_F103/board.h delete mode 100644 keyboards/chibios_test/boards/GENERIC_STM32_F103/board.mk delete mode 100644 keyboards/chibios_test/boards/GENERIC_STM32_F103/mini_stm32_mapping.png delete mode 100644 keyboards/chibios_test/boards/ST_STM32F072B_DISCOVERY/board.c delete mode 100644 keyboards/chibios_test/boards/ST_STM32F072B_DISCOVERY/board.h delete mode 100644 keyboards/chibios_test/boards/ST_STM32F072B_DISCOVERY/board.mk delete mode 100644 keyboards/chibios_test/boards/maple_mini_mapping.png delete mode 100644 keyboards/chibios_test/chibios_test.c delete mode 100644 keyboards/chibios_test/chibios_test.h delete mode 100644 keyboards/chibios_test/config.h delete mode 100644 keyboards/chibios_test/keymaps/default/keymap.c delete mode 100644 keyboards/chibios_test/ld/MKL26Z64.ld delete mode 100644 keyboards/chibios_test/ld/STM32F103x8_stm32duino_bootloader.ld delete mode 100644 keyboards/chibios_test/readme.md delete mode 100644 keyboards/chibios_test/rules.mk delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/bootloader_defs.h delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/config.h delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/led.c delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/matrix.c delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/readme.md delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/stm32_f072_onekey.c delete mode 100644 keyboards/chibios_test/stm32_f072_onekey/stm32_f072_onekey.h delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/bootloader_defs.h delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/chconf.h delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/config.h delete mode 100755 keyboards/chibios_test/stm32_f103_onekey/flash.sh delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/halconf.h delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/led.c delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/matrix.c delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/mcuconf.h delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/readme.md delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/rules.mk delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.c delete mode 100644 keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.h delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/chconf.h delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/config.h delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/halconf.h delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/instructions.md delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/led.c delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/matrix.c delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/mcuconf.h delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/readme.md delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/rules.mk delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.c delete mode 100644 keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.h rename keyboards/{chibios_test/stm32_f072_onekey => handwired/onekey/stm32f0_disco}/chconf.h (100%) rename keyboards/{proton_c/proton_c.h => handwired/onekey/stm32f0_disco/config.h} (83%) rename keyboards/{chibios_test/stm32_f072_onekey => handwired/onekey/stm32f0_disco}/halconf.h (99%) rename keyboards/{chibios_test/stm32_f072_onekey => handwired/onekey/stm32f0_disco}/mcuconf.h (99%) create mode 100644 keyboards/handwired/onekey/stm32f0_disco/readme.md rename keyboards/{chibios_test/stm32_f072_onekey => handwired/onekey/stm32f0_disco}/rules.mk (91%) delete mode 100644 keyboards/proton_c/config.h delete mode 100644 keyboards/proton_c/keymaps/default/keymap.c delete mode 100644 keyboards/proton_c/proton_c.c delete mode 100644 keyboards/proton_c/readme.md delete mode 100644 keyboards/proton_c/rules.mk diff --git a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.c b/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.c deleted file mode 100644 index 2809c9d184e..00000000000 --- a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" - -/** - * @brief PAL setup. - * @details Digital I/O ports static configuration as defined in @p board.h. - * This variable is used by the HAL when initializing the PAL driver. - */ -#if HAL_USE_PAL || defined(__DOXYGEN__) -const PALConfig pal_default_config = -{ - {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH}, - {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH}, - {VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH}, - {VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH}, - {VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH}, -}; -#endif - -/* - * Early initialization code. - * This initialization must be performed just after stack setup and before - * any other initialization. - */ -void __early_init(void) { - - stm32_clock_init(); -} - -/* - * Board-specific initialization code. - */ -void boardInit(void) { -} diff --git a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.h b/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.h deleted file mode 100644 index b31d74307b3..00000000000 --- a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#ifndef _BOARD_H_ -#define _BOARD_H_ - -/* - * Setup for a Generic STM32F103 board. - */ - -/* - * Board identifier. - */ -#define BOARD_GENERIC_STM32_F103 -#define BOARD_NAME "Generic STM32F103x board" - -/* - * Board frequencies. - */ -#define STM32_LSECLK 32768 -#define STM32_HSECLK 8000000 - -/* - * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h. - */ -#define STM32F103xB - -/* - * IO pins assignments - */ - -/* on-board */ - -#define GPIOC_LED 13 -#define GPIOD_OSC_IN 0 -#define GPIOD_OSC_OUT 1 - -/* In case your board has a "USB enable" hardware - controlled by a pin, define it here. (It could be just - a 1.5k resistor connected to D+ line.) -*/ -/* -#define GPIOB_USB_DISC 10 -*/ - -/* - * I/O ports initial setup, this configuration is established soon after reset - * in the initialization code. - * - * The digits have the following meaning: - * 0 - Analog input. - * 1 - Push Pull output 10MHz. - * 2 - Push Pull output 2MHz. - * 3 - Push Pull output 50MHz. - * 4 - Digital input. - * 5 - Open Drain output 10MHz. - * 6 - Open Drain output 2MHz. - * 7 - Open Drain output 50MHz. - * 8 - Digital input with PullUp or PullDown resistor depending on ODR. - * 9 - Alternate Push Pull output 10MHz. - * A - Alternate Push Pull output 2MHz. - * B - Alternate Push Pull output 50MHz. - * C - Reserved. - * D - Alternate Open Drain output 10MHz. - * E - Alternate Open Drain output 2MHz. - * F - Alternate Open Drain output 50MHz. - * Please refer to the STM32 Reference Manual for details. - */ - -/* - * Port A setup. - * Everything input with pull-up except: - * PA2 - Alternate output (USART2 TX). - * PA3 - Normal input (USART2 RX). - * PA9 - Alternate output (USART1 TX). - * PA10 - Normal input (USART1 RX). - */ -#define VAL_GPIOACRL 0x88884B88 /* PA7...PA0 */ -#define VAL_GPIOACRH 0x888884B8 /* PA15...PA8 */ -#define VAL_GPIOAODR 0xFFFFFFFF - -/* - * Port B setup. - * Everything input with pull-up except: - * PB10 - Push Pull output (USB switch). - */ -#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */ -#define VAL_GPIOBCRH 0x88888388 /* PB15...PB8 */ -#define VAL_GPIOBODR 0xFFFFFFFF - -/* - * Port C setup. - * Everything input with pull-up except: - * PC13 - Push Pull output (LED). - */ -#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */ -#define VAL_GPIOCCRH 0x88388888 /* PC15...PC8 */ -#define VAL_GPIOCODR 0xFFFFFFFF - -/* - * Port D setup. - * Everything input with pull-up except: - * PD0 - Normal input (XTAL). - * PD1 - Normal input (XTAL). - */ -#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */ -#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */ -#define VAL_GPIODODR 0xFFFFFFFF - -/* - * Port E setup. - * Everything input with pull-up except: - */ -#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */ -#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */ -#define VAL_GPIOEODR 0xFFFFFFFF - -/* - * USB bus activation macro, required by the USB driver. - */ -/* The point is that most of the generic STM32F103* boards - have a 1.5k resistor connected on one end to the D+ line - and on the other end to some pin. Or even a slightly more - complicated "USB enable" circuit, controlled by a pin. - That should go here. - - However on some boards (e.g. one that I have), there's no - such hardware. In which case it's better to not do anything. -*/ -/* -#define usb_lld_connect_bus(usbp) palClearPad(GPIOB, GPIOB_USB_DISC) -*/ -#define usb_lld_connect_bus(usbp) palSetPadMode(GPIOA, 12, PAL_MODE_INPUT); - -/* - * USB bus de-activation macro, required by the USB driver. - */ -/* -#define usb_lld_disconnect_bus(usbp) palSetPad(GPIOB, GPIOB_USB_DISC) -*/ -#define usb_lld_disconnect_bus(usbp) palSetPadMode(GPIOA, 12, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(GPIOA, 12); - -#if !defined(_FROM_ASM_) -#ifdef __cplusplus -extern "C" { -#endif - void boardInit(void); -#ifdef __cplusplus -} -#endif -#endif /* _FROM_ASM_ */ - -#endif /* _BOARD_H_ */ diff --git a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.mk b/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.mk deleted file mode 100644 index 6b8b312fd9f..00000000000 --- a/keyboards/chibios_test/boards/GENERIC_STM32_F103/board.mk +++ /dev/null @@ -1,5 +0,0 @@ -# List of all the board related files. -BOARDSRC = $(BOARD_PATH)/boards/GENERIC_STM32_F103/board.c - -# Required include directories -BOARDINC = $(BOARD_PATH)/boards/GENERIC_STM32_F103 diff --git a/keyboards/chibios_test/boards/GENERIC_STM32_F103/mini_stm32_mapping.png b/keyboards/chibios_test/boards/GENERIC_STM32_F103/mini_stm32_mapping.png deleted file mode 100644 index c44a7d9ebcbf5f50ce5ad9a191bcf50cae2b2522..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162908 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%0A*1RQ~AE_7CD2*!ePO3Ptc0b3ThU{N^mV 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 z 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≧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 diff --git a/keyboards/chibios_test/chibios_test.c b/keyboards/chibios_test/chibios_test.c deleted file mode 100644 index efe2d4a5d63..00000000000 --- a/keyboards/chibios_test/chibios_test.c +++ /dev/null @@ -1 +0,0 @@ -#include "chibios_test.h" diff --git a/keyboards/chibios_test/chibios_test.h b/keyboards/chibios_test/chibios_test.h deleted file mode 100644 index 9fc996ff755..00000000000 --- a/keyboards/chibios_test/chibios_test.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef KEYBOARDS_CHIBIOS_TEST_CHIBIOS_TEST_H_ -#define KEYBOARDS_CHIBIOS_TEST_CHIBIOS_TEST_H_ - -#include "quantum.h" - -#define LAYOUT(k00) {{ k00 }} - -#endif /* KEYBOARDS_CHIBIOS_TEST_CHIBIOS_TEST_H_ */ diff --git a/keyboards/chibios_test/config.h b/keyboards/chibios_test/config.h deleted file mode 100644 index 91350c4457c..00000000000 --- a/keyboards/chibios_test/config.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2015 Jun Wako - -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 . -*/ - -#ifndef CONFIG_H -#define CONFIG_H - -/* USB Device descriptor parameter */ -#define VENDOR_ID 0xFEED -#define PRODUCT_ID 0x6464 -#define DEVICE_VER 0x0001 -/* in python2: list(u"whatever".encode('utf-16-le')) */ -/* at most 32 characters or the ugly hack in usb_main.c borks */ -#define MANUFACTURER QMK -#define PRODUCT ChibiOS QMK test -#define DESCRIPTION QMK keyboard firmware test for ChibiOS - -/* key matrix size */ -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 -#define DIODE_DIRECTION COL2ROW - -/* define if matrix has ghost */ -//#define MATRIX_HAS_GHOST - -/* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 - -/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ -#define LOCKING_SUPPORT_ENABLE -/* Locking resynchronize hack */ -#define LOCKING_RESYNC_ENABLE - -/* - * Feature disable options - * These options are also useful to firmware size reduction. - */ - -/* disable debug print */ -//#define NO_DEBUG - -/* disable print */ -//#define NO_PRINT - -/* disable action features */ -//#define NO_ACTION_LAYER -//#define NO_ACTION_TAPPING -//#define NO_ACTION_ONESHOT -//#define NO_ACTION_MACRO -//#define NO_ACTION_FUNCTION - -#endif diff --git a/keyboards/chibios_test/keymaps/default/keymap.c b/keyboards/chibios_test/keymaps/default/keymap.c deleted file mode 100644 index 0edc697bf9f..00000000000 --- a/keyboards/chibios_test/keymaps/default/keymap.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -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 . -*/ - -#include QMK_KEYBOARD_H - -const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - {{KC_CAPS}}, // test with KC_CAPS, KC_A, RESET -}; diff --git a/keyboards/chibios_test/ld/MKL26Z64.ld b/keyboards/chibios_test/ld/MKL26Z64.ld deleted file mode 100644 index c4ca8b874cc..00000000000 --- a/keyboards/chibios_test/ld/MKL26Z64.ld +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2013-2016 Fabio Utzig, http://fabioutzig.com - * (C) 2016 flabbergast - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * KL26Z64 memory setup. - */ -MEMORY -{ - flash0 : org = 0x00000000, len = 0x100 - flash1 : org = 0x00000400, len = 0x10 - flash2 : org = 0x00000410, len = 62k - 0x410 - flash3 : org = 0x0000F800, len = 2k - flash4 : org = 0x00000000, len = 0 - flash5 : org = 0x00000000, len = 0 - flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x00000000, len = 0 - ram0 : org = 0x1FFFF800, len = 8k - ram1 : org = 0x00000000, len = 0 - ram2 : org = 0x00000000, len = 0 - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x00000000, len = 0 - ram5 : org = 0x00000000, len = 0 - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* Flash region for the configuration bytes.*/ -SECTIONS -{ - .cfmprotect : ALIGN(4) SUBALIGN(4) - { - KEEP(*(.cfmconfig)) - } > flash1 -} - -/* For each data/text section two region are defined, a virtual region - and a load region (_LMA suffix).*/ - -/* Flash region to be used for exception vectors.*/ -REGION_ALIAS("VECTORS_FLASH", flash0); -REGION_ALIAS("VECTORS_FLASH_LMA", flash0); - -/* Flash region to be used for constructors and destructors.*/ -REGION_ALIAS("XTORS_FLASH", flash2); -REGION_ALIAS("XTORS_FLASH_LMA", flash2); - -/* Flash region to be used for code text.*/ -REGION_ALIAS("TEXT_FLASH", flash2); -REGION_ALIAS("TEXT_FLASH_LMA", flash2); - -/* Flash region to be used for read only data.*/ -REGION_ALIAS("RODATA_FLASH", flash2); -REGION_ALIAS("RODATA_FLASH_LMA", flash2); - -/* Flash region to be used for various.*/ -REGION_ALIAS("VARIOUS_FLASH", flash2); -REGION_ALIAS("VARIOUS_FLASH_LMA", flash2); - -/* Flash region to be used for RAM(n) initialization data.*/ -REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2); - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts.*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); -REGION_ALIAS("DATA_RAM_LMA", flash2); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -__eeprom_workarea_start__ = ORIGIN(flash3); -__eeprom_workarea_size__ = LENGTH(flash3); -__eeprom_workarea_end__ = __eeprom_workarea_start__ + __eeprom_workarea_size__; - -/* Generic rules inclusion.*/ -INCLUDE rules.ld diff --git a/keyboards/chibios_test/ld/STM32F103x8_stm32duino_bootloader.ld b/keyboards/chibios_test/ld/STM32F103x8_stm32duino_bootloader.ld deleted file mode 100644 index f9bfe9c0052..00000000000 --- a/keyboards/chibios_test/ld/STM32F103x8_stm32duino_bootloader.ld +++ /dev/null @@ -1,88 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * ST32F103xB memory setup for use with the maplemini bootloader. - * You will have to - * #define CORTEX_VTOR_INIT 0x5000 - * in your projects chconf.h - */ -MEMORY -{ - flash0 : org = 0x08002000, len = 128k - 0x2000 - flash1 : org = 0x00000000, len = 0 - flash2 : org = 0x00000000, len = 0 - flash3 : org = 0x00000000, len = 0 - flash4 : org = 0x00000000, len = 0 - flash5 : org = 0x00000000, len = 0 - flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x00000000, len = 0 - ram0 : org = 0x20000000, len = 20k - ram1 : org = 0x00000000, len = 0 - ram2 : org = 0x00000000, len = 0 - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x00000000, len = 0 - ram5 : org = 0x00000000, len = 0 - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* For each data/text section two region are defined, a virtual region - and a load region (_LMA suffix).*/ - -/* Flash region to be used for exception vectors.*/ -REGION_ALIAS("VECTORS_FLASH", flash0); -REGION_ALIAS("VECTORS_FLASH_LMA", flash0); - -/* Flash region to be used for constructors and destructors.*/ -REGION_ALIAS("XTORS_FLASH", flash0); -REGION_ALIAS("XTORS_FLASH_LMA", flash0); - -/* Flash region to be used for code text.*/ -REGION_ALIAS("TEXT_FLASH", flash0); -REGION_ALIAS("TEXT_FLASH_LMA", flash0); - -/* Flash region to be used for read only data.*/ -REGION_ALIAS("RODATA_FLASH", flash0); -REGION_ALIAS("RODATA_FLASH_LMA", flash0); - -/* Flash region to be used for various.*/ -REGION_ALIAS("VARIOUS_FLASH", flash0); -REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); - -/* Flash region to be used for RAM(n) initialization data.*/ -REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts.*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); -REGION_ALIAS("DATA_RAM_LMA", flash0); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -/* Generic rules inclusion.*/ -INCLUDE rules.ld diff --git a/keyboards/chibios_test/readme.md b/keyboards/chibios_test/readme.md deleted file mode 100644 index 096ecd6aea4..00000000000 --- a/keyboards/chibios_test/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# ChibiOS Test Keyboards - -Test code for several ARM based ChibiOS boards \ No newline at end of file diff --git a/keyboards/chibios_test/rules.mk b/keyboards/chibios_test/rules.mk deleted file mode 100644 index 45f03be0208..00000000000 --- a/keyboards/chibios_test/rules.mk +++ /dev/null @@ -1,10 +0,0 @@ -#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = yes # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -NKRO_ENABLE = yes # USB Nkey Rollover -CUSTOM_MATRIX = yes # Custom matrix file - -DEFAULT_FOLDER = chibios_test/stm32_f072_onekey \ No newline at end of file diff --git a/keyboards/chibios_test/stm32_f072_onekey/bootloader_defs.h b/keyboards/chibios_test/stm32_f072_onekey/bootloader_defs.h deleted file mode 100644 index 02c48c4e6dc..00000000000 --- a/keyboards/chibios_test/stm32_f072_onekey/bootloader_defs.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here (page 175): - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - * This also requires a patch to chibios: - * /tmk_core/tool/chibios/ch-bootloader-jump.patch - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/keyboards/chibios_test/stm32_f072_onekey/config.h b/keyboards/chibios_test/stm32_f072_onekey/config.h deleted file mode 100644 index bbaf0dc4bfb..00000000000 --- a/keyboards/chibios_test/stm32_f072_onekey/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef KEYBOARDS_CHIBIOS_TEST_STM32_F072_ONEKEY_CONFIG_H_ -#define KEYBOARDS_CHIBIOS_TEST_STM32_F072_ONEKEY_CONFIG_H_ - -#include "../config.h" - - -#endif /* KEYBOARDS_CHIBIOS_TEST_STM32_F072_ONEKEY_CONFIG_H_ */ diff --git a/keyboards/chibios_test/stm32_f072_onekey/led.c b/keyboards/chibios_test/stm32_f072_onekey/led.c deleted file mode 100644 index 18edb8ba89b..00000000000 --- a/keyboards/chibios_test/stm32_f072_onekey/led.c +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2012 Jun Wako - -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 . -*/ - -#include "hal.h" - -#include "led.h" - - -void led_set(uint8_t usb_led) -{ - (void)usb_led; - if (usb_led & (1< - -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 . -*/ - -#include "ch.h" -#include "hal.h" - -/* - * scan matrix - */ -#include "print.h" -#include "debug.h" -#include "util.h" -#include "matrix.h" -#include "wait.h" - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif -static uint8_t debouncing = DEBOUNCE; - -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); - - -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} - -#define LED_ON() do { palSetPad(GPIOC, GPIOC_LED_BLUE) ;} while (0) -#define LED_OFF() do { palClearPad(GPIOC, GPIOC_LED_BLUE); } while (0) -#define LED_TGL() do { palTogglePad(GPIOC, GPIOC_LED_BLUE); } while (0) - -void matrix_init(void) -{ - // initialize row and col - unselect_rows(); - init_cols(); - - // initialize matrix state: all keys off - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - matrix_debouncing[i] = 0; - } - - //debug - debug_matrix = true; - LED_ON(); - wait_ms(500); - LED_OFF(); -} - -uint8_t matrix_scan(void) -{ - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - wait_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } - unselect_rows(); - } - - if (debouncing) { - if (--debouncing) { - wait_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - - return 1; -} - -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1</tmk_core/tool/chibios/ch-bootloader-jump.patch - */ - -// STM32F103* does NOT have an USB bootloader in ROM (only serial), -// so setting anything here does not make much sense -// #define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/keyboards/chibios_test/stm32_f103_onekey/chconf.h b/keyboards/chibios_test/stm32_f103_onekey/chconf.h deleted file mode 100644 index dfb1f9dfb9e..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/chconf.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file templates/chconf.h - * @brief Configuration file template. - * @details A copy of this file must be placed in each project directory, it - * contains the application specific kernel settings. - * - * @addtogroup config - * @details Kernel related settings and hooks. - * @{ - */ - -#ifndef CHCONF_H -#define CHCONF_H - -#define _CHIBIOS_RT_CONF_ - -/*===========================================================================*/ -/** - * @name System timers settings - * @{ - */ -/*===========================================================================*/ - -/** - * @brief System time counter resolution. - * @note Allowed values are 16 or 32 bits. - */ -#define CH_CFG_ST_RESOLUTION 16 - -/** - * @brief System tick frequency. - * @details Frequency of the system timer that drives the system ticks. This - * setting also defines the system tick time unit. - */ -#define CH_CFG_ST_FREQUENCY 2000 - -/** - * @brief Time delta constant for the tick-less mode. - * @note If this value is zero then the system uses the classic - * periodic tick. This value represents the minimum number - * of ticks that is safe to specify in a timeout directive. - * The value one is not valid, timeouts are rounded up to - * this value. - */ -#define CH_CFG_ST_TIMEDELTA 2 - -/** @} */ - -/*===========================================================================*/ -/** - * @name Kernel parameters and options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Round robin interval. - * @details This constant is the number of system ticks allowed for the - * threads before preemption occurs. Setting this value to zero - * disables the preemption for threads with equal priority and the - * round robin becomes cooperative. Note that higher priority - * threads can still preempt, the kernel is always preemptive. - * @note Disabling the round robin preemption makes the kernel more compact - * and generally faster. - * @note The round robin preemption is not supported in tickless mode and - * must be set to zero in that case. - */ -#define CH_CFG_TIME_QUANTUM 0 - -/** - * @brief Managed RAM size. - * @details Size of the RAM area to be managed by the OS. If set to zero - * then the whole available RAM is used. The core memory is made - * available to the heap allocator and/or can be used directly through - * the simplified core memory allocator. - * - * @note In order to let the OS manage the whole RAM the linker script must - * provide the @p __heap_base__ and @p __heap_end__ symbols. - * @note Requires @p CH_CFG_USE_MEMCORE. - */ -#define CH_CFG_MEMCORE_SIZE 0 - -/** - * @brief Idle thread automatic spawn suppression. - * @details When this option is activated the function @p chSysInit() - * does not spawn the idle thread. The application @p main() - * function becomes the idle thread and must implement an - * infinite loop. - */ -#define CH_CFG_NO_IDLE_THREAD FALSE - -/* Use __WFI in the idle thread for waiting. Does lower the power - * consumption. */ -#define CORTEX_ENABLE_WFI_IDLE TRUE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Performance options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief OS optimization. - * @details If enabled then time efficient rather than space efficient code - * is used when two possible implementations exist. - * - * @note This is not related to the compiler optimization options. - * @note The default is @p TRUE. - */ -#define CH_CFG_OPTIMIZE_SPEED TRUE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Subsystem options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Time Measurement APIs. - * @details If enabled then the time measurement APIs are included in - * the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_TM FALSE - -/** - * @brief Threads registry APIs. - * @details If enabled then the registry APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_REGISTRY TRUE - -/** - * @brief Threads synchronization APIs. - * @details If enabled then the @p chThdWait() function is included in - * the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_WAITEXIT TRUE - -/** - * @brief Semaphores APIs. - * @details If enabled then the Semaphores APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_SEMAPHORES TRUE - -/** - * @brief Semaphores queuing mode. - * @details If enabled then the threads are enqueued on semaphores by - * priority rather than in FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special - * requirements. - * @note Requires @p CH_CFG_USE_SEMAPHORES. - */ -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE - -/** - * @brief Mutexes APIs. - * @details If enabled then the mutexes APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MUTEXES TRUE - -/** - * @brief Enables recursive behavior on mutexes. - * @note Recursive mutexes are heavier and have an increased - * memory footprint. - * - * @note The default is @p FALSE. - * @note Requires @p CH_CFG_USE_MUTEXES. - */ -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE - -/** - * @brief Conditional Variables APIs. - * @details If enabled then the conditional variables APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_MUTEXES. - */ -#define CH_CFG_USE_CONDVARS TRUE - -/** - * @brief Conditional Variables APIs with timeout. - * @details If enabled then the conditional variables APIs with timeout - * specification are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_CONDVARS. - */ -#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE - -/** - * @brief Events Flags APIs. - * @details If enabled then the event flags APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_EVENTS TRUE - -/** - * @brief Events Flags APIs with timeout. - * @details If enabled then the events APIs with timeout specification - * are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_EVENTS. - */ -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE - -/** - * @brief Synchronous Messages APIs. - * @details If enabled then the synchronous messages APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MESSAGES TRUE - -/** - * @brief Synchronous Messages queuing mode. - * @details If enabled then messages are served by priority rather than in - * FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special - * requirements. - * @note Requires @p CH_CFG_USE_MESSAGES. - */ -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE - -/** - * @brief Mailboxes APIs. - * @details If enabled then the asynchronous messages (mailboxes) APIs are - * included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_SEMAPHORES. - */ -#define CH_CFG_USE_MAILBOXES TRUE - -/** - * @brief Core Memory Manager APIs. - * @details If enabled then the core memory manager APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MEMCORE TRUE - -/** - * @brief Heap Allocator APIs. - * @details If enabled then the memory heap allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or - * @p CH_CFG_USE_SEMAPHORES. - * @note Mutexes are recommended. - */ -#define CH_CFG_USE_HEAP TRUE - -/** - * @brief Memory Pools Allocator APIs. - * @details If enabled then the memory pools allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MEMPOOLS FALSE - -/** - * @brief Dynamic Threads APIs. - * @details If enabled then the dynamic threads creation APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_WAITEXIT. - * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. - */ -#define CH_CFG_USE_DYNAMIC FALSE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Debug options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Debug option, kernel statistics. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_STATISTICS FALSE - -/** - * @brief Debug option, system state check. - * @details If enabled the correct call protocol for system APIs is checked - * at runtime. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_SYSTEM_STATE_CHECK FALSE - -/** - * @brief Debug option, parameters checks. - * @details If enabled then the checks on the API functions input - * parameters are activated. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_ENABLE_CHECKS FALSE - -/** - * @brief Debug option, consistency checks. - * @details If enabled then all the assertions in the kernel code are - * activated. This includes consistency checks inside the kernel, - * runtime anomalies and port-defined checks. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_ENABLE_ASSERTS FALSE - -/** - * @brief Debug option, trace buffer. - * @details If enabled then the trace buffer is activated. - * - * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. - */ -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED - -/** - * @brief Trace buffer entries. - * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is - * different from @p CH_DBG_TRACE_MASK_DISABLED. - */ -#define CH_DBG_TRACE_BUFFER_SIZE 128 - -/** - * @brief Debug option, stack checks. - * @details If enabled then a runtime stack check is performed. - * - * @note The default is @p FALSE. - * @note The stack check is performed in a architecture/port dependent way. - * It may not be implemented or some ports. - * @note The default failure mode is to halt the system with the global - * @p panic_msg variable set to @p NULL. - */ -#define CH_DBG_ENABLE_STACK_CHECK FALSE - -/** - * @brief Debug option, stacks initialization. - * @details If enabled then the threads working area is filled with a byte - * value when a thread is created. This can be useful for the - * runtime measurement of the used stack. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_FILL_THREADS FALSE - -/** - * @brief Debug option, threads profiling. - * @details If enabled then a field is added to the @p thread_t structure that - * counts the system ticks occurred while executing the thread. - * - * @note The default is @p FALSE. - * @note This debug option is not currently compatible with the - * tickless mode. - */ -#define CH_DBG_THREADS_PROFILING FALSE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Kernel hooks - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Threads descriptor structure extension. - * @details User fields added to the end of the @p thread_t structure. - */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ - -/** - * @brief Threads initialization hook. - * @details User initialization code added to the @p chThdInit() API. - * - * @note It is invoked from within @p chThdInit() and implicitly from all - * the threads creation APIs. - */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} - -/** - * @brief Threads finalization hook. - * @details User finalization code added to the @p chThdExit() API. - */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} - -/** - * @brief Context switch hook. - * @details This hook is invoked just before switching between threads. - */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} - -/** - * @brief ISR enter hook. - */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} - -/** - * @brief ISR exit hook. - */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} - -/** - * @brief Idle thread enter hook. - * @note This hook is invoked within a critical zone, no OS functions - * should be invoked from here. - * @note This macro can be used to activate a power saving mode. - */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} - -/** - * @brief Idle thread leave hook. - * @note This hook is invoked within a critical zone, no OS functions - * should be invoked from here. - * @note This macro can be used to deactivate a power saving mode. - */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} - -/** - * @brief Idle Loop hook. - * @details This hook is continuously invoked by the idle thread loop. - */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} - -/** - * @brief System tick event hook. - * @details This hook is invoked in the system tick handler immediately - * after processing the virtual timers queue. - */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} - -/** - * @brief System halt hook. - * @details This hook is invoked in case to a system halting error before - * the system is halted. - */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} - -/** - * @brief Trace hook. - * @details This hook is invoked each time a new record is written in the - * trace buffer. - */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} - -/** @} */ - -/*===========================================================================*/ -/* Port-specific settings (override port settings defaulted in chcore.h). */ -/*===========================================================================*/ - -#endif /* CHCONF_H */ - -/** @} */ diff --git a/keyboards/chibios_test/stm32_f103_onekey/config.h b/keyboards/chibios_test/stm32_f103_onekey/config.h deleted file mode 100644 index de0b906f358..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/config.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef KEYBOARDS_CHIBIOS_TEST_STM32_F103_ONEKEY_CONFIG_H_ -#define KEYBOARDS_CHIBIOS_TEST_STM32_F103_ONEKEY_CONFIG_H_ - -#include "../config.h" - -#endif /* KEYBOARDS_CHIBIOS_TEST_STM32_F103_ONEKEY_CONFIG_H_ */ diff --git a/keyboards/chibios_test/stm32_f103_onekey/flash.sh b/keyboards/chibios_test/stm32_f103_onekey/flash.sh deleted file mode 100755 index 15501dfa573..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/flash.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -Arduino_STM32_usb_hid/tools/linux/maple_upload ttyACM0 2 1EAF:0003 build/ch.bin diff --git a/keyboards/chibios_test/stm32_f103_onekey/halconf.h b/keyboards/chibios_test/stm32_f103_onekey/halconf.h deleted file mode 100644 index 8b9724b1a30..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/halconf.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file templates/halconf.h - * @brief HAL configuration header. - * @details HAL configuration file, this file allows to enable or disable the - * various device drivers from your application. You may also use - * this file in order to override the device drivers default settings. - * - * @addtogroup HAL_CONF - * @{ - */ - -#ifndef _HALCONF_H_ -#define _HALCONF_H_ - -#include "mcuconf.h" - -/** - * @brief Enables the PAL subsystem. - */ -#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) -#define HAL_USE_PAL TRUE -#endif - -/** - * @brief Enables the ADC subsystem. - */ -#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) -#define HAL_USE_ADC FALSE -#endif - -/** - * @brief Enables the CAN subsystem. - */ -#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) -#define HAL_USE_CAN FALSE -#endif - -/** - * @brief Enables the DAC subsystem. - */ -#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) -#define HAL_USE_DAC FALSE -#endif - -/** - * @brief Enables the EXT subsystem. - */ -#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) -#define HAL_USE_EXT FALSE -#endif - -/** - * @brief Enables the GPT subsystem. - */ -#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) -#define HAL_USE_GPT FALSE -#endif - -/** - * @brief Enables the I2C subsystem. - */ -#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C FALSE -#endif - -/** - * @brief Enables the I2S subsystem. - */ -#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) -#define HAL_USE_I2S FALSE -#endif - -/** - * @brief Enables the ICU subsystem. - */ -#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) -#define HAL_USE_ICU FALSE -#endif - -/** - * @brief Enables the MAC subsystem. - */ -#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) -#define HAL_USE_MAC FALSE -#endif - -/** - * @brief Enables the MMC_SPI subsystem. - */ -#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) -#define HAL_USE_MMC_SPI FALSE -#endif - -/** - * @brief Enables the PWM subsystem. - */ -#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE -#endif - -/** - * @brief Enables the RTC subsystem. - */ -#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) -#define HAL_USE_RTC FALSE -#endif - -/** - * @brief Enables the SDC subsystem. - */ -#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) -#define HAL_USE_SDC FALSE -#endif - -/** - * @brief Enables the SERIAL subsystem. - */ -#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL FALSE -#endif - -/** - * @brief Enables the SERIAL over USB subsystem. - */ -#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL_USB FALSE -#endif - -/** - * @brief Enables the SPI subsystem. - */ -#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) -#define HAL_USE_SPI FALSE -#endif - -/** - * @brief Enables the UART subsystem. - */ -#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) -#define HAL_USE_UART FALSE -#endif - -/** - * @brief Enables the USB subsystem. - */ -#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) -#define HAL_USE_USB TRUE -#endif - -/** - * @brief Enables the WDG subsystem. - */ -#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) -#define HAL_USE_WDG FALSE -#endif - -/*===========================================================================*/ -/* ADC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) -#define ADC_USE_WAIT TRUE -#endif - -/** - * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define ADC_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* CAN driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Sleep mode related APIs inclusion switch. - */ -#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) -#define CAN_USE_SLEEP_MODE TRUE -#endif - -/*===========================================================================*/ -/* I2C driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the mutual exclusion APIs on the I2C bus. - */ -#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define I2C_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* MAC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables an event sources for incoming packets. - */ -#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) -#define MAC_USE_ZERO_COPY FALSE -#endif - -/** - * @brief Enables an event sources for incoming packets. - */ -#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) -#define MAC_USE_EVENTS TRUE -#endif - -/*===========================================================================*/ -/* MMC_SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - * This option is recommended also if the SPI driver does not - * use a DMA channel and heavily loads the CPU. - */ -#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) -#define MMC_NICE_WAITING TRUE -#endif - -/*===========================================================================*/ -/* SDC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Number of initialization attempts before rejecting the card. - * @note Attempts are performed at 10mS intervals. - */ -#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) -#define SDC_INIT_RETRY 100 -#endif - -/** - * @brief Include support for MMC cards. - * @note MMC support is not yet implemented so this option must be kept - * at @p FALSE. - */ -#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) -#define SDC_MMC_SUPPORT FALSE -#endif - -/** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - */ -#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) -#define SDC_NICE_WAITING TRUE -#endif - -/*===========================================================================*/ -/* SERIAL driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Default bit rate. - * @details Configuration parameter, this is the baud rate selected for the - * default configuration. - */ -#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) -#define SERIAL_DEFAULT_BITRATE 38400 -#endif - -/** - * @brief Serial buffers size. - * @details Configuration parameter, you can change the depth of the queue - * buffers depending on the requirements of your application. - * @note The default is 64 bytes for both the transmission and receive - * buffers. - */ -#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_BUFFERS_SIZE 16 -#endif - -/*===========================================================================*/ -/* SERIAL_USB driver related setting. */ -/*===========================================================================*/ - -/** - * @brief Serial over USB buffers size. - * @details Configuration parameter, the buffer size must be a multiple of - * the USB data endpoint maximum packet size. - * @note The default is 64 bytes for both the transmission and receive - * buffers. - */ -#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_SIZE 1 -#endif - -/*===========================================================================*/ -/* SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) -#define SPI_USE_WAIT TRUE -#endif - -/** - * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define SPI_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* USB driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) -#define USB_USE_WAIT TRUE -#endif - -#endif /* _HALCONF_H_ */ - -/** @} */ diff --git a/keyboards/chibios_test/stm32_f103_onekey/led.c b/keyboards/chibios_test/stm32_f103_onekey/led.c deleted file mode 100644 index f5c55f7d9ba..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/led.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2012 Jun Wako - -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 . -*/ - -#include "hal.h" -#include "led.h" - - -void led_set(uint8_t usb_led) -{ - if (usb_led & (1< - -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 . -*/ - -#include "ch.h" -#include "hal.h" - -/* - * scan matrix - */ -#include "print.h" -#include "debug.h" -#include "util.h" -#include "matrix.h" -#include "wait.h" - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif -static uint8_t debouncing = DEBOUNCE; - -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); - - -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} - -/* generic STM32F103C8T6 board */ -#ifdef BOARD_GENERIC_STM32_F103 -#define LED_ON() do { palClearPad(GPIOC, GPIOC_LED) ;} while (0) -#define LED_OFF() do { palSetPad(GPIOC, GPIOC_LED); } while (0) -#define LED_TGL() do { palTogglePad(GPIOC, GPIOC_LED); } while (0) -#endif - -/* Maple Mini */ -#ifdef BOARD_MAPLEMINI_STM32_F103 -#define LED_ON() do { palSetPad(GPIOB, 1) ;} while (0) -#define LED_OFF() do { palClearPad(GPIOB, 1); } while (0) -#define LED_TGL() do { palTogglePad(GPIOB, 1); } while (0) -#endif - -void matrix_init(void) -{ - // initialize row and col - unselect_rows(); - init_cols(); - - // initialize matrix state: all keys off - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - matrix_debouncing[i] = 0; - } - - //debug - debug_matrix = true; - LED_ON(); - wait_ms(500); - LED_OFF(); -} - -uint8_t matrix_scan(void) -{ - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - wait_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } - unselect_rows(); - } - - if (debouncing) { - if (--debouncing) { - wait_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - - return 1; -} - -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1</os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -MCU_FAMILY = STM32 -MCU_SERIES = STM32F1xx -# linker script to use -# it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ -# or /ld/ -# startup code to use -# is should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ -MCU_STARTUP = stm32f1xx -# it should exist either in /os/hal/boards/ -# or /boards -# Cortex version -# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 -MCU = cortex-m3 -# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -ARMV = 7 -# If you want to be able to jump to bootloader from firmware on STM32 MCUs, -# set the correct BOOTLOADER_ADDRESS. Either set it here, or define it in -# ./bootloader_defs.h or in ./boards//bootloader_defs.h (if you have -# a custom board definition that you plan to reuse). -# If you're not setting it here, leave it commented out. -# It is chip dependent, the correct number can be looked up here (page 175): -# http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf -# This also requires a patch to chibios: -# /tmk_core/tool/chibios/ch-bootloader-jump.patch -#STM32_BOOTLOADER_ADDRESS = 0x1FFFC800 \ No newline at end of file diff --git a/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.c b/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.c deleted file mode 100644 index 7fa99bb28d5..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.c +++ /dev/null @@ -1 +0,0 @@ -#include "stm32_f103_onekey.h" diff --git a/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.h b/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.h deleted file mode 100644 index b9ba65a9e99..00000000000 --- a/keyboards/chibios_test/stm32_f103_onekey/stm32_f103_onekey.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef STM32_F103_ONEKEY_H -#define STM32_F103_ONEKEY_H -#include "chibios_test.h" - -#define LAYOUT(k00) {{ k00 }} - -#endif diff --git a/keyboards/chibios_test/teensy_lc_onekey/chconf.h b/keyboards/chibios_test/teensy_lc_onekey/chconf.h deleted file mode 100644 index 3294ac7eeef..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/chconf.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file templates/chconf.h - * @brief Configuration file template. - * @details A copy of this file must be placed in each project directory, it - * contains the application specific kernel settings. - * - * @addtogroup config - * @details Kernel related settings and hooks. - * @{ - */ - -#ifndef CHCONF_H -#define CHCONF_H - -#define _CHIBIOS_RT_CONF_ - -/*===========================================================================*/ -/** - * @name System timers settings - * @{ - */ -/*===========================================================================*/ - -/** - * @brief System time counter resolution. - * @note Allowed values are 16 or 32 bits. - */ -#define CH_CFG_ST_RESOLUTION 32 - -/** - * @brief System tick frequency. - * @details Frequency of the system timer that drives the system ticks. This - * setting also defines the system tick time unit. - */ -#define CH_CFG_ST_FREQUENCY 1000 - -/** - * @brief Time delta constant for the tick-less mode. - * @note If this value is zero then the system uses the classic - * periodic tick. This value represents the minimum number - * of ticks that is safe to specify in a timeout directive. - * The value one is not valid, timeouts are rounded up to - * this value. - */ -#define CH_CFG_ST_TIMEDELTA 0 - -/** @} */ - -/*===========================================================================*/ -/** - * @name Kernel parameters and options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Round robin interval. - * @details This constant is the number of system ticks allowed for the - * threads before preemption occurs. Setting this value to zero - * disables the preemption for threads with equal priority and the - * round robin becomes cooperative. Note that higher priority - * threads can still preempt, the kernel is always preemptive. - * @note Disabling the round robin preemption makes the kernel more compact - * and generally faster. - * @note The round robin preemption is not supported in tickless mode and - * must be set to zero in that case. - */ -#define CH_CFG_TIME_QUANTUM 20 - -/** - * @brief Managed RAM size. - * @details Size of the RAM area to be managed by the OS. If set to zero - * then the whole available RAM is used. The core memory is made - * available to the heap allocator and/or can be used directly through - * the simplified core memory allocator. - * - * @note In order to let the OS manage the whole RAM the linker script must - * provide the @p __heap_base__ and @p __heap_end__ symbols. - * @note Requires @p CH_CFG_USE_MEMCORE. - */ -#define CH_CFG_MEMCORE_SIZE 0 - -/** - * @brief Idle thread automatic spawn suppression. - * @details When this option is activated the function @p chSysInit() - * does not spawn the idle thread. The application @p main() - * function becomes the idle thread and must implement an - * infinite loop. - */ -#define CH_CFG_NO_IDLE_THREAD FALSE - -/* Use __WFI in the idle thread for waiting. Does lower the power - * consumption. */ -#define CORTEX_ENABLE_WFI_IDLE TRUE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Performance options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief OS optimization. - * @details If enabled then time efficient rather than space efficient code - * is used when two possible implementations exist. - * - * @note This is not related to the compiler optimization options. - * @note The default is @p TRUE. - */ -#define CH_CFG_OPTIMIZE_SPEED TRUE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Subsystem options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Time Measurement APIs. - * @details If enabled then the time measurement APIs are included in - * the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_TM FALSE - -/** - * @brief Threads registry APIs. - * @details If enabled then the registry APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_REGISTRY TRUE - -/** - * @brief Threads synchronization APIs. - * @details If enabled then the @p chThdWait() function is included in - * the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_WAITEXIT TRUE - -/** - * @brief Semaphores APIs. - * @details If enabled then the Semaphores APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_SEMAPHORES TRUE - -/** - * @brief Semaphores queuing mode. - * @details If enabled then the threads are enqueued on semaphores by - * priority rather than in FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special - * requirements. - * @note Requires @p CH_CFG_USE_SEMAPHORES. - */ -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE - -/** - * @brief Mutexes APIs. - * @details If enabled then the mutexes APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MUTEXES TRUE - -/** - * @brief Enables recursive behavior on mutexes. - * @note Recursive mutexes are heavier and have an increased - * memory footprint. - * - * @note The default is @p FALSE. - * @note Requires @p CH_CFG_USE_MUTEXES. - */ -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE - -/** - * @brief Conditional Variables APIs. - * @details If enabled then the conditional variables APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_MUTEXES. - */ -#define CH_CFG_USE_CONDVARS TRUE - -/** - * @brief Conditional Variables APIs with timeout. - * @details If enabled then the conditional variables APIs with timeout - * specification are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_CONDVARS. - */ -#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE - -/** - * @brief Events Flags APIs. - * @details If enabled then the event flags APIs are included in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_EVENTS TRUE - -/** - * @brief Events Flags APIs with timeout. - * @details If enabled then the events APIs with timeout specification - * are included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_EVENTS. - */ -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE - -/** - * @brief Synchronous Messages APIs. - * @details If enabled then the synchronous messages APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MESSAGES TRUE - -/** - * @brief Synchronous Messages queuing mode. - * @details If enabled then messages are served by priority rather than in - * FIFO order. - * - * @note The default is @p FALSE. Enable this if you have special - * requirements. - * @note Requires @p CH_CFG_USE_MESSAGES. - */ -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE - -/** - * @brief Mailboxes APIs. - * @details If enabled then the asynchronous messages (mailboxes) APIs are - * included in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_SEMAPHORES. - */ -#define CH_CFG_USE_MAILBOXES TRUE - -/** - * @brief Core Memory Manager APIs. - * @details If enabled then the core memory manager APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MEMCORE TRUE - -/** - * @brief Heap Allocator APIs. - * @details If enabled then the memory heap allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or - * @p CH_CFG_USE_SEMAPHORES. - * @note Mutexes are recommended. - */ -#define CH_CFG_USE_HEAP TRUE - -/** - * @brief Memory Pools Allocator APIs. - * @details If enabled then the memory pools allocator APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - */ -#define CH_CFG_USE_MEMPOOLS TRUE - -/** - * @brief Dynamic Threads APIs. - * @details If enabled then the dynamic threads creation APIs are included - * in the kernel. - * - * @note The default is @p TRUE. - * @note Requires @p CH_CFG_USE_WAITEXIT. - * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. - */ -#define CH_CFG_USE_DYNAMIC TRUE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Debug options - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Debug option, kernel statistics. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_STATISTICS FALSE - -/** - * @brief Debug option, system state check. - * @details If enabled the correct call protocol for system APIs is checked - * at runtime. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_SYSTEM_STATE_CHECK TRUE - -/** - * @brief Debug option, parameters checks. - * @details If enabled then the checks on the API functions input - * parameters are activated. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_ENABLE_CHECKS TRUE - -/** - * @brief Debug option, consistency checks. - * @details If enabled then all the assertions in the kernel code are - * activated. This includes consistency checks inside the kernel, - * runtime anomalies and port-defined checks. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_ENABLE_ASSERTS TRUE - -/** - * @brief Debug option, trace buffer. - * @details If enabled then the trace buffer is activated. - * - * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. - */ -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED - -/** - * @brief Trace buffer entries. - * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is - * different from @p CH_DBG_TRACE_MASK_DISABLED. - */ -#define CH_DBG_TRACE_BUFFER_SIZE 128 - -/** - * @brief Debug option, stack checks. - * @details If enabled then a runtime stack check is performed. - * - * @note The default is @p FALSE. - * @note The stack check is performed in a architecture/port dependent way. - * It may not be implemented or some ports. - * @note The default failure mode is to halt the system with the global - * @p panic_msg variable set to @p NULL. - */ -#define CH_DBG_ENABLE_STACK_CHECK TRUE - -/** - * @brief Debug option, stacks initialization. - * @details If enabled then the threads working area is filled with a byte - * value when a thread is created. This can be useful for the - * runtime measurement of the used stack. - * - * @note The default is @p FALSE. - */ -#define CH_DBG_FILL_THREADS TRUE - -/** - * @brief Debug option, threads profiling. - * @details If enabled then a field is added to the @p thread_t structure that - * counts the system ticks occurred while executing the thread. - * - * @note The default is @p FALSE. - * @note This debug option is not currently compatible with the - * tickless mode. - */ -#define CH_DBG_THREADS_PROFILING FALSE - -/** @} */ - -/*===========================================================================*/ -/** - * @name Kernel hooks - * @{ - */ -/*===========================================================================*/ - -/** - * @brief Threads descriptor structure extension. - * @details User fields added to the end of the @p thread_t structure. - */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ - -/** - * @brief Threads initialization hook. - * @details User initialization code added to the @p chThdInit() API. - * - * @note It is invoked from within @p chThdInit() and implicitly from all - * the threads creation APIs. - */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} - -/** - * @brief Threads finalization hook. - * @details User finalization code added to the @p chThdExit() API. - */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} - -/** - * @brief Context switch hook. - * @details This hook is invoked just before switching between threads. - */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} - -/** - * @brief ISR enter hook. - */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} - -/** - * @brief ISR exit hook. - */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} - -/** - * @brief Idle thread enter hook. - * @note This hook is invoked within a critical zone, no OS functions - * should be invoked from here. - * @note This macro can be used to activate a power saving mode. - */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} - -/** - * @brief Idle thread leave hook. - * @note This hook is invoked within a critical zone, no OS functions - * should be invoked from here. - * @note This macro can be used to deactivate a power saving mode. - */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} - -/** - * @brief Idle Loop hook. - * @details This hook is continuously invoked by the idle thread loop. - */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} - -/** - * @brief System tick event hook. - * @details This hook is invoked in the system tick handler immediately - * after processing the virtual timers queue. - */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} - -/** - * @brief System halt hook. - * @details This hook is invoked in case to a system halting error before - * the system is halted. - */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} - -/** - * @brief Trace hook. - * @details This hook is invoked each time a new record is written in the - * trace buffer. - */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} - -/** @} */ - -/*===========================================================================*/ -/* Port-specific settings (override port settings defaulted in chcore.h). */ -/*===========================================================================*/ - -#endif /* CHCONF_H */ - -/** @} */ diff --git a/keyboards/chibios_test/teensy_lc_onekey/config.h b/keyboards/chibios_test/teensy_lc_onekey/config.h deleted file mode 100644 index d9eb05d2ac2..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/config.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef KEYBOARDS_CHIBIOS_TEST_TEENSY_LC_ONEKEY_CONFIG_H_ -#define KEYBOARDS_CHIBIOS_TEST_TEENSY_LC_ONEKEY_CONFIG_H_ - -#include "../config.h" - -#endif /* KEYBOARDS_CHIBIOS_TEST_TEENSY_LC_ONEKEY_CONFIG_H_ */ diff --git a/keyboards/chibios_test/teensy_lc_onekey/halconf.h b/keyboards/chibios_test/teensy_lc_onekey/halconf.h deleted file mode 100644 index 1b6f2adc206..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/halconf.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file templates/halconf.h - * @brief HAL configuration header. - * @details HAL configuration file, this file allows to enable or disable the - * various device drivers from your application. You may also use - * this file in order to override the device drivers default settings. - * - * @addtogroup HAL_CONF - * @{ - */ - -#ifndef _HALCONF_H_ -#define _HALCONF_H_ - -#include "mcuconf.h" - -/** - * @brief Enables the PAL subsystem. - */ -#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) -#define HAL_USE_PAL TRUE -#endif - -/** - * @brief Enables the ADC subsystem. - */ -#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) -#define HAL_USE_ADC FALSE -#endif - -/** - * @brief Enables the CAN subsystem. - */ -#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) -#define HAL_USE_CAN FALSE -#endif - -/** - * @brief Enables the DAC subsystem. - */ -#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) -#define HAL_USE_DAC FALSE -#endif - -/** - * @brief Enables the EXT subsystem. - */ -#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) -#define HAL_USE_EXT FALSE -#endif - -/** - * @brief Enables the GPT subsystem. - */ -#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) -#define HAL_USE_GPT FALSE -#endif - -/** - * @brief Enables the I2C subsystem. - */ -#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C FALSE -#endif - -/** - * @brief Enables the I2S subsystem. - */ -#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) -#define HAL_USE_I2S FALSE -#endif - -/** - * @brief Enables the ICU subsystem. - */ -#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) -#define HAL_USE_ICU FALSE -#endif - -/** - * @brief Enables the MAC subsystem. - */ -#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) -#define HAL_USE_MAC FALSE -#endif - -/** - * @brief Enables the MMC_SPI subsystem. - */ -#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) -#define HAL_USE_MMC_SPI FALSE -#endif - -/** - * @brief Enables the PWM subsystem. - */ -#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE -#endif - -/** - * @brief Enables the RTC subsystem. - */ -#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) -#define HAL_USE_RTC FALSE -#endif - -/** - * @brief Enables the SDC subsystem. - */ -#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) -#define HAL_USE_SDC FALSE -#endif - -/** - * @brief Enables the SERIAL subsystem. - */ -#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL FALSE -#endif - -/** - * @brief Enables the SERIAL over USB subsystem. - */ -#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL_USB FALSE -#endif - -/** - * @brief Enables the SPI subsystem. - */ -#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) -#define HAL_USE_SPI FALSE -#endif - -/** - * @brief Enables the UART subsystem. - */ -#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) -#define HAL_USE_UART FALSE -#endif - -/** - * @brief Enables the USB subsystem. - */ -#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) -#define HAL_USE_USB TRUE -#endif - -/** - * @brief Enables the WDG subsystem. - */ -#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) -#define HAL_USE_WDG FALSE -#endif - -/*===========================================================================*/ -/* ADC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) -#define ADC_USE_WAIT TRUE -#endif - -/** - * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define ADC_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* CAN driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Sleep mode related APIs inclusion switch. - */ -#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) -#define CAN_USE_SLEEP_MODE TRUE -#endif - -/*===========================================================================*/ -/* I2C driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables the mutual exclusion APIs on the I2C bus. - */ -#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define I2C_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* MAC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables an event sources for incoming packets. - */ -#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) -#define MAC_USE_ZERO_COPY FALSE -#endif - -/** - * @brief Enables an event sources for incoming packets. - */ -#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) -#define MAC_USE_EVENTS TRUE -#endif - -/*===========================================================================*/ -/* MMC_SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - * This option is recommended also if the SPI driver does not - * use a DMA channel and heavily loads the CPU. - */ -#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) -#define MMC_NICE_WAITING TRUE -#endif - -/*===========================================================================*/ -/* SDC driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Number of initialization attempts before rejecting the card. - * @note Attempts are performed at 10mS intervals. - */ -#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) -#define SDC_INIT_RETRY 100 -#endif - -/** - * @brief Include support for MMC cards. - * @note MMC support is not yet implemented so this option must be kept - * at @p FALSE. - */ -#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) -#define SDC_MMC_SUPPORT FALSE -#endif - -/** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - */ -#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) -#define SDC_NICE_WAITING TRUE -#endif - -/*===========================================================================*/ -/* SERIAL driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Default bit rate. - * @details Configuration parameter, this is the baud rate selected for the - * default configuration. - */ -#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) -#define SERIAL_DEFAULT_BITRATE 38400 -#endif - -/** - * @brief Serial buffers size. - * @details Configuration parameter, you can change the depth of the queue - * buffers depending on the requirements of your application. - * @note The default is 64 bytes for both the transmission and receive - * buffers. - */ -#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_BUFFERS_SIZE 16 -#endif - -/*===========================================================================*/ -/* SERIAL_USB driver related setting. */ -/*===========================================================================*/ - -/** - * @brief Serial over USB buffers size. - * @details Configuration parameter, the buffer size must be a multiple of - * the USB data endpoint maximum packet size. - * @note The default is 64 bytes for both the transmission and receive - * buffers. - */ -#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_SIZE 1 -#endif - -/*===========================================================================*/ -/* SPI driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) -#define SPI_USE_WAIT TRUE -#endif - -/** - * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define SPI_USE_MUTUAL_EXCLUSION TRUE -#endif - -/*===========================================================================*/ -/* USB driver related settings. */ -/*===========================================================================*/ - -/** - * @brief Enables synchronous APIs. - * @note Disabling this option saves both code and data space. - */ -#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) -#define USB_USE_WAIT TRUE -#endif - -#endif /* _HALCONF_H_ */ - -/** @} */ - diff --git a/keyboards/chibios_test/teensy_lc_onekey/instructions.md b/keyboards/chibios_test/teensy_lc_onekey/instructions.md deleted file mode 100644 index 66f73bf14b8..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/instructions.md +++ /dev/null @@ -1,97 +0,0 @@ -# Teensy LC, 3.0, 3.1, 3.2 support - -These ARM Teensies are now supported through [ChibiOS](http://chibios.org). - -## Installing the ARM toolchain - -You'll need to install an ARM toolchain, there is now a nice documentation about the two AVR/ARM toolchain : https://docs.qmk.fm/getting_started_build_tools.html and you can just run `sudo util/install_dependencies.sh`. -This toolchain is used instead of `avr-gcc`, which is only for AVR chips. Naturally you'll also need the usual development tools (e.g. `make`), just as in the AVR setting. - -You can find others way with the [gcc ARM embedded](https://launchpad.net/gcc-arm-embedded) website, or using your favourite package manager. After installing, you should be able to run `arm-none-eabi-gcc -v` in the command prompt and get sensible output. - -## Installing ChibiOS - -Next, you'll need ChibiOS. For Teensies, you'll need code from two repositories: [chibios-main](https://github.com/ChibiOS/ChibiOS) and [chibios-contrib](https://github.com/ChibiOS/ChibiOS). - -### If you’re using git - -Run `git submodule sync --recursive && git submodule update --init --recursive`. This will install ChibiOS and ChibiOS-Contrib in the `/lib/` directory. - -### If you’re not using Git - -If you're not using git, you can just download a [zip of chibios from here](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip), unpack the zip, and rename/move the unpacked directory (named `ChibiOS-`) to `lib/chibios/chibios` (so that the file `lib/chibios/chibios/license.txt` exists). Now the same procedure with a [zip of chibios-contrib from here](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip): unpack and move `ChibiOS-Contrib-` to `lib/chibios/chibios-contrib`. - -(If you're using git, you can just clone the two repos: [chibios](https://github.com/ChibiOS/ChibiOS) and [chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib). However - be warned that things may be somewhat out-of-sync (updates at different rates), so you may need to hunt a bit for the right commits.) - -(Why do we need chibios-contrib? Well, the main repo focuses on STM32 chips, and Freescale/NXP Kinetis chips are supported via the Contrib repository.) - -This should be it. Running `make` in `keyboard/teensy_lc_onekey` should create a working firmware in `build/`, called `ch.hex`. - -For more notes about the ChibiOS backend in TMK, see `tmk_core/protocol/chibios/README.md`. - -## About this onekey example - -It's set up for Teensy LC. To use 3.x, you'll need to edit the `Makefile` (and comment out one line in `mcuconf.h`). A sample makefile for Teensy 3.0 is provided as `Makefile.3.0`, can be used without renaming with `make -f Makefile.3.0`. Similarly for Teensy 3.2, there's `Makefile.3.2`. - -## Credits - -TMK itself is written by hasu, original sources [here](https://github.com/tmk/tmk_keyboard). - -The USB support for Kinetis MCUs is due to RedoX. His ChibiOS fork is also [on github](https://github.com/RedoXyde/ChibiOS); but it doesn't include Teensy LC definitions. - -## Features that are not implemented yet - -Currently only the more fancy suspend features are not there (power saving during suspend). The rest should work fine (reports either way are welcome). - -# Matrix programming notes - -The notes below explain what commands can be used to examine and set the status of Teensy pins. - -## ChibiOS pin manipulation basics - -### Pins - -Each pin sits on a "port", each of which comprises at most 32 individual pins. -So for instance "PTC5" from Kinetis manual/datasheet refers to port C (or GPIOA), pin 5. Most functions dealing with pins take 2 parameters which specify the pin -- the first being the port, the second being the pin number. - -Within ChibiOS, there are definitions which simplify this a bit for the Teensies. `TEENSY_PINn_IOPORT` represents the port of the MCU's pin connected Teensy's PIN `n`, and `TEENSY_PINn` represents its MCU's pin number. - -### Mode - -A MCU pin can be in several modes. The basic command to set a pin mode is - - palSetPadMode(TEENSY_PINn_IOPORT, TEENSY_PINn, PAL_MODE_INPUT_PULLUP); - -The last parameter is the mode. For keyboards, the usual ones that are used are `PAL_MODE_INPUT_PULLUP` (input with a pullup), `PAL_MODE_INPUT_PULLDOWN` (input with a pulldown), `PAL_MODE_INPUT` (input floating, a.k.a. Hi-Z), `PAL_MODE_OUTPUT_PUSHPULL` (output in the Arduino sense -- can be then set HIGH or LOW). - -### Setting - -Pins are set HIGH (after they've been put into `OUTPUT_PUSHPULL` mode) by - - palSetPad(TEENSY_PINn_IOPORT, TEENSY_PINn); - -or set LOW by - - palClearPad(TEENSY_PINn_IOPORT, TEENSY_PINn); - -Toggling can be done with - - palTogglePad(TEENSY_PINn_IOPORT, TEENSY_PINn); - -Alternatively, you can use - - palWritePad(TEENSY_PINn_IOPORT, TEENSY_PINn, bit); - -where `bit` is either `PAL_LOW` or `PAL_HIGH` (i.e. `0` or `1`). - -### Reading - -Reading pin status is done with - - palReadPad(TEENSY_PINn_IOPORT, TEENSY_PINn); - -The function returns either `PAL_HIGH` (actually `1`) or `PAL_LOW` (actually `0`). - -### Further docs - -All the commands that are available for pin manipulation through ChibiOS HAL are documented in [ChibiOS PAL driver docs](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html). diff --git a/keyboards/chibios_test/teensy_lc_onekey/led.c b/keyboards/chibios_test/teensy_lc_onekey/led.c deleted file mode 100644 index dfa60c10767..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/led.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2012 Jun Wako - -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 . -*/ - -#include "hal.h" - -#include "led.h" - - -void led_set(uint8_t usb_led) { - if (usb_led & (1< - -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 . -*/ - -#include "ch.h" -#include "hal.h" - -/* - * scan matrix - */ -#include "print.h" -#include "debug.h" -#include "util.h" -#include "matrix.h" -#include "wait.h" - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif -static uint8_t debouncing = DEBOUNCE; - -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); - - -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} - -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} - -#define LED_ON() do { palSetPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13) ;} while (0) -#define LED_OFF() do { palClearPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); } while (0) -#define LED_TGL() do { palTogglePad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); } while (0) - -void matrix_init(void) -{ - // initialize row and col - unselect_rows(); - init_cols(); - - // initialize matrix state: all keys off - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - matrix_debouncing[i] = 0; - } - - //debug - debug_matrix = true; - LED_ON(); - wait_ms(500); - LED_OFF(); -} - -uint8_t matrix_scan(void) -{ - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - wait_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } - unselect_rows(); - } - - if (debouncing) { - if (--debouncing) { - wait_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - - return 1; -} - -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1</os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -# - For Teensies, FAMILY = KINETIS and SERIES is either -# KL2x (LC) or K20x (3.0,3.1,3.2). -MCU_FAMILY = KINETIS -MCU_SERIES = KL2x - -# Linker script to use -# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ -# or /ld/ -# - NOTE: a custom ld script is needed for EEPROM on Teensy LC -# - LDSCRIPT = -# - MKL26Z64 for Teensy LC -# - MK20DX128 for Teensy 3.0 -# - MK20DX256 for Teensy 3.1 and 3.2 -MCU_LDSCRIPT = MKL26Z64 - -# Startup code to use -# - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ -# - STARTUP = -# - kl2x for Teensy LC -# - k20x5 for Teensy 3.0 -# - k20x7 for Teensy 3.1 and 3.2 -MCU_STARTUP = kl2x - -# Board: it should exist either in /os/hal/boards/ -# or /boards -# - BOARD = -# - PJRC_TEENSY_LC for Teensy LC -# - PJRC_TEENSY_3 for Teensy 3.0 -# - PJRC_TEENSY_3_1 for Teensy 3.1 or 3.2 -BOARD = PJRC_TEENSY_LC - -# Cortex version -# Teensy LC is cortex-m0plus; Teensy 3.x are cortex-m4 -MCU = cortex-m0plus - -# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -# I.e. 6 for Teensy LC; 7 for Teensy 3.x -ARMV = 6 \ No newline at end of file diff --git a/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.c b/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.c deleted file mode 100644 index b6c4327932a..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.c +++ /dev/null @@ -1 +0,0 @@ -#include "teensy_lc_onekey.h" diff --git a/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.h b/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.h deleted file mode 100644 index e94c13b663c..00000000000 --- a/keyboards/chibios_test/teensy_lc_onekey/teensy_lc_onekey.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef TEENSY_LC_ONEKEY_H -#define TEENSY_LC_ONEKEY_H -#include "chibios_test.h" - -#define LAYOUT(k00) {{ k00 }} - -#endif diff --git a/keyboards/chibios_test/stm32_f072_onekey/chconf.h b/keyboards/handwired/onekey/stm32f0_disco/chconf.h similarity index 100% rename from keyboards/chibios_test/stm32_f072_onekey/chconf.h rename to keyboards/handwired/onekey/stm32f0_disco/chconf.h diff --git a/keyboards/proton_c/proton_c.h b/keyboards/handwired/onekey/stm32f0_disco/config.h similarity index 83% rename from keyboards/proton_c/proton_c.h rename to keyboards/handwired/onekey/stm32f0_disco/config.h index 159f9975a32..039a1beffda 100644 --- a/keyboards/proton_c/proton_c.h +++ b/keyboards/handwired/onekey/stm32f0_disco/config.h @@ -1,4 +1,4 @@ -/* Copyright 2018 Jack Humbert +/* Copyright 2019 * * 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 @@ -15,4 +15,9 @@ */ #pragma once -#include "quantum.h" + +#include "config_common.h" + +#define MATRIX_COL_PINS { B4 } +#define MATRIX_ROW_PINS { B5 } +#define UNUSED_PINS diff --git a/keyboards/chibios_test/stm32_f072_onekey/halconf.h b/keyboards/handwired/onekey/stm32f0_disco/halconf.h similarity index 99% rename from keyboards/chibios_test/stm32_f072_onekey/halconf.h rename to keyboards/handwired/onekey/stm32f0_disco/halconf.h index 8b9724b1a30..53b2f91e33c 100644 --- a/keyboards/chibios_test/stm32_f072_onekey/halconf.h +++ b/keyboards/handwired/onekey/stm32f0_disco/halconf.h @@ -111,7 +111,7 @@ * @brief Enables the PWM subsystem. */ #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE +#define HAL_USE_PWM TRUE #endif /** diff --git a/keyboards/chibios_test/stm32_f072_onekey/mcuconf.h b/keyboards/handwired/onekey/stm32f0_disco/mcuconf.h similarity index 99% rename from keyboards/chibios_test/stm32_f072_onekey/mcuconf.h rename to keyboards/handwired/onekey/stm32f0_disco/mcuconf.h index faca3defdf0..20c48b611a5 100644 --- a/keyboards/chibios_test/stm32_f072_onekey/mcuconf.h +++ b/keyboards/handwired/onekey/stm32f0_disco/mcuconf.h @@ -120,7 +120,7 @@ #define STM32_PWM_USE_ADVANCED FALSE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE -#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM3 TRUE #define STM32_PWM_TIM1_IRQ_PRIORITY 3 #define STM32_PWM_TIM2_IRQ_PRIORITY 3 #define STM32_PWM_TIM3_IRQ_PRIORITY 3 diff --git a/keyboards/handwired/onekey/stm32f0_disco/readme.md b/keyboards/handwired/onekey/stm32f0_disco/readme.md new file mode 100644 index 00000000000..48d999d69c0 --- /dev/null +++ b/keyboards/handwired/onekey/stm32f0_disco/readme.md @@ -0,0 +1,5 @@ +# STM32F072 Discovery kit onekey + +Supported Hardware: + +To trigger keypress, short together pins *B4* and *B5*. diff --git a/keyboards/chibios_test/stm32_f072_onekey/rules.mk b/keyboards/handwired/onekey/stm32f0_disco/rules.mk similarity index 91% rename from keyboards/chibios_test/stm32_f072_onekey/rules.mk rename to keyboards/handwired/onekey/stm32f0_disco/rules.mk index 91c17c0244c..69639f940ea 100644 --- a/keyboards/chibios_test/stm32_f072_onekey/rules.mk +++ b/keyboards/handwired/onekey/stm32f0_disco/rules.mk @@ -1,7 +1,3 @@ -# project specific files -SRC = matrix.c \ - led.c - ## chip/board settings # the next two should match the directories in # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) @@ -33,6 +29,6 @@ ARMV = 6 # /tmk_core/tool/chibios/ch-bootloader-jump.patch #STM32_BOOTLOADER_ADDRESS = 0x1FFFC800 -# Build Options -# comment out to disable the options. -# \ No newline at end of file +# Options to pass to dfu-util when flashing +DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave +DFU_SUFFIX_ARGS = -p df11 -v 0483 diff --git a/keyboards/proton_c/config.h b/keyboards/proton_c/config.h deleted file mode 100644 index 5ebd17f99ed..00000000000 --- a/keyboards/proton_c/config.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2018 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "config_common.h" - -/* USB Device descriptor parameter */ -#define VENDOR_ID 0xFEED -#define PRODUCT_ID 0x6060 -#define DEVICE_VER 0x0006 -#define MANUFACTURER QMK -#define PRODUCT Proton C -#define DESCRIPTION A compact ortholinear keyboard - -/* key matrix size */ -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -#define MATRIX_ROW_PINS { B9 } -#define MATRIX_COL_PINS { B0 } - -/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 6 - -/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ -//#define LOCKING_SUPPORT_ENABLE -/* Locking resynchronize hack */ -//#define LOCKING_RESYNC_ENABLE - -/* - * Force NKRO - * - * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved - * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the - * makefile for this to work.) - * - * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) - * until the next keyboard reset. - * - * NKRO may prevent your keystrokes from being detected in the BIOS, but it is - * fully operational during normal computer usage. - * - * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) - * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by - * bootmagic, NKRO mode will always be enabled until it is toggled again during a - * power-up. - * - */ -//#define FORCE_NKRO - -/* - * Feature disable options - * These options are also useful to firmware size reduction. - */ - -/* disable debug print */ -//#define NO_DEBUG - -/* disable print */ -//#define NO_PRINT - -/* disable action features */ -//#define NO_ACTION_LAYER -//#define NO_ACTION_TAPPING -//#define NO_ACTION_ONESHOT -//#define NO_ACTION_MACRO -//#define NO_ACTION_FUNCTION - -/* - * MIDI options - */ - -/* Prevent use of disabled MIDI features in the keymap */ -//#define MIDI_ENABLE_STRICT 1 - -/* enable basic MIDI features: - - MIDI notes can be sent when in Music mode is on -*/ -//#define MIDI_BASIC - -/* enable advanced MIDI features: - - MIDI notes can be added to the keymap - - Octave shift and transpose - - Virtual sustain, portamento, and modulation wheel - - etc. -*/ -//#define MIDI_ADVANCED - -/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ -//#define MIDI_TONE_KEYCODE_OCTAVES 1 - -// #define WS2812_LED_N 2 -// #define RGBLED_NUM WS2812_LED_N -// #define WS2812_TIM_N 2 -// #define WS2812_TIM_CH 2 -// #define PORT_WS2812 GPIOA -// #define PIN_WS2812 1 -// #define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA stream for TIMx_UP (look up in reference manual under DMA Channel selection) -//#define WS2812_DMA_CHANNEL 7 // DMA channel for TIMx_UP -//#define WS2812_EXTERNAL_PULLUP diff --git a/keyboards/proton_c/keymaps/default/keymap.c b/keyboards/proton_c/keymaps/default/keymap.c deleted file mode 100644 index a3103432fa7..00000000000 --- a/keyboards/proton_c/keymaps/default/keymap.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 Jack Humbert - * - * 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 . - */ - -#include QMK_KEYBOARD_H - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = {{ KC_A }} -}; diff --git a/keyboards/proton_c/proton_c.c b/keyboards/proton_c/proton_c.c deleted file mode 100644 index 5256343478f..00000000000 --- a/keyboards/proton_c/proton_c.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2018 Jack Humbert - * - * 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 . - */ - -#include "proton_c.h" - -void matrix_init_kb(void) { - // Turn status LED on - setPinOutput(C13); - writePinHigh(C13); - - matrix_init_user(); -} diff --git a/keyboards/proton_c/readme.md b/keyboards/proton_c/readme.md deleted file mode 100644 index 5f27795aec4..00000000000 --- a/keyboards/proton_c/readme.md +++ /dev/null @@ -1,16 +0,0 @@ -Proton C -=== - -![Proton C](https://i.imgur.com/xZrjIqa.jpg) - -A Pro Micro drop-in replacement. - -Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert) -Hardware Supported: QMK Proton C -Hardware Availability: [List of vendors](https://qmk.fm/proton-c) - -Make example for this keyboard (after setting up your build environment): - - make proton_c: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). diff --git a/keyboards/proton_c/rules.mk b/keyboards/proton_c/rules.mk deleted file mode 100644 index 4edc75929eb..00000000000 --- a/keyboards/proton_c/rules.mk +++ /dev/null @@ -1,17 +0,0 @@ -MCU = STM32F303 - -# Build Options -# comment out to disable the options. -# -BACKLIGHT_ENABLE = no -BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration -## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = yes # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -NKRO_ENABLE = yes # USB Nkey Rollover -AUDIO_ENABLE = yes -RGBLIGHT_ENABLE = no -# SERIAL_LINK_ENABLE = yes From fadb69e2031a259248dd575384da8846ba0c2aa3 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 15 Aug 2019 22:01:34 +0100 Subject: [PATCH 27/61] Refactor of lets_split_eh to enable RGB split animations (#6411) --- keyboards/lets_split_eh/config.h | 8 +------ keyboards/lets_split_eh/eh/config.h | 18 +++++++------- keyboards/lets_split_eh/eh/eh.c | 13 ---------- keyboards/lets_split_eh/eh/eh.h | 5 +--- keyboards/lets_split_eh/eh/rules.mk | 2 +- .../lets_split_eh/keymaps/default/keymap.c | 24 +++++++++---------- keyboards/lets_split_eh/lets_split_eh.h | 5 +--- 7 files changed, 23 insertions(+), 52 deletions(-) diff --git a/keyboards/lets_split_eh/config.h b/keyboards/lets_split_eh/config.h index 655d35e1ab2..f07706a834d 100644 --- a/keyboards/lets_split_eh/config.h +++ b/keyboards/lets_split_eh/config.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef CONFIG_H -#define CONFIG_H +#pragma once #include "config_common.h" @@ -35,8 +34,3 @@ along with this program. If not, see . /* Set 0 if debouncing isn't needed */ #define DEBOUNCE 5 - -/* serial.c configuration for split keyboard */ -//#define SOFT_SERIAL_PIN D0 - -#endif diff --git a/keyboards/lets_split_eh/eh/config.h b/keyboards/lets_split_eh/eh/config.h index 59afb39c0f7..43e02665022 100644 --- a/keyboards/lets_split_eh/eh/config.h +++ b/keyboards/lets_split_eh/eh/config.h @@ -16,13 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef EH_CONFIG_H -#define EH_CONFIG_H - -// To let configuration know this is of type EH, which will force I2C irregardless of user config -#define EH -// The 'EH' only uses I2C -#define USE_I2C +#pragma once #include "config_common.h" @@ -40,10 +34,14 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGB_DI_PIN B2 -#define RGBLED_NUM 6 // Number of LEDs (each hand) +#define RGBLED_NUM 12 // Number of LEDs (each hand) +#define RGBLED_SPLIT { 6, 6 } +#define RGBLIGHT_ANIMATIONS /* Split Defines */ #define SPLIT_HAND_PIN D3 +#define SOFT_SERIAL_PIN D0 -#endif - +// The 'EH' has previously forced use of I2C so this default has been kept +// however users can undef to use serial +#define USE_I2C diff --git a/keyboards/lets_split_eh/eh/eh.c b/keyboards/lets_split_eh/eh/eh.c index e748d3ae053..d5a312085d1 100644 --- a/keyboards/lets_split_eh/eh/eh.c +++ b/keyboards/lets_split_eh/eh/eh.c @@ -1,14 +1 @@ #include "lets_split_eh.h" - -void matrix_init_kb(void) { - - // JTAG disable for PORT F. write JTD bit twice within four cycles. - MCUCR |= (1< Date: Thu, 15 Aug 2019 22:03:26 +0100 Subject: [PATCH 28/61] Add an alternative method for keyboard discovery to speed up build (#6073) * Add an alternative method for keyboard discovery to speed up build * Chain MAKEFLAGS for docker_build.sh * Slight improvement to number of items sent to sort * Remove debug line * Fix line escape --- Makefile | 9 ++++++++- util/docker_build.sh | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a6c3ee35b7a..6512f7217e4 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,10 @@ endif override SILENT := false ifndef SUB_IS_SILENT -QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null) +ifndef SKIP_GIT + QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null) +endif + ifneq ($(QMK_VERSION),) $(info QMK Firmware $(QMK_VERSION)) endif @@ -94,6 +97,7 @@ $(eval $(call NEXT_PATH_ELEMENT)) # endif define GET_KEYBOARDS +ifndef ALT_GET_KEYBOARDS All_RULES_MK := $$(patsubst $(ROOT_DIR)/keyboards/%/rules.mk,%,$$(wildcard $(ROOT_DIR)/keyboards/*/rules.mk)) All_RULES_MK += $$(patsubst $(ROOT_DIR)/keyboards/%/rules.mk,%,$$(wildcard $(ROOT_DIR)/keyboards/*/*/rules.mk)) All_RULES_MK += $$(patsubst $(ROOT_DIR)/keyboards/%/rules.mk,%,$$(wildcard $(ROOT_DIR)/keyboards/*/*/*/rules.mk)) @@ -105,6 +109,9 @@ define GET_KEYBOARDS KEYMAPS_MK += $$(patsubst $(ROOT_DIR)/keyboards/%/rules.mk,%,$$(wildcard $(ROOT_DIR)/keyboards/*/*/*/*/keymaps/*/rules.mk)) KEYBOARDS := $$(sort $$(filter-out $$(KEYMAPS_MK), $$(All_RULES_MK))) +else + KEYBOARDS := $(shell find keyboards/ -type f -iname "rules.mk" | grep -v keymaps | sed 's!keyboards/\(.*\)/rules.mk!\1!' | sort | uniq) +endif endef $(eval $(call GET_KEYBOARDS)) diff --git a/util/docker_build.sh b/util/docker_build.sh index 6feeb1f5d26..f36d5bcde5f 100755 --- a/util/docker_build.sh +++ b/util/docker_build.sh @@ -46,5 +46,11 @@ fi dir=$(pwd -W 2>/dev/null) || dir=$PWD # Use Windows path if on Windows # Run container and build firmware -docker run --rm -it $usb_args -w /qmk_firmware/ -v "$dir":/qmk_firmware qmkfm/base_container \ +docker run --rm -it $usb_args \ + -w /qmk_firmware/ \ + -v "$dir":/qmk_firmware \ + -e ALT_GET_KEYBOARDS=true \ + -e SKIP_GIT="$SKIP_GIT" \ + -e MAKEFLAGS="$MAKEFLAGS" \ + qmkfm/base_container \ make "$keyboard${keymap:+:$keymap}${target:+:$target}" From 61b5914a80a7945952dd259cbe70d1e6752259c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20=C4=90or=C4=91evi=C4=87?= Date: Sat, 17 Aug 2019 01:29:29 +0200 Subject: [PATCH 29/61] Fix Clueboard hotswap gen1 not compiling when LED Matrix is disabled (#6427) * Fix Clueboard hotswap gen1 not compiling when LED Matrix is disabled * Move keymap.json to default keymap folder * Revert "Move keymap.json to default keymap folder" This reverts commit 7f28df909d7e4dcc79ab0ff44fe264656b5dfa18. --- keyboards/clueboard/66_hotswap/gen1/gen1.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/keyboards/clueboard/66_hotswap/gen1/gen1.c b/keyboards/clueboard/66_hotswap/gen1/gen1.c index c70f223756c..3bcf74faab7 100644 --- a/keyboards/clueboard/66_hotswap/gen1/gen1.c +++ b/keyboards/clueboard/66_hotswap/gen1/gen1.c @@ -14,15 +14,10 @@ * along with this program. If not, see . */ #include "gen1.h" -#include "is31fl3731-simple.h" - -void matrix_init_kb(void) { -} - -void matrix_scan_kb(void) { -} #ifdef LED_MATRIX_ENABLE + #include "is31fl3731-simple.h" + const is31_led g_is31_leds[LED_DRIVER_LED_COUNT] = { /* Refer to IS31 manual for these locations * driver From 36dd261d06e86ed90997486776f06b286a163cd8 Mon Sep 17 00:00:00 2001 From: Danny Date: Fri, 16 Aug 2019 19:46:41 -0400 Subject: [PATCH 30/61] Add support for different encoder pinout for right half of split keyboard (#6521) * Add support for different encoder pinouts for split keyboard * Update documentation for new encoder pinout feature --- docs/feature_encoders.md | 9 +++++++++ docs/feature_split_keyboard.md | 7 +++++++ quantum/encoder.c | 14 ++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/docs/feature_encoders.md b/docs/feature_encoders.md index bb2d538e7ef..cbf72914e92 100644 --- a/docs/feature_encoders.md +++ b/docs/feature_encoders.md @@ -20,6 +20,15 @@ Additionally, the resolution can be specified in the same file (the default & su #define ENCODER_RESOLUTION 4 +## Split Keyboards + +If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout for the right half like this: + +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + ## Callbacks The callback functions can be inserted into your `.c`: diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md index 4addb1bfd0f..60e0d278c05 100644 --- a/docs/feature_split_keyboard.md +++ b/docs/feature_split_keyboard.md @@ -166,6 +166,13 @@ This allows you to specify a different set of pins for the matrix on the right s This allows you to specify a different set of direct pins for the right side. +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + +This allows you to specify a different set of encoder pins for the right side. + ```c #define RGBLIGHT_SPLIT ``` diff --git a/quantum/encoder.c b/quantum/encoder.c index 31f00c346ba..10d8cf7da0f 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -16,6 +16,9 @@ */ #include "encoder.h" +#ifdef SPLIT_KEYBOARD + #include "split_util.h" +#endif // for memcpy #include @@ -54,6 +57,17 @@ void encoder_update_kb(int8_t index, bool clockwise) { } void encoder_init(void) { +#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) + if (!isLeftHand) { + const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; + const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; + for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { + encoders_pad_a[i] = encoders_pad_a_right[i]; + encoders_pad_b[i] = encoders_pad_b_right[i]; + } + } +#endif + for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { setPinInputHigh(encoders_pad_a[i]); setPinInputHigh(encoders_pad_b[i]); From 0c03811d6affb31d9952e9b4c9c0f5e10fddee8a Mon Sep 17 00:00:00 2001 From: ridingqwerty Date: Fri, 16 Aug 2019 19:54:16 -0400 Subject: [PATCH 31/61] [Keymap] add "ridingqwerty" user and keymap for atreus keyboard (#6533) * add userspace and atreus keymap * cleaning up notes/comments * Update keyboards/atreus/keymaps/ridingqwerty/atreus.c Co-Authored-By: Joel Challis * Update keyboards/atreus/keymaps/ridingqwerty/atreus.c Co-Authored-By: Joel Challis * Create readme.md * remove reference to matrix_init_kb from atreus.c * correct atreus.c * remove unnecessary defines * merge register/unregister sequence into single tapcode * move 'LAYOUT to keymap.c; remove atreus.h * remove TAPPING_TERM from keyboard-level config.h --- .../atreus/keymaps/ridingqwerty/config.h | 13 ++ .../atreus/keymaps/ridingqwerty/keymap.c | 116 ++++++++++++++++++ .../atreus/keymaps/ridingqwerty/readme.md | 1 + .../atreus/keymaps/ridingqwerty/rules.mk | 17 +++ users/ridingqwerty/config.h | 3 + users/ridingqwerty/process_records.c | 33 +++++ users/ridingqwerty/process_records.h | 29 +++++ users/ridingqwerty/ridingqwerty.c | 1 + users/ridingqwerty/ridingqwerty.h | 37 ++++++ users/ridingqwerty/rules.mk | 8 ++ 10 files changed, 258 insertions(+) create mode 100644 keyboards/atreus/keymaps/ridingqwerty/config.h create mode 100644 keyboards/atreus/keymaps/ridingqwerty/keymap.c create mode 100644 keyboards/atreus/keymaps/ridingqwerty/readme.md create mode 100644 keyboards/atreus/keymaps/ridingqwerty/rules.mk create mode 100644 users/ridingqwerty/config.h create mode 100644 users/ridingqwerty/process_records.c create mode 100644 users/ridingqwerty/process_records.h create mode 100644 users/ridingqwerty/ridingqwerty.c create mode 100644 users/ridingqwerty/ridingqwerty.h create mode 100644 users/ridingqwerty/rules.mk diff --git a/keyboards/atreus/keymaps/ridingqwerty/config.h b/keyboards/atreus/keymaps/ridingqwerty/config.h new file mode 100644 index 00000000000..349d7b1c493 --- /dev/null +++ b/keyboards/atreus/keymaps/ridingqwerty/config.h @@ -0,0 +1,13 @@ +#pragma once + +#undef MATRIX_ROWS +#define MATRIX_ROWS 8 + +#undef MATRIX_COLS +#define MATRIX_COLS 6 + +#undef MATRIX_ROW_PINS +#define MATRIX_ROW_PINS { A6, A7, A8, A15, B11, B12, A14, A13 } + +#undef MATRIX_COL_PINS +#define MATRIX_COL_PINS { B5, B4, B3, B2, B1, B0 } diff --git a/keyboards/atreus/keymaps/ridingqwerty/keymap.c b/keyboards/atreus/keymaps/ridingqwerty/keymap.c new file mode 100644 index 00000000000..336df497303 --- /dev/null +++ b/keyboards/atreus/keymaps/ridingqwerty/keymap.c @@ -0,0 +1,116 @@ +/* Copyright 2019 George Koenig + * + * 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 . + */ + +#include QMK_KEYBOARD_H +#include "ridingqwerty.h" + +/* Atreus + ┏━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━┓ ┏━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━┓ + ┃ Q │ W │ E │ R │ T ┃ ┃ Y │ U │ I │ O │ P ┃ + ┠────────┼────────┼────────┼────────┼────────┨ ┠────────┼────────┼────────┼────────┼────────┨ + /┃ ¶ A │ S │ D │ F │ G ┃ ┃ H │ J │ K │ L │ 🔢 ; ┃ + ┠────────┼────────┼────────┼────────┼────────┞━━━━━━━━┳━━━━━━━━┞────────┼────────┼────────┼────────┼────────┨ + /┃ ⇧ Z │ X │ C │ V │ B │ ┃ │ N │ M │ , │ 𝔽 . │ ⇧ / ┃ + ┠────────┼────────┼────────┼────────┼────────┤ ¶ ⎋ ┃ ❦ ⇥ ├────────┼────────┼────────┼────────┼────────┨ + ┃ ⎈ ⎋ │ ⌘ ⇥ │ ⎇ [ │ ⇧ ] │ 🔢 ⌫ │ ┃ │ ★ ␣ │ ⇧ - │ ⎇ = │ ⌘ ' │ ⎈ ↵ ┃ + ┗━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┻━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━┛ + MODS // LAYERS // MODS // +*/ + +#ifdef LAYOUT +#undef LAYOUT +#define LAYOUT( \ + K00, K01, K02, K03, K04, K40, K41, K42, K43, K44, \ + K10, K11, K12, K13, K14, K50, K51, K52, K53, K54, \ + K20, K21, K22, K23, K24, K60, K61, K62, K63, K64, \ + K30, K31, K32, K33, K34, K35, K70, K71, K72, K73, K74, K75 \ +) { \ + { K00, K01, K02, K03, K04, KC_NO }, \ + { K10, K11, K12, K13, K14, KC_NO }, \ + { K20, K21, K22, K23, K24, KC_NO }, \ + { K30, K31, K32, K33, K34, K35 }, \ + { K44, K43, K42, K41, K40, KC_NO }, \ + { K54, K53, K52, K51, K50, KC_NO }, \ + { K64, K63, K62, K61, K60, KC_NO }, \ + { K75, K74, K73, K72, K71, K70 } \ +} +#endif + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_QWERTY] = LAYOUT( /* Qwerty */ + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + ED_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, NM_SCLN, + LS_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, FK_DOT, RS_SLSH, + LC_ESC, LG_TAB, LA_LBRC, LS_RBRC, NM_BSPC, ED_ESC, SC_TAB, SM_SPC, RS_MINS, RA_EQL, RG_QUOT, RC_ENT + ), + [_EDITOR] = LAYOUT( /* ED_A, ED_ESC */ + KC_GRV, _______, KC_END, _______, KC_TAB, _______, _______, KC_INS, _______, KC_PGUP, + KC_HOME, _______, KC_DELT, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_ENT, + _______, _______, _______, _______, _______, KC_PGDN, _______, _______, _______, KC_BSLS, + _______, _______, _______, _______, _______, _______, KC_ENT, _______, _______, _______, _______, _______ + ), + [_NUMBER] = LAYOUT( /* NM_SCLN, NM_BSPC */ + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_6, KC_7, KC_8, KC_9, KC_0, _______, KC_4, KC_5, KC_6, _______, + _______, _______, _______, _______, _______, _______, KC_1, KC_2, KC_3, KC_BSLS, + _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_0, KC_0, KC_DOT, _______, _______ + ), + [_SYMBOL] = LAYOUT( /* SM_SPC */ + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, + KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, _______, _______, _______, KC_COLN, + _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BSLS, + _______, _______, _______, _______, _______, KC_LBRC, KC_RBRC, _______, _______, _______, _______, _______ + ), + [_F_KEYS] = LAYOUT( /* FK_DOT */ + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______, _______, _______, _______, KC_F11, + KC_F11, KC_F12, _______, _______, _______, _______, _______, _______, _______, KC_F12, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [_SECRET] = LAYOUT( /* shhhh... */ + RESET, _______, _______, RUSTY, FUEL, KC_F13, _______, _______, _______, _______, + AR1ST, SYSNOC, _______, _______, _______, _______, _______, _______, OS_LAB, _______, + CDLOCAL, _______, C0RE, VAXIS, _______, _______, MUNKY, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [_FINAL] = LAYOUT( /* . */ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; + +// custom tap/hold keys +uint16_t key_timer; +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case RG_QUOT: + if (record->event.pressed) { + key_timer = timer_read(); + layer_on(_NUMBER); + register_mods(MOD_BIT(KC_RGUI)); + } else { + unregister_mods(MOD_BIT(KC_RGUI)); + layer_off(_NUMBER); + if (timer_elapsed(key_timer) < TAPPING_TERM) { + tap_code(KC_QUOT); + } + } + return false; break; + } + return true; +}; diff --git a/keyboards/atreus/keymaps/ridingqwerty/readme.md b/keyboards/atreus/keymaps/ridingqwerty/readme.md new file mode 100644 index 00000000000..936df360993 --- /dev/null +++ b/keyboards/atreus/keymaps/ridingqwerty/readme.md @@ -0,0 +1 @@ +This is a handwired Atreus42 using a Proton C diff --git a/keyboards/atreus/keymaps/ridingqwerty/rules.mk b/keyboards/atreus/keymaps/ridingqwerty/rules.mk new file mode 100644 index 00000000000..95b257f7584 --- /dev/null +++ b/keyboards/atreus/keymaps/ridingqwerty/rules.mk @@ -0,0 +1,17 @@ +MCU = STM32F303 + +# Build Options +# comment out to disable the options. +# +BACKLIGHT_ENABLE = no +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration +#MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +NKRO_ENABLE = yes # USB Nkey Rollover +AUDIO_ENABLE = yes +RGBLIGHT_ENABLE = no +# SERIAL_LINK_ENABLE = yes +#TAP_DANCE_ENABLE = yes diff --git a/users/ridingqwerty/config.h b/users/ridingqwerty/config.h new file mode 100644 index 00000000000..2461b8b8dd0 --- /dev/null +++ b/users/ridingqwerty/config.h @@ -0,0 +1,3 @@ +#pragma once +#define TAPPING_TERM 175 +#define MACRO_TIMER 5 diff --git a/users/ridingqwerty/process_records.c b/users/ridingqwerty/process_records.c new file mode 100644 index 00000000000..be72883ecb6 --- /dev/null +++ b/users/ridingqwerty/process_records.c @@ -0,0 +1,33 @@ +#include "ridingqwerty.h" + +__attribute__ ((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} + +__attribute__ ((weak)) +bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { + return true; +} + +uint16_t user_key_timer; +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case RG_QUOT: + if (record->event.pressed) { + user_key_timer = timer_read(); + layer_on(_NUMBER); + register_mods(MOD_BIT(KC_RGUI)); + } else { + unregister_mods(MOD_BIT(KC_RGUI)); + layer_off(_NUMBER); + if (timer_elapsed(user_key_timer) < TAPPING_TERM) { + register_code(KC_QUOT); + unregister_code(KC_QUOT); + } + } + return false; break; + } + return process_record_keymap(keycode, record) && + process_record_secrets(keycode, record); +} diff --git a/users/ridingqwerty/process_records.h b/users/ridingqwerty/process_records.h new file mode 100644 index 00000000000..2c453bcd93d --- /dev/null +++ b/users/ridingqwerty/process_records.h @@ -0,0 +1,29 @@ +#pragma once +#include "ridingqwerty.h" + +#if defined(KEYMAP_SAFE_RANGE) + #define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE +#else + #define PLACEHOLDER_SAFE_RANGE SAFE_RANGE +#endif + +bool process_record_secrets(uint16_t keycode, keyrecord_t *record); +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); + +enum userspace_custom_keycodes { + FIRST = PLACEHOLDER_SAFE_RANGE, + RUSTY, + FUEL, + C0RE, + MUNKY, + AR1ST, + VAXIS, + OS_LAB, + CDLOCAL, + SYSNOC, + RG_QUOT, + LAST +}; + +bool process_record_secrets(uint16_t keycode, keyrecord_t *record); +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); diff --git a/users/ridingqwerty/ridingqwerty.c b/users/ridingqwerty/ridingqwerty.c new file mode 100644 index 00000000000..fd39021da53 --- /dev/null +++ b/users/ridingqwerty/ridingqwerty.c @@ -0,0 +1 @@ +#include "ridingqwerty.h" diff --git a/users/ridingqwerty/ridingqwerty.h b/users/ridingqwerty/ridingqwerty.h new file mode 100644 index 00000000000..ae5262567c8 --- /dev/null +++ b/users/ridingqwerty/ridingqwerty.h @@ -0,0 +1,37 @@ +#pragma once + +#include "quantum.h" +#include "process_records.h" + +enum userspace_layers +{ + _QWERTY = 0, + _EDITOR, + _NUMBER, + _SYMBOL, + _F_KEYS, + _DEBUG, + _SECRET, + _FINAL +}; + +// modtaps +#define LS_Z MT(MOD_LSFT, KC_Z) +#define LC_ESC MT(MOD_LCTL, KC_ESC) +#define LG_TAB MT(MOD_LGUI, KC_TAB) +#define LA_LBRC MT(MOD_LALT, KC_LBRC) +#define LS_RBRC MT(MOD_LSFT, KC_RBRC) +#define RS_MINS MT(MOD_RSFT, KC_MINS) +#define RA_EQL MT(MOD_RALT, KC_EQL) +//RG_LMOT defined in process_records.h +#define RC_ENT MT(MOD_RCTL, KC_ENT) +#define RS_SLSH MT(MOD_RSFT, KC_SLSH) +// layertaps +#define ED_A LT(_EDITOR, KC_A) +#define ED_ESC LT(_EDITOR, KC_ESC) +#define NM_SCLN LT(_NUMBER, KC_SCLN) +#define NM_BSPC LT(_NUMBER, KC_BSPC) +#define SM_SPC LT(_SYMBOL, KC_SPC) +#define SC_TAB LT(_SECRET, KC_TAB) +#define FK_DOT LT(_F_KEYS, KC_DOT) + diff --git a/users/ridingqwerty/rules.mk b/users/ridingqwerty/rules.mk new file mode 100644 index 00000000000..9c384674480 --- /dev/null +++ b/users/ridingqwerty/rules.mk @@ -0,0 +1,8 @@ +#LEADER_ENABLE = yes + +SRC += ridingqwerty.c \ + process_records.c + +ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") + SRC += secrets.c +endif From 848f3713ad47ee3979038b44274a5b22f39d36ab Mon Sep 17 00:00:00 2001 From: Dong Zhou Date: Fri, 16 Aug 2019 20:56:15 -0400 Subject: [PATCH 32/61] [Keymap] add niu_mini custom keymaps (#6552) --- .../niu_mini/keymaps/nosarthur/README.md | 35 +++++++++++++++++++ keyboards/niu_mini/keymaps/nosarthur/keymap.c | 8 +++++ .../keymaps/nosarthur/keymap_colemak_dh.json | 1 + .../keymaps/nosarthur/keymap_qwerty.json | 1 + keyboards/niu_mini/keymaps/nosarthur/rules.mk | 4 +++ keyboards/niu_mini/keymaps/readme.md | 1 + 6 files changed, 50 insertions(+) create mode 100644 keyboards/niu_mini/keymaps/nosarthur/README.md create mode 100644 keyboards/niu_mini/keymaps/nosarthur/keymap.c create mode 100644 keyboards/niu_mini/keymaps/nosarthur/keymap_colemak_dh.json create mode 100644 keyboards/niu_mini/keymaps/nosarthur/keymap_qwerty.json create mode 100644 keyboards/niu_mini/keymaps/nosarthur/rules.mk diff --git a/keyboards/niu_mini/keymaps/nosarthur/README.md b/keyboards/niu_mini/keymaps/nosarthur/README.md new file mode 100644 index 00000000000..9d57ceb5f7c --- /dev/null +++ b/keyboards/niu_mini/keymaps/nosarthur/README.md @@ -0,0 +1,35 @@ +# Kbdfans Niu Mini + +Here `keymap.c` is generated by [qmk configurator](https://config.qmk.fm) and +it corresponds to the colemak-dh layout. + +To customize, upload the json file to qmk configurator + +- `keymap_colemak_dh.json`: colemak-dh layout +- `keymap_qwerty.json`: qwerty layout + +Make the modification via the web interface, "compile" and download "keymap only". +Then place the generated `keymap.c` in this folder. + +To flush the firmware, connect your keyboard and run + +``` +make niu_mini:nosarthur:dtu +``` +in the `qmk_firmware` source folder. +There will be some prompts saying no device is found. Click the reset button in +the back of your keyboard and it should work. + +# notes from qmk configurator + +This layout was generated by the QMK API. You can find the JSON data used to +generate this keymap in the file layers.json. + +To make use of this file you will need follow the following steps: + +* Download or Clone QMK Firmware: +* Extract QMK Firmware to a location on your hard drive +* Copy this folder into %s +* You are now ready to compile or use your keymap with the source + +More information can be found in the QMK docs: diff --git a/keyboards/niu_mini/keymaps/nosarthur/keymap.c b/keyboards/niu_mini/keymaps/nosarthur/keymap.c new file mode 100644 index 00000000000..fe719fc8214 --- /dev/null +++ b/keyboards/niu_mini/keymaps/nosarthur/keymap.c @@ -0,0 +1,8 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_planck_mit(KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_MINS, KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_G, KC_K, KC_N, KC_E, KC_I, KC_O, KC_QUOT, KC_LSFT, KC_Z, KC_X, KC_C, KC_D, KC_V, KC_M, KC_H, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_LGUI, TT(3), KC_LALT, KC_LCTL, LT(2,KC_BSPC), KC_SPC, LT(1,KC_ENT), KC_COLN, KC_2, KC_1, KC_0), + [1] = LAYOUT_planck_mit(KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL, KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_MINS, KC_COLN, KC_PIPE, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_LCBR, KC_RCBR, KC_DOT, KC_SLSH, KC_BSLS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_PLUS), + [2] = LAYOUT_planck_mit(KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_PGUP, KC_HOME, KC_UP, KC_END, KC_VOLU, KC_MUTE, KC_NO, KC_LT, KC_GT, KC_LPRN, KC_RPRN, KC_NO, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_VOLD, KC_NO, KC_TRNS, KC_NO, KC_NO, KC_LBRC, KC_RBRC, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS, KC_MPRV, KC_MNXT, KC_MPLY, KC_MSTP), + [3] = LAYOUT_planck_mit(KC_F1, KC_F2, KC_MS_U, KC_F3, KC_F4, KC_7, KC_8, KC_9, KC_MINS, KC_F10, KC_F11, KC_F12, KC_BTN2, KC_MS_L, KC_MS_D, KC_MS_R, KC_F5, KC_4, KC_5, KC_6, KC_PLUS, RGB_HUI, RGB_HUD, RGB_TOG, KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_1, KC_2, KC_3, KC_ENT, KC_ASTR, KC_SLSH, RGB_MOD, KC_TRNS, TO(0), KC_TRNS, KC_BTN1, KC_TRNS, KC_0, KC_DOT, KC_NO, KC_NO, KC_NO, KC_NO) +}; diff --git a/keyboards/niu_mini/keymaps/nosarthur/keymap_colemak_dh.json b/keyboards/niu_mini/keymaps/nosarthur/keymap_colemak_dh.json new file mode 100644 index 00000000000..8dc43350c82 --- /dev/null +++ b/keyboards/niu_mini/keymaps/nosarthur/keymap_colemak_dh.json @@ -0,0 +1 @@ +{"keyboard":"niu_mini","keymap":"22","layout":"LAYOUT_planck_mit","layers":[["KC_TAB","KC_Q","KC_W","KC_F","KC_P","KC_B","KC_J","KC_L","KC_U","KC_Y","KC_SCLN","KC_MINS","KC_ESC","KC_A","KC_R","KC_S","KC_T","KC_G","KC_K","KC_N","KC_E","KC_I","KC_O","KC_QUOT","KC_LSFT","KC_Z","KC_X","KC_C","KC_D","KC_V","KC_M","KC_H","KC_COMM","KC_DOT","KC_SLSH","KC_RSFT","KC_LGUI","TT(3)","KC_LALT","KC_LCTL","LT(2,KC_BSPC)","KC_SPC","LT(1,KC_ENT)","KC_COLN","KC_2","KC_1","KC_0"],["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_EQL","KC_TILD","KC_EXLM","KC_AT","KC_HASH","KC_DLR","KC_PERC","KC_CIRC","KC_AMPR","KC_ASTR","KC_MINS","KC_COLN","KC_PIPE","KC_TRNS","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_LCBR","KC_RCBR","KC_DOT","KC_SLSH","KC_BSLS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_CAPS","KC_TRNS","KC_NO","KC_NO","KC_NO","KC_PLUS"],["KC_TILD","KC_EXLM","KC_AT","KC_HASH","KC_DLR","KC_PERC","KC_PGUP","KC_HOME","KC_UP","KC_END","KC_VOLU","KC_MUTE","KC_NO","KC_LT","KC_GT","KC_LPRN","KC_RPRN","KC_NO","KC_PGDN","KC_LEFT","KC_DOWN","KC_RGHT","KC_VOLD","KC_NO","KC_TRNS","KC_NO","KC_NO","KC_LBRC","KC_RBRC","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_DEL","KC_TRNS","KC_MPRV","KC_MNXT","KC_MPLY","KC_MSTP"],["KC_F1","KC_F2","KC_MS_U","KC_F3","KC_F4","KC_7","KC_8","KC_9","KC_MINS","KC_F10","KC_F11","KC_F12","KC_BTN2","KC_MS_L","KC_MS_D","KC_MS_R","KC_F5","KC_4","KC_5","KC_6","KC_PLUS","RGB_HUI","RGB_HUD","RGB_TOG","KC_TRNS","KC_F6","KC_F7","KC_F8","KC_F9","KC_1","KC_2","KC_3","KC_ENT","KC_ASTR","KC_SLSH","RGB_MOD","KC_TRNS","TO(0)","KC_TRNS","KC_BTN1","KC_TRNS","KC_0","KC_DOT","KC_NO","KC_NO","KC_NO","KC_NO"]],"author":"Dong Zhou","notes":"My awesome keymap"} \ No newline at end of file diff --git a/keyboards/niu_mini/keymaps/nosarthur/keymap_qwerty.json b/keyboards/niu_mini/keymaps/nosarthur/keymap_qwerty.json new file mode 100644 index 00000000000..ec9b945f4f3 --- /dev/null +++ b/keyboards/niu_mini/keymaps/nosarthur/keymap_qwerty.json @@ -0,0 +1 @@ +{"keyboard":"niu_mini","keymap":"14","layout":"LAYOUT_planck_mit","layers":[["KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_MINS","KC_ESC","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_LSFT","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RSFT","KC_LGUI","TT(3)","KC_LALT","KC_LCTL","LT(2,KC_BSPC)","KC_SPC","LT(1,KC_ENT)","KC_3","KC_2","KC_1","KC_0"],["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_EQL","KC_TILD","KC_EXLM","KC_AT","KC_HASH","KC_DLR","KC_PERC","KC_CIRC","KC_AMPR","KC_ASTR","KC_NO","KC_COLN","KC_PIPE","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_LCBR","KC_RCBR","KC_DOT","KC_SLSH","KC_BSLS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_CAPS","KC_TRNS","KC_NO","KC_NO","KC_NO","KC_PLUS"],["KC_TILD","KC_EXLM","KC_AT","KC_HASH","KC_DLR","KC_PERC","KC_NO","KC_NO","KC_UP","KC_VOLD","KC_VOLU","KC_MUTE","KC_NO","KC_LT","KC_GT","KC_LPRN","KC_RPRN","KC_NO","KC_NO","KC_LEFT","KC_DOWN","KC_RGHT","KC_PGDN","KC_PGUP","KC_NO","KC_NO","KC_NO","KC_LBRC","KC_RBRC","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_NO","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_HOME","KC_TRNS","KC_MPRV","KC_MNXT","KC_MPLY","KC_MSTP"],["KC_F1","KC_F2","KC_MS_U","KC_F3","KC_F4","KC_7","KC_8","KC_9","KC_MINS","KC_F10","KC_F11","KC_F12","KC_BTN2","KC_MS_L","KC_MS_D","KC_MS_R","KC_NO","KC_4","KC_5","KC_6","KC_PLUS","RGB_HUI","RGB_HUD","RGB_TOG","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_1","KC_2","KC_3","KC_ENT","KC_ASTR","KC_SLSH","RGB_MOD","KC_TRNS","TO(0)","KC_TRNS","KC_BTN1","KC_TRNS","KC_0","KC_DOT","KC_NO","KC_NO","KC_NO","KC_NO"]],"author":"Dong Zhou","notes":"My awesome keymap"} \ No newline at end of file diff --git a/keyboards/niu_mini/keymaps/nosarthur/rules.mk b/keyboards/niu_mini/keymaps/nosarthur/rules.mk new file mode 100644 index 00000000000..37ba40cdfef --- /dev/null +++ b/keyboards/niu_mini/keymaps/nosarthur/rules.mk @@ -0,0 +1,4 @@ +MOUSEKEY_ENABLE = yes +BACKLIGHT_ENABLE = no +AUDIO_ENABLE = no +CONSOLE_ENABLE = no # Console for debug(+400) diff --git a/keyboards/niu_mini/keymaps/readme.md b/keyboards/niu_mini/keymaps/readme.md index 8a263ed0b4e..6cfda6fe045 100644 --- a/keyboards/niu_mini/keymaps/readme.md +++ b/keyboards/niu_mini/keymaps/readme.md @@ -22,3 +22,4 @@ When adding your keymap to this list, keep it organised alphabetically (select l - **mason** - **planck** Planck default layout - **xtonhasvim** A Planck-like layout with a few tweaks and a vim emulation layer. +- **nosarthur** Custom Colemak-dh layout and qwerty layout From 802c5755065a4519caa24c120c09010f2da56c41 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sat, 17 Aug 2019 17:29:00 +1000 Subject: [PATCH 33/61] Remove backslashes from template keymap (#6548) --- quantum/template/base/keymaps/default/keymap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c index 0e9fad357f0..5eeedd45ef9 100644 --- a/quantum/template/base/keymaps/default/keymap.c +++ b/quantum/template/base/keymaps/default/keymap.c @@ -23,8 +23,8 @@ enum custom_keycodes { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT( /* Base */ - KC_A, KC_1, KC_H, \ - KC_TAB, KC_SPC \ + KC_A, KC_1, KC_H, + KC_TAB, KC_SPC ), }; From c178bbf2e50424ee54fbd3a43609089470129c34 Mon Sep 17 00:00:00 2001 From: Mark Stosberg Date: Sat, 17 Aug 2019 11:18:40 -0400 Subject: [PATCH 34/61] Illustrate the emoji layer (#6555) Now the Emoji layer is easier to visualize. --- keyboards/handwired/promethium/keymaps/priyadi/keymap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c index fbb1ae1d69f..094eb157621 100644 --- a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c +++ b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c @@ -895,13 +895,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Emoji * ,-----------------------------------------------------------------------------------. - * | | | | | | | | | | | | | + * | 💕 | 😢 | 😩 | 😍 | 😏 | 😂 | ♻ | 😒 | 🎶 | 👌 | 😔 | 😌 | * |------+------+------+------+------+-------------+------+------+------+------+------| - * | | | | | | | | | | | | | + * | 👍 | 🙏 | 😁 | 😅 | 😳 | 😊 | ❤ | 👋 | 😘 | 🙌 | 😎 | 🙈 | * |------+------+------+------+------+------+------+------+------+------+------+------| - * | | | | | | | | | | | | | + * | 👎 | 😴 | 👏 | 😭 | ✌ | 💔 | ☀ | 😊 | 😉 | 🌔 | 😕 | 🙉 | * |------+------+------+------+------+------+------+------+------+------+------+------| - * | | | | | | | | | | | | | + * | 💩 | 👀 | 💯 | | 💀 | 😈 | 😇 | 😱 | | 😋 | 😞 | 🙊 | * `-----------------------------------------------------------------------------------' */ [_EMOJI] = LAYOUT( From 683605a9dc285c5e8f6328ec81a29505892287b7 Mon Sep 17 00:00:00 2001 From: kuchosauronad0 <22005492+kuchosauronad0@users.noreply.github.com> Date: Sat, 17 Aug 2019 08:19:35 -0700 Subject: [PATCH 35/61] Userspace kuchosauronad0 (#6541) * initial commit * Update layout. Tweak rules.mk * initial userspace configuration for kuchosauronad0 * modified userspace for kuchosauronad0 * added OSL_UNI * clean up * clean up * style * style * added more unicode * fixed representation * fixed representation * added comments * added comments, restructure * accidently one line * restructure * restructure * added git_lazy(void) * fixed indenting and added missing symbols * fixed indent * fixed indent * update * change tapping_term to 150 * added UNICODEMAP_ENABLE block * replace register with tap_code where possible * formatting * rearrange sequences * clean up * clean up * added unicode layer * disabled tap dance * add files for encoder * removed unnecessary include * removed unnecessary stuff --- keyboards/c39/keymaps/kuchosauronad0/config.h | 43 +++ keyboards/c39/keymaps/kuchosauronad0/keymap.c | 137 ++++++++++ .../c39/keymaps/kuchosauronad0/readme.md | 1 + keyboards/c39/keymaps/kuchosauronad0/rules.mk | 20 ++ users/kuchosauronad0/.gitignore | 3 + users/kuchosauronad0/config.h | 93 +++++++ users/kuchosauronad0/encoder.c | 10 + users/kuchosauronad0/encoder.h | 3 + users/kuchosauronad0/kuchosauronad0.c | 196 ++++++++++++++ users/kuchosauronad0/kuchosauronad0.h | 111 ++++++++ users/kuchosauronad0/leader.c | 84 ++++++ users/kuchosauronad0/leader.h | 6 + users/kuchosauronad0/process_records.c | 244 ++++++++++++++++++ users/kuchosauronad0/process_records.h | 94 +++++++ users/kuchosauronad0/readme.md | 145 +++++++++++ users/kuchosauronad0/rules.mk | 44 ++++ users/kuchosauronad0/tap_dances.c | 57 ++++ users/kuchosauronad0/tap_dances.h | 26 ++ users/kuchosauronad0/template.c | 125 +++++++++ users/kuchosauronad0/template.h | 18 ++ users/kuchosauronad0/unicode.c | 62 +++++ users/kuchosauronad0/unicode.h | 67 +++++ users/kuchosauronad0/wrappers.h | 206 +++++++++++++++ 23 files changed, 1795 insertions(+) create mode 100644 keyboards/c39/keymaps/kuchosauronad0/config.h create mode 100644 keyboards/c39/keymaps/kuchosauronad0/keymap.c create mode 100644 keyboards/c39/keymaps/kuchosauronad0/readme.md create mode 100644 keyboards/c39/keymaps/kuchosauronad0/rules.mk create mode 100644 users/kuchosauronad0/.gitignore create mode 100644 users/kuchosauronad0/config.h create mode 100644 users/kuchosauronad0/encoder.c create mode 100644 users/kuchosauronad0/encoder.h create mode 100644 users/kuchosauronad0/kuchosauronad0.c create mode 100644 users/kuchosauronad0/kuchosauronad0.h create mode 100644 users/kuchosauronad0/leader.c create mode 100644 users/kuchosauronad0/leader.h create mode 100644 users/kuchosauronad0/process_records.c create mode 100644 users/kuchosauronad0/process_records.h create mode 100644 users/kuchosauronad0/readme.md create mode 100644 users/kuchosauronad0/rules.mk create mode 100644 users/kuchosauronad0/tap_dances.c create mode 100644 users/kuchosauronad0/tap_dances.h create mode 100644 users/kuchosauronad0/template.c create mode 100644 users/kuchosauronad0/template.h create mode 100644 users/kuchosauronad0/unicode.c create mode 100644 users/kuchosauronad0/unicode.h create mode 100644 users/kuchosauronad0/wrappers.h diff --git a/keyboards/c39/keymaps/kuchosauronad0/config.h b/keyboards/c39/keymaps/kuchosauronad0/config.h new file mode 100644 index 00000000000..c214ddb7504 --- /dev/null +++ b/keyboards/c39/keymaps/kuchosauronad0/config.h @@ -0,0 +1,43 @@ + +/* +This is the c configuration file for the keymap + +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert +Copyright 2017 Art Ortenburger + +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 . +*/ + +#pragma once + +/* key combination for magic key command */ +#undef IS_COMMAND +#define IS_COMMAND() ( \ + get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LALT)) \ +) + +//#ifdef RGBLIGHT_ENABLE +//#define RGB_DI_PIN D3 +//#define RGBLED_NUM 16 // Number of LEDs +//#define RGBLED_SPLIT { 8, 8 } +// +//#define RGBLIGHT_HUE_STEP 12 +//#define RGBLIGHT_SAT_STEP 12 +//#define RGBLIGHT_VAL_STEP 12 +//#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 2 +//#define RGBLIGHT_EFFECT_SNAKE_LENGTH 2 +//#define RGBLIGHT_EFFECT_BREATHE_CENTER 1 +//#endif // RGBLIGHT_ENABLE + diff --git a/keyboards/c39/keymaps/kuchosauronad0/keymap.c b/keyboards/c39/keymaps/kuchosauronad0/keymap.c new file mode 100644 index 00000000000..738408cc3e9 --- /dev/null +++ b/keyboards/c39/keymaps/kuchosauronad0/keymap.c @@ -0,0 +1,137 @@ +/* +This is the keymap for the keyboard + +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert +Copyright 2017 Art Ortenburger + +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 . +*/ + +#include QMK_KEYBOARD_H +#include "kuchosauronad0.h" + +#ifdef INDICATOR_LIGHTS +extern userspace_config_t userspace_config; + +uint8_t last_mod; +uint8_t last_led; +uint8_t last_osm; +#endif + +#define LAYOUT_collide39_base( \ + K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \ + K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \ + K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A \ + ) \ + LAYOUT_wrapper( \ + MT(MOD_LALT,KC_TAB), K01, K02, K03, K04, K05, LT(RAISE,KC_PGUP), K06, K07, K08, K09, K0A, KC_BSPC, \ + SFT_T(KC_ESC), K11, K12, K13, K14, K15, LT(LOWER,KC_PGDN), K16, K17, K18, K19, K1A, SFT_T(KC_ENT), \ + MT(MOD_LCTL,KC_DEL), K21, K22, K23, K24, K25, KC_SPACE, K26, K27, K28, K29, K2A, KC_LEAD \ + ) +#define LAYOUT_collide39_base_wrapper(...) LAYOUT_collide39_base(__VA_ARGS__) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_QWERTY] = LAYOUT_collide39_base_wrapper( + _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, + _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, + _________________QWERTY_L3_________________, _________________QWERTY_R3_________________ + ), + + [_COLEMAK] = LAYOUT_collide39_base_wrapper( + _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, + _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, + _________________COLEMAK_L3________________, _________________COLEMAK_R3________________ + ), + + [_DVORAK] = LAYOUT_collide39_base_wrapper( + _________________DVORAK_L1_________________, _________________DVORAK_R1_________________, + _________________DVORAK_L2_________________, _________________DVORAK_R2_________________, + _________________DVORAK_L3_________________, _________________DVORAK_R3_________________ + ), + +#ifdef UNICODEMAP_ENABLE + [_UNICODE] = LAYOUT_collide39_base_wrapper( + _______________UNICODE_L1__________________, _______________UNICODE_R1__________________, + _______________UNICODE_L2__________________, _______________UNICODE_R2__________________, + _______________UNICODE_L3__________________, _______________UNICODE_R3__________________ + ), +#endif + [_WORKMAN] = LAYOUT_collide39_base_wrapper( + _________________WORKMAN_L1________________, _________________WORKMAN_R1________________, + _________________WORKMAN_L2________________, _________________WORKMAN_R2________________, + _________________WORKMAN_L3________________, _________________WORKMAN_R3________________ + ), + + [_NORMAN] = LAYOUT_collide39_base_wrapper( + _________________NORMAN_L1_________________, _________________NORMAN_L1_________________, + _________________NORMAN_L2_________________, _________________NORMAN_R2_________________, + _________________NORMAN_L3_________________, _________________NORMAN_R3_________________ + ), + + [_MALTRON] = LAYOUT_collide39_base_wrapper( + _________________MALTRON_L1________________, _________________MALTRON_R1________________, + _________________MALTRON_L2________________, _________________MALTRON_R2________________, + _________________MALTRON_L3________________, _________________MALTRON_R3________________ + ), + + [_EUCALYN] = LAYOUT_collide39_base_wrapper( + _________________EUCALYN_L1________________, _________________EUCALYN_R1________________, + _________________EUCALYN_L2________________, _________________EUCALYN_R2________________, + _________________EUCALYN_L3________________, _________________EUCALYN_R3________________ + ), + + [_CARPLAX] = LAYOUT_collide39_base_wrapper( + _____________CARPLAX_QFMLWY_L1_____________, _____________CARPLAX_QFMLWY_R1_____________, + _____________CARPLAX_QFMLWY_L2_____________, _____________CARPLAX_QFMLWY_R2_____________, + _____________CARPLAX_QFMLWY_L3_____________, _____________CARPLAX_QFMLWY_R3_____________ + ), + + + [_MODS] = LAYOUT_wrapper(\ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [_LOWER] = LAYOUT_wrapper(\ + KC_TILD, _________________LOWER_L1__________________, _______, _________________LOWER_R1__________________, KC_BSPC, + KC_F11, _________________LOWER_L2__________________, _______, _________________LOWER_R2__________________, KC_PIPE, + KC_F12, _________________LOWER_L3__________________, _______, _________________LOWER_R3__________________, _______ + ), + + [_RAISE] = LAYOUT_wrapper(\ + KC_GRV, _________________RAISE_L1__________________, _______, _________________RAISE_R1__________________, KC_BSPC, + _______, _________________RAISE_L2__________________, _______, _________________RAISE_R2__________________, KC_BSLS, + _______, _________________RAISE_L3__________________, _______, _________________RAISE_R3__________________, _______ + ), + + [_ADJUST] = LAYOUT_wrapper(\ + KC_MAKE, _________________ADJUST_L1_________________, _______, _________________ADJUST_R1_________________, KC_RESET, + VRSN, _________________ADJUST_L2_________________, _______, _________________ADJUST_R2_________________, EEP_RST, + TG_MODS, _________________ADJUST_L3_________________, _______, _________________ADJUST_R3_________________, KC_MPLY + ) + +}; + +void matrix_init_keymap(void) { + #ifndef CONVERT_TO_PROTON_C + setPinOutput(D5); + writePinHigh(D5); + setPinOutput(B0); + writePinHigh(B0); + #endif +} + diff --git a/keyboards/c39/keymaps/kuchosauronad0/readme.md b/keyboards/c39/keymaps/kuchosauronad0/readme.md new file mode 100644 index 00000000000..60b971e4eb3 --- /dev/null +++ b/keyboards/c39/keymaps/kuchosauronad0/readme.md @@ -0,0 +1 @@ +# Personal keymap for the collide39 diff --git a/keyboards/c39/keymaps/kuchosauronad0/rules.mk b/keyboards/c39/keymaps/kuchosauronad0/rules.mk new file mode 100644 index 00000000000..e2be2e5acc8 --- /dev/null +++ b/keyboards/c39/keymaps/kuchosauronad0/rules.mk @@ -0,0 +1,20 @@ +BOOTLOADER = caterina +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = no # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = no # Console for debug(+400) +COMMAND_ENABLE = no # Commands for debug and configuration +LEADER_ENABLE = yes # default is yes +TAP_DANCE_ENABLE = no #(+1254) +UNICODE_ENABLE = no #(+1134) +UNICODEMAP_ENABLE = yes +RGBLIGHT_ENABLE = no +AUDIO_ENABLE = no +NKRO_ENABLE = yes + +INDICATOR_LIGHTS = no +MACROS_ENABLED = no +RGBLIGHT_TWINKLE = no +RGBLIGHT_STARTUP_ANIMATION = no + +NO_SECRETS = yes diff --git a/users/kuchosauronad0/.gitignore b/users/kuchosauronad0/.gitignore new file mode 100644 index 00000000000..6878d13e7cd --- /dev/null +++ b/users/kuchosauronad0/.gitignore @@ -0,0 +1,3 @@ +secrets.c +secrets.h +kuchosauronad0_song_list.h diff --git a/users/kuchosauronad0/config.h b/users/kuchosauronad0/config.h new file mode 100644 index 00000000000..f543a4fd257 --- /dev/null +++ b/users/kuchosauronad0/config.h @@ -0,0 +1,93 @@ +#pragma once + + +#ifdef AUDIO_ENABLE + #define AUDIO_CLICKY + #define STARTUP_SONG SONG(RICK_ROLL) + #define GOODBYE_SONG SONG(SONIC_RING) + #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND), \ + SONG(OVERWATCH_THEME) \ + } + + #define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f + // #ifdef RGBLIGHT_ENABLE + // #define NO_MUSIC_MODE + // #endif //RGBLIGHT_ENABLE/ + // #ifndef __arm__ + // #undef NOTE_REST + // #define NOTE_REST 1.00f + // #endif // !__arm__ + +#define UNICODE_SONG_OSX SONG(RICK_ROLL) +#define UNICODE_SONG_LNX SONG(RICK_ROLL) +#define UNICODE_SONG_WIN SONG(RICK_ROLL) +#define UNICODE_SONG_BSD SONG(RICK_ROLL) +#define UNICODE_SONG_WINC SONG(RICK_ROLL) + +#endif // !AUDIO_ENABLE + +#ifdef RGBLIGHT_ENABLE + #define RGBLIGHT_SLEEP + #undef RGBLIGHT_ANIMATIONS + #define RGBLIGHT_EFFECT_BREATHING + #define RGBLIGHT_EFFECT_SNAKE + #define RGBLIGHT_EFFECT_KNIGHT +#endif // !RGBLIGHT_ENABLE + +#ifndef ONESHOT_TAP_TOGGLE + #define ONESHOT_TAP_TOGGLE 2 +#endif // !ONESHOT_TAP_TOGGLE + +#ifndef ONESHOT_TIMEOUT + #define ONESHOT_TIMEOUT 3000 +#endif// !ONESHOT_TIMEOUT + +#ifndef QMK_KEYS_PER_SCAN + #define QMK_KEYS_PER_SCAN 4 +#endif // !QMK_KEYS_PER_SCAN + + + +// this makes it possible to do rolling combos (zx) with keys that +// convert to other keys on hold (z becomes ctrl when you hold it, +// and when this option isn't enabled, z rapidly followed by x +// actually sends Ctrl-x. That's bad.) +#define IGNORE_MOD_TAP_INTERRUPT +#undef PERMISSIVE_HOLD +//#define TAPPING_FORCE_HOLD +//#define RETRO_TAPPING + +#define FORCE_NKRO + +#ifndef TAPPING_TOGGLE + #define TAPPING_TOGGLE 1 +#endif + +#ifdef TAPPING_TERM + #undef TAPPING_TERM +#endif // !TAPPING_TERM +#if defined(KEYBOARD_ergodox_ez) + #define TAPPING_TERM 185 +#elif defined(KEYBOARD_crkbd) + #define TAPPING_TERM 200 +#else + #define TAPPING_TERM 150 +#endif + + +// Disable action_get_macro and fn_actions, since we don't use these +// and it saves on space in the firmware. +#define NO_ACTION_MACRO +#define NO_ACTION_FUNCTION + +#define TAP_CODE_DELAY 5 + +// Enable Leader key +#if defined(LEADER_ENABLE) + #define LEADER_PER_KEY_TIMING + #define LEADER_TIMEOUT 250 +#endif // !LEADER_ENABLE + +#define MACRO_TIMER 5 diff --git a/users/kuchosauronad0/encoder.c b/users/kuchosauronad0/encoder.c new file mode 100644 index 00000000000..1b9b2cb12f7 --- /dev/null +++ b/users/kuchosauronad0/encoder.c @@ -0,0 +1,10 @@ +#include "encoder.h" + +void encoder_update_user(uint8_t index, bool clockwise) { + if (clockwise) { + tap_code(KC_1); + } else { + tap_code(KC_0); + } +} + diff --git a/users/kuchosauronad0/encoder.h b/users/kuchosauronad0/encoder.h new file mode 100644 index 00000000000..078989d52d6 --- /dev/null +++ b/users/kuchosauronad0/encoder.h @@ -0,0 +1,3 @@ +#pragma once +#include "quantum.h" +void encoder_update_user(uint8_t index, bool clockwise); diff --git a/users/kuchosauronad0/kuchosauronad0.c b/users/kuchosauronad0/kuchosauronad0.c new file mode 100644 index 00000000000..21e74a0fae2 --- /dev/null +++ b/users/kuchosauronad0/kuchosauronad0.c @@ -0,0 +1,196 @@ +/* +Copyright 2019 Andre Poley + +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 . +*/ +#include "quantum.h" +#include "kuchosauronad0.h" + +userspace_config_t userspace_config; +#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) + #define KUCHOSAURONAD0_UNICODE_MODE UC_WINC +#else + // set to 2 for UC_WIN, set to 4 for UC_WINC + #define KUCHOSAURONAD0_UNICODE_MODE 2 +#endif + + +// Add reconfigurable functions here, for keymap customization +// This allows for a global, userspace functions, and continued +// customization of the keymap. Use _keymap instead of _user +// functions in the keymaps +__attribute__ ((weak)) +void matrix_init_keymap(void) {} + +// Call user matrix init, set default RGB colors and then +// call the keymap's init function +void matrix_init_user(void) { + userspace_config.raw = eeconfig_read_user(); + + #ifdef BOOTLOADER_CATERINA + DDRD &= ~(1<<5); + PORTD &= ~(1<<5); + + DDRB &= ~(1<<0); + PORTB &= ~(1<<0); + #endif + + #if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) + set_unicode_input_mode(KUCHOSAURONAD0_UNICODE_MODE); + get_unicode_input_mode(); + #endif //UNICODE_ENABLE + matrix_init_keymap(); +} + +__attribute__((weak)) +void keyboard_post_init_keymap(void){ } + +void keyboard_post_init_user(void){ +#ifdef RGBLIGHT_ENABLE + keyboard_post_init_rgb(); +#endif + keyboard_post_init_keymap(); +} + +__attribute__ ((weak)) +void shutdown_keymap(void) {} + +void shutdown_user (void) { + #ifdef RGBLIGHT_ENABLE + rgblight_enable_noeeprom(); + rgblight_mode_noeeprom(1); + rgblight_setrgb_red(); + #endif // RGBLIGHT_ENABLE + #ifdef RGB_MATRIX_ENABLE + // uint16_t timer_start = timer_read(); + // rgb_matrix_set_color_all( 0xFF, 0x00, 0x00 ); + // while(timer_elapsed(timer_start) < 250) { wait_ms(1); } + #endif //RGB_MATRIX_ENABLE + shutdown_keymap(); +} + +__attribute__ ((weak)) +void suspend_power_down_keymap(void) {} + +void suspend_power_down_user(void) { + suspend_power_down_keymap(); +} + +__attribute__ ((weak)) +void suspend_wakeup_init_keymap(void) {} + +void suspend_wakeup_init_user(void) { + suspend_wakeup_init_keymap(); +} + + +__attribute__ ((weak)) +void matrix_scan_keymap(void) {} + +__attribute__ ((weak)) +void matrix_scan_user(void){ + static bool has_ran_yet; + if (!has_ran_yet) { + has_ran_yet = true; + startup_user(); + } + +#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code. +// run_diablo_macro_check(); +#endif // TAP_DANCE_ENABLE + +#ifdef RGBLIGHT_ENABLE + matrix_scan_rgb(); +#endif // RGBLIGHT_ENABLE + + matrix_scan_keymap(); +} + +__attribute__ ((weak)) +uint32_t layer_state_set_keymap (uint32_t state) { + return state; +} + +// on layer change, no matter where the change was initiated +// Then runs keymap's layer change check +uint32_t layer_state_set_user(uint32_t state) { + state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST); +#ifdef RGBLIGHT_ENABLE + state = layer_state_set_rgb(state); +#endif // RGBLIGHT_ENABLE + return layer_state_set_keymap (state); +} + + +__attribute__ ((weak)) +uint32_t default_layer_state_set_keymap (uint32_t state) { + return state; +} + +// Runs state check and changes underglow color and animation +uint32_t default_layer_state_set_user(uint32_t state) { + state = default_layer_state_set_keymap(state); +#if 0 +#ifdef RGBLIGHT_ENABLE + state = default_layer_state_set_rgb(state); +#endif // RGBLIGHT_ENABLE +#endif + return state; +} + +__attribute__ ((weak)) +void led_set_keymap(uint8_t usb_led) {} + +// Any custom LED code goes here. +// So far, I only have keyboard specific code, +// So nothing goes here. +void led_set_user(uint8_t usb_led) { + led_set_keymap(usb_led); +} +__attribute__ ((weak)) +void eeconfig_init_keymap(void) {} + +void eeconfig_init_user(void) { + userspace_config.raw = 0; + userspace_config.rgb_layer_change = true; + eeconfig_update_user(userspace_config.raw); + #if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) + set_unicode_input_mode(KUCHOSAURONAD0_UNICODE_MODE); + get_unicode_input_mode(); + #else + eeprom_update_byte(EECONFIG_UNICODEMODE, KUCHOSAURONAD0_UNICODE_MODE); + #endif +} + +// TMUX stuff +void tmux_prefix(void) { + register_code(KC_LCTL); + tap_code(KC_B); + unregister_code(KC_LCTL); +} + + +void tmux_pane_last(void) { + tmux_prefix(); + tap_code(KC_SCLN); +} + +void tmux_pane_switch_repeat(void) { + tmux_pane_last(); + tap_code(KC_UP); + tap_code(KC_ENT); + tmux_pane_last(); +} + +/* vi: ft=c:tw=80:sw=2:ts=2:sts=2:et */ diff --git a/users/kuchosauronad0/kuchosauronad0.h b/users/kuchosauronad0/kuchosauronad0.h new file mode 100644 index 00000000000..9ea2673dab1 --- /dev/null +++ b/users/kuchosauronad0/kuchosauronad0.h @@ -0,0 +1,111 @@ +#ifndef USERSPACE +#define USERSPACE + +//#pragma once + +#include "quantum.h" + +#include "version.h" +#include "eeprom.h" +#include "wrappers.h" +#include "process_records.h" + +#ifdef TAP_DANCE_ENABLE + #include "tap_dances.h" + #define KC_TMX TD(TD_TMX) // tap1: 't' tap2: +b + #define KC_EOL TD(TD_EOL) // tap1: 'e' tap2: +e + #define KC_BOL TD(TD_BOL) // tap1: 'a' tap2: +a + #define KC_NW TD(TD_NW) // tap1: 'f' tap2: +f + #define KC_PW TD(TD_PW) // tap1: 'b' tap2: +b + #define KC_DW TD(TD_DW) // tap1: 'w' tap2: +w +#endif //!TAP_DANCE_ENABLE +#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) + #include "rgb_stuff.h" +#endif +#if defined(UNICODEMAP_ENABLE) || defined(UNICODE_ENABLE) + #include "unicode.h" +#endif //!UNICODE_ENABLE + +// Keycode aliases +#define TM_X LCTL(KC_B) // Tmux control sequence +// Unix QoL macros +#define MC_BOL LCTL(KC_A) // jump to beginning of line +#define MC_EOL LCTL(KC_E) // jump to end of line +#define MC_NW LALT(KC_F) // next word +#define MC_PW LALT(KC_B) // previous word +#define MC_DW LCTL(KC_W) // delete word + +// Define layer names +enum userspace_layers { + _QWERTY = 0, + _NUMLOCK = 0, + _COLEMAK, + _DVORAK, + _WORKMAN, + _NORMAN, + _MALTRON, + _EUCALYN, + _CARPLAX, + _UNICODE, + _MODS, /* layer 8 now 9*/ + _GAMEPAD, + _DIABLO, + _MACROS, + _MEDIA, + _LOWER, + _RAISE, + _ADJUST, +}; + +bool mod_key_press_timer (uint16_t code, uint16_t mod_code, bool pressed); +bool mod_key_press (uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer); +bool send_game_macro(const char *str, keyrecord_t *record, bool override); +void matrix_init_keymap(void); +void shutdown_keymap(void); +void suspend_power_down_keymap(void); +void suspend_wakeup_init_keymap(void); +void matrix_scan_keymap(void); +uint32_t layer_state_set_keymap (uint32_t state); +uint32_t default_layer_state_set_keymap (uint32_t state); +void led_set_keymap(uint8_t usb_led); +void eeconfig_init_keymap(void); + +void tmux_prefix(void); +void tmux_pane_zoom(void); +void tmux_pane_last(void); +void tmux_pane_switch_repeat(void); +void tmux_pane_switch(uint16_t keycode); + +typedef union { + uint32_t raw; + struct { + bool rgb_layer_change :1; + bool is_overwatch :1; + bool nuke_switch :1; + uint8_t unicode_mod :4; + bool swapped_numbers :1; + }; +} userspace_config_t; + +extern userspace_config_t userspace_config; + +/* +Custom Keycodes for Diablo 3 layer +But since TD() doesn't work when tap dance is disabled +We use custom codes here, so we can substitute the right stuff +*/ +#ifdef TAP_DANCE_ENABLE +#define KC_D3_1 TD(TD_D3_1) +#define KC_D3_2 TD(TD_D3_2) +#define KC_D3_3 TD(TD_D3_3) +#define KC_D3_4 TD(TD_D3_4) +#else // TAP_DANCE_ENABLE +#define KC_D3_1 KC_1 +#define KC_D3_2 KC_2 +#define KC_D3_3 KC_3 +#define KC_D3_4 KC_4 +#endif // TAP_DANCE_ENABLE + +#endif // !USERSPACE + +/* vi: ft=c:tw=80:sw=2:ts=2:sts=2:et */ diff --git a/users/kuchosauronad0/leader.c b/users/kuchosauronad0/leader.c new file mode 100644 index 00000000000..611b70074c7 --- /dev/null +++ b/users/kuchosauronad0/leader.c @@ -0,0 +1,84 @@ +#include "leader.h" + +LEADER_EXTERNS(); + +void matrix_scan_user(void){ + static bool has_ran_yet; + if (!has_ran_yet) { + has_ran_yet = true; + startup_user(); + } + +#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code. +// run_diablo_macro_check(); +#endif // TAP_DANCE_ENABLE + +#ifdef RGBLIGHT_ENABLE + matrix_scan_rgb(); +#endif // RGBLIGHT_ENABLE + + LEADER_DICTIONARY() { + leading = false; + leader_end(); + // Q is for TMUX + // Z is for OS related things + // other single key sequences are mostly for terminals and vim + + SEQ_ONE_KEY(KC_W) { + // Vim + Tmux Macro, when in command mode in vim: write to file, change to the other pane in the current session and repeat the last command + SEND_STRING(":w" SS_TAP(X_ENTER)); + tmux_pane_switch_repeat(); + } + + SEQ_ONE_KEY(KC_T) { + // Send the Tmux Prefix + tmux_prefix(); + } + + SEQ_ONE_KEY(KC_A) { + // Send the Tmux Prefix and press 'right' arrow + tmux_prefix(); + tap_code(KC_RIGHT); + } + + SEQ_TWO_KEYS(KC_T, KC_T) { + // Send the Tmux Prefix to a nested session + tmux_prefix(); + tmux_prefix(); + } + SEQ_TWO_KEYS(KC_Q, KC_A) { + // Switch pane and repeat last action + tmux_pane_switch_repeat(); + } + + SEQ_TWO_KEYS(KC_Z, KC_P){ + // Press windows key, send string 'plex' and press enter + register_code(KC_LGUI); + register_code(KC_S); + unregister_code(KC_S); + + unregister_code(KC_LGUI); + SEND_STRING("plex"); + tap_code(KC_ENTER); + } + + SEQ_TWO_KEYS(KC_Z, KC_F) { + // Open a search + register_code(KC_LGUI); + register_code(KC_S); + unregister_code(KC_S); + unregister_code(KC_LGUI); + } + + SEQ_TWO_KEYS(KC_Z, KC_Z) { + SEND_STRING("https://start.duckduckgo.com"SS_TAP(X_ENTER)); + } + + SEQ_THREE_KEYS(KC_BSPC, KC_BSPC, KC_BSPC){ + // Reset the keyboard + reset_keyboard(); + } + } + + matrix_scan_keymap(); +} diff --git a/users/kuchosauronad0/leader.h b/users/kuchosauronad0/leader.h new file mode 100644 index 00000000000..ed904f3063f --- /dev/null +++ b/users/kuchosauronad0/leader.h @@ -0,0 +1,6 @@ +#pragma once +#include "kuchosauronad0.h" + +#include "leader.h" + +void matrix_scan_user(void); diff --git a/users/kuchosauronad0/process_records.c b/users/kuchosauronad0/process_records.c new file mode 100644 index 00000000000..1eb3043b1c4 --- /dev/null +++ b/users/kuchosauronad0/process_records.c @@ -0,0 +1,244 @@ +#include "kuchosauronad0.h" + +uint16_t copy_paste_timer; + +__attribute__ ((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} + +__attribute__ ((weak)) +bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { + return true; +} + +// Defines actions for my global custom keycodes. Defined in kuchosauronad0.h file +// Then runs the _keymap's record handier if not processed here +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // If console is enabled, it will print the matrix position and status of each key pressed +#ifdef KEYLOGGER_ENABLE + #if defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_keebio_iris_rev2) + xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.row, record->event.key.col, record->event.pressed); + #else + xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); + #endif +#endif //KEYLOGGER_ENABLE + + switch (keycode) { + case KC_QWERTY ... KC_UNICODE: + if (record->event.pressed) { + set_single_persistent_default_layer(keycode - KC_QWERTY); + } + break; + + case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader + if (!record->event.pressed) { + uint8_t temp_mod = get_mods(); + uint8_t temp_osm = get_oneshot_mods(); + clear_mods(); clear_oneshot_mods(); + send_string_with_delay_P(PSTR("make " QMK_KEYBOARD ":" QMK_KEYMAP), TAP_CODE_DELAY); +#ifndef MAKE_BOOTLOADER + if ( ( temp_mod | temp_osm ) & MOD_MASK_SHIFT ) +#endif + { + #if defined(__arm__) + send_string_with_delay_P(PSTR(":dfu-util"), TAP_CODE_DELAY); + #elif defined(BOOTLOADER_DFU) + send_string_with_delay_P(PSTR(":dfu"), TAP_CODE_DELAY); + #elif defined(BOOTLOADER_HALFKAY) + send_string_with_delay_P(PSTR(":teensy"), TAP_CODE_DELAY); + #elif defined(BOOTLOADER_CATERINA) + send_string_with_delay_P(PSTR(":avrdude"), TAP_CODE_DELAY); + #endif // bootloader options + } + if ( ( temp_mod | temp_osm ) & MOD_MASK_CTRL) { send_string_with_delay_P(PSTR(" -j8 --output-sync"), TAP_CODE_DELAY); } + send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY); + } + break; +// FLEDERMAUSLAND + case MC_QT1: // "" + if(record->event.pressed){ + SEND_STRING("\"\""); + tap_code(KC_LEFT); + } + break; + case MC_QT2: // '' + if(record->event.pressed){ + SEND_STRING("''"); + tap_code(KC_LEFT); + } + break; + case MC_QT3: // `' + if(record->event.pressed){ + SEND_STRING("`'"); + tap_code(KC_LEFT); + } + break; + case MC_PAR: // Parenthesis + if(record->event.pressed){ + SEND_STRING("()"); + tap_code(KC_LEFT); + } + break; + case MC_CUR: // Curly bracket + if(record->event.pressed){ + SEND_STRING("{}"); + tap_code(KC_LEFT); + } + break; + case MC_SQR: // Square bracket + if(record->event.pressed){ + SEND_STRING("[]"); + tap_code(KC_LEFT); + } + break; + case MC_ABR: // Angle bracket + if(record->event.pressed){ + SEND_STRING("<>"); + tap_code(KC_LEFT); + } + break; + case MCT_NEW: // New Tmux Session + if(record->event.pressed){ + tmux_prefix(); + SEND_STRING(":neww"); + tap_code(KC_ENT); + } + break; + case MCT_SH: // Tmux horizontal split + if(record->event.pressed){ + tmux_prefix(); + SEND_STRING("%"); + } + break; + case MCT_SV: // Tmux vertical split + if(record->event.pressed){ + tmux_prefix(); + SEND_STRING("\""); + } + break; + case MCT_ZM: // Tmux zoom + if(record->event.pressed){ + tmux_prefix(); + tap_code(KC_Z); + } + break; + case MCT_SCR: // Tmux scroll mode + if(record->event.pressed){ + tmux_prefix(); + tap_code(KC_PGUP); + } + break; + case MCT_UP: // Tmux up + break; + case MCT_DW: // Tmux down + break; + case MCT_LFT: // Tmux left + break; + case MCT_RGT: // Tmux right + tmux_prefix(); + tap_code(KC_RIGHT); + break; + case MCV_B: // Vim begin of line + if(record->event.pressed){ + tap_code(KC_0); + } + break; + case MCV_E: // Vim end of line + if(record->event.pressed){ + SEND_STRING(":vsplit"); + tap_code(KC_ENT); + } + break; + case MCT_F: // Vim for loop + if(record->event.pressed){ + SEND_STRING(":help"); + tap_code(KC_ENT); + } + break; + case VRSN: // Prints firmware version + if (record->event.pressed) { + send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY); + } + break; +// These are a series of gaming macros. +// Only enables for the viterbi, basically, +// to save on firmware space, since it's limited. +#ifdef MACROS_ENABLED + case KC_OVERWATCH: // Toggle's if we hit "ENTER" or "BACKSPACE" to input macros + if (record->event.pressed) { userspace_config.is_overwatch ^= 1; eeconfig_update_user(userspace_config.raw); } +#ifdef RGBLIGHT_ENABLE + userspace_config.is_overwatch ? rgblight_mode_noeeprom(17) : rgblight_mode_noeeprom(18); +#endif //RGBLIGHT_ENABLE + break; + case KC_SALT: + return send_game_macro("Salt, salt, salt...", record, false); + case KC_MORESALT: + return send_game_macro("Please sir, can I have some more salt?!", record, false); + case KC_SALTHARD: + return send_game_macro("Your salt only makes me harder, and even more aggressive!", record, false); + case KC_GOODGAME: + return send_game_macro("Good game, everyone!", record, false); + case KC_GLHF: + return send_game_macro("Good luck, have fun!!!", record, false); + case KC_SYMM: + return send_game_macro("Left click to win!", record, false); + case KC_JUSTGAME: + return send_game_macro("It may be a game, but if you don't want to actually try, please go play AI, so that people that actually want to take the game seriously and \"get good\" have a place to do so without trolls like you throwing games.", record, false); + case KC_TORB: + return send_game_macro("That was positively riveting!", record, false); + case KC_AIM: + send_game_macro("That aim is absolutely amazing. It's almost like you're a machine!", record, true); + return send_game_macro("Wait! That aim is TOO good! You're clearly using an aim hack! CHEATER!", record, false); + case KC_C9: + return send_game_macro("OMG!!! C9!!!", record, false); + case KC_GGEZ: + return send_game_macro("That was a fantastic game, though it was a bit easy. Try harder next time!", record, false); +#endif // MACROS_ENABLED + + case KC_CCCV: // One key copy/paste + if(record->event.pressed){ + copy_paste_timer = timer_read(); + } else { + if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy + register_code(KC_LCTL); + tap_code(KC_C); + unregister_code(KC_LCTL); + } else { // Tap, paste + register_code(KC_LCTL); + tap_code(KC_V); + unregister_code(KC_LCTL); + } + } + break; + +// Unicode +#ifdef UNICODE_ENABLE + case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻ + if (record->event.pressed) { + send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B"); + } + break; + case UC_TABL: // ┬┬ノ( º _ ºノ) + if (record->event.pressed) { + send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 30CE 0029"); + } + break; + case UC_SHRG: // ¯\_(ツ)_/¯ + if (record->event.pressed) { + send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF"); + } + break; + case UC_DISA: // ಠ_ಠ + if (record->event.pressed) { + send_unicode_hex_string("0CA0 005F 0CA0"); + } + break; +#endif //!Unicode +} + return process_record_keymap(keycode, record) && +#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) + process_record_user_rgb(keycode, record) && +#endif // RGBLIGHT_ENABLE + process_record_secrets(keycode, record); +} diff --git a/users/kuchosauronad0/process_records.h b/users/kuchosauronad0/process_records.h new file mode 100644 index 00000000000..1a66beaa77f --- /dev/null +++ b/users/kuchosauronad0/process_records.h @@ -0,0 +1,94 @@ +#pragma once +#include "kuchosauronad0.h" + +#if defined(KEYMAP_SAFE_RANGE) +#define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE +#else +#define PLACEHOLDER_SAFE_RANGE SAFE_RANGE +#endif + +enum userspace_custom_keycodes{ + VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info + KC_QWERTY, // Sets default layer to QWERTY + KC_COLEMAK, // Sets default layer to COLEMAK + KC_DVORAK, // Sets default layer to DVORAK + KC_WORKMAN, // Sets default layer to WORKMAN + KC_NORMAN, // Sets default layer to NORMAN + KC_MALTRON, // Sets default layer to MALTRON + KC_EUCALYN, // Sets default layer to EUCALYN + KC_CARPLAX, // Sets default layer to CARPLAX + KC_UNICODE, // Sets default layer to UNICODE + + KC_MAKE, // Run keyboard's customized make command + KC_RGB_T, // Toggles RGB Layer Indication mode + KC_SECRET_1, + KC_SECRET_2, + KC_SECRET_3, + KC_SECRET_4, + KC_SECRET_5, + KC_CCCV, // Hold to copy, tap to paste + KC_NUKE, // NUCLEAR LAUNCH DETECTED!!! + UC_FLIP, // (ಠ痊ಠ)┻━┻ + UC_TABL, // ┬┬ノ( º _ ºノ) + UC_SHRG, // ¯\_(ツ)_/¯ + UC_DISA, // ಠ_ಠ + + MC_QT1, // "" + MC_QT2, // '' + MC_QT3, // `' + MC_PAR, // Parenthesis + MC_CUR, // Curly bracket + MC_SQR, // Square bracket + MC_ABR, // Angle bracket + MCT_NEW, // New Tmux Session + MCT_SH, // Tmux horizontal split + MCT_SV, // Tmux vertical split + MCT_ZM, // Tmux zoom + MCT_SCR, // Tmux scroll mode + MCT_UP, // Tmux up + MCT_DW, // Tmux down + MCT_LFT, // Tmux left + MCT_RGT, // Tmux right + MCV_B, // Vim begin of line + MCV_E, // Vim end of line + MCT_F, // Vim for loop + MCG_A, // Git add + MCG_C, // Git commit + MCG_P, // Git push + MCG_R, // Git revert + MCG_L, // Git log + MCG_S, // Git status + + NEW_SAFE_RANGE //use "NEWPLACEHOLDER for keymap specific codes + }; + +bool process_record_secrets(uint16_t keycode, keyrecord_t *record); +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) +#define ADJUST MO(_ADJUST) +#define TG_MODS TG(_MODS) +#define TG_GAME TG(_GAMEPAD) +#define OS_LWR OSL(_LOWER) +#define OS_RSE OSL(_RAISE) +#define OS_UNI OSL(_UNICODE) + +#define KC_SEC1 KC_SECRET_1 +#define KC_SEC2 KC_SECRET_2 +#define KC_SEC3 KC_SECRET_3 +#define KC_SEC4 KC_SECRET_4 +#define KC_SEC5 KC_SECRET_5 +#define KC_SEC6 KC_SECRET_6 + +#define QWERTY KC_QWERTY +#define DVORAK KC_DVORAK +#define COLEMAK KC_COLEMAK +#define WORKMAN KC_WORKMAN +#define UNICODE KC_UNICODE + +#define KC_RESET RESET +#define KC_RST KC_RESET + +#define UC_IRNY UC(0x2E2E) +#define UC_CLUE UC(0x203D) diff --git a/users/kuchosauronad0/readme.md b/users/kuchosauronad0/readme.md new file mode 100644 index 00000000000..8211dc189af --- /dev/null +++ b/users/kuchosauronad0/readme.md @@ -0,0 +1,145 @@ +# qmk userspace for kuchosauronad0 +Thanks to drashna and everyone else in the qmk_firmware/users/ directory :) + +# Overview + +## Keyboard Layout Templates +This borrows from @jola5's "Not quite neo" code. This allows me to maintain blocks of keymaps in the userspace, so that I can modify the userspace, and this is reflected in all of the keyboards that use it, at once. + +This makes adding tap/hold mods, or other special keycodes or functions to all keyboards super easy, as it's done to all of them at once. + +The caveat here is that the keymap needs a processor/wrapper, as it doesn't like the substitutions. However, this is as simple as just pushing it through a define. For instance: + +`#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__)` + +Once that's been done and you've switched the keymaps to use the "wrapper", it will read the substitution blocks just fine. + +Credit goes to @jola5 for first implementing this awesome idea. + +## Custom Keycodes +Declared in `process_records.h` and `template.h` and defined in `process_record_user` in template.c + +## Tap Dances +Set `TAP_DANCE_ENABLE = yes` in rules.mk. See file tap_dances.{c,h} + +## Leader Key +Set `LEADER_ENABLE = yes` in rules.mk. +TODO: document tmux / vim / os + +## Unicode +TODO: Set `idk` in `idc` + +## Diablo Layer +Currently not in use. + +# Secret Macros +Set `NO_SECRETS = yes` in rules.mk. + +With help from gitter and Colinta, this adds the ability to add hidden macros from other users. + +First, I have several files that are hidden/excluded from Git/GitHub. These contain everything needed for the macros. To hide these files, open `.git/info/exclude` and add `secrets.c` and `secrets.h` to that file, below the comments. + +And this requires `KC_SECRET_1` through `KC_SECRET_5` to be defined in your `.h` file to define the keycodes for the new macros. + + +### .git/info/exclude + +``` +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ +/users/kuchosauronad0/secrets.c +/users/kuchosauronad0/secrets.h +``` + +Then you can create these files: + +### secrets.c + +```c +#include "kuchosauronad0.h" // replace with your keymap's "h" file, or whatever file stores the keycodes + +#if (__has_include("secrets.h") && !defined(NO_SECRETS)) +#include "secrets.h" +#else +// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware +// And I'm not familiar enough to know which is better or why... +static const char * const secret[] = { + "test1", + "test2", + "test3", + "test4", + "test5" +}; +#endif + +bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo + if (!record->event.pressed) { + clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); + send_string_with_delay(secret[keycode - KC_SECRET_1], MACRO_TIMER); + } + return false; + break; + } + return true; +} +``` + +### secrets.h + +```c +static const char * const secrets[] = { + "secret1", + "secret2", + "secret3", + "secret4", + "secret5" +}; +``` + +Replacing the strings with the codes that you need. + +### name.c + +In the `.c` file, you will want to add this to the top: + +```c +__attribute__ ((weak)) +bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { + return true; +} +``` + +This is so that the function can be called here, and replaced in the `secrets.c` file, and so it won't error out if it doesn't exist. + +And then, in the `process_record_user` function, assuming you have `return process_record_keymap(keycode, record)` here, you'll want to replace the "final" return with the following. Otherwise, you want to replace the `return true;` with `return process_record_secrets(keycode, record);` + +```c + return process_record_keymap(keycode, record) && process_record_secrets(keycode, record); +} +``` + +### rules.mk + +Here, you want your `/users//rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists. To do so, add this block: + +```make +ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") + SRC += secrets.c +endif +``` + +Additionally, if you want to make sure that you can disable the function without messing with the file, you need to add this to your `/users//rules.mk`, so that it catches the flag: + +```make +ifeq ($(strip $(NO_SECRETS)), yes) + OPT_DEFS += -DNO_SECRETS +endif +``` + +Then, if you run `make keyboard:name NO_SECRETS=yes`, it will default to the test strings in your `.c` file, rather than reading from your file. diff --git a/users/kuchosauronad0/rules.mk b/users/kuchosauronad0/rules.mk new file mode 100644 index 00000000000..8610a9b7a1c --- /dev/null +++ b/users/kuchosauronad0/rules.mk @@ -0,0 +1,44 @@ +SRC += kuchosauronad0.c \ + process_records.c + +LINK_TIME_OPTIMIZATION_ENABLE = yes + +#ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") +# SRC += secrets.c +#endif + +ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) + SRC += tap_dances.c +endif + +ifeq ($(strip $(ENCODER_ENABLE)), yes) + SRC += encoder.c +endif + +ifeq ($(strip $(LEADER_ENABLE)), yes) + SRC += leader.c +endif + +ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") + SRC += secrets.c +endif +ifeq ($(strip $(NO_SECRETS)), yes) + OPT_DEFS += -DNO_SECRETS +endif +ifeq ($(strip $(UNICODEMAP_ENABLE)), yes) + SRC += unicode.c +endif + +ifeq ($(strip $(MACROS_ENABLED)), yes) + OPT_DEFS += -DMACROS_ENABLED +endif + +ifdef CONSOLE_ENABLE + ifeq ($(strip $(KEYLOGGER_ENABLE)), yes) + OPT_DEFS += -DKEYLOGGER_ENABLE + endif +endif + +ifeq ($(strip $(MAKE_BOOTLOADER)), yes) + OPT_DEFS += -DMAKE_BOOTLOADER +endif diff --git a/users/kuchosauronad0/tap_dances.c b/users/kuchosauronad0/tap_dances.c new file mode 100644 index 00000000000..4ebb5dc7393 --- /dev/null +++ b/users/kuchosauronad0/tap_dances.c @@ -0,0 +1,57 @@ +#include "tap_dances.h" +void td_parenthesis (qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + SEND_STRING ("\("); + reset_tap_dance (state); + } + else if (state->count == 2) { + SEND_STRING("()" SS_TAP(X_LEFT)); + //tap_code(KC_2); + //tap_code(KC_3); + //tap_code(KC_LEFT); + reset_tap_dance (state); + } + else if (state->count == 3) { + SEND_STRING("[]" SS_TAP(X_LEFT)); + reset_tap_dance (state); + } + else if (state->count == 4) { + SEND_STRING("{}" SS_TAP(X_LEFT)); + reset_tap_dance (state); + } + else if (state->count >= 5) { + SEND_STRING("<>" SS_TAP(X_LEFT)); + reset_tap_dance (state); + } +} + +void safe_reset(qk_tap_dance_state_t *state, void *user_data) { + if (state->count >= 3) { + // Reset the keyboard if you tap the key more than three times + reset_keyboard(); + reset_tap_dance(state); + } +} + +qk_tap_dance_action_t tap_dance_actions[] = { + [TD_RESET] = ACTION_TAP_DANCE_FN(safe_reset), + [TD_NUM1] = ACTION_TAP_DANCE_DOUBLE(KC_1, KC_4), + [TD_NUM2] = ACTION_TAP_DANCE_DOUBLE(KC_2, KC_5), + [TD_NUM3] = ACTION_TAP_DANCE_DOUBLE(KC_3, KC_6), + [TD_QT1] = ACTION_TAP_DANCE_DOUBLE(KC_QUOT, MC_QT1), + [TD_QT2] = ACTION_TAP_DANCE_DOUBLE(LSFT(KC_QUOT), MC_QT2), + [TD_QT3] = ACTION_TAP_DANCE_DOUBLE(KC_GRV, MC_QT3), + + [TD_TMX] = ACTION_TAP_DANCE_DOUBLE(KC_T, TM_X), + [TD_EOL] = ACTION_TAP_DANCE_DOUBLE(KC_E, MC_EOL), // end of line + [TD_BOL] = ACTION_TAP_DANCE_DOUBLE(KC_A, MC_BOL), // beginning of line + [TD_NW] = ACTION_TAP_DANCE_DOUBLE(KC_F, MC_NW), // next word + [TD_PW] = ACTION_TAP_DANCE_DOUBLE(KC_B, MC_PW), // pevious word + [TD_DW] = ACTION_TAP_DANCE_DOUBLE(KC_W, MC_DW), // pevious word + + [TD_SPC] = ACTION_TAP_DANCE_FN(td_parenthesis), // \(, (), [], {}, <> + [TD_PAR] = ACTION_TAP_DANCE_DOUBLE(KC_LPRN, MC_PAR), // () + [TD_SQR] = ACTION_TAP_DANCE_DOUBLE(KC_LBRC, MC_SQR), // [] + [TD_CUR] = ACTION_TAP_DANCE_DOUBLE(LSFT(KC_LCBR), MC_CUR),// {} + [TD_ABR] = ACTION_TAP_DANCE_DOUBLE(LSFT(KC_COMM), MC_ABR),// +}; diff --git a/users/kuchosauronad0/tap_dances.h b/users/kuchosauronad0/tap_dances.h new file mode 100644 index 00000000000..19da8d69dc1 --- /dev/null +++ b/users/kuchosauronad0/tap_dances.h @@ -0,0 +1,26 @@ +#pragma once +#include "kuchosauronad0.h" + +#ifdef TAP_DANCE_ENABLE +enum { + TD_RESET = 0, + TD_SPC, // for special function td_parenthesis testing + TD_NUM1, // compact gaming numpad + TD_NUM2, // + TD_NUM3, // + TD_TMX, // tmux control sequence + TD_EOL, // end of line + TD_BOL, // beginning of line + TD_NW, // next word + TD_PW, // pevious word + TD_DW, // delete word + TD_QT1, // single double quote for ' + TD_QT2, // single double quote for " + TD_QT3, // single double quote for ` + TD_PAR, // single double parenthesis + TD_CUR, // single double curly braces + TD_SQR, // single double square brackets + TD_ABR // single double angle brackets +}; +#endif // TAP_DANCE_ENABLE +void td_parenthesis (qk_tap_dance_state_t *state, void *user_data); diff --git a/users/kuchosauronad0/template.c b/users/kuchosauronad0/template.c new file mode 100644 index 00000000000..475e45d391b --- /dev/null +++ b/users/kuchosauronad0/template.c @@ -0,0 +1,125 @@ +#include "template.h" + + +// Add reconfigurable functions here, for keymap customization +// This allows for a global, userspace functions, and continued +// customization of the keymap. Use _keymap instead of _user +// functions in the keymaps +__attribute__ ((weak)) +void matrix_init_keymap(void) {} + +// Call user matrix init, then call the keymap's init function +void matrix_init_user(void) { + matrix_init_keymap(); +} + + +__attribute__ ((weak)) +void matrix_scan_keymap(void) {} + +// No global matrix scan code, so just run keymap's matix +// scan function +__attribute__ ((weak)) +void matrix_scan_user(void) { + matrix_scan_keymap(); +} + + +__attribute__ ((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} + +// Defines actions tor my global custom keycodes. Defined in drashna.h file +// Then runs the _keymap's recod handier if not processed here, +// And use "NEWPLACEHOLDER" for new safe range +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + + switch (keycode) { + case KC_MAKE: + if (!record->event.pressed) { + SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP +#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU)) + ":dfu" +#elif defined(BOOTLOADER_HALFKAY) + ":teensy" +#elif defined(BOOTLOADER_CATERINA) + ":avrdude" +#endif + SS_TAP(X_ENTER)); + } + return false; + break; + + case VRSN: + if (record->event.pressed) { + SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); + } + return false; + break; + } + return process_record_keymap(keycode, record); +} + + +__attribute__ ((weak)) +uint32_t layer_state_set_keymap (uint32_t state) { + return state; +} + +uint32_t layer_state_set_user (uint32_t state) { + return layer_state_set_keymap (state); +} + + + +__attribute__ ((weak)) +void led_set_keymap(uint8_t usb_led) {} + +void led_set_user(uint8_t usb_led) { + led_set_keymap(usb_led); +} + + + +__attribute__ ((weak)) +void suspend_power_down_keymap(void) {} + +void suspend_power_down_user(void) +{ + suspend_power_down_keymap(); +} + + + +__attribute__ ((weak)) +void suspend_wakeup_init_keymap(void) {} + +void suspend_wakeup_init_user(void) +{ + suspend_wakeup_init_keymap(); + #ifdef KEYBOARD_ergodox_ez + wait_ms(10); + #endif +} + + + +__attribute__ ((weak)) +void startup_keymap(void) {} + +void startup_user (void) { + #ifdef RGBLIGHT_ENABLE + matrix_init_rgb(); + #endif //RGBLIGHT_ENABLE + startup_keymap(); +} + + + +__attribute__ ((weak)) +void shutdown_keymap(void) {} + +void shutdown_user (void) { + shutdown_keymap(); +} diff --git a/users/kuchosauronad0/template.h b/users/kuchosauronad0/template.h new file mode 100644 index 00000000000..dd1c487604a --- /dev/null +++ b/users/kuchosauronad0/template.h @@ -0,0 +1,18 @@ +#ifndef USERSPACE +#define USERSPACE + +#include "quantum.h" +#include "version.h" +#include "eeprom.h" + +// Define layer names +#define BASE 0 + +enum custom_keycodes { + VRSN = SAFE_RANGE, // can always be here + KC_MAKE, + KC_RESET, + NEWPLACEHOLDER //use "NEWPLACEHOLDER for keymap specific codes +}; + +#endif diff --git a/users/kuchosauronad0/unicode.c b/users/kuchosauronad0/unicode.c new file mode 100644 index 00000000000..8b312deb661 --- /dev/null +++ b/users/kuchosauronad0/unicode.c @@ -0,0 +1,62 @@ +#include "unicode.h" + +//#ifdef UNICODEMAP_ENABLE +const uint32_t PROGMEM unicode_map[] = { + [BANG] = 0x0203D,// ‽ + [IRONY] = 0x02E2E,// ⸮ + [DEGREE] = 0x000B0,// ° + [THINK] = 0x1F914,// 🤔 + [GRIN] = 0x1F600,// � + [MONOCL] = 0x1F9D0,// 🧐 + [DRUG0] = 0x1F92A,// 🤪 + [DRUG1] = 0x1F974,// 🥴 + [CLOWN] = 0x1F921,// 🤡 + [MNDBLWN] = 0x1F92F,// 🤯 + [MONEY] = 0x1F911,// 🤑 + [SHTUP] = 0x1F910,// 🤐 + [PARTY] = 0x1F973,// 🥳 + [SMRK] = 0x1F60F,// 😏 + [WEARY] = 0x1F629,// 😩 + [UNAMU] = 0x1F612,// 😒 + [SPY] = 0x1F575,//🕵 + [DAFUQ] = 0x1F47A,// 👺 + [FIST0] = 0x1F91B,// 🤛 + [FIST1] = 0x1F91C,// 🤜 + [FIST2] = 0x270A, // ✊ + [FIST3] = 0x1F44A,// 👊 + [WIFIHAND] = 0x1F44B,// 👋 + [OKOK] = 0x1F44C,// 👌 + [EFFU] = 0x1F595,// 🖕 + [SPOCK] = 0x1F596,// 🖖 + [INUP] = 0x1F446,// 👆 + [THDN] = 0x1F44E,// 👎 + [THUP] = 0x1F44D,// 👍 + [TUMBLER] = 0x1F943,// 🥃 + [DRAGON0] = 0x1F409,// 🐉 + [DRAGON1] = 0x1F432,// 🐲 + [TIGER0] = 0x1F405,// 🐅 + [TIGER1] = 0x1F42F,// 🐯 + [COOL] = 0x1F192,// 🆒 + [UCHART] = 0x1F4C8,// 📈 + [DCHART] = 0x1F4C9,// 📉 + [BCHART] = 0x1F4CA,// 📊 + [NOPRCY] = 0x1F572,// 🕲 + [PRCY] = 0x1F571,// 🕱 + [BBB] = 0x1F171,// 🅱 + [POO] = 0x1F4A9,// 💩 + [HUNDR] = 0x1F4AF,// 💯 + [EGGPL] = 0x1F346,// 🍆 + [WATER] = 0x1F4A6,// 💦 + [LIT] = 0x1F525,// 🔥 + [SNEK] = 0x1F40D,// 🐍 + [PENGUIN] = 0x1F427,// 🐧 + [BOAR] = 0x1F417,// 🐗 + [MONKEY] = 0x1F412,// 🐒 + [CHICK] = 0x1F425,// 🐥 + [DASH] = 0x1F4A8,// 💨 + [DIZZY] = 0x1F4AB,// 💫 + [KEEB] = 0x1F5AE,// 🖮 + [HOLE] = 0x1F573,// 🕳 + [SAUCER] = 0x1F6F8// 🛸 + }; +//#endif // UNICODEMAP_ENABLE diff --git a/users/kuchosauronad0/unicode.h b/users/kuchosauronad0/unicode.h new file mode 100644 index 00000000000..cb550243eea --- /dev/null +++ b/users/kuchosauronad0/unicode.h @@ -0,0 +1,67 @@ +#pragma once + +#include "quantum.h" + +void send_unicode_hex_string(const char* str); + +/* use X(n) to call the */ +#ifdef UNICODEMAP_ENABLE +enum unicode_name { +OKOK, // +BANG, // ‽ +IRONY, // ⸮ +DEGREE, // ° +THINK, // 🤔 +GRIN, // � +MONOCL, // 🧐 +DRUG0, // 🤪 +DRUG1, // 🥴 +CLOWN, // 🤡 +MNDBLWN, // 🤯 +MONEY, // 🤑 +SHTUP, // 🤐 +PARTY, // 🥳 +SMRK, // 😏 +WEARY, // 😩 +UNAMU, // 😒 +SPY, // 🕵 +DAFUQ, // 👺 +FIST0, // 🤛 +FIST1, // 🤜 +FIST2, // ✊ +FIST3, // 👊 +WIFIHAND, // 👌 +EFFU, // 🖕 +SPOCK, // 🖖 +INUP, // 👆 +THDN, // 👎 +THUP, // 👍 +TUMBLER, // 🥃 +DRAGON0, // 🐉 +DRAGON1, // 🐅 +TIGER0, // 🐅 +TIGER1, // 🐯 +COOL, // 🆒 +UCHART, // 📈 +DCHART, // 📉 +BCHART, // 📊 +NOPRCY, // 🕲 +PRCY, // 🕱 +BBB, // 🅱 +POO, // 💩 +HUNDR, // 💯 +EGGPL, // 🍆 +WATER, // 💦 +LIT, // 🔥 +SNEK, // 🐍 +PENGUIN, // 🐧 +BOAR, // 🐗 +MONKEY, // 🐒 +CHICK, // 🐥 +DASH, // 💨 +DIZZY, // 💫 +KEEB, // 🖮 +HOLE, // 🕳 +SAUCER // 🛸 +}; +#endif diff --git a/users/kuchosauronad0/wrappers.h b/users/kuchosauronad0/wrappers.h new file mode 100644 index 00000000000..3172c8a6d3a --- /dev/null +++ b/users/kuchosauronad0/wrappers.h @@ -0,0 +1,206 @@ +#pragma once +#include "kuchosauronad0.h" +/* +Since our quirky block definitions are basically a list of comma separated +arguments, we need a wrapper in order for these definitions to be +expanded before being used as arguments to the LAYOUT_xxx macro. +*/ +#if (!defined(LAYOUT) && defined(KEYMAP)) +#define LAYOUT KEYMAP +#endif + +#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__) +#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__) +#define KEYMAP_wrapper(...) LAYOUT(__VA_ARGS__) +#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) +#define LAYOUT_ortho_4x12_wrapper(...) LAYOUT_ortho_4x12(__VA_ARGS__) +#define LAYOUT_ortho_5x12_wrapper(...) LAYOUT_ortho_5x12(__VA_ARGS__) + +/* +Blocks for each of the four major keyboard layouts +Organized so we can quickly adapt and modify all of them +at once, rather than for each keyboard, one at a time. +And this allows for much cleaner blocks in the keymaps. +For instance Tap/Hold for Control on all of the layouts +NOTE: These are all the same length. If you do a search/replace + then you need to add/remove underscores to keep the + lengths consistent. +*/ +#ifdef TAP_DANCE_ENABLE + #define _________________QWERTY_L1_________________ KC_Q, KC_DW, KC_EOL, KC_R, KC_TMX + #define _________________QWERTY_L2_________________ KC_BOL, KC_S, KC_D, KC_NW, KC_G + #define _________________QWERTY_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_PW +#else + #define _________________QWERTY_L1_________________ KC_Q, KC_W, KC_E, KC_R, KC_T + #define _________________QWERTY_L2_________________ KC_A, KC_S, KC_D, KC_F, KC_G + #define _________________QWERTY_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_B +#endif + +#define _________________QWERTY_R1_________________ KC_Y, KC_U, KC_I, KC_O, KC_P +#define _________________QWERTY_R2_________________ KC_H, KC_J, KC_K, KC_L, KC_SCLN +#define _________________QWERTY_R3_________________ KC_N, KC_M, KC_COMM, KC_DOT, KC_SLASH + + +#define _________________COLEMAK_L1________________ KC_Q, KC_W, KC_F, KC_P, KC_G +#define _________________COLEMAK_L2________________ KC_A, KC_R, KC_S, KC_T, KC_D +#define _________________COLEMAK_L3________________ KC_Z, KC_X, KC_C, KC_V, KC_B + +#define _________________COLEMAK_R1________________ KC_J, KC_L, KC_U, KC_Y, KC_SCLN +#define _________________COLEMAK_R2________________ KC_H, KC_N, KC_E, KC_I, KC_O +#define _________________COLEMAK_R3________________ KC_K, KC_M, KC_COMM, KC_DOT, KC_SLASH + +#define ______________COLEMAK_MOD_DH_L1____________ KC_Q, KC_W, KC_F, KC_P, KC_B +#define ______________COLEMAK_MOD_DH_L2____________ KC_A, KC_R, KC_S, KC_T, KC_G +#define ______________COLEMAK_MOD_DH_L3____________ KC_Z, KC_X, KC_C, KC_D, KC_V + +#define ______________COLEMAK_MOD_DH_R1____________ KC_J, KC_L, KC_U, KC_Y, KC_SCLN +#define ______________COLEMAK_MOD_DH_R2____________ KC_M, KC_N, KC_E, KC_I, KC_O +#define ______________COLEMAK_MOD_DH_R3____________ KC_K, KC_H, KC_COMM, KC_DOT, KC_SLASH + + +#define _________________DVORAK_L1_________________ KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y +#define _________________DVORAK_L2_________________ KC_A, KC_O, KC_E, KC_U, KC_I +#define _________________DVORAK_L3_________________ KC_SCLN, KC_Q, KC_J, KC_K, KC_X + +#define _________________DVORAK_R1_________________ KC_F, KC_G, KC_C, KC_R, KC_L +#define _________________DVORAK_R2_________________ KC_D, KC_H, KC_T, KC_N, KC_S +#define _________________DVORAK_R3_________________ KC_B, KC_M, KC_W, KC_V, KC_Z + +#define ________________DVORAK_AU_L1_______________ KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y +#define ________________DVORAK_AU_L2_______________ KC_O, KC_A, KC_E, KC_I, KC_U +#define ________________DVORAK_AU_L3_______________ KC_SCLN, KC_Q, KC_J, KC_K, KC_X + +#define ________________DVORAK_AU_R1_______________ KC_F, KC_G, KC_C, KC_R, KC_L +#define ________________DVORAK_AU_R2_______________ KC_D, KC_H, KC_T, KC_N, KC_S +#define ________________DVORAK_AU_R3_______________ KC_B, KC_M, KC_W, KC_V, KC_Z + + +#define _________________WORKMAN_L1________________ KC_Q, KC_D, KC_R, KC_W, KC_B +#define _________________WORKMAN_L2________________ KC_A, KC_S, KC_H, KC_T, KC_G +#define _________________WORKMAN_L3________________ KC_Z, KC_X, KC_M, KC_C, KC_V + +#define _________________WORKMAN_R1________________ KC_J, KC_F, KC_U, KC_P, KC_SCLN +#define _________________WORKMAN_R2________________ KC_Y, KC_N, KC_E, KC_O, KC_I +#define _________________WORKMAN_R3________________ KC_K, KC_L, KC_COMM, KC_DOT, KC_SLASH + + +#define _________________NORMAN_L1_________________ KC_Q, KC_W, KC_D, KC_F, KC_K +#define _________________NORMAN_L2_________________ KC_A, KC_S, KC_E, KC_T, KC_G +#define _________________NORMAN_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_B + +#define _________________NORMAN_R1_________________ KC_J, KC_U, KC_R, KC_L, KC_SCLN +#define _________________NORMAN_R2_________________ KC_Y, KC_N, KC_I, KC_O, KC_U +#define _________________NORMAN_R3_________________ KC_P, KC_M, KC_COMM, KC_DOT, KC_SLASH + + +#define _________________MALTRON_L1________________ KC_Q, KC_P, KC_Y, KC_C, KC_B +#define _________________MALTRON_L2________________ KC_A, KC_N, KC_I, KC_S, KC_F +#define _________________MALTRON_L3________________ KC_SCLN, KC_SLSH, KC_J, KC_G, KC_COMM + +#define _________________MALTRON_R1________________ KC_V, KC_M, KC_U, KC_Z, KC_L +#define _________________MALTRON_R2________________ KC_D, KC_T, KC_D, KC_O, KC_R +#define _________________MALTRON_R3________________ KC_DOT, KC_W, KC_K, KC_MINS, KC_X + + +#define _________________EUCALYN_L1________________ KC_SLSH, KC_COMM, KC_DOT, KC_F, KC_Q +#define _________________EUCALYN_L2________________ KC_A, KC_O, KC_E, KC_I, KC_U +#define _________________EUCALYN_L3________________ KC_Z, KC_X, KC_C, KC_V, KC_W + +#define _________________EUCALYN_R1________________ KC_M, KC_R, KC_D, KC_Y, KC_P +#define _________________EUCALYN_R2________________ KC_G, KC_T, KC_K, KC_S, KC_N +#define _________________EUCALYN_R3________________ KC_B, KC_H, KC_J, KC_L, KC_SCLN + + +#define _____________CARPLAX_QFMLWY_L1_____________ KC_Q, KC_F, KC_M, KC_L, KC_W +#define _____________CARPLAX_QFMLWY_L2_____________ KC_D, KC_S, KC_T, KC_N, KC_R +#define _____________CARPLAX_QFMLWY_L3_____________ KC_Z, KC_V, KC_G, KC_C, KC_X + +#define _____________CARPLAX_QFMLWY_R1_____________ KC_Y, KC_U, KC_O, KC_B, KC_J +#define _____________CARPLAX_QFMLWY_R2_____________ KC_I, KC_A, KC_E, KC_H, KC_SCLN +#define _____________CARPLAX_QFMLWY_R3_____________ KC_P, KC_K, KC_COMM, KC_DOT, KC_SLSH + + +#define _____________CARPLAX_QGMLWB_L1_____________ KC_Q, KC_G, KC_M, KC_L, KC_W +#define _____________CARPLAX_QGMLWB_L2_____________ KC_D, KC_S, KC_T, KC_N, KC_R +#define _____________CARPLAX_QGMLWB_L3_____________ KC_Z, KC_X, KC_C, KC_F, KC_J + +#define _____________CARPLAX_QGMLWB_R1_____________ KC_B, KC_Y, KC_U, KC_V, KC_SCLN +#define _____________CARPLAX_QGMLWB_R2_____________ KC_I, KC_A, KC_E, KC_O, KC_H +#define _____________CARPLAX_QGMLWB_R3_____________ KC_K, KC_P, KC_COMM, KC_DOT, KC_SLSH + + +#define _____________CARPLAX_QGMLWY_L1_____________ KC_Q, KC_G, KC_M, KC_L, KC_W +#define _____________CARPLAX_QGMLWY_L2_____________ KC_D, KC_S, KC_T, KC_N, KC_R +#define _____________CARPLAX_QGMLWY_L3_____________ KC_Z, KC_X, KC_C, KC_V, KC_J + +#define _____________CARPLAX_QGMLWY_R1_____________ KC_Y, KC_F, KC_U, KC_B, KC_SCLN +#define _____________CARPLAX_QGMLWY_R2_____________ KC_I, KC_A, KC_E, KC_O, KC_H +#define _____________CARPLAX_QGMLWY_R3_____________ KC_K, KC_P, KC_COMM, KC_DOT, KC_SLSH + +#ifdef UNICODE_ENABLE +#define _______________UNICODE_L1__________________ UC_DISA,UC_DISA, UC_DISA, UC_DISA, UC_DISA +#define _______________UNICODE_L2__________________ UC_DISA,UC_DISA, UC_DISA, UC_DISA, UC_DISA +#define _______________UNICODE_L3__________________ UC_DISA,UC_DISA, UC_DISA, UC_DISA, UC_DISA + +#define _______________UNICODE_R1__________________ UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG +#define _______________UNICODE_R2__________________ UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG +#define _______________UNICODE_R3__________________ UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG, UC_SHRG +#endif + +#ifdef UNICODEMAP_ENABLE +#define _______________UNICODE_L1__________________ X(SMRK), X(THINK), X(CLOWN), X(HUNDR), X(BANG) +#define _______________UNICODE_L2__________________ X(GRIN), X(MONKEY), X(OKOK), X(EGGPL), X(LIT) +#define _______________UNICODE_L3__________________ X(WEARY), X(UNAMU), X(EFFU), X(MONOCL), X(IRONY) + +#define _______________UNICODE_R1__________________ X(DRUG0), X(THUP), X(INUP), X(DIZZY), X(COOL) +#define _______________UNICODE_R2__________________ X(FIST0), X(FIST2),X(FIST3),X(FIST1), X(OKOK) +#define _______________UNICODE_R3__________________ X(MNDBLWN), X(THDN), X(SPOCK),X(HOLE), X(DASH) +#endif + +#define ________________NUMBER_LEFT________________ KC_1, KC_2, KC_3, KC_4, KC_5 +#define ________________NUMBER_RIGHT_______________ KC_6, KC_7, KC_8, KC_9, KC_0 +#define _________________FUNC_LEFT_________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5 +#define _________________FUNC_RIGHT________________ KC_F6, KC_F7, KC_F8, KC_F9, KC_F10 + +#define ___________________BLANK___________________ _______, _______, _______, _______, _______ + + +#define _________________LOWER_L1__________________ KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC +#define _________________LOWER_L2__________________ ___________________BLANK___________________ +#define _________________LOWER_L3__________________ ___________________BLANK___________________ + +#define _________________LOWER_R1__________________ KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN +#define _________________LOWER_R2__________________ OS_UNI, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR +#define _________________LOWER_R3__________________ TM_X, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT + + + +#define _________________RAISE_L1__________________ ________________NUMBER_LEFT________________ +#define _________________RAISE_L2__________________ ___________________BLANK___________________ +#define _________________RAISE_L3__________________ ___________________BLANK___________________ + +#define _________________RAISE_R1__________________ ________________NUMBER_RIGHT_______________ +#define _________________RAISE_R2__________________ _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC +#define _________________RAISE_R3__________________ _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END + + + +#define _________________ADJUST_L1_________________ ___________________BLANK___________________ +#define _________________ADJUST_L2_________________ _________________FUNC_LEFT_________________ +#define _________________ADJUST_L3_________________ AG_SWAP, QWERTY, COLEMAK, DVORAK, WORKMAN + +#define _________________ADJUST_R1_________________ KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5 +#define _________________ADJUST_R2_________________ _________________FUNC_RIGHT________________ +#define _________________ADJUST_R3_________________ KC_MUTE, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT + + +/* +#define _________________RGB_L1____________________ RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG +#define _________________RGB_L2____________________ MU_TOG , CK_TOGG, AU_ON, AU_OFF, AG_NORM +#define _________________RGB_L3____________________ RGB_RMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T +#define _________________RGB_R1____________________ RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG +#define _________________RGB_R2____________________ MU_TOG , CK_TOGG, AU_ON, AU_OFF, AG_NORM +#define _________________RGB_R3____________________ RGB_RMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T +*/ +/* vi: ft=c:tw=80:sw=2:ts=2:sts=2:et + */ From ddaf37ffa98683be925ae7c396c55f336dce4ad2 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 18 Aug 2019 04:41:55 +1000 Subject: [PATCH 36/61] Reword a note about the MANUFACTURER and PRODUCT defines in hardware_avr.md (#6558) --- docs/hardware_avr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hardware_avr.md b/docs/hardware_avr.md index c6987d1bdf9..0c1b31bb26a 100644 --- a/docs/hardware_avr.md +++ b/docs/hardware_avr.md @@ -78,7 +78,7 @@ Do change the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` lines to accurately r #define DESCRIPTION A custom keyboard ``` -?> Note: On Windows and macOS the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` fields will be displayed in the list of USB devices. ?> On Linux these values will not be visible in lsusb by default, since Linux takes the information from the list maintained by [USB ID Repository](http://www.linux-usb.org/usb-ids.html) by default. lsusb will show the information reported by the device when executed with -v option. It is also present in kernel logs after plugging in the device. +?> Windows and macOS will display the `MANUFACTURER` and `PRODUCT` in the list of USB devices. `lsusb` on Linux instead takes these from the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html) by default. `lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in. ### Keyboard Matrix Configuration From 92f9b6c3bdff939bc562d640e02c3aebaa204e17 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 18 Aug 2019 07:29:41 +1000 Subject: [PATCH 37/61] Add ATmega32U2 to mcu_selection.mk (#6561) --- quantum/mcu_selection.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index cca7720e9c7..2d62dcbf1e3 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -36,7 +36,7 @@ ifneq ($(findstring STM32F303, $(MCU)),) DFU_SUFFIX_ARGS = -p DF11 -v 0483 endif -ifneq (,$(filter $(MCU),atmega32u4 at90usb1286)) +ifneq (,$(filter $(MCU),atmega32u2 atmega32u4 at90usb1286)) # Processor frequency. # This will define a symbol, F_CPU, in all source code files equal to the # processor frequency in Hz. You can then use this symbol in your source code to From 91ee6a1dbb6f43ac708b0dc301f5cbcef6dcfdf5 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Mon, 19 Aug 2019 15:03:05 -0700 Subject: [PATCH 38/61] [Docs] Add RGB Matrix default mode define info (#6564) --- docs/feature_rgb_matrix.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 916fcdce031..b2850c3cff2 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -374,6 +374,7 @@ These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blo #define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) #define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255 +#define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set ``` ## EEPROM storage From 4003d077cef42d7a3405250ea6417db3a3549e9e Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 20 Aug 2019 15:39:24 -0700 Subject: [PATCH 39/61] Add a universal flash command for cli (#6224) * Add universal flash command * Add bootloader info to I:C boards * Add support for ATSAM * Add messages for flash target * Message cleanup * Add USB ASP Flashing target * Make usbasp target more universal * Add phoney target for usbasp * Clarify error message when bootloader isn't matched --- .../keymaps/halfkeyboard/rules.mk | 2 + keyboards/ergodox_infinity/rules.mk | 2 + keyboards/infinity60/rules.mk | 2 + keyboards/k_type/rules.mk | 2 + keyboards/whitefox/rules.mk | 2 + message.mk | 2 + tmk_core/arm_atsam.mk | 3 + tmk_core/avr.mk | 91 +++++++++++-------- tmk_core/chibios.mk | 26 +++++- tmk_core/rules.mk | 5 +- 10 files changed, 93 insertions(+), 44 deletions(-) diff --git a/keyboards/ergodox_infinity/keymaps/halfkeyboard/rules.mk b/keyboards/ergodox_infinity/keymaps/halfkeyboard/rules.mk index 2d3597ceb99..43a31852956 100644 --- a/keyboards/ergodox_infinity/keymaps/halfkeyboard/rules.mk +++ b/keyboards/ergodox_infinity/keymaps/halfkeyboard/rules.mk @@ -54,6 +54,8 @@ ARMV = 7 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000 +BOOTLOADER = dfu + # Build Options # comment out to disable the options. # diff --git a/keyboards/ergodox_infinity/rules.mk b/keyboards/ergodox_infinity/rules.mk index af8e9ef200c..b55c9bc8c0c 100644 --- a/keyboards/ergodox_infinity/rules.mk +++ b/keyboards/ergodox_infinity/rules.mk @@ -54,6 +54,8 @@ ARMV = 7 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000 +BOOTLOADER = dfu + # Build Options # comment out to disable the options. # diff --git a/keyboards/infinity60/rules.mk b/keyboards/infinity60/rules.mk index 1f02e05c84c..6fb43dc7526 100644 --- a/keyboards/infinity60/rules.mk +++ b/keyboards/infinity60/rules.mk @@ -53,6 +53,8 @@ ARMV = 7 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB OPT_DEFS = -DCORTEX_VTOR_INIT=0x00001000 +BOOTLOADER = dfu + # Build Options # comment out to disable the options. # diff --git a/keyboards/k_type/rules.mk b/keyboards/k_type/rules.mk index 7762f186820..43579fcc71b 100644 --- a/keyboards/k_type/rules.mk +++ b/keyboards/k_type/rules.mk @@ -59,6 +59,8 @@ OPT_DEFS = DFU_ARGS = -d 1c11:b007 DFU_SUFFIX_ARGS = -p b007 -v 1c11 +BOOTLOADER = dfu + # Build Options # comment out to disable the options. # diff --git a/keyboards/whitefox/rules.mk b/keyboards/whitefox/rules.mk index d9aa911c54e..59332d1d5ac 100644 --- a/keyboards/whitefox/rules.mk +++ b/keyboards/whitefox/rules.mk @@ -57,6 +57,8 @@ OPT_DEFS = DFU_ARGS = -d 1c11:b007 DFU_SUFFIX_ARGS = -p b007 -v 1c11 +BOOTLOADER = dfu + # Build Options # comment out to disable the options. # diff --git a/message.mk b/message.mk index ec9bacbf49e..c8d2135d5c0 100644 --- a/message.mk +++ b/message.mk @@ -85,3 +85,5 @@ MSG_PYTHON_MISSING = $(WARN_COLOR)WARNING:$(NO_COLOR)\n \ Python 3 is not installed. It will be required by a future version\n\ of qmk_firmware.\n\n\ Please run $(BOLD)util/qmk_install.sh$(NO_COLOR) to install all the dependencies QMK requires.\n\n +MSG_FLASH_BOOTLOADER = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's bootloader is not specified or is not supported by the \":flash\" target at this time.\n\n +MSG_FLASH_ARCH = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's architecture is not supported by the \":flash\" target at this time.\n\n diff --git a/tmk_core/arm_atsam.mk b/tmk_core/arm_atsam.mk index 25a3411f4f9..c9b14042f8d 100644 --- a/tmk_core/arm_atsam.mk +++ b/tmk_core/arm_atsam.mk @@ -54,3 +54,6 @@ EXTRALIBDIRS = bin: $(BUILD_DIR)/$(TARGET).hex $(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin $(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin; + +flash: bin + $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_ARCH)" diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk index 5bfd5a9b0dc..e5443418b94 100644 --- a/tmk_core/avr.mk +++ b/tmk_core/avr.mk @@ -89,11 +89,11 @@ DEBUG_HOST = localhost #============================================================================ # Autodetect teensy loader ifndef TEENSY_LOADER_CLI - ifneq (, $(shell which teensy-loader-cli 2>/dev/null)) - TEENSY_LOADER_CLI ?= teensy-loader-cli - else - TEENSY_LOADER_CLI ?= teensy_loader_cli - endif + ifneq (, $(shell which teensy-loader-cli 2>/dev/null)) + TEENSY_LOADER_CLI ?= teensy-loader-cli + else + TEENSY_LOADER_CLI ?= teensy_loader_cli + endif endif # Generate a .qmk for the QMK-FF @@ -124,8 +124,12 @@ qmk: $(BUILD_DIR)/$(TARGET).hex program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep check-size $(PROGRAM_CMD) -teensy: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware +define EXEC_TEENSY $(TEENSY_LOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex +endef + +teensy: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware + $(call EXEC_TEENSY) BATCHISP ?= batchisp @@ -137,18 +141,32 @@ flip: $(BUILD_DIR)/$(TARGET).hex check-size DFU_PROGRAMMER ?= dfu-programmer GREP ?= grep -dfu: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size + +define EXEC_DFU + if [ "$(1)" ]; then \ + echo "Flashing '$(1)' for EE_HANDS split keyboard support." ;\ + fi; \ until $(DFU_PROGRAMMER) $(MCU) get bootloader-version; do\ echo "Error: Bootloader not found. Trying again in 5s." ;\ sleep 5 ;\ - done + done; \ if $(DFU_PROGRAMMER) --version 2>&1 | $(GREP) -q 0.7 ; then\ - $(DFU_PROGRAMMER) $(MCU) erase --force;\ - else\ - $(DFU_PROGRAMMER) $(MCU) erase;\ - fi - $(DFU_PROGRAMMER) $(MCU) flash $(BUILD_DIR)/$(TARGET).hex + $(DFU_PROGRAMMER) $(MCU) erase --force; \ + if [ "$(1)" ]; then \ + $(DFU_PROGRAMMER) $(MCU) flash --eeprom $(QUANTUM_PATH)/split_common/$(1);\ + fi; \ + else \ + $(DFU_PROGRAMMER) $(MCU) erase; \ + if [ "$(1)" ]; then \ + $(DFU_PROGRAMMER) $(MCU) flash-eeprom $(QUANTUM_PATH)/split_common/$(1);\ + fi; \ + fi; \ + $(DFU_PROGRAMMER) $(MCU) flash $(BUILD_DIR)/$(TARGET).hex;\ $(DFU_PROGRAMMER) $(MCU) reset +endef + +dfu: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size + $(call EXEC_DFU) dfu-start: $(DFU_PROGRAMMER) $(MCU) reset @@ -170,34 +188,10 @@ dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep $(DFU_PROGRAMMER) $(MCU) reset dfu-split-left: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size - until $(DFU_PROGRAMMER) $(MCU) get bootloader-version; do\ - echo "Error: Bootloader not found. Trying again in 5s." ;\ - sleep 5 ;\ - done - if $(DFU_PROGRAMMER) --version 2>&1 | $(GREP) -q 0.7 ; then\ - $(DFU_PROGRAMMER) $(MCU) erase --force;\ - $(DFU_PROGRAMMER) $(MCU) flash --eeprom $(QUANTUM_PATH)/split_common/eeprom-lefthand.eep;\ - else\ - $(DFU_PROGRAMMER) $(MCU) erase;\ - $(DFU_PROGRAMMER) $(MCU) flash-eeprom $(QUANTUM_PATH)/split_common/eeprom-lefthand.eep;\ - fi - $(DFU_PROGRAMMER) $(MCU) flash $(BUILD_DIR)/$(TARGET).hex - $(DFU_PROGRAMMER) $(MCU) reset + $(call EXEC_DFU,eeprom-lefthand.eep) dfu-split-right: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size - until $(DFU_PROGRAMMER) $(MCU) get bootloader-version; do\ - echo "Error: Bootloader not found. Trying again in 5s." ;\ - sleep 5 ;\ - done - if $(DFU_PROGRAMMER) --version 2>&1 | $(GREP) -q 0.7 ; then\ - $(DFU_PROGRAMMER) $(MCU) erase --force;\ - $(DFU_PROGRAMMER) $(MCU) flash --eeprom $(QUANTUM_PATH)/split_common/eeprom-righthand.eep;\ - else\ - $(DFU_PROGRAMMER) $(MCU) erase;\ - $(DFU_PROGRAMMER) $(MCU) flash-eeprom $(QUANTUM_PATH)/split_common/eeprom-righthand.eep;\ - fi - $(DFU_PROGRAMMER) $(MCU) flash $(BUILD_DIR)/$(TARGET).hex - $(DFU_PROGRAMMER) $(MCU) reset + $(call EXEC_DFU,eeprom-righthand.eep) define EXEC_AVRDUDE USB= ;\ @@ -245,8 +239,12 @@ avrdude-split-left: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware $(call EXEC_AVRDUDE,eeprom-righthand.eep) -usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware +define EXEC_USBASP avrdude -p $(MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex +endef + +usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware + $(call EXEC_USBASP) # Convert hex to bin. @@ -323,3 +321,16 @@ production: $(BUILD_DIR)/$(TARGET).hex bootloader cpfirmware @cat $(TARGET)_bootloader.hex >> $(TARGET)_production.hex echo "File sizes:" $(SIZE) $(TARGET).hex $(TARGET)_bootloader.hex $(TARGET)_production.hex + +flash: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware +ifeq ($(strip $(BOOTLOADER)), caterina) + $(call EXEC_AVRDUDE) +else ifeq ($(strip $(BOOTLOADER)), halfkay) + $(call EXEC_TEENSY) +else ifeq (dfu,$(findstring dfu,$(BOOTLOADER))) + $(call EXEC_DFU) +else ifeq ($(strip $(BOOTLOADER)), USBasp) + $(call EXEC_USBASP) +else + $(PRINT_OK); $(SILENT) || printf "&(MSG_FLASH_BOOTLOADER)" +endif diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index 4aebb477629..eee520467d7 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -234,9 +234,12 @@ qmk: $(BUILD_DIR)/$(TARGET).bin zip $(TARGET).qmk -urj $(BUILD_DIR)/$(TARGET).json printf "@ $(TARGET).json\n@=info.json\n" | zipnote -w $(TARGET).qmk -dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter +define EXEC_DFU_UTIL $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin +endef +dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter + $(call EXEC_DFU_UTIL) ifneq ($(strip $(TIME_DELAY)),) TIME_DELAY = $(strip $(TIME_DELAY)) @@ -253,7 +256,7 @@ dfu-util-wait: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter done; \ echo "Flashing $(TARGET).bin" ;\ sleep 1 ;\ - $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin + $(call EXEC_DFU_UTIL) st-link-cli: $(BUILD_DIR)/$(TARGET).hex sizeafter $(ST_LINK_CLI) $(ST_LINK_ARGS) -q -c SWD -p $(BUILD_DIR)/$(TARGET).hex -Rst @@ -268,7 +271,24 @@ ifndef TEENSY_LOADER_CLI endif endif -teensy: $(BUILD_DIR)/$(TARGET).hex cpfirmware sizeafter +define EXEC_TEENSY $(TEENSY_LOADER_CLI) -mmcu=$(MCU_LDSCRIPT) -w -v $(BUILD_DIR)/$(TARGET).hex +endef + +teensy: $(BUILD_DIR)/$(TARGET).hex cpfirmware sizeafter + $(call EXEC_TEENSY) bin: $(BUILD_DIR)/$(TARGET).bin sizeafter + $(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin; + + +flash: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter +ifeq ($(strip $(BOOTLOADER)),dfu) + $(call EXEC_DFU_UTIL) +else ifeq ($(strip $(MCU_FAMILY)),KINETIS) + $(call EXEC_TEENSY) +else ifeq ($(strip $(MCU_FAMILY)),STM32) + $(call EXEC_DFU_UTIL) +else + $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)" +endif diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index e51dbfe7c6a..31bce33c39b 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -433,4 +433,7 @@ $(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null))) .PHONY : all finish sizebefore sizeafter qmkversion \ gccversion build elf hex eep lss sym coff extcoff \ clean clean_list debug gdb-config show_path \ -program teensy dfu flip dfu-ee flip-ee dfu-start +program teensy dfu flip dfu-ee flip-ee dfu-start \ +flash dfu-split-left dfu-split-right \ +avrdude-split-left avrdude-split-right \ +avrdude-loop usbasp From 9bb4e63a1123861515c1196a624b4a0f04129601 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Wed, 21 Aug 2019 11:05:08 +1000 Subject: [PATCH 40/61] Remove old promicro_bootloader_jmp() declarations (#6444) --- keyboards/adkb96/rev1/rev1.h | 5 ----- keyboards/atreus62/atreus62.h | 2 -- keyboards/claw44/rev1/rev1.h | 2 -- keyboards/crkbd/rev1/rev1.h | 2 -- keyboards/deltasplit75/v2/v2.h | 4 +--- keyboards/divergetm2/divergetm2.h | 4 ---- keyboards/eco/rev1/rev1.h | 3 --- keyboards/eco/rev2/rev2.h | 3 --- keyboards/ergo42/rev1/rev1.h | 4 ---- keyboards/ergodash/mini/mini.h | 4 ---- keyboards/ergodash/rev1/rev1.h | 4 ---- keyboards/ergotravel/rev1/rev1.h | 4 ---- keyboards/fortitude60/rev1/rev1.h | 4 ---- keyboards/handwired/dactyl_manuform/4x5/4x5.h | 4 ---- keyboards/handwired/dactyl_manuform/dactyl_manuform.h | 1 - keyboards/handwired/xealous/rev1/rev1.h | 2 -- keyboards/helix/pico/pico.h | 4 ---- keyboards/helix/rev1/rev1.h | 5 ----- keyboards/helix/rev2/rev2.h | 4 ---- keyboards/keebio/iris/rev1/rev1.h | 4 ---- keyboards/keebio/iris/rev1_led/rev1_led.h | 4 ---- keyboards/keebio/iris/rev2/rev2.h | 4 ---- keyboards/keebio/levinson/rev1/rev1.h | 4 ---- keyboards/keebio/levinson/rev2/rev2.h | 4 ---- keyboards/keebio/levinson/rev3/rev3.h | 2 -- keyboards/keebio/nyquist/rev1/rev1.h | 4 ---- keyboards/keebio/nyquist/rev2/rev2.h | 4 ---- keyboards/keebio/rorschach/rev1/rev1.h | 4 ---- keyboards/keebio/viterbi/rev1/rev1.h | 3 --- keyboards/launchpad/rev1/rev1.h | 5 +---- keyboards/lets_split/rev1/rev1.h | 3 --- keyboards/lets_split/rev2/rev2.h | 4 ---- keyboards/lets_split/sockets/sockets.h | 4 ---- keyboards/lily58/rev1/rev1.h | 5 +---- keyboards/minidox/rev1/rev1.h | 3 --- keyboards/naked48/rev1/rev1.h | 3 --- keyboards/orthodox/rev1/rev1.h | 3 --- keyboards/orthodox/rev3/rev3.h | 3 --- keyboards/orthodox/rev3_teensy/rev3_teensy.h | 3 --- keyboards/pinky/3/3.h | 3 --- keyboards/pinky/4/4.h | 3 --- keyboards/rgbkb/zen/rev1/rev1.h | 4 ---- keyboards/rgbkb/zen/rev2/rev2.h | 4 ---- keyboards/treadstone48/rev1/rev1.h | 1 - keyboards/vitamins_included/rev1/rev1.h | 3 --- keyboards/yosino58/rev1/rev1.h | 2 -- keyboards/zinc/rev1/rev1.h | 5 ----- keyboards/zinc/reva/reva.h | 5 ----- 48 files changed, 3 insertions(+), 165 deletions(-) diff --git a/keyboards/adkb96/rev1/rev1.h b/keyboards/adkb96/rev1/rev1.h index 0ec70c5d5c9..4c4c7bae3c5 100644 --- a/keyboards/adkb96/rev1/rev1.h +++ b/keyboards/adkb96/rev1/rev1.h @@ -2,8 +2,6 @@ #include "adkb96.h" -//void promicro_bootloader_jmp(bool program); - #ifdef USE_I2C #include #ifdef __AVR__ @@ -12,9 +10,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - // Keymap with right side flipped // (TRRS jack on both halves are to the right) #define LAYOUT_ortho_6x16( \ diff --git a/keyboards/atreus62/atreus62.h b/keyboards/atreus62/atreus62.h index 4bf7dabc7dc..de6f64063bd 100644 --- a/keyboards/atreus62/atreus62.h +++ b/keyboards/atreus62/atreus62.h @@ -3,8 +3,6 @@ #include "quantum.h" -void promicro_bootloader_jmp(bool program); - // This a shortcut to help you visually see your layout. // The first section contains all of the arguements // The second converts the arguments into a two-dimensional array diff --git a/keyboards/claw44/rev1/rev1.h b/keyboards/claw44/rev1/rev1.h index f7ec2cbfe65..c6c9057fdc4 100644 --- a/keyboards/claw44/rev1/rev1.h +++ b/keyboards/claw44/rev1/rev1.h @@ -2,7 +2,6 @@ #include "../claw44.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -18,7 +17,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/crkbd/rev1/rev1.h b/keyboards/crkbd/rev1/rev1.h index 9023248e28f..5e90de72a3a 100644 --- a/keyboards/crkbd/rev1/rev1.h +++ b/keyboards/crkbd/rev1/rev1.h @@ -2,7 +2,6 @@ #include "crkbd.h" -// void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef PROTOCOL_LUFA @@ -23,7 +22,6 @@ #endif // clang-format off -//void promicro_bootloader_jmp(bool program); #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/deltasplit75/v2/v2.h b/keyboards/deltasplit75/v2/v2.h index 9e364f38abf..82f54c2b0d0 100644 --- a/keyboards/deltasplit75/v2/v2.h +++ b/keyboards/deltasplit75/v2/v2.h @@ -3,10 +3,8 @@ #include "deltasplit75.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); //matrix is defined in a weird way here; the layout on both sides are asymmetrical, but the "matrix" is symmetrical but with empty gaps //the last column is defined as a separate row because the firmware currently doesnt support more than 8 columns (this layout has 9 columns per side) K45 and K110 are the Bs on both sides; K53 and K106 are extra keys for ISO #define LAYOUT_v2( \ @@ -59,4 +57,4 @@ { KC_NO, KC_NO, K132, K133, K134, K135, K136, K137} \ } -#endif \ No newline at end of file +#endif diff --git a/keyboards/divergetm2/divergetm2.h b/keyboards/divergetm2/divergetm2.h index 50144b1d2bb..6de48e41c7a 100644 --- a/keyboards/divergetm2/divergetm2.h +++ b/keyboards/divergetm2/divergetm2.h @@ -17,10 +17,8 @@ #pragma once -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -29,8 +27,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/eco/rev1/rev1.h b/keyboards/eco/rev1/rev1.h index ba00615d34f..132760fbe85 100644 --- a/keyboards/eco/rev1/rev1.h +++ b/keyboards/eco/rev1/rev1.h @@ -3,11 +3,8 @@ #include "../eco.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ k01, k02, k03, k04, k05, k06, k07, k08, k09, k010, k011, k012, k013, k014, \ k11, k12, k13, k14, k15, k16, k17, k18, k19, k110, k111, k112, k113, k114, \ diff --git a/keyboards/eco/rev2/rev2.h b/keyboards/eco/rev2/rev2.h index adc2c6d4022..881bcc77b90 100644 --- a/keyboards/eco/rev2/rev2.h +++ b/keyboards/eco/rev2/rev2.h @@ -3,11 +3,8 @@ #include "../eco.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ k01, k02, k03, k04, k05, k06, k07, k08, k09, k010, k011, k012, k013, k014, \ k11, k12, k13, k14, k15, k16, k17, k18, k19, k110, k111, k112, k113, k114, \ diff --git a/keyboards/ergo42/rev1/rev1.h b/keyboards/ergo42/rev1/rev1.h index 64773c911b8..724ec389707 100644 --- a/keyboards/ergo42/rev1/rev1.h +++ b/keyboards/ergo42/rev1/rev1.h @@ -3,10 +3,8 @@ #include "ergo42.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/ergodash/mini/mini.h b/keyboards/ergodash/mini/mini.h index 74e57417060..d565c6168ff 100644 --- a/keyboards/ergodash/mini/mini.h +++ b/keyboards/ergodash/mini/mini.h @@ -3,10 +3,8 @@ #include "ergodash.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/ergodash/rev1/rev1.h b/keyboards/ergodash/rev1/rev1.h index f494a3558a7..eaabf7cc5f8 100644 --- a/keyboards/ergodash/rev1/rev1.h +++ b/keyboards/ergodash/rev1/rev1.h @@ -3,10 +3,8 @@ #include "ergodash.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/ergotravel/rev1/rev1.h b/keyboards/ergotravel/rev1/rev1.h index c4599fc0165..5907617ef32 100644 --- a/keyboards/ergotravel/rev1/rev1.h +++ b/keyboards/ergotravel/rev1/rev1.h @@ -3,10 +3,8 @@ #include "ergotravel.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, L06, R00, R01, R02, R03, R04, R05, R06, \ L10, L11, L12, L13, L14, L15, L16, R10, R11, R12, R13, R14, R15, R16, \ diff --git a/keyboards/fortitude60/rev1/rev1.h b/keyboards/fortitude60/rev1/rev1.h index 5b35720bc3d..bb133b3d893 100644 --- a/keyboards/fortitude60/rev1/rev1.h +++ b/keyboards/fortitude60/rev1/rev1.h @@ -3,10 +3,8 @@ #include "fortitude60.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) #define LAYOUT( \ diff --git a/keyboards/handwired/dactyl_manuform/4x5/4x5.h b/keyboards/handwired/dactyl_manuform/4x5/4x5.h index b34d97adbff..a70f52f3e14 100644 --- a/keyboards/handwired/dactyl_manuform/4x5/4x5.h +++ b/keyboards/handwired/dactyl_manuform/4x5/4x5.h @@ -2,10 +2,8 @@ #include "dactyl_manuform.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF #define LAYOUT( \ L00, L01, L02, L03, L04, R00, R01, R02, R03, R04, \ diff --git a/keyboards/handwired/dactyl_manuform/dactyl_manuform.h b/keyboards/handwired/dactyl_manuform/dactyl_manuform.h index 72f2acaab43..d8f27f729cf 100644 --- a/keyboards/handwired/dactyl_manuform/dactyl_manuform.h +++ b/keyboards/handwired/dactyl_manuform/dactyl_manuform.h @@ -14,7 +14,6 @@ #include "62key.h" #endif -//void promicro_bootloader_jmp(bool program); #include "quantum.h" diff --git a/keyboards/handwired/xealous/rev1/rev1.h b/keyboards/handwired/xealous/rev1/rev1.h index d195af49deb..0d8913b2ead 100644 --- a/keyboards/handwired/xealous/rev1/rev1.h +++ b/keyboards/handwired/xealous/rev1/rev1.h @@ -1,10 +1,8 @@ #ifndef REV1_H #define REV1_H -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); #define XXX KC_NO #define LAYOUT( \ diff --git a/keyboards/helix/pico/pico.h b/keyboards/helix/pico/pico.h index 153132775ba..d9c57206c61 100644 --- a/keyboards/helix/pico/pico.h +++ b/keyboards/helix/pico/pico.h @@ -3,7 +3,6 @@ #include "../helix.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -19,9 +18,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/helix/rev1/rev1.h b/keyboards/helix/rev1/rev1.h index d7cd749e4d8..a8d6ff05074 100644 --- a/keyboards/helix/rev1/rev1.h +++ b/keyboards/helix/rev1/rev1.h @@ -3,10 +3,8 @@ #include "../helix.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,9 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - #if HELIX_ROWS == 3 #ifndef FLIP_HALF // Standard Keymap diff --git a/keyboards/helix/rev2/rev2.h b/keyboards/helix/rev2/rev2.h index a2a1fb746ab..f4929998381 100644 --- a/keyboards/helix/rev2/rev2.h +++ b/keyboards/helix/rev2/rev2.h @@ -3,7 +3,6 @@ #include "../helix.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -19,9 +18,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - #if HELIX_ROWS == 4 #ifndef FLIP_HALF // Standard Keymap diff --git a/keyboards/keebio/iris/rev1/rev1.h b/keyboards/keebio/iris/rev1/rev1.h index da5c9cdc036..19df105c2e0 100644 --- a/keyboards/keebio/iris/rev1/rev1.h +++ b/keyboards/keebio/iris/rev1/rev1.h @@ -2,10 +2,8 @@ #include "iris.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/keebio/iris/rev1_led/rev1_led.h b/keyboards/keebio/iris/rev1_led/rev1_led.h index da5c9cdc036..19df105c2e0 100644 --- a/keyboards/keebio/iris/rev1_led/rev1_led.h +++ b/keyboards/keebio/iris/rev1_led/rev1_led.h @@ -2,10 +2,8 @@ #include "iris.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/keebio/iris/rev2/rev2.h b/keyboards/keebio/iris/rev2/rev2.h index da5c9cdc036..19df105c2e0 100644 --- a/keyboards/keebio/iris/rev2/rev2.h +++ b/keyboards/keebio/iris/rev2/rev2.h @@ -2,10 +2,8 @@ #include "iris.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/keebio/levinson/rev1/rev1.h b/keyboards/keebio/levinson/rev1/rev1.h index 2120bb0fa94..1c555b6775b 100644 --- a/keyboards/keebio/levinson/rev1/rev1.h +++ b/keyboards/keebio/levinson/rev1/rev1.h @@ -2,10 +2,8 @@ #include "levinson.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/keebio/levinson/rev2/rev2.h b/keyboards/keebio/levinson/rev2/rev2.h index 2120bb0fa94..1c555b6775b 100644 --- a/keyboards/keebio/levinson/rev2/rev2.h +++ b/keyboards/keebio/levinson/rev2/rev2.h @@ -2,10 +2,8 @@ #include "levinson.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/keebio/levinson/rev3/rev3.h b/keyboards/keebio/levinson/rev3/rev3.h index a31bfd15c35..da7349d2e7e 100644 --- a/keyboards/keebio/levinson/rev3/rev3.h +++ b/keyboards/keebio/levinson/rev3/rev3.h @@ -2,10 +2,8 @@ #include "levinson.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ diff --git a/keyboards/keebio/nyquist/rev1/rev1.h b/keyboards/keebio/nyquist/rev1/rev1.h index 6d3a23383bf..20f53b3b447 100644 --- a/keyboards/keebio/nyquist/rev1/rev1.h +++ b/keyboards/keebio/nyquist/rev1/rev1.h @@ -2,10 +2,8 @@ #include "nyquist.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/keebio/nyquist/rev2/rev2.h b/keyboards/keebio/nyquist/rev2/rev2.h index 6d3a23383bf..20f53b3b447 100644 --- a/keyboards/keebio/nyquist/rev2/rev2.h +++ b/keyboards/keebio/nyquist/rev2/rev2.h @@ -2,10 +2,8 @@ #include "nyquist.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/keebio/rorschach/rev1/rev1.h b/keyboards/keebio/rorschach/rev1/rev1.h index 583f0efc446..278bf8186ef 100644 --- a/keyboards/keebio/rorschach/rev1/rev1.h +++ b/keyboards/keebio/rorschach/rev1/rev1.h @@ -2,10 +2,8 @@ #include "rorschach.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/keebio/viterbi/rev1/rev1.h b/keyboards/keebio/viterbi/rev1/rev1.h index f31373f02e0..88a3200f6b2 100644 --- a/keyboards/keebio/viterbi/rev1/rev1.h +++ b/keyboards/keebio/viterbi/rev1/rev1.h @@ -3,7 +3,6 @@ #include "viterbi.h" #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -12,8 +11,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/launchpad/rev1/rev1.h b/keyboards/launchpad/rev1/rev1.h index fd692cad1fe..6644db83006 100644 --- a/keyboards/launchpad/rev1/rev1.h +++ b/keyboards/launchpad/rev1/rev1.h @@ -3,11 +3,8 @@ #include "../launchpad.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ K00, K01, \ K10, K11, \ @@ -21,4 +18,4 @@ { K30, K31 } \ } -#endif \ No newline at end of file +#endif diff --git a/keyboards/lets_split/rev1/rev1.h b/keyboards/lets_split/rev1/rev1.h index a43d4a25ba0..6a65954f229 100644 --- a/keyboards/lets_split/rev1/rev1.h +++ b/keyboards/lets_split/rev1/rev1.h @@ -2,11 +2,8 @@ #include "lets_split.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/lets_split/rev2/rev2.h b/keyboards/lets_split/rev2/rev2.h index 34e64e89f1f..a1a3f00a0eb 100644 --- a/keyboards/lets_split/rev2/rev2.h +++ b/keyboards/lets_split/rev2/rev2.h @@ -2,10 +2,8 @@ #include "lets_split.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/lets_split/sockets/sockets.h b/keyboards/lets_split/sockets/sockets.h index a79770bac6f..0ee93c0206a 100644 --- a/keyboards/lets_split/sockets/sockets.h +++ b/keyboards/lets_split/sockets/sockets.h @@ -3,10 +3,8 @@ #include "lets_split.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -15,8 +13,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifndef FLIP_HALF // Standard Keymap // (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left) diff --git a/keyboards/lily58/rev1/rev1.h b/keyboards/lily58/rev1/rev1.h index 4949bf5372d..aa9f5727c2b 100644 --- a/keyboards/lily58/rev1/rev1.h +++ b/keyboards/lily58/rev1/rev1.h @@ -2,7 +2,6 @@ #include "lily58.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -18,8 +17,6 @@ #endif #endif - -//void promicro_bootloader_jmp(bool program); #ifndef FLIP_HALF #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ @@ -62,4 +59,4 @@ { R30, R31, R32, R33, R34, R35 }, \ { KC_NO, R41, R42, R43, R44, R45 } \ } -#endif \ No newline at end of file +#endif diff --git a/keyboards/minidox/rev1/rev1.h b/keyboards/minidox/rev1/rev1.h index 99c579d6eb5..5d32b05d41a 100644 --- a/keyboards/minidox/rev1/rev1.h +++ b/keyboards/minidox/rev1/rev1.h @@ -3,11 +3,8 @@ #include "../minidox.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - // readability #define ___ KC_NO diff --git a/keyboards/naked48/rev1/rev1.h b/keyboards/naked48/rev1/rev1.h index 45878dc5052..914459a8a58 100644 --- a/keyboards/naked48/rev1/rev1.h +++ b/keyboards/naked48/rev1/rev1.h @@ -2,7 +2,6 @@ #include "naked48.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -10,8 +9,6 @@ #include "ws2812.h" #endif -//void promicro_bootloader_jmp(bool program); - ////////////////////////////////////////////////////////////////////////////// // When only use Naked48. ////////////////////////////////////////////////////////////////////////////// diff --git a/keyboards/orthodox/rev1/rev1.h b/keyboards/orthodox/rev1/rev1.h index 783dfb34b95..d9d0b78dfc3 100644 --- a/keyboards/orthodox/rev1/rev1.h +++ b/keyboards/orthodox/rev1/rev1.h @@ -23,11 +23,8 @@ along with this program. If not, see . #include "orthodox.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, L16, L18, R10, R12, R13, R14, R15, R16, R17, R18, \ diff --git a/keyboards/orthodox/rev3/rev3.h b/keyboards/orthodox/rev3/rev3.h index 783dfb34b95..d9d0b78dfc3 100644 --- a/keyboards/orthodox/rev3/rev3.h +++ b/keyboards/orthodox/rev3/rev3.h @@ -23,11 +23,8 @@ along with this program. If not, see . #include "orthodox.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, L16, L18, R10, R12, R13, R14, R15, R16, R17, R18, \ diff --git a/keyboards/orthodox/rev3_teensy/rev3_teensy.h b/keyboards/orthodox/rev3_teensy/rev3_teensy.h index 783dfb34b95..d9d0b78dfc3 100644 --- a/keyboards/orthodox/rev3_teensy/rev3_teensy.h +++ b/keyboards/orthodox/rev3_teensy/rev3_teensy.h @@ -23,11 +23,8 @@ along with this program. If not, see . #include "orthodox.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, L16, L18, R10, R12, R13, R14, R15, R16, R17, R18, \ diff --git a/keyboards/pinky/3/3.h b/keyboards/pinky/3/3.h index ca1109d262a..8bd2d49fafc 100644 --- a/keyboards/pinky/3/3.h +++ b/keyboards/pinky/3/3.h @@ -2,7 +2,6 @@ #include "../pinky.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef USE_I2C @@ -13,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, L06, R00, R01, R02, R03, R04, R05, R06, \ L10, L11, L12, L13, L14, L15, L16, R10, R11, R12, R13, R14, R15, R16, \ diff --git a/keyboards/pinky/4/4.h b/keyboards/pinky/4/4.h index ad105ce7fc5..2550940011c 100644 --- a/keyboards/pinky/4/4.h +++ b/keyboards/pinky/4/4.h @@ -2,7 +2,6 @@ #include "../pinky.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef USE_I2C @@ -13,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ L00, L01, L02, L03, L04, L05, L06, R00, R01, R02, R03, R04, R05, R06, \ L10, L11, L12, L13, L14, L15, L16, R10, R11, R12, R13, R14, R15, R16, \ diff --git a/keyboards/rgbkb/zen/rev1/rev1.h b/keyboards/rgbkb/zen/rev1/rev1.h index a12f2ea789a..470a26a43f2 100644 --- a/keyboards/rgbkb/zen/rev1/rev1.h +++ b/keyboards/rgbkb/zen/rev1/rev1.h @@ -2,10 +2,8 @@ #include "zen.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define LAYOUT( \ k00, k01, k02, k03, k04, k05, k55, k54, k53, k52, k51, k50, \ k10, k11, k12, k13, k14, k15, k65, k64, k63, k62, k61, k60, \ diff --git a/keyboards/rgbkb/zen/rev2/rev2.h b/keyboards/rgbkb/zen/rev2/rev2.h index 101622988d3..c545710abb7 100644 --- a/keyboards/rgbkb/zen/rev2/rev2.h +++ b/keyboards/rgbkb/zen/rev2/rev2.h @@ -2,10 +2,8 @@ #include "zen.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" - #ifdef USE_I2C #include #ifdef __AVR__ @@ -14,8 +12,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #ifdef CONVERT_TO_PROTON_C #define LAYOUT( \ k00, k01, k02, k03, k04, k05, k55, k54, k53, k52, k51, k50, \ diff --git a/keyboards/treadstone48/rev1/rev1.h b/keyboards/treadstone48/rev1/rev1.h index c6145398dd8..16ab2d716e0 100644 --- a/keyboards/treadstone48/rev1/rev1.h +++ b/keyboards/treadstone48/rev1/rev1.h @@ -3,7 +3,6 @@ #include "../treadstone48.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE diff --git a/keyboards/vitamins_included/rev1/rev1.h b/keyboards/vitamins_included/rev1/rev1.h index 743c341c3cd..aa502903499 100644 --- a/keyboards/vitamins_included/rev1/rev1.h +++ b/keyboards/vitamins_included/rev1/rev1.h @@ -5,7 +5,6 @@ #include QMK_KEYBOARD_H -//void promicro_bootloader_jmp(bool program); #include "quantum.h" @@ -17,8 +16,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - #define KEYMAP( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/yosino58/rev1/rev1.h b/keyboards/yosino58/rev1/rev1.h index 84d90737d53..bc68892e887 100644 --- a/keyboards/yosino58/rev1/rev1.h +++ b/keyboards/yosino58/rev1/rev1.h @@ -2,7 +2,6 @@ #include "../yosino58.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -18,7 +17,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); #define LAYOUT( \ L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ diff --git a/keyboards/zinc/rev1/rev1.h b/keyboards/zinc/rev1/rev1.h index 933e635c2df..aa1c408b0bf 100644 --- a/keyboards/zinc/rev1/rev1.h +++ b/keyboards/zinc/rev1/rev1.h @@ -2,7 +2,6 @@ #include "../zinc.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -18,10 +17,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - - // Standard Keymap // (TRRS jack on both halves are to the left side) #define LAYOUT( \ diff --git a/keyboards/zinc/reva/reva.h b/keyboards/zinc/reva/reva.h index 933e635c2df..aa1c408b0bf 100644 --- a/keyboards/zinc/reva/reva.h +++ b/keyboards/zinc/reva/reva.h @@ -2,7 +2,6 @@ #include "../zinc.h" -//void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE @@ -18,10 +17,6 @@ #endif #endif -//void promicro_bootloader_jmp(bool program); - - - // Standard Keymap // (TRRS jack on both halves are to the left side) #define LAYOUT( \ From a0f248c20ed14303c742365e841ed2482749c972 Mon Sep 17 00:00:00 2001 From: Ceremony <5873369+Ceremony64@users.noreply.github.com> Date: Wed, 21 Aug 2019 03:26:00 +0200 Subject: [PATCH 41/61] Implement NUMLOCK indicator light for XD96 (#6581) --- keyboards/xd96/xd96.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/keyboards/xd96/xd96.c b/keyboards/xd96/xd96.c index 45cfb3b1f17..e2af9f10043 100644 --- a/keyboards/xd96/xd96.c +++ b/keyboards/xd96/xd96.c @@ -16,9 +16,11 @@ #include "xd96.h" #define CAPS_PIN B6 +#define NUMLOCK_PIN C6 void keyboard_pre_init_kb(void) { setPinOutput(CAPS_PIN); + setPinOutput(NUMLOCK_PIN); keyboard_pre_init_user(); } @@ -29,6 +31,12 @@ void led_set_kb(uint8_t usb_led) { } else { writePinHigh(CAPS_PIN); } + + if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { + writePinLow(NUMLOCK_PIN); + } else { + writePinHigh(NUMLOCK_PIN); + } led_set_user(usb_led); } From 42f2ad96a30cbd9dfaa7afbeddc1e532f4864640 Mon Sep 17 00:00:00 2001 From: mikethetiger <30720424+mikethetiger@users.noreply.github.com> Date: Tue, 20 Aug 2019 23:22:54 -0500 Subject: [PATCH 42/61] [Keymap] mikethetiger's let's split eh? keymap (#6562) * Added my Preonic keymap * Update keyboards/preonic/keymaps/mikethetiger/keymap.c Co-Authored-By: mikethetiger <30720424+mikethetiger@users.noreply.github.com> * Update keyboards/preonic/keymaps/mikethetiger/keymap.c Co-Authored-By: mikethetiger <30720424+mikethetiger@users.noreply.github.com> * Added my Preonic keymap * Added my Preonic keymap * mikethetigers lets slpit eh keymap --- .../keymaps/mikethetiger/config.h | 23 ++++ .../keymaps/mikethetiger/keymap.c | 120 ++++++++++++++++++ .../keymaps/mikethetiger/rules.mk | 0 3 files changed, 143 insertions(+) create mode 100644 keyboards/lets_split_eh/keymaps/mikethetiger/config.h create mode 100644 keyboards/lets_split_eh/keymaps/mikethetiger/keymap.c create mode 100644 keyboards/lets_split_eh/keymaps/mikethetiger/rules.mk diff --git a/keyboards/lets_split_eh/keymaps/mikethetiger/config.h b/keyboards/lets_split_eh/keymaps/mikethetiger/config.h new file mode 100644 index 00000000000..c535299e74a --- /dev/null +++ b/keyboards/lets_split_eh/keymaps/mikethetiger/config.h @@ -0,0 +1,23 @@ +/* +This is the c configuration file for the keymap + +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert + +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 . +*/ + +#pragma once + + // place overrides here diff --git a/keyboards/lets_split_eh/keymaps/mikethetiger/keymap.c b/keyboards/lets_split_eh/keymaps/mikethetiger/keymap.c new file mode 100644 index 00000000000..8ee300b7489 --- /dev/null +++ b/keyboards/lets_split_eh/keymaps/mikethetiger/keymap.c @@ -0,0 +1,120 @@ +#include QMK_KEYBOARD_H + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +enum layers { + _QWERTY, + _LOWER, + _RAISE, + _FUNCTION, + _ADJUST, +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) +#define FUNCTION MO(_FUNCTION) +#define ADJUST MO(_ADJUST) + +// Defines for task manager and such +#define CALTDEL LCTL(LALT(KC_DEL)) +#define TSKMGR LCTL(LSFT(KC_ESC)) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Tab | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT( \ + KC_ESC, 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_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + _______, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 | | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT( \ + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_HOME, KC_END, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 | | |Pg Up |Pg Dn | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT( \ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_PGUP, KC_PGDN, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | RESET| | | | | | |RGBMOD|RGBVAI|RGBSAI|RGBHUI|caltde| + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | | | | | |RGBRMO|RGBVAD|RGBSAD|RGBHUD|RGBTOG| + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | | | | | | | | | | |BLSTEP| + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT( \ + RESET, _______, _______, _______, _______, _______, _______, RGB_MOD, RGB_VAI, RGB_SAI, RGB_HUI, CALTDEL, \ + _______, _______, _______, _______, _______, _______, _______, RGB_RMOD,RGB_VAD, RGB_SAD, RGB_HUD, RGB_TOG, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, BL_STEP, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ +), + +/* Function + * ,-----------------------------------------------------------------------------------. + * | | | | | | | | | Up | | | | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | | | | | | Left | Down |Right | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Caps | | | | | | | | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_FUNCTION] = LAYOUT( \ + _______, _______, _______, _______, _______, _______, _______, _______, KC_UP, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, \ + KC_CAPS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ +) + +}; + +uint32_t layer_state_set_user(uint32_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} diff --git a/keyboards/lets_split_eh/keymaps/mikethetiger/rules.mk b/keyboards/lets_split_eh/keymaps/mikethetiger/rules.mk new file mode 100644 index 00000000000..e69de29bb2d From 5fca6c01204f4cad9af17ec0529a11147a829427 Mon Sep 17 00:00:00 2001 From: Sid Carter Date: Wed, 21 Aug 2019 00:33:06 -0400 Subject: [PATCH 43/61] [Keymap] Add velocikey, move reset and align layout (#6569) --- .../projectkb/alice/keymaps/madhatter/keymap.c | 14 +++++++------- .../projectkb/alice/keymaps/madhatter/rules.mk | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 keyboards/projectkb/alice/keymaps/madhatter/rules.mk diff --git a/keyboards/projectkb/alice/keymaps/madhatter/keymap.c b/keyboards/projectkb/alice/keymaps/madhatter/keymap.c index 32cf7e0ba76..7ebb670e0c3 100644 --- a/keyboards/projectkb/alice/keymaps/madhatter/keymap.c +++ b/keyboards/projectkb/alice/keymaps/madhatter/keymap.c @@ -25,19 +25,19 @@ enum layer_names { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT_default( - KC_ESC, KC_GRV, 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_DEL, KC_BSPC, + KC_ESC, 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_DEL, KC_BSPC, 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_BSLS, - KC_PGDN, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_PGDN, KC_GRV, 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_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RALT, KC_LCTL, KC_LALT, KC_ENT, KC_LCMD, KC_SPC, FNM, KC_RCTL ), [_FNM] = LAYOUT_default( - RGB_TOG, _______, 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_MOD, _______, _______, _______, _______, _______, _______, RGB_SAI, RGB_HUI, RGB_VAI, RGB_SAD, RGB_HUD, RGB_VAD, _______, _______, - RGB_RMOD, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, - _______, BL_INC, BL_DEC, BL_TOGG, BL_BRTG, _______, _______, _______, _______, _______, _______, _______, _______, _______, - RESET, _______, _______, _______, _______, _______, _______ + RGB_TOG, _______, 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_MOD, _______, _______, _______, _______, _______, _______, RGB_SAI, RGB_HUI, RGB_VAI, RGB_SAD, RGB_HUD, RGB_VAD, _______, RESET, + VLK_TOG, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, + _______, BL_INC, BL_DEC, BL_TOGG, BL_BRTG, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______ ) }; diff --git a/keyboards/projectkb/alice/keymaps/madhatter/rules.mk b/keyboards/projectkb/alice/keymaps/madhatter/rules.mk new file mode 100644 index 00000000000..1b0f198d06c --- /dev/null +++ b/keyboards/projectkb/alice/keymaps/madhatter/rules.mk @@ -0,0 +1 @@ +VELOCIKEY_ENABLE = yes From 367eac22293ac148e19e545e110d5a591de1eb6e Mon Sep 17 00:00:00 2001 From: noroadsleft <18669334+noroadsleft@users.noreply.github.com> Date: Tue, 20 Aug 2019 21:57:45 -0700 Subject: [PATCH 44/61] [Keyboard] PCB Ruler updates (#6584) * Move default keymap's rules to keyboard level * Concatenate the two sets of rules This sets CONSOLE_ENABLE to no, which was being set at the keymap level. * Wrap the USB Device Description in quotes Some preventative maintenance. The firmware for the_ruler can't be compiled without this change if `CONSOLE_ENABLE = yes` because this string has a comma, which gets picked up as two arguments by the Command code, instead of one as it should be. * Linting - remove firmware size impacts - remove trailing white space - visual alignment of rules * Use QMK's pre-loaded default rules for atmega32u4 * Update readme - markdown formatting - update Hardware Availability link (Maple Computing's site has disappeared) - update Docs links * Update header files to use #pragma once --- keyboards/the_ruler/config.h | 7 +-- keyboards/the_ruler/keymaps/default/rules.mk | 18 -------- keyboards/the_ruler/readme.md | 9 ++-- keyboards/the_ruler/rules.mk | 47 +++----------------- keyboards/the_ruler/the_ruler.h | 5 +-- 5 files changed, 12 insertions(+), 74 deletions(-) diff --git a/keyboards/the_ruler/config.h b/keyboards/the_ruler/config.h index ecae3a4f21c..0ec3f69d1bd 100644 --- a/keyboards/the_ruler/config.h +++ b/keyboards/the_ruler/config.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef CONFIG_H -#define CONFIG_H +#pragma once #include "config_common.h" @@ -26,7 +25,7 @@ along with this program. If not, see . #define DEVICE_VER 0x0001 #define MANUFACTURER Maple Computing #define PRODUCT The PCB Ruler -#define DESCRIPTION A custom keyboard PCB ruler, can also function as a macro pad +#define DESCRIPTION "A custom keyboard PCB ruler, can also function as a macro pad" /* key matrix size */ #define MATRIX_ROWS 1 @@ -155,5 +154,3 @@ along with this program. If not, see . #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 - -#endif diff --git a/keyboards/the_ruler/keymaps/default/rules.mk b/keyboards/the_ruler/keymaps/default/rules.mk index 2791cc1054b..e69de29bb2d 100644 --- a/keyboards/the_ruler/keymaps/default/rules.mk +++ b/keyboards/the_ruler/keymaps/default/rules.mk @@ -1,18 +0,0 @@ -# Build Options -# change to "no" to disable the options, or define them in the Makefile in -# the appropriate keymap folder that will get included automatically -# -BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = no # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration -NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality -MIDI_ENABLE = no # MIDI controls -AUDIO_ENABLE = no # Audio output on port C6 -UNICODE_ENABLE = no # Unicode -BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. -SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend - diff --git a/keyboards/the_ruler/readme.md b/keyboards/the_ruler/readme.md index 63a6ffeee37..13ea61c9a7e 100644 --- a/keyboards/the_ruler/readme.md +++ b/keyboards/the_ruler/readme.md @@ -1,14 +1,13 @@ -The Ruler PCB -======= +# The Ruler PCB -A custom keyboard PCB ruler, that can also function as a macro pad +A custom keyboard PCB ruler, that can also function as a macro pad. Keyboard Maintainer: Maple Computing Hardware Supported: PCB Ruler V1 by That-Canadian and Bishop Keyboards -Hardware Availability: https://www.maple-computing.com/products/pcb-ruler-v1-1 +Hardware Availability: [Bishop Keyboards](https://bishopkeyboards.com/product/pcb-ruler-gloss-black-silver/) Make example for this keyboard (after setting up your build environment): make the_ruler: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. +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). diff --git a/keyboards/the_ruler/rules.mk b/keyboards/the_ruler/rules.mk index 7eca12ad4f2..33611c44bb0 100644 --- a/keyboards/the_ruler/rules.mk +++ b/keyboards/the_ruler/rules.mk @@ -1,43 +1,6 @@ # MCU name MCU = atmega32u4 -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency in Hz. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# -# This will be an integer division of F_USB below, as it is sourced by -# F_USB after it has run through any CPU prescalers. Note that this value -# does not *change* the processor frequency - it should merely be updated to -# reflect the processor speed set externally so that the code can use accurate -# software delays. -F_CPU = 16000000 - - -# -# LUFA specific -# -# Target architecture (see library "Board Types" documentation). -ARCH = AVR8 - -# Input clock frequency. -# This will define a symbol, F_USB, in all source code files equal to the -# input clock frequency (before any prescaling is performed) in Hz. This value may -# differ from F_CPU if prescaling is used on the latter, and is required as the -# raw input clock is fed directly to the PLL sections of the AVR for high speed -# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -# at the end, this will be done automatically to create a 32-bit value in your -# source code. -# -# If no clock division is performed on the input clock inside the AVR (via the -# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -F_USB = $(F_CPU) - -# Interrupt driven control endpoint task(+60) -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - - # Boot Section Size in *bytes* # Teensy halfKay 512 # Teensy++ halfKay 1024 @@ -50,10 +13,10 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096 # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) +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 = yes # 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 @@ -64,4 +27,4 @@ MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 -RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. +RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. diff --git a/keyboards/the_ruler/the_ruler.h b/keyboards/the_ruler/the_ruler.h index 45a327b0dcc..171d21a072a 100644 --- a/keyboards/the_ruler/the_ruler.h +++ b/keyboards/the_ruler/the_ruler.h @@ -1,5 +1,4 @@ -#ifndef THERULER_H -#define THERULER_H +#pragma once #include "quantum.h" @@ -7,5 +6,3 @@ K00, K01, K02, K03, K04, K05 ) { \ { K00, K01, K02, K03, K04, K05 } \ } - -#endif From 977c316eb1bdca7f0e13026936322cb9a9fcd0d2 Mon Sep 17 00:00:00 2001 From: imchipwood Date: Tue, 20 Aug 2019 22:08:30 -0700 Subject: [PATCH 45/61] [Keymap] dumbpad updates, new keymap (#6481) * removed some debug prints * removed unnecessary files, tweaked some things * rotary encoder button now connected into column 0, row 3 * tweaked keymap and moved encoder control into keymap * tweaks * added test keymap * updated some things to make it easier to work with QMK configurator * updates after merging latest master in * fixed a few things * removed test keymap and all related #ifdefs * changed some dumbpad default keys, added KC_LOCK * added image to readme * added link to PCB github repo * moved lock key to the rotary encoder pushbutton * making suggested changes from @fauxpark in https://github.com/qmk/qmk_firmware/pull/6452 * adding bootmagic lite since i'm lazy and haven't soldered on the reset button... * renamed to * using 7 underscores for KC_TRNS * adding my layout (default is for wife) * updated my own layout, tweaked default keymap to use cleaner switch for encoder control * removed commented out import from imchipwood keymap, removed unnecessary comment from default layout * added LED layer control * flash the layer indicator LEDs at startup * change layer_state_set_user to layer_state_set_kb Co-Authored-By: Joel Challis * in layer_state_set_kb, return layer_state_set_user Co-Authored-By: Drashna Jaelre * remove include of upper level config.h, add pragma once Co-Authored-By: Drashna Jaelre * changing default keymap slightly, added config.h for default layout * change _delay_ms to wait_ms * replaced locking numlock with numlock * Update keyboards/dumbpad/dumbpad.c change `keyboard_pre_init_user` to `keyboard_pre_init_kb` Co-Authored-By: Joel Challis * Update keyboards/dumbpad/dumbpad.c adding `keyboard_pre_init_user()` to `keyboard_pre_init_kb()` Co-Authored-By: Joel Challis * fixed some comments about the layer key (MO to TT) and the SUB layer rotary encoder control --- keyboards/dumbpad/config.h | 4 + keyboards/dumbpad/dumbpad.c | 40 ++++- keyboards/dumbpad/keymaps/default/config.h | 2 + keyboards/dumbpad/keymaps/default/keymap.c | 45 +++-- keyboards/dumbpad/keymaps/imchipwood/config.h | 2 + keyboards/dumbpad/keymaps/imchipwood/keymap.c | 163 ++++++++++++++++++ 6 files changed, 237 insertions(+), 19 deletions(-) create mode 100644 keyboards/dumbpad/keymaps/default/config.h create mode 100644 keyboards/dumbpad/keymaps/imchipwood/config.h create mode 100644 keyboards/dumbpad/keymaps/imchipwood/keymap.c diff --git a/keyboards/dumbpad/config.h b/keyboards/dumbpad/config.h index a7d4e7b3c8c..3c27a35b28d 100644 --- a/keyboards/dumbpad/config.h +++ b/keyboards/dumbpad/config.h @@ -51,6 +51,10 @@ along with this program. If not, see . #define ENCODERS_PAD_A { D0 } #define ENCODERS_PAD_B { D4 } +/* LED layer indicators */ +#define LAYER_INDICATOR_LED_0 B3 +#define LAYER_INDICATOR_LED_1 B1 + /* Bootmagic - hold down rotary encoder pushbutton while plugging in to enter bootloader */ #define BOOTMAGIC_LITE_ROW 3 #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/keyboards/dumbpad/dumbpad.c b/keyboards/dumbpad/dumbpad.c index b53856237c0..d9b649c7155 100644 --- a/keyboards/dumbpad/dumbpad.c +++ b/keyboards/dumbpad/dumbpad.c @@ -15,15 +15,49 @@ */ #include "dumbpad.h" +void keyboard_pre_init_kb(void) { + // Set the layer LED IO as outputs + setPinOutput(LAYER_INDICATOR_LED_0); + setPinOutput(LAYER_INDICATOR_LED_1); + + keyboard_pre_init_user(); +} + +void shutdown_user() { + // Shutdown the layer LEDs + writePinLow(LAYER_INDICATOR_LED_0); + writePinLow(LAYER_INDICATOR_LED_1); +} + +layer_state_t layer_state_set_kb(layer_state_t state) { + // Layer LEDs act as binary indication of current layer + uint8_t layer = biton32(state); + writePin(LAYER_INDICATOR_LED_0, layer & 0b1); + writePin(LAYER_INDICATOR_LED_1, (layer >> 1) & 0b1); + return layer_state_set_user(state); +} + // Optional override functions below. // You can leave any or all of these undefined. // These are only required if you want to perform custom actions. -/* - void matrix_init_kb(void) { // put your keyboard start-up code here // runs once when the firmware starts up + for (int i = 0; i < 2; i++) { + writePin(LAYER_INDICATOR_LED_0, true); + writePin(LAYER_INDICATOR_LED_1, false); + wait_ms(100); + writePin(LAYER_INDICATOR_LED_0, true); + writePin(LAYER_INDICATOR_LED_1, true); + wait_ms(100); + writePin(LAYER_INDICATOR_LED_0, false); + writePin(LAYER_INDICATOR_LED_1, true); + wait_ms(100); + writePin(LAYER_INDICATOR_LED_0, false); + writePin(LAYER_INDICATOR_LED_1, false); + wait_ms(100); + } matrix_init_user(); } @@ -47,5 +81,3 @@ void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } - -*/ diff --git a/keyboards/dumbpad/keymaps/default/config.h b/keyboards/dumbpad/keymaps/default/config.h new file mode 100644 index 00000000000..83808855931 --- /dev/null +++ b/keyboards/dumbpad/keymaps/default/config.h @@ -0,0 +1,2 @@ +#pragma once +#define TAPPING_TOGGLE 2 diff --git a/keyboards/dumbpad/keymaps/default/keymap.c b/keyboards/dumbpad/keymaps/default/keymap.c index 061215a61bc..c0d4a7c0771 100644 --- a/keyboards/dumbpad/keymaps/default/keymap.c +++ b/keyboards/dumbpad/keymaps/default/keymap.c @@ -28,14 +28,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |---------|---------|---------|---------| | | 1 | 2 | 3 | Tab | |-------------|---------|---------|---------|---------| - | Left mouse | MO(SUB) | 0 | . | Enter | + | Left mouse | TT(SUB) | 0 | . | Enter | \-----------------------------------------------------' */ - [_BASE] = LAYOUT( /* Base */ + [_BASE] = LAYOUT( KC_7, KC_8, KC_9, KC_BSPC, KC_4, KC_5, KC_6, KC_ESC, KC_1, KC_2, KC_3, KC_TAB, - KC_BTN1, MO(_SUB), KC_0, KC_DOT, KC_ENTER + KC_BTN1, TT(_SUB), KC_0, KC_DOT, KC_ENTER ), /* SUB LAYER @@ -88,19 +88,34 @@ void led_set_user(uint8_t usb_led) { } void encoder_update_user(uint8_t index, bool clockwise) { + /* Custom encoder control - handles CW/CCW turning of encoder + * Default behavior: + * main layer: + * CW: move mouse right + * CCW: move mouse left + * other layers: + * CW: = (equals/plus - increase slider in Adobe products) + * CCW: - (minus/underscore - decrease slider in adobe products) + */ if (index == 0) { - if (layer_state && 0x1) { - if (clockwise) { - tap_code(KC_VOLU); - } else { - tap_code(KC_VOLD); - } - } else { - if (clockwise) { - tap_code(KC_MS_R); - } else { - tap_code(KC_MS_L); - } + switch (biton32(layer_state)) { + case _BASE: + // main layer - move mouse right (CW) and left (CCW) + if (clockwise) { + tap_code(KC_MS_R); + } else { + tap_code(KC_MS_L); + } + break; + + default: + // other layers - =/+ (quals/plus) (CW) and -/_ (minus/underscore) (CCW) + if (clockwise) { + tap_code(KC_EQL); + } else { + tap_code(KC_MINS); + } + break; } } } diff --git a/keyboards/dumbpad/keymaps/imchipwood/config.h b/keyboards/dumbpad/keymaps/imchipwood/config.h new file mode 100644 index 00000000000..83808855931 --- /dev/null +++ b/keyboards/dumbpad/keymaps/imchipwood/config.h @@ -0,0 +1,2 @@ +#pragma once +#define TAPPING_TOGGLE 2 diff --git a/keyboards/dumbpad/keymaps/imchipwood/keymap.c b/keyboards/dumbpad/keymaps/imchipwood/keymap.c new file mode 100644 index 00000000000..73a8e824ca2 --- /dev/null +++ b/keyboards/dumbpad/keymaps/imchipwood/keymap.c @@ -0,0 +1,163 @@ +/* Copyright 2019 imchipwood + * + * 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 . + */ +#include QMK_KEYBOARD_H + +#define _BASE 0 +#define _SUB 1 +#define _DBG 2 + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* + BASE LAYER + /-----------------------------------------------------` + | | 7 | 8 | 9 | Bkspc | + | |---------|---------|---------|---------| + | | 4 | 5 | 6 | + | + | |---------|---------|---------|---------| + | | 1 | 2 | 3 | * | + |-------------|---------|---------|---------|---------| + | Play/Pause | TT(SUB) | 0 | . | Enter | + \-----------------------------------------------------' + */ + [_BASE] = LAYOUT( + KC_P7, KC_P8, KC_P9, KC_BSPC, + KC_P4, KC_P5, KC_P6, KC_KP_PLUS, + KC_P1, KC_P2, KC_P3, KC_KP_ASTERISK, + KC_MPLY, TT(_SUB), KC_P0, KC_PDOT, KC_KP_ENTER + ), + /* + SUB LAYER + /-----------------------------------------------------` + | | | | | Numlock | + | |---------|---------|---------|---------| + | | | | | - | + | |---------|---------|---------|---------| + | | | | | / | + |-------------|---------|---------|---------|---------| + | MO(_DBG) | | | | = | + \-----------------------------------------------------' + */ + [_SUB] = LAYOUT( + _______, _______, _______, KC_NLCK, + _______, _______, _______, KC_KP_MINUS, + _______, _______, _______, KC_KP_SLASH, + MO(_DBG), _______, _______, _______, KC_KP_EQUAL + ), + /* + DEBUG LAYER + /-----------------------------------------------------` + | | | | | Reset | + | |---------|---------|---------|---------| + | | | | | | + | |---------|---------|---------|---------| + | | | | | | + |-------------|---------|---------|---------|---------| + | | | | | | + \-----------------------------------------------------' + */ + [_DBG] = LAYOUT( + _______, _______, _______, RESET, + _______, _______, _______, _______, + _______, _______, _______, _______, + _______, _______, _______, _______, _______ + ), +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // If console is enabled, it will print the matrix position and status of each key pressed +/* +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif +*/ + return true; +} + +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + //debug_enable = true; + //debug_matrix = true; + //debug_keyboard = true; + //debug_mouse = true; +} + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +void led_set_user(uint8_t usb_led) { + +} + + +void encoder_update_user(uint8_t index, bool clockwise) { + /* Custom encoder control - handles CW/CCW turning of encoder + * Cusotom behavior: + * main layer: + * CW: volume up + * CCW: volume down + * sub layer: + * CW: next media track + * CCW: prev media track + * debug layer: + * CW: brightness up + * CCW: brightness down + */ + if (index == 0) { + switch (biton32(layer_state)) { + case _BASE: + // main layer - volume up (CW) and down (CCW) + if (clockwise) { + tap_code(KC_VOLU); + } else { + tap_code(KC_VOLD); + } + break; + + case _SUB: + // sub layer - next track (CW) and previous track (CCW) + if (clockwise) { + tap_code(KC_MNXT); + } else { + tap_code(KC_MPRV); + } + break; + + case _DBG: + // debug layer - brightness up (CW) and brightness down (CCW) + if (clockwise) { + tap_code(KC_BRIU); + } else { + tap_code(KC_BRID); + } + break; + + default: + // any other layer (shouldn't exist..) - volume up (CW) and down (CCW) + if (clockwise) { + tap_code(KC_VOLU); + } else { + tap_code(KC_VOLD); + } + break; + } + } +} From f2c179de58c63b2202a490d283fd8fa216680ce7 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Wed, 21 Aug 2019 15:18:52 +1000 Subject: [PATCH 46/61] Remove superfluous JTAG disable code (#6445) * Remove superfluous JTAG disable code * 32A has differently named register * Accidentally some operators * 32A also has different JTAG pins * Wrap disable_jtag() in an ifndef * Document this new define * Rename the define, it conflicts with a LUFA thing Also, move the ifndef wrapping to the call in keyboard_setup() --- docs/faq_debug.md | 17 +++++------------ docs/zh-cn/faq_debug.md | 17 ----------------- keyboards/amj96/matrix.c | 3 --- keyboards/clueboard/17/17.c | 4 ---- keyboards/clueboard/66/rev2/rev2.c | 4 ---- .../clueboard/66_hotswap/prototype/prototype.c | 4 ---- keyboards/ergodone/matrix.c | 4 ---- keyboards/handwired/promethium/matrix.c | 7 ------- keyboards/hhkb/rn42/rn42.c | 4 ---- keyboards/hid_liber/matrix.c | 4 ---- keyboards/hotdox/matrix.c | 4 ---- keyboards/launchpad/rev1/rev1.c | 7 +------ keyboards/lets_split/sockets/sockets.h | 1 - keyboards/miniaxe/config.h | 2 -- keyboards/sx60/matrix.c | 7 ------- keyboards/vitamins_included/matrix.c | 6 ------ keyboards/vitamins_included/rev1/rev1.h | 1 - tmk_core/common/keyboard.c | 11 +++++++++-- tmk_core/common/keyboard.h | 2 -- 19 files changed, 15 insertions(+), 94 deletions(-) diff --git a/docs/faq_debug.md b/docs/faq_debug.md index f6cc729b612..5cc20251d30 100644 --- a/docs/faq_debug.md +++ b/docs/faq_debug.md @@ -184,22 +184,15 @@ Pressing any key during sleep should wake host. Arduino Leonardo and micro have **ATMega32U4** and can be used for TMK, though Arduino bootloader may be a problem. +## Enabling JTAG -## Using PF4-7 Pins of USB AVR? -You need to set JTD bit of MCUCR yourself to use PF4-7 as GPIO. Those pins are configured to serve JTAG function by default. MCUs like ATMega*U* or AT90USB* are affected with this. +By default, the JTAG debugging interface is disabled as soon as the keyboard starts up. JTAG-capable MCUs come from the factory with the `JTAGEN` fuse set, and it takes over certain pins of the MCU that the board may be using for the switch matrix, LEDs, etc. -If you are using Teensy this isn't needed. Teensy is shipped with JTAGEN fuse bit unprogrammed to disable the function. +If you would like to keep JTAG enabled, just add the following to your `config.h`: -See this code. +```c +#define NO_JTAG_DISABLE ``` - // JTAG disable for PORT F. write JTD bit twice within four cycles. - MCUCR |= (1< -代码如下。 -``` - // F接口JTAG失能。在四个周期内写入两次JTD位。 - MCUCR |= (1<. //#define EE_HANDS #define I2C_MASTER_LEFT //#define I2C_MASTER_RIGHT - -#define DISABLE_JTAG diff --git a/keyboards/sx60/matrix.c b/keyboards/sx60/matrix.c index e8e9d6574e8..58647d13b08 100644 --- a/keyboards/sx60/matrix.c +++ b/keyboards/sx60/matrix.c @@ -113,13 +113,6 @@ uint8_t matrix_cols(void) { } void matrix_init(void) { - - /* To use PORTF disable JTAG with writing JTD bit twice within four cycles. */ - #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__)) - MCUCR |= _BV(JTD); - MCUCR |= _BV(JTD); - #endif - mcp23018_status = true; /* initialize row and col */ diff --git a/keyboards/vitamins_included/matrix.c b/keyboards/vitamins_included/matrix.c index 1f5071c6932..d44e70f08ee 100644 --- a/keyboards/vitamins_included/matrix.c +++ b/keyboards/vitamins_included/matrix.c @@ -136,12 +136,6 @@ bool has_usb(void) { void matrix_init(void) { -#ifdef DISABLE_JTAG - // JTAG disable for PORT F. write JTD bit twice within four cycles. - MCUCR |= (1< Date: Tue, 20 Aug 2019 22:39:13 -0700 Subject: [PATCH 47/61] [Keyboard] Tweak RGB Matrix timing for ZSA Boards (#6422) * Optimize RGB Matrix rendering for Ergodox EZ * Optimize RGB Matrix rendering for Planck EZ * Update keyboards/planck/ez/config.h Co-Authored-By: Joel Challis --- keyboards/ergodox_ez/config.h | 3 +++ keyboards/planck/ez/config.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/keyboards/ergodox_ez/config.h b/keyboards/ergodox_ez/config.h index d22836bd867..45ca06a5d22 100644 --- a/keyboards/ergodox_ez/config.h +++ b/keyboards/ergodox_ez/config.h @@ -109,6 +109,9 @@ along with this program. If not, see . #define DRIVER_2_LED_TOTAL 24 #define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) +#define RGB_MATRIX_LED_PROCESS_LIMIT 5 +#define RGB_MATRIX_LED_FLUSH_LIMIT 26 + // #define RGBLIGHT_COLOR_LAYER_0 0x00, 0x00, 0xFF /* #define RGBLIGHT_COLOR_LAYER_1 0x00, 0x00, 0xFF */ /* #define RGBLIGHT_COLOR_LAYER_2 0xFF, 0x00, 0x00 */ diff --git a/keyboards/planck/ez/config.h b/keyboards/planck/ez/config.h index d007873bbaa..61d9981c181 100644 --- a/keyboards/planck/ez/config.h +++ b/keyboards/planck/ez/config.h @@ -140,6 +140,10 @@ #define RGB_MATRIX_KEYPRESSES #define RGB_MATRIX_FRAMEBUFFER_EFFECTS +#define RGB_MATRIX_LED_PROCESS_LIMIT 5 +#define RGB_MATRIX_LED_FLUSH_LIMIT 26 + + #define IGNORE_MOD_TAP_INTERRUPT #define TAPPING_TOGGLE 1 From d534c72a544454132b3c6c05af85c821f6a93d65 Mon Sep 17 00:00:00 2001 From: Stephen Wanhella Date: Wed, 21 Aug 2019 17:07:08 -0700 Subject: [PATCH 48/61] Added keycodes for swapping and unswapping the Control and OS keys (#6110) * Add MAGIC_SWAP_CONTROL_LGUI and MAGIC_UNSWAP_CONTROL_LGUI keycodes Key codes to swap and unswap the control and windows/cmd keys * Fix issues with pull request #6110 Renamed swap/unswap lctl and lgui key codes, added key codes to swap/unswap rctl and rgui, and moved new bool inside keycode_config.h struct to the end * Move new keycodes to the end of the enum (#6110) * add cases for swapped control and OS keys to mod_config (#6110) * Add new keycodes to feature_bootmagic.md (#6110) * Add R+L swap codes to keep in parity with AG_* codes * Extend Magic range check to include new magic codes * Update audio docs * Combine 2 byte ranges into 1 word for EECONFG Fix names for Keymap config EEPROM * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> --- docs/feature_audio.md | 2 ++ docs/feature_bootmagic.md | 11 +++++++-- docs/keycodes.md | 11 +++++++-- quantum/keycode_config.c | 38 ++++++++++++++++++++++++++++++ quantum/keycode_config.h | 2 ++ quantum/quantum.c | 48 +++++++++++++++++++++++++++++++++++++- quantum/quantum_keycodes.h | 13 +++++++++++ tmk_core/common/command.c | 2 ++ tmk_core/common/eeconfig.c | 12 +++++++--- tmk_core/common/eeconfig.h | 8 ++++--- 10 files changed, 136 insertions(+), 11 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 7511598bcfb..5132dfe9719 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -21,6 +21,8 @@ STARTUP_SONG // plays when the keyboard starts up (audio.c) GOODBYE_SONG // plays when you press the RESET key (quantum.c) AG_NORM_SONG // plays when you press AG_NORM (quantum.c) AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c) +CG_NORM_SONG // plays when you press CG_NORM (quantum.c) +CG_SWAP_SONG // plays when you press CG_SWAP (quantum.c) MUSIC_ON_SONG // plays when music mode is activated (process_music.c) MUSIC_OFF_SONG // plays when music mode is deactivated (process_music.c) CHROMATIC_SONG // plays when the chromatic music mode is selected (process_music.c) diff --git a/docs/feature_bootmagic.md b/docs/feature_bootmagic.md index 225189ccb76..fc37a3302b1 100644 --- a/docs/feature_bootmagic.md +++ b/docs/feature_bootmagic.md @@ -64,8 +64,11 @@ Hold down the Bootmagic key (Space by default) and the desired hotkey while plug |`MAGIC_NO_GUI` | |Disable the GUI keys (useful when gaming) | |`MAGIC_UNNO_GUI` | |Enable the GUI keys | |`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides (for macOS)| -|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Left Alt and Left GUI | -|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Left Alt and GUI swap | +|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap | +|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Ctrl and GUI on both sides (for macOS)| +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap | |`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace | |`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace | |`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Left Control and Caps Lock | @@ -76,6 +79,10 @@ Hold down the Bootmagic key (Space by default) and the desired hotkey while plug |`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and Left GUI | |`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and Right GUI | |`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and Right GUI | +|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and Left GUI | +|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and Left GUI | +|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and Right GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and Right GUI | ## Configuration diff --git a/docs/keycodes.md b/docs/keycodes.md index bd4dd61a5b4..e17fef6fd20 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -261,6 +261,8 @@ This is a reference only. Each group of keys links to the page documenting their |----------------------------------|---------|------------------------------------| |`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Caps Lock and Left Control | |`MAGIC_CAPSLOCK_TO_CONTROL` | |Treat Caps Lock as Control | +|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and GUI | +|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and GUI | |`MAGIC_SWAP_LALT_LGUI` | |Swap Left Alt and GUI | |`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and GUI | |`MAGIC_NO_GUI` | |Disable the GUI key | @@ -268,8 +270,11 @@ This is a reference only. Each group of keys links to the page documenting their |`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace | |`MAGIC_HOST_NKRO` | |Force NKRO on | |`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | +|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Ctrl and GUI on both sides (for macOS)| |`MAGIC_UNSWAP_CONTROL_CAPSLOCK` | |Unswap Caps Lock and Left Control | |`MAGIC_UNCAPSLOCK_TO_CONTROL` | |Stop treating Caps Lock as Control | +|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and GUI | |`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and GUI | |`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and GUI | |`MAGIC_UNNO_GUI` | |Enable the GUI key | @@ -277,8 +282,10 @@ This is a reference only. Each group of keys links to the page documenting their |`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace | |`MAGIC_UNHOST_NKRO` | |Force NKRO off | |`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | -|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides| -|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI on both sides | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap on both sides | +|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | ## [Bluetooth](feature_bluetooth.md) diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c index 0dc5105d218..73fe15861d0 100644 --- a/quantum/keycode_config.c +++ b/quantum/keycode_config.c @@ -31,6 +31,12 @@ uint16_t keycode_config(uint16_t keycode) { if (keymap_config.swap_control_capslock) { return KC_CAPSLOCK; } + if (keymap_config.swap_lctl_lgui) { + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_LGUI; + } return KC_LCTL; case KC_LALT: if (keymap_config.swap_lalt_lgui) { @@ -44,10 +50,21 @@ uint16_t keycode_config(uint16_t keycode) { if (keymap_config.swap_lalt_lgui) { return KC_LALT; } + if (keymap_config.swap_lctl_lgui) { + return KC_LCTRL; + } if (keymap_config.no_gui) { return KC_NO; } return KC_LGUI; + case KC_RCTL: + if (keymap_config.swap_rctl_rgui) { + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_RGUI; + } + return KC_RCTL; case KC_RALT: if (keymap_config.swap_ralt_rgui) { if (keymap_config.no_gui) { @@ -60,6 +77,9 @@ uint16_t keycode_config(uint16_t keycode) { if (keymap_config.swap_ralt_rgui) { return KC_RALT; } + if (keymap_config.swap_rctl_rgui) { + return KC_RCTL; + } if (keymap_config.no_gui) { return KC_NO; } @@ -108,6 +128,24 @@ uint8_t mod_config(uint8_t mod) { mod |= MOD_RGUI; } } + if (keymap_config.swap_lctl_lgui) { + if ((mod & MOD_RGUI) == MOD_LGUI) { + mod &= ~MOD_LGUI; + mod |= MOD_LCTL; + } else if ((mod & MOD_RCTL) == MOD_LCTL) { + mod &= ~MOD_LCTL; + mod |= MOD_LGUI; + } + } + if (keymap_config.swap_rctl_rgui) { + if ((mod & MOD_RGUI) == MOD_RGUI) { + mod &= ~MOD_RGUI; + mod |= MOD_RCTL; + } else if ((mod & MOD_RCTL) == MOD_RCTL) { + mod &= ~MOD_RCTL; + mod |= MOD_RGUI; + } + } if (keymap_config.no_gui) { mod &= ~MOD_LGUI; mod &= ~MOD_RGUI; diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index 022f4bd19bb..7b01fcea456 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -36,6 +36,8 @@ typedef union { bool swap_grave_esc:1; bool swap_backslash_backspace:1; bool nkro:1; + bool swap_lctl_lgui:1; + bool swap_rctl_rgui:1; }; } keymap_config_t; diff --git a/quantum/quantum.c b/quantum/quantum.c index 77cbbb2e77d..f489c90310e 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -65,9 +65,17 @@ extern backlight_config_t backlight_config; #ifndef AG_SWAP_SONG #define AG_SWAP_SONG SONG(AG_SWAP_SOUND) #endif + #ifndef CG_NORM_SONG + #define CG_NORM_SONG SONG(AG_NORM_SOUND) + #endif + #ifndef CG_SWAP_SONG + #define CG_SWAP_SONG SONG(AG_SWAP_SOUND) + #endif float goodbye_song[][2] = GOODBYE_SONG; float ag_norm_song[][2] = AG_NORM_SONG; float ag_swap_song[][2] = AG_SWAP_SONG; + float cg_norm_song[][2] = CG_NORM_SONG; + float cg_swap_song[][2] = CG_SWAP_SONG; #ifdef DEFAULT_LAYER_SONGS float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; #endif @@ -563,7 +571,8 @@ bool process_record_quantum(keyrecord_t *record) { return false; #endif #endif - case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI: + case MAGIC_SWAP_LCTL_LGUI ... MAGIC_TOGGLE_CTL_GUI: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { @@ -585,6 +594,12 @@ bool process_record_quantum(keyrecord_t *record) { case MAGIC_SWAP_RALT_RGUI: keymap_config.swap_ralt_rgui = true; break; + case MAGIC_SWAP_LCTL_LGUI: + keymap_config.swap_lctl_lgui = true; + break; + case MAGIC_SWAP_RCTL_RGUI: + keymap_config.swap_rctl_rgui = true; + break; case MAGIC_NO_GUI: keymap_config.no_gui = true; break; @@ -604,6 +619,13 @@ bool process_record_quantum(keyrecord_t *record) { PLAY_SONG(ag_swap_song); #endif break; + case MAGIC_SWAP_CTL_GUI: + keymap_config.swap_lctl_lgui = true; + keymap_config.swap_rctl_rgui = true; + #ifdef AUDIO_ENABLE + PLAY_SONG(cg_swap_song); + #endif + break; case MAGIC_UNSWAP_CONTROL_CAPSLOCK: keymap_config.swap_control_capslock = false; break; @@ -616,6 +638,12 @@ bool process_record_quantum(keyrecord_t *record) { case MAGIC_UNSWAP_RALT_RGUI: keymap_config.swap_ralt_rgui = false; break; + case MAGIC_UNSWAP_LCTL_LGUI: + keymap_config.swap_lctl_lgui = false; + break; + case MAGIC_UNSWAP_RCTL_RGUI: + keymap_config.swap_rctl_rgui = false; + break; case MAGIC_UNNO_GUI: keymap_config.no_gui = false; break; @@ -635,6 +663,13 @@ bool process_record_quantum(keyrecord_t *record) { PLAY_SONG(ag_norm_song); #endif break; + case MAGIC_UNSWAP_CTL_GUI: + keymap_config.swap_lctl_lgui = false; + keymap_config.swap_rctl_rgui = false; + #ifdef AUDIO_ENABLE + PLAY_SONG(cg_norm_song); + #endif + break; case MAGIC_TOGGLE_ALT_GUI: keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; @@ -646,6 +681,17 @@ bool process_record_quantum(keyrecord_t *record) { } #endif break; + case MAGIC_TOGGLE_CTL_GUI: + keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui; + keymap_config.swap_rctl_rgui = !keymap_config.swap_rctl_rgui; + #ifdef AUDIO_ENABLE + if (keymap_config.swap_rctl_rgui) { + PLAY_SONG(cg_swap_song); + } else { + PLAY_SONG(cg_norm_song); + } + #endif + break; case MAGIC_TOGGLE_NKRO: keymap_config.nkro = !keymap_config.nkro; break; diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index b5c6783e5e7..bb16da4d500 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -492,6 +492,15 @@ enum quantum_keycodes { CMB_ON, CMB_OFF, CMB_TOG, + + MAGIC_SWAP_LCTL_LGUI, + MAGIC_SWAP_RCTL_RGUI, + MAGIC_UNSWAP_LCTL_LGUI, + MAGIC_UNSWAP_RCTL_RGUI, + MAGIC_SWAP_CTL_GUI, + MAGIC_UNSWAP_CTL_GUI, + MAGIC_TOGGLE_CTL_GUI, + // always leave at the end SAFE_RANGE }; @@ -639,6 +648,10 @@ enum quantum_keycodes { #define AG_NORM MAGIC_UNSWAP_ALT_GUI #define AG_TOGG MAGIC_TOGGLE_ALT_GUI +#define CG_SWAP MAGIC_SWAP_CTL_GUI +#define CG_NORM MAGIC_UNSWAP_CTL_GUI +#define CG_TOGG MAGIC_TOGGLE_CTL_GUI + // GOTO layer - 16 layers max // when: // ON_PRESS = 1 diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c index d3884d9fa97..949615ecf91 100644 --- a/tmk_core/common/command.c +++ b/tmk_core/common/command.c @@ -286,6 +286,8 @@ static void print_eeconfig(void) print("keymap_config.raw: "); print_hex8(kc.raw); print("\n"); print(".swap_control_capslock: "); print_dec(kc.swap_control_capslock); print("\n"); print(".capslock_to_control: "); print_dec(kc.capslock_to_control); print("\n"); + print(".swap_lctl_lgui: "); print_dec(kc.swap_lctl_lgui); print("\n"); + print(".swap_rctl_rgui: "); print_dec(kc.swap_rctl_rgui); print("\n"); print(".swap_lalt_lgui: "); print_dec(kc.swap_lalt_lgui); print("\n"); print(".swap_ralt_rgui: "); print_dec(kc.swap_ralt_rgui); print("\n"); print(".no_gui: "); print_dec(kc.no_gui); print("\n"); diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c index 4f440abc9c2..28f5d3ad5e9 100644 --- a/tmk_core/common/eeconfig.c +++ b/tmk_core/common/eeconfig.c @@ -39,7 +39,8 @@ void eeconfig_init_quantum(void) { eeprom_update_byte(EECONFIG_DEBUG, 0); eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); default_layer_state = 0; - eeprom_update_byte(EECONFIG_KEYMAP, 0); + eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0); + eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0); eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0); eeprom_update_byte(EECONFIG_BACKLIGHT, 0); eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default @@ -127,12 +128,17 @@ void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DE * * FIXME: needs doc */ -uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMAP); } +uint16_t eeconfig_read_keymap(void) { + return ( eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8) ); +} /** \brief eeconfig update keymap * * FIXME: needs doc */ -void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); } +void eeconfig_update_keymap(uint16_t val) { + eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, val & 0xFF); + eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, ( val >> 8 ) & 0xFF ); +} /** \brief eeconfig read backlight * diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h index 3100041b4e9..0d5c6a82fc4 100644 --- a/tmk_core/common/eeconfig.h +++ b/tmk_core/common/eeconfig.h @@ -45,7 +45,8 @@ along with this program. If not, see . #define EECONFIG_HAPTIC (uint32_t *)24 #define EECONFIG_RGB_MATRIX (uint32_t *)28 #define EECONFIG_RGB_MATRIX_SPEED (uint8_t *)32 - +// TODO: Combine these into a single word and single block of EEPROM +#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)33 /* debug bit */ #define EECONFIG_DEBUG_ENABLE (1<<0) #define EECONFIG_DEBUG_MATRIX (1<<1) @@ -62,6 +63,7 @@ along with this program. If not, see . #define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1<<6) #define EECONFIG_KEYMAP_NKRO (1<<7) +#define EECONFIG_KEYMAP_LOWER_BYTE EECONFIG_KEYMAP bool eeconfig_is_enabled(void); bool eeconfig_is_disabled(void); @@ -81,8 +83,8 @@ void eeconfig_update_debug(uint8_t val); uint8_t eeconfig_read_default_layer(void); void eeconfig_update_default_layer(uint8_t val); -uint8_t eeconfig_read_keymap(void); -void eeconfig_update_keymap(uint8_t val); +uint16_t eeconfig_read_keymap(void); +void eeconfig_update_keymap(uint16_t val); #ifdef BACKLIGHT_ENABLE uint8_t eeconfig_read_backlight(void); From b62e160a8950f451b08f1fee0109e60a58c5ddaa Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Wed, 21 Aug 2019 17:07:49 -0700 Subject: [PATCH 49/61] Additional changes for Layer State typedef compatibility (#5906) * Additional changes for Layer State typedef compatibility * Replace biton32 with get_highest_layer in docs * Change additional layer structure code * Fix uGFX reference issue * Remove dynamic_keymap check * Where did all these extra spaces come from Co-Authored-By: fauxpark --- docs/custom_quantum_functions.md | 12 ++++++------ docs/feature_oled_driver.md | 2 +- docs/feature_userspace.md | 4 ++-- docs/ref_functions.md | 4 ++-- quantum/quantum.c | 6 +++--- quantum/quantum.h | 2 +- quantum/visualizer/visualizer.c | 4 ++-- quantum/visualizer/visualizer.h | 7 ++++--- tmk_core/common/action_layer.h | 5 ++++- 9 files changed, 25 insertions(+), 21 deletions(-) diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index 7be82c650f7..839d49ca056 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md @@ -297,8 +297,8 @@ This runs code every time that the layers get changed. This can be useful for l This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example ```c -uint32_t layer_state_set_user(uint32_t state) { - switch (biton32(state)) { +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { case _RAISE: rgblight_setrgb (0x00, 0x00, 0xFF); break; @@ -320,8 +320,8 @@ uint32_t layer_state_set_user(uint32_t state) { ``` ### `layer_state_set_*` Function Documentation -* Keyboard/Revision: `uint32_t layer_state_set_kb(uint32_t state)` -* Keymap: `uint32_t layer_state_set_user(uint32_t state)` +* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)` +* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)` The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status) @@ -377,8 +377,8 @@ void keyboard_post_init_user(void) { The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above. ```c -uint32_t layer_state_set_user(uint32_t state) { - switch (biton32(state)) { +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { case _RAISE: if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } break; diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index 503e4382885..9d19beedb2b 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -31,7 +31,7 @@ This enables the feature and the `OLED_DRIVER_ENABLE` define. Then in your `keym void oled_task_user(void) { // Host Keyboard Layer Status oled_write_P(PSTR("Layer: "), false); - switch (biton32(layer_state)) { + switch (get_highest_layer(layer_state)) { case _QWERTY: oled_write_P(PSTR("Default\n"), false); break; diff --git a/docs/feature_userspace.md b/docs/feature_userspace.md index 2f119c8bde5..1cc8ca7425c 100644 --- a/docs/feature_userspace.md +++ b/docs/feature_userspace.md @@ -115,11 +115,11 @@ For instance, let's look at the `layer_state_set_user()` function. You can enab In your `` file, you'd want to add this: ```c __attribute__ ((weak)) -uint32_t layer_state_set_keymap (uint32_t state) { +layer_state_t layer_state_set_keymap (layer_state_t state) { return state; } -uint32_t layer_state_set_user (uint32_t state) { +layer_state_t layer_state_set_user (layer_state_t state) { state = update_tri_layer_state(state, 2, 3, 5); return layer_state_set_keymap (state); } diff --git a/docs/ref_functions.md b/docs/ref_functions.md index 174d9a95a6f..1ac83cec42f 100644 --- a/docs/ref_functions.md +++ b/docs/ref_functions.md @@ -50,7 +50,7 @@ The caveat to this method is that you cannot access the `z` layer without having #### Example ```c -uint32_t layer_state_set_user(uint32_t state) { +layer_state_t layer_state_set_user(layer_state_t state) { return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); } ``` @@ -58,7 +58,7 @@ uint32_t layer_state_set_user(uint32_t state) { Alternatively, you don't have to immediately "return" the value. This is useful if you want to add multiple tri layers, or if you want to add additional effects. ```c -uint32_t layer_state_set_user(uint32_t state) { +layer_state_t layer_state_set_user(layer_state_t state) { state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL); return state; diff --git a/quantum/quantum.c b/quantum/quantum.c index f489c90310e..665d6fdd916 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -931,9 +931,9 @@ void set_single_persistent_default_layer(uint8_t default_layer) { default_layer_set(1U<. #include "keyboard.h" #include "action.h" -#if defined(LAYER_STATE_8BIT) || ( defined(DYNAMIC_KEYMAP_ENABLE) && DYNAMIC_KEYMAP_LAYER_COUNT >= 8 ) +#if defined(LAYER_STATE_8BIT) typedef uint8_t layer_state_t; +#define get_highest_layer(state) biton8(state) #elif defined(LAYER_STATE_16BIT) typedef uint16_t layer_state_t; +#define get_highest_layer(state) biton16(state) #else typedef uint32_t layer_state_t; +#define get_highest_layer(state) biton32(state) #endif From 1c5b0cbbeb049b1ce3fb2da6a81fbf83dd9a3ea7 Mon Sep 17 00:00:00 2001 From: Takeshi ISHII <2170248+mtei@users.noreply.github.com> Date: Thu, 22 Aug 2019 09:10:47 +0900 Subject: [PATCH 50/61] AVR GPIO macro defines more readable (#5937) * A little easier to read the definition of the GPIO control macro for AVR. No change in build result. * Changed to not use GNU statement expression extension. No change in build result. * Modified split_common/serial.c to use qmk_firmware standard GPIO control macro. No change in build result. * fix PE6 -> E6 * remove some space * add some comment to config_common.h * Changed split_common/serial.c to use a newer version of qmk_firmware standard GPIO control macro. --- quantum/config_common.h | 10 ++++++++++ quantum/quantum.h | 15 +++++++-------- quantum/split_common/serial.c | 31 +++++++++++++------------------ 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/quantum/config_common.h b/quantum/config_common.h index bc4d9ec1af1..ae72701da1d 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -132,6 +132,16 @@ #define F7 PINDEF(F, 7) #endif + #ifndef __ASSEMBLER__ + #define _PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + (p >> PORT_SHIFTER) + offset) + // Port X Input Pins Address + #define PINx_ADDRESS(p) _PIN_ADDRESS(p, 0) + // Port X Data Direction Register, 0:input 1:output + #define DDRx_ADDRESS(p) _PIN_ADDRESS(p, 1) + // Port X Data Register + #define PORTx_ADDRESS(p) _PIN_ADDRESS(p, 2) + #endif + #elif defined(PROTOCOL_CHIBIOS) // Defines mapping for Proton C replacement #ifdef CONVERT_TO_PROTON_C diff --git a/quantum/quantum.h b/quantum/quantum.h index 2214625670c..2cb26d4f461 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -149,18 +149,17 @@ extern layer_state_t default_layer_state; #if defined(__AVR__) typedef uint8_t pin_t; - #define PIN_ADDRESS(p, offset) (_SFR_IO8(ADDRESS_BASE + ((p) >> PORT_SHIFTER) + (offset))) - #define setPinInput(pin) (PIN_ADDRESS(pin, 1) &= ~_BV((pin) & 0xF)) - #define setPinInputHigh(pin) (PIN_ADDRESS(pin, 1) &= ~_BV((pin) & 0xF), \ - PIN_ADDRESS(pin, 2) |= _BV((pin) & 0xF)) + #define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin) & 0xF)) + #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin) & 0xF), \ + PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) #define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") - #define setPinOutput(pin) (PIN_ADDRESS(pin, 1) |= _BV((pin) & 0xF)) + #define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin) & 0xF)) - #define writePinHigh(pin) (PIN_ADDRESS(pin, 2) |= _BV((pin) & 0xF)) - #define writePinLow(pin) (PIN_ADDRESS(pin, 2) &= ~_BV((pin) & 0xF)) + #define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) + #define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin) & 0xF)) #define writePin(pin, level) ((level) ? writePinHigh(pin) : writePinLow(pin)) - #define readPin(pin) ((bool)(PIN_ADDRESS(pin, 0) & _BV((pin) & 0xF))) + #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin) & 0xF))) #elif defined(PROTOCOL_CHIBIOS) typedef ioline_t pin_t; diff --git a/quantum/split_common/serial.c b/quantum/split_common/serial.c index 1315377a345..322ab8030bd 100644 --- a/quantum/split_common/serial.c +++ b/quantum/split_common/serial.c @@ -29,36 +29,32 @@ #endif #endif + #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin) & 0xF), \ + PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) + #define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin) & 0xF)) + #define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) + #define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin) & 0xF)) + #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin) & 0xF))) + #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3 - #define SERIAL_PIN_DDR DDRD - #define SERIAL_PIN_PORT PORTD - #define SERIAL_PIN_INPUT PIND #if SOFT_SERIAL_PIN == D0 - #define SERIAL_PIN_MASK _BV(PD0) #define EIMSK_BIT _BV(INT0) #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) #define SERIAL_PIN_INTERRUPT INT0_vect #elif SOFT_SERIAL_PIN == D1 - #define SERIAL_PIN_MASK _BV(PD1) #define EIMSK_BIT _BV(INT1) #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) #define SERIAL_PIN_INTERRUPT INT1_vect #elif SOFT_SERIAL_PIN == D2 - #define SERIAL_PIN_MASK _BV(PD2) #define EIMSK_BIT _BV(INT2) #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) #define SERIAL_PIN_INTERRUPT INT2_vect #elif SOFT_SERIAL_PIN == D3 - #define SERIAL_PIN_MASK _BV(PD3) #define EIMSK_BIT _BV(INT3) #define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) #define SERIAL_PIN_INTERRUPT INT3_vect #endif #elif SOFT_SERIAL_PIN == E6 - #define SERIAL_PIN_DDR DDRE - #define SERIAL_PIN_PORT PORTE - #define SERIAL_PIN_INPUT PINE - #define SERIAL_PIN_MASK _BV(PE6) #define EIMSK_BIT _BV(INT6) #define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) #define SERIAL_PIN_INTERRUPT INT6_vect @@ -200,33 +196,32 @@ void serial_delay_half2(void) { inline static void serial_output(void) ALWAYS_INLINE; inline static void serial_output(void) { - SERIAL_PIN_DDR |= SERIAL_PIN_MASK; + setPinOutput(SOFT_SERIAL_PIN); } // make the serial pin an input with pull-up resistor inline static void serial_input_with_pullup(void) ALWAYS_INLINE; inline static void serial_input_with_pullup(void) { - SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; - SERIAL_PIN_PORT |= SERIAL_PIN_MASK; + setPinInputHigh(SOFT_SERIAL_PIN); } inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; inline static uint8_t serial_read_pin(void) { - return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); + return !! readPin(SOFT_SERIAL_PIN); } inline static void serial_low(void) ALWAYS_INLINE; inline static void serial_low(void) { - SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; + writePinLow(SOFT_SERIAL_PIN); } inline static void serial_high(void) ALWAYS_INLINE; inline static void serial_high(void) { - SERIAL_PIN_PORT |= SERIAL_PIN_MASK; + writePinHigh(SOFT_SERIAL_PIN); } void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) @@ -245,7 +240,7 @@ void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) // Enable INT0-INT3,INT6 EIMSK |= EIMSK_BIT; -#if SERIAL_PIN_MASK == _BV(PE6) +#if SOFT_SERIAL_PIN == E6 // Trigger on falling edge of INT6 EICRB &= EICRx_BIT; #else From 94efa18c28c8c0e08526c9665a8f0d6a4e7d3e96 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Wed, 21 Aug 2019 17:19:07 -0700 Subject: [PATCH 51/61] [Keyboard] Updates to ZSA boards (#6513) * Update Layer functions to use layer_state_t in ZSA Boards * Update Music Mask for ZSA boards Fixes an issue with the board getting stuck on Adjust layer when activating music mode * Add Support for SMART LED Toggle to Planck EZ * Add support for SMART LED toggle in Ergodox EZ * Ifdef swiss cheeze for Oryx Configurator * Documentation and updates * Add Oryx Keymap * Add option to configure the layers for the Layer Indicator * Update keymap with better examples * Make sure eeprom is initialized before reading from it * Force flush of LED matrix when suspending board This fixes an issue where the LEDs don't fully clear sometimes when the host system goes to sleep * Enable RGB Sleeping by default * Add clarification about planck ez led layer config --- keyboards/ergodox_ez/config.h | 4 + keyboards/ergodox_ez/ergodox_ez.c | 74 ++++ keyboards/ergodox_ez/ergodox_ez.h | 19 + keyboards/ergodox_ez/keymaps/default/keymap.c | 6 +- keyboards/planck/ez/config.h | 1 + keyboards/planck/ez/ez.c | 94 ++++- keyboards/planck/ez/ez.h | 5 +- keyboards/planck/ez/readme.md | 41 ++ keyboards/planck/keymaps/default/keymap.c | 2 +- keyboards/planck/keymaps/oryx/config.h | 16 + keyboards/planck/keymaps/oryx/keymap.c | 372 ++++++++++++++++++ keyboards/planck/keymaps/oryx/rules.mk | 6 + 12 files changed, 629 insertions(+), 11 deletions(-) create mode 100644 keyboards/planck/keymaps/oryx/config.h create mode 100644 keyboards/planck/keymaps/oryx/keymap.c create mode 100644 keyboards/planck/keymaps/oryx/rules.mk diff --git a/keyboards/ergodox_ez/config.h b/keyboards/ergodox_ez/config.h index 45ca06a5d22..c35fe73941f 100644 --- a/keyboards/ergodox_ez/config.h +++ b/keyboards/ergodox_ez/config.h @@ -85,6 +85,8 @@ along with this program. If not, see . #define RGBW 1 +#define RGBLIGHT_SLEEP + /* * The debounce filtering reports a key/switch change directly, * without any extra delay. After that the debounce logic will filter @@ -112,6 +114,8 @@ along with this program. If not, see . #define RGB_MATRIX_LED_PROCESS_LIMIT 5 #define RGB_MATRIX_LED_FLUSH_LIMIT 26 +#define RGB_DISABLE_WHEN_USB_SUSPENDED true + // #define RGBLIGHT_COLOR_LAYER_0 0x00, 0x00, 0xFF /* #define RGBLIGHT_COLOR_LAYER_1 0x00, 0x00, 0xFF */ /* #define RGBLIGHT_COLOR_LAYER_2 0xFF, 0x00, 0x00 */ diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c index 947a173e369..d313f7d5d99 100644 --- a/keyboards/ergodox_ez/ergodox_ez.c +++ b/keyboards/ergodox_ez/ergodox_ez.c @@ -22,6 +22,8 @@ extern inline void ergodox_right_led_set(uint8_t led, uint8_t n); extern inline void ergodox_led_all_set(uint8_t n); +keyboard_config_t keyboard_config; + bool i2c_initialized = 0; i2c_status_t mcp23018_status = 0x20; @@ -43,6 +45,16 @@ void matrix_init_kb(void) { PORTD |= (1<<5 | 1<<4); PORTE |= (1<<6); + keyboard_config.raw = eeconfig_read_kb(); + ergodox_led_all_set((uint8_t)keyboard_config.led_level * 255 / 4 ); +#ifdef RGB_MATRIX_ENABLE + if (keyboard_config.rgb_matrix_enable) { + rgb_matrix_set_flags(LED_FLAG_ALL); + } else { + rgb_matrix_set_flags(LED_FLAG_NONE); + } +#endif + ergodox_blink_all_leds(); matrix_init_user(); @@ -305,6 +317,7 @@ led_config_t g_led_config = { { } }; void suspend_power_down_kb(void) { + rgb_matrix_set_color_all(0, 0, 0); rgb_matrix_set_suspend_state(true); suspend_power_down_user(); } @@ -314,4 +327,65 @@ void suspend_power_down_kb(void) { suspend_wakeup_init_user(); } +#ifdef ORYX_CONFIGURATOR +void keyboard_post_init_kb(void) { + rgb_matrix_enable_noeeprom(); + keyboard_post_init_user(); +} #endif +#endif + +#ifdef ORYX_CONFIGURATOR +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LED_LEVEL: + if (record->event.pressed) { + keyboard_config.led_level++; + if (keyboard_config.led_level > 4) { + keyboard_config.led_level = 0; + } + ergodox_led_all_set((uint8_t)keyboard_config.led_level * 255 / 4 ); + eeconfig_update_kb(keyboard_config.raw); + layer_state_set_kb(layer_state); + } + break; +#ifdef RGB_MATRIX_ENABLE + case TOGGLE_LAYER_COLOR: + if (record->event.pressed) { + keyboard_config.disable_layer_led ^= 1; + if (keyboard_config.disable_layer_led) + rgb_matrix_set_color_all(0, 0, 0); + eeconfig_update_kb(keyboard_config.raw); + } + break; + case RGB_TOG: + if (record->event.pressed) { + switch (rgb_matrix_get_flags()) { + case LED_FLAG_ALL: { + rgb_matrix_set_flags(LED_FLAG_NONE); + keyboard_config.rgb_matrix_enable = false; + rgb_matrix_set_color_all(0, 0, 0); + } + break; + default: { + rgb_matrix_set_flags(LED_FLAG_ALL); + keyboard_config.rgb_matrix_enable = true; + } + break; + } + eeconfig_update_kb(keyboard_config.raw); + } + return false; +#endif + } + return process_record_user(keycode, record); +} +#endif + +void eeconfig_init_kb(void) { // EEPROM is getting reset! + keyboard_config.raw = 0; + keyboard_config.led_level = 4; + keyboard_config.rgb_matrix_enable = true; + eeconfig_update_kb(keyboard_config.raw); + eeconfig_init_user(); +} diff --git a/keyboards/ergodox_ez/ergodox_ez.h b/keyboards/ergodox_ez/ergodox_ez.h index 383702b9578..7ff62d38a16 100644 --- a/keyboards/ergodox_ez/ergodox_ez.h +++ b/keyboards/ergodox_ez/ergodox_ez.h @@ -107,6 +107,25 @@ inline void ergodox_led_all_set(uint8_t n) ergodox_right_led_3_set(n); } +#ifdef ORYX_CONFIGURATOR +enum ergodox_ez_keycodes { + LED_LEVEL = SAFE_RANGE, + TOGGLE_LAYER_COLOR, + EZ_SAFE_RANGE, +}; +#endif + +typedef union { + uint32_t raw; + struct { + uint8_t led_level :3; + bool disable_layer_led :1; + bool rgb_matrix_enable :1; + }; +} keyboard_config_t; + +extern keyboard_config_t keyboard_config; + /* * LEFT HAND: LINES 115-122 * RIGHT HAND: LINES 124-131 diff --git a/keyboards/ergodox_ez/keymaps/default/keymap.c b/keyboards/ergodox_ez/keymaps/default/keymap.c index 40d0a1eaf03..fb3d3896bf4 100644 --- a/keyboards/ergodox_ez/keymaps/default/keymap.c +++ b/keyboards/ergodox_ez/keymaps/default/keymap.c @@ -6,7 +6,11 @@ #define MDIA 2 // media keys enum custom_keycodes { +#ifdef ORYX_CONFIGURATOR + EPRM = EZ_SAFE_RANGE, +#else EPRM = SAFE_RANGE, +#endif VRSN, RGB_SLD }; @@ -164,7 +168,7 @@ void matrix_init_user(void) { }; // Runs whenever there is a layer state change. -uint32_t layer_state_set_user(uint32_t state) { +layer_state_t layer_state_set_user(layer_state_t state) { ergodox_board_led_off(); ergodox_right_led_1_off(); ergodox_right_led_2_off(); diff --git a/keyboards/planck/ez/config.h b/keyboards/planck/ez/config.h index 61d9981c181..0cb428dd858 100644 --- a/keyboards/planck/ez/config.h +++ b/keyboards/planck/ez/config.h @@ -139,6 +139,7 @@ #define RGB_MATRIX_KEYPRESSES #define RGB_MATRIX_FRAMEBUFFER_EFFECTS +#define RGB_DISABLE_WHEN_USB_SUSPENDED true #define RGB_MATRIX_LED_PROCESS_LIMIT 5 #define RGB_MATRIX_LED_FLUSH_LIMIT 26 diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c index 8734042a429..8369ce50c10 100644 --- a/keyboards/planck/ez/ez.c +++ b/keyboards/planck/ez/ez.c @@ -16,8 +16,8 @@ #include "ez.h" #include "ch.h" #include "hal.h" - keyboard_config_t keyboard_config; +keyboard_config_t keyboard_config; #ifdef RGB_MATRIX_ENABLE const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { @@ -106,6 +106,7 @@ led_config_t g_led_config = { { } }; void suspend_power_down_kb(void) { + rgb_matrix_set_color_all(0, 0, 0); rgb_matrix_set_suspend_state(true); suspend_power_down_user(); } @@ -207,33 +208,65 @@ void led_initialize_hardware(void) { } void keyboard_pre_init_kb(void) { + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } // read kb settings from eeprom keyboard_config.raw = eeconfig_read_kb(); - - // initialize settings for front LEDs +#if defined(RGB_MATRIX_ENABLE) && defined(ORYX_CONFIGURATOR) + if (keyboard_config.rgb_matrix_enable) { + rgb_matrix_set_flags(LED_FLAG_ALL); + } else { + rgb_matrix_set_flags(LED_FLAG_NONE); + } +#endif led_initialize_hardware(); + keyboard_pre_init_user(); } +#if defined(RGB_MATRIX_ENABLE) && defined(ORYX_CONFIGURATOR) +void keyboard_post_init_kb(void) { + rgb_matrix_enable_noeeprom(); + keyboard_post_init_user(); +} +#endif + void eeconfig_init_kb(void) { // EEPROM is getting reset! keyboard_config.raw = 0; + keyboard_config.rgb_matrix_enable = true; keyboard_config.led_level = 4; eeconfig_update_kb(keyboard_config.raw); eeconfig_init_user(); } + +#ifdef ORYX_CONFIGURATOR + +#ifndef PLANCK_EZ_USER_LEDS + +#ifndef PLANCK_EZ_LED_LOWER +# define PLANCK_EZ_LED_LOWER 3 +#endif +#ifndef PLANCK_EZ_LED_RAISE +# define PLANCK_EZ_LED_RAISE 4 +#endif +#ifndef PLANCK_EZ_LED_ADJUST +# define PLANCK_EZ_LED_ADJUST 6 +#endif + layer_state_t layer_state_set_kb(layer_state_t state) { planck_ez_left_led_off(); planck_ez_right_led_off(); state = layer_state_set_user(state); uint8_t layer = biton32(state); switch (layer) { - case 3: + case PLANCK_EZ_LED_LOWER: planck_ez_left_led_on(); break; - case 4: + case PLANCK_EZ_LED_RAISE: planck_ez_right_led_on(); break; - case 6: + case PLANCK_EZ_LED_ADJUST: planck_ez_right_led_on(); planck_ez_left_led_on(); break; @@ -242,7 +275,7 @@ layer_state_t layer_state_set_kb(layer_state_t state) { } return state; } - +#endif bool process_record_kb(uint16_t keycode, keyrecord_t *record) { switch (keycode) { @@ -258,6 +291,51 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { layer_state_set_kb(layer_state); } break; +#ifdef RGB_MATRIX_ENABLE + case TOGGLE_LAYER_COLOR: + if (record->event.pressed) { + keyboard_config.disable_layer_led ^= 1; + if (keyboard_config.disable_layer_led) + rgb_matrix_set_color_all(0, 0, 0); + eeconfig_update_kb(keyboard_config.raw); + } + break; + case RGB_TOG: + if (record->event.pressed) { + switch (rgb_matrix_get_flags()) { + case LED_FLAG_ALL: { + rgb_matrix_set_flags(LED_FLAG_NONE); + keyboard_config.rgb_matrix_enable = false; + rgb_matrix_set_color_all(0, 0, 0); + } + break; + default: { + rgb_matrix_set_flags(LED_FLAG_ALL); + keyboard_config.rgb_matrix_enable = true; + } + break; + } + eeconfig_update_kb(keyboard_config.raw); + } + return false; +#endif } - return true; + return process_record_user(keycode, record); } +#endif + +#ifdef AUDIO_ENABLE +bool music_mask_kb(uint16_t keycode) { + switch (keycode) { + case QK_LAYER_TAP ... QK_ONE_SHOT_LAYER_MAX: + case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX: + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + case AU_ON ... MUV_DE: + case RESET: + case EEP_RST: + return false; + default: + return music_mask_user(keycode); + } +} +#endif diff --git a/keyboards/planck/ez/ez.h b/keyboards/planck/ez/ez.h index e2ddaf3cecb..29bcc1b83c3 100644 --- a/keyboards/planck/ez/ez.h +++ b/keyboards/planck/ez/ez.h @@ -60,13 +60,16 @@ void planck_ez_left_led_level(uint8_t level); enum planck_ez_keycodes { LED_LEVEL = SAFE_RANGE, + TOGGLE_LAYER_COLOR, EZ_SAFE_RANGE, }; typedef union { uint32_t raw; struct { - uint8_t led_level :3; + uint8_t led_level :3; + bool disable_layer_led :1; + bool rgb_matrix_enable :1; }; } keyboard_config_t; diff --git a/keyboards/planck/ez/readme.md b/keyboards/planck/ez/readme.md index 9bd161abdfe..df8d1b46bb9 100644 --- a/keyboards/planck/ez/readme.md +++ b/keyboards/planck/ez/readme.md @@ -13,3 +13,44 @@ Make example for this keyboard (after setting up your build environment): make planck/ez: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). + +## Planck EZ Configuration (from Oryx) + +### Indicator LEDs + +The two front "teeth" LED indicators are PWM controlled. If you have `ORYX_CONFIGURATOR` defined in your keymap's `config.h`, you can use the `LED_LEVEL` to cycle through preset vales (0, 25%, 50%, 75%, 100%), and will be saved to EEPROM (persistent storage) + +Alternatively, you can set the brightness by calling the following functions: + +```c +void planck_ez_right_led_level(uint8_t level); +void planck_ez_left_led_level(uint8_t level); +``` + +These settings are not persistent, so you'd need to reset it every time the board starts. + +These are on a 0-255 scale + +#### Layer indication + +By default, the indicator lights are used for layer indication, expecting the specific layers used in the default keymap. However, this may not work for you. And if that is the case, you can add `#define PLANCK_EZ_USER_LEDS` to your `config.h` file. + +This will remove the default behavior for changing the LEDs based on layer, and allow you to control them manually. + +Alternatively, you can use the following defines in your keymap's `config.h` to control which layers are used, as long as you have `ORYX_CONFIGURATOR` defined in your keymap's `config.h` file, as well. + +```c +#define PLANCK_EZ_LED_LOWER 3 +#define PLANCK_EZ_LED_RAISE 4 +#define PLANCK_EZ_LED_ADJUST 6 +``` + +This will allow you to change the layers that are used, without having to add anything code to your `keymap.c` + +### RGB Matrix Features + +If you're using the Smart LED (layer indication) feature from the Oryx Configurator, you want to make sure that you enable these options by adding `#define ORYX_CONFIGURATOR` to your keymap's `config.h`. + +This changes the `RGB_TOG` keycode so that it will toggle the lights on and off, in a way that will allow the Smart LEDs to continue to work, even with the rest of the LEDs turned off. + +Additionally, a new keycode has been added to toggle the Smart LEDs. Use `TOGGLE_LAYER_COLOR`, if you aren't already. diff --git a/keyboards/planck/keymaps/default/keymap.c b/keyboards/planck/keymaps/default/keymap.c index 588ee646e18..90197719878 100644 --- a/keyboards/planck/keymaps/default/keymap.c +++ b/keyboards/planck/keymaps/default/keymap.c @@ -177,7 +177,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); #endif -uint32_t layer_state_set_user(uint32_t state) { +layer_state_t layer_state_set_user(layer_state_t state) { return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); } diff --git a/keyboards/planck/keymaps/oryx/config.h b/keyboards/planck/keymaps/oryx/config.h new file mode 100644 index 00000000000..a9171bf538e --- /dev/null +++ b/keyboards/planck/keymaps/oryx/config.h @@ -0,0 +1,16 @@ +#pragma once + +#ifdef AUDIO_ENABLE +#define STARTUP_SONG SONG(PLANCK_SOUND) +#endif + +#define MIDI_BASIC + +#define ENCODER_RESOLUTION 4 + +#define ORYX_CONFIGURATOR + +/* + Set any config.h overrides for your specific keymap here. + See config.h options at https://docs.qmk.fm/#/config_options?id=the-configh-file +*/ diff --git a/keyboards/planck/keymaps/oryx/keymap.c b/keyboards/planck/keymaps/oryx/keymap.c new file mode 100644 index 00000000000..7892d1a5fb3 --- /dev/null +++ b/keyboards/planck/keymaps/oryx/keymap.c @@ -0,0 +1,372 @@ +#include QMK_KEYBOARD_H +#include "muse.h" +#include "eeprom.h" +#include "keymap_german.h" +#include "keymap_nordic.h" +#include "keymap_french.h" +#include "keymap_spanish.h" +#include "keymap_hungarian.h" +#include "keymap_swedish.h" +//#include "keymap_br_abnt2.h" +#include "keymap_canadian_multilingual.h" +#include "keymap_german_ch.h" + +#define KC_MAC_UNDO LGUI(KC_Z) +#define KC_MAC_CUT LGUI(KC_X) +#define KC_MAC_COPY LGUI(KC_C) +#define KC_MAC_PASTE LGUI(KC_V) +#define KC_PC_UNDO LCTL(KC_Z) +#define KC_PC_CUT LCTL(KC_X) +#define KC_PC_COPY LCTL(KC_C) +#define KC_PC_PASTE LCTL(KC_V) +#define NO_TH ALGR(KC_T) +#define NO_ETH ALGR(KC_D) + +enum planck_layers { + _QWERTY, + _COLEMAK, + _DVORAK, + _LOWER, + _RAISE, + _PLOVER, + _ADJUST +}; + +enum planck_keycodes { + QWERTY = EZ_SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + BACKLIT, + EXT_PLV, + RGB_SLD +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = LAYOUT_planck_grid( + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, + KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT_planck_grid( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT_planck_grid( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ +[_PLOVER] = LAYOUT_planck_grid( + KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 , + XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, + XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX +), + +/* Adjust (Lower + Raise) + * v------------------------RGB CONTROL--------------------v + * ,----------------------------------------------------------------------------------- + * | | Reset|Debug | RGB |RGBMOD| HUE+ | HUE- | SAT+ | SAT- |BRGTH+|BRGTH-| Del | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT_planck_grid( + _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______, + _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, TOGGLE_LAYER_COLOR, LED_LEVEL, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ +) + +}; + + +#ifdef AUDIO_ENABLE + float plover_song[][2] = SONG(PLOVER_SOUND); + float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); +#endif + +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +const uint8_t PROGMEM ledmap[][DRIVER_LED_TOTAL][3] = { + [0] = { {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255}, {130,255,255} }, + + [1] = { {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {146,224,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {42,255,255}, {32,255,234}, {32,255,234}, {32,255,234}, {32,255,234} }, + + [2] = { {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {169,120,255}, {169,120,255}, {169,120,255}, {169,120,255}, {169,120,255}, {169,120,255}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {169,120,255}, {169,120,255}, {169,120,255}, {169,120,255}, {169,120,255}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246}, {89,255,246} }, + + [3] = { {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {249,228,255}, {249,228,255}, {249,228,255}, {216,255,255}, {216,255,255}, {105,255,255}, {105,255,255}, {105,255,255}, {216,255,255}, {14,255,255}, {216,255,255}, {216,255,255}, {249,228,255}, {249,228,255}, {249,228,255}, {216,255,255}, {216,255,255}, {105,255,255}, {105,255,255}, {105,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255}, {216,255,255} }, + +}; + +void set_layer_color(int layer) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + HSV hsv = { + .h = pgm_read_byte(&ledmap[layer][i][0]), + .s = pgm_read_byte(&ledmap[layer][i][1]), + .v = pgm_read_byte(&ledmap[layer][i][2]), + }; + if (!hsv.h && !hsv.s && !hsv.v) { + rgb_matrix_set_color( i, 0, 0, 0 ); + } else { + RGB rgb = hsv_to_rgb( hsv ); + float f = (float)rgb_matrix_config.hsv.v / UINT8_MAX; + rgb_matrix_set_color( i, f * rgb.r, f * rgb.g, f * rgb.b ); + } + } +} + +void rgb_matrix_indicators_user(void) { + if (g_suspend_state || keyboard_config.disable_layer_led) { return; } + switch (biton32(layer_state)) { + case 0: + set_layer_color(0); + break; + case 3: + set_layer_color(1); + break; + case 4: + set_layer_color(2); + break; + case 6: + set_layer_color(3); + break; + default: + if (rgb_matrix_get_flags() == LED_FLAG_NONE) + rgb_matrix_set_color_all(0, 0, 0); + break; + } +} + + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case RGB_SLD: + if (record->event.pressed) { + rgblight_mode(1); + } + return false; + case QWERTY: + if (record->event.pressed) { + print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_DVORAK); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + #ifdef KEYBOARD_planck_rev5 + PORTE &= ~(1<<6); + #endif + } else { + unregister_code(KC_RSFT); + #ifdef KEYBOARD_planck_rev5 + PORTE |= (1<<6); + #endif + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_SONG(plover_song); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} + +bool muse_mode = false; +uint8_t last_muse_note = 0; +uint16_t muse_counter = 0; +uint8_t muse_offset = 70; +uint16_t muse_tempo = 50; + +void encoder_update(bool clockwise) { + if (muse_mode) { + if (IS_LAYER_ON(_RAISE)) { + if (clockwise) { + muse_offset++; + } else { + muse_offset--; + } + } else { + if (clockwise) { + muse_tempo+=1; + } else { + muse_tempo-=1; + } + } + } else { + if (clockwise) { + #ifdef MOUSEKEY_ENABLE + register_code(KC_MS_WH_DOWN); + unregister_code(KC_MS_WH_DOWN); + #else + register_code(KC_PGDN); + unregister_code(KC_PGDN); + #endif + } else { + #ifdef MOUSEKEY_ENABLE + register_code(KC_MS_WH_UP); + unregister_code(KC_MS_WH_UP); + #else + register_code(KC_PGUP); + unregister_code(KC_PGUP); + #endif + } + } +} + +void matrix_scan_user(void) { +#ifdef AUDIO_ENABLE + if (muse_mode) { + if (muse_counter == 0) { + uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()]; + if (muse_note != last_muse_note) { + stop_note(compute_freq_for_midi_note(last_muse_note)); + play_note(compute_freq_for_midi_note(muse_note), 0xF); + last_muse_note = muse_note; + } + } + muse_counter = (muse_counter + 1) % muse_tempo; + } +#endif +} diff --git a/keyboards/planck/keymaps/oryx/rules.mk b/keyboards/planck/keymaps/oryx/rules.mk new file mode 100644 index 00000000000..fb44d6b95ea --- /dev/null +++ b/keyboards/planck/keymaps/oryx/rules.mk @@ -0,0 +1,6 @@ +SRC += muse.c +# Set any rules.mk overrides for your specific keymap here. +# See rules at https://docs.qmk.fm/#/config_options?id=the-rulesmk-file +LINK_TIME_OPTIMIZATION_ENABLE = yes +COMMAND_ENABLE = no +MOUSEKEY_ENABLE = no From 63b96c34ce254f552cdb098060a9e7d7705263b2 Mon Sep 17 00:00:00 2001 From: kakunpc <15257475+kakunpc@users.noreply.github.com> Date: Thu, 22 Aug 2019 09:40:37 +0900 Subject: [PATCH 52/61] [Keyboard] new keyboard "angel17" (#6542) * add angel17 keyboard * fix rules.mk * change BOOTLOADER * set LAYOUT_numpad_5x4 * Update keyboards/angel17/rules.mk Co-Authored-By: Drashna Jaelre * fix LAYOUTS = numpad_5x4 * update info.json --- keyboards/angel17/angel17.c | 51 ++++ keyboards/angel17/angel17.h | 40 ++++ keyboards/angel17/config.h | 249 ++++++++++++++++++++ keyboards/angel17/info.json | 34 +++ keyboards/angel17/keymaps/default/config.h | 19 ++ keyboards/angel17/keymaps/default/keymap.c | 42 ++++ keyboards/angel17/keymaps/default/readme.md | 1 + keyboards/angel17/readme.md | 15 ++ keyboards/angel17/rules.mk | 46 ++++ 9 files changed, 497 insertions(+) create mode 100644 keyboards/angel17/angel17.c create mode 100644 keyboards/angel17/angel17.h create mode 100644 keyboards/angel17/config.h create mode 100644 keyboards/angel17/info.json create mode 100644 keyboards/angel17/keymaps/default/config.h create mode 100644 keyboards/angel17/keymaps/default/keymap.c create mode 100644 keyboards/angel17/keymaps/default/readme.md create mode 100644 keyboards/angel17/readme.md create mode 100644 keyboards/angel17/rules.mk diff --git a/keyboards/angel17/angel17.c b/keyboards/angel17/angel17.c new file mode 100644 index 00000000000..80635a30e14 --- /dev/null +++ b/keyboards/angel17/angel17.c @@ -0,0 +1,51 @@ +/* Copyright 2019 kakunpc + * + * 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 . + */ +#include "angel17.h" + +// Optional override functions below. +// You can leave any or all of these undefined. +// These are only required if you want to perform custom actions. + +/* + +void matrix_init_kb(void) { + // put your keyboard start-up code here + // runs once when the firmware starts up + + matrix_init_user(); +} + +void matrix_scan_kb(void) { + // put your looping keyboard code here + // runs every cycle (a lot) + + matrix_scan_user(); +} + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + // put your per-action keyboard code here + // runs for every action, just before processing by the firmware + + return process_record_user(keycode, record); +} + +void led_set_kb(uint8_t usb_led) { + // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here + + led_set_user(usb_led); +} + +*/ diff --git a/keyboards/angel17/angel17.h b/keyboards/angel17/angel17.h new file mode 100644 index 00000000000..5b8600a2063 --- /dev/null +++ b/keyboards/angel17/angel17.h @@ -0,0 +1,40 @@ +/* Copyright 2019 kakunpc + * + * 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 . + */ +#pragma once + +#include "quantum.h" + +/* This 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_numpad_5x4( \ + k00, k01, k02, k03, \ + k10, k11, k12, \ + k20, k21, k22, k13, \ + k30, k31, k32, \ + k40, k41, k33 \ +) \ +{ \ + { k00, k10, k20, k31, k41 }, \ + { k02, k12, k22, k33, KC_NO }, \ + { k01, k11, k21, k32, KC_NO }, \ + { k03, k13, k30, k40, KC_NO }, \ +} diff --git a/keyboards/angel17/config.h b/keyboards/angel17/config.h new file mode 100644 index 00000000000..2bb74acc897 --- /dev/null +++ b/keyboards/angel17/config.h @@ -0,0 +1,249 @@ +/* +Copyright 2019 kakunpc + +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 . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x0000 +#define DEVICE_VER 0x0001 +#define MANUFACTURER kakunpc +#define PRODUCT angel17 +#define DESCRIPTION A custom keyboard + +/* key matrix size */ +#define MATRIX_ROWS 4 +#define MATRIX_COLS 5 + +/* + * 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 { D4, C6, D7, E6 } +#define MATRIX_COL_PINS { F4, F5, F6, F7, B1 } +#define UNUSED_PINS + +/* COL2ROW, ROW2COL*/ +#define DIODE_DIRECTION COL2ROW + +/* + * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. + */ +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 + +// #define BACKLIGHT_PIN B7 +// #define BACKLIGHT_BREATHING +// #define BACKLIGHT_LEVELS 3 + +// #define RGB_DI_PIN E2 +// #ifdef RGB_DI_PIN +// #define RGBLED_NUM 16 +// #define RGBLIGHT_HUE_STEP 8 +// #define RGBLIGHT_SAT_STEP 8 +// #define RGBLIGHT_VAL_STEP 8 +// #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ +// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */ +// /*== all animations enable ==*/ +// #define RGBLIGHT_ANIMATIONS +// /*== or choose animations ==*/ +// #define RGBLIGHT_EFFECT_BREATHING +// #define RGBLIGHT_EFFECT_RAINBOW_MOOD +// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL +// #define RGBLIGHT_EFFECT_SNAKE +// #define RGBLIGHT_EFFECT_KNIGHT +// #define RGBLIGHT_EFFECT_CHRISTMAS +// #define RGBLIGHT_EFFECT_STATIC_GRADIENT +// #define RGBLIGHT_EFFECT_RGB_TEST +// #define RGBLIGHT_EFFECT_ALTERNATING +// /*== customize breathing effect ==*/ +// /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/ +// #define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64 +// /*==== use exp() and sin() ====*/ +// #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7 +// #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 +// #endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is userful for the Windows task manager shortcut (ctrl+shift+esc). + */ +// #define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Magic Key Options + * + * Magic keys are hotkey commands that allow control over firmware functions of + * the keyboard. They are best used in combination with the HID Listen program, + * found here: https://www.pjrc.com/teensy/hid_listen.html + * + * The options below allow the magic key functionality to be changed. This is + * useful if your keyboard/keypad is missing keys and you want magic key support. + * + */ + +/* key combination for magic key command */ +/* defined by default; to change, uncomment and set to the combination you want */ +// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT) + +/* control how magic key switches layers */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false + +/* override magic key keymap */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM +//#define MAGIC_KEY_HELP H +//#define MAGIC_KEY_HELP_ALT SLASH +//#define MAGIC_KEY_DEBUG D +//#define MAGIC_KEY_DEBUG_MATRIX X +//#define MAGIC_KEY_DEBUG_KBD K +//#define MAGIC_KEY_DEBUG_MOUSE M +//#define MAGIC_KEY_VERSION V +//#define MAGIC_KEY_STATUS S +//#define MAGIC_KEY_CONSOLE C +//#define MAGIC_KEY_LAYER0 0 +//#define MAGIC_KEY_LAYER0_ALT GRAVE +//#define MAGIC_KEY_LAYER1 1 +//#define MAGIC_KEY_LAYER2 2 +//#define MAGIC_KEY_LAYER3 3 +//#define MAGIC_KEY_LAYER4 4 +//#define MAGIC_KEY_LAYER5 5 +//#define MAGIC_KEY_LAYER6 6 +//#define MAGIC_KEY_LAYER7 7 +//#define MAGIC_KEY_LAYER8 8 +//#define MAGIC_KEY_LAYER9 9 +//#define MAGIC_KEY_BOOTLOADER B +//#define MAGIC_KEY_BOOTLOADER_ALT ESC +//#define MAGIC_KEY_LOCK CAPS +//#define MAGIC_KEY_EEPROM E +//#define MAGIC_KEY_EEPROM_CLEAR BSPACE +//#define MAGIC_KEY_NKRO N +//#define MAGIC_KEY_SLEEP_LED Z + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ +//#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 1 + +/* + * HD44780 LCD Display Configuration + */ +/* +#define LCD_LINES 2 //< number of visible lines of the display +#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display + +#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode + +#if LCD_IO_MODE +#define LCD_PORT PORTB //< port for the LCD lines +#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0 +#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1 +#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2 +#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3 +#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0 +#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1 +#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2 +#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3 +#define LCD_RS_PORT LCD_PORT //< port for RS line +#define LCD_RS_PIN 3 //< pin for RS line +#define LCD_RW_PORT LCD_PORT //< port for RW line +#define LCD_RW_PIN 2 //< pin for RW line +#define LCD_E_PORT LCD_PORT //< port for Enable line +#define LCD_E_PIN 1 //< pin for Enable line +#endif +*/ + +/* Bootmagic Lite key configuration */ +// #define BOOTMAGIC_LITE_ROW 0 +// #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/keyboards/angel17/info.json b/keyboards/angel17/info.json new file mode 100644 index 00000000000..823235348ab --- /dev/null +++ b/keyboards/angel17/info.json @@ -0,0 +1,34 @@ +{ + "keyboard_name": "angel17", + "url": "https://kakunpc.booth.pm/", + "maintainer": "kakunpc", + "width": 4, + "height": 5, + "layouts": { + "LAYOUT_numpad_5x4": { + "layout": [ + {"label":"Num Lock", "x":0, "y":0}, + {"label":"/", "x":1, "y":0}, + {"label":"*", "x":2, "y":0}, + {"label":"-", "x":3, "y":0}, + + {"label":"7", "x":0, "y":1}, + {"label":"8", "x":1, "y":1}, + {"label":"9", "x":2, "y":1}, + + {"label":"4", "x":0, "y":2}, + {"label":"5", "x":1, "y":2}, + {"label":"6", "x":2, "y":2}, + {"label":"+", "x":3, "y":1, "h":2}, + + {"label":"1", "x":0, "y":3}, + {"label":"2", "x":1, "y":3}, + {"label":"3", "x":2, "y":3}, + + {"label":"0", "x":0, "y":4, "w":2}, + {"label":".", "x":2, "y":4}, + {"label":"Enter", "x":3, "y":3, "h":2} + ] + } + } +} diff --git a/keyboards/angel17/keymaps/default/config.h b/keyboards/angel17/keymaps/default/config.h new file mode 100644 index 00000000000..bf1149ebc63 --- /dev/null +++ b/keyboards/angel17/keymaps/default/config.h @@ -0,0 +1,19 @@ +/* Copyright 2019 kakunpc + * + * 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 . + */ + +#pragma once + +// place overrides here diff --git a/keyboards/angel17/keymaps/default/keymap.c b/keyboards/angel17/keymaps/default/keymap.c new file mode 100644 index 00000000000..509bcf5e254 --- /dev/null +++ b/keyboards/angel17/keymaps/default/keymap.c @@ -0,0 +1,42 @@ +/* Copyright 2019 kakunpc + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_numpad_5x4( /* Base */ + KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, + KC_P7, KC_P8, KC_P9, + KC_P4, KC_P5, KC_P6, KC_PPLS, + KC_P1, KC_P2, KC_P3, + KC_P0, KC_PDOT, KC_PENT + ), +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + return true; +} + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +void led_set_user(uint8_t usb_led) { + +} diff --git a/keyboards/angel17/keymaps/default/readme.md b/keyboards/angel17/keymaps/default/readme.md new file mode 100644 index 00000000000..a509fef7a35 --- /dev/null +++ b/keyboards/angel17/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for angel17 \ No newline at end of file diff --git a/keyboards/angel17/readme.md b/keyboards/angel17/readme.md new file mode 100644 index 00000000000..8c9b8066855 --- /dev/null +++ b/keyboards/angel17/readme.md @@ -0,0 +1,15 @@ +# angel17 + +![angel17](https://i.gyazo.com/30787446262c5818bc60e0ffb34c96ed.jpg) + +Keyboard for tablets. + +Keyboard Maintainer: [kakunpc](https://github.com/kakunpc) +Hardware Supported: angel17_alpha, promicro +Hardware Availability: booth([@kakunpc](https://kakunpc.booth.pm/)) + +Make example for this keyboard (after setting up your build environment): + + make angel17: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). diff --git a/keyboards/angel17/rules.mk b/keyboards/angel17/rules.mk new file mode 100644 index 00000000000..423ebddc514 --- /dev/null +++ b/keyboards/angel17/rules.mk @@ -0,0 +1,46 @@ +# MCU name +MCU = atmega32u4 + + +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# atmega32a bootloadHID +BOOTLOADER = caterina + + +# If you don't know the bootloader type, then you can specify the +# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +# OPT_DEFS += -DBOOTLOADER_SIZE=4096 + + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # 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 +MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config) +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE = no # Audio output on port C6 +FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches +HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) + +LAYOUTS = numpad_5x4 From fcf87370a835942681592891dcab6b3a0809bb1f Mon Sep 17 00:00:00 2001 From: fauxpark Date: Thu, 22 Aug 2019 10:41:29 +1000 Subject: [PATCH 53/61] [Keyboard] Update NovelPad (#6559) * Update NovelPad * Lowercase readme * Update keyboards/novelpad/keymaps/default/keymap.c Co-Authored-By: Joel Challis * Remove default F_CPU, F_USB, ARCH, and OPT_DEFS - covered in mcu_selection.mk --- keyboards/novelpad/config.h | 218 ++++++++++++++++++-- keyboards/novelpad/info.json | 27 ++- keyboards/novelpad/keymaps/default/keymap.c | 137 ++++-------- keyboards/novelpad/novelpad.c | 1 + keyboards/novelpad/novelpad.h | 26 ++- keyboards/novelpad/{README.md => readme.md} | 2 +- keyboards/novelpad/rules.mk | 45 +--- 7 files changed, 292 insertions(+), 164 deletions(-) rename keyboards/novelpad/{README.md => readme.md} (68%) diff --git a/keyboards/novelpad/config.h b/keyboards/novelpad/config.h index c9b6b91a595..a2d24d7f820 100755 --- a/keyboards/novelpad/config.h +++ b/keyboards/novelpad/config.h @@ -14,8 +14,8 @@ 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 . */ -#ifndef CONFIG_H -#define CONFIG_H + +#pragma once #include "config_common.h" @@ -31,35 +31,219 @@ along with this program. If not, see . #define MATRIX_ROWS 5 #define MATRIX_COLS 4 -/* key matrix pins */ +/* + * 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 { C2, C4, C5, C6, C7 } #define MATRIX_COL_PINS { D7, D6, D5, D4 } #define UNUSED_PINS -/* COL2ROW or ROW2COL */ +/* COL2ROW, ROW2COL*/ #define DIODE_DIRECTION COL2ROW -/* Set 0 if debouncing isn't needed */ +#define BACKLIGHT_PIN B7 +//#define BACKLIGHT_BREATHING +#define BACKLIGHT_LEVELS 10 + +/* + * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. + */ +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 + +#define RGB_DI_PIN D3 +#ifdef RGB_DI_PIN + #define RGBLED_NUM 4 +// #define RGBLIGHT_HUE_STEP 8 +// #define RGBLIGHT_SAT_STEP 8 +// #define RGBLIGHT_VAL_STEP 8 +// #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ +// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */ +// /*== all animations enable ==*/ + #define RGBLIGHT_ANIMATIONS +// /*== or choose animations ==*/ +// #define RGBLIGHT_EFFECT_BREATHING +// #define RGBLIGHT_EFFECT_RAINBOW_MOOD +// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL +// #define RGBLIGHT_EFFECT_SNAKE +// #define RGBLIGHT_EFFECT_KNIGHT +// #define RGBLIGHT_EFFECT_CHRISTMAS +// #define RGBLIGHT_EFFECT_STATIC_GRADIENT +// #define RGBLIGHT_EFFECT_RGB_TEST +// #define RGBLIGHT_EFFECT_ALTERNATING +// /*== customize breathing effect ==*/ +// /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/ +// #define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64 +// /*==== use exp() and sin() ====*/ +// #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7 +// #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 +#endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE - /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE -/* key combination for command */ -#define IS_COMMAND() ( \ - false \ -) +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is userful for the Windows task manager shortcut (ctrl+shift+esc). + */ +// #define GRAVE_ESC_CTRL_OVERRIDE -#define BACKLIGHT_LEVELS 10 -#define BACKLIGHT_PIN B7 +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO -#ifdef RGBLIGHT_ENABLE -#define RGB_DI_PIN D3 -#define RGBLIGHT_ANIMATIONS -#define RGBLED_NUM 4 +/* + * Magic Key Options + * + * Magic keys are hotkey commands that allow control over firmware functions of + * the keyboard. They are best used in combination with the HID Listen program, + * found here: https://www.pjrc.com/teensy/hid_listen.html + * + * The options below allow the magic key functionality to be changed. This is + * useful if your keyboard/keypad is missing keys and you want magic key support. + * + */ + +/* key combination for magic key command */ +/* defined by default; to change, uncomment and set to the combination you want */ +// #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) + +/* control how magic key switches layers */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false + +/* override magic key keymap */ +//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS +//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM +//#define MAGIC_KEY_HELP H +//#define MAGIC_KEY_HELP_ALT SLASH +//#define MAGIC_KEY_DEBUG D +//#define MAGIC_KEY_DEBUG_MATRIX X +//#define MAGIC_KEY_DEBUG_KBD K +//#define MAGIC_KEY_DEBUG_MOUSE M +//#define MAGIC_KEY_VERSION V +//#define MAGIC_KEY_STATUS S +//#define MAGIC_KEY_CONSOLE C +//#define MAGIC_KEY_LAYER0 0 +//#define MAGIC_KEY_LAYER0_ALT GRAVE +//#define MAGIC_KEY_LAYER1 1 +//#define MAGIC_KEY_LAYER2 2 +//#define MAGIC_KEY_LAYER3 3 +//#define MAGIC_KEY_LAYER4 4 +//#define MAGIC_KEY_LAYER5 5 +//#define MAGIC_KEY_LAYER6 6 +//#define MAGIC_KEY_LAYER7 7 +//#define MAGIC_KEY_LAYER8 8 +//#define MAGIC_KEY_LAYER9 9 +//#define MAGIC_KEY_BOOTLOADER B +//#define MAGIC_KEY_BOOTLOADER_ALT ESC +//#define MAGIC_KEY_LOCK CAPS +//#define MAGIC_KEY_EEPROM E +//#define MAGIC_KEY_EEPROM_CLEAR BSPACE +//#define MAGIC_KEY_NKRO N +//#define MAGIC_KEY_SLEEP_LED Z + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ +//#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 1 + +/* + * HD44780 LCD Display Configuration + */ +/* +#define LCD_LINES 2 //< number of visible lines of the display +#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display + +#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode + +#if LCD_IO_MODE +#define LCD_PORT PORTB //< port for the LCD lines +#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0 +#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1 +#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2 +#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3 +#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0 +#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1 +#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2 +#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3 +#define LCD_RS_PORT LCD_PORT //< port for RS line +#define LCD_RS_PIN 3 //< pin for RS line +#define LCD_RW_PORT LCD_PORT //< port for RW line +#define LCD_RW_PIN 2 //< pin for RW line +#define LCD_E_PORT LCD_PORT //< port for Enable line +#define LCD_E_PIN 1 //< pin for Enable line #endif +*/ -#endif +/* Bootmagic Lite key configuration */ +// #define BOOTMAGIC_LITE_ROW 0 +// #define BOOTMAGIC_LITE_COLUMN 0 diff --git a/keyboards/novelpad/info.json b/keyboards/novelpad/info.json index 7523bf5dda3..4bd648754b3 100644 --- a/keyboards/novelpad/info.json +++ b/keyboards/novelpad/info.json @@ -6,7 +6,32 @@ "height": 5, "layouts": { "LAYOUT_ortho_5x4": { - "layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}, {"x":0, "y":4}, {"x":1, "y":4}, {"x":2, "y":4}, {"x":3, "y":4}] + "layout": [ + {"x":0, "y":0}, + {"x":1, "y":0}, + {"x":2, "y":0}, + {"x":3, "y":0}, + + {"x":0, "y":1}, + {"x":1, "y":1}, + {"x":2, "y":1}, + {"x":3, "y":1}, + + {"x":0, "y":2}, + {"x":1, "y":2}, + {"x":2, "y":2}, + {"x":3, "y":2}, + + {"x":0, "y":3}, + {"x":1, "y":3}, + {"x":2, "y":3}, + {"x":3, "y":3}, + + {"x":0, "y":4}, + {"x":1, "y":4}, + {"x":2, "y":4}, + {"x":3, "y":4} + ] } } } diff --git a/keyboards/novelpad/keymaps/default/keymap.c b/keyboards/novelpad/keymaps/default/keymap.c index 76e0937e6d2..cbac67eaaac 100755 --- a/keyboards/novelpad/keymaps/default/keymap.c +++ b/keyboards/novelpad/keymaps/default/keymap.c @@ -14,111 +14,60 @@ 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 . */ + #include QMK_KEYBOARD_H enum custom_keycodes { - BL = SAFE_RANGE, - WK_RED, - WK_GREEN, - WK_BLUE + WK_RED = SAFE_RANGE, + WK_GREEN, + WK_BLUE }; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_NLCK, KC_PSLS, KC_PAST, KC_ESC, + KC_P7, KC_P8, KC_P9, KC_PMNS, + KC_P4, KC_P5, KC_P6, KC_PPLS, + KC_P1, KC_P2, KC_P3, KC_TAB, + MO(1), KC_P0, KC_PDOT, KC_ENT + ), - [0] = LAYOUT( - KC_NLCK, KC_PSLS, KC_PAST, KC_ESC, - KC_P7, KC_P8, KC_P9, KC_PMNS, - KC_P4, KC_P5, KC_P6, KC_PPLS, - KC_P1, KC_P2, KC_P3, KC_TAB, - MO(1), KC_P0, KC_PDOT, KC_ENT - ), - - [1] = LAYOUT( - _______, BL, RGB_MODE_SWIRL, RESET, - RGB_TOG, RGB_MOD, RGB_MODE_PLAIN, RGB_MODE_SNAKE, - RGB_HUI, RGB_SAI, RGB_VAI, RGB_MODE_KNIGHT, - RGB_HUD, RGB_SAD, RGB_VAD, RGB_MODE_XMAS, - _______, WK_RED, WK_GREEN, WK_BLUE - ), - + [1] = LAYOUT( + _______, BL_STEP, RGB_M_SW, RESET, + RGB_TOG, RGB_MOD, RGB_M_P, RGB_M_SN, + RGB_HUI, RGB_SAI, RGB_VAI, RGB_M_K, + RGB_HUD, RGB_SAD, RGB_VAD, RGB_M_X, + _______, WK_RED, WK_GREEN, WK_BLUE + ) }; -void matrix_init_user(void) { - - rgblight_setrgb(0,255,0); -} - -void matrix_scan_user(void) { +void keyboard_post_init_user(void) { + rgblight_setrgb(0, 255, 0); } bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case BL: - if (record->event.pressed) { -#ifdef BACKLIGHT_ENABLE - backlight_step(); -#endif + switch (keycode) { + case WK_RED: + if (record->event.pressed) { + rgblight_show_solid_color(0xFF, 0x00, 0x00); + } else { + rgblight_show_solid_color(0xFF, 0xFF, 0xFF); + } + return false; + case WK_GREEN: + if (record->event.pressed) { + rgblight_show_solid_color(0x00, 0xFF, 0x00); + } else { + rgblight_show_solid_color(0xFF, 0xFF, 0xFF); + } + return false; + case WK_BLUE: + if (record->event.pressed) { + rgblight_show_solid_color(0x00, 0x00, 0xFF); + } else { + rgblight_show_solid_color(0xFF, 0xFF, 0xFF); + } + return false; } - return false; - break; - case WK_RED: - if (record->event.pressed) { - rgblight_show_solid_color(0xFF, 0, 0); - } else { - rgblight_show_solid_color(0xFF, 0xFF, 0xFF); - } - return false; - break; - case WK_GREEN: - if (record->event.pressed) { - rgblight_show_solid_color(0, 0xFF, 0); - } else { - rgblight_show_solid_color(0xFF, 0xFF, 0xFF); - } - return false; - break; - case WK_BLUE: - if (record->event.pressed) { - rgblight_show_solid_color(0, 0, 0xFF); - } else { - rgblight_show_solid_color(0xFF, 0xFF, 0xFF); - } - return false; - break; - } - return true; -} - -void led_set_user(uint8_t usb_led) { - - if (usb_led & (1 << USB_LED_NUM_LOCK)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_CAPS_LOCK)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_SCROLL_LOCK)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_COMPOSE)) { - - } else { - - } - - if (usb_led & (1 << USB_LED_KANA)) { - - } else { - - } - + return true; } diff --git a/keyboards/novelpad/novelpad.c b/keyboards/novelpad/novelpad.c index 719cb89d6a5..9f6ee7dae47 100755 --- a/keyboards/novelpad/novelpad.c +++ b/keyboards/novelpad/novelpad.c @@ -14,4 +14,5 @@ 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 . */ + #include "novelpad.h" diff --git a/keyboards/novelpad/novelpad.h b/keyboards/novelpad/novelpad.h index f5a0b95f59c..6650a672232 100755 --- a/keyboards/novelpad/novelpad.h +++ b/keyboards/novelpad/novelpad.h @@ -14,25 +14,23 @@ 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 . */ -#ifndef KB_H -#define KB_H + +#pragma once #include "quantum.h" #define LAYOUT_ortho_5x4( \ - K00, K01, K02, K03, \ - K10, K11, K12, K13, \ - K20, K21, K22, K23, \ - K30, K31, K32, K33, \ - K40, K41, K42, K43 \ + K00, K01, K02, K03, \ + K10, K11, K12, K13, \ + K20, K21, K22, K23, \ + K30, K31, K32, K33, \ + K40, K41, K42, K43 \ ) { \ - { K00, K01, K02, K03 }, \ - { K10, K11, K12, K13 }, \ - { K20, K21, K22, K23 }, \ - { K30, K31, K32, K33 }, \ - { K40, K41, K42, K43 } \ + { K00, K01, K02, K03 }, \ + { K10, K11, K12, K13 }, \ + { K20, K21, K22, K23 }, \ + { K30, K31, K32, K33 }, \ + { K40, K41, K42, K43 } \ } #define LAYOUT LAYOUT_ortho_5x4 - -#endif diff --git a/keyboards/novelpad/README.md b/keyboards/novelpad/readme.md similarity index 68% rename from keyboards/novelpad/README.md rename to keyboards/novelpad/readme.md index 5c73644a289..0cde8337ca0 100644 --- a/keyboards/novelpad/README.md +++ b/keyboards/novelpad/readme.md @@ -12,4 +12,4 @@ Make example for this keyboard (after setting up your build environment): make novelpad: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. +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). diff --git a/keyboards/novelpad/rules.mk b/keyboards/novelpad/rules.mk index 8d35c6c05cc..e77a0d6515a 100755 --- a/keyboards/novelpad/rules.mk +++ b/keyboards/novelpad/rules.mk @@ -1,44 +1,15 @@ # MCU name MCU = atmega32u2 -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency in Hz. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# -# This will be an integer division of F_USB below, as it is sourced by -# F_USB after it has run through any CPU prescalers. Note that this value -# does not *change* the processor frequency - it should merely be updated to -# reflect the processor speed set externally so that the code can use accurate -# software delays. -F_CPU = 16000000 -# -# LUFA specific -# -# Target architecture (see library "Board Types" documentation). -ARCH = AVR8 - -# Input clock frequency. -# This will define a symbol, F_USB, in all source code files equal to the -# input clock frequency (before any prescaling is performed) in Hz. This value may -# differ from F_CPU if prescaling is used on the latter, and is required as the -# raw input clock is fed directly to the PLL sections of the AVR for high speed -# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -# at the end, this will be done automatically to create a 32-bit value in your -# source code. -# -# If no clock division is performed on the input clock inside the AVR (via the -# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -F_USB = $(F_CPU) - -# Interrupt driven control endpoint task(+60) -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - - -# Boot Section Size in *bytes* -OPT_DEFS += -DBOOTLOADER_SIZE=4096 +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# atmega32a bootloadHID +BOOTLOADER = atmel-dfu # Build Options From 129e4d1b2f481c09c4f67d24656e6af9cf92b1b6 Mon Sep 17 00:00:00 2001 From: madivad Date: Thu, 22 Aug 2019 10:44:37 +1000 Subject: [PATCH 54/61] [Docs] Update how_keyboards_work.md (#6528) * Update how_keyboards_work.md bridged the gap between scancodes and keycodes, the doc didn't make the distinction and was ambiguous. * Update docs/how_keyboards_work.md Co-Authored-By: Drashna Jaelre * Update docs/how_keyboards_work.md fix typo Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> --- docs/how_keyboards_work.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/how_keyboards_work.md b/docs/how_keyboards_work.md index 5697a21872c..bbd22a2788c 100644 --- a/docs/how_keyboards_work.md +++ b/docs/how_keyboards_work.md @@ -33,7 +33,11 @@ The firmware does not send actual letters or characters, but only scancodes. Thus, by modifying the firmware, you can only modify what scancode is sent over USB for a given key. -## 3. What the Operating System Does +## 3. What the Event Input/Kernel Does + +The *scancode* is mapped to a *keycode* dependent on the keyboard [60-keyboard.hwdb at Master](https://github.com/systemd/systemd/blob/master/hwdb/60-keyboard.hwdb). Without this mapping, the operating system will not receive a valid keycode and will be unable to do anything useful with that key press. + +## 4. What the Operating System Does Once the keycode reaches the operating system, a piece of software has to have it match an actual character thanks to a keyboard layout. For example, if your From 8a2e328a33efd9479d5176ed959ade725b62d9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Dos=C3=A9?= Date: Wed, 21 Aug 2019 17:47:45 -0700 Subject: [PATCH 55/61] [Keyboard] Fix RGB_TOG cycle for Massdrop CTRL default keymap (#6056) This includes the modifier keys in "keys only" mode, bringing the keymap closer to what the off-the-shelf firmware does. --- keyboards/massdrop/ctrl/keymaps/mac/keymap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c index 79fe7388af6..e5b194a3436 100644 --- a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c @@ -102,11 +102,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { switch (rgb_matrix_get_flags()) { case LED_FLAG_ALL: { - rgb_matrix_set_flags(LED_FLAG_KEYLIGHT); + rgb_matrix_set_flags(LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER); rgb_matrix_set_color_all(0, 0, 0); } break; - case LED_FLAG_KEYLIGHT: { + case LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER: { rgb_matrix_set_flags(LED_FLAG_UNDERGLOW); rgb_matrix_set_color_all(0, 0, 0); } From b5ee6c200c96df0b0e4557defdf3a61f70f5d260 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Thu, 22 Aug 2019 00:22:32 -0700 Subject: [PATCH 56/61] Fixup Bootmagic code (#6386) --- quantum/keycode_config.c | 11 +++++++++++ quantum/quantum.c | 16 ++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c index 73fe15861d0..bfd40d045c0 100644 --- a/quantum/keycode_config.c +++ b/quantum/keycode_config.c @@ -18,6 +18,11 @@ extern keymap_config_t keymap_config; +/** \brief keycode_config + * + * This function is used to check a specific keycode against the bootmagic config, + * and will return the corrected keycode, when appropriate. + */ uint16_t keycode_config(uint16_t keycode) { switch (keycode) { @@ -109,6 +114,12 @@ uint16_t keycode_config(uint16_t keycode) { } } +/** \brief mod_config + * + * This function checks the mods passed to it against the bootmagic config, + * and will remove or replace mods, based on that. + */ + uint8_t mod_config(uint8_t mod) { if (keymap_config.swap_lalt_lgui) { if ((mod & MOD_RGUI) == MOD_LGUI) { diff --git a/quantum/quantum.c b/quantum/quantum.c index 665d6fdd916..cbd1f9df0c8 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -613,15 +613,13 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.nkro = true; break; case MAGIC_SWAP_ALT_GUI: - keymap_config.swap_lalt_lgui = true; - keymap_config.swap_ralt_rgui = true; + keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true; #ifdef AUDIO_ENABLE PLAY_SONG(ag_swap_song); #endif break; case MAGIC_SWAP_CTL_GUI: - keymap_config.swap_lctl_lgui = true; - keymap_config.swap_rctl_rgui = true; + keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true; #ifdef AUDIO_ENABLE PLAY_SONG(cg_swap_song); #endif @@ -657,22 +655,20 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.nkro = false; break; case MAGIC_UNSWAP_ALT_GUI: - keymap_config.swap_lalt_lgui = false; - keymap_config.swap_ralt_rgui = false; + keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false; #ifdef AUDIO_ENABLE PLAY_SONG(ag_norm_song); #endif break; case MAGIC_UNSWAP_CTL_GUI: - keymap_config.swap_lctl_lgui = false; - keymap_config.swap_rctl_rgui = false; + keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false; #ifdef AUDIO_ENABLE PLAY_SONG(cg_norm_song); #endif break; case MAGIC_TOGGLE_ALT_GUI: keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; - keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui; + keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui; #ifdef AUDIO_ENABLE if (keymap_config.swap_ralt_rgui) { PLAY_SONG(ag_swap_song); @@ -683,7 +679,7 @@ bool process_record_quantum(keyrecord_t *record) { break; case MAGIC_TOGGLE_CTL_GUI: keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui; - keymap_config.swap_rctl_rgui = !keymap_config.swap_rctl_rgui; + keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui; #ifdef AUDIO_ENABLE if (keymap_config.swap_rctl_rgui) { PLAY_SONG(cg_swap_song); From a20e6aa0224ff243e6dc80259c9de868c4acc9ce Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Thu, 22 Aug 2019 01:59:37 -0700 Subject: [PATCH 57/61] Reduce compile size to fix various Travis CI errors (#6426) Due to feature creep --- keyboards/clueboard/card/rules.mk | 2 ++ keyboards/preonic/rev1/rules.mk | 8 +++++--- keyboards/preonic/rev2/rules.mk | 14 ++++++++------ keyboards/xd004/v1/rules.mk | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/keyboards/clueboard/card/rules.mk b/keyboards/clueboard/card/rules.mk index 37b439e75a7..46d6f91130d 100644 --- a/keyboards/clueboard/card/rules.mk +++ b/keyboards/clueboard/card/rules.mk @@ -19,3 +19,5 @@ MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = yes # Audio output on port C6 + +LINK_TIME_OPTIMIZATION_ENABLE = yes diff --git a/keyboards/preonic/rev1/rules.mk b/keyboards/preonic/rev1/rules.mk index 128deb0c851..db3d644545f 100644 --- a/keyboards/preonic/rev1/rules.mk +++ b/keyboards/preonic/rev1/rules.mk @@ -35,7 +35,7 @@ F_USB = $(F_CPU) # Bootloader # This definition is optional, and if your keyboard supports multiple bootloaders of -# different sizes, comment this out, and the correct address will be loaded +# different sizes, comment this out, and the correct address will be loaded # automatically (+60). See bootloader.mk for all options. BOOTLOADER = atmel-dfu @@ -43,13 +43,13 @@ BOOTLOADER = atmel-dfu OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Build Options -# change to "no" to disable the options, or define them in the Makefile in +# change to "no" to disable the options, or define them in the Makefile in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) +CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality @@ -64,3 +64,5 @@ API_SYSEX_ENABLE = no SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend LAYOUTS = ortho_5x12 + +LINK_TIME_OPTIMIZATION_ENABLE = yes diff --git a/keyboards/preonic/rev2/rules.mk b/keyboards/preonic/rev2/rules.mk index 53411647dda..47a292e3361 100644 --- a/keyboards/preonic/rev2/rules.mk +++ b/keyboards/preonic/rev2/rules.mk @@ -35,7 +35,7 @@ F_USB = $(F_CPU) # Bootloader # This definition is optional, and if your keyboard supports multiple bootloaders of -# different sizes, comment this out, and the correct address will be loaded +# different sizes, comment this out, and the correct address will be loaded # automatically (+60). See bootloader.mk for all options. BOOTLOADER = qmk-dfu @@ -43,18 +43,18 @@ BOOTLOADER = qmk-dfu OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Build Options -# change to "no" to disable the options, or define them in the Makefile in +# change to "no" to disable the options, or define them in the Makefile in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = no # Mouse keys(+4700) +MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) -COMMAND_ENABLE = no # Commands for debug and configuration +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls -AUDIO_ENABLE = yes # Audio output on port C6 +AUDIO_ENABLE = yes # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. @@ -64,3 +64,5 @@ API_SYSEX_ENABLE = no SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend LAYOUTS = ortho_5x12 + +LINK_TIME_OPTIMIZATION_ENABLE = yes diff --git a/keyboards/xd004/v1/rules.mk b/keyboards/xd004/v1/rules.mk index ad2d732d438..c55d65c0f58 100644 --- a/keyboards/xd004/v1/rules.mk +++ b/keyboards/xd004/v1/rules.mk @@ -63,7 +63,7 @@ UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend - +SPACE_CADET_ENABLE = no # Saves about 5% of space: LINK_TIME_OPTIMIZATION_ENABLE = yes From 1c805b3d008a98a5a15112b0655ba14b42dbae67 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 22 Aug 2019 15:27:18 +0100 Subject: [PATCH 58/61] Relocate pca9555 driver to core (#6563) * Move pca9555 files to central location * Get pca9555 boards compiling * Slight alignment of rules.mk --- {keyboards/moon => drivers/gpio}/pca9555.c | 0 {keyboards/moon => drivers/gpio}/pca9555.h | 0 keyboards/moon/rules.mk | 16 +++-- keyboards/xd84/pca9555.c | 78 ---------------------- keyboards/xd84/pca9555.h | 55 --------------- keyboards/xd84/rules.mk | 4 +- keyboards/xd96/pca9555.c | 78 ---------------------- keyboards/xd96/pca9555.h | 55 --------------- keyboards/xd96/rules.mk | 4 +- 9 files changed, 15 insertions(+), 275 deletions(-) rename {keyboards/moon => drivers/gpio}/pca9555.c (100%) rename {keyboards/moon => drivers/gpio}/pca9555.h (100%) delete mode 100644 keyboards/xd84/pca9555.c delete mode 100644 keyboards/xd84/pca9555.h delete mode 100644 keyboards/xd96/pca9555.c delete mode 100644 keyboards/xd96/pca9555.h diff --git a/keyboards/moon/pca9555.c b/drivers/gpio/pca9555.c similarity index 100% rename from keyboards/moon/pca9555.c rename to drivers/gpio/pca9555.c diff --git a/keyboards/moon/pca9555.h b/drivers/gpio/pca9555.h similarity index 100% rename from keyboards/moon/pca9555.h rename to drivers/gpio/pca9555.h diff --git a/keyboards/moon/rules.mk b/keyboards/moon/rules.mk index 699fc339570..c8b39e8b7a1 100644 --- a/keyboards/moon/rules.mk +++ b/keyboards/moon/rules.mk @@ -1,6 +1,3 @@ -# Project specific files -SRC += i2c_master.c pca9555.c matrix.c - # MCU name MCU = atmega32u4 @@ -50,10 +47,6 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # atmega32a bootloadHID BOOTLOADER = atmel-dfu - -# Supported layouts -LAYOUTS = tkl_ansi tkl_iso - # Build Options # change yes to no to disable # @@ -74,4 +67,13 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) + +# custom matrix setup CUSTOM_MATRIX = yes + +VPATH += drivers/gpio +SRC += pca9555.c matrix.c +QUANTUM_LIB_SRC += i2c_master.c + +# Supported layouts +LAYOUTS = tkl_ansi tkl_iso diff --git a/keyboards/xd84/pca9555.c b/keyboards/xd84/pca9555.c deleted file mode 100644 index b0e542d8def..00000000000 --- a/keyboards/xd84/pca9555.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#include "i2c_master.h" -#include "pca9555.h" - -#include "debug.h" - -#define SLAVE_TO_ADDR(n) (n << 1) -#define TIMEOUT 100 - -enum { - CMD_INPUT_0 = 0, - CMD_INPUT_1, - CMD_OUTPUT_0, - CMD_OUTPUT_1, - CMD_INVERSION_0, - CMD_INVERSION_1, - CMD_CONFIG_0, - CMD_CONFIG_1, -}; - -void pca9555_init(uint8_t slave_addr) { - static uint8_t s_init = 0; - if (!s_init) { - i2c_init(); - - s_init = 1; - } - - // TODO: could check device connected - // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - // i2c_stop(); -} - -void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; - - i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_set_config::FAILED\n"); - } -} - -void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; - - i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_set_output::FAILED\n"); - } -} - -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; - - uint8_t data = 0; - i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_readPins::FAILED\n"); - } - return data; -} diff --git a/keyboards/xd84/pca9555.h b/keyboards/xd84/pca9555.h deleted file mode 100644 index ebb97e2f301..00000000000 --- a/keyboards/xd84/pca9555.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#pragma once - -/* - PCA9555 - ,----------. - SDA --| SDA P00 |-- P00 - SCL --| SCL P01 |-- P01 - INT --| INT P02 |-- P02 - | P03 |-- P03 - A0 --| A0 P04 |-- P04 - A1 --| A1 P05 |-- P05 - A2 --| A2 P06 |-- P06 - | P07 |-- P07 - | | - | P10 |-- P10 - | P11 |-- P11 - | P12 |-- P12 - | P13 |-- P13 - | P14 |-- P14 - | P15 |-- P15 - | P16 |-- P16 - | P17 |-- P17 - `----------' -*/ - -#define PCA9555_PORT0 0 -#define PCA9555_PORT1 1 - -#define ALL_OUTPUT 0 -#define ALL_INPUT 0xFF -#define ALL_LOW 0 -#define ALL_HIGH 0xFF - -void pca9555_init(uint8_t slave_addr); - -void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); - -void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); - -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); diff --git a/keyboards/xd84/rules.mk b/keyboards/xd84/rules.mk index e0982e0401c..91664522621 100644 --- a/keyboards/xd84/rules.mk +++ b/keyboards/xd84/rules.mk @@ -77,11 +77,13 @@ UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches -HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) +HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) LINK_TIME_OPTIMIZATION_ENABLE = yes # custom matrix setup CUSTOM_MATRIX = yes + +VPATH += drivers/gpio SRC += custom_matrix_helper.c pca9555.c matrix.c QUANTUM_LIB_SRC += i2c_master.c diff --git a/keyboards/xd96/pca9555.c b/keyboards/xd96/pca9555.c deleted file mode 100644 index b0e542d8def..00000000000 --- a/keyboards/xd96/pca9555.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#include "i2c_master.h" -#include "pca9555.h" - -#include "debug.h" - -#define SLAVE_TO_ADDR(n) (n << 1) -#define TIMEOUT 100 - -enum { - CMD_INPUT_0 = 0, - CMD_INPUT_1, - CMD_OUTPUT_0, - CMD_OUTPUT_1, - CMD_INVERSION_0, - CMD_INVERSION_1, - CMD_CONFIG_0, - CMD_CONFIG_1, -}; - -void pca9555_init(uint8_t slave_addr) { - static uint8_t s_init = 0; - if (!s_init) { - i2c_init(); - - s_init = 1; - } - - // TODO: could check device connected - // i2c_start(SLAVE_TO_ADDR(slave) | I2C_WRITE); - // i2c_stop(); -} - -void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0; - - i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_set_config::FAILED\n"); - } -} - -void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0; - - i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_set_output::FAILED\n"); - } -} - -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0; - - uint8_t data = 0; - i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - print("pca9555_readPins::FAILED\n"); - } - return data; -} diff --git a/keyboards/xd96/pca9555.h b/keyboards/xd96/pca9555.h deleted file mode 100644 index ebb97e2f301..00000000000 --- a/keyboards/xd96/pca9555.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#pragma once - -/* - PCA9555 - ,----------. - SDA --| SDA P00 |-- P00 - SCL --| SCL P01 |-- P01 - INT --| INT P02 |-- P02 - | P03 |-- P03 - A0 --| A0 P04 |-- P04 - A1 --| A1 P05 |-- P05 - A2 --| A2 P06 |-- P06 - | P07 |-- P07 - | | - | P10 |-- P10 - | P11 |-- P11 - | P12 |-- P12 - | P13 |-- P13 - | P14 |-- P14 - | P15 |-- P15 - | P16 |-- P16 - | P17 |-- P17 - `----------' -*/ - -#define PCA9555_PORT0 0 -#define PCA9555_PORT1 1 - -#define ALL_OUTPUT 0 -#define ALL_INPUT 0xFF -#define ALL_LOW 0 -#define ALL_HIGH 0xFF - -void pca9555_init(uint8_t slave_addr); - -void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); - -void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); - -uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); diff --git a/keyboards/xd96/rules.mk b/keyboards/xd96/rules.mk index 91736bd8785..3a97fe5f98b 100644 --- a/keyboards/xd96/rules.mk +++ b/keyboards/xd96/rules.mk @@ -77,10 +77,12 @@ UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches -HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) +HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400) LINK_TIME_OPTIMIZATION_ENABLE = yes # custom matrix setup CUSTOM_MATRIX = yes + +VPATH += drivers/gpio SRC += custom_matrix_helper.c pca9555.c matrix.c QUANTUM_LIB_SRC += i2c_master.c From ae44ec9820cdf5348e802c9bae3af34557617685 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 23 Aug 2019 00:08:45 +0100 Subject: [PATCH 59/61] Align flashing behaviour of dfu-util (#6578) * Align flashing retry logic of dfu-util * Align bootloader wait messages Co-Authored-By: Drashna Jaelre --- docs/flashing.md | 6 ++---- tmk_core/chibios.mk | 22 ++++++---------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/docs/flashing.md b/docs/flashing.md index 833b9dd629f..d11dbdf15b5 100644 --- a/docs/flashing.md +++ b/docs/flashing.md @@ -171,7 +171,5 @@ Flashing sequence: There are a number of DFU commands that you can use to flash firmware to a STM32 device: -* `:dfu-util` - The default command for flashing to STM32 devices. -* `:dfu-util-wait` - This works like the default command, but it gives you a (configurable) 10 second timeout before it attempts to flash the firmware. You can use `TIME_DELAY=20` from the command line to change the timeout. - * Eg: `make ::dfu-util TIME_DELAY=5` -* `:st-link-cli` - This allows you to flash the firmware via ST-LINK's CLI utility, rather than dfu-util. +* `:dfu-util` - The default command for flashing to STM32 devices. +* `:st-link-cli` - This allows you to flash the firmware via ST-LINK's CLI utility, rather than dfu-util. diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index eee520467d7..4b5b6d00b5a 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -235,28 +235,18 @@ qmk: $(BUILD_DIR)/$(TARGET).bin printf "@ $(TARGET).json\n@=info.json\n" | zipnote -w $(TARGET).qmk define EXEC_DFU_UTIL + until $(DFU_UTIL) -l | grep -q "Found DFU"; do\ + echo "Error: Bootloader not found. Trying again in 5s." ;\ + sleep 5 ;\ + done $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin endef dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter $(call EXEC_DFU_UTIL) -ifneq ($(strip $(TIME_DELAY)),) - TIME_DELAY = $(strip $(TIME_DELAY)) -else - TIME_DELAY = 10 -endif -dfu-util-wait: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter - echo "Preparing to flash firmware. Please enter bootloader now..." ;\ - COUNTDOWN=$(TIME_DELAY) ;\ - while [[ $$COUNTDOWN -ge 1 ]] ; do \ - echo "Flashing in $$COUNTDOWN ..."; \ - sleep 1 ;\ - ((COUNTDOWN = COUNTDOWN - 1)) ; \ - done; \ - echo "Flashing $(TARGET).bin" ;\ - sleep 1 ;\ - $(call EXEC_DFU_UTIL) +# Legacy alias +dfu-util-wait: dfu-util st-link-cli: $(BUILD_DIR)/$(TARGET).hex sizeafter $(ST_LINK_CLI) $(ST_LINK_ARGS) -q -c SWD -p $(BUILD_DIR)/$(TARGET).hex -Rst From e0f91f37c4b944b328f9e022b18f2f1ad702fcf4 Mon Sep 17 00:00:00 2001 From: Elias Date: Fri, 23 Aug 2019 23:18:37 +0200 Subject: [PATCH 60/61] Added 4by3 keyboard (#6547) * Added 4by3 keyboard * Added DEVICE_VER and DESCRIPTION * Removed F_CPU, F_USB, ARCH, and OPT_DEFS * Add 3 new LAYOUT macros for orientations and fixes * Apply suggestions from code review Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Added comments to 4by3 and changed info.json * Update keyboards/4by3/4by3.h Co-Authored-By: fauxpark --- keyboards/4by3/4by3.c | 1 + keyboards/4by3/4by3.h | 70 +++++++++++++++++++ keyboards/4by3/config.h | 26 +++++++ keyboards/4by3/info.json | 41 +++++++++++ keyboards/4by3/keymaps/arrowpad/keymap.c | 12 ++++ keyboards/4by3/keymaps/default/keymap.c | 9 +++ keyboards/4by3/keymaps/default/readme.md | 3 + .../4by3/keymaps/funcpad_horizontal/keymap.c | 9 +++ .../4by3/keymaps/funcpad_vertical/keymap.c | 12 ++++ .../4by3/keymaps/numpad_horizontal/keymap.c | 9 +++ .../4by3/keymaps/numpad_vertical/keymap.c | 12 ++++ keyboards/4by3/readme.md | 15 ++++ keyboards/4by3/rules.mk | 8 +++ 13 files changed, 227 insertions(+) create mode 100644 keyboards/4by3/4by3.c create mode 100644 keyboards/4by3/4by3.h create mode 100644 keyboards/4by3/config.h create mode 100644 keyboards/4by3/info.json create mode 100644 keyboards/4by3/keymaps/arrowpad/keymap.c create mode 100644 keyboards/4by3/keymaps/default/keymap.c create mode 100644 keyboards/4by3/keymaps/default/readme.md create mode 100644 keyboards/4by3/keymaps/funcpad_horizontal/keymap.c create mode 100644 keyboards/4by3/keymaps/funcpad_vertical/keymap.c create mode 100644 keyboards/4by3/keymaps/numpad_horizontal/keymap.c create mode 100644 keyboards/4by3/keymaps/numpad_vertical/keymap.c create mode 100644 keyboards/4by3/readme.md create mode 100644 keyboards/4by3/rules.mk diff --git a/keyboards/4by3/4by3.c b/keyboards/4by3/4by3.c new file mode 100644 index 00000000000..3ae27260d44 --- /dev/null +++ b/keyboards/4by3/4by3.c @@ -0,0 +1 @@ +#include "4by3.h" \ No newline at end of file diff --git a/keyboards/4by3/4by3.h b/keyboards/4by3/4by3.h new file mode 100644 index 00000000000..b41628137a6 --- /dev/null +++ b/keyboards/4by3/4by3.h @@ -0,0 +1,70 @@ +#pragma once + +#include "quantum.h" + +/* LAYOUT_horizontal + * ┌───┐ + * │USB│ + * ├───┼───┬───┬───┐ + * │K00│K01│K02│K03│ + * ├───┼───┼───┼───┤ + * │K10│K11│K12│K13│ + * ├───┼───┼───┼───┤ + * │K20│K21│K22│K23│ + * └───┴───┴───┴───┘ + */ +#define LAYOUT_horizontal( \ + K00, K01, K02, K03, \ + K10, K11, K12, K13, \ + K20, K21, K22, K23 \ +) { \ + { K00, K01, K02, K03 }, \ + { K10, K11, K12, K13 }, \ + { K20, K21, K22, K23 } \ +} + +/* LAYOUT_vertical_right + * ┌───┬───┬───┬───┐ + * │K00│K01│K03│USB│ + * ├───┼───┼───┬───┘ + * │K04│K05│K06│ + * ├───┼───┼───┤ + * │K07│K08│K09│ + * ├───┼───┼───┤ + * │K10│K11│K12│ + * └───┴───┴───┘ + */ +#define LAYOUT_vertical_right( \ + K20, K10, K00, \ + K21, K11, K01, \ + K22, K12, K02, \ + K23, K13, K03 \ +) { \ + { K00, K01, K02, K03 }, \ + { K10, K11, K12, K13 }, \ + { K20, K21, K22, K23 } \ +} + +/* LAYOUT_vertical_left + * ┌───┬───┬───┐ + * │K00│K01│K03│ + * ├───┼───┼───┤ + * │K04│K05│K06│ + * ├───┼───┼───┤ + * │K07│K08│K09│ + * ┌───┼───┼───┼───┤ + * │USB│K10│K11│K12│ + * └───┴───┴───┴───┘ + */ +#define LAYOUT_vertical_left( \ + K03, K13, K23, \ + K02, K12, K22, \ + K01, K11, K21, \ + K00, K10, K20 \ +) { \ + { K00, K01, K02, K03 }, \ + { K10, K11, K12, K13 }, \ + { K20, K21, K22, K23 } \ +} + +#define LAYOUT LAYOUT_horizontal diff --git a/keyboards/4by3/config.h b/keyboards/4by3/config.h new file mode 100644 index 00000000000..2095ee42c22 --- /dev/null +++ b/keyboards/4by3/config.h @@ -0,0 +1,26 @@ +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xEEEE +#define PRODUCT_ID 0x2019 +#define DEVICE_VER 0x0001 +#define MANUFACTURER Elias Sjögreen +#define PRODUCT 4by3 +#define DESCRIPTION A small 12 key keypad + +/* key matrix size */ +#define MATRIX_ROWS 3 +#define MATRIX_COLS 4 + +/* key matrix pins */ +#define MATRIX_ROW_PINS { D1, D0, D4 } +#define MATRIX_COL_PINS { C6, D7, E6, B4 } +#define UNUSED_PINS + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 diff --git a/keyboards/4by3/info.json b/keyboards/4by3/info.json new file mode 100644 index 00000000000..9cc07a9240f --- /dev/null +++ b/keyboards/4by3/info.json @@ -0,0 +1,41 @@ +{ + "keyboard_name": "4by3", + "url": "https://github.com/eliassjogreen/4by3", + "maintainer": "eliassjogreen", + "width": 4, + "height": 3, + "layouts": { + "LAYOUT_horizontal": { + "key_count": 12, + "width": 4, + "height": 3, + "layout": [ + { "x": 0, "y": 0 }, { "x": 1, "y": 0 }, { "x": 2, "y": 0 }, { "x": 3, "y": 0 }, + { "x": 0, "y": 1 }, { "x": 1, "y": 1 }, { "x": 2, "y": 1 }, { "x": 3, "y": 1 }, + { "x": 0, "y": 2 }, { "x": 1, "y": 2 }, { "x": 2, "y": 2 }, { "x": 3, "y": 2 } + ] + }, + "LAYOUT_vertical_right": { + "key_count": 12, + "width": 3, + "height": 4, + "layout": [ + { "x": 0, "y": 0 }, { "x": 1, "y": 0 }, { "x": 2, "y": 0 }, + { "x": 0, "y": 1 }, { "x": 1, "y": 1 }, { "x": 2, "y": 1 }, + { "x": 0, "y": 2 }, { "x": 1, "y": 2 }, { "x": 2, "y": 2 }, + { "x": 0, "y": 3 }, { "x": 1, "y": 3 }, { "x": 2, "y": 3 } + ] + }, + "LAYOUT_vertical_left": { + "key_count": 12, + "width": 3, + "height": 4, + "layout": [ + { "x": 0, "y": 0 }, { "x": 1, "y": 0 }, { "x": 2, "y": 0 }, + { "x": 0, "y": 1 }, { "x": 1, "y": 1 }, { "x": 2, "y": 1 }, + { "x": 0, "y": 2 }, { "x": 1, "y": 2 }, { "x": 2, "y": 2 }, + { "x": 0, "y": 3 }, { "x": 1, "y": 3 }, { "x": 2, "y": 3 } + ] + } + } +} diff --git a/keyboards/4by3/keymaps/arrowpad/keymap.c b/keyboards/4by3/keymaps/arrowpad/keymap.c new file mode 100644 index 00000000000..df803a35e60 --- /dev/null +++ b/keyboards/4by3/keymaps/arrowpad/keymap.c @@ -0,0 +1,12 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Change 'LAYOUT_vertical_right' to 'LAYOUT_vertical_left' + to change the side where the pro micro usb port is. */ + [0] = LAYOUT_vertical_right( + KC_INS , KC_HOME , KC_PGUP , + KC_DEL , KC_END , KC_PGDN , + KC_PSCR , KC_UP , KC_PAUS , + KC_LEFT , KC_DOWN , KC_RGHT + ) +}; diff --git a/keyboards/4by3/keymaps/default/keymap.c b/keyboards/4by3/keymaps/default/keymap.c new file mode 100644 index 00000000000..f348dc84fb0 --- /dev/null +++ b/keyboards/4by3/keymaps/default/keymap.c @@ -0,0 +1,9 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_horizontal( + KC_VOLU , _______ , _______ , _______ , + KC_MUTE , KC_MPRV , KC_MPLY , KC_MNXT , + KC_VOLD , _______ , _______ , _______ + ) +}; diff --git a/keyboards/4by3/keymaps/default/readme.md b/keyboards/4by3/keymaps/default/readme.md new file mode 100644 index 00000000000..281dfd5463f --- /dev/null +++ b/keyboards/4by3/keymaps/default/readme.md @@ -0,0 +1,3 @@ +# The default 4by3 keymap + +![The default 4by3 keymap](https://i.imgur.com/E4OlQAs.png) diff --git a/keyboards/4by3/keymaps/funcpad_horizontal/keymap.c b/keyboards/4by3/keymaps/funcpad_horizontal/keymap.c new file mode 100644 index 00000000000..287d125ef13 --- /dev/null +++ b/keyboards/4by3/keymaps/funcpad_horizontal/keymap.c @@ -0,0 +1,9 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_horizontal( + KC_F1 , KC_F2 , KC_F3 , KC_F4 , + KC_F5 , KC_F6 , KC_F7 , KC_F8 , + KC_F9 , KC_F10 , KC_F11 , KC_F12 + ) +}; diff --git a/keyboards/4by3/keymaps/funcpad_vertical/keymap.c b/keyboards/4by3/keymaps/funcpad_vertical/keymap.c new file mode 100644 index 00000000000..c345f282401 --- /dev/null +++ b/keyboards/4by3/keymaps/funcpad_vertical/keymap.c @@ -0,0 +1,12 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Change 'LAYOUT_vertical_right' to 'LAYOUT_vertical_left' + to change the side where the pro micro usb port is. */ + [0] = LAYOUT_vertical_right( + KC_F1 , KC_F2 , KC_F3 , + KC_F4 , KC_F5 , KC_F6 , + KC_F7 , KC_F8 , KC_F9 , + KC_F10 , KC_F11 , KC_F12 + ) +}; diff --git a/keyboards/4by3/keymaps/numpad_horizontal/keymap.c b/keyboards/4by3/keymaps/numpad_horizontal/keymap.c new file mode 100644 index 00000000000..c1195b0bc90 --- /dev/null +++ b/keyboards/4by3/keymaps/numpad_horizontal/keymap.c @@ -0,0 +1,9 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_horizontal( + KC_P1 , KC_P2 , KC_P3 , KC_P4 , + KC_P5 , KC_P6 , KC_P7 , KC_P8 , + KC_P9 , KC_P0 , KC_BSPC , KC_ENT + ), +}; diff --git a/keyboards/4by3/keymaps/numpad_vertical/keymap.c b/keyboards/4by3/keymaps/numpad_vertical/keymap.c new file mode 100644 index 00000000000..7705ea9b83e --- /dev/null +++ b/keyboards/4by3/keymaps/numpad_vertical/keymap.c @@ -0,0 +1,12 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Change 'LAYOUT_vertical_right' to 'LAYOUT_vertical_left' + to change the side where the pro micro usb port is. */ + [0] = LAYOUT_vertical_right( + KC_P1 , KC_P2 , KC_P3 , + KC_P4 , KC_P5 , KC_P6 , + KC_P7 , KC_P8 , KC_P9 , + KC_BSPC , KC_P0 , KC_ENT + ), +}; diff --git a/keyboards/4by3/readme.md b/keyboards/4by3/readme.md new file mode 100644 index 00000000000..0197c4ff80d --- /dev/null +++ b/keyboards/4by3/readme.md @@ -0,0 +1,15 @@ +# 4by3 + +![4by3](https://i.imgur.com/Ykb7evL.jpg) + +A 12 key mechanical keypad. + +Keyboard Maintainer: [eliassjogreen](https://github.com/eliassjogreen) +Hardware Supported: 4by3 +Hardware Availability: [eliassjogreen/4by3](https://github.com/eliassjogreen/4by3) + +Make example for this keyboard (after setting up your build environment): + + make 4by3: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). diff --git a/keyboards/4by3/rules.mk b/keyboards/4by3/rules.mk new file mode 100644 index 00000000000..7d22998333e --- /dev/null +++ b/keyboards/4by3/rules.mk @@ -0,0 +1,8 @@ +MCU = atmega32u4 +BOOTLOADER = caterina + +EXTRAKEY_ENABLE = yes +NKRO_ENABLE = yes +CONSOLE_ENABLE = yes +COMMAND_ENABLE = yes + From 064d9da93e8055d95717823aefd2b88289374c12 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Fri, 23 Aug 2019 14:23:53 -0700 Subject: [PATCH 61/61] Add Soft Serial Speed to Diverge3 keyboard config for compatibility (#5076) --- keyboards/diverge3/.gitignore | 1 - keyboards/diverge3/config.h | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 keyboards/diverge3/.gitignore diff --git a/keyboards/diverge3/.gitignore b/keyboards/diverge3/.gitignore deleted file mode 100644 index 722d5e71d93..00000000000 --- a/keyboards/diverge3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.vscode diff --git a/keyboards/diverge3/config.h b/keyboards/diverge3/config.h index a593bca9db6..96196667c04 100644 --- a/keyboards/diverge3/config.h +++ b/keyboards/diverge3/config.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef CONFIG_H -#define CONFIG_H +#pragma once #include "config_common.h" @@ -59,6 +58,10 @@ along with this program. If not, see . /* serial.c configuration for split keyboard */ #define SOFT_SERIAL_PIN D0 +#ifndef SELECT_SOFT_SERIAL_SPEED +#define SELECT_SOFT_SERIAL_SPEED 3 +#endif + /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST @@ -181,5 +184,3 @@ along with this program. If not, see . /* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ //#define MIDI_TONE_KEYCODE_OCTAVES 1 - -#endif