Compare commits

...

13 Commits

Author SHA1 Message Date
Ryan
261d94ce34 Tidy up spi_master includes (#13053) 2021-06-03 16:26:41 +10:00
James Young
a0cc2dc6d0 Update noroadsleft userspace and keymaps (2021-06-02) (#13086) 2021-06-02 23:06:30 -07:00
Nick Brassel
597d2e0e7b Fix up WS2812 SPI driver on F072. (#13022) 2021-06-03 09:48:16 +10:00
Joel Elkins
35dbe8ba03 [Keymap] merge jdelkins userspace and associated keymaps (#11276)
* [Keymap] merge jdelkins userspace and associated keymaps

* Add copyright & license info

* Change rgblight_config.enable to rgblight_is_enabled()

* Update keyboards/dz60/keymaps/jdelkins/keymap.c

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

* Update keyboards/dz60/keymaps/jdelkins/keymap.c

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

* Update keyboards/dz60/keymaps/jdelkins/keymap.c

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

* Remove superfluous includes

* Change EXTRAFLAGS+=-flto to LTO_ENABLE=yes

* Remove unnecessary jdelkins_ss symlink in users

* Add copyright and license notices

* Use preferred way to determine capslock / numlock state

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

* Add #pragma once to a header

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

* Include QMK_KEYBOARD_H only once, in userspace header

* Remove unnecessary initialization in matrix_init_keymap

* Do process_record_keymap before cases handled in process_record_user

* Reorganize & simplify secrets feature enablement

* Use tap_code16

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

* Remove superfluous break

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

* Remove copyright from rules.mk

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

* Remove copyright from rules.mk

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

* Use tap_code16

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

* include "print.h" instead of <print.h>

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

* Use tap_cod16

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

* Use tap_code16

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

* Use tap_code16

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

* Use tap_code16

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

* Remove copyright from rules.mk

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

* add #pragma once to a header

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

* include "print.h" instead of <print.h>

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

* Remove copyright from rules.mk

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

* Remove copyright from rules.mk

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

* Remove copyright from rules.mk

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

* Use tap_code16

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

* Use tap_code16

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

* Use :flash target where possible

* Remove special case flash target and use PROGRAM_CMD

* dz60/jdelkins_ss: use tap_code16

Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2021-06-03 06:59:52 +10:00
Xelus22
93496c8364 fix missing arg (#13068) 2021-06-01 18:12:17 +10:00
Xelus22
5a06813b10 VIA compile fixes (#13054) 2021-05-31 21:56:23 -07:00
Jeff Apczynski
6bafefa886 [Keymap] lja83's Planck keymap (#12809)
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Jeff Apczynski <jeffrey.apczynski@braincorp.com>
2021-05-30 21:16:26 -07:00
Gregorio
1a3064afb1 [Keyboard] Add Rubi Numpad (#12283)
Co-authored-by: Drashna Jaelre <drashna@live.com>
Co-authored-by: Ryan <fauxpark@gmail.com>
2021-05-30 21:04:26 -07:00
Lander
2b8f1fcdfb [Keyboard] Unicomp Mini M (#12892) 2021-05-30 14:58:43 -07:00
Brandon Lewis
7b055dcc55 [Keyboard] Added BOP support (#12991)
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Brandon Lewis <blewis308@users.noreply.github.com>
2021-05-30 14:57:43 -07:00
lukeski14
fc9a2167b1 [Keyboard] jabberwocky via support (#13029) 2021-05-30 14:55:58 -07:00
Sergey Vlasov
3aca3d3572 merge/um70:via: Avoid sprintf() to make the code fit into flash (#12919)
The code using sprintf() did not fit into flash when `merge/um70:via`
was compiled with avr-gcc 5.4.0:

     * The firmware is too large! 29756/28672 (1084 bytes over)

Replacing `sprintf(wpm_str, " %03d", current_wpm);` with custom
formatting code reduces the firmware size by 1504 bytes, which is enough
to make the `merge/um70:via` firmware fit:

    * The firmware size is approaching the maximum - 28252/28672 (98%, 420 bytes free)
2021-05-30 14:47:44 -07:00
Erovia
305cca9a5e CLI: Fix automagic (#13046) 2021-05-30 16:17:40 +01:00
96 changed files with 5932 additions and 81 deletions

View File

@@ -72,7 +72,9 @@ WS2812_DRIVER = spi
Configure the hardware via your config.h:
```c
#define WS2812_SPI SPID1 // default: SPID1
#define WS2812_SPI_MOSI_PAL_MODE 5 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5
#define WS2812_SPI_MOSI_PAL_MODE 5 // MOSI pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5
#define WS2812_SPI_SCK_PIN B3 // Required for F072, may be for others -- SCK pin, see the respective datasheet for the appropriate values for your MCU. default: unspecified
#define WS2812_SPI_SCK_PAL_MODE 5 // SCK pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5
```
You must also turn on the SPI feature in your halconf.h and mcuconf.h
@@ -100,11 +102,11 @@ Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported by hardware.
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
| | SPI1 | SPI2 | SPI3 |
|-|-|-|-|
| f072 | ? | B15 :heavy_check_mark: | N/A |
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
| | SPI1 | SPI2 | SPI3 |
|------|---------------------------------------------|-----------------------------------------|-----------------------|
| f072 | ? | B15 :heavy_check_mark: (needs SCK: B13) | N/A |
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*

View File

@@ -14,10 +14,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include "spi_master.h"
#include "quantum.h"
#include "timer.h"
#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)

View File

@@ -16,7 +16,9 @@
#pragma once
#include "quantum.h"
#include <stdbool.h>
#include "gpio.h"
typedef int16_t spi_status_t;

View File

@@ -15,7 +15,7 @@
*/
#include "spi_master.h"
#include "quantum.h"
#include "timer.h"
static pin_t currentSlavePin = NO_PIN;

View File

@@ -18,7 +18,9 @@
#include <ch.h>
#include <hal.h>
#include "quantum.h"
#include <stdbool.h>
#include "gpio.h"
#ifndef SPI_DRIVER
# define SPI_DRIVER SPID2

View File

@@ -16,19 +16,23 @@
# define WS2812_SPI_MOSI_PAL_MODE 5
#endif
#ifndef WS2812_SPI_SCK_PAL_MODE
# define WS2812_SPI_SCK_PAL_MODE 5
#endif
// Push Pull or Open Drain Configuration
// Default Push Pull
#ifndef WS2812_EXTERNAL_PULLUP
# if defined(USE_GPIOV1)
# define WS2812_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
# else
# define WS2812_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL
# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL
# endif
#else
# if defined(USE_GPIOV1)
# define WS2812_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
# else
# define WS2812_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN
# define WS2812_MOSI_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN
# endif
#endif
@@ -63,6 +67,12 @@
# define WS2812_SPI_BUFFER_MODE 0 // normal buffer
#endif
#if defined(USE_GPIOV1)
# define WS2812_SCK_OUTPUT_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
#else
# define WS2812_SCK_OUTPUT_MODE PAL_MODE_ALTERNATE(WS2812_SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL
#endif
#define BYTES_FOR_LED_BYTE 4
#define NB_COLORS 3
#define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * NB_COLORS)
@@ -109,7 +119,11 @@ static void set_led_color_rgb(LED_TYPE color, int pos) {
}
void ws2812_init(void) {
palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE);
palSetLineMode(RGB_DI_PIN, WS2812_MOSI_OUTPUT_MODE);
#ifdef WS2812_SPI_SCK_PIN
palSetLineMode(WS2812_SPI_SCK_PIN, WS2812_SCK_OUTPUT_MODE);
#endif // WS2812_SPI_SCK_PIN
// TODO: more dynamic baudrate
static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR};

View File

@@ -51,6 +51,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//SPI
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
#define WS2812_EXTERNAL_PULLUP
// I2C OLED defines

17
keyboards/bop/bop.c Normal file
View File

@@ -0,0 +1,17 @@
/* Copyright 2021 Brandon Lewis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bop.h"

35
keyboards/bop/bop.h Normal file
View File

@@ -0,0 +1,35 @@
/* Copyright 2021 Brandon Lewis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#define LAYOUT( \
K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014, K015, K016, K017, K018, K019, \
K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117, K118, K119, \
K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214, K215, K216, K217, K218, K219, \
K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314, K315, K316, K317, K318, K319, \
K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K413, K414, K415, K416, K417, K418, K419, \
K500, K501, K502, K503, K504, K505, K506, K507, K508, K509, K510, K511, K512, K513, K514, K515, K516, K517, K518, K519 \
) { \
{ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014, K015, K016, K017, K018, K019 }, \
{ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117, K118, K119 }, \
{ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214, K215, K216, K217, K218, K219 }, \
{ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314, K315, K316, K317, K318, K319 }, \
{ K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K413, K414, K415, K416, K417, K418, K419 }, \
{ K500, K501, K502, K503, K504, K505, K506, K507, K508, K509, K510, K511, K512, K513, K514, K515, K516, K517, K518, K519 } \
}

49
keyboards/bop/config.h Normal file
View File

@@ -0,0 +1,49 @@
/* Copyright 2021 Brandon Lewis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0x666B // fk
#define PRODUCT_ID 0x626F // bo
#define DEVICE_VER 0x0001 // rev 1
#define MANUFACTURER fruitykeeb
#define PRODUCT bop
/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 20
/* key matrix pins */
#define MATRIX_ROW_PINS { B7, D0, D1, D2, D3, D4 }
#define MATRIX_COL_PINS { D5, C5, B0, B1, B2, B3, B4, B5, B6, E7, E6, F0, F7, F6, F5, F4, F3, F2, F1, C6 }
// If your board is spamming the end column, change C7 to C6 in the line above and short those pins on the controller
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* 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

138
keyboards/bop/info.json Normal file
View File

@@ -0,0 +1,138 @@
{
"keyboard_name": "bop",
"url": "https://github.com/blewis308/BOP-Keyboard",
"maintainer": "Fruit",
"width": 20.0,
"height": 6.0,
"layouts": {
"LAYOUT": {
"layout": [
{"x":0, "y":0},
{"x":1, "y":0},
{"x":2, "y":0},
{"x":3, "y":0},
{"x":4, "y":0},
{"x":5, "y":0},
{"x":6, "y":0},
{"x":7, "y":0},
{"x":8, "y":0},
{"x":9, "y":0},
{"x":10, "y":0},
{"x":11, "y":0},
{"x":12, "y":0},
{"x":13, "y":0},
{"x":14, "y":0},
{"x":15, "y":0},
{"x":16, "y":0},
{"x":17, "y":0},
{"x":18, "y":0},
{"x":19, "y":0},
{"x":0, "y":1},
{"x":1, "y":1},
{"x":2, "y":1},
{"x":3, "y":1},
{"x":4, "y":1},
{"x":5, "y":1},
{"x":6, "y":1},
{"x":7, "y":1},
{"x":8, "y":1},
{"x":9, "y":1},
{"x":10, "y":1},
{"x":11, "y":1},
{"x":12, "y":1},
{"x":13, "y":1},
{"x":14, "y":1},
{"x":15, "y":1},
{"x":16, "y":1},
{"x":17, "y":1},
{"x":18, "y":1},
{"x":19, "y":1},
{"x":0, "y":2},
{"x":1, "y":2},
{"x":2, "y":2},
{"x":3, "y":2},
{"x":4, "y":2},
{"x":5, "y":2},
{"x":6, "y":2},
{"x":7, "y":2},
{"x":8, "y":2},
{"x":9, "y":2},
{"x":10, "y":2},
{"x":11, "y":2},
{"x":12, "y":2},
{"x":13, "y":2},
{"x":14, "y":2},
{"x":15, "y":2},
{"x":16, "y":2},
{"x":17, "y":2},
{"x":18, "y":2},
{"x":19, "y":2},
{"x":0, "y":3},
{"x":1, "y":3},
{"x":2, "y":3},
{"x":3, "y":3},
{"x":4, "y":3},
{"x":5, "y":3},
{"x":6, "y":3},
{"x":7, "y":3},
{"x":8, "y":3},
{"x":9, "y":3},
{"x":10, "y":3},
{"x":11, "y":3},
{"x":12, "y":3},
{"x":13, "y":3},
{"x":14, "y":3},
{"x":15, "y":3},
{"x":16, "y":3},
{"x":17, "y":3},
{"x":18, "y":3},
{"x":19, "y":3},
{"x":0, "y":4},
{"x":1, "y":4},
{"x":2, "y":4},
{"x":3, "y":4},
{"x":4, "y":4},
{"x":5, "y":4},
{"x":6, "y":4},
{"x":7, "y":4},
{"x":8, "y":4},
{"x":9, "y":4},
{"x":10, "y":4},
{"x":11, "y":4},
{"x":12, "y":4},
{"x":13, "y":4},
{"x":14, "y":4},
{"x":15, "y":4},
{"x":16, "y":4},
{"x":17, "y":4},
{"x":18, "y":4},
{"x":19, "y":4},
{"x":0, "y":5},
{"x":1, "y":5},
{"x":2, "y":5},
{"x":3, "y":5},
{"x":4, "y":5},
{"x":5, "y":5},
{"x":6, "y":5},
{"x":7, "y":5},
{"x":8, "y":5},
{"x":9, "y":5},
{"x":10, "y":5},
{"x":11, "y":5},
{"x":12, "y":5},
{"x":13, "y":5},
{"x":14, "y":5},
{"x":15, "y":5},
{"x":16, "y":5},
{"x":17, "y":5},
{"x":18, "y":5},
{"x":19, "y":5}
]
}
}
}

View File

@@ -0,0 +1,46 @@
/* Copyright 2021 Brandon Lewis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(
/* For build guide: go to https://github.com/blewis308/BOP-Keyboard
* ,-----------------------------------------------------------------------------------------------------------------------.
* | F1 | F5 | F9 | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | _ | + | del | { | } | | |
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
* | F2 | F6 | F10 | esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |bkspc| home| end |pg up|
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
* | F3 | F7 | F11 | tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ | : | " |pg dn|
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
* | F4 | F8 | F12 |caplk| a | s | d | f | g | h | j | k | l | ; | ' |enter| | 7 | 8 | 9 |
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----| 0 |-----+-----+-----|
* |ptscr|scrlk|psbrk|shift| z | x | c | v | b | n | m | < | > | ? |shift| up | | 4 | 5 | 6 |
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
* | cut | copy|paste|Lctrl|L gui|L alt| space | n/a | space | , | . | / | left| down|right| 1 | 2 | 3 |
* `-----------------------------------------------------------------------------------------------------------------------'
*
* Notes: spaces and numpad 0 can be 1u instead of 2u also, this is already reflected in the keymap below
*/
KC_F1, KC_F5, KC_F9, KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_UNDS, KC_PLUS, KC_DEL, KC_LCBR, KC_RCBR, KC_PIPE,
KC_F2, KC_F6, KC_F10, KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME, KC_END, KC_PGUP,
KC_F3, KC_F7, KC_F11, 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_COLN, KC_DQUO, KC_PGDN,
KC_F4, KC_F8, KC_F12, 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_0, KC_7, KC_8, KC_9,
KC_PSCR, KC_SLCK, KC_PAUS, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_LABK, KC_RABK, KC_QUES, KC_RSFT, KC_UP, KC_0, KC_4, KC_5, KC_6,
LCTL(KC_X), LCTL(KC_C), LCTL(KC_V), KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_NO, KC_SPC, KC_SPC, KC_COMM, KC_DOT, KC_SLSH, KC_LEFT, KC_DOWN, KC_RGHT, KC_1, KC_2, KC_3 )
};

16
keyboards/bop/readme.md Normal file
View File

@@ -0,0 +1,16 @@
# bop
![Bop](https://i.imgur.com/mEWmMgvh.jpg)
![Bop-top](https://i.imgur.com/DbjVdvVh.jpg)
A huge 6x20 ortholinear keyboard inspired by the BFO-9000
* Keyboard Maintainer: [Fruit](https://github.com/Blewis308)
* Hardware Supported: Bop v1.1 PCB, Teensy 2.0++
* Hardware Availablility: Through Group Buy - Jan 2021
Make example for this keyboard (after setting up your build envionment):
make bop: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).

23
keyboards/bop/rules.mk Normal file
View File

@@ -0,0 +1,23 @@
# MCU name
MCU = at90usb1286
# Bootloader selection
BOOTLOADER = halfkay
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
SWAP_HANDS_ENABLE = no

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 14
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -50,6 +50,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGB_DI_PIN B15
#define RGBLED_NUM 22
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -55,6 +55,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGB_DI_PIN B15
#define RGBLED_NUM 20
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 20
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 14
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 20
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 20
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*

View File

@@ -60,6 +60,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 8
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
#define DYNAMIC_KEYMAP_LAYER_COUNT 2

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 20
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 22
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*
* Feature disable options

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 20
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/*

View File

@@ -1,2 +1,4 @@
RGB_MATRIX_ENABLE = yes # Enable RGB matrix
RGB_MATRIX_DRIVER = WS2812 # Set Driver to WS2812
LTO_ENABLE = yes

View File

@@ -1,2 +1,4 @@
RGB_MATRIX_ENABLE = yes # Enable RGB matrix
RGB_MATRIX_DRIVER = WS2812 # Set Driver to WS2812
LTO_ENABLE = yes

View File

@@ -0,0 +1,20 @@
/* Copyright 2021 James Young (@noroadsleft)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define ANSI_NUBS_ROW 3
#define ANSI_NUBS_COL 2

View File

@@ -54,10 +54,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
[_FN] = LAYOUT_65_ansi(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_PSCR,
_______, KC_CALC, KC_APP, _______, _______, _______, KC_INS, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_PSCR, KC_SLCK, KC_PAUS, _______,
_______, M_SALL, _______, _______, _______, _______, KC_DEL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, _______, _______, _______,
_______, M_UNDO, M_CUT, M_COPY, M_PASTE, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, TO(_SY), _______, _______, _______,
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, DM_REC1,
_______, KC_CALC, KC_APP, _______, _______, _______, KC_INS, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_PSCR, KC_SLCK, KC_PAUS, DM_REC2,
_______, M_SALL, _______, _______, _______, _______, KC_DEL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, _______, DM_RSTP, DM_PLY1,
_______, M_UNDO, M_CUT, M_COPY, M_PASTE, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, TO(_SY), _______, _______, DM_PLY2,
_______, _______, _______, TG(_NP), _______, _______, _______, _______, _______, _______
),

View File

@@ -0,0 +1 @@
DYNAMIC_MACRO_ENABLE = yes

View File

@@ -0,0 +1,51 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* Directional arrangement | LAYOUT_directional
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │ 0e │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │10 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
* │20 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │
* ├──────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬───┬───┤
* │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │
* ├────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴───┼───┼───┼───┼───┼───┤
* │40 │41 │43 │ 46 │4a │4b │4c │4d │4e │
* └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┘
*/
#define LAYOUT_directional_nosplitspace( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0e, \
k10, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, \
k20, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, \
k30, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, \
k40, k41, k43, k46, k4a, k4b, k4c, k4d, k4e \
) { \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, KC_NO,k0e }, \
{ k10, KC_NO, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e }, \
{ k20, KC_NO, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, KC_NO }, \
{ k30, KC_NO, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e }, \
{ k40, k41, KC_NO, k43, KC_NO,KC_NO, k46, KC_NO, KC_NO,KC_NO, k4a, k4b, k4c, k4d, k4e } \
}
#define AUTO_SHIFT_TIMEOUT 160
#define RGBLIGHT_LAYERS
#define LEADER_TIMEOUT 400
#define LEADER_PER_KEY_TIMING

View File

@@ -0,0 +1,279 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jdelkins.h"
#undef LAYOUT
#define LAYOUT LAYOUT_directional_nosplitspace
#define IDLE_TIMEOUT 360
uint16_t rgb_idle_seconds = 0;
uint16_t rgb_timer;
bool rgb_was_enabled;
// Tap Dance
int ctl_state = 0;
void ctl_finished(qk_tap_dance_state_t *state, void *user_data) {
ctl_state = cur_dance(state);
switch(ctl_state) {
case SINGLE_TAP: qk_leader_start(); break;
case SINGLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_TAP: tap_code(KC_RCTL); break;
case DOUBLE_HOLD: register_code(KC_RCTL); break;
case TRIPLE_TAP: tap_code(KC_RCTL); tap_code(KC_RCTL); break;
case TRIPLE_HOLD: tap_code(KC_RCTL); register_code(KC_RCTL); break;
}
}
void ctl_reset(qk_tap_dance_state_t *state, void *user_data) {
switch(ctl_state) {
case SINGLE_HOLD: unregister_code(KC_LCTL); break;
case DOUBLE_HOLD:
case TRIPLE_HOLD: unregister_code(KC_RCTL); break;
}
ctl_state = 0;
}
void g_finished(qk_tap_dance_state_t *state, void *user_data) {
switch (cur_dance(state)) {
case SINGLE_TAP:
tap_code16(C(KC_END));
break;
case DOUBLE_TAP:
tap_code16(C(KC_HOME));
break;
}
}
enum {
TD_LDCTL,
TD_G,
};
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LDCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ctl_finished, ctl_reset),
[TD_G] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, g_finished, NULL),
};
// Layers
const uint16_t PROGMEM keymaps[_LAYER_MAX][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT(
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_BSPC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,
MY_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_BSPC, MO(_ADJUST),
TD(TD_LDCTL), MY_GUI, MY_ALT, MY_SPC, KC_RALT, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
),
[_GAME] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
KC_LCTL, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, KC_LALT, KC_SPC, _______, _______, _______, _______, _______
),
[_FUNC] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL,
_______, _______, FW_WRD, KB_EOL, _______, _______, KB_COPY, KC_PGUP, _______, _______, KB_PASTE, KC_SLCK, _______, MY_CALC,
_______, KB_BOL, _______, KC_PGDN, _______, TD(TD_G), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______,
_______, _______, KC_DEL, _______, _______, BK_WRD, _______, _______, _______, _______, _______, _______, KC_INS, _______,
_______, MY_RGUI, MY_RALT, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
),
[_KP] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, KC_KP_ASTERISK, _______, _______, _______, _______, _______,
KC_NUMLOCK, _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, _______, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_MINUS, _______, _______, _______,
_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D, _______, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, _______, _______,
_______, _______, _______, _______, _______, _______, _______, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_SLASH, _______, _______, TG(_KP),
_______, _______, _______, KC_KP_0, KC_KP_DOT, _______, _______, _______, _______
),
[_ADJUST] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL,
_______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, _______, _______, KC_PSCR, KC_SLCK, _______, KC_MUTE,
_______, RGB_RMOD, RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, TG(_KP), _______, _______, _______, KC_MPLY,
_______, RGB_TOG, KB_MAKE, KB_FLSH, KB_VRSN, KB_BOOT, _______, TG_SYS, _______, _______, _______, _______, KC_DEL, _______,
_______, MY_RGUI, MY_RALT, _______, _______, KC_MPRV, KC_VOLD, KC_VOLU, KC_MNXT
),
};
const rgblight_segment_t PROGMEM game_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 1, HSV_RED},
{7, 2, HSV_RED},
{15, 1, HSV_RED}
);
const rgblight_segment_t PROGMEM func_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 8, HSV_GREEN}
);
const rgblight_segment_t PROGMEM kp_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 16, HSV_ORANGE}
);
const rgblight_segment_t PROGMEM adjust_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 16, HSV_BLUE}
);
const rgblight_segment_t PROGMEM capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{10, 4, HSV_WHITE}
);
const rgblight_segment_t PROGMEM numlock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 2, HSV_PURPLE},
{14, 2, HSV_PURPLE}
);
enum rgb_layer_index {
L_GAME,
L_FUNC,
L_KP,
L_ADJUST,
L_CAPSLOCK,
L_NUMLOCK,
};
const rgblight_segment_t * const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
[L_GAME] = game_layer,
[L_FUNC] = func_layer,
[L_KP] = kp_layer,
[L_ADJUST] = adjust_layer,
[L_CAPSLOCK] = capslock_layer,
[L_NUMLOCK] = numlock_layer
);
layer_state_t layer_state_set_keymap(layer_state_t state) {
rgblight_set_layer_state(L_GAME, layer_state_cmp(state, _GAME));
rgblight_set_layer_state(L_FUNC, layer_state_cmp(state, _FUNC));
rgblight_set_layer_state(L_KP, layer_state_cmp(state, _KP));
rgblight_set_layer_state(L_ADJUST, layer_state_cmp(state, _ADJUST));
rgblight_set_layer_state(L_CAPSLOCK, CAPSLOCK_ON);
rgblight_set_layer_state(L_NUMLOCK, NUMLOCK_ON && layer_state_cmp(state, _KP));
if (layer_state_cmp(state, _GAME))
autoshift_disable();
else
autoshift_enable();
return state;
}
bool led_update_user(led_t led_state) {
rgblight_set_layer_state(L_CAPSLOCK, led_state.caps_lock);
rgblight_set_layer_state(L_NUMLOCK, led_state.num_lock && layer_state_is(_KP));
return true;
}
void keyboard_post_init_keymap(void) {
rgblight_layers = my_rgb_layers;
rgb_was_enabled = rgblight_is_enabled();
}
LEADER_EXTERNS();
void matrix_scan_keymap(void) {
if (rgblight_is_enabled() && timer_elapsed(rgb_timer) > 1000) {
rgb_idle_seconds++;
rgb_timer = timer_read();
}
if (rgb_idle_seconds > IDLE_TIMEOUT) {
rgb_was_enabled = rgblight_is_enabled();
rgblight_disable_noeeprom();
rgb_idle_seconds = 0;
}
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_K) {
layer_invert(_KP);
}
SEQ_ONE_KEY(KC_G) {
layer_invert(_GAME);
}
SEQ_ONE_KEY(KC_KP_5) {
layer_invert(_KP);
}
SEQ_TWO_KEYS(KC_SCLN, KC_1) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_2) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_3) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_4) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_5) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_6) {
send_secret_string(5);
}
SEQ_TWO_KEYS(KC_SCLN, KC_M) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_COMM) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_DOT) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_J) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_K) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_L) {
send_secret_string(5);
}
SEQ_ONE_KEY(KC_C) {
tap_code16(C(KC_C));
}
}
}
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
static uint16_t gesc_timer;
rgb_idle_seconds = 0;
if (!rgblight_is_enabled() && rgb_was_enabled)
rgblight_enable_noeeprom();
switch (keycode) {
// custom handle KC_GESC to emulate auto shift on it
case KC_GESC:
if (get_autoshift_state()) {
if (record->event.pressed)
gesc_timer = timer_read();
else {
if (timer_elapsed(gesc_timer) > AUTO_SHIFT_TIMEOUT || MODS_SHIFT) {
tap_code16(S(KC_GRV));
} else if (MODS_GUI)
tap_code(KC_GRV);
else
tap_code(KC_ESC);
}
return false;
}
return false;
}
return true;
}

View File

@@ -0,0 +1,7 @@
LEADER_ENABLE = yes
MOUSEKEY_ENABLE = yes
CONSOLE_ENABLE = no
NKRO_ENABLE = no
TAP_DANCE_ENABLE = yes
LTO_ENABLE = yes
AUTO_SHIFT_ENABLE = yes

View File

@@ -0,0 +1,51 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* My hhkb variant
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
* │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │0e │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤
* │10 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
* │20 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤
* │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3d │3e │
* ├────┬───┴┬──┴─┬─┴───┴──┬┴───┼───┴───┴──┬┴──┬┴──┬┴──┬───┼───┤
* │40 │41 │43 │44 │46 │48 │4a │4b │4c │4d │4e │
* └────┴────┴────┴────────┴────┴──────────┴───┴───┴───┴───┴───┘
*/
#define LAYOUT_hhkb_split( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k0e, \
k10, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, \
k20, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, \
k30, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3d, k3e, \
k40, k41, k43, k44, k46, k48, k4a, k4b, k4c, k4d, k4e \
) { \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k0e }, \
{ k10, KC_NO, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e }, \
{ k20, KC_NO, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, KC_NO }, \
{ k30, KC_NO, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, KC_NO, k3d, k3e }, \
{ k40, k41, KC_NO, k43, k44, KC_NO, k46, KC_NO, k48, KC_NO, k4a, k4b, k4c, k4d, k4e } \
}
#define AUTO_SHIFT_TIMEOUT 165
#define RGBLIGHT_LAYERS
#define LEADER_TIMEOUT 400
#define LEADER_PER_KEY_TIMING

View File

@@ -0,0 +1,367 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jdelkins.h"
#undef LAYOUT
#define LAYOUT LAYOUT_hhkb_split
#define IDLE_TIMEOUT 360
uint16_t rgb_idle_seconds = 0;
uint16_t rgb_timer;
uint16_t bspc_timer;
bool rgb_was_enabled;
enum {
MY_BSPC = USER_SAFE_RANGE,
};
// Tap Dance
int ctl_state = 0;
void ctl_finished(qk_tap_dance_state_t *state, void *user_data) {
ctl_state = cur_dance(state);
switch (ctl_state) {
case SINGLE_TAP: qk_leader_start(); break;
case SINGLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_TAP: tap_code(KC_RCTL); break;
case DOUBLE_HOLD: register_code(KC_RCTL); break;
case TRIPLE_TAP: tap_code(KC_RCTL); tap_code(KC_RCTL); break;
case TRIPLE_HOLD: tap_code(KC_RCTL); register_code(KC_RCTL); break;
}
}
void ctl_reset(qk_tap_dance_state_t *state, void *user_data) {
switch (ctl_state) {
case SINGLE_HOLD: unregister_code(KC_LCTL); break;
case DOUBLE_HOLD:
case TRIPLE_HOLD: unregister_code(KC_RCTL); break;
}
ctl_state = 0;
}
void g_finished(qk_tap_dance_state_t *state, void *user_data) {
switch (cur_dance(state)) {
case SINGLE_TAP:
tap_code16(C(KC_END));
break;
case DOUBLE_TAP:
tap_code16(C(KC_HOME));
break;
}
}
int kp_state = 0;
void kp_finished(qk_tap_dance_state_t *state, void *user_data) {
kp_state = hold_cur_dance(state);
switch (kp_state) {
case SINGLE_TAP:
tap_code(KC_SPC);
break;
default:
layer_invert(_KP);
break;
}
}
void kp_reset(qk_tap_dance_state_t *state, void *user_data) {
switch (kp_state) {
case SINGLE_HOLD:
case DOUBLE_HOLD:
case TRIPLE_HOLD:
layer_invert(_KP);
break;
}
}
enum {
TD_LDCTL,
TD_G,
TD_KP,
};
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LDCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ctl_finished, ctl_reset),
[TD_G] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, g_finished, NULL),
[TD_KP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, kp_finished, kp_reset),
};
// Layers
const uint16_t PROGMEM keymaps[_LAYER_MAX][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_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_BSLS,
MY_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_ADJUST),
TD(TD_LDCTL), MY_GUI, MY_ALT, MY_BSPC, TD(TD_KP), MY_SPC, KC_RALT, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT
),
[_RPT] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
[_GAME] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
KC_LCTL, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, KC_LALT, KC_SPC, KC_LALT, _______, _______, _______, _______, _______, _______
),
[_FUNC] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_F13,
_______, _______, FW_WRD, KB_EOL, TG(_RPT), _______, KB_COPY, KC_PGUP, _______, _______, KB_PASTE, KC_SLCK, _______, MY_CALC,
_______, KB_BOL, _______, KC_PGDN, _______, TD(TD_G), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______,
_______, _______, KC_DEL, _______, _______, BK_WRD, _______, _______, _______, _______, _______, _______, KC_NO,
_______, MY_RGUI, MY_RALT, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
),
[_KP] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, KC_KP_ASTERISK, _______, _______, _______, _______, _______, _______,
KC_NUMLOCK, _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, _______, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_MINUS, _______, _______, _______,
_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D, _______, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, _______, _______,
_______, _______, _______, _______, _______, _______, _______, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_SLASH, _______, TG(_KP),
_______, _______, _______, _______, _______, KC_KP_0, KC_KP_DOT, _______, _______, _______, _______
),
[_ADJUST] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_F13,
_______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, _______, _______, KC_PSCR, KC_SLCK, _______, KC_MUTE,
_______, RGB_RMOD, RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, TG(_KP), _______, _______, _______, KC_MPLY,
_______, RGB_TOG, KB_MAKE, KB_FLSH, KB_VRSN, KB_BOOT, _______, TG_SYS, _______, _______, _______, _______, _______,
_______, MY_RGUI, MY_RALT, KC_DEL, _______, _______, _______, KC_MPRV, KC_VOLD, KC_VOLU, KC_MNXT
),
};
const rgblight_segment_t PROGMEM rpt_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{8, 8, HSV_PINK}
);
const rgblight_segment_t PROGMEM game_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 1, HSV_RED},
{7, 2, HSV_RED},
{15, 1, HSV_RED}
);
const rgblight_segment_t PROGMEM func_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 8, HSV_GREEN}
);
const rgblight_segment_t PROGMEM kp_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 16, HSV_ORANGE}
);
const rgblight_segment_t PROGMEM adjust_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 16, HSV_BLUE}
);
const rgblight_segment_t PROGMEM capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{10, 4, HSV_WHITE}
);
const rgblight_segment_t PROGMEM numlock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
{0, 2, HSV_PURPLE},
{14, 2, HSV_PURPLE}
);
enum rgb_layer_index {
L_RPT,
L_GAME,
L_FUNC,
L_KP,
L_ADJUST,
L_CAPSLOCK,
L_NUMLOCK,
};
const rgblight_segment_t * const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
[L_RPT] = rpt_layer,
[L_GAME] = game_layer,
[L_FUNC] = func_layer,
[L_KP] = kp_layer,
[L_ADJUST] = adjust_layer,
[L_CAPSLOCK] = capslock_layer,
[L_NUMLOCK] = numlock_layer
);
layer_state_t layer_state_set_keymap(layer_state_t state) {
rgblight_set_layer_state(L_RPT, layer_state_cmp(state, _RPT));
rgblight_set_layer_state(L_GAME, layer_state_cmp(state, _GAME));
rgblight_set_layer_state(L_FUNC, layer_state_cmp(state, _FUNC));
rgblight_set_layer_state(L_KP, layer_state_cmp(state, _KP));
rgblight_set_layer_state(L_ADJUST, layer_state_cmp(state, _ADJUST));
rgblight_set_layer_state(L_CAPSLOCK, CAPSLOCK_ON);
rgblight_set_layer_state(L_NUMLOCK, NUMLOCK_ON && layer_state_cmp(state, _KP));
if (layer_state_cmp(state, _GAME) || layer_state_cmp(state, _RPT))
autoshift_disable();
else
autoshift_enable();
return state;
}
bool led_update_user(led_t led_state) {
rgblight_set_layer_state(L_CAPSLOCK, led_state.caps_lock);
rgblight_set_layer_state(L_NUMLOCK, led_state.num_lock && layer_state_is(_KP));
return true;
}
void keyboard_post_init_keymap(void) {
rgblight_layers = my_rgb_layers;
rgb_was_enabled = rgblight_is_enabled();
bspc_timer = 0;
}
LEADER_EXTERNS();
void matrix_scan_keymap(void) {
if (rgblight_is_enabled() && timer_elapsed(rgb_timer) > 1000) {
rgb_idle_seconds++;
rgb_timer = timer_read();
}
if (rgb_idle_seconds > IDLE_TIMEOUT) {
rgb_was_enabled = rgblight_is_enabled();
rgblight_disable_noeeprom();
rgb_idle_seconds = 0;
}
// if MY_BSPC is held down too long, pretend like it wasn't and start
// pressing backspace
if (bspc_timer > 0 && timer_elapsed(bspc_timer) > LEADER_TIMEOUT) {
layer_off(_FUNC);
bspc_timer = 0;
register_code(KC_BSPC);
}
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_R) {
layer_invert(_RPT);
}
SEQ_ONE_KEY(KC_G) {
layer_invert(_GAME);
}
SEQ_ONE_KEY(KC_K) {
layer_invert(_KP);
}
SEQ_ONE_KEY(KC_KP_5) {
layer_invert(_KP);
}
SEQ_TWO_KEYS(KC_SCLN, KC_1) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_2) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_3) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_4) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_5) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_6) {
send_secret_string(5);
}
SEQ_TWO_KEYS(KC_SCLN, KC_M) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_COMM) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_DOT) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_J) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_K) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_L) {
send_secret_string(5);
}
SEQ_ONE_KEY(KC_C) {
tap_code16(C(KC_C));
}
}
}
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
static bool bspc_del = false;
static bool bspc_initiated_func = false;
bool rc = true;
rgb_idle_seconds = 0;
if (!rgblight_is_enabled() && rgb_was_enabled)
rgblight_enable_noeeprom();
switch (keycode) {
case MY_BSPC:
if (record->event.pressed) {
if (IS_LAYER_ON(_FUNC)) {
// special case: if _FUNC was turned on by another key,
// treat this as KC_DEL and don't do anything else
bspc_del = true;
register_code(KC_DEL);
return false;
} else {
bspc_timer = timer_read();
bspc_initiated_func = true;
layer_on(_FUNC);
}
} else {
if (bspc_del) {
// special case: if _FUNC was turned on by another key,
// treat this as KC_DEL and don't do anything else
unregister_code(KC_DEL);
bspc_del = false;
return false;
}
if (bspc_initiated_func) {
layer_off(_FUNC);
bspc_initiated_func = false;
}
if (bspc_timer > 0) {
// here the key was pressed and released before the timer
// expired, so treat as a backspace tap and pretend we
// never activated _FUNC
bspc_timer = 0;
tap_code(KC_BSPC);
} else {
// the timer went off, so KC_BSPC was registered in
// matrix_scan_keymap. unregister it now
unregister_code(KC_BSPC);
}
}
return false; // special case, return now without resetting timer
// other paths should set rc and break
break;
}
// if something was pressed while MY_BSPC was held down, keep it pressed by
// disabling the timer
bspc_timer = 0;
return rc;
}

View File

@@ -0,0 +1,8 @@
LEADER_ENABLE = yes
MOUSEKEY_ENABLE = yes
CONSOLE_ENABLE = no
NKRO_ENABLE = no
TAP_DANCE_ENABLE = yes
AUTO_SHIFT_ENABLE = yes
LTO_ENABLE = yes
USER_NAME := jdelkins

View File

@@ -45,7 +45,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______
),
@@ -53,7 +53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______
)

View File

@@ -0,0 +1,59 @@
/*
Copyright 2021 stevendlander
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x0000
#define DEVICE_VER 0x0001
#define MANUFACTURER stevendlander
#define PRODUCT Unicomp Mini M
/* key matrix size */
#define MATRIX_ROWS 12
#define MATRIX_COLS 16
/*
* 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 { F7, F6, F5, F4, F3, F2, F1, F0, E6, E7, B0, B1 }
#define MATRIX_COL_PINS { C7, C6, C5, C4, C3, C2, C1, C0, E1, E0, D7, B7, D5, D4, D3, D2 }
#define UNUSED_PINS
#define LED_PIN_ON_STATE 0
#define LED_NUM_LOCK_PIN B6
#define LED_CAPS_LOCK_PIN B5
#define LED_SCROLL_LOCK_PIN B4
/* COL2ROW, ROW2COL*/
#define DIODE_DIRECTION ROW2COL
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed (5 is default) */
#define DEBOUNCE 5
/* The Mini M has no diodes */
#define MATRIX_HAS_GHOST

