forked from mirror/qmk_firmware
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0269eea2c9 | ||
|
|
1836382f66 | ||
|
|
504533b3b4 | ||
|
|
ba9642c83d |
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
50
keyboards/handwired/sector245/s245/keyboard.json
Normal file
50
keyboards/handwired/sector245/s245/keyboard.json
Normal 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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
18
keyboards/handwired/sector245/s245/keymaps/default/keymap.c
Normal file
18
keyboards/handwired/sector245/s245/keymaps/default/keymap.c
Normal 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
|
||||
@@ -0,0 +1 @@
|
||||
ENCODER_MAP_ENABLE = yes
|
||||
24
keyboards/handwired/sector245/s245/readme.md
Normal file
24
keyboards/handwired/sector245/s245/readme.md
Normal 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
|
||||
48
keyboards/pad9/keyboard.json
Normal file
48
keyboards/pad9/keyboard.json
Normal 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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
18
keyboards/pad9/keymaps/default/keymap.c
Normal file
18
keyboards/pad9/keymaps/default/keymap.c
Normal 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
|
||||
)
|
||||
};
|
||||
1
keyboards/pad9/keymaps/default/rules.mk
Normal file
1
keyboards/pad9/keymaps/default/rules.mk
Normal file
@@ -0,0 +1 @@
|
||||
ENCODER_MAP_ENABLE = yes
|
||||
26
keyboards/pad9/readme.md
Normal file
26
keyboards/pad9/readme.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# pad9
|
||||
|
||||

|
||||
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
|
||||
Reference in New Issue
Block a user