

Testing split kb
My own firmware for my own keyboard. Written in pure Rust.
- Size
- 121.5 × 73.1 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 37
- Nets
- 23
- Pads
- 207
- Tracks, vias
- 314, 9
- Routed
- Yes
- KiCad
- KiCad 9.0 (file 20241229)
- Created
- 3 Feb 2025
- Updated
- 29 Jul 2026
Overview
Testing split kb is an open-source printed circuit board by devcexx, from the devcexx/dxkb repository on GitHub. It is a 2-layer board of 121.5 × 73.1 mm with 37 parts on 23 nets, routed with 314 tracks and 9 vias.
Its parts include 15 diodes, 15 switches and 1 connector. It belongs with the keyboards and input boards and the STM32 boards of this library.
README
README.mddxkb
What is it?
dxkb is a keyboard firmware library purely developed in Rust, that provides the functionality to build your own keyboard. It is mainly designed for my personal use and for learning purposes. As of today, it only provides support for building split keyboards on the STM32F411 microcontroller.
What is it not?
dxkb is not a keyboard firmware that is provided ready to be flashed into a MCU. The API that provides is designed considering that the final user will define its own hardware configuration, main and ISR functions, as well as any other functionality aside from the keyboard itself, that is not included on the library (e.g. LEDs, OLED displays etc.)
Design tenets
As a learning project, I prioritize the following principles during the development:
-
Types first: Most of the keyboard configuration happens through types, that defines the configuration of the firmware in compile time, without adding extra overhead, or possible errors in runtime. This library makes a heavy use of types for defining a lot of aspects of the device, such as the size of the key matrix, debouncing algorithms, etc. This also usually translate into a heavy use of macros, that help to define types and impls that are useful to achieve this purpose.
-
No hardware abstraction frameworks: As part of the learning process in embedded development, it is preferred to avoid the usage of frameworks that abstracts too much over the hardware, and working close to it instead. Usage of these kind of frameworks, like Embassy or RTIC is not contemplated as for now.
-
Rust unstable: Nightly versions of Rust are preferred to play with all the unstable Rust features. The main driver for using Rust unstable is the ability to use generic_const_exprs, that are just too cool to not use them, even though it is still an incomplete feature. A successful compilation is not guaranteed in any other Rust version than the specified by this repository.
-
Some unsafe is fine: For the sake of avoiding as much as possible using unwraps or useless error handling when some condition cannot be proven to the compiler in compile time, and add extra overhead to the final binary; using some unsafe code is fine from the perspective of this library. For example, there are places in this library where some UnsafeCell's are used instead of RefCells, to avoid the overhead of the RefCell's borrow checking in, especially considering the fact that the only supported MCU is single-core.
-
Low number of external dependencies: As a learning project, it is preferred to investigate and develop my own version of some components, instead of using already existing libraries that can fit the needs. Base libraries such as HAL, PACs and USB control libraries are used, but generally, building the functionality as part of the library is preferred.
Features
-
Support for split keyboards (actually, it does not support anything else but split keyboards).
-
Key matrix:
- Support for column to row and row to column scans.
- Active-low press detection.
- Support for key debouncing (Right now, only implemented an eager, per-key debouncing algorithm, see QMK Docs for more information).
- Support for input pins oversampling (Read multiple times the matrix input pins to ensure that the received signals are coming from presses and are not electrical noise).
-
Support for report keyboard HID protocol, that is NKRO by default. Dual Boot + Report protocol support is still not implemented.
-
Debug endpoint that supports logging through a HID interface and debug command sending, such as commands to entering into the bootloader. Especially useful for PCBs that don't expose the STM32 debugging pins.
-
DMA-based serial communication across the two sides of the keyboard, up to 2 MBaud with option for Full duplex and Half duplex, and automatic frame separation through the detection of IDLE signals in the line.
-
Split link: a low-footprint protocol built on top of serial that allows a reliable, bidirectional communication across the sides of the keyboard. This protocol combines capabilities from a link and transport protocols, having the ability to detect whether the link is up, negotiate the link establishment, and frame management, ensuring that the messages arrive to the other side in order, with no duplicates, and automatically retransmitting dropped frames if the peer couldn't confirm the reception of one.
-
Automatic USB master side detection and promotion.
-
Custom key definition: New keys can be built with ease on top of the default ones that can define their own logic when pressed or unpressed.
-
Multi layer, tree based layer definition: The keyboard supports the definition of multiple layers, that can be defined in a tree hierarchy defined through macros. In compile time, this layer hierarchy is flattened, so that there's no a performance penalty when leading with bigger layer trees.
-
Remote wakeup support: The keyboard may wake up their host when this latter one is suspended, after pressing a key.
Examples
- Testing keyboard used for development purposes.
- My personal Lily58 keyboard firmware, that uses STeMCell as a drop-in replacement for the Arduino ProMicro, using a STM32F411 instead.
Parts
37| Qty | Value | Footprint | References |
|---|---|---|---|
| 15 | 1N4148 | TestingSplitKb:D_DO-35_SOD27_P7.62mm_Horizontal_BothSides | D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15 |
| 15 | SW_Push_Dual | TestingSplitKb:Kailh_socket_MX_reversible | SW1, SW2, SW3, SW4, SW5, SW6, SW7, SW8, SW9, SW10, SW11, SW12, SW13, SW14, SW15 |
| 3 | , , | ||
| 1 | Conn_01x08_Pin | Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_Vertical | J1 |
| 1 | LOGO | TestingSplitKb:TigerBite | G*** |
| 1 | LOGO | TestingSplitKb:Alasca | G*** |
The 36 most common of 37 parts.
Questions
How big is the Testing split kb PCB?
It measures 121.5 × 73.1 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Testing split kb use?
37 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Testing split kb KiCad files?
From the devcexx/dxkb repository on GitHub, at the commit this page was made from: the board is testing-split-kb/testing-split-kb.kicad_pcb and its schematic testing-split-kb/testing-split-kb.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Testing split kb design in my own project?
Its repository states no licence, so its author keeps all rights: ask devcexx before reusing the design.
Similar boards
- 2 layers40 × 34 mm

- 2 layers53.9 × 23.2 mm

Analog
hoglet67/RGBtoHDMI
Bare-metal Raspberry Pi project that provides pixel-perfect sampling of Retro Computer RGB/YUV video and conversion to HDMI
37 parts1kGPL-3.0 - 2 layers52 × 51.8 mm

Esp32-homeassistant rf bridge
hackclub/OnBoard
💡 Join 1,000 teenagers and make your first PCB with a $100 grant!
37 parts915 - 2 layers87.8 × 59.8 mm

FreeDeck SMD 2020-02
FreeYourStream/freedeck-hardware
all the stuff you need to build your own FreeDeck
37 parts772 - 2 layers65 × 28 mm

BMS Cell Module
stuartpittaway/diyBMS
Do it yourself battery management system for Lithium ion battery packs/cells
37 parts676GPL-3.0 - 2 layers48 × 32 mm

FlatSat
Pwnsat/FlatSat
Flatsat v1.0 is a hardware based platform for aerospace cybersecurity research
37 parts575GPL-2.0 - 2 layers38.1 × 153.7 mm

- 2 layers47.8 × 27.4 mm

Vsf stm32h7b0
vsfteam/vsf
Versaloon Software Framework -- a tiny preemptive-capable event-driven incremental software framework for embedded systems
37 parts341Apache-2.0