View File

@@ -0,0 +1,462 @@
{
"keyboard_name": "Unicomp Mini M",
"url": "",
"maintainer": "stevendlander",
"width": 15.5,
"height": 7.5,
"layouts": {
"LAYOUT": {
"layout": [
{ "label": "Esc",
"x": 0,
"y": 0
},
{
"label": "F1",
"x": 2,
"y": 0
},
{
"label": "F2",
"x": 3,
"y": 0
},
{
"label": "F3",
"x": 4,
"y": 0
},
{
"label": "F4",
"x": 5,
"y": 0
},
{
"label": "F5",
"x": 6.5,
"y": 0
},
{
"label": "F6",
"x": 7.5,
"y": 0
},
{
"label": "F7",
"x": 8.5,
"y": 0
},
{
"label": "F8",
"x": 9.5,
"y": 0
},
{
"label": "F9",
"x": 11,
"y": 0
},
{
"label": "F10",
"x": 12,
"y": 0
},
{
"label": "F11",
"x": 13,
"y": 0
},
{
"label": "F12",
"x": 14,
"y": 0
},
{
"label": "PrtSc",
"x": 15.25,
"y": 0
},
{
"label": "Scroll Lock",
"x": 16.25,
"y": 0
},
{
"label": "Pause",
"x": 17.25,
"y": 0
},
{
"label": "~",
"x": 0,
"y": 1.5
},
{
"label": "!",
"x": 1,
"y": 1.5
},
{
"label": "@",
"x": 2,
"y": 1.5
},
{
"label": "#",
"x": 3,
"y": 1.5
},
{
"label": "$",
"x": 4,
"y": 1.5
},
{
"label": "%",
"x": 5,
"y": 1.5
},
{
"label": "^",
"x": 6,
"y": 1.5
},
{
"label": "&",
"x": 7,
"y": 1.5
},
{
"label": "*",
"x": 8,
"y": 1.5
},
{
"label": "(",
"x": 9,
"y": 1.5
},
{
"label": ")",
"x": 10,
"y": 1.5
},
{
"label": "_",
"x": 11,
"y": 1.5
},
{
"label": "+",
"x": 12,
"y": 1.5
},
{
"label": "Backspace",
"x": 13,
"y": 1.5,
"w": 2
},
{
"label": "Insert",
"x": 15.25,
"y": 1.5
},
{
"label": "Home",
"x": 16.25,
"y": 1.5
},
{
"label": "PgUp",
"x": 17.25,
"y": 1.5
},
{
"label": "Tab",
"x": 0,
"y": 2.5,
"w": 1.5
},
{
"label": "Q",
"x": 1.5,
"y": 2.5
},
{
"label": "W",
"x": 2.5,
"y": 2.5
},
{
"label": "E",
"x": 3.5,
"y": 2.5
},
{
"label": "R",
"x": 4.5,
"y": 2.5
},
{
"label": "T",
"x": 5.5,
"y": 2.5
},
{
"label": "Y",
"x": 6.5,
"y": 2.5
},
{
"label": "U",
"x": 7.5,
"y": 2.5
},
{
"label": "I",
"x": 8.5,
"y": 2.5
},
{
"label": "O",
"x": 9.5,
"y": 2.5
},
{
"label": "P",
"x": 10.5,
"y": 2.5
},
{
"label": "{",
"x": 11.5,
"y": 2.5
},
{
"label": "}",
"x": 12.5,
"y": 2.5
},
{
"label": "|",
"x": 13.5,
"y": 2.5,
"w": 1.5
},
{
"label": "Delete",
"x": 15.25,
"y": 2.5
},
{
"label": "End",
"x": 16.25,
"y": 2.5
},
{
"label": "PgDn",
"x": 17.25,
"y": 2.5
},
{
"label": "Caps Lock",
"x": 0,
"y": 3.5,
"w": 1.75
},
{
"label": "A",
"x": 1.75,
"y": 3.5
},
{
"label": "S",
"x": 2.75,
"y": 3.5
},
{
"label": "D",
"x": 3.75,
"y": 3.5
},
{
"label": "F",
"x": 4.75,
"y": 3.5
},
{
"label": "G",
"x": 5.75,
"y": 3.5
},
{
"label": "H",
"x": 6.75,
"y": 3.5
},
{
"label": "J",
"x": 7.75,
"y": 3.5
},
{
"label": "K",
"x": 8.75,
"y": 3.5
},
{
"label": "L",
"x": 9.75,
"y": 3.5
},
{
"label": ":",
"x": 10.75,
"y": 3.5
},
{
"label": "\"",
"x": 11.75,
"y": 3.5
},
{
"label": "Enter",
"x": 12.75,
"y": 3.5,
"w": 2.25
},
{
"label": "Shift",
"x": 0,
"y": 4.5,
"w": 2.25
},
{
"label": "Z",
"x": 2.25,
"y": 4.5
},
{
"label": "X",
"x": 3.25,
"y": 4.5
},
{
"label": "C",
"x": 4.25,
"y": 4.5
},
{
"label": "V",
"x": 5.25,
"y": 4.5
},
{
"label": "B",
"x": 6.25,
"y": 4.5
},
{
"label": "N",
"x": 7.25,
"y": 4.5
},
{
"label": "M",
"x": 8.25,
"y": 4.5
},
{
"label": "<",
"x": 9.25,
"y": 4.5
},
{
"label": ">",
"x": 10.25,
"y": 4.5
},
{
"label": "?",
"x": 11.25,
"y": 4.5
},
{
"label": "Shift",
"x": 12.25,
"y": 4.5,
"w": 2.75
},
{
"label": "\u2191",
"x": 16.25,
"y": 4.5
},
{
"label": "Ctrl",
"x": 0,
"y": 5.5,
"w": 1.5
},
{
"label": "Meta",
"x": 1.5,
"y": 5.5,
"w": 1
},
{
"label": "Alt",
"x": 2.5,
"y": 5.5,
"w": 1.5
},
{
"label": "Space",
"x": 4,
"y": 5.5,
"w": 5.75
},
{
"label": "Alt",
"x": 9.75,
"y": 5.5,
"w": 1.25
},
{
"label": "Meta",
"x": 11,
"y": 5.5,
"w": 1.5
},
{
"label": "Menu",
"x": 12.5,
"y": 5.5,
"w": 1
},
{
"label": "Ctrl",
"x": 13.5,
"y": 5.5,
"w": 1.5
},
{
"label": "\u2190",
"x": 15.25,
"y": 5.5
},
{
"label": "\u2193",
"x": 16.25,
"y": 5.5
},
{
"label": "\u2192",
"x": 17.25,
"y": 5.5
}
]
}
}
}

View File

@@ -0,0 +1,106 @@
/* Copyright 2021 stevendlander
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
// Layer shortcuts
enum custom_layers {
_QWERTY,
_NUMPAD,
};
enum custom_keycodes {
NUMSLCK = SAFE_RANGE, // Num Lock on shift, Scroll Lock regularly
PAUSRST, // Resets keyboard on shift, Pause|break regularly
PSCSYSR, // Sends SYSREQ on alt, Print Screen regularly
};
// Mod key detection
#define MODS_SHIFT_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
#define MODS_ALT_MASK (MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT(
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, PSCSYSR, NUMSLCK, PAUSRST,
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_NO, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, 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_NO, KC_ENT,
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_NO, KC_RSFT, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[_NUMPAD] = LAYOUT(
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, NUMSLCK, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_P7, KC_P8, KC_P9, KC_TRNS, KC_PMNS, KC_PPLS, 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_P4, KC_P5, KC_P6, 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_P1, KC_P2, KC_P3, KC_PAST, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_P0, KC_TRNS, KC_PDOT, KC_PSLS, 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 NUMSLCK: {
if (record->event.pressed) {
if (keyboard_report->mods & MODS_SHIFT_MASK) {
tap_code(KC_NLCK);
} else {
register_code(KC_SLCK);
}
} else {
unregister_code(KC_SLCK);
}
break;
}
case PAUSRST: {
if (record->event.pressed) {
if (keyboard_report->mods & MODS_SHIFT_MASK) {
reset_keyboard();
} else {
register_code(KC_PAUS);
}
} else {
unregister_code(KC_PAUS);
}
break;
}
case PSCSYSR: {
if (record->event.pressed) {
if (keyboard_report->mods & MODS_ALT_MASK) {
tap_code(KC_SYSREQ);
} else {
register_code(KC_PAUS);
}
} else {
unregister_code(KC_PAUS);
}
break;
}
}
return true;
}
bool led_update_user(led_t led_state) {
static bool num_state = false;
if (num_state != led_state.num_lock) {
if (led_state.num_lock) {
layer_on(_NUMPAD);
} else {
layer_off(_NUMPAD);
}
num_state = led_state.num_lock;
}
return true;
}

View File

@@ -0,0 +1 @@
# The default keymap for unicomp\_mini\_m

View File

@@ -0,0 +1,127 @@
## Unicomp Mini M with Teensy2.0++ controller & QMK Firmware
### Overview
#### Goals
The goal of this project was to replace the stock control board of the Unicomp Mini M with a programmable one. The Mini
M was released by [Unicomp](https://www.pckeyboard.com) in Q1 of 2021 and is a re-release of The IBM Model M Space
Saving Keyboard (SSK) with some enhancements.
This guide strives to achieve the following:
* Make completely reversable changes, or in other words, no permanent modifications to the Mini M
* Allow full programmability of the Mini M via QMK
* Be able to flash firmware without having to take the board apart to hit the reset button
* Create a default keymap that works just like the stock keymap shipped from Unicomp, including the toggle-able number
pad
* Support all LEDs as normal
My guide will go a few steps further:
* Convert the wired connection from USB-A to USB-C
* Install a potentiometer to dim the LEDs if desired
#### Credits
The following resources were instrumental to the success of this project:
* Model M 101/102 write-up located in `qmk_firmware/keyboards/converter/modelm`
* [Model M Subreddit](https://modelm.reddit.com)
* Model M Discord
### Hardware
##### Parts
For a working Mini M with QMK *without* LEDs working, the following parts are necessary:
* 1 Adafruit Perma-Proto Full Sized Breadboard. Luckily, this board is a perfect fit for the Mini M case!
* 1 Teensy2.0++, with headers soldered on if you can find it
* 2 20-row x 1 column headers, if you can't find a Teensy with headers already soldered on
* 2 16-pin Ribbon connectors, PCB mount
* Hookup wire. I used 30AWG wire and while it worked, I should have used 1 gauge (or more) thicker
* A panel mount male USB-B to female USB-C extender
To get the Mini M working with LEDs, you will need:
* 3 1kOhm through-hole resistors
##### Tools
The following were absolutely critical for the project:
* Soldering iron, preferably one with a narrow tip for small connections
* Drill, preferably a hand-held rotary tool (such as a Dremel)
* Wire strippers/cutters
* A sharp knife
Optional, but worth having around:
* Helping-hands, PCB holder, preferably both
* Multi-meter for testing continuity of your connections
* Hot-glue gun for mounting the USB extender to the Perma-Proto
### Assembly
#### Solder Teensy to the Perma-Proto
1. Solder headers to Teensy
2. Solder headers to Perma-Proto
#### Solder ribbon connectors
* Rows on the Perma-Proto that line up with membrane ribbons
* Trim excess under board
* Test continuity
#### Solder in hookup wires
* Ribbon connector used for the right ribbon will need hookup wire to establish connections to the Teensy
* 12 required, 16 if you want full functionality
#### Optional: Solder in resistors
#### Caveat: D6 pin on the Teensy
There are a few ways to mount the Teensy to the Perma-Proto board. I chose to connect my 16 pin ribbon connector to the
Teensy pins starting at C7 and ending at D2. If you do this, beware that pin D6 will not work for the purposes of this
project. It is possible to modify it to make it so, but that is beyond the scope of this guide.
Bypassing D6 is necessary if you mount your ribbon connector as I have just described. Luckily, it is a simple process!
First, with a sharp knife, sever the connection between your ribbon connector pin that is connected to Teensy D6 pin. I
would recommend doing this at the closest possible point to the Teensy on the underside of the Perma-Proto board. Once
that is done, use a remaining point on the Perma-Proto bus for that ribbon connection (that was previously connected to
D6) to add a jumper wire connected to pin B7. If you are using the firmware files provided in this repository,
everything is already set for this configuration.
### Testing
### Software
#### Build firmware
See qmk documentation on getting your build environment working.
Compile the Mini M firmware files with the default keymap. It allows for the Mini M to be used with the same
functionality as shipped from the manufacturer.
```bash
$ qmk compile -kb unicomp/mini_m -km default
```
While plugged in, press the reset button on your Teensy and then:
```bash
$ qmk flash -kb unicomp/mini_m -km default
```
If everything works to this point, congratulations! You now have a programmable Mini M. If you are using the default
keymap, you can reset your Teensy by pressing Shift+Pause together, eliminating the need to take apart the case in order
to do so.
#### Keymaps
To build your own keymap, create a new directory in `keyboards/unicomp/mini_m/keymaps/<your name>`, copy the files from
`keyboards/unicomp/mini_m/default` into your new directory, and edit them as you wish. When you are ready to flash your
new keymap to the Mini M, the command will be `qmk flash -kb unicomp/mini_m -kb <your name>`.

View File

@@ -0,0 +1,22 @@
# MCU name
MCU = at90usb1286
# Bootloader selection
BOOTLOADER = halfkay
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = no # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = no # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output

View File

@@ -0,0 +1,16 @@
/* Copyright 2021 stevendlander
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "unicomp_mini_m.h"

View File

@@ -0,0 +1,49 @@
/* Copyright 2021 stevendlander
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
/* This a shortcut to help you visually see your layout.
* The first section contains "names" for physical keys of the keyboard
* and defines their position on the board.
* The second section defines position of the keys on the switch matrix
* (where COLUMNS and ROWS crosses). */
#define LAYOUT( \
K5A, K5B, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, \
\
K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4N, K4O, K4P, K4Q, K4R, \
K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3O, K3P, K3Q, \
K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2M, K2N, \
K1A, K1B, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1M, K1N, K1O, \
K0A, K0B, K0C, K0D, K0E, K0F, K0G, K0H, K0I, K0J, K0K \
) \
{ \
/* 00 */ { K4A, K5A, K4F, K1M, K5C, K5D, K5E, K3K, KC_NO, KC_NO, KC_NO, KC_NO, K0C, K2N, KC_NO, KC_NO }, \
/* 01 */ { K2A, K1B, K3B, KC_NO, KC_NO, KC_NO, KC_NO, K4G, K5F, KC_NO, KC_NO, KC_NO, KC_NO, K2M, K0H, K1N, }, \
/* 02 */ { K2C, K2D, K5B, K2E, K2F, K1C, K1E, KC_NO, K1D, K1F, K1G, K2B, K3A, KC_NO, KC_NO, KC_NO }, \
/* 03 */ { KC_NO, KC_NO, K4B, KC_NO, KC_NO, KC_NO, KC_NO, K3G, K5G, KC_NO, KC_NO, K0B, KC_NO, KC_NO, KC_NO, KC_NO }, \
/* 04 */ { KC_NO, KC_NO, K4E, KC_NO, KC_NO, KC_NO, KC_NO, K3J, K5H, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K0A, K1A, }, \
/* 05 */ { KC_NO, KC_NO, K3C, KC_NO, KC_NO, KC_NO, KC_NO, K4H, K5I, K3L, K0F, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
/* 06 */ { KC_NO, KC_NO, K4C, KC_NO, KC_NO, KC_NO, KC_NO, K3H, K5J, K4M, K5K, K5L, K4L, K5N, KC_NO, KC_NO }, \
/* 07 */ { KC_NO, KC_NO, K4D, KC_NO, KC_NO, KC_NO, KC_NO, K3I, KC_NO, KC_NO, KC_NO, K5M, K4N, K5O, KC_NO, KC_NO }, \
/* 08 */ { KC_NO, KC_NO, K3F, KC_NO, KC_NO, KC_NO, KC_NO, K4K, KC_NO, K4O, K1O, K3P, K4P, KC_NO, KC_NO, KC_NO }, \
/* 09 */ { KC_NO, KC_NO, K3E, K0E, K0I, KC_NO, KC_NO, K4J, KC_NO, K3N, KC_NO, KC_NO, KC_NO, K4Q, KC_NO, KC_NO }, \
/* 0A */ { K0D, KC_NO, K3D, KC_NO, K0G, KC_NO, KC_NO, K4I, KC_NO, K3M, K0K, K0J, K4R, K3Q, KC_NO, KC_NO }, \
/* 0B */ { K1I, K1J, KC_NO, K1K, K1L, K2G, K2I, KC_NO, K2H, K2J, K2K, K1H, K2L, K3O, KC_NO, K5P, }, \
}
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */

View File

@@ -22,3 +22,6 @@
#define PRODUCT KBD75 rev1
#define BACKLIGHT_BREATHING
#define ANSI_NUBS_ROW 4
#define ANSI_NUBS_COL 2

View File

@@ -31,3 +31,6 @@
#endif
#define NO_ACTION_ONESHOT
#define ANSI_NUBS_ROW 3
#define ANSI_NUBS_COL 2

View File

@@ -107,7 +107,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
[_SY] = LAYOUT_60_ansi(
TG(_SY), TO(_QW), TO(_DV), TO(_CM), TG(_Q2), XXXXXXX, XXXXXXX, XXXXXXX, RESET, XXXXXXX, DEBUG, XXXXXXX, VRSN, XXXXXXX,
TG(_SY), TO(_DV), TO(_QW), TO(_CM), TG(_Q2), XXXXXXX, XXXXXXX, XXXXXXX, RESET, XXXXXXX, DEBUG, XXXXXXX, VRSN, XXXXXXX,
XXXXXXX, XXXXXXX, M_MDSWP, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, BL_DEC, BL_TOGG, BL_INC, BL_BRTG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,

View File

@@ -0,0 +1,23 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define RGB_MATRIX_STARTUP_SPD 20
#define AUTO_SHIFT_TIMEOUT 160
#define LEADER_TIMEOUT 400
#define LEADER_PER_KEY_TIMING

View File

@@ -0,0 +1,504 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jdelkins.h"
#include "print.h"
// Idle handling
#define IDLE_TIMEOUT 360
#define _LAYERS _RPT
uint16_t rgb_idle_seconds = 0;
uint16_t rgb_timer;
uint8_t save_layer;
// Macro keycodes
enum alt_keycodes {
U_T_AUTO = USER_SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active
U_T_AGCR, //USB Toggle Automatic GCR control
DBG_TOG, //DEBUG Toggle On / Off
DBG_MTRX, //DEBUG Toggle Matrix Prints
DBG_KBD, //DEBUG Toggle Keyboard Prints
DBG_MOU, //DEBUG Toggle Mouse Prints
};
// Tap Dance
int ctl_state = 0;
void ctl_finished(qk_tap_dance_state_t *state, void *user_data) {
ctl_state = cur_dance(state);
switch(ctl_state) {
case SINGLE_TAP: qk_leader_start(); break;
case SINGLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_TAP: tap_code(KC_RCTL); break;
case DOUBLE_HOLD: register_code(KC_RCTL); break;
case TRIPLE_TAP: tap_code(KC_RCTL); tap_code(KC_RCTL); break;
case TRIPLE_HOLD: tap_code(KC_RCTL); register_code(KC_RCTL); break;
}
}
void ctl_reset(qk_tap_dance_state_t *state, void *user_data) {
switch(ctl_state) {
case SINGLE_HOLD: unregister_code(KC_LCTL); break;
case DOUBLE_HOLD:
case TRIPLE_HOLD: unregister_code(KC_RCTL); break;
}
ctl_state = 0;
}
void g_finished(qk_tap_dance_state_t *state, void *user_data) {
switch (cur_dance(state)) {
case SINGLE_TAP:
tap_code16(C(KC_END));
break;
case DOUBLE_TAP:
tap_code16(C(KC_HOME));
break;
}
}
enum {
TD_LDCTL,
TD_GUI,
TD_G,
};
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LDCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ctl_finished, ctl_reset),
[TD_GUI] = ACTION_TAP_DANCE_DOUBLE(KC_LGUI, KC_RGUI),
[TD_G] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, g_finished, NULL),
};
// Layers
const uint16_t PROGMEM keymaps[_LAYER_MAX][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT(
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_BSPC, KC_DEL,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME,
MY_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_PGUP,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
TD(TD_LDCTL), TD(TD_GUI), KC_LALT, MY_SPC, KC_RALT, MO(_ADJUST),KC_LEFT, KC_DOWN, KC_RGHT
),
[_GAME] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
KC_LCTL, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, KC_NO, _______, KC_SPC, _______, _______, _______, _______, _______
),
[_FUNC] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS,
_______, _______, FW_WRD, KC_END, _______, _______, C(KC_INS),KC_PGUP, _______, _______, S(KC_INS),KC_SLCK, KC_PAUS, KC_CALC, KC_END,
_______, KC_HOME, _______, KC_PGDN, _______, TD(TD_G), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, _______,
_______, _______, KC_DEL, _______, _______, BK_WRD, _______, _______, _______, _______, _______, _______, KC_PGUP, _______,
_______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
),
[_LAYERS] = LAYOUT(
KC_NO, TO(_QWERTY),TO(_GAME), KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, _______, KC_NO, KC_NO, KC_NO
),
[_KP] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, KC_KP_ASTERISK, _______, _______, _______, _______, _______, _______,
KC_NUMLOCK, KC_KP_7, KC_KP_8, KC_KP_9, _______, _______, _______, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_MINUS, _______, _______, _______, _______,
_______, KC_KP_4, KC_KP_5, KC_KP_6, _______, _______, _______, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, _______, _______, _______,
_______, KC_KP_1, KC_KP_2, KC_KP_3, _______, _______, _______, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_SLASH, _______, _______, _______,
_______, _______, _______, KC_KP_0, KC_KP_DOT, TG(_KP), _______, _______, _______
),
[_SECRETS] = LAYOUT(
KC_NO, KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5, KC_SEC6, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, _______, KC_NO, KC_NO, KC_NO
),
[_ADJUST] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_F13, KC_INS,
_______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, KC_CALC, KC_END,
_______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, TG(_KP), OSL(_LAYERS), OSL(_SECRETS), _______, _______, KC_MPLY,
_______, RGB_TOG, KB_MAKE, KB_FLSH, KB_VRSN, KB_BOOT, NK_TOGG, DBG_TOG, _______, _______, _______, _______, KC_VOLU, KC_MUTE,
_______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT
),
/*
[X] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
),
*/
};
#ifdef _______
#undef _______
#endif
#define RGB_NULL 254, 254, 254
#define RGB_IS_NULL(rgb) ((rgb).r == 254 && (rgb).g == 254 && (rgb).b == 254)
#define DEFAULT_HSV 255, 255, 128
#define R(COL) { RGB_ ## COL }
#define _______ R(NULL)
#define xxxxxxx R(BLACK)
struct layer_rgb PROGMEM rgbs[_LAYER_MAX] = {
[_QWERTY] = LAYOUT_hsv(LED_FLAG_ALL, RGB_MATRIX_CYCLE_ALL, DEFAULT_HSV),
[_GAME] = LAYOUT_hsv(LED_FLAG_KEYLIGHT, RGB_MATRIX_SOLID_COLOR, DEFAULT_HSV),
[_FUNC] = LAYOUT_rgb(LED_FLAG_KEYLIGHT, RGB_LINK_TO_LAYER(_QWERTY),
R(BLUE), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(BLUE),
R(BLUE), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, R(BLUE),
R(BLUE), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, R(BLUE),
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
R(BLUE), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, R(BLUE),
R(BLUE), _______, _______, _______, _______, _______, _______, _______, _______, _______, R(BLUE),
R(BLUE), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(RED), R(BLUE)
),
[_LAYERS] = LAYOUT_rgb(LED_FLAG_NONE, RGB_MATRIX_SOLID_COLOR,
R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN),
R(CYAN), xxxxxxx, R(RED), R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(CYAN),
R(CYAN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(CYAN),
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
R(CYAN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(CYAN),
R(CYAN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(CYAN),
R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN), R(CYAN)
),
[_KP] = LAYOUT_rgb(LED_FLAG_NONE, RGB_MATRIX_SOLID_COLOR,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(YELLOW),xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, R(WHITE), R(WHITE), R(WHITE), xxxxxxx, xxxxxxx, xxxxxxx, R(WHITE), R(WHITE), R(WHITE), R(YELLOW), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, R(WHITE), R(WHITE), R(WHITE), xxxxxxx, xxxxxxx, xxxxxxx, R(WHITE), R(WHITE), R(WHITE), R(YELLOW), xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, R(WHITE), R(WHITE), R(WHITE), xxxxxxx, xxxxxxx, xxxxxxx, R(WHITE), R(WHITE), R(WHITE), R(YELLOW), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(WHITE), R(YELLOW), R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx
),
[_SECRETS] = LAYOUT_rgb(LED_FLAG_NONE, RGB_MATRIX_SOLID_COLOR,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx,
xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx
),
[_ADJUST] = LAYOUT_rgb(LED_FLAG_NONE, RGB_MATRIX_SOLID_COLOR,
R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN),
R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(GREEN),
R(GREEN), xxxxxxx, R(BLUE), R(YELLOW), R(BLUE), R(GREEN), R(ORANGE),xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(GREEN),
xxxxxxx, R(MAGENTA),R(YELLOW), R(MAGENTA),R(GREEN),R(ORANGE),xxxxxxx, xxxxxxx, R(CORAL), R(CORAL), R(CORAL), xxxxxxx, xxxxxxx, xxxxxxx,
R(GREEN), xxxxxxx, R(WHITE), R(CYAN), R(CYAN), R(CYAN), R(CYAN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(GREEN),
R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(GREEN),
R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN)
),
/*
[X] = LAYOUT_rgb(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
*/
};
#undef _______
#define _______ KC_TRANS
static void set_rgb_layer(int layer) {
const struct layer_rgb *cur = &rgbs[layer];
switch (cur->type) {
case type_hsv:
for (uint8_t i = 0; i < DRIVER_LED_TOTAL ; i++) {
if (!(g_led_config.flags[i] & cur->flags))
rgb_matrix_set_color(i, 0, 0, 0);
}
rgb_matrix_set_flags(cur->flags);
if (cur->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_matrix_mode_noeeprom(rgbs[cur->mode - RGB_MATRIX_EFFECT_MAX].mode);
else
rgb_matrix_mode_noeeprom(cur->mode);
rgb_matrix_sethsv_noeeprom(cur->hsv.h, cur->hsv.s, cur->hsv.v);
break;
case type_rgb:
rgb_matrix_set_flags(cur->flags);
if (cur->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_matrix_mode_noeeprom(rgbs[cur->mode - RGB_MATRIX_EFFECT_MAX].mode);
else
rgb_matrix_mode_noeeprom(cur->mode);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
const RGB *m = &cur->rgb[i];
if (!RGB_IS_NULL(*m))
rgb_matrix_set_color(i, m->r, m->g, m->b);
}
break;
}
}
// Runs just one time when the keyboard initializes.
void matrix_init_keymap(void) {
// force numlock on upon startup
if (!NUMLOCK_ON) {
tap_code(KC_NUMLOCK);
}
};
LEADER_EXTERNS();
// Runs constantly in the background, in a loop.
void matrix_scan_keymap(void) {
if (rgb_matrix_get_flags() != LED_FLAG_NONE && timer_elapsed(rgb_timer) > 1000) {
rgb_idle_seconds++;
rgb_timer = timer_read();
}
if (rgb_idle_seconds > IDLE_TIMEOUT) {
rgb_matrix_disable_noeeprom();
rgb_idle_seconds = 0;
}
if (IS_LAYER_ON(_KP)) {
if (NUMLOCK_ON)
rgb_matrix_set_color(15, RGB_GOLD);
else
rgb_matrix_set_color(15, 0, 0, 0);
}
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_K) {
layer_invert(_KP);
}
SEQ_ONE_KEY(KC_G) {
layer_invert(_GAME);
}
SEQ_ONE_KEY(KC_KP_5) {
layer_invert(_KP);
}
SEQ_TWO_KEYS(KC_SCLN, KC_1) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_2) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_3) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_4) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_5) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_6) {
send_secret_string(5);
}
SEQ_TWO_KEYS(KC_SCLN, KC_M) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_COMM) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_DOT) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_J) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_K) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_L) {
send_secret_string(5);
}
}
};
layer_state_t layer_state_set_keymap(layer_state_t state) {
dprintf("layer: %d\n", get_highest_layer(state));
set_rgb_layer(get_highest_layer(state));
#ifdef AUTO_SHIFT_ENABLE
autoshift_enable();
#endif
if (layer_state_cmp(state, _GAME)) {
save_layer = _GAME;
#ifdef AUTO_SHIFT_ENABLE
autoshift_disable();
#endif
}
else if (layer_state_cmp(state, _QWERTY))
save_layer = _QWERTY;
return state;
}
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
struct layer_rgb *rgb_base_layer = &rgbs[save_layer];
rgb_idle_seconds = 0;
rgb_matrix_enable_noeeprom();
switch (keycode) {
// custom handle KC_GESC to emulate auto shift on it
case KC_GESC:
#ifdef AUTO_SHIFT_ENABLE
if (get_autoshift_state()) {
static uint16_t gesc_timer;
if (record->event.pressed)
gesc_timer = timer_read();
else {
if (timer_elapsed(gesc_timer) > AUTO_SHIFT_TIMEOUT || MODS_SHIFT) {
tap_code16(S(KC_GRV));
} else if (MODS_GUI)
tap_code(KC_GRV);
else
tap_code(KC_ESC);
}
return false;
}
#else // AUTO_SHIFT_ENABLE
return true;
#endif // AUTO_SHIFT_ENABLE
break;
case U_T_AUTO:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
}
return false;
case U_T_AGCR:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
}
return false;
case DBG_TOG:
if (record->event.pressed) {
TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
}
return false;
case DBG_MTRX:
if (record->event.pressed) {
TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
}
return false;
case DBG_KBD:
if (record->event.pressed) {
TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
}
return false;
case DBG_MOU:
if (record->event.pressed) {
TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
}
return false;
case RGB_MOD:
if (record->event.pressed) {
if (++rgb_base_layer->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_base_layer->mode = RGB_MATRIX_NONE;
set_rgb_layer(save_layer);
}
return false;
case RGB_RMOD:
if (record->event.pressed) {
if (--rgb_base_layer->mode <= RGB_MATRIX_NONE)
rgb_base_layer->mode = RGB_MATRIX_EFFECT_MAX - 1;
set_rgb_layer(save_layer);
}
return false;
case RGB_HUI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.h > 235)
rgb_base_layer->hsv.h = 255;
else
rgb_base_layer->hsv.h += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_HUD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.h < 20)
rgb_base_layer->hsv.h = 0;
else
rgb_base_layer->hsv.h -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_SAI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.s > 235)
rgb_base_layer->hsv.s = 255;
else
rgb_base_layer->hsv.s += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_SAD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.s < 20)
rgb_base_layer->hsv.s = 0;
else
rgb_base_layer->hsv.s -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_VAI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.v > 235)
rgb_base_layer->hsv.v = 255;
else
rgb_base_layer->hsv.v += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_VAD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.v < 20)
rgb_base_layer->hsv.v = 0;
else
rgb_base_layer->hsv.v -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_TOG:
if (record->event.pressed) {
switch (rgb_base_layer->flags) {
case LED_FLAG_ALL:
rgb_base_layer->flags = LED_FLAG_KEYLIGHT;
break;
case LED_FLAG_KEYLIGHT:
rgb_base_layer->flags = LED_FLAG_UNDERGLOW;
break;
case LED_FLAG_UNDERGLOW:
rgb_base_layer->flags = LED_FLAG_NONE;
break;
default:
rgb_base_layer->flags = LED_FLAG_ALL;
break;
}
}
set_rgb_layer(save_layer);
return false;
default:
return true; //Process all other keycodes normally
}
return true;
}

View File

@@ -0,0 +1,94 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* RGB LED Layout on the Massdrop ALT
*
* ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
* │ │
* │ 100 99 98 97 96 95 94 93 92 91 90 89 88 │
* │ 101 87 |
* │ ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬────────────┬───────┐ │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ BackSpace │ Home │ │
* │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ │
* │ 102 ├───────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬─────────┼───────┤ 86 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ Del │ │
* │ │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ │
* │ 103 ├──────────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─────────┼───────┤ 85 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Ctrl/Esc │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Return │ PgUp │ │
* │ │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 40 │ 41 │ 42 │ 43 │ 44 │ │
* │ 104 ├────────────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴───────┬───────┼───────┤ 84 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ Up │ PgDn │ │
* │ │ 45 │ 46 │ 47 │ 48 │ 49 │ 50 │ 51 │ 52 │ 53 │ 54 │ 55 │ 56 │ 57 │ 58 │ │
* │ 105 ├─────────┬─────┴───┬───┴─────┬─┴───────┴───────┴───────┴───────┴───────┴─────┬─┴───────┼───────┴─┬──┬───────┼───────┼───────┤ 83 │
* │ │ │ │ │ │ │ │▒▒│ │ │ │ │
* │ │ Ctrl │ GUI │ Alt │ Space │ Alt │ Func │▒▒│ Left │ Down │ Right │ │
* │ │ 59 │ 60 │ 61 │ 62 │ 63 │ 64 │▒▒│ 65 │ 66 │ 67 │ │
* │ └─────────┴─────────┴─────────┴───────────────────────────────────────────────┴─────────┴─────────┴──┴───────┴───────┴───────┘ │
* │ 68 82 │
* │ 69 70 71 72 73 74 75 76 77 78 79 80 81 │
* │ │
* └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
enum layer_rgb_type {
type_hsv,
type_rgb,
};
#define RGB_LINK_TO_LAYER(layer) (layer + RGB_MATRIX_EFFECT_MAX)
struct layer_rgb {
uint8_t type;
led_flags_t flags;
uint8_t mode;
union {
HSV hsv;
RGB rgb[DRIVER_LED_TOTAL];
};
};
#define LAYOUT_rgb(_flags, _mode, \
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, \
R102, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R86, \
R103, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R85, \
R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, \
R104, R45, R46, R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R84, \
R105, R59, R60, R61, R62, R63, R64, R65, R66, R67, R83, \
R68, R69, R70, R71, R72, R73, R74, R75, R76, R77, R78, R79, R80, R81, R82 \
) (struct layer_rgb) { .type = type_rgb, .flags = _flags, .mode = _mode, .rgb = { \
R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, \
R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, \
R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, \
R60, R61, R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, R77, R78, \
R79, R80, R81, R82, R83, R84, R85, R86, R87, R88, R89, R90, R91, R92, R93, R94, R95, R96, R97, \
R98, R99, R100, R101, R102, R103, R104, R105 \
}}
#define LAYOUT_hsv(_flags, _mode, _hsv) \
(struct layer_rgb) { \
.type = type_hsv, \
.flags = _flags, \
.mode = _mode, \
.hsv = {_hsv} \
}

View File

@@ -0,0 +1,17 @@
ifeq ($(OS),Windows_NT)
PROGRAM_CMD = bin/mdloader_windows --first --download $(TARGET).hex --restart
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
PROGRAM_CMD = bin/mdloader_mac --first --download $(TARGET).hex --restart
else
PROGRAM_CMD = sudo bin/mdloader_linux --first --download $(TARGET).hex --restart
endif
endif
LEADER_ENABLE = yes
MOUSEKEY_ENABLE = no
CONSOLE_ENABLE = no
NKRO_ENABLE = no
TAP_DANCE_ENABLE = yes
AUTO_SHIFT_ENABLE = no

View File

@@ -0,0 +1,20 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define RGB_MATRIX_STARTUP_SPD 20

View File

