Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Cem Aksoylar <[email protected]>
  • Loading branch information
petejohanson and caksoylar authored Sep 29, 2023
1 parent a88c814 commit 4edcd5d
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions docs/docs/features/soft-off.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Soft Off Feature
sidebar_label: Soft Off
---

Similar to the deep sleep feature, that will send the keyboard into a low power state after a certain period of inactivity, the soft off feature is used to turn the keyboard on and off explicitly. Depending on the keyboard, this may be through a dedicated on/off push button, or merely through an additional binding in the keymap to turn the device off, and the existing reset button to turn the device back on.
Similar to the deep sleep feature that sends the keyboard into a low power state after a certain period of inactivity, the soft off feature is used to turn the keyboard on and off explicitly. Depending on the keyboard, this may be through a dedicated on/off push button, or merely through an additional binding in the keymap to turn the device off and the existing reset button to turn the device back on.

The feature is intended as an alternative to using a hardware switch to physically cut power from the battery to the keyboard. This can be useful for existing PCBs not designed for wireless that don't have a power switch, or for new designs that favor a push button on/off like found on other devices.

Expand All @@ -16,13 +16,13 @@ The power off is accomplished by putting the MCU into a "soft off" state. Power
Once powered off, the keyboard will only wake up when:

- You press the same button/sequence that you pressed to power off the keyboard, or
- You press a reset button found on the keyboard
- You press a reset button found on the keyboard.

## Soft Off With Existing Designs

For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap, and then invoking it. For splits, at least for now, you'll need to place it somewhere on each side of your keymap, triggering it on your split peripheral side first.
For existing designs, using soft off is as simple as placing the [Soft Off Behavior](../behaviors/soft-off.md) in your keymap and then invoking it. For splits, at least for now, you'll need to place it somewhere on each side of your keymap and trigger on both sides, starting from the peripheral side first.

Waking the keyboard is as simple as pressing the reset button once.
You can then wake up the keyboard by pressing the reset button once, and repeating this for each side for split keyboards.

## Adding Soft On/Off To New Designs

Expand All @@ -35,17 +35,17 @@ soft off state when it goes active again later.

The simplest way to achieve this is with a push button between a GPIO pin and ground.

#### Martix Integrated Hardware Combo
#### Matrix-Integrated Hardware Combo

Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin, so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times.
Another, more complicated option is to tie two of the switch outputs in the matrix together through an AND gate and connect that to the dedicated GPIO pin. This way you can use a key combination in your existing keyboard matrix to trigger soft on/off. To make this work best, the two switches used should both be driven by the same matrix input pin so that both will be active simultaneously on the AND gate inputs. The alternative is to use a combination of diodes and capacitors to ensure both pins are active/high at the same time even if scanning sets them high at different times.

### Firmware Changes

Several items work together to make both triggering soft off properly, and setting up the device to _wake_ from soft off work as expected.

#### GPIO Key

Zephyr's basic GPIO Key concept is used as a shared configuration of the details of the GPIO pin that will be used both for triggering soft off, and for waking the device latter. Here is an example for a keyboard with a dedicated on/off push button that is a direct wire between the GPIO pin, and ground:
Zephyr's basic GPIO Key concept is used to configure the GPIO pin that will be used for both triggering soft off and waking the device later. Here is an example for a keyboard with a dedicated on/off push button that is a direct wire between the GPIO pin and ground:

```
/ {
Expand All @@ -58,9 +58,9 @@ Zephyr's basic GPIO Key concept is used as a shared configuration of the details
};
```

GPIO keys are defined by using child nodes under the `gpio-keys` compatible node. Each child needs just one property defined:
GPIO keys are defined using child nodes under the `gpio-keys` compatible node. Each child needs just one property defined:

- The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the pin low by pressing a switch that has the other leg connected to ground.
- The `gpios` property should be a phandle-array with a fully defined GPIO pin and with the correct pull up/down and active high/low flags set. In the above example the soft on/off would be triggered by pulling the specified pin low, typically by pressing a switch that has the other leg connected to ground.

#### Behavior Key

Expand Down Expand Up @@ -93,7 +93,7 @@ Here are the properties for the behavior key node:
- The `bindings` property is a phandle to the soft off behavior defined above.
- The `key` property is a phandle to the GPIO key defined earlier.

If you have set up your on/off to be controlled by a matrix integrated combo, the behavior key needs use a different driver that will handle detecting the pressed state when the pin is toggled by the other matrix kscan driver:
If you have set up your on/off to be controlled by a matrix-integrated combo, the behavior key needs use a different driver that will handle detecting the pressed state when the pin is toggled by the other matrix kscan driver:

```
/ {
Expand All @@ -106,15 +106,15 @@ If you have set up your on/off to be controlled by a matrix integrated combo, th
};
```

The only difference is using a `compatible` value of `zmk,behavior-key-scanned`.
Note that the only difference from the `soft_off_behavior_key` definition for GPIO keys above is the `compatible` value of `zmk,behavior-key-scanned`.

#### Wakeup Sources

Zephyr has general support for the concept of a device as a "wakeup source", which ZMK has not previously used. Adding soft off requires properly updating the existing `kscan` devices with the `wakeup-source` property, e.g.:

```
/ {
kscan0: kscan_0 {
kscan0: kscan_0 {
compatible = "zmk,kscan-gpio-matrix";
label = "KSCAN";
diode-direction = "col2row";
Expand All @@ -127,7 +127,7 @@ Zephyr has general support for the concept of a device as a "wakeup source", whi

#### Soft Off Waker

Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and which will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed.
Next, we need to add another device which will be enabled only when the keyboard is going into soft off state, and will configure the previously declared GPIO key with the correct interrupt configuration to wake the device from soft off once it is pressed.

```
/ {
Expand All @@ -145,7 +145,7 @@ Here are the properties for the node:
- The `compatible` property for the node must be `zmk,wakeup-trigger-key`.
- The `trigger` property is a phandle to the GPIO key defined earlier.
- The `wakeup-source` property signals to Zephyr this device should not be suspended during the shutdown procedure.
- An optional `output-gpios` property contains a list of GPIO pins to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off.
- An optional `output-gpios` property contains a list of GPIO pins (including the appropriate flags) to set active before going into power off, if needed to ensure the GPIO pin will trigger properly to wake the keyboard. This is only needed for matrix integrated combos. For those keyboards, the list should include the matrix output needs needed so the combo hardware is properly "driven" when the keyboard is off.

Once that is declared, we will list it in an additional configuration section so that the ZMK soft off process knows it needs to enable this device as part of the soft off processing:

Expand All @@ -161,4 +161,4 @@ Once that is declared, we will list it in an additional configuration section so
Here are the properties for the node:

- The `compatible` property for the node must be `zmk,soft-off-wakeup-sources`.
- The `wakeup-sources` property is a phandle array pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard.
- The `wakeup-sources` property is a [phandle array](../config/index.md#devicetree-property-types) pointing to all the devices that should be enabled during the shutdown process to be sure they can later wake the keyboard.

0 comments on commit 4edcd5d

Please sign in to comment.