mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-11 20:57:16 +01:00
132 lines
28 KiB
HTML
132 lines
28 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 I2C API."><title>embedded_hal::i2c - 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 i2c</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#bus-sharing" title="Bus sharing">Bus sharing</a></li><li><a href="#flushing" title="Flushing">Flushing</a></li><li><a href="#for-driver-authors" title="For driver authors">For driver authors</a><ul><li><a href="#device-driver-compatible-only-with-7-bit-addresses" title="Device driver compatible only with 7-bit addresses">Device driver compatible only with 7-bit addresses</a></li><li><a href="#device-driver-compatible-only-with-10-bit-addresses" title="Device driver compatible only with 10-bit addresses">Device driver compatible only with 10-bit addresses</a></li></ul></li><li><a href="#for-hal-authors" title="For HAL authors">For HAL authors</a></li></ul><h3><a href="#enums">Module Items</a></h3><ul class="block"><li><a href="#enums" title="Enums">Enums</a></li><li><a href="#traits" title="Traits">Traits</a></li><li><a href="#types" title="Type Aliases">Type Aliases</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>i2c</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/i2c.rs.html#1-432">source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Blocking I2C API.</p>
|
|||
|
<p>This API supports 7-bit and 10-bit addresses. Traits feature an <a href="trait.AddressMode.html" title="trait embedded_hal::i2c::AddressMode"><code>AddressMode</code></a>
|
|||
|
marker type parameter. Two implementation of the <a href="trait.AddressMode.html" title="trait embedded_hal::i2c::AddressMode"><code>AddressMode</code></a> exist:
|
|||
|
<a href="type.SevenBitAddress.html" title="type embedded_hal::i2c::SevenBitAddress"><code>SevenBitAddress</code></a> and <a href="type.TenBitAddress.html" title="type embedded_hal::i2c::TenBitAddress"><code>TenBitAddress</code></a>.</p>
|
|||
|
<p>Through this marker types it is possible to implement each address mode for
|
|||
|
the traits independently in <code>embedded-hal</code> implementations and device drivers
|
|||
|
can depend only on the mode that they support.</p>
|
|||
|
<p>Additionally, the I2C 10-bit address mode has been developed to be fully
|
|||
|
backwards compatible with the 7-bit address mode. This allows for a
|
|||
|
software-emulated 10-bit addressing implementation if the address mode
|
|||
|
is not supported by the hardware.</p>
|
|||
|
<p>Since 7-bit addressing is the mode of the majority of I2C devices,
|
|||
|
<a href="type.SevenBitAddress.html" title="type embedded_hal::i2c::SevenBitAddress"><code>SevenBitAddress</code></a> has been set as default mode and thus can be omitted if desired.</p>
|
|||
|
<h2 id="bus-sharing"><a class="doc-anchor" href="#bus-sharing">§</a>Bus sharing</h2>
|
|||
|
<p>I2C allows sharing a single bus between many I2C devices. The SDA and SCL lines are
|
|||
|
wired in parallel to all devices. When starting a transfer an “address” is sent
|
|||
|
so that the addressed device can respond and all the others can ignore the transfer.</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" style="background-color: rgb(42, 42, 42);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="381px" height="242px" viewBox="-0.5 -0.5 381 242" content="<mxfile host="app.diagrams.net" modified="2022-07-26T11:32:28.668Z" agent="5.0 (X11)" etag="ttHSAAff0ktqe0i_JMaC" version="16.5.6" type="device"><diagram id="GDSX7qAwtoJQx5dvUb6s" name="Page-1">7Vldd5owAP01PrpDQD58bMHaru2Zq+u6Pe1QiZCJhIVYdb9+QYJ8JKXWarXHdef0JDchJPfe3mShpdnTRZ+4cXCLPRi2VMVbtDSnpaqmpbPfKbDMAKAbZob4BHkcK4Ah+gs5qHB0hjyYVDpSjEOK4io4wlEER7SCuYTgebXbGIfVt8auDwVgOHJDEX1AHg0y1NKVAr+EyA/yNwOFtzy6o4lP8Czi74twBLOWqZsPw7smgevheQnSei3NJhjTrDRd2DBMac0Zy567eKZ1PWUCI7rJA/PJZHC3jB0afft6Mb00nESft3UjG+bJDWecCz5buszJWS0PpqMoLe18HiAKh7E7SlvnzA4MC+g0ZDXAimMUhjYOMVk9q3X09B/DE0rwBOYtK5q0c3EJfFVPkFC4KEF8SX2Ip5CSJevCW3N2ufPauaPmhYyaxbGgJKHa4aDLreOvhy44ZAVOo5xSuxO2B4bzS4Xx5Obx8SG5Q35bt/ZLqbL62Q17nSp7EvKAKiEP6HsjTxPIGzpnAn9sebRKktRfZeY45IbIj1iVZKs5T7lCLAjOOD5Fnpe+RSpKVbYd8G9W+ddF/qXe3QH70jQAIvn2zamQbx6YfFkSG2FKk4eeWNFPi7f2fY6yl5Qa9qDSiFELydtkGuOIDvmkJDvWqzXTq5qpksBS3lM08+NkvWpsF/bdfXEn7pP7ifoQjg8fNscW9d13ivqjJP/QUQ/EU44k669UNrri9L5f2T1WACcd/HUJD578oPOBo1/G3rtmP9BPOfyBcegAEg+bJxT/wDo0/eLu+3L+q//zv6yhdugNIB+4aQOAkXeWXk8WHJdkqRIGF4j+SMuful2L13+u6pqm8bqzKHV2lqXKABLElpWqlmGRd4HS9TT/DSV4RkZ8ro2XWdCrXKCKMpVk0CUq5BiBoUvRU/XaVSYNf8MAIzbltQtAV36Qy0fI1sMfUkt3obVx6huiURuHusSHVBhn5ZP1ore3ji5etDRZB7N+jdZZiw3KRqqYyDStV5toI9s0Ho6OxDbC+ceytvRN7brZ2sw3TEh3WeoWpx2ShvnWXpPbvrBhNuJuTanuNs82S6AjdUhd2E0NAl4YZ9/BIvuP5fYaJmy6tJZCK6wcNx9L505z8G+7gYD6TrSrJKh/oTF3mwTXi27/yx+7/9kY3s/uZveOcw3amugZpl5+msOEBtjHkRv2CrRmnKLPDcYxd8pvSOmSf/t1ZxRXnVecf/TSxgWaNy3ByjI31qz3toNQpuuLHUV/b2zcZw6lrFp8K86ULr7Fa71/</diagram></mxfile>"><defs/><g><rect x="0" y="0" width="380" height="240" 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;">SDA</div></div></div></foreignObject><text x="128" y="74" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="end">SDA</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-events: all; white-space: normal; overflow-wrap: normal;">SCL</div></div></div></foreignObject><text x="128" y="94" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="end">SCL</text></switch></g><rect x="30" y="30" width="100" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="trans
|
|||
|
<p>This bus sharing is common when having multiple I2C devices in the same board, since it uses fewer MCU
|
|||
|
pins (<code>2</code> instead of <code>2*n</code>), and fewer MCU I2C peripherals (<code>1</code> instead of <code>n</code>).</p>
|
|||
|
<p>This API supports bus sharing natively. Types implementing <a href="trait.I2c.html" title="trait embedded_hal::i2c::I2c"><code>I2c</code></a> are allowed
|
|||
|
to represent either exclusive or shared access to an I2C bus. HALs typically
|
|||
|
provide exclusive access implementations. Drivers shouldn’t care which
|
|||
|
kind they receive, they just do transactions on it and let the
|
|||
|
underlying implementation share or not.</p>
|
|||
|
<p>The <a href="https://docs.rs/embedded-hal-bus"><code>embedded-hal-bus</code></a> crate provides several
|
|||
|
implementations for sharing I2C buses. You can use them to take an exclusive instance
|
|||
|
you’ve received from a HAL and “split” it into multiple shared ones, to instantiate
|
|||
|
several drivers on the same bus.</p>
|
|||
|
<h2 id="flushing"><a class="doc-anchor" href="#flushing">§</a>Flushing</h2>
|
|||
|
<p>Implementations must flush the transfer, ensuring the bus has returned to an idle state before returning.
|
|||
|
No pipelining is allowed. Users must be able to shut down the I2C peripheral immediately after a transfer
|
|||
|
returns, without any risk of e.g. cutting short a stop condition.</p>
|
|||
|
<p>(Implementations must wait until the last ACK bit to report it as an error anyway. Therefore pipelining would only
|
|||
|
yield very small time savings, not worth the complexity)</p>
|
|||
|
<h2 id="for-driver-authors"><a class="doc-anchor" href="#for-driver-authors">§</a>For driver authors</h2>
|
|||
|
<p>Drivers can select the adequate address length with <code>I2c<SevenBitAddress></code> or <code>I2c<TenBitAddress></code> depending
|
|||
|
on the target device. If it can use either, the driver can
|
|||
|
be generic over the address kind as well, though this is rare.</p>
|
|||
|
<p>Drivers should take the <code>I2c</code> instance as an argument to <code>new()</code>, and store it in their
|
|||
|
struct. They <strong>should not</strong> take <code>&mut I2c</code>, the trait has a blanket impl for all <code>&mut T</code>
|
|||
|
so taking just <code>I2c</code> ensures the user can still pass a <code>&mut</code>, but is not forced to.</p>
|
|||
|
<p>Drivers <strong>should not</strong> try to enable bus sharing by taking <code>&mut I2c</code> at every method.
|
|||
|
This is much less ergonomic than owning the <code>I2c</code>, which still allows the user to pass an
|
|||
|
implementation that does sharing behind the scenes
|
|||
|
(from <a href="https://docs.rs/embedded-hal-bus"><code>embedded-hal-bus</code></a>, or others).</p>
|
|||
|
<h3 id="device-driver-compatible-only-with-7-bit-addresses"><a class="doc-anchor" href="#device-driver-compatible-only-with-7-bit-addresses">§</a>Device driver compatible only with 7-bit addresses</h3>
|
|||
|
<p>For demonstration purposes the address mode parameter has been omitted in this example.</p>
|
|||
|
|
|||
|
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>embedded_hal::i2c::{I2c, Error};
|
|||
|
|
|||
|
<span class="kw">const </span>ADDR: u8 = <span class="number">0x15</span>;
|
|||
|
<span class="kw">pub struct </span>TemperatureSensorDriver<I2C> {
|
|||
|
i2c: I2C,
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl</span><I2C: I2c> TemperatureSensorDriver<I2C> {
|
|||
|
<span class="kw">pub fn </span>new(i2c: I2C) -> <span class="self">Self </span>{
|
|||
|
<span class="self">Self </span>{ i2c }
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">pub fn </span>read_temperature(<span class="kw-2">&mut </span><span class="self">self</span>) -> <span class="prelude-ty">Result</span><u8, I2C::Error> {
|
|||
|
<span class="kw">let </span><span class="kw-2">mut </span>temp = [<span class="number">0</span>];
|
|||
|
<span class="self">self</span>.i2c.write_read(ADDR, <span class="kw-2">&</span>[TEMP_REGISTER], <span class="kw-2">&mut </span>temp)<span class="question-mark">?</span>;
|
|||
|
<span class="prelude-val">Ok</span>(temp[<span class="number">0</span>])
|
|||
|
}
|
|||
|
}</code></pre></div>
|
|||
|
<h3 id="device-driver-compatible-only-with-10-bit-addresses"><a class="doc-anchor" href="#device-driver-compatible-only-with-10-bit-addresses">§</a>Device driver compatible only with 10-bit addresses</h3>
|
|||
|
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>embedded_hal::i2c::{Error, TenBitAddress, I2c};
|
|||
|
|
|||
|
<span class="kw">const </span>ADDR: u16 = <span class="number">0x158</span>;
|
|||
|
<span class="kw">pub struct </span>TemperatureSensorDriver<I2C> {
|
|||
|
i2c: I2C,
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl</span><I2C: I2c<TenBitAddress>> TemperatureSensorDriver<I2C> {
|
|||
|
<span class="kw">pub fn </span>new(i2c: I2C) -> <span class="self">Self </span>{
|
|||
|
<span class="self">Self </span>{ i2c }
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">pub fn </span>read_temperature(<span class="kw-2">&mut </span><span class="self">self</span>) -> <span class="prelude-ty">Result</span><u8, I2C::Error> {
|
|||
|
<span class="kw">let </span><span class="kw-2">mut </span>temp = [<span class="number">0</span>];
|
|||
|
<span class="self">self</span>.i2c.write_read(ADDR, <span class="kw-2">&</span>[TEMP_REGISTER], <span class="kw-2">&mut </span>temp)<span class="question-mark">?</span>;
|
|||
|
<span class="prelude-val">Ok</span>(temp[<span class="number">0</span>])
|
|||
|
}
|
|||
|
}</code></pre></div>
|
|||
|
<h2 id="for-hal-authors"><a class="doc-anchor" href="#for-hal-authors">§</a>For HAL authors</h2>
|
|||
|
<p>HALs <strong>should not</strong> include bus sharing mechanisms. They should expose a single type representing
|
|||
|
exclusive ownership over the bus, and let the user use <a href="https://docs.rs/embedded-hal-bus"><code>embedded-hal-bus</code></a>
|
|||
|
if they want to share it. (One exception is if the underlying platform already
|
|||
|
supports sharing, such as Linux or some RTOSs.)</p>
|
|||
|
<p>Here is an example of an embedded-hal implementation of the <code>I2C</code> trait
|
|||
|
for both addressing modes. All trait methods have have default implementations in terms of <code>transaction</code>.
|
|||
|
As such, that is the only method that requires implementation in the HAL.</p>
|
|||
|
|
|||
|
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>embedded_hal::i2c::{<span class="self">self</span>, SevenBitAddress, TenBitAddress, I2c, Operation};
|
|||
|
|
|||
|
<span class="doccomment">/// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
|
|||
|
</span><span class="kw">pub struct </span>I2c0;
|
|||
|
|
|||
|
<span class="attr">#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|||
|
</span><span class="kw">pub enum </span>Error {
|
|||
|
<span class="comment">// ...
|
|||
|
</span>}
|
|||
|
|
|||
|
<span class="kw">impl </span>i2c::Error <span class="kw">for </span>Error {
|
|||
|
<span class="kw">fn </span>kind(<span class="kw-2">&</span><span class="self">self</span>) -> i2c::ErrorKind {
|
|||
|
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
|
|||
|
<span class="comment">// ...
|
|||
|
</span>}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl </span>i2c::ErrorType <span class="kw">for </span>I2c0 {
|
|||
|
<span class="kw">type </span>Error = Error;
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl </span>I2c<SevenBitAddress> <span class="kw">for </span>I2c0 {
|
|||
|
<span class="kw">fn </span>transaction(<span class="kw-2">&mut </span><span class="self">self</span>, address: u8, operations: <span class="kw-2">&mut </span>[Operation<<span class="lifetime">'_</span>>]) -> <span class="prelude-ty">Result</span><(), <span class="self">Self</span>::Error> {
|
|||
|
<span class="comment">// ...
|
|||
|
</span>}
|
|||
|
}
|
|||
|
|
|||
|
<span class="kw">impl </span>I2c<TenBitAddress> <span class="kw">for </span>I2c0 {
|
|||
|
<span class="kw">fn </span>transaction(<span class="kw-2">&mut </span><span class="self">self</span>, address: u16, operations: <span class="kw-2">&mut </span>[Operation<<span class="lifetime">'_</span>>]) -> <span class="prelude-ty">Result</span><(), <span class="self">Self</span>::Error> {
|
|||
|
<span class="comment">// ...
|
|||
|
</span>}
|
|||
|
}</code></pre></div>
|
|||
|
</div></details><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::i2c::ErrorKind">Error<wbr>Kind</a></div><div class="desc docblock-short">I2C error kind.</div></li><li><div class="item-name"><a class="enum" href="enum.NoAcknowledgeSource.html" title="enum embedded_hal::i2c::NoAcknowledgeSource">NoAcknowledge<wbr>Source</a></div><div class="desc docblock-short">I2C no acknowledge error source.</div></li><li><div class="item-name"><a class="enum" href="enum.Operation.html" title="enum embedded_hal::i2c::Operation">Operation</a></div><div class="desc docblock-short">I2C operation.</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.AddressMode.html" title="trait embedded_hal::i2c::AddressMode">Address<wbr>Mode</a></div><div class="desc docblock-short">Address mode (7-bit / 10-bit).</div></li><li><div class="item-name"><a class="trait" href="trait.Error.html" title="trait embedded_hal::i2c::Error">Error</a></div><div class="desc docblock-short">I2C error.</div></li><li><div class="item-name"><a class="trait" href="trait.ErrorType.html" title="trait embedded_hal::i2c::ErrorType">Error<wbr>Type</a></div><div class="desc docblock-short">I2C error type trait.</div></li><li><div class="item-name"><a class="trait" href="trait.I2c.html" title="trait embedded_hal::i2c::I2c">I2c</a></div><div class="desc docblock-short">Blocking I2C.</div></li></ul><h2 id="types" class="section-header">Type Aliases<a href="#types" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="type" href="type.SevenBitAddress.html" title="type embedded_hal::i2c::SevenBitAddress">Seven<wbr>BitAddress</a></div><div class="desc docblock-short">7-bit address mode type.</div></li><li><div class="item-name"><a class="type" href="type.TenBitAddress.html" title="type embedded_hal::i2c::TenBitAddress">TenBit<wbr>Address</a></div><div class="desc docblock-short">10-bit address mode type.</div></li></ul></section></div></main></body></html>
|