@@ -0,0 +1,280 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "print.h"
// Idle handling
#define IDLE_TIMEOUT 360
uint16_t rgb_idle_seconds = 0;
uint16_t rgb_timer;
uint8_t save_layer;
#define NUMLOCK_ON (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))
#define MODS_SHIFT (get_mods() & MOD_MASK_SHIFT)
#define MODS_CTRL (get_mods() & MOD_MASK_CTRL)
// Macro keycodes
enum alt_keycodes {
KB_BOOT = SAFE_RANGE,
};
enum layers {
_QWERTY,
_ADJUST,
};
// Layers
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT(
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_BSPC, KC_DEL,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME,
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_PGUP,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RALT, MO(_ADJUST),KC_LEFT, KC_DOWN, KC_RGHT
),
[_ADJUST] = LAYOUT(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_F13, KC_INS,
_______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_CALC, KC_END,
_______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, KC_MPLY,
_______, RGB_TOG, _______, _______, _______, KB_BOOT, _______, _______, _______, _______, _______, _______, KC_VOLU, KC_MUTE,
_______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT
),
/*
[X] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______
),
*/
};
#ifdef _______
#undef _______
#endif
#define RGB_NULL 254, 254, 254
#define RGB_IS_NULL(rgb) ((rgb).r == 254 && (rgb).g == 254 && (rgb).b == 254)
#define DEFAULT_HSV 255, 255, 128
#define R(COL) { RGB_ ## COL }
#define _______ R(NULL)
#define xxxxxxx R(BLACK)
struct layer_rgb PROGMEM rgbs[] = {
[_QWERTY] = LAYOUT_hsv(LED_FLAG_ALL, RGB_MATRIX_CYCLE_ALL, DEFAULT_HSV),
[_ADJUST] = LAYOUT_rgb(LED_FLAG_NONE, RGB_MATRIX_SOLID_COLOR,
R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN),
R(GREEN), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(WHITE), R(GREEN),
R(GREEN), xxxxxxx, R(BLUE), R(YELLOW), R(BLUE), R(GREEN), R(ORANGE),xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(GREEN),
xxxxxxx, R(MAGENTA),R(YELLOW), R(MAGENTA),R(GREEN),R(ORANGE),xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(BLUE),
R(GREEN), xxxxxxx, R(WHITE), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(YELLOW),R(ORANGE), R(GREEN),
R(GREEN), xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, xxxxxxx, R(RED), R(YELLOW),R(RED), R(GREEN),
R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN), R(GREEN)
),
/*
[X] = LAYOUT_rgb(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
*/
};
#undef _______
#define _______ KC_TRANS
static void set_rgb_layer(int layer) {
const struct layer_rgb *cur = &rgbs[layer];
switch (cur->type) {
case type_hsv:
for (uint8_t i = 0; i < DRIVER_LED_TOTAL ; i++) {
if (!(g_led_config.flags[i] & cur->flags))
rgb_matrix_set_color(i, 0, 0, 0);
}
rgb_matrix_set_flags(cur->flags);
if (cur->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_matrix_mode_noeeprom(rgbs[cur->mode - RGB_MATRIX_EFFECT_MAX].mode);
else
rgb_matrix_mode_noeeprom(cur->mode);
rgb_matrix_sethsv_noeeprom(cur->hsv.h, cur->hsv.s, cur->hsv.v);
break;
case type_rgb:
rgb_matrix_set_flags(cur->flags);
if (cur->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_matrix_mode_noeeprom(rgbs[cur->mode - RGB_MATRIX_EFFECT_MAX].mode);
else
rgb_matrix_mode_noeeprom(cur->mode);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
const RGB *m = &cur->rgb[i];
if (!RGB_IS_NULL(*m))
rgb_matrix_set_color(i, m->r, m->g, m->b);
}
break;
}
}
// Runs just one time when the keyboard initializes.
void matrix_init_keymap(void) {
set_rgb_layer(_QWERTY);
// force numlock on upon startup
if (!NUMLOCK_ON) {
tap_code(KC_NUMLOCK);
}
};
// Runs constantly in the background, in a loop.
void matrix_scan_keymap(void) {
if (rgb_matrix_get_flags() != LED_FLAG_NONE && timer_elapsed(rgb_timer) > 1000) {
rgb_idle_seconds++;
rgb_timer = timer_read();
}
if (rgb_idle_seconds > IDLE_TIMEOUT) {
rgb_matrix_disable_noeeprom();
rgb_idle_seconds = 0;
}
};
layer_state_t layer_state_set_keymap(layer_state_t state) {
set_rgb_layer(get_highest_layer(state));
if (layer_state_cmp(state, _QWERTY))
save_layer = _QWERTY;
return state;
}
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
static uint32_t boot_timer;
struct layer_rgb *rgb_base_layer = &rgbs[save_layer];
rgb_idle_seconds = 0;
rgb_matrix_enable_noeeprom();
switch (keycode) {
case KB_BOOT:
if (!get_mods()) {
if (record->event.pressed) {
boot_timer = timer_read32();
} else {
if (timer_elapsed32(boot_timer) >= 750) {
reset_keyboard();
}
}
return false;
}
break;
case RGB_MOD:
if (record->event.pressed) {
if (++rgb_base_layer->mode >= RGB_MATRIX_EFFECT_MAX)
rgb_base_layer->mode = RGB_MATRIX_NONE;
set_rgb_layer(save_layer);
}
return false;
case RGB_RMOD:
if (record->event.pressed) {
if (--rgb_base_layer->mode <= RGB_MATRIX_NONE)
rgb_base_layer->mode = RGB_MATRIX_EFFECT_MAX - 1;
set_rgb_layer(save_layer);
}
return false;
case RGB_HUI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.h > 235)
rgb_base_layer->hsv.h = 255;
else
rgb_base_layer->hsv.h += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_HUD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.h < 20)
rgb_base_layer->hsv.h = 0;
else
rgb_base_layer->hsv.h -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_SAI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.s > 235)
rgb_base_layer->hsv.s = 255;
else
rgb_base_layer->hsv.s += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_SAD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.s < 20)
rgb_base_layer->hsv.s = 0;
else
rgb_base_layer->hsv.s -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_VAI:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.v > 235)
rgb_base_layer->hsv.v = 255;
else
rgb_base_layer->hsv.v += 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_VAD:
if (rgb_base_layer->type == type_hsv && record->event.pressed) {
if (rgb_base_layer->hsv.v < 20)
rgb_base_layer->hsv.v = 0;
else
rgb_base_layer->hsv.v -= 20;
}
set_rgb_layer(save_layer);
return false;
case RGB_TOG:
if (record->event.pressed) {
switch (rgb_base_layer->flags) {
case LED_FLAG_ALL:
rgb_base_layer->flags = LED_FLAG_KEYLIGHT;
break;
case LED_FLAG_KEYLIGHT:
rgb_base_layer->flags = LED_FLAG_UNDERGLOW;
break;
case LED_FLAG_UNDERGLOW:
rgb_base_layer->flags = LED_FLAG_NONE;
break;
default:
rgb_base_layer->flags = LED_FLAG_ALL;
break;
}
}
set_rgb_layer(save_layer);
return false;
default:
return true; //Process all other keycodes normally
}
return true;
}

View File

@@ -0,0 +1,94 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* RGB LED Layout on the Massdrop ALT
*
* ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
* │ │
* │ 100 99 98 97 96 95 94 93 92 91 90 89 88 │
* │ 101 87 |
* │ ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬────────────┬───────┐ │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ BackSpace │ Home │ │
* │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ │
* │ 102 ├───────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬─────────┼───────┤ 86 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ Del │ │
* │ │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ │
* │ 103 ├──────────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─┬─────┴─────────┼───────┤ 85 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Ctrl/Esc │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Return │ PgUp │ │
* │ │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 40 │ 41 │ 42 │ 43 │ 44 │ │
* │ 104 ├────────────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴──┬────┴───────┬───────┼───────┤ 84 │
* │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
* │ │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ Up │ PgDn │ │
* │ │ 45 │ 46 │ 47 │ 48 │ 49 │ 50 │ 51 │ 52 │ 53 │ 54 │ 55 │ 56 │ 57 │ 58 │ │
* │ 105 ├─────────┬─────┴───┬───┴─────┬─┴───────┴───────┴───────┴───────┴───────┴─────┬─┴───────┼───────┴─┬──┬───────┼───────┼───────┤ 83 │
* │ │ │ │ │ │ │ │▒▒│ │ │ │ │
* │ │ Ctrl │ GUI │ Alt │ Space │ Alt │ Func │▒▒│ Left │ Down │ Right │ │
* │ │ 59 │ 60 │ 61 │ 62 │ 63 │ 64 │▒▒│ 65 │ 66 │ 67 │ │
* │ └─────────┴─────────┴─────────┴───────────────────────────────────────────────┴─────────┴─────────┴──┴───────┴───────┴───────┘ │
* │ 68 82 │
* │ 69 70 71 72 73 74 75 76 77 78 79 80 81 │
* │ │
* └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
enum layer_rgb_type {
type_hsv,
type_rgb,
};
#define RGB_LINK_TO_LAYER(layer) (layer + RGB_MATRIX_EFFECT_MAX)
struct layer_rgb {
uint8_t type;
led_flags_t flags;
uint8_t mode;
union {
HSV hsv;
RGB rgb[DRIVER_LED_TOTAL];
};
};
#define LAYOUT_rgb(_flags, _mode, \
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87, \
R102, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R86, \
R103, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R85, \
R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, \
R104, R45, R46, R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R84, \
R105, R59, R60, R61, R62, R63, R64, R65, R66, R67, R83, \
R68, R69, R70, R71, R72, R73, R74, R75, R76, R77, R78, R79, R80, R81, R82 \
) (struct layer_rgb) { .type = type_rgb, .flags = _flags, .mode = _mode, .rgb = { \
R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, \
R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, \
R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, \
R60, R61, R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, R77, R78, \
R79, R80, R81, R82, R83, R84, R85, R86, R87, R88, R89, R90, R91, R92, R93, R94, R95, R96, R97, \
R98, R99, R100, R101, R102, R103, R104, R105 \
}}
#define LAYOUT_hsv(_flags, _mode, _hsv) \
(struct layer_rgb) { \
.type = type_hsv, \
.flags = _flags, \
.mode = _mode, \
.hsv = {_hsv} \
}

View File

@@ -0,0 +1,12 @@
ifeq ($(OS),Windows_NT)
PROGRAM_CMD = bin/mdloader_windows --first --download $(TARGET).hex --restart
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
PROGRAM_CMD = bin/mdloader_mac --first --download $(TARGET).hex --restart
else
PROGRAM_CMD = sudo bin/mdloader_linux --first --download $(TARGET).hex --restart
endif
endif
USER_NAME := jdelkins

View File

@@ -15,7 +15,6 @@
*/
#include QMK_KEYBOARD_H
#include <stdio.h>
enum layer_names {
_BASE,
@@ -123,7 +122,7 @@ static const char PROGMEM merge_logo[] = {
0x01, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00
};
int current_wpm = 0;
uint8_t current_wpm = 0;
static void print_status_narrow(void) {
oled_set_cursor(0,1);
@@ -159,10 +158,15 @@ static void print_status_narrow(void) {
//oled_write_ln_P(PSTR(" "), false);
oled_write_P(PSTR("-----"), false);
// WPM counter Start (Need #include <stdio.h> to work)
char wpm_str[8];
// WPM counter Start
char wpm_str[5];
oled_set_cursor(0,13);
sprintf(wpm_str, " %03d", current_wpm);
wpm_str[4] = '\0';
uint8_t n = current_wpm;
wpm_str[3] = '0' + n % 10;
wpm_str[2] = '0' + (n /= 10) % 10;
wpm_str[1] = '0' + n / 10;
wpm_str[0] = ' ';
oled_write(wpm_str, false);
oled_set_cursor(0,14);
oled_write(" WPM ", false);

View File

@@ -1,18 +1,18 @@
/* Copyright 2020 MT<704340378@qq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
@@ -44,8 +44,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_TOGG, BL_INC, BL_STEP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
};
void rgb_matrix_indicators_user(void) {
if (!g_suspend_state && layer_state_is(1)) {
if (layer_state_is(1)) {
rgb_matrix_set_color(77,0xFF, 0x80, 0x00);
}
if (host_keyboard_led_state().caps_lock) {

View File

@@ -100,6 +100,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define WS2812_SPI SPID2 // default: SPID1
#define WS2812_SPI_MOSI_PAL_MODE 0 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
#define RGB_DI_PIN B15
#ifdef RGB_DI_PIN

View File

@@ -50,3 +50,5 @@
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* Reducing layer count to 3 for via support */
#define DYNAMIC_KEYMAP_LAYER_COUNT 3

View File

@@ -0,0 +1,46 @@
/* Copyright 2021 W. Alex Ronke, a.k.a. NoPunIn10Did (w.alex.ronke@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_rh_any(
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_PSCR,KC_SLCK,KC_INS ,KC_DEL ,KC_HOME,KC_END ,KC_PGUP,KC_PGDN,
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_INT3,KC_BSPC, KC_NLCK,KC_PSLS,KC_PAST,KC_PAUS,
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_P7 ,KC_P8 ,KC_P9 ,KC_PMNS,
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_P4 ,KC_P5 ,KC_P6 ,KC_PPLS,
KC_LSFT,KC_NUBS,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B ,MO(1), MO(1), KC_N ,KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_INT1,KC_RSFT,KC_UP , KC_P1 ,KC_P2 ,KC_P3 ,KC_PENT,
KC_LCTL,KC_LGUI, KC_LALT,KC_MENU,KC_SPC , KC_SPC , KC_ALGR, KC_RGUI,KC_RCTL,KC_LEFT,KC_DOWN,KC_RGHT, KC_P0 ,KC_P0 ,KC_PDOT,KC_PENT),
[1] = LAYOUT_rh_any(
RESET ,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,RESET ,_______, _______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______, _______,_______,_______, _______, _______, _______,_______,_______,_______,_______, _______,_______,_______,_______),
[2] = LAYOUT_rh_any(
_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,
_______,_______, _______,_______,_______, _______, _______, _______,_______,_______,_______,_______, _______,_______,_______,_______),
};

View File

@@ -0,0 +1,2 @@
VIA_ENABLE = yes
LTO_ENABLE = yes

View File

@@ -0,0 +1,58 @@
/* Copyright 2020 Joel Elkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
// #define STARTUP_SONG SONG(NO_SOUND)
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
SONG(COLEMAK_SOUND), \
SONG(DVORAK_SOUND) \
}
#endif
/*
* 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 2
// Most tactile encoders have detents every 4 stages
#define ENCODER_RESOLUTION 4
#define AUTO_SHIFT_TIMEOUT 165
#define LEADER_TIMEOUT 400
#define LEADER_PER_KEY_TIMING

View File

@@ -0,0 +1,423 @@
/* Copyright 2015-2017 Jack Humbert
* Portions Copyright 2020 Joel Elkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jdelkins.h"
#include "muse.h"
#ifdef LAYOUT
#undef LAYOUT
#endif
#define LAYOUT LAYOUT_planck_2x2u
uint16_t bspc_timer;
enum {
MY_BSPC = USER_SAFE_RANGE,
BACKLIT,
};
// recycle unused layers defined in my userspace
#define _RAISE _FUNC
#define _LOWER _SECRETS
#define KP MO(_KP)
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
int ctl_state = 0;
void ctl_finished(qk_tap_dance_state_t *state, void *user_data) {
ctl_state = cur_dance(state);
switch (ctl_state) {
case SINGLE_TAP: qk_leader_start(); break;
case SINGLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_TAP: tap_code(KC_RCTL); break;
case DOUBLE_HOLD: register_code(KC_RCTL); break;
case TRIPLE_TAP: tap_code(KC_RCTL); tap_code(KC_RCTL); break;
case TRIPLE_HOLD: tap_code(KC_RCTL); register_code(KC_RCTL); break;
}
}
void ctl_reset(qk_tap_dance_state_t *state, void *user_data) {
switch (ctl_state) {
case SINGLE_HOLD: unregister_code(KC_LCTL); break;
case DOUBLE_HOLD:
case TRIPLE_HOLD: unregister_code(KC_RCTL); break;
}
ctl_state = 0;
}
void g_finished(qk_tap_dance_state_t *state, void *user_data) {
switch (cur_dance(state)) {
case SINGLE_TAP:
tap_code16(C(KC_END));
break;
case DOUBLE_TAP:
tap_code16(C(KC_HOME));
break;
}
}
int kp_state = 0;
void kp_finished(qk_tap_dance_state_t *state, void *user_data) {
kp_state = hold_cur_dance(state);
switch (kp_state) {
case SINGLE_HOLD: layer_on(_KP); break;
case DOUBLE_HOLD: layer_on(_RPT); break;
}
}
void kp_reset(qk_tap_dance_state_t *state, void *user_data) {
switch (kp_state) {
case SINGLE_HOLD: layer_off(_KP); break;
case DOUBLE_HOLD: layer_off(_RPT); break;
}
kp_state = 0;
}
enum {
TD_LDCTL,
TD_G,
TD_KP
};
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_LDCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ctl_finished, ctl_reset),
[TD_G] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, g_finished, NULL),
[TD_KP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, kp_finished, kp_reset),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | E | R | T | Y | U | I | O | P | ` |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | Gui | Alt |Keypad| Bksp | Space | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = LAYOUT(
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_GRV,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
TD(TD_LDCTL), MO(_ADJUST), MY_GUI, MY_ALT, MY_BSPC, MY_SPC, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
),
[_GAME] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, KC_NO, KC_LALT, RAISE, KC_SPC, KC_SPC, _______, _______, _______, _______
),
[_RAISE] = LAYOUT(
KC_ESC, _______, FW_WRD, KB_EOL, _______, _______, KB_COPY, KC_PGUP, _______, KC_LPRN, KC_RPRN, KC_MINS,
_______, KB_BOL, _______, KC_PGDN, _______, TD(TD_G), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, KC_BSLS,
_______, _______, KC_DEL, _______, KB_PASTE, BK_WRD, _______, _______, _______, _______, _______, KC_CALC,
_______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
),
/* Same as _QWERTY but disable autoshift */
[_RPT] = LAYOUT(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, KC_BSPC, KC_SPC, _______, _______, _______, _______
),
[_KP] = LAYOUT(
KC_NUMLOCK, KC_F9, KC_F10, KC_F11, KC_F12, KC_F13, KC_F14, KC_7, KC_8, KC_9, KC_MINS, KC_EQL,
_______, KC_F5, KC_F6, KC_F7, KC_F8, XXXXXXX, XXXXXXX, KC_4, KC_5, KC_6, KC_ASTR, _______,
_______, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, XXXXXXX, KC_1, KC_2, KC_3, KC_SLSH, _______,
_______, _______, _______, _______, _______, _______, KC_0, KC_DOT, KC_PLUS, KC_END
),
[_LOWER] = LAYOUT(
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LBRC, KC_RBRC, KC_EQL,
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LCBR, KC_RCBR, KC_PIPE,
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_END, KC_MPLY,
_______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_VOLU, KC_MNXT
),
[_ADJUST] = LAYOUT(
_______, 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, _______, _______, _______, _______, _______,
_______, RGB_TOG, KB_MAKE, KB_FLSH, KB_VRSN, KB_BOOT, _______, TG_SYS, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
/* [_ADJUST] = LAYOUT( */
/* _______, 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, _______, _______, _______, */
/* _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ */
/* ) */
};
#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_keymap(layer_state_t state) {
if (layer_state_cmp(state, _GAME) || layer_state_cmp(state, _RPT))
autoshift_disable();
else
autoshift_enable();
return update_tri_layer_state(state, _KP, _RAISE, _LOWER);
}
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
bool rc = true;
static bool bspc_del = false;
static bool bspc_initiated_func = false;
switch (keycode) {
case MY_BSPC:
if (record->event.pressed) {
if (IS_LAYER_ON(_KP)) {
// special case: if _KP was turned on by another key,
// treat this as KC_DEL and don't do anything else
bspc_del = true;
register_code(KC_DEL);
return false;
} else {
bspc_timer = timer_read();
bspc_initiated_func = true;
layer_on(_KP);
}
} else {
if (bspc_del) {
// special case: if _KP was turned on by another key,
// treat this as KC_DEL and don't do anything else
unregister_code(KC_DEL);
bspc_del = false;
return false;
}
if (bspc_initiated_func) {
layer_off(_KP);
bspc_initiated_func = false;
}
if (bspc_timer > 0) {
// here the key was pressed and released before the timer
// expired, so treat as a backspace tap and pretend we
// never activated _KP
bspc_timer = 0;
tap_code(KC_BSPC);
} else {
// the timer went off, so KC_BSPC was registered in
// matrix_scan_keymap. unregister it now
unregister_code(KC_BSPC);
}
}
return false; // special case, return now without resetting timer
// other paths should set rc and break
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
rc = false;
break;
}
bspc_timer = 0;
return rc;
}
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
tap_code(KC_MS_WH_DOWN);
#else
tap_code(KC_PGDN);
#endif
} else {
#ifdef MOUSEKEY_ENABLE
tap_code(KC_MS_WH_UP);
#else
tap_code(KC_PGUP);
#endif
}
}
}
void dip_switch_update_user(uint8_t index, bool active) {
switch (index) {
case 0: {
#ifdef AUDIO_ENABLE
static bool play_sound = false;
#endif
if (active) {
#ifdef AUDIO_ENABLE
if (play_sound) { PLAY_SONG(plover_song); }
#endif
layer_on(_ADJUST);
} else {
#ifdef AUDIO_ENABLE
if (play_sound) { PLAY_SONG(plover_gb_song); }
#endif
layer_off(_ADJUST);
}
#ifdef AUDIO_ENABLE
play_sound = true;
#endif
break;
}
case 1:
if (active) {
muse_mode = true;
} else {
muse_mode = false;
}
}
}
void keyboard_post_init_keymap(void) {
bspc_timer = 0;
}
LEADER_EXTERNS();
void matrix_scan_keymap(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;
} else {
if (muse_counter) {
stop_all_notes();
muse_counter = 0;
}
}
#endif
// if MY_BSPC is held down too long, pretend like it wasn't and start
// pressing backspace
if (bspc_timer > 0 && timer_elapsed(bspc_timer) > LEADER_TIMEOUT) {
layer_off(_KP);
bspc_timer = 0;
register_code(KC_BSPC);
}
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_K) {
layer_invert(_KP);
}
SEQ_ONE_KEY(KC_G) {
layer_invert(_GAME);
}
SEQ_ONE_KEY(KC_KP_5) {
layer_invert(_KP);
}
SEQ_ONE_KEY(KC_5) {
layer_invert(_KP);
}
SEQ_TWO_KEYS(KC_SCLN, KC_1) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_2) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_3) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_4) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_5) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_6) {
send_secret_string(5);
}
SEQ_TWO_KEYS(KC_SCLN, KC_M) {
send_secret_string(0);
}
SEQ_TWO_KEYS(KC_SCLN, KC_COMM) {
send_secret_string(1);
}
SEQ_TWO_KEYS(KC_SCLN, KC_DOT) {
send_secret_string(2);
}
SEQ_TWO_KEYS(KC_SCLN, KC_J) {
send_secret_string(3);
}
SEQ_TWO_KEYS(KC_SCLN, KC_K) {
send_secret_string(4);
}
SEQ_TWO_KEYS(KC_SCLN, KC_L) {
send_secret_string(5);
}
SEQ_ONE_KEY(KC_C) {
tap_code16(C(KC_C));
}
}
}
bool music_mask_user(uint16_t keycode) {
switch (keycode) {
case RAISE:
case LOWER:
return false;
default:
return true;
}
}

