qmk_firmware/assets/drivers_spi.md.tJVeIT7e.js

16 lines
14 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.DyMmIvSC.js";
const __pageData = JSON.parse('{"title":"SPI Master Driver","description":"","frontmatter":{},"headers":[],"relativePath":"drivers/spi.md","filePath":"drivers/spi.md"}');
const _sfc_main = { name: "drivers/spi.md" };
const _hoisted_1 = /* @__PURE__ */ createStaticVNode('<h1 id="spi-master-driver" tabindex="-1">SPI Master Driver <a class="header-anchor" href="#spi-master-driver" aria-label="Permalink to &quot;SPI Master Driver {#spi-master-driver}&quot;"></a></h1><p>The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs.</p><h2 id="usage" tabindex="-1">Usage <a class="header-anchor" href="#usage" aria-label="Permalink to &quot;Usage {#usage}&quot;"></a></h2><p>In most cases, the SPI Master driver code is automatically included if you are using a feature or driver which requires it, such as <a href="./../features/oled_driver">OLED</a>.</p><p>However, if you need to use the driver standalone, add the following to your <code>rules.mk</code>:</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;">SPI_DRIVER_REQUIRED = yes</span></span></code></pre></div><p>You can then call the SPI API by including <code>spi_master.h</code> in your code.</p><h2 id="avr-configuration" tabindex="-1">AVR Configuration <a class="header-anchor" href="#avr-configuration" aria-label="Permalink to &quot;AVR Configuration {#avr-configuration}&quot;"></a></h2><p>No special setup is required - just connect the <code>SS</code>, <code>SCK</code>, <code>MOSI</code> and <code>MISO</code> pins of your SPI devices to the matching pins on the MCU:</p><table><thead><tr><th>MCU</th><th><code>SS</code></th><th><code>SCK</code></th><th><code>MOSI</code></th><th><code>MISO</code></th></tr></thead><tbody><tr><td>ATmega16/32U2/4</td><td><code>B0</code></td><td><code>B1</code></td><td><code>B2</code></td><td><code>B3</code></td></tr><tr><td>AT90USB64/128/162</td><td><code>B0</code></td><td><code>B1</code></td><td><code>B2</code></td><td><code>B3</code></td></tr><tr><td>ATmega32A</td><td><code>B4</code></td><td><code>B7</code></td><td><code>B5</code></td><td><code>B6</code></td></tr><tr><td>ATmega328/P</td><td><code>B2</code></td><td><code>B5</code></td><td><code>B3</code></td><td><code>B4</code></td></tr></tbody></table><p>You may use more than one slave select pin, not just the <code>SS</code> pin. This is useful when you have multiple devices connected and need to communicate with them individually. <code>SPI_SS_PIN</code> can be passed to <code>spi_start()</code> to refer to <code>SS</code>.</p><h2 id="arm-configuration" tabindex="-1">ChibiOS/ARM Configuration <a class="header-anchor" href="#arm-configuration" aria-label="Permalink to &quot;ChibiOS/ARM Configuration {#arm-configuration}&quot;"></a></h2><p>You&#39;ll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc.</p><p>To enable SPI, modify your board&#39;s <code>halconf.h</code> to enable SPI:</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;"> HAL_USE_SPI</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;"> SPI_USE_WAIT</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;"> SPI_SELECT_MODE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SPI_SELECT_MODE_PAD</span></span></code></pre></div><p>Then, modify your board&#39;s <code>mcuconf.h</code> to enable the peripheral you&#39;ve chosen, for example:</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;">#undef</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> STM32_SPI_USE_SPI2</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_SPI_USE_SPI2</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> TRUE</span></span></code></pre></div><p>Configuration-wise, you&#39;ll need to set up the peripheral as per your MCU&#39;s datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303.</p><table><thead><tr><th><code>config.h</code> Override</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td><code>SPI_DRIVER</code></td><td>SPI peripheral to use - SPI1 -&gt; <code>SPID1</code>, SPI2 -&gt; <code>SPID2</code> etc.</td><td><code>SPID2</code></td></tr><tr><td><code>SPI_SCK_PIN</code></td><td>The pin to use for SCK</td><td><code>B13</code></td></tr><tr><td><code>SPI_SCK_PAL_MODE</code></td><td>The alternate function mode for SCK</td><td><code>5</code></td></tr><tr><td><code>SPI_MOSI_PIN</code></td><td>The pin to use for MOSI</td><td><code>B15</code></td></tr><tr><td><code>SPI_MOSI_PAL_MODE</code></td><td>The alternate function mode for MOSI</td><td><code>5</code></td></tr><tr><td><code>SPI_MISO_PIN</code></td><td>The pin to use for MISO</td><td><code>B14</code></td></tr><tr><td><code>SPI_MISO_PAL_MODE</code></td><td>The alternate function mode for MISO</td><td><code>5</code></td></tr></tbody></table><p>As per the AVR configuration, you may choose any other standard GPIO as a slave select pin, which should be supplied to <code>spi_start()</code>.</p><p>If a complete SPI interface is not required, then the following can be done to disable certain SPI pins, so they don&#39;t occupy a GPIO unnecessarily:</p><ul><li>in <code>config.h</code>: <code>#define SPI_MISO_PIN NO_PIN</code></li><li>in <code>config.h</code>: <code>#define SPI_MOSI_PIN NO_PIN</code></li><li>in <code>mcuconf.h</code>: <code>#define SPI_SELECT_MODE SPI_SELECT_MODE_NONE</code>, in this case the <code>slavePin</code> argument passed to <code>spi_start()</code> may be <code>NO_PIN</code> if the slave select pin is not used.</li></ul><h2 id="api" tabindex="-1">API <a class="header-anchor" href="#api" aria-label="Permalink to &quot;API {#api}&quot;"></a></h2><h3 id="api-spi-init" tabindex="-1"><code>void spi_init(void)</code> <a class="header-anchor" href="#api-spi-init" aria-label="Permalink to &quot;`void spi_init(void)` {#api-spi-init}&quot;"></a></h3><p>Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.</p><hr><h3 id="api-spi-start" tabindex="-1"><code>bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)</code> <a class="header-anchor" href="#api-spi-start" aria-label="Permalink to &quot;`bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)` {#api-spi-start}&quot;"></a></h3><p>Start an SPI transaction.</p><h4 id="api-spi-start-arguments" tabindex="-1">Arguments <a class="header-anchor" href="#api-spi-start-arguments" aria-label="Permalink to &quot;Arguments {#api-spi-start-arguments}&quot;"></a></h4><ul><li><p><code>pin_t slavePin</code><br> The QMK pin to assert as the slave select pin, eg. <code>B4</code>.</p></li><li><p><code>bool lsbFirst</code><br> Determines the endianness of the transmission. If <code>true</code>, the least significant bit of each byte is sent first.</p></li><li><p><code>uint8_t mode</code><br> The SPI mode to use:</p><table><thead><tr><th>Mode</th><th>Clock Polarity</th><th>Clock Phase</th></tr></thead><tbody><tr><td><code>0</code></td><td>Leading edge rising</td><td>Sample on leading edge</td></tr><tr><td><code>1</code></td><td>Leading edge rising</td><td>Sample on trailing edge</td></tr><tr><td><code>2</code></td><td>Leading edge falling</td><td>Sample on leading edge</td></tr><tr><td><code>3</code></td><td>Leading edge falling</td><td>Sample on trailing edge</td></tr></tbody></table></li><li><p><code>uint16_t divisor</code><br> The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU&#39;s clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to <code>2</code>.</p></li></ul><h4 id="api-spi-start-return" tabindex="-1">Return Value <a class="header-anchor" href="#api-spi-start-return" aria-label="Permalink to &quot;Return Value {#api-spi-start-return}&quot;"></a></h4><p><code>false</code> if the supplied parameters are invalid or the SPI peripheral is already in use, or <code>true</code>.</p><hr><h3 id="api-spi-write" tabindex="-1"><code>spi_status_t spi_write(uint8_t data)</code> <a class="header-anchor" href="#api-spi-write" aria-label="Permalink to &quot;`spi_status_t spi_write(uint8_t data)` {#api-spi-write}&quot;"></a></h3><p>Write a byte to the selected SPI device.</p><h4 id="api-spi-write-arguments" tabindex="-1">Arguments <a class="header-anchor" href="#api-spi-write-arguments" aria-label="Permalink to &quot;Arguments {#api-spi-write-arguments}&quot;"></a></h4><ul><li><code>uint8_t data</code><br> The byte to write.</li></ul><h4 id="api-spi-write-return" tabindex="-1">Return Value <a class="header-anchor" href="#api-spi-write-return" aria-label="Permalink to &quot;Return Value {#api-spi-write-return}&quot;"></a></h4><p><code>SPI_STATUS_TIMEOUT</code> if the timeout period elapses, or <code>SPI_STATUS_SUCCESS</code>.</p><hr><h3 id="api-spi-read" tabindex="-1"><code>spi_status_t spi_read(void)</code> <a class="header-anchor" href="#api-spi-read" aria-label="Permalink to &quot;`spi_status_t spi_read(void)` {#api-spi-read}&quot;"></a></h3><p>Read a byte from the selected SPI device.</p><h4 id="api-spi-read-return" tabindex="-1">Return Value <a class="header-anchor" href="#api-spi-read-return" aria-label="Permalink to &quot;Return Value {#api-spi-read-return}&quot;"></a></h4><p><code>SPI_STATUS_TIMEOUT</code> if the timeout period elapses, or the byte read from the device.</p><hr><h3 id="api-spi-transmit" tabindex="-1"><code>spi_status_t spi_transmit(const uint8_t *data, uint16_t length)</code> <a class="header-anchor" href="#api-spi-transmit" aria-label="Permalink to &quot;`spi_status_t spi_transmit(const uint8_t *data, uint16_t length)` {#api-spi-transmit}&quot;"></a></h3><p>Send multiple bytes to the selected SPI device.</p><h4 id="api-spi-transmit-arguments" tabindex="-1">Arguments <a class="header-anchor" href="#api-spi-transmit-arguments" aria-label="Permalink to &quot;Arguments {#api-spi-transmit-arguments}&quot;"></a></h4><ul><li><code>const uint8_t *data</code><br> A pointer to the data to write from.</li><li><code>uint16_t length</code><br> The number of bytes to write. Take care not to overrun the length of <code>data</code>.</li></ul><h4 id="api-spi-transmit-return" tabindex="-1">Return Value <a class="header-anchor" href="#api-spi-transmit-return" aria-label="Permalink to &quot;Return Value {#api-spi-transmit-return}&quot;"></a></h4><p><code>SPI_STATUS_TIMEOUT</code> if the timeout period elapses, <code>SPI_STATUS_ERROR</code> if some other error occurs, otherwise <code>SPI_STATUS_SUCCESS</code>.</p><hr><h3 id="api-spi-receive" tabindex="-1"><code>spi_status_t spi_receive(uint8_t *data, uint16_t length)</code> <a class="header-anchor" href="#api-spi-receive" aria-label="Permalink to &quot;`spi_status_t spi_receive(uint8_t *data, uint16_t length)` {#api-spi-receive}&quot;"></a></h3><p>Receive multiple bytes from the selected SPI device.</p><h4 id="api-spi-receive-arguments" tabindex="-1">Arguments <a class="header-anchor" href="#api-spi-receive-arguments" aria-label="Permalink to &quot;Arguments {#api-spi-receive-arguments}&quot;"></a></h4><ul><li><code>uint8_t *data</code><br> A pointer to the buffer to read into.</li><li><code>uint16_t length</code><br> The number of bytes to read. Take care not to overrun the length of <code>data</code>.</li></ul><h4 id="api-spi-receive-return" tabindex="-1">Return Value <a class="header-anchor" href="#api-spi-receive-return" aria-label="Permalink to &quot;Return Value {#api-spi-receive-return}&quot;"></a></h4><p><code>SPI_STATUS_TIMEOUT</code> if the timeout period elapses, <code>SPI_STATUS_ERROR</code> if some other error occurs, otherwise <code>SPI_STATUS_SUCCESS</code>.</p><hr><h3 id="api-spi-stop" tabindex="-1"><code>void spi_stop(void)</code> <a class="header-anchor" href="#api-spi-stop" aria-label="Permalink to &quot;`void spi_stop(void)` {#api-spi-stop}&quot;"></a></h3><p>End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by <code>spi_start()</code>.</p>', 61);
const _hoisted_62 = [
_hoisted_1
];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", null, _hoisted_62);
}
const spi = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
__pageData,
spi as default
};