rtic/dev/api/embedded_hal/spi/index.html

143 lines
41 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Blocking SPI master mode traits."><title>embedded_hal::spi - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-46f98efaafac5295.ttf.woff2,FiraSans-Regular-018c141bf0843ffd.woff2,FiraSans-Medium-8f9a781e4970d388.woff2,SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2,SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../../static.files/rustdoc-b0742ba02757f159.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="embedded_hal" data-themes="" data-resource-suffix="" data-rustdoc-version="1.83.0 (90b35a623 2024-11-26)" data-channel="1.83.0" data-search-js="search-f0d225181b97f9a4.js" data-settings-js="settings-805db61a62df4bd2.js" ><script src="../../static.files/storage-1d39b6787ed640ff.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-f070b9041d14864c.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-0111fcff984fae8f.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../embedded_hal/index.html">embedded_<wbr>hal</a><span class="version">1.0.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module spi</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#bus-vs-device" title="Bus vs Device">Bus vs Device</a><ul><li><a href="#bus" title="Bus">Bus</a></li><li><a href="#device" title="Device">Device</a></li></ul></li><li><a href="#for-driver-authors" title="For driver authors">For driver authors</a></li><li><a href="#for-hal-authors" title="For HAL authors">For HAL authors</a></li><li><a href="#flushing" title="Flushing">Flushing</a></li><li><a href="#cs-to-clock-delays" title="CS-to-clock delays">CS-to-clock delays</a></li></ul><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li><li><a href="#constants" title="Constants">Constants</a></li><li><a href="#traits" title="Traits">Traits</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate embedded_<wbr>hal</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><span class="rustdoc-breadcrumbs"><a href="../index.html">embedded_hal</a></span><h1>Module <span>spi</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/embedded_hal/spi.rs.html#1-506">source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Blocking SPI master mode traits.</p>
<h2 id="bus-vs-device"><a class="doc-anchor" href="#bus-vs-device">§</a>Bus vs Device</h2>
<p>SPI allows sharing a single bus between many SPI devices. The SCK, MOSI and MISO lines are
wired in parallel to all the devices, and each device gets a dedicated chip-select (CS) line from the MCU, like this:</p>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<p><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="382px" height="322px" viewBox="-0.5 -0.5 382 322" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-02-15T23:37:14.963Z&quot; agent=&quot;5.0 (X11)&quot; etag=&quot;_1iMPbCJGwQuwz6QJ5_u&quot; version=&quot;16.5.6&quot;&gt;&lt;diagram id=&quot;GDSX7qAwtoJQx5dvUb6s&quot; name=&quot;Page-1&quot;&gt;7Vtdl6I2GP41XupJCCBcrjrTndPuWbu23e3VHkYyyhHBQhy1v74BEiUhKqN8OHX0QvKSz/d58uYJxA4aLre/RM5q/iV0sd/RgLvtoFFH0yDSTfqTWHbMYgOQWWaR5zLbwTDx/sXMyLOtPRfHQkYShj7xVqJxGgYBnhLB5kRRuBGzvYS+2OrKmeGCYTJ1/KL1u+eSeWa1DHCwf8bebM5bhnx8z850MYvCdcDaC8IAZ3eWDq+GZY3njhtucib00EHDKAxJdrXcDrGf+JV7LCv3eOTuvssRDkiZApvFYvxttxqR4I/fH5efzVFsbLoGQ+7V8dfMF6y3ZMedkw4PJ7WADhps5h7Bk5UzTe5uKB+obU6WPk1Bevni+f4w9MMoLYt0I/lSe0yicIH5ndRNaMDaxhHB26OjgntfUf7hcIlJtKNZWAHuXca8LmfU5gAjsphtnoMQ8YIOo85sX/XBh/SCuVHt0qHud8fm6KeGV4vfnp+/x9+8Wdew6nUpSD977xVcpXDoUe/povcUzoOawnnQqM15SOE806ftDlzvNWnR92ZBesP8Z51MnUGU9mufpFez5Hcy/JWXpD1JC2c3CmBQXxHR40qy5mFgJt6ZrAtokDjeo1HlE7MvPddNWlEiLHKgAjD7IphGEUzVRKhiHihDC6wKyS9Pk6/vD8qropoEZb9lKM9MSgbT18nTfcNktwyTXgam4eQnvG+YoGKZaxQnoyRO2p3jhFrGSaWNi2Fv+GdjME2pI3F0HU4vYUAmrFPHJMZbQDNE0DSFhARNgtZXgFaf+r5u72JeKL9RXc5TbV0KjG9SWfv4pf24dGvK2i4Vl5pUzTcJU9uqmU/nG5LNN4lT27IZntmpcj123yi1rpphcRc6GdOpA0YPfz0NH+gFvBPJJUPTuuaCqp3nexFdZuuqC5baEN697NJA2xGo3Ibw7oWXKiA1C5RqE/ihvIpA6W0DVWrDee/SS1MsUc3CVGrHKakxrTHQ3oNGg4rdaLMijVd8SqThwP2UHKdInOo7cexNRWREn+GtR34k1z3btlj67zSNEGLp0TaXebTLJcY48ujIEuAyW0BH+SOfYHVZOjccKktTu3xKri4bG3YLBz8Kb1jjcB1NWa6Tb/SJE80wOeHivpoSOcgNBeLcFmHfId6r2F8VDVgL49CjI9kzDtoi4/oSkbJhskIHLhXqkQ8FyITMvFCoJ+XkftBX0LTE8YnLaAp7ANgCTQ3broympg0/aFqCpvL+y7J7AF3GVNiXqyrFVEodZ5fLtkoyxCd6DKVQDoSDVvQiq7HaaaBacq+bBpy4XdADEIrstXS7XvbeNimhCUWI5aBXOnhKr8MgtHuWZh8+VqPBFJU43ncFi4AuscioOQaeZVH2JOpmaIRsui5UxCRalwHfzKS3BjtoSc3q4GQ35fxaH9YfHI3qpezRVf0SQscUDMJbD2kvue3R83n7/xvS7x/LScvjBcLTFqmk272+Wc+SLvWZ+6Je1qreMx1nLePNWVmbLueSrtUu0bXuRezMy9JbZKd0QNy6lJxn6qmKmFIzGtOB9RJTqzyc7p8MACA+GTCQ9WZqVkjGdrc+ulUJF6G8hWp2h648o1/L6oss42P5PUsqkQzmpaQ6ciqj6gAnP12CV628NHn4B1WW/fAXNfTwHw==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="0" y="0" width="380" height="320" fill="#454545" stroke="none" pointer-events="all"/><rect x="20" y="20" width="120" height="150" fill="#000000" stroke="rgb(240, 240, 240)" pointer-events="all"/><rect x="50" y="60" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 78px; height: 1px; padding-top: 70px; margin-left: 50px;"><div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(240, 240, 240); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div align="right">SCK</div></div></div></div></foreignObject><text x="128" y="74" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="end">SCK</text></switch></g><rect x="50" y="80" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 78px; height: 1px; padding-top: 90px; margin-left: 50px;"><div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(240, 240, 240); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-event
<p>CS is usually active-low. When CS is high (not asserted), SPI devices ignore all incoming data, and
dont drive MISO. When CS is low (asserted), the device is active: reacts to incoming data on MOSI and
drives MISO with the response data. By asserting one CS or another, the MCU can choose to which
SPI device it “talks” to on the (possibly shared) bus.</p>
<p>This bus sharing is common when having multiple SPI devices in the same board, since it uses fewer MCU
pins (<code>n+3</code> instead of <code>4*n</code>), and fewer MCU SPI peripherals (<code>1</code> instead of <code>n</code>).</p>
<p>However, it poses a challenge when building portable drivers for SPI devices. The driver needs to
be able to talk to its device on the bus, while not interfering with other drivers talking to other
devices.</p>
<p>To solve this, <code>embedded-hal</code> has two kinds of SPI traits: <strong>SPI bus</strong> and <strong>SPI device</strong>.</p>
<h3 id="bus"><a class="doc-anchor" href="#bus">§</a>Bus</h3>
<p>The <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> trait represents <strong>exclusive ownership</strong> over the whole SPI bus. This is usually the entire
SPI MCU peripheral, plus the SCK, MOSI and MISO pins.</p>
<p>Owning an instance of an SPI bus guarantees exclusive access, this is, we have the guarantee no other
piece of code will try to use the bus while we own it.</p>
<h3 id="device"><a class="doc-anchor" href="#device">§</a>Device</h3>
<p>The <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> trait represents <strong>ownership over a single SPI device selected by a CS pin</strong> in a (possibly shared) bus. This is typically:</p>
<ul>
<li>Exclusive ownership of the <strong>CS pin</strong>.</li>
<li>Access to the <strong>underlying SPI bus</strong>. If shared, itll be behind some kind of lock/mutex.</li>
</ul>
<p>An <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> allows initiating <a href="trait.SpiDevice.html#tymethod.transaction" title="method embedded_hal::spi::SpiDevice::transaction">transactions</a> against the target device on the bus. A transaction
consists of asserting CS, then doing one or more transfers, then deasserting CS. For the entire duration of the transaction, the <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a>
implementation will ensure no other transaction can be opened on the same bus. This is the key that allows correct sharing of the bus.</p>
<h2 id="for-driver-authors"><a class="doc-anchor" href="#for-driver-authors">§</a>For driver authors</h2>
<p>When implementing a driver, its crucial to pick the right trait, to ensure correct operation
with maximum interoperability. Here are some guidelines depending on the device youre implementing a driver for:</p>
<p>If your device <strong>has a CS pin</strong>, use <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a>. Do not manually
manage the CS pin, the <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> implementation will do it for you.
By using <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a>, your driver will cooperate nicely with other drivers for other devices in the same shared SPI bus.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">pub struct </span>MyDriver&lt;SPI&gt; {
spi: SPI,
}
<span class="kw">impl</span>&lt;SPI&gt; MyDriver&lt;SPI&gt;
<span class="kw">where
</span>SPI: SpiDevice,
{
<span class="kw">pub fn </span>new(spi: SPI) -&gt; <span class="self">Self </span>{
<span class="self">Self </span>{ spi }
}
<span class="kw">pub fn </span>read_foo(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;[u8; <span class="number">2</span>], MyError&lt;SPI::Error&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>buf = [<span class="number">0</span>; <span class="number">2</span>];
<span class="comment">// `transaction` asserts and deasserts CS for us. No need to do it manually!
</span><span class="self">self</span>.spi.transaction(<span class="kw-2">&amp;mut </span>[
Operation::Write(<span class="kw-2">&amp;</span>[<span class="number">0x90</span>]),
Operation::Read(<span class="kw-2">&amp;mut </span>buf),
]).map_err(MyError::Spi)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(buf)
}
}
<span class="attr">#[derive(Copy, Clone, Debug)]
</span><span class="kw">enum </span>MyError&lt;SPI&gt; {
Spi(SPI),
<span class="comment">// Add other errors for your driver here.
</span>}</code></pre></div>
<p>If your device <strong>does not have a CS pin</strong>, use <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a>. This will ensure
your driver has exclusive access to the bus, so no other drivers can interfere. Its not possible to safely share
a bus without CS pins. By requiring <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> you disallow sharing, ensuring correct operation.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">pub struct </span>MyDriver&lt;SPI&gt; {
spi: SPI,
}
<span class="kw">impl</span>&lt;SPI&gt; MyDriver&lt;SPI&gt;
<span class="kw">where
</span>SPI: SpiBus,
{
<span class="kw">pub fn </span>new(spi: SPI) -&gt; <span class="self">Self </span>{
<span class="self">Self </span>{ spi }
}
<span class="kw">pub fn </span>read_foo(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;[u8; <span class="number">2</span>], MyError&lt;SPI::Error&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>buf = [<span class="number">0</span>; <span class="number">2</span>];
<span class="self">self</span>.spi.write(<span class="kw-2">&amp;</span>[<span class="number">0x90</span>]).map_err(MyError::Spi)<span class="question-mark">?</span>;
<span class="self">self</span>.spi.read(<span class="kw-2">&amp;mut </span>buf).map_err(MyError::Spi)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(buf)
}
}
<span class="attr">#[derive(Copy, Clone, Debug)]
</span><span class="kw">enum </span>MyError&lt;SPI&gt; {
Spi(SPI),
<span class="comment">// Add other errors for your driver here.
</span>}</code></pre></div>
<p>If youre (ab)using SPI to <strong>implement other protocols</strong> by bitbanging (WS2812B, onewire, generating arbitrary waveforms…), use <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a>.
SPI bus sharing doesnt make sense at all in this case. By requiring <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> you disallow sharing, ensuring correct operation.</p>
<h2 id="for-hal-authors"><a class="doc-anchor" href="#for-hal-authors">§</a>For HAL authors</h2>
<p>HALs <strong>must</strong> implement <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a>. Users can combine the bus together with the CS pin (which should
implement <a href="../digital/trait.OutputPin.html" title="trait embedded_hal::digital::OutputPin"><code>OutputPin</code></a>) using HAL-independent <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> implementations such as the ones in <a href="https://crates.io/crates/embedded-hal-bus"><code>embedded-hal-bus</code></a>.</p>
<p>HALs may additionally implement <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> to <strong>take advantage of hardware CS management</strong>, which may provide some performance
benefits. (Theres no point in a HAL implementing <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a> if the CS management is software-only, this task is better left to
the HAL-independent implementations).</p>
<p>HALs <strong>must not</strong> add infrastructure for sharing at the <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> level. User code owning a <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> must have the guarantee
of exclusive access.</p>
<h2 id="flushing"><a class="doc-anchor" href="#flushing">§</a>Flushing</h2>
<p>To improve performance, <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a> implementations are allowed to return before the operation is finished, i.e. when the bus is still not
idle. This allows pipelining SPI transfers with CPU work.</p>
<p>When calling another method when a previous operation is still in progress, implementations can either wait for the previous operation
to finish, or enqueue the new one, but they must not return a “busy” error. Users must be able to do multiple method calls in a row
and have them executed “as if” they were done sequentially, without having to check for “busy” errors.</p>
<p>When using a <a href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus"><code>SpiBus</code></a>, call <a href="trait.SpiBus.html#tymethod.flush" title="method embedded_hal::spi::SpiBus::flush"><code>flush</code></a> to wait for operations to actually finish. Examples of situations
where this is needed are:</p>
<ul>
<li>To synchronize SPI activity and GPIO activity, for example before deasserting a CS pin.</li>
<li>Before deinitializing the hardware SPI peripheral.</li>
</ul>
<p>When using a <a href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice"><code>SpiDevice</code></a>, you can still call <a href="trait.SpiBus.html#tymethod.flush" title="method embedded_hal::spi::SpiBus::flush"><code>flush</code></a> on the bus within a transaction.
Its very rarely needed, because <a href="trait.SpiDevice.html#tymethod.transaction" title="method embedded_hal::spi::SpiDevice::transaction"><code>transaction</code></a> already flushes for you
before deasserting CS. For example, you may need it to synchronize with GPIOs other than CS, such as DCX pins
sometimes found in SPI displays.</p>
<p>For example, for <a href="trait.SpiBus.html#tymethod.write" title="method embedded_hal::spi::SpiBus::write"><code>write</code></a> operations, it is common for hardware SPI peripherals to have a small
FIFO buffer, usually 1-4 bytes. Software writes data to the FIFO, and the peripheral sends it on MOSI at its own pace,
at the specified SPI frequency. It is allowed for an implementation of <a href="trait.SpiBus.html#tymethod.write" title="method embedded_hal::spi::SpiBus::write"><code>write</code></a> to return as soon
as all the data has been written to the FIFO, before it is actually sent. Calling <a href="trait.SpiBus.html#tymethod.flush" title="method embedded_hal::spi::SpiBus::flush"><code>flush</code></a> would
wait until all the bits have actually been sent, the FIFO is empty, and the bus is idle.</p>
<p>This still applies to other operations such as <a href="trait.SpiBus.html#tymethod.read" title="method embedded_hal::spi::SpiBus::read"><code>read</code></a> or <a href="trait.SpiBus.html#tymethod.transfer" title="method embedded_hal::spi::SpiBus::transfer"><code>transfer</code></a>. It is less obvious
why, because these methods cant return before receiving all the read data. However its still technically possible
for them to return before the bus is idle. For example, assuming SPI mode 0, the last bit is sampled on the first (rising) edge
of SCK, at which point a method could return, but the second (falling) SCK edge still has to happen before the bus is idle.</p>
<h2 id="cs-to-clock-delays"><a class="doc-anchor" href="#cs-to-clock-delays">§</a>CS-to-clock delays</h2>
<p>Many chips require a minimum delay between asserting CS and the first SCK edge, and the last SCK edge and deasserting CS.
Drivers should <em>NOT</em> use <a href="enum.Operation.html#variant.DelayNs" title="variant embedded_hal::spi::Operation::DelayNs"><code>Operation::DelayNs</code></a> for this, they should instead document that the user should configure the
delays when creating the <code>SpiDevice</code> instance, same as they have to configure the SPI frequency and mode. This has a few advantages:</p>
<ul>
<li>Allows implementations that use hardware-managed CS to program the delay in hardware</li>
<li>Allows the end user more flexibility. For example, they can choose to not configure any delay if their MCU is slow
enough to “naturally” do the delay (very common if the delay is in the order of nanoseconds).</li>
</ul>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.Mode.html" title="struct embedded_hal::spi::Mode">Mode</a></div><div class="desc docblock-short">SPI mode.</div></li></ul><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="enum" href="enum.ErrorKind.html" title="enum embedded_hal::spi::ErrorKind">Error<wbr>Kind</a></div><div class="desc docblock-short">SPI error kind.</div></li><li><div class="item-name"><a class="enum" href="enum.Operation.html" title="enum embedded_hal::spi::Operation">Operation</a></div><div class="desc docblock-short">SPI transaction operation.</div></li><li><div class="item-name"><a class="enum" href="enum.Phase.html" title="enum embedded_hal::spi::Phase">Phase</a></div><div class="desc docblock-short">Clock phase.</div></li><li><div class="item-name"><a class="enum" href="enum.Polarity.html" title="enum embedded_hal::spi::Polarity">Polarity</a></div><div class="desc docblock-short">Clock polarity.</div></li></ul><h2 id="constants" class="section-header">Constants<a href="#constants" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="constant" href="constant.MODE_0.html" title="constant embedded_hal::spi::MODE_0">MODE_0</a></div><div class="desc docblock-short">Helper for CPOL = 0, CPHA = 0.</div></li><li><div class="item-name"><a class="constant" href="constant.MODE_1.html" title="constant embedded_hal::spi::MODE_1">MODE_1</a></div><div class="desc docblock-short">Helper for CPOL = 0, CPHA = 1.</div></li><li><div class="item-name"><a class="constant" href="constant.MODE_2.html" title="constant embedded_hal::spi::MODE_2">MODE_2</a></div><div class="desc docblock-short">Helper for CPOL = 1, CPHA = 0.</div></li><li><div class="item-name"><a class="constant" href="constant.MODE_3.html" title="constant embedded_hal::spi::MODE_3">MODE_3</a></div><div class="desc docblock-short">Helper for CPOL = 1, CPHA = 1.</div></li></ul><h2 id="traits" class="section-header">Traits<a href="#traits" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="trait" href="trait.Error.html" title="trait embedded_hal::spi::Error">Error</a></div><div class="desc docblock-short">SPI error.</div></li><li><div class="item-name"><a class="trait" href="trait.ErrorType.html" title="trait embedded_hal::spi::ErrorType">Error<wbr>Type</a></div><div class="desc docblock-short">SPI error type trait.</div></li><li><div class="item-name"><a class="trait" href="trait.SpiBus.html" title="trait embedded_hal::spi::SpiBus">SpiBus</a></div><div class="desc docblock-short">SPI bus.</div></li><li><div class="item-name"><a class="trait" href="trait.SpiDevice.html" title="trait embedded_hal::spi::SpiDevice">SpiDevice</a></div><div class="desc docblock-short">SPI device trait.</div></li></ul></section></div></main></body></html>