1
0

Compare commits

..

7 Commits

Author SHA1 Message Date
Joel Challis
0269eea2c9 Add EECONFIG_{KB,USER}_DATA_SIZE docs (#26200) 2026-05-19 02:58:50 +01:00
Nick Brassel
1836382f66 GCC 16.1 compatibility fix. (#26216)
Co-authored-by: Joel Challis <git@zvecr.com>
2026-05-17 13:06:47 +10:00
prkrln
504533b3b4 Add pad9 keyboard (#26051) 2026-05-03 04:02:11 +01:00
Sinopoli Mauro
ba9642c83d Add sector245/s245_streamdeck keyboard (#26013) 2026-05-01 00:26:54 +01:00
Joel Challis
c2f7a5b5c5 Fix config.h bool parsing (#26166) 2026-04-30 23:57:08 +01:00
Isaac Rex
ccc6c6ce0b [Keyboard] Added Nifty Numpad (#23019)
* Initial commit of Nifty Numpad keyboard

* Initial commit of Nifty Numpad keyboard

* Fixed double repo

* Updated available effects

* Added a default and VIA keymap, moved cadence to its own keymap

* Fixed qmk_firmware submodule issue

* Updated Nifty Numpad readme

Updated Cadence keymap

Updated vscode settings to match QMK master

* Added Nifty Numpad

* Added config.h to idle_rgb_example

* renamed info.json, removed rules.mk

* Updated to conform with most recent PR checklist

- Removed VIA keymap
- Formatted keyboard.json with qmk format-json
- Updated custom keycodes in nifty_numpad.h to start at QK_USER

* Address review feedback

- Remove the config.h file from the idle_rgb_example keymap as the only
  settings was equal to the default
- Added empty endline to the end of idle_rgb_example/rules.mk and post_rules.mk
- Updated RGB_DEF custom keycode to QK_KB

* Removed commented layout visuals

* Updated RGB Matrix keycodes

* Updated use of eeconfig_update_kb_datablock to new signature
2026-04-17 20:55:09 -07:00
kbd0
c93ef27143 [Keyboard] Add Kbd0 Curve0 75% ANSI (#25997) 2026-04-14 11:17:28 +01:00
25 changed files with 1171 additions and 12 deletions

View File

@@ -72,6 +72,8 @@ endif
endif
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
CFLAGS += $(call cc-option,-Wunused-but-set-variable=1,-Wunused-but-set-variable)
CFLAGS += $(call cc-option,-Wunused-but-set-parameter=1,-Wunused-but-set-parameter)
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CFLAGS += -Werror
endif
@@ -89,7 +91,8 @@ CXXFLAGS += -O$(OPT)
CXXFLAGS += -w
CXXFLAGS += -Wall
CXXFLAGS += -Wundef
CXXFLAGS += $(call cc-option,-Wunused-but-set-variable=1,-Wunused-but-set-variable)
CXXFLAGS += $(call cc-option,-Wunused-but-set-parameter=1,-Wunused-but-set-parameter)
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CXXFLAGS += -Werror
endif

View File

@@ -4,7 +4,7 @@
# $(2) = option to use if $(1) is not supported
# $(3) = additional arguments to pass to the compiler during the test, but aren't contained in the output
cc-option = $(shell \
if { echo 'int main(){return 0;}' | $(CC) $(1) $(3) -o /dev/null -x c /dev/null >/dev/null 2>&1; }; \
if { echo 'int main(){return 0;}' | $(CC) $(1) $(3) -Wl,--unresolved-symbols=ignore-all -o /dev/null -x c /dev/null >/dev/null 2>&1; }; \
then echo "$(1)"; else echo "$(2)"; fi)
# Helper to pass comma character to make functions (use with `$(,)` to pass in `$(call ...)` arguments)

View File

@@ -1,14 +1,20 @@
# Persistent Configuration (EEPROM)
This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss.
Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU.
* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
::: tip
If you don't understand the examples, then you may want to avoid using this feature, as it is rather complicated.
:::
## Example Implementation
## Basic
The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
### Example Implementation
This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work!
@@ -126,9 +132,111 @@ void eeconfig_init_user(void) { // EEPROM is getting reset!
And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to.
## 'EECONFIG' Function Documentation
### Basic API
* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)`
* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
## Datablock {#datablock}
An extended form exists that allows larger blocks of data to be allocated.
::: info
When using datablock, the [basic API](#eeconfig-function-documentation) is unavailable.
:::
:::::tabs
==== keyboard
In `config.h`, define the size required, and optionally a version number:
| Define | Default | Description |
|------------------------------|---------------------------|------------------------------------------------------------------|
| `EECONFIG_KB_DATA_SIZE` | `0` | Size in bytes for the persistent block of data |
| `EECONFIG_KB_DATA_VERSION` | `EECONFIG_KB_DATA_SIZE` | Version number that can be incremented to invalidate stored data |
Which exposes the following API:
```c
bool eeconfig_is_kb_datablock_valid(void);
uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_kb_datablock(void);
# define eeconfig_read_kb_datablock_field(__object, __field) eeconfig_read_kb_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
# define eeconfig_update_kb_datablock_field(__object, __field) eeconfig_update_kb_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
```
==== keymap
In `config.h`, define the size required, and optionally a version number:
| Define | Default | Description |
|------------------------------|---------------------------|------------------------------------------------------------------|
| `EECONFIG_USER_DATA_SIZE` | `0` | Size in bytes for the persistent block of data |
| `EECONFIG_USER_DATA_VERSION` | `EECONFIG_USER_DATA_SIZE` | Version number that can be incremented to invalidate stored data |
Which exposes the following API:
```c
bool eeconfig_is_user_datablock_valid(void);
uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_user_datablock(void);
# define eeconfig_read_user_datablock_field(__object, __field) eeconfig_read_user_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
# define eeconfig_update_user_datablock_field(__object, __field) eeconfig_update_user_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
```
:::::
### Example
This is an example of how to add settings, and read and write it. We're using the user keymap for the example here.
In your `config.h` add:
```c
#define EECONFIG_USER_DATA_SIZE 8
```
In your keymap.c file, add:
```c
#include "debug.h"
#include "timer.h"
#include "eeconfig.h"
typedef struct my_config_t {
uint64_t data;
} my_config_t;
static my_config_t config;
void keyboard_post_init_user(void) {
if (!eeconfig_is_user_datablock_valid()) {
eeconfig_init_user_datablock();
}
eeconfig_read_user_datablock(&config, 0, sizeof(my_config_t));
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!record->event.pressed) {
config.data += 1;
eeconfig_update_user_datablock(&config, 0, sizeof(my_config_t));
}
return true;
}
void housekeeping_task_user(void) {
static uint32_t last_sync = 0;
if (timer_elapsed32(last_sync) > 1000) {
last_sync = timer_read32();
dprintf("Config: %ld\n", config.data);
}
}
```

View File

@@ -0,0 +1,50 @@
{
"keyboard_name": "S245 Streamdeck",
"manufacturer": "sector245",
"maintainer": "sector245",
"processor": "RP2040",
"bootloader": "rp2040",
"debounce": 20,
"usb": {
"vid": "0x5345",
"pid": "0x0001",
"device_version": "1.0.0"
},
"features": {
"bootmagic": true,
"extrakey": true,
"encoder": true
},
"matrix_pins": {
"direct": [
["GP2", "GP3", "GP13"],
["GP4", "GP5", "GP6"],
["GP7", "GP8", "GP9"]
]
},
"encoder": {
"rotary": [
{
"pin_a": "GP10",
"pin_b": "GP11",
"resolution": 2
}
]
},
"community_layouts": ["ortho_3x3"],
"layouts": {
"LAYOUT_ortho_3x3": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0, "encoder": 0},
{"matrix": [1, 0], "x": 0, "y": 1},
{"matrix": [1, 1], "x": 1, "y": 1},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2},
{"matrix": [2, 1], "x": 1, "y": 2},
{"matrix": [2, 2], "x": 2, "y": 2}
]
}
}
}

View File

@@ -0,0 +1,18 @@
// Copyright 2025 sector245 (@sector245)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_ortho_3x3(
KC_A, KC_B, KC_C,
KC_D, KC_E, KC_F,
KC_G, KC_H, KC_I
)
};
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }
};
#endif

View File

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

View File

@@ -0,0 +1,24 @@
# S245 Streamdeck
A 3x3 macropad with rotary encoder.
* Keyboard Maintainer: [sector245](https://github.com/sinomau)
* Hardware Supported: S245 Streamdeck PCB, RP2040
Make example for this keyboard (after setting up your build environment):
make handwired/sector245/s245:default
Flashing example for this keyboard:
make handwired/sector245/s245:default:flash
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).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (top left key) and plug in the keyboard
* **Physical reset button**: Hold the BOOTSEL button on the Pico and plug in the keyboard
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View File

@@ -0,0 +1,206 @@
{
"manufacturer": "kbd0",
"keyboard_name": "kbd0/curve0/75_ansi",
"maintainer": "kbd0",
"bootloader": "rp2040",
"bootloader_instructions": "Hold the little button on the main PCB (inside the keyboard, near the spacebar) while plugging in the keyboard to enter bootloader.",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"matrix_pins": {
"cols": ["GP6", "GP5", "GP4", "GP7", "GP10", "GP9", "GP11", "GP12", "GP13", "GP14", "GP25", "GP20", "GP19", "GP18", "GP16", "GP3"],
"rows": ["GP2", "GP23", "GP22", "GP21", "GP24", "GP17"]
},
"processor": "RP2040",
"url": "https://kbd0.com/item/curve0",
"usb": {
"device_version": "1.0.0",
"pid": "0xC001",
"vid": "0xCBD0"
},
"community_layouts": ["75_ansi"],
"layouts": {
"LAYOUT_all": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0},
{"matrix": [0, 5], "x": 5, "y": 0},
{"matrix": [0, 6], "x": 6, "y": 0},
{"matrix": [0, 7], "x": 7, "y": 0},
{"matrix": [0, 8], "x": 8, "y": 0},
{"matrix": [0, 9], "x": 9, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [0, 14], "x": 14, "y": 0},
{"matrix": [0, 15], "x": 15, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1},
{"matrix": [1, 1], "x": 1, "y": 1},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1},
{"matrix": [1, 5], "x": 5, "y": 1},
{"matrix": [1, 6], "x": 6, "y": 1},
{"matrix": [1, 7], "x": 7, "y": 1},
{"matrix": [1, 8], "x": 8, "y": 1},
{"matrix": [1, 9], "x": 9, "y": 1},
{"matrix": [1, 10], "x": 10, "y": 1},
{"matrix": [1, 11], "x": 11, "y": 1},
{"matrix": [1, 12], "x": 12, "y": 1},
{"matrix": [1, 13], "x": 13, "y": 1},
{"matrix": [1, 14], "x": 14, "y": 1},
{"matrix": [1, 15], "x": 15, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2},
{"matrix": [2, 2], "x": 2.5, "y": 2},
{"matrix": [2, 3], "x": 3.5, "y": 2},
{"matrix": [2, 4], "x": 4.5, "y": 2},
{"matrix": [2, 5], "x": 5.5, "y": 2},
{"matrix": [2, 6], "x": 6.5, "y": 2},
{"matrix": [2, 7], "x": 7.5, "y": 2},
{"matrix": [2, 8], "x": 8.5, "y": 2},
{"matrix": [2, 9], "x": 9.5, "y": 2},
{"matrix": [2, 10], "x": 10.5, "y": 2},
{"matrix": [2, 11], "x": 11.5, "y": 2},
{"matrix": [2, 12], "x": 12.5, "y": 2},
{"matrix": [2, 13], "x": 13.5, "y": 2, "w": 1.5},
{"matrix": [2, 15], "x": 15, "y": 2},
{"matrix": [3, 0], "x": 0, "y": 3, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3},
{"matrix": [3, 2], "x": 2.75, "y": 3},
{"matrix": [3, 3], "x": 3.75, "y": 3},
{"matrix": [3, 4], "x": 4.75, "y": 3},
{"matrix": [3, 5], "x": 5.75, "y": 3},
{"matrix": [3, 6], "x": 6.75, "y": 3},
{"matrix": [3, 7], "x": 7.75, "y": 3},
{"matrix": [3, 8], "x": 8.75, "y": 3},
{"matrix": [3, 9], "x": 9.75, "y": 3},
{"matrix": [3, 10], "x": 10.75, "y": 3},
{"matrix": [3, 11], "x": 11.75, "y": 3},
{"matrix": [3, 12], "x": 12.75, "y": 3, "w": 2.25},
{"matrix": [3, 15], "x": 15, "y": 3},
{"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
{"matrix": [4, 1], "x": 1.25, "y": 4},
{"matrix": [4, 2], "x": 2.25, "y": 4},
{"matrix": [4, 3], "x": 3.25, "y": 4},
{"matrix": [4, 4], "x": 4.25, "y": 4},
{"matrix": [4, 5], "x": 5.25, "y": 4},
{"matrix": [4, 6], "x": 6.25, "y": 4},
{"matrix": [4, 7], "x": 7.25, "y": 4},
{"matrix": [4, 8], "x": 8.25, "y": 4},
{"matrix": [4, 9], "x": 9.25, "y": 4},
{"matrix": [4, 10], "x": 10.25, "y": 4},
{"matrix": [4, 11], "x": 11.25, "y": 4},
{"matrix": [4, 12], "x": 12.25, "y": 4, "w": 1.75},
{"matrix": [4, 14], "x": 14, "y": 4},
{"matrix": [4, 15], "x": 15, "y": 4},
{"matrix": [5, 0], "x": 0, "y": 5, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5, "w": 1.25},
{"matrix": [5, 6], "x": 3.75, "y": 5, "w": 6.25},
{"matrix": [5, 10], "x": 10, "y": 5},
{"matrix": [5, 11], "x": 11, "y": 5},
{"matrix": [5, 12], "x": 12, "y": 5},
{"matrix": [5, 13], "x": 13, "y": 5},
{"matrix": [5, 14], "x": 14, "y": 5},
{"matrix": [5, 15], "x": 15, "y": 5}
]
},
"LAYOUT_75_ansi": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0},
{"matrix": [0, 5], "x": 5, "y": 0},
{"matrix": [0, 6], "x": 6, "y": 0},
{"matrix": [0, 7], "x": 7, "y": 0},
{"matrix": [0, 8], "x": 8, "y": 0},
{"matrix": [0, 9], "x": 9, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [0, 14], "x": 14, "y": 0},
{"matrix": [0, 15], "x": 15, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1},
{"matrix": [1, 1], "x": 1, "y": 1},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1},
{"matrix": [1, 5], "x": 5, "y": 1},
{"matrix": [1, 6], "x": 6, "y": 1},
{"matrix": [1, 7], "x": 7, "y": 1},
{"matrix": [1, 8], "x": 8, "y": 1},
{"matrix": [1, 9], "x": 9, "y": 1},
{"matrix": [1, 10], "x": 10, "y": 1},
{"matrix": [1, 11], "x": 11, "y": 1},
{"matrix": [1, 12], "x": 12, "y": 1},
{"matrix": [1, 14], "x": 13, "y": 1, "w": 2},
{"matrix": [1, 15], "x": 15, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2},
{"matrix": [2, 2], "x": 2.5, "y": 2},
{"matrix": [2, 3], "x": 3.5, "y": 2},
{"matrix": [2, 4], "x": 4.5, "y": 2},
{"matrix": [2, 5], "x": 5.5, "y": 2},
{"matrix": [2, 6], "x": 6.5, "y": 2},
{"matrix": [2, 7], "x": 7.5, "y": 2},
{"matrix": [2, 8], "x": 8.5, "y": 2},
{"matrix": [2, 9], "x": 9.5, "y": 2},
{"matrix": [2, 10], "x": 10.5, "y": 2},
{"matrix": [2, 11], "x": 11.5, "y": 2},
{"matrix": [2, 12], "x": 12.5, "y": 2},
{"matrix": [2, 13], "x": 13.5, "y": 2, "w": 1.5},
{"matrix": [2, 15], "x": 15, "y": 2},
{"matrix": [3, 0], "x": 0, "y": 3, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3},
{"matrix": [3, 2], "x": 2.75, "y": 3},
{"matrix": [3, 3], "x": 3.75, "y": 3},
{"matrix": [3, 4], "x": 4.75, "y": 3},
{"matrix": [3, 5], "x": 5.75, "y": 3},
{"matrix": [3, 6], "x": 6.75, "y": 3},
{"matrix": [3, 7], "x": 7.75, "y": 3},
{"matrix": [3, 8], "x": 8.75, "y": 3},
{"matrix": [3, 9], "x": 9.75, "y": 3},
{"matrix": [3, 10], "x": 10.75, "y": 3},
{"matrix": [3, 11], "x": 11.75, "y": 3},
{"matrix": [3, 12], "x": 12.75, "y": 3, "w": 2.25},
{"matrix": [3, 15], "x": 15, "y": 3},
{"matrix": [4, 0], "x": 0, "y": 4, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4},
{"matrix": [4, 3], "x": 3.25, "y": 4},
{"matrix": [4, 4], "x": 4.25, "y": 4},
{"matrix": [4, 5], "x": 5.25, "y": 4},
{"matrix": [4, 6], "x": 6.25, "y": 4},
{"matrix": [4, 7], "x": 7.25, "y": 4},
{"matrix": [4, 8], "x": 8.25, "y": 4},
{"matrix": [4, 9], "x": 9.25, "y": 4},
{"matrix": [4, 10], "x": 10.25, "y": 4},
{"matrix": [4, 11], "x": 11.25, "y": 4},
{"matrix": [4, 12], "x": 12.25, "y": 4, "w": 1.75},
{"matrix": [4, 14], "x": 14, "y": 4},
{"matrix": [4, 15], "x": 15, "y": 4},
{"matrix": [5, 0], "x": 0, "y": 5, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5, "w": 1.25},
{"matrix": [5, 6], "x": 3.75, "y": 5, "w": 6.25},
{"matrix": [5, 10], "x": 10, "y": 5},
{"matrix": [5, 11], "x": 11, "y": 5},
{"matrix": [5, 12], "x": 12, "y": 5},
{"matrix": [5, 13], "x": 13, "y": 5},
{"matrix": [5, 14], "x": 14, "y": 5},
{"matrix": [5, 15], "x": 15, "y": 5}
]
}
}
}

View File

@@ -0,0 +1,16 @@
{
"author": "kbd0",
"keyboard": "kbd0/curve0/75_ansi",
"keymap": "75_ansi",
"layout": "LAYOUT_75_ansi",
"layers": [
[
"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_PRINT_SCREEN", "KC_DELETE", "KC_INSERT",
"KC_GRAVE", "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_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_END",
"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_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "KC_APP", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RIGHT"
]
]
}

View File

@@ -0,0 +1,16 @@
{
"author": "kbd0",
"keyboard": "kbd0/curve0/75_ansi",
"keymap": "default",
"layout": "LAYOUT_all",
"layers": [
[
"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_PRINT_SCREEN", "KC_DELETE", "KC_INSERT",
"KC_GRAVE", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", "KC_MINS", "KC_EQL", "KC_BSLS", "KC_BSPC", "KC_HOME",
"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_END",
"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_NUBS", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", "KC_RSFT", "KC_UP", "KC_PGDN",
"KC_LCTL", "KC_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "KC_APP", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RIGHT"
]
]
}

View File

@@ -0,0 +1,27 @@
# kbd0/curve0/75_ansi
![Curve0](https://i.imgur.com/0YOTmsk.jpeg)
Curve0 - Curved stainless steel keyboard by Kbd0
* Keyboard Maintainer: [kbd0](https://github.com/kbd0)
* Hardware Supported: Curve0 PCB
* Hardware Availability: [kbd0.com](https://kbd0.com/item/curve0)
Make example for this keyboard (after setting up your build environment):
make kbd0/curve0/75_ansi:default
Flashing example for this keyboard:
make kbd0/curve0/75_ansi:default:flash
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).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold the top left key of the keyboard while plugging in the keyboard
* **Physical reset button**: Hold the little button on the main PCB (inside the keyboard, near the spacebar) while plugging in the keyboard
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View File

@@ -0,0 +1,6 @@
// Copyright 2023 Isaac Rex (@Acliad)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define EECONFIG_KB_DATA_SIZE 10

View File

@@ -0,0 +1,150 @@
{
"manufacturer": "Isaac Rex",
"keyboard_name": "Nifty Numpad",
"maintainer": "Acliad",
"bootloader": "rp2040",
"diode_direction": "ROW2COL",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true,
"rgb_matrix": true
},
"matrix_pins": {
"cols": ["GP17", "GP18", "GP15", "GP13", "GP14", "GP12"],
"rows": ["GP20", "GP21", "GP22", "GP23", "GP24", "GP25"]
},
"processor": "RP2040",
"rgb_matrix": {
"animations": {
"band_pinwheel_sat": true,
"band_pinwheel_val": true,
"band_sat": true,
"band_spiral_sat": true,
"band_spiral_val": true,
"band_val": true,
"breathing": true,
"cycle_all": true,
"cycle_left_right": true,
"cycle_out_in": true,
"cycle_out_in_dual": true,
"cycle_pinwheel": true,
"cycle_spiral": true,
"cycle_up_down": true,
"digital_rain": true,
"dual_beacon": true,
"gradient_up_down": true,
"jellybean_raindrops": true,
"multisplash": true,
"rainbow_beacon": true,
"rainbow_moving_chevron": true,
"rainbow_pinwheels": true,
"raindrops": true,
"solid_multisplash": true,
"solid_reactive": true,
"solid_reactive_cross": true,
"solid_reactive_multicross": true,
"solid_reactive_multinexus": true,
"solid_reactive_multiwide": true,
"solid_reactive_nexus": true,
"solid_reactive_simple": true,
"solid_reactive_wide": true,
"solid_splash": true,
"splash": true,
"typing_heatmap": false
},
"default": {
"animation": "solid_color",
"hue": 127,
"speed": 100
},
"driver": "ws2812",
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0, "flags": 4},
{"matrix": [0, 1], "x": 43, "y": 0, "flags": 4},
{"matrix": [0, 2], "x": 96, "y": 0, "flags": 4},
{"matrix": [0, 3], "x": 139, "y": 0, "flags": 4},
{"matrix": [0, 4], "x": 181, "y": 0, "flags": 4},
{"matrix": [0, 5], "x": 224, "y": 0, "flags": 4},
{"matrix": [1, 0], "x": 0, "y": 17, "flags": 4},
{"matrix": [1, 1], "x": 43, "y": 17, "flags": 4},
{"matrix": [1, 2], "x": 96, "y": 17, "flags": 4},
{"matrix": [1, 3], "x": 139, "y": 17, "flags": 4},
{"matrix": [1, 4], "x": 181, "y": 17, "flags": 4},
{"matrix": [1, 5], "x": 224, "y": 17, "flags": 4},
{"matrix": [2, 0], "x": 0, "y": 29, "flags": 4},
{"matrix": [2, 1], "x": 43, "y": 29, "flags": 4},
{"matrix": [2, 2], "x": 96, "y": 29, "flags": 4},
{"matrix": [2, 3], "x": 139, "y": 29, "flags": 4},
{"matrix": [2, 4], "x": 181, "y": 29, "flags": 4},
{"matrix": [2, 5], "x": 224, "y": 35, "flags": 4},
{"matrix": [3, 0], "x": 0, "y": 41, "flags": 4},
{"matrix": [3, 1], "x": 43, "y": 41, "flags": 4},
{"matrix": [3, 2], "x": 96, "y": 41, "flags": 4},
{"matrix": [3, 3], "x": 139, "y": 41, "flags": 4},
{"matrix": [3, 4], "x": 181, "y": 41, "flags": 4},
{"matrix": [4, 0], "x": 0, "y": 52, "flags": 4},
{"matrix": [4, 1], "x": 43, "y": 52, "flags": 4},
{"matrix": [4, 2], "x": 96, "y": 52, "flags": 4},
{"matrix": [4, 3], "x": 139, "y": 52, "flags": 4},
{"matrix": [4, 4], "x": 181, "y": 52, "flags": 4},
{"matrix": [4, 5], "x": 224, "y": 58, "flags": 4},
{"matrix": [5, 0], "x": 0, "y": 64, "flags": 4},
{"matrix": [5, 1], "x": 43, "y": 64, "flags": 4},
{"matrix": [5, 2], "x": 117, "y": 64, "flags": 4},
{"matrix": [5, 3], "x": 181, "y": 64, "flags": 4}
]
},
"url": "https://gitlab.com/Acliad/nifty-numpad",
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0x4E4E"
},
"ws2812": {
"driver": "vendor",
"pin": "GP19"
},
"layouts": {
"LAYOUT_numpad_6x6": {
"layout": [
{"label": "F13", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "F19", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "BACKSPACE", "matrix": [0, 2], "x": 2.25, "y": 0},
{"label": "TASK VIEW", "matrix": [0, 3], "x": 3.25, "y": 0},
{"label": "EXPLORER", "matrix": [0, 4], "x": 4.25, "y": 0},
{"label": "SCREENSHOT", "matrix": [0, 5], "x": 5.25, "y": 0},
{"label": "F14", "matrix": [1, 0], "x": 0, "y": 1.5},
{"label": "F20", "matrix": [1, 1], "x": 1, "y": 1.5},
{"label": "NUM LOCK", "matrix": [1, 2], "x": 2.25, "y": 1.5},
{"label": "/", "matrix": [1, 3], "x": 3.25, "y": 1.5},
{"label": "*", "matrix": [1, 4], "x": 4.25, "y": 1.5},
{"label": "-", "matrix": [1, 5], "x": 5.25, "y": 1.5},
{"label": "F15", "matrix": [2, 0], "x": 0, "y": 2.5},
{"label": "F21", "matrix": [2, 1], "x": 1, "y": 2.5},
{"label": "7", "matrix": [2, 2], "x": 2.25, "y": 2.5},
{"label": "8", "matrix": [2, 3], "x": 3.25, "y": 2.5},
{"label": "9", "matrix": [2, 4], "x": 4.25, "y": 2.5},
{"label": "+", "matrix": [2, 5], "x": 5.25, "y": 2.5, "h": 2},
{"label": "F16", "matrix": [3, 0], "x": 0, "y": 3.5},
{"label": "F22", "matrix": [3, 1], "x": 1, "y": 3.5},
{"label": "4", "matrix": [3, 2], "x": 2.25, "y": 3.5},
{"label": "5", "matrix": [3, 3], "x": 3.25, "y": 3.5},
{"label": "6", "matrix": [3, 4], "x": 4.25, "y": 3.5},
{"label": "F17", "matrix": [4, 0], "x": 0, "y": 4.5},
{"label": "F23", "matrix": [4, 1], "x": 1, "y": 4.5},
{"label": "1", "matrix": [4, 2], "x": 2.25, "y": 4.5},
{"label": "2", "matrix": [4, 3], "x": 3.25, "y": 4.5},
{"label": "3", "matrix": [4, 4], "x": 4.25, "y": 4.5},
{"label": "ENTER", "matrix": [4, 5], "x": 5.25, "y": 4.5, "h": 2},
{"label": "F18", "matrix": [5, 0], "x": 0, "y": 5.5},
{"label": "F24", "matrix": [5, 1], "x": 1, "y": 5.5},
{"label": "0", "matrix": [5, 2], "x": 2.25, "y": 5.5, "w": 2},
{"label": ".", "matrix": [5, 4], "x": 4.25, "y": 5.5}
]
}
}
}

View File

@@ -0,0 +1,31 @@
// Copyright 2023 Isaac Rex (@Acliad)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
// Layers
// NOTE: LAYER_RGB is defined in nifty_numpad.h
enum LAYERS {
LAYER_BL,
};
// Setup keymap
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[LAYER_BL] = LAYOUT_numpad_6x6(
KC_F13, KC_F19, LT(LAYER_RGB, KC_BSPC), RGUI(KC_TAB), RGUI(KC_E), RGUI(RSFT(KC_S)),
KC_F14, KC_F20, KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
KC_F15, KC_F21, KC_P7, KC_P8, KC_P9, KC_PPLS,
KC_F16, KC_F22, KC_P4, KC_P5, KC_P6,
KC_F17, KC_F23, KC_P1, KC_P2, KC_P3, KC_PENT,
KC_F18, KC_F24, KC_P0, KC_PDOT
),
[LAYER_RGB] = LAYOUT_numpad_6x6(
_______, _______, _______, RM_HUEU, RM_SATU, RM_VALU,
_______, _______, _______, RM_HUED, RM_SATD, RM_VALD,
_______, _______, _______, RM_NEXT, _______, RM_SPDU,
_______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, RM_SPDD,
_______, _______, _______, _______
)
};

View File

@@ -0,0 +1,107 @@
// Copyright 2023 Isaac Rex (@Acliad)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
// Layers
// NOTE: LAYER_RGB is defined in nifty_numpad.h
enum LAYERS {
LAYER_BL = 0,
LAYER_MOD,
};
// Layer Indicator LED index
#define _NUM_LED_INDEX 8
// Tap Dance Declarations
enum {
TD_NUM_TOGGLE = 0,
TD_EDIT_GEN_TOGGLE,
TD_M1,
TD_M2,
TD_M3,
TD_M4,
TD_M5,
TD_M6,
TD_M7,
TD_M8,
TD_M9,
TD_M10,
TD_M11,
TD_M12,
};
// TD function for 1 tap, toggle layer; 2 taps, press numlock
void tap_dance_num_toggle(tap_dance_state_t *state, void *user_data){
switch(state->count){
case 1:
layer_invert(LAYER_MOD);
break;
case 2:
tap_code16(KC_NUM);
break;
}
}
// Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_NUM_TOGGLE] = ACTION_TAP_DANCE_FN(tap_dance_num_toggle),
[TD_M1] = ACTION_TAP_DANCE_DOUBLE(KC_F13, LCTL(KC_F13)),
[TD_M2] = ACTION_TAP_DANCE_DOUBLE(KC_F14, LCTL(KC_F14)),
[TD_M3] = ACTION_TAP_DANCE_DOUBLE(KC_F15, LCTL(KC_F15)),
[TD_M4] = ACTION_TAP_DANCE_DOUBLE(KC_F16, LCTL(KC_F16)),
[TD_M5] = ACTION_TAP_DANCE_DOUBLE(KC_F17, LCTL(KC_F17)),
[TD_M6] = ACTION_TAP_DANCE_DOUBLE(KC_F18, LCTL(KC_F18)),
[TD_M7] = ACTION_TAP_DANCE_DOUBLE(KC_F19, LCTL(KC_F19)),
[TD_M8] = ACTION_TAP_DANCE_DOUBLE(KC_F20, LCTL(KC_F20)),
[TD_M9] = ACTION_TAP_DANCE_DOUBLE(KC_F21, LCTL(KC_F21)),
[TD_M10] = ACTION_TAP_DANCE_DOUBLE(KC_F22, LCTL(KC_F22)),
[TD_M11] = ACTION_TAP_DANCE_DOUBLE(KC_F23, LCTL(KC_F23)),
[TD_M12] = ACTION_TAP_DANCE_DOUBLE(KC_F24, LCTL(KC_F24))
};
// Setup keymap
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[LAYER_BL] = LAYOUT_numpad_6x6(
TD(TD_M1), TD(TD_M7) , LT(LAYER_RGB, KC_BSPC), RGUI(KC_TAB), RGUI(KC_E), RGUI(RSFT(KC_S)),
TD(TD_M2), TD(TD_M8) , TD(TD_NUM_TOGGLE), KC_PSLS, KC_PAST, KC_PMNS,
TD(TD_M3), TD(TD_M9) , KC_P7, KC_P8, KC_P9, KC_PPLS,
TD(TD_M4), TD(TD_M10), KC_P4, KC_P5, KC_P6,
TD(TD_M5), TD(TD_M11), KC_P1, KC_P2, KC_P3, KC_PENT,
TD(TD_M6), TD(TD_M12), KC_P0, KC_PDOT
),
[LAYER_MOD] = LAYOUT_numpad_6x6(
_______, _______, KC_F9, KC_F10, KC_F11, KC_F12,
_______, _______, TD(TD_NUM_TOGGLE), RCTL(KC_PSLS), RCTL(KC_PAST), _______,
_______, _______, RCTL(KC_P7), RCTL(KC_P8), RCTL(KC_P9), _______,
_______, _______, RCTL(KC_P4), RCTL(KC_P5), RCTL(KC_P6),
_______, _______, RCTL(KC_P1), RCTL(KC_P2), RCTL(KC_P3), _______,
_______, _______, RCTL(KC_P0), RCTL(KC_PDOT)
),
[LAYER_RGB] = LAYOUT_numpad_6x6(
_______, _______, _______, RM_HUEU, RM_SATU, RM_VALU,
_______, _______, _______, RM_HUED, RM_SATD, RM_VALD,
_______, _______, _______, RM_DMOD, RM_IMOD, RM_SPDU,
_______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, RM_SPDD,
_______, _______, _______, _______
)
};
// Set the layer toggle key to an indication of the active layer. This is a
// bit janky and should be done better, but I'm trying to avoid scope creep.
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
if (layer_state_is(LAYER_MOD) && !rgb_matrix_idle_mode()) {
// Get a hue that contrasts with current hue
uint8_t hue = rgb_matrix_get_hue() + 127;
// Make sure saturation is high enough to distiguish between hues
uint8_t sat = 255;
uint8_t val = MIN((uint16_t) rgb_matrix_get_val() + 50, 255);
RGB rgb = hsv_to_rgb((HSV) {hue, sat, val});
rgb_matrix_set_color(_NUM_LED_INDEX, rgb.r, rgb.g, rgb.b);
}
return false;
}

View File

@@ -0,0 +1,2 @@
TAP_DANCE_ENABLE=yes
RGB_IDLE_ENABLE=yes

View File

@@ -0,0 +1,229 @@
/* Copyright 2023 Acliad
*
* 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
#ifdef RGB_IDLE_ENABLE
typedef struct {
uint8_t mode;
uint8_t speed;
HSV hsv;
} rgb_matrix_state_t;
_Static_assert(sizeof(rgb_matrix_state_t) == 5, "Invalid size for rgb_matrix_state_t");
typedef struct {
rgb_matrix_state_t active_rgb_matrix;
rgb_matrix_state_t idle_rgb_matrix;
} kb_config_t;
_Static_assert(sizeof(kb_config_t) == EECONFIG_KB_DATA_SIZE, "Invalid size for kb_config_t");
bool rgb_idle_mode = false;
bool rgb_idle_edit_mode = false;
static rgb_matrix_state_t active_rgb_matrix;
static rgb_matrix_state_t idle_rgb_matrix;
static kb_config_t config;
// Returns true if current RGB matrix mode is idle
bool rgb_matrix_idle_mode(void) {
return rgb_idle_mode;
}
// Stores the current mode, HSV, and speed of the RGB matrix into state
void rgb_matrix_state_save(rgb_matrix_state_t* state) {
state->mode = rgb_matrix_get_mode();
state->hsv = rgb_matrix_get_hsv();
state->speed = rgb_matrix_get_speed();
}
// Restores the mode, HSV, and speed of the RGB matrix from previous state
void rgb_matrix_state_restore(rgb_matrix_state_t* state) {
HSV hsv = state->hsv;
rgb_matrix_mode_noeeprom(state->mode);
rgb_matrix_sethsv_noeeprom(hsv.h, hsv.s, hsv.v);
rgb_matrix_set_speed_noeeprom(state->speed);
}
#endif
void housekeeping_task_kb(void) {
#ifdef RGB_IDLE_ENABLE
// Check if enough time has passed since last keypress to go into idle mode
if (last_input_activity_elapsed() > RGB_IDLE_TIMEOUT_MS && !rgb_idle_mode) {
rgb_matrix_state_save(&active_rgb_matrix);
rgb_idle_mode = true;
rgb_matrix_state_restore(&idle_rgb_matrix);
}
#endif
};
layer_state_t layer_state_set_kb(layer_state_t state) {
#ifdef RGB_IDLE_ENABLE
// Track if the last layer was the RGB edit layer
static bool rgb_was_on = false;
if (IS_LAYER_ON_STATE(state, LAYER_RGB)) {
rgb_was_on = true;
}
// Not in RGB edit layer, but previously were
if (!IS_LAYER_ON_STATE(state, LAYER_RGB) && rgb_was_on) {
rgb_was_on = false;
if (rgb_idle_edit_mode) {
// If we were editing the RGB idle mode, we are done now.
// Restore to active mode
rgb_idle_edit_mode = false;
rgb_matrix_state_restore(&active_rgb_matrix);
}
// Done changing stuff, save settings in "EEPROM"
config.active_rgb_matrix = active_rgb_matrix;
config.idle_rgb_matrix = idle_rgb_matrix;
eeconfig_update_kb_datablock(&config, 0, EECONFIG_KB_DATA_SIZE);
}
#endif
return layer_state_set_user(state);
}
// Process custom keycodes
bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
#ifdef RGB_IDLE_ENABLE
// If we were idling and a key was pressed, restore active RGB
if (record->event.pressed) {
if (rgb_idle_mode) {
rgb_matrix_state_restore(&active_rgb_matrix);
rgb_idle_mode = false;
}
}
#endif
switch (keycode) {
#ifdef RGB_IDLE_ENABLE
// Handle all the RGB settings
case RM_DMOD:
if (record->event.pressed) {
// Change the RGB matrix state to active if editing idle
if (rgb_idle_edit_mode) {
rgb_matrix_state_restore(&active_rgb_matrix);
rgb_idle_edit_mode = false;
}
rgb_matrix_step_noeeprom();
rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_IMOD:
if (record->event.pressed) {
// Change the RGB matrix state to idle
if (!rgb_idle_edit_mode) {
rgb_matrix_state_restore(&idle_rgb_matrix);
rgb_idle_edit_mode = true;
} else {
rgb_matrix_step_noeeprom();
rgb_matrix_state_save(&idle_rgb_matrix);
}
}
return false;
case RM_SATU:
if (record->event.pressed) {
rgb_matrix_increase_sat_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_SATD:
if (record->event.pressed) {
rgb_matrix_decrease_sat_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_VALU:
if (record->event.pressed) {
rgb_matrix_increase_val_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_VALD:
if (record->event.pressed) {
rgb_matrix_decrease_val_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_HUEU:
if (record->event.pressed) {
rgb_matrix_increase_hue_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_HUED:
if (record->event.pressed) {
rgb_matrix_decrease_hue_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_SPDU:
if (record->event.pressed) {
rgb_matrix_increase_speed_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
case RM_SPDD:
if (record->event.pressed) {
rgb_matrix_decrease_speed_noeeprom();
rgb_idle_edit_mode ? rgb_matrix_state_save(&idle_rgb_matrix) : rgb_matrix_state_save(&active_rgb_matrix);
}
return false;
#endif
}
return process_record_user(keycode, record);
};
void keyboard_post_init_kb(void) {
#ifdef RGB_IDLE_ENABLE
// Read in the RGB Matrices from before
eeconfig_read_kb_datablock(&config, 0, EECONFIG_KB_DATA_SIZE);
active_rgb_matrix = config.active_rgb_matrix;
idle_rgb_matrix = config.idle_rgb_matrix;
// Restore the active matrix
rgb_matrix_state_restore(&active_rgb_matrix);
#endif
keyboard_post_init_user();
}
// Setup default EEPROM config values
void eeconfig_init_kb_datablock(void) {
#ifdef RGB_IDLE_ENABLE
rgb_matrix_state_t default_active_rgb_matrix;
rgb_matrix_state_t default_idle_rgb_matrix;
default_active_rgb_matrix.mode = RGB_MATRIX_GRADIENT_UP_DOWN;
default_active_rgb_matrix.hsv = (HSV){127, 255, 100};
default_active_rgb_matrix.speed = 127;
default_idle_rgb_matrix.mode = RGB_MATRIX_BREATHING;
default_idle_rgb_matrix.hsv = (HSV){127, 255, 100};
default_idle_rgb_matrix.speed = 127;
config.active_rgb_matrix = default_active_rgb_matrix;
config.idle_rgb_matrix = default_idle_rgb_matrix;
eeconfig_update_kb_datablock(&config, 0, EECONFIG_KB_DATA_SIZE);
# if (EECONFIG_USER_DATA_SIZE) > 0
eeconfig_init_user_datablock();
# endif // EECONFIG_USER_DATA_SIZE
#endif // RGB_IDLE_ENABLE
}

View File

@@ -0,0 +1,34 @@
/* Copyright 2023 Acliad
*
* 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"
enum custom_keycodes {
RM_DMOD = QK_KB,
RM_IMOD
};
#define LAYER_RGB (MAX_LAYER - 1)
#ifdef RGB_IDLE_ENABLE
#define RGB_IDLE_TIMEOUT_MS (10*60*1000)
// Functions exposed by nifty_numpad.c
bool rgb_matrix_idle_mode(void);
#endif

View File

@@ -0,0 +1,3 @@
ifeq ($(strip $(RGB_IDLE_ENABLE)), yes)
OPT_DEFS += -DRGB_IDLE_ENABLE
endif

View File

@@ -0,0 +1,35 @@
# Nifty Numpad
![Nifty Numpad](https://i.imgur.com/jfB8tfKh.png)
Nifty Numpad is a full sized numpad with an extra row and two extra columns of macro keys. It was created because I wanted a companion to my TKL keyboard for work. My main workflow involves heavy use of ECAD programs, so the design was tailored for that, but it is generic enough to be nice for many workflows!
The main features are:
- Full sized numpad with row of macro/function keys on the top
- Two extra columns of macro keys
- Cherry MX style socketed switches
- Key Backlights
- 3D printable case (FDM or resin)
### Development Information:
* Keyboard Maintainer: [Isaac Rex](https://github.com/Acliad/)
* Hardware Supported: RP2040
* Hardware Availability: See [The GitLab Page](https://gitlab.com/Acliad/nifty-numpad) for full details
Make example for this keyboard (after setting up your build environment):
make nifty_numpad:default
Flashing example for this keyboard:
make nifty_numpad:default:flash
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).
## Bootloader
Enter the bootloader in 2 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (top left) and plug in the keyboard
* **Physical reset button**: Press the `RST` button while holding the `BOOT_SEL` button on the back of the PCB

View File

@@ -0,0 +1,48 @@
{
"manufacturer": "prkrln",
"keyboard_name": "pad9",
"maintainer": "prkrln",
"diode_direction": "COL2ROW",
"bootloader": "rp2040",
"processor": "RP2040",
"features": {
"bootmagic": true,
"encoder": true,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"encoder": {
"rotary": [
{"pin_a": "GP27", "pin_b": "GP26"}
]
},
"matrix_pins": {
"direct": [
["GP6", "GP1", "GP3"],
["GP29", "GP7", "GP4"],
["GP28", "GP0", "GP2"]
]
},
"usb": {
"device_version": "1.0.0",
"pid": "0x5009",
"vid": "0x504B"
},
"community_layouts": ["ortho_3x3"],
"layouts": {
"LAYOUT_ortho_3x3": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0, "encoder": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1},
{"matrix": [1, 1], "x": 1, "y": 1},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2},
{"matrix": [2, 1], "x": 1, "y": 2},
{"matrix": [2, 2], "x": 2, "y": 2}
]
}
}
}

View File

@@ -0,0 +1,18 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
};
#endif
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_ortho_3x3(
KC_1, KC_2, KC_3,
KC_4, KC_5, KC_6,
KC_7, KC_8, KC_9
)
};

View File

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

26
keyboards/pad9/readme.md Normal file
View File

@@ -0,0 +1,26 @@
# pad9
![pad9](https://github.com/prkrln/pad9/blob/main/pad9.jpg)
A cheap small macropad with the mcu underneath the switches.
* Keyboard Maintainer: [prkrln](https://github.com/prkrln)
* Hardware Supported: [XAIO RP2040](https://wiki.seeedstudio.com/XIAO-RP2040)
* Hardware Availability: [Seeed](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html), [Digikey](https://www.digikey.com/en/products/detail/seeed-technology-co-ltd/102010428/14672129)
Make example for this keyboard (after setting up your build environment):
make pad9:default
Flashing example for this keyboard:
make pad9:default:flash
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).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the encoder or top left key and plug in the keyboard
* **Physical reset button**: Briefly press the button on the back of the MCU
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View File

@@ -18,8 +18,8 @@ from qmk.makefile import parse_rules_mk_file
from qmk.math_ops import compute
from qmk.util import maybe_exit, truthy
true_values = ['1', 'on', 'yes']
false_values = ['0', 'off', 'no']
TRUE_VALUES = ['true', '1', 'on', 'yes']
FALSE_VALUES = ['false', '0', 'off', 'no']
class LedFlags(IntFlag):
@@ -319,7 +319,7 @@ def _extract_features(info_data, rules):
for key, value in rules.items():
if key.endswith('_ENABLE'):
key = '_'.join(key.split('_')[:-1]).lower()
value = True if value.lower() in true_values else False if value.lower() in false_values else value
value = True if value.lower() in TRUE_VALUES else False if value.lower() in FALSE_VALUES else value
if key in ['lto']:
continue
@@ -657,7 +657,7 @@ def _config_to_json(key_type, config_value):
elif key_type in ['bool', 'flag']:
if isinstance(config_value, bool):
return config_value
return config_value in true_values
return config_value in TRUE_VALUES
elif key_type == 'hex':
return '0x' + config_value[2:].upper()