View File

@@ -0,0 +1,13 @@
# jdelkins layout
Features:
- 2x2u layout with the split spaces both operating as layer keys
- No top row numbers; rely on a keypad layer
- My typical leader setup for toggling modes, accessing secrets, etc.
# TODO
- Add/improve audio features
- Fix \_ADJUST layer - there's a bunch of junk on there that needs cleanng up.

View File

@@ -0,0 +1,4 @@
SRC += muse.c
LEADER_ENABLE = yes
TAP_DANCE_ENABLE = yes
AUTO_SHIFT_ENABLE = yes

View File

@@ -0,0 +1,25 @@
#pragma once
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
// #define STARTUP_SONG SONG(NO_SOUND)
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
SONG(COLEMAK_SOUND), \
SONG(DVORAK_SOUND) \
}
#endif
/*
* MIDI options
*/
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
// Most tactile encoders have detents every 4 stages
#define ENCODER_RESOLUTION 4

View File

@@ -0,0 +1,362 @@
/* Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "muse.h"
enum planck_layers {
_QWERTY,
_COLEMAK,
_DVORAK,
_LOWER,
_RAISE,
_PLOVER,
_ADJUST,
_NAV,
};
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
BACKLIT,
EXT_PLV
};
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define NAV MO(_NAV)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format off
/* 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,
LCTL_T(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, RSFT_T(KC_ENT),
BACKLIT, KC_LCTL, KC_LGUI, KC_LALT, LOWER, LT(_NAV, 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 |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | |MUSmod|Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|TermOn|TermOf| | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_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, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
[_NAV] = LAYOUT_planck_grid(
XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_UP, XXXXXXX, KC_MS_WH_UP, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_BTN1, KC_MS_BTN3, KC_MS_BTN2, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
)
};
// clang-format on
#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);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
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
writePinLow(E6);
#endif
} else {
unregister_code(KC_RSFT);
#ifdef KEYBOARD_planck_rev5
writePinHigh(E6);
#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;
bool encoder_update_user(uint16_t index, 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
tap_code(KC_MS_WH_DOWN);
#else
tap_code(KC_PGDN);
#endif
} else {
#ifdef MOUSEKEY_ENABLE
tap_code(KC_MS_WH_UP);
#else
tap_code(KC_PGUP);
#endif
}
}
return true;
}
void dip_switch_update_user(uint8_t index, bool active) {
switch (index) {
case 0: {
#ifdef AUDIO_ENABLE
static bool play_sound = false;
#endif
if (active) {
#ifdef AUDIO_ENABLE
if (play_sound) { PLAY_SONG(plover_song); }
#endif
layer_on(_ADJUST);
} else {
#ifdef AUDIO_ENABLE
if (play_sound) { PLAY_SONG(plover_gb_song); }
#endif
layer_off(_ADJUST);
}
#ifdef AUDIO_ENABLE
play_sound = true;
#endif
break;
}
case 1:
if (active) {
muse_mode = true;
} else {
muse_mode = false;
}
}
}
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;
} else {
if (muse_counter) {
stop_all_notes();
muse_counter = 0;
}
}
#endif
}
bool music_mask_user(uint16_t keycode) {
switch (keycode) {
case RAISE:
case LOWER:
return false;
default:
return true;
}
}

View File

@@ -0,0 +1,2 @@
# LJA83 Planck Layout

View File

@@ -0,0 +1 @@
SRC += muse.c

View File

@@ -36,6 +36,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 3
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 14
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
#define INDICATOR_PIN_0 A0
#define INDICATOR_PIN_1 A1

View File

@@ -56,6 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 14
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
#define INDICATOR_PIN_0 A9
#define INDICATOR_PIN_1 A8

65
keyboards/rubi/config.h Normal file
View File

@@ -0,0 +1,65 @@
/*
Copyright 2021 gregorio
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0x4752
#define PRODUCT_ID 0x5242
#define DEVICE_VER 0x0001
#define MANUFACTURER gregorio
#define PRODUCT Rubi
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 4
/*
* 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 { F0, F1, F4, F5, F6 }
#define MATRIX_COL_PINS { B3, B2, B1, F7 }
#define UNUSED_PINS
#define ENCODERS_PAD_A { D7 }
#define ENCODERS_PAD_B { D6 }
/* COL2ROW, ROW2COL */
#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
/* disable these deprecated features by default */
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define OLED_FONT_H "lib/glcdfont.c"

31
keyboards/rubi/info.json Normal file
View File

@@ -0,0 +1,31 @@
{
"keyboard_name": "Rubi",
"url": "https://github.com/ohchiko/qmk_firmware/tree/master/keyboards/rubi",
"maintainer": "gregorio",
"width": 4,
"height": 5,
"layouts": {
"LAYOUT": {
"layout": [
{"x":3, "y":0},
{"x":0, "y":1.25},
{"x":1, "y":1.25},
{"x":2, "y":1.25},
{"x":3, "y":1.25},
{"x":0, "y":2.25},
{"x":1, "y":2.25},
{"x":2, "y":2.25},
{"x":3, "y":2.25, "h":2},
{"x":0, "y":3.25},
{"x":1, "y":3.25},
{"x":2, "y":3.25},
{"x":0, "y":4.25},
{"x":1, "y":4.25},
{"x":2, "y":4.25},
{"x":3, "y":4.25, "h":2},
{"x":0, "y":5.25, "w":2},
{"x":2, "y":5.25}
]
}
}
}

View File

@@ -0,0 +1,89 @@
/* Copyright 2020 gregorio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
// enum custom_keycodes {
// FIRST = NEW_SAFE_RANGE,
// };
// Defines names for use in layer keycodes and the keymap
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Base */
[0] = LAYOUT(
ENC_PRESS,
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
KC_P7 , KC_P8 , KC_P9 , KC_PPLS,
KC_P4 , KC_P5 , KC_P6 ,
KC_P1 , KC_P2 , KC_P3 , KC_PENT,
KC_P0 , LT(2, KC_PDOT)
),
[1] = LAYOUT(
KC_TRNS,
KC_C , KC_SLSH, CL_STAR, KC_MINS,
KC_7 , KC_8 , KC_9 , CL_PLUS,
KC_4 , KC_5 , KC_6 ,
KC_1 , KC_2 , KC_3 , KC_EQL,
KC_0 , KC_DOT
),
[2] = LAYOUT(
KC_TRNS,
KC_TRNS, KC_N , KC_S , KC_R ,
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
),
[3] = LAYOUT(
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, RESET , KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS
),
};
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
if (get_highest_layer(layer_state) == 0) {
uint16_t mapped_code = 0;
if (clockwise) {
mapped_code = handle_encoder_cw();
} else {
mapped_code = handle_encoder_ccw();
}
if (mapped_code != 0) {
tap_code16(mapped_code);
}
} else {
if (clockwise) {
if (oled_mode == OLED_MODE_CALC) {
handle_encoder_cw();
} else if (oled_mode == OLED_MODE_DEFAULT) {
change_encoder_mode(false);
}
} else {
if (oled_mode == OLED_MODE_CALC) {
handle_encoder_ccw();
} else if (oled_mode == OLED_MODE_DEFAULT) {
change_encoder_mode(true);
}
}
}
}
return true;
}

View File

@@ -0,0 +1,4 @@
# The default keymap for Rubi
[KLE](http://www.keyboard-layout-editor.com/#/gists/984e9039971cf4738d507150b4494190)
![Rubi Default Keymap](https://i.imgur.com/bsG8BdW.jpg)

View File

@@ -0,0 +1,84 @@
/* Copyright 2020 gregorio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Base */
[0] = LAYOUT(
ENC_PRESS,
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
KC_P7 , KC_P8 , KC_P9 , KC_PPLS,
KC_P4 , KC_P5 , KC_P6 ,
KC_P1 , KC_P2 , KC_P3 , KC_PENT,
KC_P0 , LT(2, KC_PDOT)
),
[1] = LAYOUT(
KC_TRNS,
KC_C , KC_SLSH, CL_STAR, KC_MINS,
KC_7 , KC_8 , KC_9 , CL_PLUS,
KC_4 , KC_5 , KC_6 ,
KC_1 , KC_2 , KC_3 , KC_EQL,
KC_0 , KC_DOT
),
[2] = LAYOUT(
KC_TRNS,
KC_TRNS, KC_N , KC_S , KC_R ,
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
),
[3] = LAYOUT(
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, RESET , KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS
),
};
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
if (get_highest_layer(layer_state) == 0) {
uint16_t mapped_code = 0;
if (clockwise) {
mapped_code = handle_encoder_cw();
} else {
mapped_code = handle_encoder_ccw();
}
if (mapped_code != 0) {
tap_code16(mapped_code);
}
} else {
if (clockwise) {
if (oled_mode == OLED_MODE_CALC) {
handle_encoder_cw();
} else if (oled_mode == OLED_MODE_DEFAULT) {
change_encoder_mode(false);
}
} else {
if (oled_mode == OLED_MODE_CALC) {
handle_encoder_ccw();
} else if (oled_mode == OLED_MODE_DEFAULT) {
change_encoder_mode(true);
}
}
}
}
return true;
}

View File

@@ -0,0 +1,2 @@
VIA_ENABLE = yes
LTO_ENABLE = yes

261
keyboards/rubi/lib/calc.c Normal file
View File

