<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// or, for user:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SPLIT_TRANSACTION_IDS_USER</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> USER_SYNC_A, USER_SYNC_B, USER_SYNC_C</span></span></code></pre></div><p>These <em>transaction IDs</em> then need a slave-side handler function to be registered with the split transport, for example:</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;">typedef</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> struct</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _master_to_slave_t</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> s2m->s2m_data </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> m2s->m2s_data </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">+</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 5</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // whatever comes in, add 5 so it can be sent back</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>The master side can then invoke the slave-side handler - for normal keyboard functionality to be minimally affected, any keyboard- or user-level code attempting to sync data should be throttled:</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;">void</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> housekeeping_task_user</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> dprintf</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Slave value: </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%d\n</span><spanstyle="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, s2m.s2m_data);</span><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // this will now be 11, as the slave adds 5</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><divclass="warning custom-block"><pclass="custom-block-title">WARNING</p><p>It is recommended that any data sync between halves happens during the master side's <em>housekeeping task</em>. This ensures timely retries should failures occur.</p></div><p>If only one-way data transfer is needed, helper methods are provided:</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;">bool</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> transaction_rpc_exec</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> transaction_id</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint8_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> initiator2target_buffer_size</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;">initiator2target_buffer</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint8_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> target2initiator_buffer_size</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;">target2initiator_buffer</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">bool</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> transaction_rpc_recv</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">int8_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> transaction_id</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">uint8_t</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> target2initiator_buffer_size</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><spanstyle="--shiki-light:#E36209;--shiki-dark:#FFAB70;">target2initiator_buffer</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>By default, the inbound and outbound data is limited to a maximum of 32 bytes each. The sizes can be altered if required:</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:#6A737D;--shiki-dark:#6A737D;">// Master to slave:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Slave to master:</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> RPC_S2M_BUFFER_SIZE</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 48</span></span></code></pre></div><h3id="hardware-configuration-options"tabindex="-1">Hardware Configuration Options <aclass="header-anchor"href="#hardware-configuration-options"aria-label="Permalink to "Hardware Configuration Options""></a></h3><p>There are some settings that you may need to configure, based on how the hardware is set up.</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;"> MATRIX_ROW_PINS_RIGHT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">row pins</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> MATRIX_COL_PINS_RIGHT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">col pins</span><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p>This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). The number of pins in the right and left matrices must be the same, if you have a board with a different number of rows or columns on one side, pad out the extra spaces with <code>NO_PIN</code> and make sure you add the unused rows or columns to your matrix.</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;"> DIRECT_PINS_RIGHT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }</span></span></code></pre></div><p>This allows you to specify a different set of direct pins for the right side.</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;"> ENCODER_A_PINS_RIGHT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { encoder1a, encoder2a }</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ENCODER_B_PINS_RIGHT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { encoder1b, encoder2b }</span></span></code></pre></div><p>This allows you to specify a different set of encoder pins for the right side.</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;"> RGBLIGHT_SPLIT</span></span></code></pre></div><p>This option enables synchronization of the RGB Light modes between the controllers of the split keyboard. This is for keyboards that have RGB LEDs that are directly wired to the controller (that is, they are not using the "extra data" option on the TRRS cable).</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;"> RGBLED_SPLIT</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">6</span><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p>This sets how many LEDs are directly connected to each controller. The first number is the left side, and the second number is the right side.</p><divclass="tip custom-block"><pclass="custom-block-title">TIP</p><p>This setting implies that <code>RGBLIGHT_SPLIT</code> is enabled, and will forcibly enable it, if it's not.</p></div><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;"> SPLIT_USB_DETECT</span></span></code></pre></div><p>Enabling this option changes the startup behavior to listen for an active USB communication to delegate which part is master and which is slave. With this option enabled and theres's USB communication, then that half assumes it is the master, otherwise it assumes it is the slave.</p><p>Without this option, the master is the half that can detect voltage on the physical USB connection (VBUS detection).</p><p>Enabled by default on ChibiOS/ARM.</p><divclass="tip custom-block"><pclass="custom-block-title">TIP</p><p>This setting will stop the ability to demo using battery packs.</p></div><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;"> SPLIT_USB_TIMEOUT</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 2000</span></span></code></pre></div><p>This sets the maximum timeout when detecting master/slave when using <code>SPLIT_USB_DETECT</code>.</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;"> SPLIT_USB_TIMEOUT_POLL</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 10</span></span></code