-
-
Notifications
You must be signed in to change notification settings - Fork 37.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for encoders and support ENCODER_MAP_ENABLE on Planck rev7 #23967
base: develop
Are you sure you want to change the base?
Conversation
280c1d4
to
78ffe75
Compare
c81492d
to
f52be72
Compare
keyboards/planck/rev7/matrix.c
Outdated
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); | ||
} | ||
|
||
// direction is arbitrary here, but this clockwise | ||
if (encoder_pulses[i] <= -resolution) { | ||
encoder_queue_event(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]); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rolls back encoder abstraction PR, so I can't approve it.
Work out what the actual issue is, rather than blindly reverting the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tracyde Thank you for your review. I see. Of course, If can use abstraction codes, I think that needs use it.
but does not work with abstraction code.
but I tried update code with encoder_quadrature_handle_read. what do you think?
1cf0cc6
Note: This message is old. @sigprof tells me good(?) code after commit code. Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did update code. Please continue check. e34700f
keyboards/planck/rev7/matrix.c
Outdated
#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 | ||
|
||
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); | ||
encoder_quadrature_handle_read(i, palReadPad(GPIOB, 12), palReadPad(GPIOB, 13)); | ||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the custom matrix implementation, I guess that something like this should work:
#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 | |
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); | |
encoder_quadrature_handle_read(i, palReadPad(GPIOB, 12), palReadPad(GPIOB, 13)); | |
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 | |
#if !defined(PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY) | |
# define PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY 20 | |
#endif | |
void encoder_quadrature_init_pin(uint8_t index, bool pad_b) { | |
// encoder_init() is called before matrix_init(), so the pin init needs to be done here. | |
pin_t col_pin = pad_b ? B13 : B12; | |
gpio_set_pin_input_low(col_pin); | |
gpio_set_pin_input_low(matrix_row_pins[index]); | |
} | |
uint8_t encoder_quadrature_read_pin(uint8_t index, bool pad_b) { | |
pin_t col_pin = pad_b ? B13 : B12; | |
gpio_set_pin_high(col_pin); | |
wait_us(PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY); | |
uint8_t ret = gpio_read_pin(matrix_row_pins[index]) ? 0 : 1; | |
gpio_set_pin_input_low(col_pin); | |
return ret; | |
} |
(Although the matrix code uses gpio_set_pin_low()
instead of gpio_set_pin_input_low()
for inactive columns; maybe it should be used here too, then the encoder pin init code in matrix_init_custom()
needs to be changed to match.)
It could be possible to avoid the multiple settle delays by reading the state of all encoders at once, but with the current API it would require either making some assumptions about the order of encoder_quadrature_read_pin()
calls (and in the existing code the order of calls for pads A and B is actually unspecified), or overriding encoder_driver_task()
.
And this implementation of encoder_quadrature_init_pin()
might still not be enough, because it does not init the other column pins, so they might interfere with the encoder_quadrature_read_pin()
calls done during encoder_quadrature_post_init()
(that's unlikely though, because it would require that some keys are held down during startup). Doing things in a 100% correct way may require moving the matrix pin init into keyboard_pre_init_kb()
, then encoder_quadrature_init_pin()
may be empty (the default implementation still needs to be overridden though).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sigprof Thank you for your review and sample code.
I may do not understand your sample code, I tried use your code on my local env and but does not work correct. so I will try find other way as reference to your sample code, and I need a time more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: does not work code.
#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 | |
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); | |
encoder_quadrature_handle_read(i, palReadPad(GPIOB, 12), palReadPad(GPIOB, 13)); | |
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 | |
#if defined(ENCODER_ENABLE) || defined(ENCODER_MAP_ENABLE) | |
void encoder_quadrature_init_pin(uint8_t index, bool pad_b) { | |
// encoder_init() is called before matrix_init(), so the pin init needs to be done here. | |
pin_t col_pin = pad_b ? B13 : B12; | |
gpio_set_pin_input_low(col_pin); | |
gpio_set_pin_input_low(matrix_row_pins[index]); | |
} | |
uint8_t encoder_quadrature_read_pin(uint8_t index, bool pad_b) { | |
pin_t col_pin = pad_b ? B13 : B12; | |
gpio_set_pin_input_high(col_pin); // If using `gpio_set_pin_high`, compile error. so i did change to this. | |
wait_us(PLANCK_ENCODER_SETTLE_PIN_STATE_DELAY); | |
uint8_t ret = gpio_read_pin(matrix_row_pins[index]) ? 0 : 1; | |
gpio_set_pin_input_low(col_pin); | |
return ret; | |
} | |
#endif // ENCODER_ENABLE || ENCODER_MAP_ENABLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, that was a typo, gpio_set_pin_high
should have been gpio_write_pin_high
; replacing it with gpio_set_pin_input_high
would break things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(And gpio_set_pin_output(col_pin)
is needed before.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And your code which switches the row pins to the output mode somewhat defeats the point of the custom matrix implementation (to avoid using the C13…C15 pins as outputs). My suggestion tries to keep those pins in the input mode, as the custom matrix code does (but apparently writing the code in the GitHub comment box is too hard).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sigprof I did update code with blank encoder_quadrature_init_pin function. (already called gpio_set_pin_input_low for B12 and B13 on matrix_init_custom(void))
My suggestion tries to keep those pins in the input mode, as the custom matrix code does
I'm not confident. but updated. Is this commit expected code? e34700f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
encoder_init() is called before matrix_init(), so the pin init needs to be done here.
That commit has blank encoder_quadrature_init_pin function. but looks no problem for me on using. Should that use encoder_quadrature_init_pin
? and needs delete init code in matrix_init_custom
?
1cf0cc6
to
e34700f
Compare
180a2fc
to
634f9c4
Compare
* Fix for encoders * Support ENCODER_MAP_ENABLE feature * Update readme.md
…AP_ENABLE, play melody.
634f9c4
to
45167b6
Compare
Description
ENCODER_MAP_ENABLE
feature on Planck rev7Types of Changes
Issues Fixed or Closed by This PR
Checklist