@@ -0,0 +1,261 @@
/*
This is the modified version of [calculator by MWWorks](https://github.com/MWWorks/mw_calc_numpad/blob/master/calc.c). Below is the quote from [MWWorks](https://github.com/MWWorks).
Calculator for QMK-based keyboard by MWWorks, https://mwworks.uk
This is free, usual disclaimers, don't use it to calculate megaton yields, surgery plans, etc
I did not plan to reinvent the wheel for this - I figured surely somebody somewhere has working calculator code?
Found lots but none that actually work like you expect a calculator to, hence DIYing it
As such, this is probably a bit janky, especially as I am a bit of a hack at C
Seems to be working well, with occasional glitchs, solved by clearing it
And some occasional floating-point issues - eg get a long decimal rather than the whole number you were expecting
Feel free to fix it! I think it needs to detect the precision of the two operands and then figure out what the precision of the result should be
*/
#include "rubi.h"
static uint8_t calc_current_operand = 0;
static char calc_operand_0[CALC_DIGITS+1] = "";
static char calc_operand_1[CALC_DIGITS+1] = "";
char calc_result[CALC_DIGITS+1] = "";
static char calc_status[CALC_DIGITS+1] = "";
static char calc_operator = ' ';
static bool calc_reset = false;
void calcBegin(void){
}
//update display
void calcUpdate(void){
if (calc_display_lines == 2) {
if((calc_current_operand == 1) || (calc_reset)){
strcpy(calc_status, calc_operand_0);
if((strlen(calc_operand_0)>0) || (strlen(calc_operand_1)>0)){
uint8_t len = strlen(calc_status);
if (!(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')) {
calc_status[len] = calc_operator;
}
calc_status[len+1] = 0;
if(calc_reset
&& !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){
strncat(calc_status, calc_operand_1, CALC_DIGITS-strlen(calc_status));
calc_operator = ' ';
}
}
strcpy(calc_status_display, calc_status);
}
} else if (calc_display_lines == 1) {
if(calc_reset
&& !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){
calc_operator = ' ';
}
}
calc_operator_display = calc_operator;
strcpy(calc_result_display, calc_result);
}
//perform calculation on the 2 operands
void calcOperands(void){
float result = 0;
switch (calc_operator){
//standard operators
case '+':
result = strtod(calc_operand_0, NULL) + strtod(calc_operand_1, NULL);
break;
case '-':
result = strtod(calc_operand_0, NULL) - strtod(calc_operand_1, NULL);
break;
case '/':
result = strtod(calc_operand_0, NULL) / strtod(calc_operand_1, NULL);
break;
case '*':
result = strtod(calc_operand_0, NULL) * strtod(calc_operand_1, NULL);
break;
//single operand operators - these are all in 2
case 's':
result = sqrt(strtod(calc_operand_0, NULL));
break;
case 'r':
result = 1/(strtod(calc_operand_0, NULL));
break;
}
//now convert the float result into a string
//we know the total string size but we need to find the size of the integer component to know how much we have for decimals
uint8_t magnitude = ceil(log10(result));
uint8_t max_decimals = CALC_DIGITS-magnitude-1;
//but max it at 7 because that seems the useful limit of our floats
if(max_decimals>7){
max_decimals = 7;
}
dtostrf(result, CALC_DIGITS, max_decimals, calc_result);
//now to clean up the result - we need it clean as it may be the input of next calculation
//this seems a lot of code to format this string :| note that this c doesn't support float in sprintf
uint8_t i;
//first find if theres a dot
uint8_t dotpos = CALC_DIGITS+1;
for(i=0; i<strlen(calc_result); i++){
if(calc_result[i] == '.'){
dotpos = i;
break;
}
}
//if there is, work back to it and remove trailing 0 or .
if(dotpos>=0){
for(i=strlen(calc_result)-1; i>=dotpos; i--){
if((calc_result[i] == '0') || (calc_result[i] == '.')){
calc_result[i] = 0;
}else{
break;
}
}
}
//now find how many leading spaces
uint8_t spaces = 0;
for(i=0; i<strlen(calc_result); i++){
if(calc_result[i] == ' '){
spaces++;
}else{
break;
}
}
//and shift the string
for(i=0; i<strlen(calc_result)-spaces; i++){
calc_result[i] = calc_result[i+spaces];
}
calc_result[strlen(calc_result)-spaces] = 0;
calcUpdate();
//the result is available as the first operand for another calculation
strcpy(calc_operand_0, calc_result);
calc_operand_1[0] = 0;
}
void calcInput(char input){
char *operand = calc_operand_0;
if(calc_current_operand == 1){
operand = calc_operand_1;
}
uint8_t len = strlen(operand);
if(
((input >= 48) && (input <= 57)) ||
(input == '.')
){
//if this is following an equals, then we start from scratch as if new calculation
if(calc_reset == true){
calc_reset = false;
calc_current_operand = 0;
calc_operand_0[0] = 0;
calc_operand_1[0] = 0;
operand = calc_operand_0;
len = 0;
}
if(len<CALC_DIGITS){
operand[len] = input;
operand[len+1] = 0;
strcpy(calc_result, operand);
calcUpdate();
}
//special input to backspace
}else if(input == 'x'){
operand[len-1] = 0;
strcpy(calc_result, operand);
calcUpdate();
//clear
}else if(input == 'c'){
operand[0] = 0;
calc_operand_0[0] = 0;
calc_operand_1[0] = 0;
calc_operator = ' ';
calc_reset = true;
strcpy(calc_result, operand);
calcUpdate();
//special input switch neg/pos
}else if((input == 'n') && (len>0)){
uint8_t i;
if(operand[0] == '-'){
for(i=1; i<=len; i++){
operand[i-1] = operand[i];
}
}else if(len<CALC_DIGITS){
for(i=0; i<=len; i++){
operand[len-i+1] = operand[len-i];
}
operand[0] = '-';
}
calc_operator = input;
strcpy(calc_result, operand);
calcUpdate();
//standard 2 operand operators
}else if((input == '+') || (input == '-') || (input == '*') || (input == '/')){
//get ready for second operand
if(calc_current_operand == 0){
calc_operator = input;
calc_current_operand = 1;
calcUpdate();
//we pressed = we now expect a new second operand
}else if(calc_reset){
calc_operator = input;
calc_reset = false;
calc_operand_1[0] = 0;
calcUpdate();
}else {
//if we use this on the second operand, calculate first, then ready for a second operand again
if (strlen(calc_operand_1)>0){
calcOperands();
}
calc_operand_1[0] = 0;
calc_operator = input;
calcUpdate();
}
}else if(input == '='){
//only accept = if we are on the second operand
if(calc_current_operand == 1){
//keep the second operand for a subsequent press of =; but flag to reset if start entry of new operand
calc_reset = true;
calcOperands();
}
//single operands - square root and reciprocal - needs to operate on 0 so it works after a previous = result
}else if((input == 's') || (input == 'r')){
//but maybe we started entering 1
if(calc_current_operand == 1 && !calc_reset){
strcpy(calc_operand_0, calc_operand_1);
}
calc_current_operand = 1;
calc_operand_1[0] = 0;
calc_operator = input;
calc_reset = true; //simulate another =
calcOperands();
}
}

View File

@@ -0,0 +1,115 @@
/*
Copyright 2021 gregorio
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rubi.h"
void change_encoder_mode(bool reverse) {
if (reverse) {
if (encoder_mode == 0) {
encoder_mode = _NUM_ENCODER_MODES - 1;
} else {
encoder_mode = encoder_mode - 1;
}
} else {
encoder_mode = (encoder_mode + 1) % _NUM_ENCODER_MODES;
}
}
uint16_t handle_encoder_cw(void) {
uint16_t mapped_code = 0;
if (oled_mode == OLED_MODE_CALC) {
layer_on(2);
return mapped_code;
}
switch (encoder_mode) {
default:
case ENC_MODE_VOLUME:
mapped_code = KC_VOLU;
break;
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_NEXT_TRACK;
break;
case ENC_MODE_BRIGHTNESS:
mapped_code = KC_BRIGHTNESS_UP;
break;
}
return mapped_code;
}
uint16_t handle_encoder_ccw(void) {
uint16_t mapped_code = 0;
if (oled_mode == OLED_MODE_CALC) {
layer_off(2);
return mapped_code;
}
switch (encoder_mode) {
default:
case ENC_MODE_VOLUME:
mapped_code = KC_VOLD;
break;
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_PREV_TRACK;
break;
case ENC_MODE_BRIGHTNESS:
mapped_code = KC_BRIGHTNESS_DOWN;
break;
}
return mapped_code;
}
uint16_t handle_encoder_press(void) {
uint16_t mapped_code = 0;
if (get_highest_layer(layer_state) == 1) {
if (oled_mode == OLED_MODE_CALC) {
layer_on(3);
}
layer_off(1);
return mapped_code;
} else if (get_highest_layer(layer_state) == 2) {
if (oled_mode == OLED_MODE_CALC) {
layer_off(1);
layer_on(3);
} else {
layer_on(1);
}
layer_off(2);
return mapped_code;
} else if (get_highest_layer(layer_state) == 3) {
if (oled_mode == OLED_MODE_OFF) {
layer_off(3);
}
return mapped_code;
}
switch (encoder_mode) {
default:
case ENC_MODE_VOLUME:
mapped_code = KC_MUTE;
break;
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_PLAY_PAUSE;
break;
}
return mapped_code;
}

View File

@@ -0,0 +1,246 @@
/* Copyright 2021 gregorio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "progmem.h"
const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
0x18, 0x3C, 0x7E, 0xBC, 0x18, 0x00,
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
0x5A, 0x3C, 0x66, 0x3C, 0x5A, 0x00,
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5E, 0x00, 0x00, 0x00,
0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x26, 0x16, 0x08, 0x34, 0x32, 0x00,
0x36, 0x4A, 0x56, 0x20, 0x50, 0x00,
0x00, 0x0A, 0x06, 0x00, 0x00, 0x00,
0x00, 0x3C, 0x42, 0x00, 0x00, 0x00,
0x00, 0x00, 0x42, 0x3C, 0x00, 0x00,
0x14, 0x08, 0x3E, 0x08, 0x14, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0xA0, 0x60, 0x00, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x45, 0x45, 0x3B, 0x00,
0x38, 0x26, 0x21, 0x7F, 0x20, 0x00,
0x2F, 0x49, 0x49, 0x49, 0x31, 0x00,
0x3E, 0x49, 0x49, 0x49, 0x31, 0x00,
0x01, 0x01, 0x61, 0x19, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x4E, 0x51, 0x51, 0x51, 0x3E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x00, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x00, 0x22, 0x14, 0x08, 0x00,
0x00, 0x04, 0x52, 0x0A, 0x04, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7E, 0x09, 0x09, 0x09, 0x7E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x49, 0x49, 0x3A, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x20, 0x41, 0x41, 0x3F, 0x00, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x04, 0x02, 0x7F, 0x00,
0x7F, 0x02, 0x04, 0x08, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x01, 0x01, 0x7F, 0x01, 0x01, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x07, 0x08, 0x70, 0x08, 0x07, 0x00,
0x61, 0x51, 0x49, 0x45, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x00, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x00, 0x06, 0x0A, 0x00, 0x00,
0x20, 0x54, 0x54, 0x54, 0x78, 0x00,
0x7E, 0x48, 0x48, 0x48, 0x30, 0x00,
0x30, 0x48, 0x48, 0x48, 0x48, 0x00,
0x30, 0x48, 0x48, 0x48, 0x7E, 0x00,
0x38, 0x54, 0x54, 0x54, 0x58, 0x00,
0x00, 0x08, 0x7C, 0x0A, 0x00, 0x00,
0x98, 0xA4, 0xA4, 0xA4, 0x78, 0x00,
0x7E, 0x08, 0x08, 0x08, 0x70, 0x00,
0x00, 0x00, 0x7A, 0x00, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3A, 0x00, 0x00,
0x7E, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x04, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0xFC, 0x24, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x24, 0xFC, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x00, 0x04, 0x7E, 0x44, 0x00, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x5C, 0xA0, 0xA0, 0xA0, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
0x7E, 0xFF, 0x81, 0xFB, 0xF7, 0xEF,
0x81, 0xFF, 0xC1, 0xBF, 0xBF, 0xBF,
0xC1, 0xFF, 0x81, 0xFB, 0xF7, 0xFB,
0x81, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
0xDB, 0xFF, 0x83, 0xED, 0xED, 0xED,
0x83, 0xFF, 0x81, 0xED, 0xED, 0xED,
0xF3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xE1, 0xDF, 0xBF, 0xDF,
0xE1, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
0xC3, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
0xCB, 0xFF, 0x81, 0xED, 0xCD, 0xAD,
0xB3, 0xFF, 0xFD, 0xFD, 0x81, 0xFD,
0xFD, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
0xDB, 0xFF, 0x83, 0xED, 0xED, 0xED,
0x83, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x08, 0x3E,
0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x6F, 0x5F, 0x63,
0x7B, 0x7B, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x7F, 0x59, 0x6F,
0x77, 0x7B, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x14, 0x08, 0x3E,
0x08, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x08, 0x2A,
0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x04, 0x08, 0x10,
0x7E, 0x00, 0x3E, 0x40, 0x40, 0x40,
0x3E, 0x00, 0x7E, 0x04, 0x08, 0x04,
0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x42, 0x42, 0x42,
0x24, 0x00, 0x7C, 0x12, 0x12, 0x12,
0x7C, 0x00, 0x7E, 0x12, 0x12, 0x12,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0x81, 0xFB, 0xE7, 0xFB,
0x81, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
0xBD, 0xFF, 0x81, 0xBD, 0xBD, 0xBD,
0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
0xCB, 0xFF, 0x81, 0xEF, 0xF7, 0xEB,
0x9D, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0x81, 0xED, 0xED, 0xED,
0xF3, 0xFF, 0x83, 0xED, 0xED, 0xED,
0x83, 0xFF, 0x81, 0xBD, 0xBD, 0xBD,
0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x77, 0x6F, 0x77,
0x7B, 0x77, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x08, 0x10, 0x08,
0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x77, 0x77, 0x55,
0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xB3, 0xAD, 0xAD, 0xAD,
0xDB, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
0xDB, 0xFF, 0x81, 0xED, 0xCD, 0xAD,
0xB3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x20, 0x1C,
0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x42, 0x42, 0x42,
0x24, 0x00, 0x7C, 0x12, 0x12, 0x12,
0x7C, 0x00, 0x7E, 0x40, 0x40, 0x40,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x12, 0x12, 0x12,
0x0C, 0x00, 0x7C, 0x12, 0x12, 0x12,
0x7C, 0x00, 0x7E, 0x42, 0x42, 0x42,
0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xFF, 0xBB, 0x81, 0xBF,
0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0x9B, 0xAD, 0xAD, 0xAD,
0xB3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xDD, 0xBD, 0xB5, 0xB5,
0xC9, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xE7, 0xEB, 0xED, 0x81,
0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x7E, 0xFF, 0xD1, 0xB5, 0xB5, 0xB5,
0xCD, 0xFF, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x77, 0x77, 0x41,
0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x77, 0x77, 0x77,
0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x6B, 0x77, 0x41,
0x77, 0x6B, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x4C, 0x52, 0x52, 0x52,
0x24, 0x00, 0x3C, 0x42, 0x42, 0x42,
0x24, 0x00, 0x7E, 0x12, 0x32, 0x52,
0x4C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x26, 0x10,
0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
};

268
keyboards/rubi/lib/oled.c Normal file
View File

@@ -0,0 +1,268 @@
/*
Copyright 2021 gregorio
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "./lib/oled.h"
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
return process_record_user(keycode, record);
}
void change_oled_mode(void) {
oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
}
void render_layer_section(void) {
// Layer indicators
static const char PROGMEM layer_0[] = {0xc8, 0xc9, 0};
static const char PROGMEM layer_1[] = {0xca, 0xcb, 0};
static const char PROGMEM layer_2[] = {0xcc, 0xcd, 0};
static const char PROGMEM layer_3[] = {0xce, 0xcf, 0};
oled_set_cursor(oled_max_chars()-15, 0);
oled_write_P(PSTR("LAYER"), false);
switch (get_highest_layer(layer_state)) {
case 0:
oled_write_P(layer_0, false);
break;
case 1:
oled_write_P(layer_1, false);
break;
case 2:
oled_write_P(layer_2, false);
break;
case 3:
oled_write_P(layer_3, false);
break;
default:
oled_write_P(PSTR("? "), false);
break;
}
}
void render_encoder_section(void) {
static const char PROGMEM enc_vol[] = {0x88, 0x89, 0x8a, 0x8b, 0};
static const char PROGMEM enc_med[] = {0xa8, 0xa9, 0xaa, 0xab, 0};
static const char PROGMEM enc_brt[] = {0x8c, 0x8d, 0x8e, 0x8f, 0};
oled_set_cursor(oled_max_chars()-7, 0);
oled_write_P(PSTR("ENC"), false);
switch (encoder_mode) {
default:
case ENC_MODE_VOLUME:
oled_write_P(enc_vol, false);
break;
case ENC_MODE_MEDIA:
oled_write_P(enc_med, false);
break;
case ENC_MODE_BRIGHTNESS:
oled_write_P(enc_brt, false);
break;
}
}
void render_numlock_section(void) {
static const char PROGMEM num_on[] = {0x80, 0x81, 0x82, 0x83, 0};
static const char PROGMEM num_off[] = {0xa0, 0xa1, 0xa2, 0xa3, 0};
static const char PROGMEM cap_on[] = {0x84, 0x85, 0x86, 0x87, 0};
static const char PROGMEM cap_off[] = {0xa4, 0xa5, 0xa6, 0xa7, 0};
static const char PROGMEM scr_on[] = {0xba, 0xbb, 0xbc, 0xbd, 0};
static const char PROGMEM scr_off[] = {0xda, 0xdb, 0xdc, 0xdd, 0};
led_t led_state = host_keyboard_led_state();
oled_set_cursor(oled_max_chars()-12, 3);
// num lock
oled_write_P(led_state.num_lock ? num_on : num_off, false);
oled_write_P(led_state.caps_lock ? cap_on : cap_off, false);
oled_write_P(led_state.scroll_lock ? scr_on : scr_off, false);
}
void render_mode_section(void) {
static const char PROGMEM pad_on[] = {0xb0, 0xb1, 0xb2, 0xb3, 0};
static const char PROGMEM pad_off[] = {0xc4, 0xc5, 0xc6, 0xc7, 0};
static const char PROGMEM cal_on[] = {0x90, 0x91, 0x92, 0x93, 0};
static const char PROGMEM cal_off[] = {0xc0, 0xc1, 0xc2, 0xc3, 0};
if (oled_mode == OLED_MODE_CALC) {
oled_set_cursor(0, 0);
oled_write_P(pad_off, false);
oled_set_cursor(0, 1);
oled_write_P(cal_on, false);
} else {
oled_set_cursor(0, 0);
oled_write_P(pad_on, false);
oled_set_cursor(0, 1);
oled_write_P(cal_off, false);
}
}
void render_calc_section(void) {
static const char PROGMEM add_on[] = {0xd4, 0xd5, 0};
static const char PROGMEM add_off[] = {0x94, 0x95, 0};
static const char PROGMEM sub_on[] = {0xd6, 0xd7, 0};
static const char PROGMEM sub_off[] = {0x96, 0x97, 0};
static const char PROGMEM mul_on[] = {0xd8, 0xd9, 0};
static const char PROGMEM mul_off[] = {0x9c, 0x9d, 0};
static const char PROGMEM div_on[] = {0xb8, 0xb9, 0};
static const char PROGMEM div_off[] = {0x9e, 0x9f, 0};
static const char PROGMEM sqr_on[] = {0x98, 0x99, 0};
static const char PROGMEM sqr_off[] = {0xbe, 0xbf, 0};
static const char PROGMEM rec_on[] = {0x9a, 0x9b, 0};
static const char PROGMEM rec_off[] = {0xde, 0xdf, 0};
static const char PROGMEM neg_on[] = {0xb4, 0xb5, 0};
static const char PROGMEM neg_off[] = {0xb6, 0xb7, 0};
if (oled_mode == OLED_MODE_CALC) {
if (get_highest_layer(layer_state) == 1) {
oled_set_cursor(oled_max_chars()-8, 0);
switch (calc_operator_display) {
case '+':
oled_write_P(div_off, false);
oled_write_P(mul_off, false);
oled_write_P(sub_off, false);
oled_write_P(add_on, false);
break;
case '-':
oled_write_P(div_off, false);
oled_write_P(mul_off, false);
oled_write_P(sub_on, false);
oled_write_P(add_off, false);
break;
case '*':
oled_write_P(div_off, false);
oled_write_P(mul_on, false);
oled_write_P(sub_off, false);
oled_write_P(add_off, false);
break;
case '/':
oled_write_P(div_on, false);
oled_write_P(mul_off, false);
oled_write_P(sub_off, false);
oled_write_P(add_off, false);
break;
case 's':
case 'r':
case 'n':
layer_on(2);
break;
default:
oled_write_P(div_off, false);
oled_write_P(mul_off, false);
oled_write_P(sub_off, false);
oled_write_P(add_off, false);
break;
}
} else if (get_highest_layer(layer_state) == 2) {
oled_set_cursor(oled_max_chars()-6, 0);
switch (calc_operator_display) {
case '+':
case '-':
case '*':
case '/':
layer_off(2);
break;
case 's':
oled_write_P(neg_off, false);
oled_write_P(sqr_on, false);
oled_write_P(rec_off, false);
break;
case 'r':
oled_write_P(neg_off, false);
oled_write_P(sqr_off, false);
oled_write_P(rec_on, false);
break;
case 'n':
oled_write_P(neg_on, false);
oled_write_P(sqr_off, false);
oled_write_P(rec_off, false);
break;
default:
oled_write_P(neg_off, false);
oled_write_P(sqr_off, false);
oled_write_P(rec_off, false);
break;
}
}
if (calc_display_lines == 1) {
oled_set_cursor(oled_max_chars()-strlen(calc_result_display)-2, 3);
oled_write_char(calc_operator_display, false);
} else if (calc_display_lines == 2) {
oled_set_cursor(oled_max_chars()-strlen(calc_status_display), 2);
oled_write(calc_status_display, false);
}
oled_set_cursor(oled_max_chars()-strlen(calc_result_display), 3);
oled_write(calc_result_display, false);
}
}
static void render_logo(void) {
oled_write_raw_P(raw_logo, sizeof(raw_logo));
}
void render_frame(void) {
if (oled_logo_expired) {
if (oled_mode == OLED_MODE_DEFAULT) {
render_mode_section();
render_layer_section();
render_encoder_section();
render_numlock_section();
} else if (oled_mode == OLED_MODE_CALC) {
render_mode_section();
render_calc_section();
} else if (oled_mode == OLED_MODE_OFF) {
if (is_oled_on()) {
oled_off();
}
}
} else {
render_logo();
oled_logo_expired = timer_elapsed(oled_logo_timer) > OLED_LOGO_TIMEOUT;
}
}
__attribute__((weak)) void oled_task_user(void) {
if (timer_elapsed(oled_frame_timer) > OLED_FRAME_TIMEOUT) {
oled_clear();
oled_frame_timer = timer_read();
render_frame();
}
if (get_highest_layer(layer_state) == 1) {
oled_mode = OLED_MODE_CALC;
} else if (get_highest_layer(layer_state) == 2) {
if (IS_LAYER_ON(1)) {
oled_mode = OLED_MODE_CALC;
} else {
oled_mode = OLED_MODE_DEFAULT;
}
} else if (get_highest_layer(layer_state) == 3) {
oled_mode = OLED_MODE_OFF;
} else {
oled_mode = OLED_MODE_DEFAULT;
}
}
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
oled_logo_timer = timer_read();
oled_frame_timer = timer_read();
return rotation;
}

32
keyboards/rubi/lib/oled.h Normal file
View File

@@ -0,0 +1,32 @@
/*
Copyright 2021 gregorio
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define OLED_FRAME_TIMEOUT (1000 / 30) // 30 fps
#define OLED_LOGO_TIMEOUT 3000 // 3 sec
static uint16_t oled_frame_timer = 0;
static uint16_t oled_logo_timer = 0;
static bool oled_logo_expired = false;
static const char PROGMEM raw_logo[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,128,128,128,128, 0, 0, 0, 0, 0, 0, 0,128,128,128,128,128,128,128,128,128,128,128, 0, 0, 0, 0, 0, 0,128,128,128,128, 0, 0, 0, 0, 0, 0,128,128,128,128, 0, 0,128,128,128,128,128,128,128,128,128,128,128, 0, 0, 0, 0, 0,128,128,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,224,112,184,220,204,182,123,254,251,187,223,231,203,126,254, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,248, 8, 8, 8, 8, 8,249,225, 2, 12,248, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0,255,255,255,255, 0, 0,255,255,255,255,199,199,199,199,199,207,255,255,254,124, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127,191,188,211,223,223,247,187,187,252,126,123,247,239,223,190,115,142, 0, 0, 0, 0, 0,255, 0, 0, 0,227, 34, 34, 34, 98,194, 1, 56,236,135, 1, 0, 0, 31, 63,127,255,248,240,240,240,240,248,255,127, 63, 31, 0, 0,255,255,255,255,227,227,227,227,227,243,255,255,127, 62, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

23
keyboards/rubi/readme.md Normal file
View File

@@ -0,0 +1,23 @@
# Rubi
![Rubi](https://i.imgur.com/XUzxe0rh.jpg)
[Proto Album](https://imgur.com/a/QVtU7hV)
A 4x5 layout numpad with rotary encoder, LED indicator and OLED screen, featuring a basic calculator inside the OLED screen. The PCB supports both hotswap and solderable switch. Currently the PCB and case can only be purchased in Indonesia.
* Keyboard Maintainer: [ohchiko](https://github.com/ohchiko)
* Hardware Supported: Rubi PCB Rev. A, ATMega32u4
* Hardware Availability: Local Indonesia GB.
Make example for this keyboard (after setting up your build environment):
make rubi:default
Flashing example for this keyboard:
make rubi:default:flash
To put this keyboard into bootloader mode (for flashing firmware), simply activate layer 3 and press the middle key (key "5" on the proto picture) on the default keymap.
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).

79
keyboards/rubi/rubi.c Normal file
View File

@@ -0,0 +1,79 @@
/* Copyright 2021 gregorio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rubi.h"
uint8_t oled_mode = OLED_MODE_DEFAULT;
char calc_result_display[CALC_DIGITS+1] = "";
char calc_operator_display = ' ';
char calc_status_display[CALC_DIGITS+1] = "";
uint8_t calc_display_lines = 2;
const char keycode_to_ascii_lut[58] = {0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t', ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/'};
uint8_t encoder_mode = ENC_MODE_VOLUME;
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
if (keycode < 58 && keycode != KC_TAB) {
if (record->event.pressed) {
calcInput(keycode_to_ascii_lut[(uint8_t)keycode]);
}
return false;
}
switch (keycode) {
case ENC_PRESS:
if (record->event.pressed) {
uint16_t mapped_code = handle_encoder_press();
if (mapped_code != 0) {
tap_code16(mapped_code);
}
}
return false;
case CL_PLUS:
if (record->event.pressed) {
calcInput('+');
}
return false;
case CL_STAR:
if (record->event.pressed) {
calcInput('*');
}
return false;
case CL_TYPE:
if (record->event.pressed) {
send_string(calc_result_display);
}
return false;
default:
break;
}
return process_record_user_oled(keycode, record);
}
bool led_update_kb(led_t led_state) {
bool res = led_update_user(led_state);
if (res) {
writePin(C6, led_state.num_lock);
}
return true;
}
bool encoder_update_kb(uint8_t index, bool clockwise) {
if (!encoder_update_user(index, clockwise)) { return false; }
return true;
}

102
keyboards/rubi/rubi.h Normal file
View File

@@ -0,0 +1,102 @@
/* Copyright 2021 gregorio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#define CALC_DIGITS 12
enum rubi_keycodes {
ENC_PRESS = SAFE_RANGE,
CL_PLUS,
CL_STAR,
CL_TYPE,
NEW_SAFE_RANGE
};
enum oled_modes {
OLED_MODE_DEFAULT,
OLED_MODE_CALC,
OLED_MODE_OFF,
_NUM_OLED_MODES
};
enum encoder_modes {
ENC_MODE_VOLUME,
ENC_MODE_MEDIA,
ENC_MODE_BRIGHTNESS,
_NUM_ENCODER_MODES
};
extern uint8_t current_layer;
extern uint8_t oled_mode;
extern uint8_t encoder_mode;
extern char calc_result_display[CALC_DIGITS+1];
extern char calc_operator_display;
extern char calc_status_display[CALC_DIGITS+1];
extern uint8_t calc_display_lines;
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
void change_oled_mode(void);
void change_encoder_mode(bool reverse);
uint16_t handle_encoder_cw(void);
uint16_t handle_encoder_ccw(void);
uint16_t handle_encoder_press(void);
void calcUpdate(void);
void calcInput(char input);
void calcOperands(void);
/* This is a shortcut to help you visually see your layout.
*
* The first section contains all of the arguments representing the physical
* layout of the board and position of the keys.
*
* The second converts the arguments into a two-dimensional array which
* represents the switch matrix.
*/
/* Rubi matrix layout
* ,---------------.
* | 23|
* |---------------|
* | 00| 01| 02| 03|
* |---------------|
* | 10| 11| 12| |
* |-----------| 13|
* | 20| 21| 22| |
* |---------------|
* | 30| 31| 32| |
* |-----------| 33|
* | 41 | 42| |
* `---------------'
*/
#define LAYOUT( \
k23, \
k00, k01, k02, k03, \
k10, k11, k12, k13, \
k20, k21, k22, \
k30, k31, k32, k33, \
k41, k42 \
) { \
{ k00, k01, k02, k03 }, \
{ k10, k11, k12, k13 }, \
{ k20, k21, k22, k23 }, \
{ k30, k31, k32, k33 }, \
{ KC_NO, k41, k42, KC_NO } \
}

