Metadata-Version: 2.4
Name: das-keyboard-4-flasher
Version: 0.1.0
Summary: Firmware flasher for the Das Keyboard 4 (Professional, Ultimate, Professional for Mac)
Author: Giuseppe Iannello
License-Expression: GPL-3.0-only
Project-URL: Homepage, https://github.com/giannello/das_keyboard_4
Project-URL: Issues, https://github.com/giannello/das_keyboard_4/issues
Keywords: das-keyboard,das-keyboard-4,dk4,keyboard,firmware,flasher,hid
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: COPYING
Requires-Dist: hidapi>=0.14.0
Dynamic: license-file

# Das Keyboard 4 Flasher

A firmware flasher for the **Das Keyboard 4** — Professional, Ultimate and
Professional for Mac — which report themselves as `D4215` on USB `0x24F0` and are
built by Heng Yu Technology as an OEM for Metadot.

This is specific to the DK4. Other Das Keyboard models use different firmware and
are not supported; see [Scope](#scope) below.

The vendor ships flashing utilities for Windows and macOS. This is a single-file
cross-platform alternative with two additions the vendor tools do not have:

- **`verify`** — runs every non-writing check against a connected keyboard and
  reports a pass/fail table, so you can confirm a unit is updatable *before*
  starting a flash.
- **`info`** — parses and validates a firmware image without touching hardware.

Both apply to both platforms; the vendor's Windows and macOS utilities are separate
programs that only run on their own OS.

## Install

```console
$ pip install das-keyboard-4-flasher
```

That is the whole command. `hidapi` is installed automatically as a dependency, and
the package installs two equivalent commands — `das-keyboard-4-flasher` and
`dk4-flasher` — so you can use whichever reads better.

On Linux, `hidapi` needs the USB system libraries present at runtime. Wheels are
published for macOS and Windows, so no extra work is needed there; on Linux
distributions that do not ship a wheel, install the runtime libraries first:

| Distribution | Command |
|---|---|
| Debian, Ubuntu | `sudo apt install libusb-1.0-0 libudev1` |
| Fedora, RHEL | `sudo dnf install libusbx systemd-libs` |
| Arch | `sudo pacman -S libusb libsystemd` |
| macOS | `brew install libusb` |

If `pip` tries to compile `hidapi` from source instead of using a wheel, you will
also need the headers (`libusb-1.0-0-dev libudev-dev` on Debian/Ubuntu,
`libusbx-devel libudev-devel` on Fedora) and a compiler.

You may need to be a member of a group that can read USB devices — on Debian and
Ubuntu that is typically `plugdev`:

```console
$ sudo usermod -aG plugdev $USER
```

Log out and back in for that to take effect. Without it the keyboard will not
enumerate for a non-root user even though it is plugged in.

## Scope

Supports the **Das Keyboard 4** family only:

| Model | USB | Notes |
|---|---|---|
| Das Keyboard 4 Professional | `0x24F0` | |
| Das Keyboard 4 Ultimate | `0x24F0` | |
| Das Keyboard 4 Professional for Mac | `0x24F0` | ships the macOS keymap variant |

All three present as `D4215` and share one firmware family. Other Das Keyboard
models (DK8, DK10, DK Pro, cloud-connected models, and any later release) are
**not** supported — they use different firmware and a different update mechanism.
Running this against another model is not prevented by design; it will simply fail
to find a device or fail validation.

**Firmware images are not distributed with this package.** Obtain them from the
vendor's official download. The image is a Windows or macOS variant and the two are
*not* interchangeable — the hardware is identical but the keycodes differ, and the
keyboard will not warn you if you flash the wrong one.

Note that the DK4 is a wired USB keyboard. Cloud-connected Das Keyboard models
require the vendor's DDK utility over a network connection and are unrelated to
this protocol.

## Usage

```console
$ das-keyboard-4-flasher list                      # find connected keyboards
$ das-keyboard-4-flasher info firmware.bin         # inspect an image, no hardware
$ das-keyboard-4-flasher selftest firmware.bin     # exercise the protocol vs a mock
$ das-keyboard-4-flasher flash firmware.bin --dry-run
$ das-keyboard-4-flasher flash firmware.bin --yes
$ das-keyboard-4-flasher verify firmware.bin       # check a unit is updatable
```

Run any subcommand with `-h` for its options.

### Typical session

```console
$ das-keyboard-4-flasher info L1947V33.bin
L1947V33.bin: application, 32 KB, profile Global Full
...
entry command  0xA0
version        'S1947V33'
  variant      Windows firmware, enumerates as 0x24F0:0140

$ das-keyboard-4-flasher verify L1947V33.bin
PASS: 16/16 checks passed
application version: 'S1947V33'
bootloader version: 'B2175V13'

$ das-keyboard-4-flasher flash L1947V33.bin --yes
  0xA0 enter ISP
  device reports target 32 KB, model 0x0000
  ...
Update successfully.
```

## Safety notes

- **Always run `verify` before `flash`.** It reports whether the unit can accept the
  image, including the profile check that actually gates the update.
- **Pass `--yes` deliberately.** `flash` is interactive by default; `--yes` skips the
  confirmation and is what makes it non-interactive.
- **Interrupted writes fail safe.** The image checksum is validated by the
  keyboard itself, and this tool writes the vector table last, so a flash cut short
  by a cable pull will not leave the unit unbootable.
- **Wrong-OS firmware is not caught by the device.** Both Windows and macOS images
  carry the same profile, so the keyboard accepts either. The symptom is misplaced
  keys, not a failure. `flash` warns when the running firmware disagrees with the
  image's known variant.
- **Bootloader images are refused.** The command that would install one does not
  work on this hardware — it latches a working keyboard instead. `flash` exits with
  an explanation rather than trying.
- **`verify` writes no flash** but does enter bootloader mode, and by default
  exercises a latch it then recovers from. Pass `--no-latch` to skip that part.
- **`flash --dry-run` still enters bootloader mode** and skips the reset that
  returns the keyboard to normal operation. If it stops there, run
  `das-keyboard-4-flasher reset` or unplug and replug.

## Troubleshooting

**`error: No Das Keyboard found`** — check `list`. If the keyboard is in bootloader
mode it shows PID `0x0000`; run `reset` to return it to normal operation.

**`OSError: read error` right after a mode change** — expected. The keyboard
re-enumerates and hidapi reports the drop as an error. The tool retries on its own;
a persistent failure means the keyboard did not come back, so replug it.

**Update fails at `0xA4 erase chip` with status `0x18`** — the profile check that
preceded it was rejected, even though the tool may have looked past it. This leaves
the existing firmware intact.

**The keyboard is unresponsive to commands but still types** — it is latched in
bootloader mode. `reset` fixes it without a power cycle.

## How it works

The [repository](https://github.com/giannello/das_keyboard_4) contains
`FIRMWARE_UPDATE_PROTOCOL.md`, which documents the wire protocol in full: frame
format, command table, firmware image layout and checksum, and the update
sequence, with the behavioural details that were measured on hardware and differ
from what the vendor's own tools do. Section numbers referenced in error messages
and source comments refer to that document.

That document is not shipped in the installed package — it is in the repository
only.

## License

GNU General Public License v3
See [`COPYING`](COPYING) for the full text.

    Copyright (C) 2026 Giuseppe Iannello

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, version 3 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
