From 1134c38c2012dd8424d27265d30be2d998f2c4d7 Mon Sep 17 00:00:00 2001 From: KEISUKE YAMAGUCHI Date: Fri, 21 Jun 2024 01:45:14 +0900 Subject: [PATCH] Fix and Support ENCODER_MAP_ENABLE on Planck rev7 * Fix for encoders * Support ENCODER_MAP_ENABLE feature * Update readme.md --- .../planck/rev7/keymaps/default/config.h | 7 ++ .../planck/rev7/keymaps/default/keymap.c | 79 +++++++++++++++-- keyboards/planck/rev7/matrix.c | 86 +++++++++++++++++-- keyboards/planck/rev7/readme.md | 36 +++++++- 4 files changed, 186 insertions(+), 22 deletions(-) diff --git a/keyboards/planck/rev7/keymaps/default/config.h b/keyboards/planck/rev7/keymaps/default/config.h index fbbab996e1e7..937d6a5e419f 100644 --- a/keyboards/planck/rev7/keymaps/default/config.h +++ b/keyboards/planck/rev7/keymaps/default/config.h @@ -41,3 +41,10 @@ - etc. */ // #define MIDI_ADVANCED + +/* + * Encoder options + */ +// #define PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY 20 +// #define ENCODER_MAP_KEY_DELAY 10 +// #define ENCODER_RESOLUTION 4 diff --git a/keyboards/planck/rev7/keymaps/default/keymap.c b/keyboards/planck/rev7/keymaps/default/keymap.c index 4ac4c0de4f88..c2d477f4165c 100644 --- a/keyboards/planck/rev7/keymaps/default/keymap.c +++ b/keyboards/planck/rev7/keymaps/default/keymap.c @@ -154,6 +154,62 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ) }; + +#ifdef ENCODER_MAP_ENABLE +/* Rotary Encoders + */ +const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { + /* Qwerty + * v- (index) Clockwise / Counter Clockwise v- (index) Clockwise / Counter Clockwise + * ,---------------------------------------------------------------------------------------. + * | (0) Vol- / Vol+ | | | | | | | | | | | (4) Vol- / Vol+ | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (1) KC_MNXT / KC_MPRV | | | | | | | | | | | (5) KC_MNXT / KC_MPRV | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (2) KC_WBAK / KC_WFWD | | | | | | | | | | | (6) KC_SPC / KC_ENT | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (3) KC_LEFT / KC_RGHT | | | | | | | | | | (7) KC_DOWN / KC_UP | + * `---------------------------------------------------------------------------------------' + */ + [_QWERTY] = { + // LEFT SIDE (index 0 to 3) + ENCODER_CCW_CW(KC_VOLU, KC_VOLD), + ENCODER_CCW_CW(KC_MNXT, KC_MPRV), + ENCODER_CCW_CW(KC_WBAK, KC_WFWD), + ENCODER_CCW_CW(KC_LEFT, KC_RGHT), + // RIGHT SIDE (index 4 to 7) + ENCODER_CCW_CW(KC_VOLU, KC_VOLD), + ENCODER_CCW_CW(KC_MNXT, KC_MPRV), + ENCODER_CCW_CW(KC_SPC, KC_ENT), + ENCODER_CCW_CW(KC_DOWN, KC_UP) + }, + + /* Adjust (Lower + Raise) + * v- (index) Clockwise / Counter Clockwise v- (index) Clockwise / Counter Clockwise + * ,---------------------------------------------------------------------------------------. + * | (0) _______ / _______ | | | | | | | | | | | (4) _______ / _______ | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (1) _______ / _______ | | | | | | | | | | | (5) _______ / _______ | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (2) RGB_MOD / RGB_RMOD| | | | | | | | | | | (6) SAT- / SAT+ | + * |-----------------------+---+---+---+---+---+---+---+---+---+---+-----------------------| + * | (3) BRGTH- / BRGTH+ | | | | | | | | | | (7) HUE- / HUE+ | + * `---------------------------------------------------------------------------------------' + */ + [_ADJUST] = { + // LEFT SIDE (index 0 to 3) + ENCODER_CCW_CW(_______, _______), + ENCODER_CCW_CW(_______, _______), + ENCODER_CCW_CW(RGB_MOD, RGB_RMOD), + ENCODER_CCW_CW(RGB_VAD, RGB_VAI), + // RIGHT SIDE (index 4 to 7) + ENCODER_CCW_CW(_______, _______), + ENCODER_CCW_CW(_______, _______), + ENCODER_CCW_CW(RGB_SAD, RGB_SAI), + ENCODER_CCW_CW(RGB_HUD, RGB_HUI) + } +}; +#endif /* clang-format on */ #ifdef AUDIO_ENABLE @@ -228,13 +284,13 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { /* clang-format off */ float melody[8][2][2] = { - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, - {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, + {{440.0f, 8}, {440.0f, 24}}, {{440.0f, 8}, {440.0f, 24}}, }; /* clang-format on */ @@ -251,7 +307,7 @@ float melody[8][2][2] = { #define ET12_MAJOR_THIRD 1.259921 #define ET12_PERFECT_FOURTH 1.33484 #define ET12_TRITONE 1.414214 -#define ET12_PERFECT_FIFTH 1.498307 +#define ET12_PERFECT_FIFTH 1.498307 deferred_token tokens[8]; @@ -275,6 +331,11 @@ bool encoder_update_user(uint8_t index, bool clockwise) { return false; } +void encoder_keymap_task(uint8_t index, bool clockwise) { + // Write your custom logic here + encoder_update_user(index, clockwise); +} + bool dip_switch_update_user(uint8_t index, bool active) { switch (index) { case 0: { @@ -303,4 +364,4 @@ bool dip_switch_update_user(uint8_t index, bool active) { } } return true; -} \ No newline at end of file +} diff --git a/keyboards/planck/rev7/matrix.c b/keyboards/planck/rev7/matrix.c index 777bd6a7fe80..4f5bbbf69655 100644 --- a/keyboards/planck/rev7/matrix.c +++ b/keyboards/planck/rev7/matrix.c @@ -19,6 +19,7 @@ #include #include #include "wait.h" +#include "encoder.h" // STM32-specific watchdog config calculations // timeout = 31.25us * PR * (RL + 1) @@ -111,13 +112,80 @@ bool matrix_scan_custom(matrix_row_t current_matrix[]) { return changed; } -uint8_t encoder_quadrature_read_pin(uint8_t index, bool pad_b) { - pin_t pin = pad_b ? B13: B12; - gpio_set_pin_input_high(pin); - gpio_write_pin_low(matrix_row_pins[index]); - wait_us(10); - uint8_t ret = gpio_read_pin(pin) ? 1 : 0; - gpio_set_pin_input_low(matrix_row_pins[index]); - gpio_set_pin_input_low(pin); - return ret; +#if defined(ENCODER_ENABLE) || defined(ENCODER_MAP_ENABLE) + +#if !defined(PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY) +# define PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY 20 +#endif +#if !defined(ENCODER_RESOLUTION) +# define ENCODER_RESOLUTION 4 +#endif + +#define ENCODER_CLOCKWISE true +#define ENCODER_COUNTER_CLOCKWISE false + +int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; +uint8_t encoder_state[8] = {0}; +int8_t encoder_pulses[8] = {0}; + + +__attribute__ ((weak)) void encoder_keymap_task(uint8_t index, bool clockwise) { +} + +static void encoder_handle_state_change(uint8_t index, uint8_t state) { + uint8_t i = index; + + const uint8_t resolution = ENCODER_RESOLUTION; + + encoder_pulses[i] += encoder_LUT[state & 0xF]; + + if (encoder_pulses[i] >= resolution) { + encoder_queue_event(index, ENCODER_COUNTER_CLOCKWISE); + encoder_keymap_task(index, ENCODER_COUNTER_CLOCKWISE); + } + + // direction is arbitrary here, but this clockwise + if (encoder_pulses[i] <= -resolution) { + encoder_queue_event(index, ENCODER_CLOCKWISE); + encoder_keymap_task(index, ENCODER_CLOCKWISE); + } + encoder_pulses[i] %= resolution; + } + +void encoder_driver_task(void) { + + // set up C/rows for encoder read + for (int i = 0; i < MATRIX_ROWS; i++) { + gpio_set_pin_output(matrix_row_pins[i]); + gpio_write_pin_high(matrix_row_pins[i]); + } + + // set up A & B for reading + gpio_set_pin_input_high(B12); + gpio_set_pin_input_high(B13); + + for (int i = 0; i < MATRIX_ROWS; i++) { + gpio_write_pin_low(matrix_row_pins[i]); + wait_us(PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY); + uint8_t new_status = (palReadPad(GPIOB, 12) << 0) | (palReadPad(GPIOB, 13) << 1); + if ((encoder_state[i] & 0x3) != new_status) { + encoder_state[i] <<= 2; + encoder_state[i] |= new_status; + encoder_handle_state_change(i, encoder_state[i]); + } + gpio_write_pin_high(matrix_row_pins[i]); + } + + // revert A & B to matrix state + gpio_set_pin_input_low(B12); + gpio_set_pin_input_low(B13); + + // revert C/rows to matrix state + for (int i = 0; i < MATRIX_ROWS; i++) { + gpio_set_pin_input_low(matrix_row_pins[i]); + } + +} + +#endif // ENCODER_ENABLE || ENCODER_MAP_ENABLE diff --git a/keyboards/planck/rev7/readme.md b/keyboards/planck/rev7/readme.md index 6a4df377046a..9831a03f0ae5 100644 --- a/keyboards/planck/rev7/readme.md +++ b/keyboards/planck/rev7/readme.md @@ -14,7 +14,8 @@ See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_to ## Encoders -Encoders must have matching pulse & detent resolutions (e.g. 24/24) for the scanning to work properly. Multiple encoders can be used at the same time, and are zero-indexed (compared to being one-indexed on the PCB's silkscreen) in the `encoder_update_user(uint8_t index, bool clockwise)` function: +Encoders must have matching pulse & detent resolutions (e.g. 24/24) for the scanning to work properly. Multiple encoders can be used at the same time. +If an encoder has a switch built-in, it's connected to the key at that location with index number: ``` ,-----------------------------------------------------------------------------------. @@ -28,7 +29,34 @@ Encoders must have matching pulse & detent resolutions (e.g. 24/24) for the scan `-----------------------------------------------------------------------------------' ``` -If an encoder has a switch built-in, it's connected to the key at that location. On the default keymap, each encoder will play its own rising/falling tone sequence when rotated, and will reset the pitch after one second of inactivity. The encoder map feature is not currently supported. +Planck rev7 support `ENCODER_ENABLE` and `ENCODER_MAP_ENABLE`. If both ENCODER_MAP_ENABLE and ENCODER_ENABLE are defined, ENCODER_MAP_ENABLE takes precedence. On the default keymap, each encoder will play its own rising/falling tone sequence when rotated, and will reset the pitch after one second of inactivity. + +### With ENCODER_ENABLE + +Define it as follows in `rules.mk`: + +``` +ENCODER_ENABLE = yes +``` + +Zero-indexed (compared to being one-indexed on the PCB's silkscreen) in the `encoder_update_user(uint8_t index, bool clockwise)` function. + +### With ENCODER_MAP_ENABLE + +Define it as follows in `rules.mk`: + +``` +ENCODER_MAP_ENABLE = yes +``` + +If you enable `ENCODER_MAP_ENABLE`, defined `const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]` and configure your keycode. And, If you enable `ENCODER_MAP_ENABLE`, does not use `encoder_update_user` directly. However by default, `encoder_update_user` has use via `encoder_keymap_task(uint8_t index, bool clockwise)` for play tone sequence. + +Absolutely, You can use the following config.h options: + +```c +#define ENCODER_MAP_KEY_DELAY 10 +#define ENCODER_RESOLUTION 4 +``` ## Some Planck-specific config.h options: @@ -37,6 +65,6 @@ If an encoder has a switch built-in, it's connected to the key at that location. #define PLANCK_WATCHDOG_TIMEOUT 1.0 // disables the watchdog timer - you may want to disable the watchdog timer if you use longer macros #define PLANCK_WATCHDOG_DISABLE -// the resolution of the encoders used in the encoder matrix -#define PLANCK_ENCODER_RESOLUTION 4 +// Sets the time to wait for the rotary encoder pin state to stabilize while scanning (Default is 20(us)) +#define PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY 20 ```