28
keyboards/rubi/rules.mk Normal file
View File

@@ -0,0 +1,28 @@
# MCU name
MCU = atmega32u4
# Bootloader selection
BOOTLOADER = atmel-dfu
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
OLED_DRIVER_ENABLE = yes
ENCODER_ENABLE = yes
SRC += lib/oled.c \
lib/encoder.c \
lib/calc.c

View File

@@ -67,6 +67,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// SPI RGB Driver
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
#define WS2812_SPI_SCK_PAL_MODE 0
#define WS2812_SPI_SCK_PIN B13
// OLED defines
#define OLED_TIMEOUT 60000

View File

@@ -17,12 +17,12 @@ def automagic_keyboard(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Ensure that `--keyboard` was not passed and CWD is under `qmk_firmware/keyboards`
if cli.config_source[cli._entrypoint.__name__]['keyboard'] != 'argument':
if cli.config_source[cli._subcommand.__name__]['keyboard'] != 'argument':
keyboard = find_keyboard_from_dir()
if keyboard:
cli.config[cli._entrypoint.__name__]['keyboard'] = keyboard
cli.config_source[cli._entrypoint.__name__]['keyboard'] = 'keyboard_directory'
cli.config[cli._subcommand.__name__]['keyboard'] = keyboard
cli.config_source[cli._subcommand.__name__]['keyboard'] = 'keyboard_directory'
return func(*args, **kwargs)
@@ -37,12 +37,12 @@ def automagic_keymap(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Ensure that `--keymap` was not passed and that we're under `qmk_firmware`
if cli.config_source[cli._entrypoint.__name__]['keymap'] != 'argument':
if cli.config_source[cli._subcommand.__name__]['keymap'] != 'argument':
keymap_name, keymap_type = find_keymap_from_dir()
if keymap_name:
cli.config[cli._entrypoint.__name__]['keymap'] = keymap_name
cli.config_source[cli._entrypoint.__name__]['keymap'] = keymap_type
cli.config[cli._subcommand.__name__]['keymap'] = keymap_name
cli.config_source[cli._subcommand.__name__]['keymap'] = keymap_type
return func(*args, **kwargs)

1
users/jdelkins/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
secrets.h

274
users/jdelkins/jdelkins.c Normal file
View File

@@ -0,0 +1,274 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jdelkins.h"
#include "version.h"
#ifdef DO_SECRETS
# include "secrets.h"
#else
# ifndef NO_SECRETS
# pragma message("Warning: secrets.h not found")
# endif
#endif
user_config_t user_config;
__attribute__ ((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
void send_secret_string(uint8_t n) {
#ifdef DO_SECRETS
send_string(secret[n]);
#else
SEND_STRING("");
#endif
}
#ifdef TAP_DANCE_ENABLE
// To activate SINGLE_HOLD, you will need to hold for 200ms first.
// This tap dance favors keys that are used frequently in typing like 'f'
int cur_dance(qk_tap_dance_state_t *state) {
if (state->count == 1) {
// If count = 1, and it has been interrupted - it doesn't matter if it
// is pressed or not: Send SINGLE_TAP
if (state->interrupted) {
// if (!state->pressed) return SINGLE_TAP;
// need "permissive hold" here.
// else return SINsGLE_HOLD;
// If the interrupting key is released before the tap-dance key,
// then it is a single HOLD However, if the tap-dance key is
// released first, then it is a single TAP But how to get access to
// the state of the interrupting key????
return SINGLE_TAP;
} else {
if (!state->pressed)
return SINGLE_TAP;
else
return SINGLE_HOLD;
}
}
// If count = 2, and it has been interrupted - assume that user is trying to
// type the letter associated with single tap.
else if (state->count == 2) {
if (state->interrupted)
return DOUBLE_SINGLE_TAP;
else if (state->pressed)
return DOUBLE_HOLD;
else
return DOUBLE_TAP;
} else if ((state->count == 3) && ((state->interrupted) || (!state->pressed)))
return TRIPLE_TAP;
else if (state->count == 3)
return TRIPLE_HOLD;
else
return 8; // magic number. At some point this method will expand to work for more presses
}
// This works well if you want this key to work as a "fast modifier". It favors
// being held over being tapped.
int hold_cur_dance(qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted) {
if (!state->pressed)
return SINGLE_TAP;
else
return SINGLE_HOLD;
} else {
if (!state->pressed)
return SINGLE_TAP;
else
return SINGLE_HOLD;
}
}
// If count = 2, and it has been interrupted - assume that user is trying to
// type the letter associated with single tap.
else if (state->count == 2) {
if (state->pressed)
return DOUBLE_HOLD;
else
return DOUBLE_TAP;
} else if (state->count == 3) {
if (!state->pressed)
return TRIPLE_TAP;
else
return TRIPLE_HOLD;
} else
return 8; // magic number. At some point this method will expand to work for more presses
}
#endif // TAP_DANCE_ENABLE
__attribute__ ((weak))
void keyboard_post_init_keymap(void) {
}
void keyboard_post_init_user(void) {
user_config.raw = eeconfig_read_user();
keyboard_post_init_keymap();
}
void eeconfig_init_user(void) {
user_config.raw = 0;
user_config.system_mac = false;
eeconfig_update_user(user_config.raw);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
static uint32_t boot_timer;
if (!process_record_keymap(keycode, record)) {
return false;
}
switch (keycode) {
case FW_WRD:
do_mac_key(LCTL(KC_RIGHT), ROPT(KC_RIGHT), record);
break;
case BK_WRD:
do_mac_key(LCTL(KC_LEFT), ROPT(KC_LEFT), record);
break;
case KB_BOL:
do_mac_key(KC_HOME, RCMD(KC_LEFT), record);
break;
case KB_EOL:
do_mac_key(KC_END, RCMD(KC_RIGHT), record);
break;
case TG_SYS:
if (record->event.pressed) {
user_config.system_mac ^= 1;
eeconfig_update_user(user_config.raw);
}
break;
case KB_COPY:
do_mac_key(LCTL(KC_INS), RCMD(KC_C), record);
break;
case KB_PASTE:
do_mac_key(LSFT(KC_INS), RCMD(KC_V), record);
break;
case MY_GUI:
do_mac_key(KC_LGUI, KC_LOPT, record);
break;
case MY_ALT:
do_mac_key(KC_LALT, KC_LCMD, record);
break;
case MY_RGUI:
do_mac_key(KC_RGUI, KC_ROPT, record);
break;
case MY_RALT:
do_mac_key(KC_RALT, KC_RCMD, record);
break;
case MY_CALC:
do_mac_key(KC_CALC, KC_F14, record);
break;
case KB_MAKE:
if (!get_mods()) {
if (!record->event.pressed)
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP SS_TAP(X_ENTER));
return false;
}
break;
case KB_VRSN:
if (!get_mods()) {
if (!record->event.pressed) {
if (user_config.system_mac) {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION " (mac mode)");
} else {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION " (non-mac mode)");
}
}
return false;
}
break;
case KB_BOOT:
if (!get_mods()) {
if (record->event.pressed) {
boot_timer = timer_read32();
} else {
if (timer_elapsed32(boot_timer) >= 500) {
reset_keyboard();
}
}
return false;
}
break;
case KB_FLSH:
if (!get_mods()) {
if (!record->event.pressed) {
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP ":flash\n");
reset_keyboard();
}
return false;
}
break;
#ifdef DO_SECRETS
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_secret_string(keycode - KC_SECRET_1);
}
return false;
break;
#endif
}
return true;
}
__attribute__ ((weak))
void matrix_init_keymap(void) {
}
void matrix_init_user(void) {
matrix_init_keymap();
}
__attribute__ ((weak))
void matrix_scan_keymap(void) {
}
void matrix_scan_user(void) {
matrix_scan_keymap();
}
__attribute__ ((weak))
layer_state_t layer_state_set_keymap(layer_state_t state) {
return state;
}
layer_state_t layer_state_set_user(layer_state_t state) {
return layer_state_set_keymap(state);
}

134
users/jdelkins/jdelkins.h Normal file
View File

@@ -0,0 +1,134 @@
/*
Copyright 2020 Joel Elkins <joel@elkins.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include QMK_KEYBOARD_H
// Secrets
#if !defined(NO_SECRETS) && __has_include("secrets.h")
# define DO_SECRETS
#endif
void send_secret_string(uint8_t n);
// standard layers
enum jdelkins_layers {
_QWERTY = 0,
_RPT,
_GAME,
_FUNC,
_KP,
_SECRETS,
_ADJUST,
_LAYER_MAX
};
// key definitions
typedef union {
uint32_t raw;
struct {
bool system_mac :1;
};
} user_config_t;
extern user_config_t user_config;
static inline void do_mac_key(uint16_t norm_key, uint16_t mac_key, keyrecord_t *record) {
uint16_t key = user_config.system_mac ? mac_key : norm_key;
if (record->event.pressed)
register_code16(key);
else
unregister_code16(key);
}
enum jdelkins_keycodes {
KB_MAKE = SAFE_RANGE,
KB_FLSH,
KB_VRSN,
KB_BOOT,
FW_WRD,
BK_WRD,
KB_BOL,
KB_EOL,
TG_SYS,
KB_COPY,
KB_PASTE,
MY_GUI,
MY_ALT,
MY_RGUI,
MY_RALT,
MY_CALC,
#ifdef DO_SECRETS
KC_SECRET_1,
KC_SECRET_2,
KC_SECRET_3,
KC_SECRET_4,
KC_SECRET_5,
KC_SECRET_6,
#endif
USER_SAFE_RANGE,
};
#ifdef DO_SECRETS
# 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
#else
# define KC_SEC1 KC_NO
# define KC_SEC2 KC_NO
# define KC_SEC3 KC_NO
# define KC_SEC4 KC_NO
# define KC_SEC5 KC_NO
# define KC_SEC6 KC_NO
#endif
#define MODS_SHIFT (get_mods() & MOD_MASK_SHIFT)
#define MODS_CTRL (get_mods() & MOD_MASK_CTRL)
#define MODS_ALT (get_mods() & MOD_MASK_ALT)
#define MODS_GUI (get_mods() & MOD_MASK_GUI)
#define MY_CAPS LCTL_T(KC_CAPS)
#define MY_SPC LT(_FUNC, KC_SPC)
#define NUMLOCK_ON host_keyboard_led_state().num_lock
#define CAPSLOCK_ON host_keyboard_led_state().caps_lock
#ifdef TAP_DANCE_ENABLE
enum {
SINGLE_TAP = 1,
SINGLE_HOLD = 2,
DOUBLE_TAP = 3,
DOUBLE_HOLD = 4,
DOUBLE_SINGLE_TAP = 5, //send two single taps
TRIPLE_TAP = 6,
TRIPLE_HOLD = 7
};
int cur_dance(qk_tap_dance_state_t *state); // prefer tap
int hold_cur_dance(qk_tap_dance_state_t *state); // prefer hold
#endif // TAP_DANCE_ENABLE

10
users/jdelkins/rules.mk Normal file
View File

@@ -0,0 +1,10 @@
SRC += jdelkins.c
ifeq ($(strip $(NO_SECRETS)), yes)
OPT_DEFS += -DNO_SECRETS
endif
users/jdelkins/secrets.h: users/jdelkins/secrets.h.gpg
gpg -d $< >$@
BOOTMAGIC_ENABLE = no

View File

@@ -29,10 +29,21 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keymap(keycode, record)) {
return false;
}
#if defined(ANSI_NUBS_ROW) && defined(ANSI_NUBS_COL)
// if ANSI_NUBS_ROW and ANSI_NUBS_COL are both defined, and Right Alt mod is active
if ( record->event.key.row == ANSI_NUBS_ROW && record->event.key.col == ANSI_NUBS_COL && get_mods() & MOD_MASK_RALT ) {
if (record->event.pressed) {
register_code(KC_NUBS);
} else {
unregister_code(KC_NUBS);
}
return false;
}
#endif
switch (keycode) {
case VRSN:
if (record->event.pressed) {
SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION);
SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " # @ " QMK_VERSION);
}
return false;
case G_PUSH:
@@ -118,21 +129,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
macroMode ^= 1;
}
return false;
case KC_Z:
if (record->event.pressed) {
if ( get_mods() & MOD_MASK_RALT ) {
register_code(KC_NUBS);
} else {
register_code(KC_Z);
}
} else {
if ( get_mods() & MOD_MASK_RALT ) {
unregister_code(KC_NUBS);
} else {
unregister_code(KC_Z);
}
};
return false;
case KC_1 ... KC_0:
if (record->event.pressed) {
if (get_mods() & MOD_MASK_RALT) {

View File

@@ -21,9 +21,9 @@ Some frequently used Git commands.
| Keycode | Output | Output with <kbd>Shift</kbd> |
| :---------------------------------- | :--------------------- | :--------------------------- |
| [`G_PUSH`](./noroadsleft.c#L38-L42) | `git push origin ` | `git push origin ` |
| [`G_FTCH`](./noroadsleft.c#L43-L52) | `git fetch upstream ` | `git pull upstream ` |
| [`G_BRCH`](./noroadsleft.c#L53-L62) | `master` | `$(git branch-name)` |
| [`G_PUSH`](./noroadsleft.c#L49-L53) | `git push origin ` | `git push origin ` |
| [`G_FTCH`](./noroadsleft.c#L54-L63) | `git fetch upstream ` | `git pull upstream ` |
| [`G_BRCH`](./noroadsleft.c#L64-L73) | `master` | `$(git branch-name)` |
`$(git branch-name)` is an alias for `git rev-parse --abbrev-ref HEAD`, which normally returns the name of the current branch.
@@ -33,24 +33,28 @@ Some of my macros and keycodes do different things depending on the value of the
| Keycode | `macroMode == 0` | `macroMode == 1` | `macroMode == 1` with <kbd>Shift</kbd> |
| :------------------------------------- | :--------------- | :--------------- | :------------------------------------- |
| [`M_SALL`](./noroadsleft.c#L63-L71) | `Ctrl+A` | `Cmd+A` | `Cmd+A` |
| [`M_UNDO`](./noroadsleft.c#L72-L84) | `Ctrl+Z` | `Cmd+Z` | `Cmd+Shift+Z` |
| [`M_CUT`](./noroadsleft.c#L85-L93) | `Ctrl+X` | `Cmd+X` | `Cmd+X` |
| [`M_COPY`](./noroadsleft.c#L94-L102) | `Ctrl+C` | `Cmd+C` | `Cmd+C` |
| [`M_PASTE`](./noroadsleft.c#L103-L115) | `Ctrl+V` | `Cmd+V` | `Cmd+Shift+Opt+V` |
| [`KC_PSCR`](./noroadsleft.c#L166-L174) | `KC_PSCR` | `Cmd+Shift+3` | `Cmd+Shift+3` |
| [`KC_HOME`](./noroadsleft.c#L175-L183) | `KC_HOME` | `Cmd+Left` | `Cmd+Left` |
| [`KC_END`](./noroadsleft.c#L184-L192) | `KC_END` | `Cmd+Right` | `Cmd+Right` |
| [`M_SALL`](./noroadsleft.c#L74-L82) | `Ctrl+A` | `Cmd+A` | `Cmd+A` |
| [`M_UNDO`](./noroadsleft.c#L83-L95) | `Ctrl+Z` | `Cmd+Z` | `Cmd+Shift+Z` |
| [`M_CUT`](./noroadsleft.c#L96-L104) | `Ctrl+X` | `Cmd+X` | `Cmd+X` |
| [`M_COPY`](./noroadsleft.c#L105-L113) | `Ctrl+C` | `Cmd+C` | `Cmd+C` |
| [`M_PASTE`](./noroadsleft.c#L114-L126) | `Ctrl+V` | `Cmd+V` | `Cmd+Shift+Opt+V` |
| [`KC_PSCR`](./noroadsleft.c#L162-L170) | `KC_PSCR` | `Cmd+Shift+3` | `Cmd+Shift+3` |
| [`KC_HOME`](./noroadsleft.c#L171-L179) | `KC_HOME` | `Cmd+Left` | `Cmd+Left` |
| [`KC_END`](./noroadsleft.c#L180-L188) | `KC_END` | `Cmd+Right` | `Cmd+Right` |
### [Emulated Non-US Backslash](./noroadsleft.c#L121-L135)
### [Emulated Non-US Backslash](./noroadsleft.c#L32-L42)
Sometimes I type in languages from countries that use ISO layout, but my keyboard is ANSI, so I have one key fewer. This macro simulates the Non-US Backslash key if I use Right Alt + `KC_Z`.
Sometimes I type in languages from countries that use ISO layout, but my keyboards are all ANSI layout, so I have one key fewer than necessary.
### [Emulated Numeric Keypad](./noroadsleft.c#L136-L150)
This macro simulates the Non-US Backslash key if I hold Right Alt and tap the key to the right of Left Shift.
Requires defining `ANSI_NUBS_ROW` and `ANSI_NUBS_COL` in `config.h` at the keymap level.[<sup>2</sup>](#footnotes)
### [Emulated Numeric Keypad](./noroadsleft.c#L132-L146)
If I hold the Right Alt key, the number row (`KC_1` through `KC_0`) will output numpad keycodes instead of number row keycodes, enabling quicker access to characters like ™ and °.
### [Emulated Extended Function Keys](./noroadsleft.c#L151-L165)
### [Emulated Extended Function Keys](./noroadsleft.c#L147-L161)
Similar to the emulated numpad, if I hold the Right Alt key with the Fn key, the function row (`KC_F1` through `KC_F12`) will output keycodes `KC_F13` throught `KC_F24`.
@@ -79,3 +83,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
- [KC60](../../keyboards/kc60/keymaps/noroadsleft/keymap.c#L111)
- [KBDfans KBD75 rev1](../../keyboards/kbdfans/kbd75/keymaps/noroadsleft/keymap.c#L93)
- [CoseyFannitutti Discipline](../../keyboards/coseyfannitutti/discipline/keymaps/noroadsleft/keymap.c#L66)
- 2: [^](#emulated-non-us-backslash) `ANSI_NUBS_ROW` and `ANSI_NUBS_COL` are in the following locations:
- [KC60](../../keyboards/kc60/keymaps/noroadsleft/config.h#L35-L36)
- [KBDfans KBD75 rev1](../../keyboards/kbdfans/kbd75/keymaps/noroadsleft/config.h#L26-L27)
- [CoseyFannitutti Discipline](../../keyboards/coseyfannitutti/discipline/keymaps/noroadsleft/config.h#L19-L20)