avr-libc  2.0.0 Standard C library for AVR-GCC
sfr_defs.h
1 /* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl>
3
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions are met:
6
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in
12  the documentation and/or other materials provided with the
13  distribution.
14
15  * Neither the name of the copyright holders nor the names of
16  contributors may be used to endorse or promote products derived
17  from this software without specific prior written permission.
18
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  POSSIBILITY OF SUCH DAMAGE. */
30
31 /* avr/sfr_defs.h - macros for accessing AVR special function registers */
32
33 /* $Id: sfr__defs_8h_source.html,v 1.1.1.6 2016/02/09 07:13:56 joerg_wunsch Exp$ */
34
35 #ifndef _AVR_SFR_DEFS_H_
36 #define _AVR_SFR_DEFS_H_ 1
37
38 /** \defgroup avr_sfr_notes Additional notes from <avr/sfr_defs.h>
39  \ingroup avr_sfr
40
41  The \c <avr/sfr_defs.h> file is included by all of the \c <avr/ioXXXX.h>
42  files, which use macros defined here to make the special function register
43  definitions look like C variables or simple constants, depending on the
44  <tt>_SFR_ASM_COMPAT</tt> define. Some examples from \c <avr/iocanxx.h> to
45  show how to define such macros:
46
47 \code
48 #define PORTA _SFR_IO8(0x02)
49 #define EEAR _SFR_IO16(0x21)
50 #define UDR0 _SFR_MEM8(0xC6)
51 #define TCNT3 _SFR_MEM16(0x94)
52 #define CANIDT _SFR_MEM32(0xF0)
53 \endcode
54
55  If \c _SFR_ASM_COMPAT is not defined, C programs can use names like
56  <tt>PORTA</tt> directly in C expressions (also on the left side of
57  assignment operators) and GCC will do the right thing (use short I/O
58  instructions if possible). The \c __SFR_OFFSET definition is not used in
59  any way in this case.
60
61  Define \c _SFR_ASM_COMPAT as 1 to make these names work as simple constants
62  (addresses of the I/O registers). This is necessary when included in
63  preprocessed assembler (*.S) source files, so it is done automatically if
64  \c __ASSEMBLER__ is defined. By default, all addresses are defined as if
65  they were memory addresses (used in \c lds/sts instructions). To use these
66  addresses in \c in/out instructions, you must subtract 0x20 from them.
67
68  For more backwards compatibility, insert the following at the start of your
69  old assembler source file:
70
71 \code
72 #define __SFR_OFFSET 0
73 \endcode
74
75  This automatically subtracts 0x20 from I/O space addresses, but it's a
76  hack, so it is recommended to change your source: wrap such addresses in
77  macros defined here, as shown below. After this is done, the
78  <tt>__SFR_OFFSET</tt> definition is no longer necessary and can be removed.
79
80  Real example - this code could be used in a boot loader that is portable
81  between devices with \c SPMCR at different addresses.
82
83 \verbatim
84 <avr/iom163.h>: #define SPMCR _SFR_IO8(0x37)
85 <avr/iom128.h>: #define SPMCR _SFR_MEM8(0x68)
86 \endverbatim
87
88 \code
89 #if _SFR_IO_REG_P(SPMCR)
91 #else
93 #endif
94 \endcode
95
96  You can use the \c in/out/cbi/sbi/sbic/sbis instructions, without the
97  <tt>_SFR_IO_REG_P</tt> test, if you know that the register is in the I/O
98  space (as with \c SREG, for example). If it isn't, the assembler will
99  complain (I/O address out of range 0...0x3f), so this should be fairly
100  safe.
101
102  If you do not define \c __SFR_OFFSET (so it will be 0x20 by default), all
103  special register addresses are defined as memory addresses (so \c SREG is
104  0x5f), and (if code size and speed are not important, and you don't like
105  the ugly \#if above) you can always use lds/sts to access them. But, this
106  will not work if <tt>__SFR_OFFSET</tt> != 0x20, so use a different macro
107  (defined only if <tt>__SFR_OFFSET</tt> == 0x20) for safety:
108
109 \code
111 \endcode
112
113  In C programs, all 3 combinations of \c _SFR_ASM_COMPAT and
114  <tt>__SFR_OFFSET</tt> are supported - the \c _SFR_ADDR(SPMCR) macro can be
115  used to get the address of the \c SPMCR register (0x57 or 0x68 depending on
116  device). */
117
118 #ifdef __ASSEMBLER__
119 #define _SFR_ASM_COMPAT 1
120 #elif !defined(_SFR_ASM_COMPAT)
121 #define _SFR_ASM_COMPAT 0
122 #endif
123
124 #ifndef __ASSEMBLER__
125 /* These only work in C programs. */
126 #include <inttypes.h>
127
131 #endif
132
133 #if _SFR_ASM_COMPAT
134
135 #ifndef __SFR_OFFSET
136 /* Define as 0 before including this file for compatibility with old asm
137  sources that don't subtract __SFR_OFFSET from symbolic I/O addresses. */
138 # if __AVR_ARCH__ >= 100
139 # define __SFR_OFFSET 0x00
140 # else
141 # define __SFR_OFFSET 0x20
142 # endif
143 #endif
144
145 #if (__SFR_OFFSET != 0) && (__SFR_OFFSET != 0x20)
146 #error "__SFR_OFFSET must be 0 or 0x20"
147 #endif
148
154
155 #define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)
157 #define _SFR_IO_REG_P(sfr) ((sfr) < 0x40 + __SFR_OFFSET)
158
159 #if (__SFR_OFFSET == 0x20)
160 /* No need to use ?: operator, so works in assembler too. */
162 #elif !defined(__ASSEMBLER__)
164 #endif
165
166 #else /* !_SFR_ASM_COMPAT */
167
168 #ifndef __SFR_OFFSET
169 # if __AVR_ARCH__ >= 100
170 # define __SFR_OFFSET 0x00
171 # else
172 # define __SFR_OFFSET 0x20
173 # endif
174 #endif
175
181
184 #define _SFR_IO_REG_P(sfr) (_SFR_MEM_ADDR(sfr) < 0x40 + __SFR_OFFSET)
185
187
188 #endif /* !_SFR_ASM_COMPAT */
189
193
194 /** \name Bit manipulation */
195
196 /*@{*/
197 /** \def _BV
198  \ingroup avr_sfr
199
200  \code #include <avr/io.h>\endcode
201
202  Converts a bit number into a byte value.
203
204  \note The bit shift is performed by the compiler which then inserts the
205  result into the code. Thus, there is no run-time overhead when using
206  _BV(). */
207
208 #define _BV(bit) (1 << (bit))
209
210 /*@}*/
211
212 #ifndef _VECTOR
213 #define _VECTOR(N) __vector_ ## N
214 #endif
215
216 #ifndef __ASSEMBLER__
217
218
219 /** \name IO register bit manipulation */
220
221 /*@{*/
222
223
224
225 /** \def bit_is_set
226  \ingroup avr_sfr
227
228  \code #include <avr/io.h>\endcode
229
230  Test whether bit \c bit in IO register \c sfr is set.
231  This will return a 0 if the bit is clear, and non-zero
232  if the bit is set. */
233
234 #define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))
235
236 /** \def bit_is_clear
237  \ingroup avr_sfr
238
239  \code #include <avr/io.h>\endcode
240
241  Test whether bit \c bit in IO register \c sfr is clear.
242  This will return non-zero if the bit is clear, and a 0
243  if the bit is set. */
244
245 #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
246
247 /** \def loop_until_bit_is_set
248  \ingroup avr_sfr
249
250  \code #include <avr/io.h>\endcode
251
252  Wait until bit \c bit in IO register \c sfr is set. */
253
254 #define loop_until_bit_is_set(sfr, bit) do { } while (bit_is_clear(sfr, bit))
255
256 /** \def loop_until_bit_is_clear
257  \ingroup avr_sfr
258
259  \code #include <avr/io.h>\endcode
260
261  Wait until bit \c bit in IO register \c sfr is clear. */
262
263 #define loop_until_bit_is_clear(sfr, bit) do { } while (bit_is_set(sfr, bit))
264
265 /*@}*/
266
267 #endif /* !__ASSEMBLER__ */
268
269 #endif /* _SFR_DEFS_H_ */