feat(split): Runtime selection of split transport (#2886)

feat(split): Runtime selection of split transport

Allow building multiple split transports, and select an active
one based on the transport availability. Wired split availability
depends on additional `detect-gpios` which must be a GPIO pin
that goes active when a wired connection is present.

feat(split): Suspend/resume wired UART devices.

To better support runtime split support, suspend/resume the UART
as necessary to save power when not using the UART.

docs(split): Document adjusting nRF52 UART interrupt priorities

For wired split on nRF52, you may need to adjust the priority for UART
interrupts lower, to ensure the interrupts used for timing sensitive
BT operations can run when needed, so document this in our pinctrl docs.

refactor(split): Restore use of aync UART on nRF52.

With fixes for Zephyr UART driver, re-enable using async API on nRF52.

fix(split): Minor wired split fixes.

Various minor fixes for wired split to avoid spurious TX in half duplex,
etc.

fix: Unconditionally define HID payloads to avoid error.

Don't conditionally define HID indicator payload, to avoid compilation
errors.

docs(split): Expand on details of split transports.

Expand the split keyboard documentation with a more fleshed out section
on the available split trasnports, and what is and isn't supported by
each, including the runtime selection functionality.

---------

Co-authored-by: Nicolas Munnich <98408764+nmunnich@users.noreply.github.com>
This commit is contained in:
Pete Johanson
2025-06-16 01:45:25 -06:00
committed by GitHub
parent 462d48b78e
commit 6b44d33db2
22 changed files with 830 additions and 93 deletions

View File

@@ -358,6 +358,28 @@ In the pin control file:
bias-pull-up;
};
};
uart0_default: uart0_default {
group1 {
psels = <NRF_PSEL(UART_TX, 0, 22)>, // EXT1
<NRF_PSEL(UART_RX, 0, 21)>; // EXT2
};
};
uart0_sleep: uart0_sleep {
group1 {
/* configure P0.1 as UART_TX and P0.2 as UART_RTS */
psels = <NRF_PSEL(UART_TX, 0, 1)>, <NRF_PSEL(UART_RTS, 0, 2)>;
low-power-enable;
};
group2 {
/* configure P0.3 as UART_RX and P0.4 as UART_CTS */
psels = <NRF_PSEL(UART_RX, 0, 3)>, <NRF_PSEL(UART_CTS, 0, 4)>;
/* both P0.3 and P0.4 are configured with pull-up */
bias-pull-up;
low-power-enable;
};
};
};
```
@@ -368,10 +390,35 @@ In the main file:
&uart0 {
pinctrl-0 = <&uart0_default>;
pinctrl-names = "default";
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};
```
On designs using wired split on nRF52840, using asynchronous UART APIs with DMA will help ensure that the interrupts used to handle timing sensitive BT interactions can respond when needed.
This can be accomplished by overwriding the `compatible` property to `"nordic,nrf-uarte"`, e.g.:
```dts
&uart0 {
compatible = "nordic,nrf-uarte";
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};
```
In addition to this `compatible` override, a setting needs to be tweaked to ensure that the UART isn't selected for interrupt mode when async is prefered.
The following should be added to the board's/shield's `Kconfig.defconfig`:
```dts
config UART_0_INTERRUPT_DRIVEN
depends on !ZMK_SPLIT_WIRED_UART_MODE_ASYNC
```
for the correct `UART_#` prefix matching the numbered UART being used.
#### UART rp2040
In the pin control file: