DevTerm Keyboard firmware mod: hot mode switching / gear switching

I’ve made a mod for the keyboard firmware to allow hot mode switching and gear switching.

Important: if your keyboard suffers from Keyboard stuck in Bootloader mode, please hold on a while – I need to cherry pick this fix into my firmware.

Usage

  • FN+DPAD L/R: Switch selector. Currently there are three selectors: Joystick, Gear and Powersave.
  • To switch gears, use FN+L/R to first select Gear mode. Then use FN+U/D to switch gears.
    • It assumes that the system boots up in gear 3.
    • Starting from v4, the keyboard is stateless, and the keyboard service remembers the current gear.
  • To switch joystick mode, use FN+LR to first select Joystick mode. Then use FN+U/D to switch joystick mode. There are 3 modes:
    • Joystick mode: stock joystick mode.
      • TODO: currently DPAD is mapped to left stick. Switch to right stick when middle button is pressed. Good for many-axis applications like OpenSCAD.
    • Keyboard mode: stock keyboard mode equivalent to flipping PD2
    • Mouse mode: mouse emulation.
      • DPAD: move/scroll
      • Select: Left mouse button
      • Start: Right mouse button
      • B: Left mouse button
      • A: Right mouse button
      • X: Middle mouse button / scroll (both horizontal and vertical!)
      • Y: Slow mode
    • Mouse mode has two overlay layers. SELECT = Layer1, START = Layer2. These two layers bind to unused joystick keys 23-32. The user service devterm-mouse.service will translate them into custom hotkeys:
    • Layer1: Data manipulation
      • SELECT-B: Send Ctrl-C (Copy)
      • SELECT-A: Send Ctrl-V (Paste)
      • SELECT-Y: Send Ctrl-A (Select all)
      • SELECT-X: Send Ctrl-X (Cut)
    • Layer2: Window management
      • START-Y: Toggle fullscreen
      • START-X: Close window
      • START-B: Move window
      • START-A: Resize window
  • Powersave mode: Type a few keys, and leave it idle for ~20seconds, and the keyboard will power down the USB subsystem. Saves about 100mA overall. The drawback is that resume latency is as high as 500ms – but I’ve gone a long way to make sure the keyboard does not drop your input (buffered).
    • Powersave is automatically disabled in Joystick mode.
    • You can also manually disable it with the powersave selector.

A notification will be sent to the desktop for the current operation.

Installation

  • Get the firmware package: https://nextcloud.yatao.info:10443/s/PFTDcwZPnakaW9E
    • (v5 and later) sudo ./yatli_custom_keyboard_fw_v5.sh
    • (v4 and earlier) Unpack, and cd yatli_custom_keyboard_fw && sudo ./flash.sh
    • Or, compile and upload the keyboard firmware.
  • Optional: Two accompanion services are also available, one for keyboard status monitoring/gear switching, one for mouse overlay.
    • Make sure that python3 and pip are installed.
    • If the service crashes with error ‘serial not found’, do: sudo pip install pyserial
    • A04 users, please edit devterm_keyboard.py and change devterm-a06-gearbox to devterm-a04-gearbox.
    • Navigate to DevTerm/Code/devterm_keyboard/service and sudo make install.

Changelog

14 Likes

Nicely done. These little community improvements are what I love about a device like this. New features continue to roll in long after it was made.

Question - Is this an enhancement to the official clockworkpi keyboard source, referred to as “DevTerm_keyboard_firmware_v0.1_utils.sh” and not the user re-written code, referred to as “DevTerm_keyboard_firmware_v0.2_utils.sh” and “DevTerm_keyboard_firmware_v0.3_utils.sh”, correct?

(as referred to here: I've rewritten DevTerm keyboard & trackball firmware)

Not sure, I never used the scripts to update the firmware.
Did not touch the scripts either, so my “compile and upload the keyboard firmware” means taking it out to a PC, use arduino to compile the code and upload the new fw.

I can probably also update the scripts though.

My starting point was the latest official code repo, and it already has the trackball enhancements.

DONE: joystick also needs some improvements. I noticed it only after I played some retro games: hold left, hold right, release left, joystick reports middle position instead of right.

TODO: deal with different cpi hardware versions and OS configurations. Arch/Manjaro package has a different name for the gearbox; Arch/Manjaro requires an additional script “root-notify-send” I wrote to correctly connect to the DBUS. And… the script currently doesn’t know about wayland sessions.

TODO: currently the serial communication is single-sided. Host receives notification changes from the keyboard. I’d like the host to also send commands to the keyboard, including:

  • Restore settings after power cycle.
  • Custom key mappings
  • Any suggestions?

I suggest power save modes. Power saving at the expense of response time. Maybe have the system place keyboard into “sleep” before suspend, and wake up after? Technically this should be done on the USB side, but that sounds complicated :sweat_smile:

I think the power to the keyboard is cut on suspend?

I still have usb power after suspend, but I haven’t tested it fully yet. Maybe it’s not going into deep suspend? ¯\_(ツ)_/¯

I’m not sure – saw some other users posting suspend issues like “can’t use keyboard to wake up from suspend” – maybe the host controller is done for and the keyboard is awake actually?

Maybe we should let it enter sleep if there’s no usb connection.

why has no one done a rotary encoder mod yet

any ideas where to place it?

It has been discussed before. I would likely know better once i get mine

Update: Joystick behavior fixed. fix joystick behavior · yatli/DevTerm@1bd6c2c · GitHub

Also as the first step towards @pkr 's suggestion, lowered from 72MHz to 48MHz (still crazy for a keyboard isn’t it)

2 Likes

@pkr I’ve implemented low-power mode.
Whenever there’s no user input, it uses the instruction “wfi” to wait for interrupts.

When I connect a charging meter between keyboard & DT, it stays at <10mA (so I cannot measure)
When I connect a charging meter between DT and charger, having keyboard installed/not installed resulted in ~100mA difference (570mA w/ keyboard vs. 470mA w/o keyboard)
I even tried to “half connect” the keyboard by only supplying power but not let the host see the keyboard – power remains at 470mA)
So I figure it’s not the keyboard is drawing that much power… but it’s the main cpu (A06) that’s kept busy by the keyboard. And A06 is very bad at energy saving at the moment.

3 Likes

Nice! This would be great for CM3 users because their devices don’t shut down all the way–USB stays on and the keyboard drains ~40mA. EDIT: weird. I also tried connecting my keyboard to a power meter via USB, and the current consumption was too low to measure… EDIT #2: daisy-chained a USB hub in between. Hub draws 0.06A, and after connecting kb it’s 0.13A. So I guess keyboard draws ~70mA? EDIT #3: trying all sorts of loads… (0.05A/0.09A, 0.06A/0.10A). Can’t seem to get 0.13A draw anymore, so I guess keyboard drains ~40mA.

Do you happen to have a binary I could test with? I’m too computer illiterate to do arduino stuff, especially under linux :sweat_smile:

Try this: Nextcloud

Install dfu-util first.
Then sudo ./flash.sh

1 Like

Thanks! Works great, though there’s no perceivable difference in power consumption. I don’t think I’ll be installing the daemon, but the joystick modes are very useful as-is :smiley:

Suggestion: for gear switching, it should send gear +/- (or up/down) instead of keeping track of the gear in the keyboard. That way the daemon can be easily changed to work with something else, or in case they add more gears in the future, etc…

1 Like

Also, a bug: in joystick mouse mode, middle button click doesn’t work (both X and the bottom middle button). It only enables scrolling.

Thanks for feedback. I must have broken something yesterday.

Overwrite the bin file and sudo ./flash.sh again

Warning: the script does not always work! It may leave the keyboard in a state that requires flashing via an Arduino IDE, or at least, detached and connected externally via microusb (sometimes fails to put the keyboard into DFU mode)