mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-26 03:49:34 +01:00
143 lines
41 KiB
HTML
143 lines
41 KiB
HTML
|
<!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="<mxfile host="app.diagrams.net" modified="2022-02-15T23:37:14.963Z" agent="5.0 (X11)" etag="_1iMPbCJGwQuwz6QJ5_u" version="16.5.6"><diagram id="GDSX7qAwtoJQx5dvUb6s" name="Page-1">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==</diagram></mxfile>"><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
|
|||
|
don’t 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, it’ll 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, it’s crucial to pick the right trait, to ensure correct operation
|
|||
|
with maximum interoperability. Here are some guidelines depending on the device you’re 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<SPI> {
|
|||
|
spi: SPI,
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl</span><SPI> MyDriver<SPI>
|
|||
|
<span class="kw">where
|
|||
|
</span>SPI: SpiDevice,
|
|||
|
{
|
|||
|
<span class="kw">pub fn </span>new(spi: SPI) -> <span class="self">Self </span>{
|
|||
|
<span class="self">Self </span>{ spi }
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">pub fn </span>read_foo(<span class="kw-2">&mut </span><span class="self">self</span>) -> <span class="prelude-ty">Result</span><[u8; <span class="number">2</span>], MyError<SPI::Error>> {
|
|||
|
<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">&mut </span>[
|
|||
|
Operation::Write(<span class="kw-2">&</span>[<span class="number">0x90</span>]),
|
|||
|
Operation::Read(<span class="kw-2">&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<SPI> {
|
|||
|
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. It’s 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<SPI> {
|
|||
|
spi: SPI,
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl</span><SPI> MyDriver<SPI>
|
|||
|
<span class="kw">where
|
|||
|
</span>SPI: SpiBus,
|
|||
|
{
|
|||
|
<span class="kw">pub fn </span>new(spi: SPI) -> <span class="self">Self </span>{
|
|||
|
<span class="self">Self </span>{ spi }
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">pub fn </span>read_foo(<span class="kw-2">&mut </span><span class="self">self</span>) -> <span class="prelude-ty">Result</span><[u8; <span class="number">2</span>], MyError<SPI::Error>> {
|
|||
|
<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">&</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">&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<SPI> {
|
|||
|
Spi(SPI),
|
|||
|
<span class="comment">// Add other errors for your driver here.
|
|||
|
</span>}</code></pre></div>
|
|||
|
<p>If you’re (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 doesn’t 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. (There’s 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.
|
|||
|
It’s 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 can’t return before receiving all the read data. However it’s 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>
|