qmk_firmware/assets/drivers_audio.md.FGaarcoq.js

16 lines
25 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { _ as _export_sfc, c as createElementBlock, o as openBlock, a8 as createStaticVNode } from "./chunks/framework.B9AX-CPi.js";
const __pageData = JSON.parse('{"title":"Audio Driver","description":"","frontmatter":{},"headers":[],"relativePath":"drivers/audio.md","filePath":"drivers/audio.md"}');
const _sfc_main = { name: "drivers/audio.md" };
const _hoisted_1 = /* @__PURE__ */ createStaticVNode('<h1 id="audio-driver" tabindex="-1">Audio Driver <a class="header-anchor" href="#audio-driver" aria-label="Permalink to &quot;Audio Driver {#audio-driver}&quot;"></a></h1><p>The <a href="./../features/audio">Audio feature</a> breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-&quot;core&quot; - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed.</p><p>Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral.</p><h2 id="avr" tabindex="-1">AVR <a class="header-anchor" href="#avr" aria-label="Permalink to &quot;AVR {#avr}&quot;"></a></h2><p>Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker. The possible configurations are:</p><table><thead><tr><th></th><th>Timer3</th><th>Timer1</th></tr></thead><tbody><tr><td>one speaker</td><td>C4,C5 or C6</td><td></td></tr><tr><td>one speaker</td><td></td><td>B4, B5 or B7</td></tr><tr><td>two speakers</td><td>C4,C5 or C6</td><td>B4, B5 or B7</td></tr></tbody></table><p>Currently there is only one/default driver for AVR based boards, which is automatically configured to:</p><div class="language-make vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">make</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">AUDIO_DRIVER = pwm_hardware</span></span></code></pre></div><h2 id="arm" tabindex="-1">ARM <a class="header-anchor" href="#arm" aria-label="Permalink to &quot;ARM {#arm}&quot;"></a></h2><p>For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available.</p><p>Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below; piezo speakers are marked with 1⃣ for the first/primary and 2⃣ for the secondary.</p><table><thead><tr><th>driver</th><th>GPTD6<br>Tim6</th><th>GPTD7<br>Tim7</th><th>GPTD8<br>Tim8</th><th>PWMD1<sup>1</sup><br>Tim1_Ch1</th></tr></thead><tbody><tr><td>dac_basic</td><td>A4+DACD1 = 1⃣</td><td>A5+DACD2 = 1⃣</td><td>state</td><td></td></tr><tr><td></td><td>A4+DACD1 = 1⃣ + Gnd</td><td>A5+DACD2 = 2⃣ + Gnd</td><td>state</td><td></td></tr><tr><td></td><td>A4+DACD1 = 2⃣ + Gnd</td><td>A5+DACD2 = 1⃣ + Gnd</td><td>state</td><td></td></tr><tr><td></td><td>A4+DACD1 = 1⃣ + Gnd</td><td></td><td>state</td><td></td></tr><tr><td></td><td></td><td>A5+DACD2 = 1⃣ + Gnd</td><td>state</td><td></td></tr><tr><td>dac_additive</td><td>A4+DACD1 = 1⃣ + Gnd</td><td></td><td></td><td></td></tr><tr><td></td><td>A5+DACD2 = 1⃣ + Gnd</td><td></td><td></td><td></td></tr><tr><td></td><td>A4+DACD1 + A5+DACD2 = 1⃣ <sup>2</sup></td><td></td><td></td><td></td></tr><tr><td>pwm_software</td><td>state-update</td><td></td><td></td><td>any = 1⃣</td></tr><tr><td>pwm hardware</td><td>state-update</td><td></td><td></td><td>A8 = 1⃣ <sup>3</sup></td></tr></tbody></table><p><sup>1</sup>: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet<br><sup>2</sup>: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set<br><sup>3</sup>: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL</p><h3 id="dac-basic" tabindex="-1">DAC basic <a class="header-anchor" href="#dac-basic" aria-label="Permalink to &quot;DAC basic {#dac-basic}&quot;"></a></h3><p>The default driver for ARM boards, in absence of an overriding configuration. This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core.</p><p>Additionally, in the board config, you&#39;ll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//halconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_DAC</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_GPT</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;halconf.h&gt;</span></span></code></pre></div><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// mcuconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;mcuconf.h&gt;</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH1</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH1</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH2</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH2</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM6</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM6</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM7</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM7</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM8</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM8</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).</p></div><p>You can also change the timer used for the overall audio state by defining the driver. For instance:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_STATE_TIMER</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> GPTD9</span></span></code></pre></div><h3 id="dac-additive" tabindex="-1">DAC additive <a class="header-anchor" href="#dac-additive" aria-label="Permalink to &quot;DAC additive {#dac-additive}&quot;"></a></h3><p>only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback.</p><p>Additionally, in the board config, you&#39;ll want to make changes to enable the DACs, GPT for Timer 6:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//halconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_DAC</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_GPT</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;halconf.h&gt;</span></span></code></pre></div><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// mcuconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;mcuconf.h&gt;</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH1</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH1</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH2</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_DAC_USE_DAC1_CH2</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM6</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_GPT_USE_TIM6</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><h3 id="dac-config" tabindex="-1">DAC Config <a class="header-anchor" href="#dac-config" aria-label="Permalink to &quot;DAC Config&quot;"></a></h3><table><thead><tr><th>Define</th><th>Defaults</th><th>Description</th></tr></thead><tbody><tr><td><code>AUDIO_DAC_SAMPLE_MAX</code></td><td><code>4095U</code></td><td>Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples.</td></tr><tr><td><code>AUDIO_DAC_OFF_VALUE</code></td><td><code>AUDIO_DAC_SAMPLE_MAX / 2</code></td><td>The value of the DAC when not playing anything. Some setups may require a high (<code>AUDIO_DAC_SAMPLE_MAX</code>) or low (<code>0</code>) value here.</td></tr><tr><td><code>AUDIO_MAX_SIMULTANEOUS_TONES</code></td><td><strong>see next table</strong></td><td>The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played.</td></tr><tr><td><code>AUDIO_DAC_SAMPLE_RATE</code></td><td><strong>see next table</strong></td><td>Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality.</td></tr><tr><td><code>AUDIO_DAC_BUFFER_SIZE</code></td><td><strong>see next table</strong></td><td>Number of samples generated every refill. Too few may cause excessive CPU load; too many may cause freezes, RAM or flash exhaustion or lags during matrix scanning.</td></tr></tbody></table><p>There are a number of predefined quality settings that you can use, with &quot;sane minimum&quot; being the default. You can use custom values by simply defining the sample rate, number of simultaneous tones and buffer size, instead of using one of the listed presets.</p><table><thead><tr><th>Define</th><th>Sample Rate</th><th>Simultaneous tones</th><th>Buffer size</th></tr></thead><tbody><tr><td><code>AUDIO_DAC_QUALITY_VERY_LOW</code></td><td><code>11025U</code></td><td><code>8</code></td><td><code>64U</code></td></tr><tr><td><code>AUDIO_DAC_QUALITY_LOW</code></td><td><code>22050U</code></td><td><code>4</code></td><td><code>128U</code></td></tr><tr><td><code>AUDIO_DAC_QUALITY_HIGH</code></td><td><code>44100U</code></td><td><code>2</code></td><td><code>256U</code></td></tr><tr><td><code>AUDIO_DAC_QUALITY_VERY_HIGH</code></td><td><code>88200U</code></td><td><code>1</code></td><td><code>256U</code></td></tr><tr><td><code>AUDIO_DAC_QUALITY_SANE_MINIMUM</code></td><td><code>16384U</code></td><td><code>8</code></td><td><code>64U</code></td></tr></tbody></table><h4 id="buffer-size" tabindex="-1">Notes on buffer size <a class="header-anchor" href="#buffer-size" aria-label="Permalink to &quot;Notes on buffer size {#buffer-size}&quot;"></a></h4><p>By default, the buffer size attempts to keep to these constraints:</p><ul><li>The interval between buffer refills can&#39;t be too short, since the microcontroller would then only be servicing buffer refills and would freeze up.</li><li>On the additive driver, the interval between buffer refills can&#39;t be too long, since matrix scanning would suffer lengthy pauses every so often, which would delay key presses or releases or lose some short taps altogether.</li><li>The interval between buffer refills is kept to a minimum, which allows notes to stop as soon as possible after they should.</li><li>For greater compatibility, the buffer size should be a power of 2.</li><li>The buffer size being too large causes resource exhaustion leading to build failures or freezing at runtime: RAM usage (on the additive driver) or flash usage (on the basic driver).</li></ul><p>You can lower the buffer size if you need a bit more space in your firmware, or raise it if your keyboard freezes up.</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX)</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * *</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * *</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * ---------------------------------------------------------</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * * } AUDIO_DAC_SAMPLE_MAX/100</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * * } AUDIO_DAC_SAMPLE_MAX/100</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * ---------------------------------------------------------</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * *</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * *</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * * *</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> * =====*=*================================================= 0x0</span></span>\n<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> */</span></span></code></pre></div><h3 id="pwm-hardware" tabindex="-1">PWM hardware <a class="header-anchor" href="#pwm-hardware" aria-label="Permalink to &quot;PWM hardware {#pwm-hardware}&quot;"></a></h3><p>This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. The hardware directly toggles the pin via its alternate function. See your MCU&#39;s data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function.</p><p>A configuration example for the STM32F103C8 would be:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//halconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_PWM</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> HAL_USE_PAL</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;halconf.h&gt;</span></span></code></pre></div><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// mcuconf.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#include_next</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &lt;mcuconf.h&gt;</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_PWM_USE_TIM1</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_PWM_USE_TIM1</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions</p><ul><li>TIM1_CH1 = PA8 &lt;- alternate0</li><li>TIM1_CH2 = PA9</li><li>TIM1_CH3 = PA10</li><li>TIM1_CH4 = PA11</li></ul><p>with all this information, the configuration would contain these lines:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">//config.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_PIN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A8</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_PWM_DRIVER</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PWMD1</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_PWM_CHANNEL</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span></span></code></pre></div><p>ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. On &#39;larger&#39; STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure <code>AUDIO_PWM_PAL_MODE</code> to the correct alternate function for the selected pin, timer and timer-channel.</p><p>You can also use the Complementary output (<code>TIMx_CHyN</code>) for PWM on supported controllers. To enable this functionality, you will need to make the following changes:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// config.h:</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_PWM_COMPLEMENTARY_OUTPUT</span></span></code></pre></div><h3 id="pwm-software" tabindex="-1">PWM software <a class="header-anchor" href="#pwm-software" aria-label="Permalink to &quot;PWM software {#pwm-software}&quot;"></a></h3><p>This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software. During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd).</p><p>You can also change the timer used for software PWM by defining the driver. For instance:</p><div class="language-c vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">c</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AUDIO_STATE_TIMER</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> GPTD8</span></span></code></pre></div><h3 id="testing-notes" tabindex="-1">Testing Notes <a class="header-anchor" href="#testing-notes" aria-label="Permalink to &quot;Testing Notes {#testing-notes}&quot;"></a></h3><p>While not an exhaustive list, the following table provides the scenarios that have been partially validated:</p><table><thead><tr><th></th><th>DAC basic</th><th>DAC additive</th><th>PWM hardware</th><th>PWM software</th></tr></thead><tbody><tr><td>Atmega32U4</td><td>⭕</td><td>⭕</td><td>✔️</td><td>⭕</td></tr><tr><td>RP2040</td><td>❌</td><td>❌</td><td>✔️</td><td>?</td></tr><tr><td>STM32F103C8 (bluepill)</td><td>❌</td><td>❌</td><td>✔️</td><td>✔️</td></tr><tr><td>STM32F303CCT6 (proton-c)</td><td>✔️</td><td>✔️</td><td>?</td><td>✔️</td></tr><tr><td>STM32F405VG</td><td>✔️</td><td>✔️</td><td>✔️</td><td>✔️</td></tr><tr><td>L0xx</td><td>❌ (no Tim8)</td><td>?</td><td>?</td><td>?</td></tr></tbody></table><p>✔️ : works and was tested<br> ⭕ : does not apply<br> ❌ : not supported by MCU</p><p><em>Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.</em></p>', 56);
const _hoisted_57 = [
_hoisted_1
];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", null, _hoisted_57);
}
const audio = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
__pageData,
audio as default
};