keyboard stuff
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rework converter docs (#18314)

authored by

Joel Challis and committed by
GitHub
01d81b95 a00177d1

+365 -97
+243 -97
docs/feature_converters.md
··· 2 2 3 3 This 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. 4 4 5 + You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example: 6 + 7 + ```sh 8 + qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c 9 + ``` 10 + 11 + You can also configure this within your [keymap](#keymap) to accomplish the same thing. 12 + 13 + ::: tip 14 + 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. 15 + ::: 16 + 5 17 ## Supported Converters 18 + 19 + Each converter category is broken down by its declared `pin compatibility`. This ensures that only valid combinations are attempted. 6 20 7 21 The following converters are available at this time: 8 22 ··· 28 42 | `elite_c` | `helios` | 29 43 | `elite_c` | `liatris` | 30 44 45 + ## Configuration 31 46 32 - ## Overview 47 + Configuring a converter to use can be done by adding one of the following lines to your keymaps's configuration: 33 48 34 - 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: 49 + :::::tabs 35 50 36 - ```sh 37 - qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c 38 - ``` 51 + ==== keymap.json 39 52 40 - You can also add the same `CONVERT_TO=<target>` to your keymap's `rules.mk`, which will accomplish the same thing. 41 - 42 - ::: tip 43 - 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. 44 - ::: 45 - 46 - ### Conditional Configuration 47 - 48 - 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: 49 - 50 - ```c 51 - #ifdef CONVERT_TO_PROTON_C 52 - // Proton C code 53 - #else 54 - // Pro Micro code 55 - #endif 53 + ```json [keymap.json] 54 + { 55 + "version": 1, 56 + "keyboard": "keebio/bdn9/rev1", 57 + "keymap": "keebio_bdn9_rev1_layout_2025-05-20", 58 + "converter": "proton_c", // [!code focus] 59 + "layout": "LAYOUT", 60 + } 56 61 ``` 57 62 58 - ### Pin Compatibility 59 - 60 - 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: 61 - 62 - | Pin Compatibility | Notes | 63 - |-------------------|-----------------------------------| 64 - | `promicro` | Includes RX/TX LEDs | 65 - | `elite_c` | Includes bottom row pins, no LEDs | 66 - 67 - To declare the base for conversions, add this line to your keyboard's `rules.mk`: 63 + ==== rules.mk 68 64 69 65 ```makefile 70 - PIN_COMPATIBLE = elite_c 66 + CONVERT_TO = proton_c 71 67 ``` 72 68 73 - ## Pro Micro 69 + ::::: 74 70 75 - 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: 71 + ::: tip 72 + 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. 73 + ::: 76 74 77 - | Device | Target | 78 - |------------------------------------------------------------------------------------------|-------------------| 79 - | [Proton C](https://qmk.fm/proton-c/) | `proton_c` | 80 - | [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` | 81 - | [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `sparkfun_pm2040` | 82 - | [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` | 83 - | [Bit-C PRO](https://nullbits.co/bit-c-pro) | `bit_c_pro` | 84 - | [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | 85 - | [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` | 86 - | [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | 87 - | [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | 88 - | [Liatris](https://splitkb.com/products/liatris) | `liatris` | 89 - | [Imera](https://splitkb.com/products/imera) | `imera` | 90 - | [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` | 91 - | [Svlinky](https://github.com/sadekbaroudi/svlinky) | `svlinky` | 75 + ## Pro Micro Converters 92 76 93 - Converter summary: 77 + 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: 94 78 95 - | Target | Argument | `rules.mk` | Condition | 96 - |-------------------|---------------------------------|------------------------------|-------------------------------------| 97 - | `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` | 98 - | `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` | 99 - | `sparkfun_pm2040` | `-e CONVERT_TO=sparkfun_pm2040` | `CONVERT_TO=sparkfun_pm2040` | `#ifdef CONVERT_TO_SPARKFUN_PM2040` | 100 - | `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` | 101 - | `bit_c_pro` | `-e CONVERT_TO=bit_c_pro` | `CONVERT_TO=bit_c_pro` | `#ifdef CONVERT_TO_BIT_C_PRO` | 102 - | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | 103 - | `bonsai_c4` | `-e CONVERT_TO=bonsai_c4` | `CONVERT_TO=bonsai_c4` | `#ifdef CONVERT_TO_BONSAI_C4` | 104 - | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | 105 - | `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` | 106 - | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | 107 - | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | 108 - | `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` | 109 - | `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` | 110 - | `svlinky` | `-e CONVERT_TO=svlinky` | `CONVERT_TO=svlinky` | `#ifdef CONVERT_TO_SVLINKY` | 79 + | Device | Target | CLI Argument | `rules.mk` | Condition | 80 + |------------------------------------------------------------------------------------------|-------------------|---------------------------------|------------------------------|-------------------------------------| 81 + | [Proton C](https://qmk.fm/proton-c/) | `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` | 82 + | [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` | 83 + | [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` | 84 + | [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` | 85 + | [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` | 86 + | [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | 87 + | [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` | 88 + | [RP2040 Community Edition](#rp2040_ce) | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | 89 + | [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` | 90 + | [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | 91 + | [Liatris](https://splitkb.com/products/liatris) | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | 92 + | [Imera](https://splitkb.com/products/imera) | `imera` | `-e CONVERT_TO=imera` | `CONVERT_TO=imera` | `#ifdef CONVERT_TO_IMERA` | 93 + | [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` | 94 + | [Svlinky](https://github.com/sadekbaroudi/svlinky) | `svlinky` | `-e CONVERT_TO=svlinky` | `CONVERT_TO=svlinky` | `#ifdef CONVERT_TO_SVLINKY` | 111 95 112 96 ### Proton C {#proton_c} 113 97 ··· 119 103 120 104 The following defaults are based on what has been implemented for STM32 boards. 121 105 122 - | Feature | Notes | 123 - |----------------------------------------------|------------------------------------------------------------------------------------------------------------------| 124 - | [Audio](features/audio) | Enabled | 125 - | [RGB Lighting](features/rgblight) | Disabled | 106 + | Feature | Notes | 107 + |--------------------------------------------|----------------------------------------------------------------------------------------------------------------| 108 + | [Audio](features/audio) | Enabled | 109 + | [RGB Lighting](features/rgblight) | Disabled | 126 110 | [Backlight](features/backlight) | Forces [task driven PWM](features/backlight#software-pwm-driver) until ARM can provide automatic configuration | 127 - | USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | 128 - | [Split keyboards](features/split_keyboard) | Partial - heavily dependent on enabled features | 111 + | USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | 112 + | [Split keyboards](features/split_keyboard) | Partial - heavily dependent on enabled features | 129 113 130 114 ### Adafruit KB2040 {#kb2040} 131 115 132 116 The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040) boards. 133 117 134 - | Feature | Notes | 135 - |----------------------------------------------|------------------------------------------------------------------------------------------------------------------| 136 - | [RGB Lighting](features/rgblight) | Enabled via `PIO` vendor driver | 118 + | Feature | Notes | 119 + |--------------------------------------------|----------------------------------------------------------------------------------------------------------------| 120 + | [RGB Lighting](features/rgblight) | Enabled via `PIO` vendor driver | 137 121 | [Backlight](features/backlight) | Forces [task driven PWM](features/backlight#software-pwm-driver) until ARM can provide automatic configuration | 138 - | USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | 139 - | [Split keyboards](features/split_keyboard) | Partial via `PIO` vendor driver - heavily dependent on enabled features | 122 + | USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | 123 + | [Split keyboards](features/split_keyboard) | Partial via `PIO` vendor driver - heavily dependent on enabled features | 140 124 141 - ### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#sparkfun_pm2040 } 125 + ### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#sparkfun_pm2040} 142 126 143 127 Feature set is identical to [Adafruit KB2040](#kb2040). 144 128 ··· 177 161 178 162 Feature 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. 179 163 180 - ## Elite-C 164 + ## Elite-C Converters 181 165 182 - 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: 166 + 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: 183 167 184 - | Device | Target | 185 - |----------------------------------------------------------------------------------|-------------------| 186 - | [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | 187 - | [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | 188 - | [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | 189 - | [Liatris](https://splitkb.com/products/liatris) | `liatris` | 190 - 191 - Converter summary: 192 - 193 - | Target | Argument | `rules.mk` | Condition | 194 - |-------------------|---------------------------------|------------------------------|-------------------------------------| 195 - | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | 196 - | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | 197 - | `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` | 198 - | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | 199 - | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | 168 + | Device | Target | CLI Argument | `rules.mk` | Condition | 169 + |----------------------------------------------------------------------------------|-------------|---------------------------|------------------------|-------------------------------| 170 + | [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | 171 + | [RP2040 Community Edition](#rp2040_ce_elite) | `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | 172 + | [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` | 173 + | [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | 174 + | [Liatris](https://splitkb.com/products/liatris) | `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | 200 175 201 - ### STeMCell {#stemcell}_elite 176 + ### STeMCell {#stemcell_elite} 202 177 203 178 Identical to [Pro Micro - STeMCell](#stemcell) with support for the additional bottom row of pins. 204 179 205 180 ### RP2040 Community Edition {#rp2040_ce_elite} 206 181 207 182 Identical to [Pro Micro - RP2040 Community Edition](#rp2040_ce) with support for the additional bottom row of pins. 183 + 184 + ## Advanced Topics 185 + 186 + ### Keyboard Configuration 187 + 188 + To configure a keyboard to allow the converter feature, add the following line to your keyboard's `.json` configuration: 189 + 190 + ```json [keyboard.json] 191 + { 192 + "maintainer": "QMK", 193 + "development_board": "promicro", // [!code focus] 194 + "diode_direction": "COL2ROW", 195 + } 196 + ``` 197 + 198 + See the [pin compatibility](#pin_compatible) for more information. 199 + 200 + #### Additional Requirements {#keyboard-req} 201 + 202 + Keyboards must use the platform agnostic abstractions provided by QMK. This includes: 203 + 204 + * Use of [GPIO Controls](drivers/gpio). 205 + 206 + ### Additional Keymap Configuration {#keymap-add} 207 + 208 + While effort has been made to make converters as compatible as possible, sometimes additional platform specific configuration is required. 209 + 210 + For example, enabling hardware peripherals by adding a keymap level `mcuconf.h` with something like the following: 211 + ```c 212 + #pragma once 213 + 214 + #include_next <mcuconf.h> 215 + 216 + #undef RP_SIO_USE_UART0 217 + #define RP_SIO_USE_UART0 TRUE 218 + ``` 219 + 220 + You can find details on how to configure drivers on their respective pages. 221 + 222 + Alternatively, you may have to disable incompatible features. For example: 223 + 224 + :::::tabs 225 + 226 + ==== keymap.json 227 + 228 + ```json [keymap.json] 229 + { 230 + "version": 1, 231 + "keyboard": "keebio/bdn9/rev1", 232 + "keymap": "keebio_bdn9_rev1_layout_2025-05-20", 233 + "converter": "proton_c", 234 + "config": { // [!code focus] 235 + "features": { // [!code focus] 236 + "audio": false // [!code focus] 237 + } 238 + } 239 + "layout": "LAYOUT", 240 + } 241 + ``` 242 + 243 + ==== rules.mk 244 + 245 + ```makefile 246 + AUDIO_ENABLE = no 247 + ``` 248 + 249 + ::::: 250 + 251 + ### Conditional Configuration 252 + 253 + 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: 254 + 255 + ```c 256 + #ifdef CONVERT_TO_PROTON_C 257 + // Proton C code 258 + #else 259 + // Pro Micro code 260 + #endif 261 + ``` 262 + 263 + ### Pin Compatibility {#pin_compatible} 264 + 265 + To ensure compatibility, provide validation, and power future workflows, a keyboard should declare its `pin compatibility`. This ensures that only valid combinations are attempted. 266 + 267 + ::: tip Note 268 + This will already be configured for you if are using the `promicro` development board preset. 269 + ::: 270 + 271 + To declare the base interface for conversions, add the following line to your keyboard's configuration: 272 + 273 + ```json [keyboard.json] 274 + { 275 + "maintainer": "QMK", 276 + "development_board": "elite_c", // [!code focus] 277 + "pin_compatible": "elite_c", // [!code focus] 278 + "diode_direction": "COL2ROW", 279 + } 280 + ``` 281 + 282 + The above example, configures a keyboard for a default of `elite_c` while allowing any of the `elite_c` converter targets. 283 + 284 + The framework then allows mapping of pins from `<PIN_COMPATIBLE>` to converter `<target>`. 285 + 286 + ::: warning 287 + Mapped pins should adhere strictly to the defined interface, any extras present on the hardware should be ignored. 288 + ::: 289 + 290 + #### Available Pin Compatibility 291 + 292 + :::::tabs 293 + 294 + ==== promicro 295 + 296 + ![promicro](/pin_compatible_promicro.svg) 297 + 298 + <!-- ```svgbob 299 + pins 300 + .-------------. LEDs 301 + | | _|_ _|_ 302 + D3 -+-O | \ /B0 \ /D5 303 + D2 -+-O | -+- -+- 304 + | | | | 305 + | | 306 + D1 -+-O O-+- F4 307 + D0 -+-O O-+- F5 308 + D4 -+-O O-+- F6 309 + C6 -+-O O-+- F7 310 + D7 -+-O O-+- B1 311 + E6 -+-O O-+- B3 312 + B4 -+-O O-+- B2 313 + B5 -+-O O-+- B6 314 + | | 315 + '---+-+-+-+-+---' 316 + ``` --> 317 + 318 + ::: info Notes: 319 + Includes LEDs - these may be mapped to unused/unavailable pins when not present. 320 + ::: 321 + 322 + ==== elite_c 323 + 324 + ![elite_c](/pin_compatible_elite_c.svg) 325 + 326 + <!-- ```svgbob 327 + pins 328 + .-------------. 329 + | | 330 + D3 -+-O | 331 + D2 -+-O | 332 + | | 333 + | | 334 + D1 -+-O O-+- F4 335 + D0 -+-O O-+- F5 336 + D4 -+-O O-+- F6 337 + C6 -+-O O-+- F7 338 + D7 -+-O O-+- B1 339 + E6 -+-O O-+- B3 340 + B4 -+-O O-+- B2 341 + B5 -+-O O O O O O O-+- B6 342 + | | | | | | | 343 + '---+-+-+-+-+---' 344 + + + + + + 345 + B D C F F 346 + 7 5 7 1 0 347 + ``` --> 348 + 349 + ::: info Notes: 350 + Includes bottom row pins, no LEDs. 351 + ::: 352 + 353 + :::::
+61
docs/public/pin_compatible_elite_c.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="208" height="352" class="svgbob"><style>.svgbob line, .svgbob path, .svgbob circle, .svgbob rect, .svgbob polygon { 2 + stroke: black; 3 + stroke-width: 2; 4 + stroke-opacity: 1; 5 + fill-opacity: 1; 6 + stroke-linecap: round; 7 + stroke-linejoin: miter; 8 + } 9 + .svgbob text { 10 + white-space: pre; 11 + fill: black; 12 + font-family: Iosevka Fixed, monospace; 13 + font-size: 14px; 14 + } 15 + .svgbob rect.backdrop { 16 + stroke: none; 17 + fill: white; 18 + } 19 + .svgbob .broken { 20 + stroke-dasharray: 8; 21 + } 22 + .svgbob .filled { 23 + fill: black; 24 + } 25 + .svgbob .bg_filled { 26 + fill: white; 27 + stroke-width: 1; 28 + } 29 + .svgbob .nofill { 30 + fill: white; 31 + } 32 + .svgbob .end_marked_arrow { 33 + marker-end: url(#arrow); 34 + } 35 + .svgbob .start_marked_arrow { 36 + marker-start: url(#arrow); 37 + } 38 + .svgbob .end_marked_diamond { 39 + marker-end: url(#diamond); 40 + } 41 + .svgbob .start_marked_diamond { 42 + marker-start: url(#diamond); 43 + } 44 + .svgbob .end_marked_circle { 45 + marker-end: url(#circle); 46 + } 47 + .svgbob .start_marked_circle { 48 + marker-start: url(#circle); 49 + } 50 + .svgbob .end_marked_open_circle { 51 + marker-end: url(#open_circle); 52 + } 53 + .svgbob .start_marked_open_circle { 54 + marker-start: url(#open_circle); 55 + } 56 + .svgbob .end_marked_big_open_circle { 57 + marker-end: url(#big_open_circle); 58 + } 59 + .svgbob .start_marked_big_open_circle { 60 + marker-start: url(#big_open_circle); 61 + }<!--separator--></style><defs><marker id="arrow" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><polygon points="0,0 0,4 4,2 0,0"></polygon></marker><marker id="diamond" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><polygon points="0,2 2,0 4,2 2,4 0,2"></polygon></marker><marker id="circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="2" class="filled"></circle></marker><marker id="open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="2" class="bg_filled"></circle></marker><marker id="big_open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="3" class="bg_filled"></circle></marker></defs><rect class="backdrop" x="0" y="0" width="208" height="352"></rect><text x="82" y="28" >pins</text><line x1="24" y1="72" x2="52" y2="72" class="solid end_marked_big_open_circle"></line><line x1="24" y1="88" x2="52" y2="88" class="solid end_marked_big_open_circle"></line><line x1="24" y1="136" x2="52" y2="136" class="solid end_marked_big_open_circle"></line><line x1="160" y1="136" x2="148" y2="136" class="solid end_marked_big_open_circle"></line><line x1="160" y1="136" x2="176" y2="136" class="solid"></line><line x1="24" y1="152" x2="52" y2="152" class="solid end_marked_big_open_circle"></line><line x1="160" y1="152" x2="148" y2="152" class="solid end_marked_big_open_circle"></line><line x1="160" y1="152" x2="176" y2="152" class="solid"></line><line x1="24" y1="168" x2="52" y2="168" class="solid end_marked_big_open_circle"></line><line x1="160" y1="168" x2="148" y2="168" class="solid end_marked_big_open_circle"></line><line x1="160" y1="168" x2="176" y2="168" class="solid"></line><line x1="24" y1="184" x2="52" y2="184" class="solid end_marked_big_open_circle"></line><line x1="160" y1="184" x2="148" y2="184" class="solid end_marked_big_open_circle"></line><line x1="160" y1="184" x2="176" y2="184" class="solid"></line><line x1="24" y1="200" x2="52" y2="200" class="solid end_marked_big_open_circle"></line><line x1="160" y1="200" x2="148" y2="200" class="solid end_marked_big_open_circle"></line><line x1="160" y1="200" x2="176" y2="200" class="solid"></line><line x1="24" y1="216" x2="52" y2="216" class="solid end_marked_big_open_circle"></line><line x1="160" y1="216" x2="148" y2="216" class="solid end_marked_big_open_circle"></line><line x1="160" y1="216" x2="176" y2="216" class="solid"></line><line x1="24" y1="232" x2="52" y2="232" class="solid end_marked_big_open_circle"></line><line x1="160" y1="232" x2="148" y2="232" class="solid end_marked_big_open_circle"></line><line x1="160" y1="232" x2="176" y2="232" class="solid"></line><line x1="24" y1="248" x2="52" y2="248" class="solid end_marked_big_open_circle"></line><line x1="68" y1="252" x2="68" y2="248" class="solid end_marked_big_open_circle"></line><line x1="84" y1="252" x2="84" y2="248" class="solid end_marked_big_open_circle"></line><line x1="100" y1="252" x2="100" y2="248" class="solid end_marked_big_open_circle"></line><line x1="116" y1="252" x2="116" y2="248" class="solid end_marked_big_open_circle"></line><line x1="132" y1="252" x2="132" y2="248" class="solid end_marked_big_open_circle"></line><line x1="160" y1="248" x2="148" y2="248" class="solid end_marked_big_open_circle"></line><line x1="160" y1="248" x2="176" y2="248" class="solid"></line><line x1="68" y1="256" x2="68" y2="296" class="solid"></line><line x1="84" y1="256" x2="84" y2="296" class="solid"></line><line x1="100" y1="256" x2="100" y2="296" class="solid"></line><line x1="116" y1="256" x2="116" y2="296" class="solid"></line><line x1="132" y1="256" x2="132" y2="296" class="solid"></line><text x="66" y="316" >B</text><text x="82" y="316" >D</text><text x="98" y="316" >C</text><text x="114" y="316" >F</text><text x="130" y="316" >F</text><text x="66" y="332" >7</text><text x="82" y="332" >5</text><text x="98" y="332" >7</text><text x="114" y="332" >1</text><text x="130" y="332" >0</text><text x="2" y="76" >D3</text><text x="2" y="92" >D2</text><text x="2" y="140" >D1</text><text x="2" y="156" >D0</text><text x="2" y="172" >D4</text><text x="2" y="188" >C6</text><text x="2" y="204" >D7</text><text x="2" y="220" >E6</text><text x="2" y="236" >B4</text><text x="2" y="252" >B5</text><text x="186" y="140" >F4</text><text x="186" y="156" >F5</text><text x="186" y="172" >F6</text><text x="186" y="188" >F7</text><text x="186" y="204" >B1</text><text x="186" y="220" >B3</text><text x="186" y="236" >B2</text><text x="186" y="252" >B6</text><g><path d="M 44,40 A 8,8 0,0,0 36,48" class="nofill"></path><line x1="44" y1="40" x2="156" y2="40" class="solid"></line><path d="M 156,40 A 8,8 0,0,1 164,48" class="nofill"></path><line x1="36" y1="48" x2="36" y2="276" class="solid"></line><line x1="164" y1="48" x2="164" y2="276" class="solid"></line><path d="M 36,276 A 4,4 0,0,0 40,280" class="nofill"></path><line x1="40" y1="280" x2="160" y2="280" class="solid"></line><path d="M 164,276 A 4,4 0,0,1 160,280" class="nofill"></path></g></svg>
+61
docs/public/pin_compatible_promicro.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="344" height="288" class="svgbob"><style>.svgbob line, .svgbob path, .svgbob circle, .svgbob rect, .svgbob polygon { 2 + stroke: black; 3 + stroke-width: 2; 4 + stroke-opacity: 1; 5 + fill-opacity: 1; 6 + stroke-linecap: round; 7 + stroke-linejoin: miter; 8 + } 9 + .svgbob text { 10 + white-space: pre; 11 + fill: black; 12 + font-family: Iosevka Fixed, monospace; 13 + font-size: 14px; 14 + } 15 + .svgbob rect.backdrop { 16 + stroke: none; 17 + fill: white; 18 + } 19 + .svgbob .broken { 20 + stroke-dasharray: 8; 21 + } 22 + .svgbob .filled { 23 + fill: black; 24 + } 25 + .svgbob .bg_filled { 26 + fill: white; 27 + stroke-width: 1; 28 + } 29 + .svgbob .nofill { 30 + fill: white; 31 + } 32 + .svgbob .end_marked_arrow { 33 + marker-end: url(#arrow); 34 + } 35 + .svgbob .start_marked_arrow { 36 + marker-start: url(#arrow); 37 + } 38 + .svgbob .end_marked_diamond { 39 + marker-end: url(#diamond); 40 + } 41 + .svgbob .start_marked_diamond { 42 + marker-start: url(#diamond); 43 + } 44 + .svgbob .end_marked_circle { 45 + marker-end: url(#circle); 46 + } 47 + .svgbob .start_marked_circle { 48 + marker-start: url(#circle); 49 + } 50 + .svgbob .end_marked_open_circle { 51 + marker-end: url(#open_circle); 52 + } 53 + .svgbob .start_marked_open_circle { 54 + marker-start: url(#open_circle); 55 + } 56 + .svgbob .end_marked_big_open_circle { 57 + marker-end: url(#big_open_circle); 58 + } 59 + .svgbob .start_marked_big_open_circle { 60 + marker-start: url(#big_open_circle); 61 + }<!--separator--></style><defs><marker id="arrow" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><polygon points="0,0 0,4 4,2 0,0"></polygon></marker><marker id="diamond" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><polygon points="0,2 2,0 4,2 2,4 0,2"></polygon></marker><marker id="circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="2" class="filled"></circle></marker><marker id="open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="2" class="bg_filled"></circle></marker><marker id="big_open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><circle cx="4" cy="4" r="3" class="bg_filled"></circle></marker></defs><rect class="backdrop" x="0" y="0" width="344" height="288"></rect><text x="82" y="12" >pins</text><line x1="24" y1="56" x2="52" y2="56" class="solid end_marked_big_open_circle"></line><line x1="24" y1="72" x2="52" y2="72" class="solid end_marked_big_open_circle"></line><line x1="24" y1="120" x2="52" y2="120" class="solid end_marked_big_open_circle"></line><line x1="160" y1="120" x2="148" y2="120" class="solid end_marked_big_open_circle"></line><line x1="160" y1="120" x2="176" y2="120" class="solid"></line><line x1="24" y1="136" x2="52" y2="136" class="solid end_marked_big_open_circle"></line><line x1="160" y1="136" x2="148" y2="136" class="solid end_marked_big_open_circle"></line><line x1="160" y1="136" x2="176" y2="136" class="solid"></line><line x1="24" y1="152" x2="52" y2="152" class="solid end_marked_big_open_circle"></line><line x1="160" y1="152" x2="148" y2="152" class="solid end_marked_big_open_circle"></line><line x1="160" y1="152" x2="176" y2="152" class="solid"></line><line x1="24" y1="168" x2="52" y2="168" class="solid end_marked_big_open_circle"></line><line x1="160" y1="168" x2="148" y2="168" class="solid end_marked_big_open_circle"></line><line x1="160" y1="168" x2="176" y2="168" class="solid"></line><line x1="24" y1="184" x2="52" y2="184" class="solid end_marked_big_open_circle"></line><line x1="160" y1="184" x2="148" y2="184" class="solid end_marked_big_open_circle"></line><line x1="160" y1="184" x2="176" y2="184" class="solid"></line><line x1="24" y1="200" x2="52" y2="200" class="solid end_marked_big_open_circle"></line><line x1="160" y1="200" x2="148" y2="200" class="solid end_marked_big_open_circle"></line><line x1="160" y1="200" x2="176" y2="200" class="solid"></line><line x1="24" y1="216" x2="52" y2="216" class="solid end_marked_big_open_circle"></line><line x1="160" y1="216" x2="148" y2="216" class="solid end_marked_big_open_circle"></line><line x1="160" y1="216" x2="176" y2="216" class="solid"></line><line x1="24" y1="232" x2="52" y2="232" class="solid end_marked_big_open_circle"></line><line x1="160" y1="232" x2="148" y2="232" class="solid end_marked_big_open_circle"></line><line x1="160" y1="232" x2="176" y2="232" class="solid"></line><text x="250" y="28" >LEDs</text><text x="242" y="60" >B0</text><text x="322" y="60" >D5</text><text x="2" y="60" >D3</text><text x="2" y="76" >D2</text><text x="2" y="124" >D1</text><text x="2" y="140" >D0</text><text x="2" y="156" >D4</text><text x="2" y="172" >C6</text><text x="2" y="188" >D7</text><text x="2" y="204" >E6</text><text x="2" y="220" >B4</text><text x="2" y="236" >B5</text><text x="186" y="124" >F4</text><text x="186" y="140" >F5</text><text x="186" y="156" >F6</text><text x="186" y="172" >F7</text><text x="186" y="188" >B1</text><text x="186" y="204" >B3</text><text x="186" y="220" >B2</text><text x="186" y="236" >B6</text><g><path d="M 44,24 A 8,8 0,0,0 36,32" class="nofill"></path><line x1="44" y1="24" x2="156" y2="24" class="solid"></line><path d="M 156,24 A 8,8 0,0,1 164,32" class="nofill"></path><line x1="36" y1="32" x2="36" y2="260" class="solid"></line><line x1="164" y1="32" x2="164" y2="260" class="solid"></line><path d="M 36,260 A 4,4 0,0,0 40,264" class="nofill"></path><line x1="40" y1="264" x2="160" y2="264" class="solid"></line><path d="M 164,260 A 4,4 0,0,1 160,264" class="nofill"></path></g><g><line x1="216" y1="48" x2="240" y2="48" class="solid"></line><line x1="228" y1="32" x2="228" y2="48" class="solid"></line><line x1="216" y1="48" x2="228" y2="72" class="solid"></line><line x1="240" y1="48" x2="228" y2="72" class="solid"></line><line x1="216" y1="72" x2="240" y2="72" class="solid"></line><line x1="228" y1="72" x2="228" y2="96" class="solid"></line></g><g><line x1="296" y1="48" x2="320" y2="48" class="solid"></line><line x1="308" y1="32" x2="308" y2="48" class="solid"></line><line x1="296" y1="48" x2="308" y2="72" class="solid"></line><line x1="320" y1="48" x2="308" y2="72" class="solid"></line><line x1="296" y1="72" x2="320" y2="72" class="solid"></line><line x1="308" y1="72" x2="308" y2="96" class="solid"></line></g></svg>