<spanclass="line"><span>+-------+ +-------+</span></span></code></pre></div><p>One GPIO pin is needed for the bitbang driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the <code>SOFT_SERIAL_PIN</code> (SSP) in the configuration. A TRS or USB cable provides enough conductors for this driver to function.</p><h3id="setup"tabindex="-1">Setup <aclass="header-anchor"href="#setup"aria-label="Permalink to "Setup""></a></h3><p>To use the bitbang driver follow these steps to activate it.</p><ol><li>Change the <code>SERIAL_DRIVER</code> to <code>bitbang</code> in your keyboards <code>rules.mk</code> file:</li></ol><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SERIAL_DRIVER = bitbang</span></span></code></pre></div><olstart="2"><li>Configure the GPIO pin of your keyboard via the <code>config.h</code> file:</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SOFT_SERIAL_PIN</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> D0</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // or D1, D2, D3, E6</span></span></code></pre></div><olstart="3"><li>On ARM platforms you must turn on ChibiOS <code>PAL_USE_CALLBACKS</code> feature:</li></ol><ul><li>In <code>halconf.h</code> add the line <code>#define PAL_USE_CALLBACKS TRUE</code>.</li></ul><hr><h2id="usart-half-duplex"tabindex="-1">USART Half-duplex <aclass="header-anchor"href="#usart-half-duplex"aria-label="Permalink to "USART Half-duplex""></a></h2><p>Targeting ARM boards based on ChibiOS, where communication is offloaded to a USART hardware device that supports Half-duplex operation. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose Half-duplex over Bitbang if MCU is capable of utilising Half-duplex, and Full-duplex can't be used instead (e.g. lack of available GPIO pins, or imcompatible PCB design).</p><h3id="pin-configuration-1"tabindex="-1">Pin configuration <aclass="header-anchor"href="#pin-configuration-1"aria-label="Permalink to "Pin configuration""></a></h3><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> LEFT RIGHT </span></span>
<spanclass="line"><span>+-------+ +-------+</span></span></code></pre></div><p>Only one GPIO pin is needed for the Half-duplex driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the <code>SERIAL_USART_TX_PIN</code> in the configuration. Ensure that the pin chosen for split communication can operate as the TX pin of the contoller's USART peripheral. A TRS or USB cable provides enough conductors for this driver to function. As the split connection is configured to operate in open-drain mode, an <strong>external pull-up resistor is needed to keep the line high</strong>. Resistor values of 1.5kΩ to 8.2kΩ are known to work.</p><divclass="warning custom-block"><pclass="custom-block-title">WARNING</p><p><em><strong>Note:</strong></em> A pull-up resistor isn't required for RP2040 controllers configured with PIO subsystem.</p></div><h3id="setup-1"tabindex="-1">Setup <aclass="header-anchor"href="#setup-1"aria-label="Permalink to "Setup""></a></h3><p>To use the Half-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation, start at step 2.</p><ol><li>Change the <code>SERIAL_DRIVER</code> to <code>usart</code> in your keyboards <code>rules.mk</code> file:</li></ol><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SERIAL_DRIVER = usart</span></span></code></pre></div><p>Skip to step 3.</p><olstart="2"><li>(RP2040 + PIO only!) Change the <code>SERIAL_DRIVER</code> to <code>vendor</code> in your keyboards <code>rules.mk</code> file:</li></ol><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SERIAL_DRIVER = vendor</span></span></code></pre></div><olstart="3"><li>Configure the hardware of your keyboard via the <code>config.h</code> file:</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_TX_PIN</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> B6</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // The GPIO pin that is used split communication.</span></span></code></pre></div><p>For STM32 MCUs several GPIO configuration options can be changed as well. See the section <ahref="#alternate-functions-for-selected-stm32-mcus">"Alternate Functions for selected STM32 MCUs"</a>.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> USART1_REMAP</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Remap USART TX and RX pins on STM32F103 MCUs, see table below.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_TX_PAL_MODE</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 7</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7</span></span></code></pre></div><olstart="4"><li>Decide either for <code>SERIAL</code>, <code>SIO</code>, or <code>PIO</code> subsystem. See section <ahref="#choosing-a-driver-subsystem">"Choosing a driver subsystem"</a>.</li></ol><hr><h2id="usart-full-duplex"tabindex="-1">USART Full-duplex <aclass="header-anchor"href="#usart-full-duplex"aria-label="Permalink to "USART Full-duplex""></a></h2><p>Targeting ARM boards based on ChibiOS where communication is offloaded to an USART hardware device. The advantages over bitbanging are fast, accurate timings and reduced CPU usage; therefore it is advised to choose this driver over all others where possible. Due to its internal design Full-duplex is slightly more efficient than the Half-duplex driver, but Full-duplex should be primarily chosen if Half-duplex operation is not supported by the controller's USART peripheral.</p><h3id="pin-configuration-2"tabindex="-1">Pin configuration <aclass="header-anchor"href="#pin-configuration-2"aria-label="Permalink to "Pin configuration""></a></h3><divclass="language- vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang"></span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><span> LEFT RIGHT</span></span>
<spanclass="line"><span>+-------+ +-------+</span></span></code></pre></div><p>Two GPIO pins are needed for the Full-duplex driver, as two distinct wires are used for receiving and transmitting data. The pin transmitting data is the <code>TX</code> pin and refereed to as the <code>SERIAL_USART_TX_PIN</code>, the pin receiving data is the <code>RX</code> pin and refereed to as the <code>SERIAL_USART_RX_PIN</code> in this configuration. Please note that <code>TX</code> pin of the master half has to be connected with the <code>RX</code> pin of the slave half and the <code>RX</code> pin of the master half has to be connected with the <code>TX</code> pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the PCB. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU. A TRRS or USB cable provides enough conductors for this driver to function.</p><p>To use this driver the USART peripherals <code>TX</code> and <code>RX</code> pins must be configured with the correct Alternate-functions. If you are using a Proton-C development board everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting <code>SERIAL_USART_TX_PAL_MODE</code> and <code>SERIAL_USART_RX_PAL_MODE</code>. Refer to the corresponding datasheets of your MCU or find those settings in the section <ahref="#alternate-functions-for-selected-stm32-mcus">"Alternate Functions for selected STM32 MCUs"</a>.</p><h3id="setup-2"tabindex="-1">Setup <aclass="header-anchor"href="#setup-2"aria-label="Permalink to "Setup""></a></h3><p>To use the Full-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation, start at step 2</p><ol><li>Change the <code>SERIAL_DRIVER</code> to <code>usart</code> in your keyboards <code>rules.mk</code> file:</li></ol><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SERIAL_DRIVER = usart</span></span></code></pre></div><p>Skip to step 3</p><olstart="2"><li>(RP2040 + PIO only!) Change the <code>SERIAL_DRIVER</code> to <code>vendor</code> in your keyboards <code>rules.mk</code> file:</li></ol><divclass="language-make vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">make</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SERIAL_DRIVER = vendor</span></span></code></pre></div><olstart="3"><li>Configure the hardware of your keyboard via the <code>config.h</code> file:</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_FULL_DUPLEX</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Enable full duplex operation mode.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_RX_PIN</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> B7</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // USART RX pin</span></span></code></pre></div><p>For STM32 MCUs several GPIO configuration options, including the ability for <code>TX</code> to <code>RX</code> pin swapping, can be changed as well. See the section <ahref="#alternate-functions-for-selected-stm32-mcus">"Alternate Functions for selected STM32 MCUs"</a>.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_PIN_SWAP</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Swap TX and RX pins if keyboard is master halve. (Only available on some MCUs)</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> USART1_REMAP</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Remap USART TX and RX pins on STM32F103 MCUs, see table below.</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_TX_PAL_MODE</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 7</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7</span></span></code></pre></div><olstart="4"><li>Decide either for <code>SERIAL</code>, <code>SIO</code>, or <code>PIO</code> subsystem. See section <ahref="#choosing-a-driver-subsystem">"Choosing a driver subsystem"</a>.</li></ol><hr><h2id="choosing-a-driver-subsystem"tabindex="-1">Choosing a driver subsystem <aclass="header-anchor"href="#choosing-a-driver-subsystem"aria-label="Permalink to "Choosing a driver subsystem""></a></h2><h3id="the-serial-driver"tabindex="-1">The <code>SERIAL</code> driver <aclass="header-anchor"href="#the-serial-driver"aria-label="Permalink to "The `SERIAL` driver""></a></h3><p>The <code>SERIAL</code> Subsystem is supported for the majority of ChibiOS MCUs and should be used whenever supported. Follow these steps in order to activate it:</p><ol><li>In your keyboards <code>halconf.h</code> add:</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_SERIAL</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><olstart="2"><li>In your keyboards <code>mcuconf.h</code>: activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the <code>mcuconf.h</code> files of your MCU that ship with ChibiOS.</li></ol><p>Just below <code>#include_next <mcuconf.h></code> add:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><spanstyle="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"><mcuconf.h></span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_SERIAL_USE_USARTn</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>Where 'n' matches the peripheral number of your selected USART on the MCU.</p><olstart="3"><li>In you keyboards <code>config.h</code>: override the default USART <code>SERIAL</code> driver if you use a USART peripheral that does not belong to the default selected <code>SD1</code> driver. For instance, if you selected <code>STM32_SERIAL_USE_USART3</code> the matching driver would be <code>SD3</code>.</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> #define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_DRIVER</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SD3</span></span></code></pre></div><h3id="the-sio-driver"tabindex="-1">The <code>SIO</code> driver <aclass="header-anchor"href="#the-sio-driver"aria-label="Permalink to "The `SIO` driver""></a></h3><p>The <code>SIO</code> Subsystem was added to ChibiOS with the 21.11 release and is only supported on selected MCUs. It should only be chosen when the <code>SERIAL</code> subsystem is not supported by your MCU.</p><p>Follow these steps in order to activate it:</p><ol><li>In your keyboards <code>halconf.h</code> add:</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_SIO</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><olstart="2"><li>In your keyboards <code>mcuconf.h:</code> activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the <code>mcuconf.h</code> files of your MCU that ship with ChibiOS.</li></ol><p>Just below <code>#include_next <mcuconf.h></code> add:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><spanstyle="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"><mcuconf.h></span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_SIO_USE_USARTn</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>Where 'n' matches the peripheral number of your selected USART on the MCU.</p><olstart="3"><li>In the keyboard's <code>config.h</code> file: override the default USART <code>SIO</code> driver if you use a USART peripheral that does not belong to the default selected <code>SIOD1</code> driver. For instance, if you selected <code>STM32_SERIAL_USE_USART3</code> the matching driver would be <code>SIOD3</code>.</li></ol><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> #define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_USART_DRIVER</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SIOD3</span></span></code></pre></div><h3id="the-pio-driver"tabindex="-1">The <code>PIO</code> driver <aclass="header-anchor"href="#the-pio-driver"aria-label="Permalink to "The `PIO` driver""></a></h3><p>The <code>PIO</code> subsystem is a Raspberry Pi RP2040 specific implementation, using an integrated PIO peripheral and is therefore only available on this MCU. Because of the flexible nature of PIO peripherals, <strong>any</strong> GPIO pin can be used as a <code>TX</code> or <code>RX</code> pin. Half-duplex and Full-duplex operation modes are fully supported with this driver. Half-duplex uses the built-in pull-ups and GPIO manipulation of the RP2040 to drive the line high by default, thus an external pull-up resistor <strong>is not required</strong>.</p><p>Optionally, the PIO peripheral utilized for split communication can be changed with the following define in config.h:</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SERIAL_PIO_USE_PIO1</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Force the usage of PIO1 peripheral, by default the Serial implementation uses the PIO0 peripheral</span></span></code></pre></div><p>The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on.</p><hr><h2id="advanced-configuration"tabindex="-1">Advanced Configuration <aclass="header-anchor"href="#advanced-configuration"aria-label="Permalink to "Advanced Configuration""></a></h2><p>There are several advanced configuration options that can be defined in your keyboards <code>config.h</code> file:</p><h3id="baudrate"tabindex="-1">Baudrate <aclass="header-anchor"href="#baudrate"aria-label="Permalink to "Baudrate""></a></h3><p>If you're having issues or need a higher baudrate with serial communication, you can change the baudrate which in turn controls the communication speed for serial. You want to lower the baudrate if you experience failed transactions.</p><divclass="language-c vp-adaptive-theme"><buttontitle="Copy Code"class="copy"></button><spanclass="lang">c</span><preclass="shiki shiki-themes github-light github-dark vp-code"><code><spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SELECT_SOFT_SERIAL_SPEED</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {#}</span></span></code></pre></div><table><thead><tr><th>Speed</th><th>Bitbang</th><th>Half-duplex and Full-duplex</th></tr></thead><tbody><tr><td><code>0</code></td><td>189000 baud (experimental)</td><td>460800 baud</