zmk
zmk copied to clipboard
Add wired split support using UART communication
Initial wired split support. Raised this PR to get feedback on initial changes and design
Changes:
- Updated Kconfig to allow configuring split communication type using Kconfig choice
- Type can either be BLE or SERIAL for now
- BLE is selected as default when board supports BLE
- Serial is selected when there is only USB support
- Used choice for central/peripheral instead of using single flag. This is experimental. Want to get feedback on this
- Use chosen node to select UART dev for serial split driver
- Serial central & service behaves similarly to the current ble split comm
- Only addition is the CRC to split position packet which i added as a defensive check
- Please look at the a_dux Kconfig.defconfig changes and let me know whether it makes sense to use like this.
Note:
- I tried to make changes to be not intrusive, i.e does not change/affect existing design to make PR merge smoother
- Ignore the west.yml change. Cherrypicked one PR from zephyr main for STM32 single wire UART and will revert it
- Ignore the stemcell.overlay file. I added this to give an idea about the change needed. Will remove this later.
- Will update other split keyboard's defconfig once the design seems acceptable
SteMCell board config: https://github.com/megamind4089/zmk-config/tree/main/config/boards/arm/stemcell
Cherrypicked zephyr PR: https://github.com/zephyrproject-rtos/zephyr/pull/40525
Should really the Async-API of zephyr's uart be used here? As far as I've seen the API is only supported by STM32, NRF and sam0. Or is the API the future 'standard' for uart in zephyr.
At least for now I'm not able to 'simply' use this on a Pi Pico... maybe I'll looker deeper on how the async api has to be implemented or find a workaround for this.
Maybe at least a Kconfig error should be generated if SERIAL_SUPPORT_ASYNC of a board is set to n?
I do think using the async API is probably preferred, which means we should work on the RP2040 UART driver for Zephyr to add support for it.
Yeah, thought so... maybe I'll find some time soon. So for now I'll have to stick with KMK for my KB2040 / Sofle combo ;-)
@marcoster Can this be used for two Nice!Nanos in its current state?
@petejohanson What would have to be done to move this forward?
I would also be interested in the answers to @mbrgm 's questions. Also, I wonder what the main benefits are of wiring the two halves. Does it reduce power consumption or improve latency?
And would it be possible to connect with Bluetooth to the host, and use uart between halves, or would this only be supported when connected over USB?
@mbrgm Sorry, never wrote an answer - as I don't have any nice!nanos around I don't really know, but since the nRF52840 in Zephyr supports async uart it normally should work. @nov1n Well I kinda don't need wireless split and some quite cheap and available controller-options (RP2040 boards i.e.) don't have any wireless capabilities. If done right I guess it should be possible to connect to the host per BLE.
Am I right to assume that UART support in Zephyr would allow for wired split communication between peripheral and central over TRRS? 🙏
Am I right to assume that UART support in Zephyr would allow for wired split communication between peripheral and central over TRRS? 🙏
This PR definitely needs a rebase into latest ZMK main
, but yes*.
- this assumes a proper hardware uart, not any single wire bit-banging approach, etc as is often used in many three wire TRRS splits.
I have a corne cherry with sparkfun_pro_micro_rp2040 and will make this work with the latest main branch within the next few days. Shall I open a new PR once done?
I have a corne cherry with sparkfun_pro_micro_rp2040 and will make this work with the latest main branch within the next few days. Shall I open a new PR once done?
Sure! See my previous note about the current state needing a working UART device (in terms of Zephyr device w/ associated UART driver) so any single wire work will need to either:
- Adapt this code to use a higher level abstraction than the Zephyr UART driver one, OR
- Create a UART driver that works for single wire hardware, maybe using PIO, etc. Doing this likely requires experimental Zephyr version that recently added PIO driver support.
Hey there, I was looking at implementing "just this" (wired connection between halves, likely using TRRS and UART TTL) on the Glove80 (dual nRF52840, harware UART). Any way I can help?
Am also interested in seeing this happen. If there's a contributor who wants to pick this up but needs hardware to do so, please post a comment and I'll sponsor the needful :)