rtic/dev/api/imxrt_ral/macro.modify_reg.html

85 lines
9.7 KiB
HTML
Raw 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="Modify a RWRegister or UnsafeRWRegister."><title>modify_reg in imxrt_ral - 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-492a78a4a87dcc01.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="imxrt_ral" data-themes="" data-resource-suffix="" data-rustdoc-version="1.82.0 (f6e511eec 2024-10-15)" data-channel="1.82.0" data-search-js="search-a99f1315e7cc5121.js" data-settings-js="settings-4313503d2e1961c2.js" ><script src="../static.files/storage-118b08c4c78b968e.js"></script><script defer src="sidebar-items.js"></script><script defer src="../static.files/main-921df33f47b8780c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-3b12f09e550e0385.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 macro"><!--[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="../imxrt_ral/index.html">imxrt_<wbr>ral</a><span class="version">0.5.3</span></h2></div><div class="sidebar-elems"></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"><h1>Macro <a href="index.html">imxrt_ral</a>::<wbr><a class="macro" href="#">modify_reg</a><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><span class="out-of-band"><a class="src" href="../src/ral_registers/lib.rs.html#420">source</a> · <button id="toggle-all-docs" title="collapse all docs">[<span>&#x2212;</span>]</button></span></div><pre class="rust item-decl"><span class="macro">macro_rules!</span> modify_reg {
( <span class="macro-nonterminal">$periph</span>:path, <span class="macro-nonterminal">$instance</span>:expr, <span class="macro-nonterminal">$reg</span>:ident $([<span class="macro-nonterminal">$offset</span>:expr])<span class="kw-2">*</span>, $( <span class="macro-nonterminal">$field</span>:ident : <span class="macro-nonterminal">$value</span>:expr ),+ $(,)<span class="question-mark">? </span>) =&gt; { ... };
( <span class="macro-nonterminal">$periph</span>:path, <span class="macro-nonterminal">$instance</span>:expr, <span class="macro-nonterminal">$reg</span>:ident $([<span class="macro-nonterminal">$offset</span>:expr])<span class="kw-2">*</span>, <span class="macro-nonterminal">$</span><span class="kw">fn</span>:<span class="macro-nonterminal">expr </span>) =&gt; { ... };
}</pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Modify a RWRegister or UnsafeRWRegister.</p>
<h2 id="examples"><a class="doc-anchor" href="#examples">§</a>Examples</h2>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// Safely acquire the peripheral instance (will panic if already acquired)
</span><span class="kw">let </span>gpioa = stm32ral::gpio::GPIOA::take().unwrap();
<span class="comment">// Update the register to ensure bit 3 is set.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, ODR, |reg| reg | (<span class="number">1</span>&lt;&lt;<span class="number">3</span>));
<span class="comment">// Write values to specific fields. Unspecified fields are left unchanged.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog);
<span class="comment">// Unsafe access without requiring you to first `take()` the instance
</span><span class="kw">unsafe </span>{ <span class="macro">modify_reg!</span>(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) };</code></pre></div>
<p>To support register arrays, each macro form also supports one or more array indices after the
register. For example, <code>modify_reg!(stm32ral::gpio, gpioa, ODR[2], |reg| reg | (1&lt;&lt;3));</code> sets
a high bit in the third register of an <code>ODR</code> register array.</p>
<h2 id="usage"><a class="doc-anchor" href="#usage">§</a>Usage</h2>
<p>Like <code>write_reg!</code>, this macro can be used in two ways, either with a modification of the entire
register, or by specifying which fields to change and what value to change them to.</p>
<p>In both cases, the first arguments are:</p>
<ul>
<li>the path to the peripheral module: <code>stm32ral::gpio</code>,</li>
<li>a reference to the instance of that peripheral: gpioa (anything which dereferences to
<code>RegisterBlock</code>, such as <code>Instance</code>, <code>&amp;Instance</code>, <code>&amp;RegisterBlock</code>, or
<code>*const RegisterBlock</code>),</li>
<li>the register (and offset, for arrays) you wish you access: <code>MODER</code> (a field on the
<code>RegisterBlock</code>).</li>
</ul>
<p>In the whole-register usage, the final argument is a closure that accepts the current value
of the register and returns the new value to write:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// Turn on PA3 without affecting anything else.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, ODR, |reg| reg | (<span class="number">1</span>&lt;&lt;<span class="number">3</span>));</code></pre></div>
<p>Otherwise, the remaining arguments are <code>Field: Value</code> pairs:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// Set PA3 to Output, PA4 to Analog, and leave everything else unchanged.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, MODER, MODER3: <span class="number">0b01</span>, MODER4: <span class="number">0b11</span>);</code></pre></div>
<p>For fields with annotated values, you can also specify a named value:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// As above, but with named values.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, MODER, MODER3: Output, MODER4: Analog);</code></pre></div>
<p>This macro expands to calling <code>(*instance).register.write(value)</code>.
When called with a closure, <code>(*instance).register.read()</code> is called, the result
passed in to the closure, and the return value of the closure is used for <code>value</code>.
When called with <code>Field: Value</code> arguments, the current value is read and then masked
according to the specified fields, and then ORd with the OR of each field value,
each masked and shifted appropriately for the field. The named values are brought into scope
by <code>use peripheral::register::field::*</code> for each field. The same constants could just be
specified manually:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// As above, but being explicit about named values.
</span><span class="macro">modify_reg!</span>(stm32ral::gpio, gpioa, MODER, MODER3: stm32ral::gpio::MODER::MODER3::RW::Output,
MODER4: stm32ral::gpio::MODER::MODER4::RW::Analog);</code></pre></div>
<p>The fully expanded form is equivalent to:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="comment">// As above, but expanded.
</span>(<span class="kw-2">*</span>gpioa).MODER.write(
(
<span class="comment">// First read the current value...
</span>(<span class="kw-2">*</span>gpioa).MODER.read()
<span class="comment">// Then AND it with an appropriate mask...
</span>&amp;
!( stm32ral::gpio::MODER::MODER3::mask | stm32ral::gpio::MODER::MODER4::mask )
)
<span class="comment">// Then OR with each field value.
</span>|
((stm32ral::gpio::MODER::MODER3::RW::Output &lt;&lt; stm32ral::gpio::MODER::MODER3::offset)
&amp; stm32ral::gpio::MODER::MODER3::mask)
|
((stm32ral::gpio::MODER::MODER4::RW::Analog &lt;&lt; stm32ral::gpio::MODER::MODER3::offset)
&amp; stm32ral::gpio::MODER::MODER3::mask)
);</code></pre></div>
<h2 id="safety"><a class="doc-anchor" href="#safety">§</a>Safety</h2>
<p>This macro will require an unsafe function or block when used with an UnsafeRWRegister,
but not if used with RWRegister.</p>
<p>When run in an unsafe context, peripheral instances are directly accessible without requiring
having called <code>take()</code> beforehand:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">unsafe </span>{ <span class="macro">modify_reg!</span>(stm32ral::gpio, GPIOA, MODER, MODER3: Output, MODER4: Analog) };</code></pre></div>
<p>This works because <code>GPIOA</code> is a <code>*const RegisterBlock</code> in the <code>stm32ral::gpio</code> module;
and the macro brings such constants into scope and then dereferences the provided reference.</p>
</div></details></section></div></main></body></html>