Skip to content

Commit

Permalink
Fix and Support ENCODER_MAP_ENABLE on Planck rev7
Browse files Browse the repository at this point in the history
* Fix for encoders
* Support ENCODER_MAP_ENABLE feature
* Update readme.md
  • Loading branch information
ykeisuke committed Jun 24, 2024
1 parent 378dbd3 commit 1134c38
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 22 deletions.
7 changes: 7 additions & 0 deletions keyboards/planck/rev7/keymaps/default/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
79 changes: 70 additions & 9 deletions keyboards/planck/rev7/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand All @@ -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];

Expand All @@ -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: {
Expand Down Expand Up @@ -303,4 +364,4 @@ bool dip_switch_update_user(uint8_t index, bool active) {
}
}
return true;
}
}
86 changes: 77 additions & 9 deletions keyboards/planck/rev7/matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <hal_pal.h>
#include <math.h>
#include "wait.h"
#include "encoder.h"

// STM32-specific watchdog config calculations
// timeout = 31.25us * PR * (RL + 1)
Expand Down Expand Up @@ -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
36 changes: 32 additions & 4 deletions keyboards/planck/rev7/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

```
,-----------------------------------------------------------------------------------.
Expand All @@ -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:
Expand All @@ -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
```

0 comments on commit 1134c38

Please sign in to comment.