Skip to content

Conversation

@petejohanson
Copy link
Contributor

This refactor is needed for my upcoming Ferris board work. In particular, the Ferris:

  • Uses the composite kscan driver, to compose the left and right half matrixes.
  • Uses matrix polling, which seems to have been broken by the interrupt work, done for sleep recently.

While there, I took the opportunity to add some more useful macros to make the conditional code a little bit easier to read.

There's also a small commit in here as well that removes some default n settings from some Kconfig settings to allow them to be defaulted yes elsewhere as needed.

* Actually allow defaulting yes in other places.
* Add easier macros for conditional polling/interrupt code.
* Properly continue polling on intervals, without extra
  enable/disable code for pins that is superfluous when not trying to
  deal with interupts firing.
* Fix to allow multiple GPIO drivers when doing splits w/ IO expanders
@petejohanson petejohanson added core Core functionality/behavior of ZMK refactor labels Jan 28, 2021
@petejohanson petejohanson self-assigned this Jan 28, 2021
Copy link
Collaborator

@joelspadin joelspadin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I fully understand how the kscan driver works, but everything I see changing here looks reasonable to me.

(int err = kscan_gpio_enable_interrupts_##n(dev); \
if (err) { return err; } return kscan_gpio_read_##n(dev);)) \
COND_POLL_OR_INTERRUPTS((struct kscan_gpio_data_##n *data = dev->data; \
k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10)); \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correctly interpreting this that when polling is enabled, we poll at a constant 100 Hz? It might be useful to make that configurable, for example if someone wanted to make a wired keyboard that polls as fast as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I hadn't remembered hardcoding.this, but it does seem so, yeah. Good item to move into Kconfig soon, yeah.

COND_POLL_OR_INTERRUPTS( \
(k_timer_init(&data->poll_timer, kscan_gpio_timer_handler_##n, NULL); \
kscan_gpio_set_output_state_##n(dev, 0);), \
(kscan_gpio_set_output_state_##n(dev, 1);)) \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would I be correct in guessing that the interrupt behavior is different here because it sets all the outputs active, waits for an interrupt to happen on any input, and then does a regular scan?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. We want to drive all outputs to active when "idle", so that any key press will trigger an interrupt. Then we keep polling/scanning until all keys are released again.

Copy link
Contributor Author

@petejohanson petejohanson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self approving, been using this extensively for several days on Ferris and on other interrupt based boards like Corne.

@petejohanson petejohanson merged commit 6c7ab0c into zmkfirmware:main Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core functionality/behavior of ZMK refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants