···2233This page documents the automated process for converting keyboards to use drop-in replacement controllers. This process is designed to be easy to use and can be completed in a few simple steps.
4455+You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
66+77+```sh
88+qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
99+```
1010+1111+You can also configure this within your [keymap](#keymap) to accomplish the same thing.
1212+1313+::: tip
1414+If you get build errors, you will need to convert the keyboard's code to be [compatible](#keyboard-req) with the converter feature, or provide additional [keymap](#keymap-add) configuration.
1515+:::
1616+517## Supported Converters
1818+1919+Each converter category is broken down by its declared `pin compatibility`. This ensures that only valid combinations are attempted.
620721The following converters are available at this time:
822···2842| `elite_c` | `helios` |
2943| `elite_c` | `liatris` |
30444545+## Configuration
31463232-## Overview
4747+Configuring a converter to use can be done by adding one of the following lines to your keymaps's configuration:
33483434-Each converter category is broken down by its declared `pin compatibility`. This ensures that only valid combinations are attempted. You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
4949+:::::tabs
35503636-```sh
3737-qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
3838-```
5151+==== keymap.json
39524040-You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing.
4141-4242-::: tip
4343-If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](drivers/gpio) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
4444-:::
4545-4646-### Conditional Configuration
4747-4848-Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag that you can use in your code with `#ifdef`s, For example:
4949-5050-```c
5151-#ifdef CONVERT_TO_PROTON_C
5252- // Proton C code
5353-#else
5454- // Pro Micro code
5555-#endif
5353+```json [keymap.json]
5454+{
5555+ "version": 1,
5656+ "keyboard": "keebio/bdn9/rev1",
5757+ "keymap": "keebio_bdn9_rev1_layout_2025-05-20",
5858+ "converter": "proton_c", // [!code focus]
5959+ "layout": "LAYOUT",
6060+}
5661```
57625858-### Pin Compatibility
5959-6060-To ensure compatibility, provide validation, and enable future workflows, a keyboard should declare its `pin compatibility`. For legacy reasons, this is currently assumed to be `promicro`. The following pin compatibility interfaces are currently defined:
6161-6262-| Pin Compatibility | Notes |
6363-|-------------------|-----------------------------------|
6464-| `promicro` | Includes RX/TX LEDs |
6565-| `elite_c` | Includes bottom row pins, no LEDs |
6666-6767-To declare the base for conversions, add this line to your keyboard's `rules.mk`:
6363+==== rules.mk
68646965```makefile
7070-PIN_COMPATIBLE = elite_c
6666+CONVERT_TO = proton_c
7167```
72687373-## Pro Micro
6969+:::::
74707575-If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are:
7171+::: tip
7272+If you get build errors, you will need to convert the keyboard's code to be [compatible](#keyboard-req) with the converter feature, or provide additional [keymap](#keymap-add) configuration.
7373+:::
76747777-| Device | Target |
7878-|------------------------------------------------------------------------------------------|-------------------|
7979-| [Proton C](https://qmk.fm/proton-c/) | `proton_c` |
8080-| [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` |
8181-| [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `sparkfun_pm2040` |
8282-| [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` |
8383-| [Bit-C PRO](https://nullbits.co/bit-c-pro) | `bit_c_pro` |
8484-| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` |
8585-| [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` |
8686-| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` |
8787-| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` |
8888-| [Liatris](https://splitkb.com/products/liatris) | `liatris` |
8989-| [Imera](https://splitkb.com/products/imera) | `imera` |
9090-| [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` |
9191-| [Svlinky](https://github.com/sadekbaroudi/svlinky) | `svlinky` |
7575+## Pro Micro Converters
92769393-Converter summary:
7777+If a board currently supported by QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are:
94789595-| Target | Argument | `rules.mk` | Condition |
9696-|-------------------|---------------------------------|------------------------------|-------------------------------------|
9797-| `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` |
9898-| `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` |
9999-| `sparkfun_pm2040` | `-e CONVERT_TO=sparkfun_pm2040` | `CONVERT_TO=sparkfun_pm2040` | `#ifdef CONVERT_TO_SPARKFUN_PM2040` |
100100-| `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` |
101101-| `bit_c_pro` | `-e CONVERT_TO=bit_c_pro` | `CONVERT_TO=bit_c_pro` | `#ifdef CONVERT_TO_BIT_C_PRO` |
102102-| `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` |
103103-| `bonsai_c4` | `-e CONVERT_TO=bonsai_c4` | `CONVERT_TO=bonsai_c4` | `#ifdef CONVERT_TO_BONSAI_C4` |
104104-| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
105105-| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
106106-| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
107107-| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
108108-| `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` |
109109-| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
110110-| `svlinky` | `-e CONVERT_TO=svlinky` | `CONVERT_TO=svlinky` | `#ifdef CONVERT_TO_SVLINKY` |
7979+| Device | Target | CLI Argument | `rules.mk` | Condition |
8080+|------------------------------------------------------------------------------------------|-------------------|---------------------------------|------------------------------|-------------------------------------|
8181+| [Proton C](https://qmk.fm/proton-c/) | `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` |
8282+| [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` |
8383+| [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `sparkfun_pm2040` | `-e CONVERT_TO=sparkfun_pm2040` | `CONVERT_TO=sparkfun_pm2040` | `#ifdef CONVERT_TO_SPARKFUN_PM2040` |
8484+| [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` |
8585+| [Bit-C PRO](https://nullbits.co/bit-c-pro) | `bit_c_pro` | `-e CONVERT_TO=bit_c_pro` | `CONVERT_TO=bit_c_pro` | `#ifdef CONVERT_TO_BIT_C_PRO` |
8686+| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` |
8787+| [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` | `-e CONVERT_TO=bonsai_c4` | `CONVERT_TO=bonsai_c4` | `#ifdef CONVERT_TO_BONSAI_C4` |
8888+| [RP2040 Community Edition](#rp2040_ce) | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
8989+| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
9090+| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
9191+| [Liatris](https://splitkb.com/products/liatris) | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
9292+| [Imera](https://splitkb.com/products/imera) | `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` |
9393+| [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
9494+| [Svlinky](https://github.com/sadekbaroudi/svlinky) | `svlinky` | `-e CONVERT_TO=svlinky` | `CONVERT_TO=svlinky` | `#ifdef CONVERT_TO_SVLINKY` |
1119511296### Proton C {#proton_c}
11397···119103120104The following defaults are based on what has been implemented for STM32 boards.
121105122122-| Feature | Notes |
123123-|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
124124-| [Audio](features/audio) | Enabled |
125125-| [RGB Lighting](features/rgblight) | Disabled |
106106+| Feature | Notes |
107107+|--------------------------------------------|----------------------------------------------------------------------------------------------------------------|
108108+| [Audio](features/audio) | Enabled |
109109+| [RGB Lighting](features/rgblight) | Disabled |
126110| [Backlight](features/backlight) | Forces [task driven PWM](features/backlight#software-pwm-driver) until ARM can provide automatic configuration |
127127-| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
128128-| [Split keyboards](features/split_keyboard) | Partial - heavily dependent on enabled features |
111111+| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
112112+| [Split keyboards](features/split_keyboard) | Partial - heavily dependent on enabled features |
129113130114### Adafruit KB2040 {#kb2040}
131115132116The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040) boards.
133117134134-| Feature | Notes |
135135-|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
136136-| [RGB Lighting](features/rgblight) | Enabled via `PIO` vendor driver |
118118+| Feature | Notes |
119119+|--------------------------------------------|----------------------------------------------------------------------------------------------------------------|
120120+| [RGB Lighting](features/rgblight) | Enabled via `PIO` vendor driver |
137121| [Backlight](features/backlight) | Forces [task driven PWM](features/backlight#software-pwm-driver) until ARM can provide automatic configuration |
138138-| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
139139-| [Split keyboards](features/split_keyboard) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
122122+| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
123123+| [Split keyboards](features/split_keyboard) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
140124141141-### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#sparkfun_pm2040 }
125125+### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#sparkfun_pm2040}
142126143127Feature set is identical to [Adafruit KB2040](#kb2040).
144128···177161178162Feature set is a pro micro equivalent of the [RP2040 Community Edition](#rp2040_ce), except that two of the analog GPIO have been replaced with digital only GPIO. These two were moved to the FPC connector to support the [VIK specification](https://github.com/sadekbaroudi/vik). This means that if you are expecting analog support on all 4 pins as provided on a RP2040 Community Edition pinout, you will not have that. Please see the [Svlinky github page](https://github.com/sadekbaroudi/svlinky) for more details.
179163180180-## Elite-C
164164+## Elite-C Converters
181165182182-If a board currently supported in QMK uses an [Elite-C](https://keeb.io/products/elite-c-low-profile-version-usb-c-pro-micro-replacement-atmega32u4), the supported alternative controllers are:
166166+If a board currently supported by QMK uses an [Elite-C](https://keeb.io/products/elite-c-low-profile-version-usb-c-pro-micro-replacement-atmega32u4), the supported alternative controllers are:
183167184184-| Device | Target |
185185-|----------------------------------------------------------------------------------|-------------------|
186186-| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` |
187187-| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` |
188188-| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` |
189189-| [Liatris](https://splitkb.com/products/liatris) | `liatris` |
190190-191191-Converter summary:
192192-193193-| Target | Argument | `rules.mk` | Condition |
194194-|-------------------|---------------------------------|------------------------------|-------------------------------------|
195195-| `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` |
196196-| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
197197-| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
198198-| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
199199-| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
168168+| Device | Target | CLI Argument | `rules.mk` | Condition |
169169+|----------------------------------------------------------------------------------|-------------|---------------------------|------------------------|-------------------------------|
170170+| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` |
171171+| [RP2040 Community Edition](#rp2040_ce_elite) | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` |
172172+| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` |
173173+| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
174174+| [Liatris](https://splitkb.com/products/liatris) | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` |
200175201201-### STeMCell {#stemcell}_elite
176176+### STeMCell {#stemcell_elite}
202177203178Identical to [Pro Micro - STeMCell](#stemcell) with support for the additional bottom row of pins.
204179205180### RP2040 Community Edition {#rp2040_ce_elite}
206181207182Identical to [Pro Micro - RP2040 Community Edition](#rp2040_ce) with support for the additional bottom row of pins.
183183+184184+## Advanced Topics
185185+186186+### Keyboard Configuration
187187+188188+To configure a keyboard to allow the converter feature, add the following line to your keyboard's `.json` configuration:
189189+190190+```json [keyboard.json]
191191+{
192192+ "maintainer": "QMK",
193193+ "development_board": "promicro", // [!code focus]
194194+ "diode_direction": "COL2ROW",
195195+}
196196+```
197197+198198+See the [pin compatibility](#pin_compatible) for more information.
199199+200200+#### Additional Requirements {#keyboard-req}
201201+202202+Keyboards must use the platform agnostic abstractions provided by QMK. This includes:
203203+204204+* Use of [GPIO Controls](drivers/gpio).
205205+206206+### Additional Keymap Configuration {#keymap-add}
207207+208208+While effort has been made to make converters as compatible as possible, sometimes additional platform specific configuration is required.
209209+210210+For example, enabling hardware peripherals by adding a keymap level `mcuconf.h` with something like the following:
211211+```c
212212+#pragma once
213213+214214+#include_next <mcuconf.h>
215215+216216+#undef RP_SIO_USE_UART0
217217+#define RP_SIO_USE_UART0 TRUE
218218+```
219219+220220+You can find details on how to configure drivers on their respective pages.
221221+222222+Alternatively, you may have to disable incompatible features. For example:
223223+224224+:::::tabs
225225+226226+==== keymap.json
227227+228228+```json [keymap.json]
229229+{
230230+ "version": 1,
231231+ "keyboard": "keebio/bdn9/rev1",
232232+ "keymap": "keebio_bdn9_rev1_layout_2025-05-20",
233233+ "converter": "proton_c",
234234+ "config": { // [!code focus]
235235+ "features": { // [!code focus]
236236+ "audio": false // [!code focus]
237237+ }
238238+ }
239239+ "layout": "LAYOUT",
240240+}
241241+```
242242+243243+==== rules.mk
244244+245245+```makefile
246246+AUDIO_ENABLE = no
247247+```
248248+249249+:::::
250250+251251+### Conditional Configuration
252252+253253+Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag that you can use in your code with `#ifdef`s, For example:
254254+255255+```c
256256+#ifdef CONVERT_TO_PROTON_C
257257+ // Proton C code
258258+#else
259259+ // Pro Micro code
260260+#endif
261261+```
262262+263263+### Pin Compatibility {#pin_compatible}
264264+265265+To ensure compatibility, provide validation, and power future workflows, a keyboard should declare its `pin compatibility`. This ensures that only valid combinations are attempted.
266266+267267+::: tip Note
268268+This will already be configured for you if are using the `promicro` development board preset.
269269+:::
270270+271271+To declare the base interface for conversions, add the following line to your keyboard's configuration:
272272+273273+```json [keyboard.json]
274274+{
275275+ "maintainer": "QMK",
276276+ "development_board": "elite_c", // [!code focus]
277277+ "pin_compatible": "elite_c", // [!code focus]
278278+ "diode_direction": "COL2ROW",
279279+}
280280+```
281281+282282+The above example, configures a keyboard for a default of `elite_c` while allowing any of the `elite_c` converter targets.
283283+284284+The framework then allows mapping of pins from `<PIN_COMPATIBLE>` to converter `<target>`.
285285+286286+::: warning
287287+Mapped pins should adhere strictly to the defined interface, any extras present on the hardware should be ignored.
288288+:::
289289+290290+#### Available Pin Compatibility
291291+292292+:::::tabs
293293+294294+==== promicro
295295+296296+
297297+298298+<!-- ```svgbob
299299+ pins
300300+ .-------------. LEDs
301301+ | | _|_ _|_
302302+D3 -+-O | \ /B0 \ /D5
303303+D2 -+-O | -+- -+-
304304+ | | | |
305305+ | |
306306+D1 -+-O O-+- F4
307307+D0 -+-O O-+- F5
308308+D4 -+-O O-+- F6
309309+C6 -+-O O-+- F7
310310+D7 -+-O O-+- B1
311311+E6 -+-O O-+- B3
312312+B4 -+-O O-+- B2
313313+B5 -+-O O-+- B6
314314+ | |
315315+ '---+-+-+-+-+---'
316316+``` -->
317317+318318+::: info Notes:
319319+Includes LEDs - these may be mapped to unused/unavailable pins when not present.
320320+:::
321321+322322+==== elite_c
323323+324324+
325325+326326+<!-- ```svgbob
327327+ pins
328328+ .-------------.
329329+ | |
330330+D3 -+-O |
331331+D2 -+-O |
332332+ | |
333333+ | |
334334+D1 -+-O O-+- F4
335335+D0 -+-O O-+- F5
336336+D4 -+-O O-+- F6
337337+C6 -+-O O-+- F7
338338+D7 -+-O O-+- B1
339339+E6 -+-O O-+- B3
340340+B4 -+-O O-+- B2
341341+B5 -+-O O O O O O O-+- B6
342342+ | | | | | | |
343343+ '---+-+-+-+-+---'
344344+ + + + + +
345345+ B D C F F
346346+ 7 5 7 1 0
347347+``` -->
348348+349349+::: info Notes:
350350+Includes bottom row pins, no LEDs.
351351+:::
352352+353353+:::::