Skip to content
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

Use PORT events for kscan matrix interrupts, add option for deep sleep. #211

Merged

Conversation

petejohanson
Copy link
Contributor

  • Lower power usage compared to regular interrupts on nrf52.

I've taken the first approach suggested in zephyrproject-rtos/zephyr#28499 and updated the matrix KSCAN driver to using GPIO_INT_LEVEL_ACTIVE, and disabling the interrupt(s) as soon as we get our first one.

This is fine, since we continuously poll and read while keys are pressed to properly detect releases, especially for multiple keys sharing the same input pin.

@Nicell Before I spend more time pursuing this, would you mind testing this, and power profiling it to compare the idle usage with this change?

Assuming this is working properly (I believe it is), we should be able to leverage this for enabling deep sleep, and allow waking each half with key presses, since the PORT events should still trigger when in that low power mode.

@petejohanson petejohanson added enhancement New feature or request help wanted Extra attention is needed core Core functionality/behavior of ZMK labels Sep 25, 2020
@petejohanson petejohanson self-assigned this Sep 25, 2020
@petejohanson petejohanson force-pushed the core/keymap-port-event-exploration branch 4 times, most recently from 255cc73 to 3b3c7e5 Compare October 3, 2020 03:59
@petejohanson petejohanson changed the title feat(kscan): Use PORT events for kscan matrix interrupts Use PORT events for kscan matrix interrupts, add option for deep sleep. Oct 3, 2020
@petejohanson
Copy link
Contributor Author

Ok, I've pushed ever more to this branch, this now includes the initial sleep/power management support I've been working on. This include support for:

  1. Going to deep sleep after a configured number of milliseconds without any key position event activity.
  2. Waking on keypress afterwards.
  3. Skipping deep sleep if we detect an active USB connection, since saving power in that scenario isn't as important, keeping the keyboard up is.

To test, you should be able to add:

CONFIG_ZMK_SLEEP=y
# CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=30000

And uncomment the timeout to change the default idle from 15 minutes to 30 seconds for easier testing.

@Nicell I haven't had a chance to fix the adveristing stuff yet to reduce power further, but can you try profiling this, in particularr once this actually enters deep sleep?

Caveats

On Linux (only so far), sometimes when resuming from sleep, my laptop will reconnect to the keyboard, but fail to setup the correct HOG input device, so even though the keyboard is sending GATT notifications on HID events, no one on the other end is listening.

I've got some hcidumps for working/non-working times, so I will be trying to analyze a bit more and try to see if it's something we are doing wrong on our end.

@petejohanson
Copy link
Contributor Author

Ok, so digging a bit more on the Linux reconnect issue, I find this discrepancy between working and non-working hcidump.

Working:

< ACL data: handle 8 flags 0x00 dlen 11
    ATT: Read By Type req (0x08)
      start 0x0001, end 0xffff
      type-uuid 0x2b3a
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 8 packets 1
> ACL data: handle 8 flags 0x02 dlen 9
    ATT: Error (0x01)
      Error: Attribute not found (10)
      Read By Type req (0x08) on handle 0x0001
< ACL data: handle 8 flags 0x00 dlen 11
    ATT: Read By Type req (0x08)
      start 0x0001, end 0xffff
      type-uuid 0x2b2a
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 8 packets 1
> ACL data: handle 8 flags 0x02 dlen 24
    ATT: Read By Type resp (0x09)
      length: 18
        handle 0x0008, value 0x00 0xe7 0x76 0x4c 0xbf 0x18 0x56 0x90 0xc6 0x1e 0x47 0xe5 0x8e 0x5c 0xf0 0x3b•

There is a "read by type" request that the keyboard responds to with an error.

When not working, I see this:

< ACL data: handle 22 flags 0x00 dlen 11
    ATT: Read By Type req (0x08)
      start 0x0001, end 0xffff
      type-uuid 0x2b3a
> ACL data: handle 22 flags 0x02 dlen 21
    ATT: Handle notify (0x1b)
      handle 0x0021    
      value 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00•

The "read by type" never is responded to by ZMK, which I think leaves the Linux HOG code "waiting" for a response, so it never finishes subscribing, creating the necessary HOG input device, etc.

Will dig more.

@petejohanson
Copy link
Contributor Author

The 0x2b3a attribute is defined in Zephyr as BT_UUID_GATT_SERVER_FEATURES, which for whatever reason Zephyr does not seem to respond to sometimes.

@petejohanson
Copy link
Contributor Author

Oh! For testing, make sure you do a west update before trying to build this. It requires a one line patch to our Zephyr fork.

@tominabox1
Copy link
Contributor

It appears that with ZMK_USB (usb hid) disabled, the build fails
image

As an end user, I would not expect USB HID output configuration to be related to power stuff, so I'm not sure if this is intended or not but its not what I would personally expect.

* Lower power usage compared to regular interrupts on nrf52.
@petejohanson petejohanson force-pushed the core/keymap-port-event-exploration branch 6 times, most recently from e9e432e to dfa316b Compare October 6, 2020 21:21
* New ZMK_SLEEP Kconfig symbol to enable the functionality.
* Switch to PORT events that allows wake from deep sleep.
* Initial basic power management policy, with idle ms,
  and ignoring deep sleep if we detect a USB connection.
@petejohanson petejohanson force-pushed the core/keymap-port-event-exploration branch from dfa316b to a7496ab Compare October 6, 2020 21:24
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.

Here goes nothing!

@petejohanson petejohanson merged commit 12b9a37 into zmkfirmware:main Oct 6, 2020
MangoIV pushed a commit to MangoIV/zmk that referenced this pull request Dec 18, 2020
…-event-exploration

Use PORT events for kscan matrix interrupts, add option for deep sleep.
tyalie pushed a commit to tyalie/zmk that referenced this pull request Nov 15, 2022
…-event-exploration

Use PORT events for kscan matrix interrupts, add option for deep sleep.
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 enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants