Sophie

Sophie

distrib > Fedora > 13 > i386 > media > os > by-pkgid > 73443d16ffe49ffcb4131bf0d8d1b044 > files > 106

avr-libc-docs-1.6.7-2.fc13.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
    <title>avr-libc: Additional notes from &lt;avr/sfr_defs.h&gt;</title>
    <link href="dox.css" rel="stylesheet" type="text/css">
  </head>
<body>
<center>
<table width="80%">
  <tr>
    <td align="left"><a href="http://www.nongnu.org/avr-libc/">AVR Libc Home Page</a></td>
    <td align="center" colspan=4><img src="avrs.png" alt="AVRs" align="middle" border="0"></td>
    <td align="right"><a href="https://savannah.nongnu.org/projects/avr-libc/">AVR Libc Development Pages</a></td>
  </tr>
  <tr>
    <td align="center" width="13%"><a href="index.html">Main Page</a></td>
    <td align="center" width="13%"><a href="pages.html">User Manual</a></td>
    <td align="center" width="13%"><a href="modules.html">Library Reference</a></td>
    <td align="center" width="13%"><a href="FAQ.html">FAQ</a></td>
    <td align="center" width="13%"><a href="globals.html">Alphabetical Index</a></td>
    <td align="center" width="13%"><a href="group__demos.html">Example Projects</a></td>
  </tr>
</table>
</center>
<hr width="80%">
<!-- Generated by Doxygen 1.6.1 -->
<div class="contents">
<h1>Additional notes from &lt;avr/sfr_defs.h&gt;<br/>
<small>
[<a class="el" href="group__avr__sfr.html">&lt;avr/sfr_defs.h&gt;: Special function registers</a>]</small>
</h1><table border="0" cellpadding="0" cellspacing="0">
</table>
<p>The <code>&lt;avr/sfr_defs.h&gt;</code> file is included by all of the <code>&lt;avr/ioXXXX.h&gt;</code> files, which use macros defined here to make the special function register definitions look like C variables or simple constants, depending on the <code>_SFR_ASM_COMPAT</code> define. Some examples from <code>&lt;avr/iocanxx.h&gt;</code> to show how to define such macros:</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#define PORTA   _SFR_IO8(0x02)</span>
<span class="preprocessor"></span><span class="preprocessor">#define EEAR    _SFR_IO16(0x21)</span>
<span class="preprocessor"></span><span class="preprocessor">#define UDR0    _SFR_MEM8(0xC6)</span>
<span class="preprocessor"></span><span class="preprocessor">#define TCNT3   _SFR_MEM16(0x94)</span>
<span class="preprocessor">#define CANIDT  _SFR_MEM32(0xF0)</span>
</pre></div><p>If <code>_SFR_ASM_COMPAT</code> is not defined, C programs can use names like <code>PORTA</code> directly in C expressions (also on the left side of assignment operators) and GCC will do the right thing (use short I/O instructions if possible). The <code>__SFR_OFFSET</code> definition is not used in any way in this case.</p>
<p>Define <code>_SFR_ASM_COMPAT</code> as 1 to make these names work as simple constants (addresses of the I/O registers). This is necessary when included in preprocessed assembler (*.S) source files, so it is done automatically if <code>__ASSEMBLER__</code> is defined. By default, all addresses are defined as if they were memory addresses (used in <code>lds/sts</code> instructions). To use these addresses in <code>in/out</code> instructions, you must subtract 0x20 from them.</p>
<p>For more backwards compatibility, insert the following at the start of your old assembler source file:</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#define __SFR_OFFSET 0</span>
</pre></div><p>This automatically subtracts 0x20 from I/O space addresses, but it's a hack, so it is recommended to change your source: wrap such addresses in macros defined here, as shown below. After this is done, the <code>__SFR_OFFSET</code> definition is no longer necessary and can be removed.</p>
<p>Real example - this code could be used in a boot loader that is portable between devices with <code>SPMCR</code> at different addresses.</p>
<div class="fragment"><pre class="fragment">
&lt;avr/iom163.h&gt;: #define SPMCR _SFR_IO8(0x37)
&lt;avr/iom128.h&gt;: #define SPMCR _SFR_MEM8(0x68)
</pre></div><div class="fragment"><pre class="fragment"><span class="preprocessor">#if _SFR_IO_REG_P(SPMCR)</span>
<span class="preprocessor"></span>        out     _SFR_IO_ADDR(SPMCR), r24
<span class="preprocessor">#else</span>
<span class="preprocessor"></span>        sts     _SFR_MEM_ADDR(SPMCR), r24
<span class="preprocessor">#endif</span>
</pre></div><p>You can use the <code>in/out/cbi/sbi/sbic/sbis</code> instructions, without the <code>_SFR_IO_REG_P</code> test, if you know that the register is in the I/O space (as with <code>SREG</code>, for example). If it isn't, the assembler will complain (I/O address out of range 0...0x3f), so this should be fairly safe.</p>
<p>If you do not define <code>__SFR_OFFSET</code> (so it will be 0x20 by default), all special register addresses are defined as memory addresses (so <code>SREG</code> is 0x5f), and (if code size and speed are not important, and you don't like the ugly #if above) you can always use lds/sts to access them. But, this will not work if <code>__SFR_OFFSET</code> != 0x20, so use a different macro (defined only if <code>__SFR_OFFSET</code> == 0x20) for safety:</p>
<div class="fragment"><pre class="fragment">        sts     _SFR_ADDR(SPMCR), r24
</pre></div><p>In C programs, all 3 combinations of <code>_SFR_ASM_COMPAT</code> and <code>__SFR_OFFSET</code> are supported - the <code>_SFR_ADDR(SPMCR)</code> macro can be used to get the address of the <code>SPMCR</code> register (0x57 or 0x68 depending on device). </p>
</div>

<hr width="80%">
<p><center>Automatically generated by Doxygen 1.6.1 on 30 Nov 2009.</center></p>

</body>
</html>