<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Note that this is called in the main keyboard loop,</span></span>
<spanclass="line"><spanstyle="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // so long running actions here can cause performance issues</span></span>
<spanclass="line"><spanstyle="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h2id="avr-configuration"tabindex="-1">AVR Configuration <aclass="header-anchor"href="#avr-configuration"aria-label="Permalink to "AVR Configuration {#avr-configuration}""></a></h2><h3id="avr-pwm-driver"tabindex="-1">PWM Driver <aclass="header-anchor"href="#avr-pwm-driver"aria-label="Permalink to "PWM Driver {#avr-pwm-driver}""></a></h3><p>The following table describes the supported pins for the PWM driver. Only cells marked with a timer number are capable of hardware PWM output; any others must use the <code>timer</code> driver.</p><table><thead><tr><th>Backlight Pin</th><th>AT90USB64/128</th><th>AT90USB162</th><th>ATmega16/32U4</th><th>ATmega16/32U2</th><th>ATmega32A</th><th>ATmega328/P</th></tr></thead><tbody><tr><td><code>B1</code></td><td></td><td></td><td></td><td></td><td></td><td>Timer 1</td></tr><tr><td><code>B2</code></td><td></td><td></td><td></td><td></td><td></td><td>Timer 1</td></tr><tr><td><code>B5</code></td><td>Timer 1</td><td></td><td>Timer 1</td><td></td><td></td><td></td></tr><tr><td><code>B6</code></td><td>Timer 1</td><td></td><td>Timer 1</td><td></td><td></td><td></td></tr><tr><td><code>B7</code></td><td>Timer 1</td><td>Timer 1</td><td>Timer 1</td><td>Timer 1</td><td></td><td></td></tr><tr><td><code>C4</code></td><td>Timer 3</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td><code>C5</code></td><td>Timer 3</td><td>Timer 1</td><td></td><td>Timer 1</td><td></td><td></td></tr><tr><td><code>C6</code></td><td>Timer 3</td><td>Timer 1</td><td>Timer 3</td><td>Timer 1</td><td></td><td></td></tr><tr><td><code>D4</code></td><td></td><td></td><td></td><td></td><td>Timer 1</td><td></td></tr><tr><td><code>D5</code></td><td></td><td></td><td></td><td></td><td>Timer 1</td><td></td></tr></tbody></table><h3id="avr-timer-driver"tabindex="-1">Timer Driver <aclass="header-anchor"href="#avr-timer-driver"aria-label="Permalink to "Timer Driver {#avr-timer-driver}""></a></h3><p>Any GPIO pin can be used with this driver. The following table describes the supported timers:</p><table><thead><tr><th>AT90USB64/128</th><th>AT90USB162</th><th>ATmega16/32U4</th><th>ATmega16/32U2</th><th>ATmega32A</th><th>ATmega328/P</th></tr></thead><tbody><tr><td>Timers 1 & 3</td><td>Timer 1</td><td>Timers 1 & 3</td><td>Timer 1</td><td>Timer 1</td><td>Timer 1</td></tr></tbody></table><p>The following <code>#define</code>s apply only to the <code>timer</code> driver:</p><table><thead><tr><th>Define</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>BACKLIGHT_PWM_TIMER</code></td><td><code>1</code></td><td>The timer to use</td></tr></tbody></table><p>Note that the choice of timer may conflict with the <ahref="./audio">Audio</a> feature.</p><h2id="arm-configuration"tabindex="-1">ChibiOS/ARM Configuration <aclass="header-anchor"href="#arm-configuration"aria-label="Permalink to "ChibiOS/ARM Configuration {#arm-configuration}""></a></h2><h3id="arm-pwm-driver"tabindex="-1">PWM Driver <aclass="header-anchor"href="#arm-pwm-driver"aria-label="Permalink to "PWM Driver {#arm-pwm-driver}""></a></h3><p>Depending on the ChibiOS board configuration, you may need to enable PWM at the keyboard level. For STM32, this would look like:</p><p><code>halconf.h</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;"> HAL_USE_PWM</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p><code>mcuconf.h</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><s
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_PWM_USE_TIM4</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>The following <code>#define</code>s apply only to the <code>pwm</code> driver:</p><table><thead><tr><th>Define</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>BACKLIGHT_PWM_DRIVER</code></td><td><code>PWMD4</code></td><td>The PWM driver to use</td></tr><tr><td><code>BACKLIGHT_PWM_CHANNEL</code></td><td><code>3</code></td><td>The PWM channel to use</td></tr><tr><td><code>BACKLIGHT_PAL_MODE</code></td><td><code>2</code></td><td>The pin alternative function to use</td></tr><tr><td><code>BACKLIGHT_PWM_PERIOD</code></td><td><em>Not defined</em></td><td>The PWM period in counter ticks - Default is platform dependent</td></tr></tbody></table><p>Refer to the ST datasheet for your particular MCU to determine these values. For example, these defaults are set up for pin <code>B8</code> on a Proton-C (STM32F303) using <code>TIM4_CH3</code> on AF2. Unless you are designing your own keyboard, you generally should not need to change them.</p><h3id="arm-timer-driver"tabindex="-1">Timer Driver <aclass="header-anchor"href="#arm-timer-driver"aria-label="Permalink to "Timer Driver {#arm-timer-driver}""></a></h3><p>Depending on the ChibiOS board configuration, you may need to enable general-purpose timers at the keyboard level. For STM32, this would look like:</p><p><code>halconf.h</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;"> HAL_USE_GPT</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p><code>mcuconf.h</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;">#undef</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM15</span></span>
<spanclass="line"><spanstyle="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><spanstyle="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM15</span><spanstyle="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>The following <code>#define</code>s apply only to the <code>timer</code> driver:</p><table><thead><tr><th>Define</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>BACKLIGHT_GPT_DRIVER</code></td><td><code>GPTD15</code></td><td>The timer to use</td></tr></tbody></table><h2id="example-schematic"tabindex="-1">Example Schematic <aclass="header-anchor"href="#example-schematic"aria-label="Permalink to "Example Schematic""></a></h2><p>Since the MCU can only supply so much current to its GPIO pins, instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs.</p><p>In this typical example, the backlight LEDs are all connected in parallel towards an N-channel MOSFET. Its gate pin is wired to one of the microcontroller's GPIO pins through a 470Ω resistor to avoid ringing. A pulldown resistor is also placed between the gate pin and ground to keep it at a defined state when it is not otherwise being driven by the MCU. The values of these resistors are not critical - see <ahref="https://electronics.stackexchange.com/q/68748"target="_blank"rel="noreferrer">this Electronics StackExchange question</a> for more information.</p><p><imgsrc="https://i.imgur.com/BmAvoUC.png"alt="Backlight example circuit"></p><h2id="api"tabindex="-1">API <aclass="header-anchor"href="#api"aria-label="Permalink to "API {#api}""></a></h2><h3id="api-backlight-toggle"tabindex="-1"><code>void backlight_toggle(void)</code><aclass="header-anchor"href="#api-backlight-toggle"aria-label="Permalink to "`void backlight_toggle(void)` {#api-backlight-toggle}""></a></h3><p>Toggle the backlight on or off.</p><hr><h3id="api-backlight-enable"tabindex="-1"><code>void backlight_enable(void)</code><aclass="header-anchor"href="#api-backlight-enable"aria-label="Permalink to "`void backlight_enable(void)` {#api-backlight-enable}""></a></h3><p>Turn the backlight on.</p><hr><h3id="api-backlight-disable"tabindex="-1"><code>void backlight_disable(void)</code><aclass="header-anchor"href="#api-backlight-disable"aria-label="Permalink to "`void backlight_disable(void)` {#api-backlight-disable}""></a></h3><p>Turn the backlight off.</p><hr><h3id="api-backlight-step"tabindex="-1"><code>void backlight_step(void)</code><aclass="header-anchor"href="#api-backlight-step"aria-label="Permalink to "`void backlight_step(void)` {#api-backlight-step}""></a></h3><p>Cycle through backlight levels.</p><hr><h3id="api-backlight-increase"tabindex="-1"><code>void backlight_increase(void)</code><aclass="header-anchor"href="#api-backlight-increase"aria-label="Permalink to "`void backlight_increase(void)` {#api-backlight-increase}""></a></h3><p>Increase the backlight level.</p><hr><h3id="api-backlight-decrease"tabindex="-1"><code>void backlight_decrease(void)</code><aclass="header-anchor"href="#api-backlight-decrease"aria-label="Permalink to "`void backlight_decrease(void)` {#api-backlight-decrease}""></a></h3><p>Decrease the backlight level.</p><hr><h3id="api-backlight-level"tabindex="-1"><code>void backlight_level(uint8_t level)</code><aclass="header-anchor"href="#api-backlight-level"aria-label="Permalink to "`void backlight_level(uint8_t level)` {#api-backlight-level}""></a></h3><p>Set the backlight level.</p><h4id="api-backlight-level-arguments"tabindex="-1">Arguments <aclass="header-anchor"href="#api-backlight-level-arguments"aria-label="Permalink to "Arguments {#api-backlight-level-arguments}""></a></h4><ul><li><code>uint8_t level</code><br> The level to set, from 0 to <code>BACKLIGHT_LEVELS</code>.</li></ul><hr><h3id="api-get-back