AVR-LibC
2.3.0
Standard C library for AVR-GCC
AVR-LibC Manual
AVR-LibC Sources
Main Page
User Manual
Library Reference
FAQ
Example Projects
Index
Loading...
Searching...
No Matches
source
avr-libc-onlinedocs
include
avr
sfr_defs.h
1
/* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl>
2
All rights reserved.
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
#ifndef _AVR_SFR_DEFS_H_
34
#define _AVR_SFR_DEFS_H_ 1
35
36
/** \defgroup avr_sfr_notes Additional notes from <avr/sfr_defs.h>
37
\ingroup avr_sfr
38
39
The \c <avr/sfr_defs.h> file is included by all of the \c <avr/ioXXXX.h>
40
files, which use macros defined here to make the special function register
41
definitions look like C variables or simple constants, depending on the
42
<tt>_SFR_ASM_COMPAT</tt> define. Some examples from \c <avr/iocanxx.h> to
43
show how to define such macros:
44
45
\code
46
#define PORTA _SFR_IO8(0x02)
47
#define EEAR _SFR_IO16(0x21)
48
#define UDR0 _SFR_MEM8(0xC6)
49
#define TCNT3 _SFR_MEM16(0x94)
50
#define CANIDT _SFR_MEM32(0xF0)
51
\endcode
52
53
If \c _SFR_ASM_COMPAT is not defined, C programs can use names like
54
<tt>PORTA</tt> directly in C expressions (also on the left side of
55
assignment operators) and GCC will do the right thing (use short I/O
56
instructions if possible). The \c __SFR_OFFSET definition is not used in
57
any way in this case.
58
59
Define \c _SFR_ASM_COMPAT as 1 to make these names work as simple constants
60
(addresses of the I/O registers). This is necessary when included in
61
preprocessed assembler (*.S) source files, so it is done automatically if
62
\c __ASSEMBLER__ is defined. By default, all addresses are defined as if
63
they were memory addresses (used in \c lds/sts instructions). To use these
64
addresses in \c in/out instructions, you must subtract 0x20 from them.
65
66
For more backwards compatibility, insert the following at the start of your
67
old assembler source file:
68
69
\code
70
#define __SFR_OFFSET 0
71
\endcode
72
73
This automatically subtracts 0x20 from I/O space addresses, but it's a
74
hack, so it is recommended to change your source: wrap such addresses in
75
macros defined here, as shown below. After this is done, the
76
<tt>__SFR_OFFSET</tt> definition is no longer necessary and can be removed.
77
78
Real example - this code could be used in a boot loader that is portable
79
between devices with \c SPMCR at different addresses.
80
81
\verbatim
82
<avr/iom163.h>: #define SPMCR _SFR_IO8(0x37)
83
<avr/iom128.h>: #define SPMCR _SFR_MEM8(0x68)
84
\endverbatim
85
86
\code
87
#if _SFR_IO_REG_P(SPMCR)
88
out _SFR_IO_ADDR(SPMCR), r24
89
#else
90
sts _SFR_MEM_ADDR(SPMCR), r24
91
#endif
92
\endcode
93
94
You can use the \c in/out/cbi/sbi/sbic/sbis instructions, without the
95
<tt>_SFR_IO_REG_P</tt> test, if you know that the register is in the I/O
96
space (as with \c SREG, for example). If it isn't, the assembler will
97
complain (I/O address out of range 0...0x3f), so this should be fairly
98
safe.
99
100
If you do not define \c __SFR_OFFSET (so it will be 0x20 by default), all
101
special register addresses are defined as memory addresses (so \c SREG is
102
0x5f), and (if code size and speed are not important, and you don't like
103
the ugly \#if above) you can always use lds/sts to access them. But, this
104
will not work if <tt>__SFR_OFFSET</tt> != 0x20, so use a different macro
105
(defined only if <tt>__SFR_OFFSET</tt> == 0x20) for safety:
106
107
\code
108
sts _SFR_ADDR(SPMCR), r24
109
\endcode
110
111
In C programs, all 3 combinations of \c _SFR_ASM_COMPAT and
112
<tt>__SFR_OFFSET</tt> are supported - the \c _SFR_ADDR(SPMCR) macro can be
113
used to get the address of the \c SPMCR register (0x57 or 0x68 depending on
114
device). */
115
116
#ifdef __ASSEMBLER__
117
#define _SFR_ASM_COMPAT 1
118
#elif !defined(_SFR_ASM_COMPAT)
119
#define _SFR_ASM_COMPAT 0
120
#endif
121
122
#ifndef __ASSEMBLER__
123
/* These only work in C programs. */
124
#include <
inttypes.h
>
125
126
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
127
#define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr))
128
#define _MMIO_DWORD(mem_addr) (*(volatile uint32_t *)(mem_addr))
129
#endif
130
131
#if _SFR_ASM_COMPAT
132
133
#ifndef __SFR_OFFSET
134
/* Define as 0 before including this file for compatibility with old asm
135
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses. */
136
# if __AVR_ARCH__ >= 100
137
# define __SFR_OFFSET 0x00
138
# else
139
# define __SFR_OFFSET 0x20
140
# endif
141
#endif
142
143
#if (__SFR_OFFSET != 0) && (__SFR_OFFSET != 0x20)
144
#error "__SFR_OFFSET must be 0 or 0x20"
145
#endif
146
147
#define _SFR_MEM8(mem_addr) (mem_addr)
148
#define _SFR_MEM16(mem_addr) (mem_addr)
149
#define _SFR_MEM32(mem_addr) (mem_addr)
150
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
151
#define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)
152
153
#define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)
154
#define _SFR_MEM_ADDR(sfr) (sfr)
155
#define _SFR_IO_REG_P(sfr) ((sfr) < 0x40 + __SFR_OFFSET)
156
157
#if (__SFR_OFFSET == 0x20)
158
/* No need to use ?: operator, so works in assembler too. */
159
#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)
160
#elif !defined(__ASSEMBLER__)
161
#define _SFR_ADDR(sfr) (_SFR_IO_REG_P(sfr) ? (_SFR_IO_ADDR(sfr) + 0x20) : _SFR_MEM_ADDR(sfr))
162
#endif
163
164
#else
/* !_SFR_ASM_COMPAT */
165
166
#ifndef __SFR_OFFSET
167
# if __AVR_ARCH__ >= 100
168
# define __SFR_OFFSET 0x00
169
# else
170
# define __SFR_OFFSET 0x20
171
# endif
172
#endif
173
174
#define _SFR_MEM8(mem_addr) _MMIO_BYTE(mem_addr)
175
#define _SFR_MEM16(mem_addr) _MMIO_WORD(mem_addr)
176
#define _SFR_MEM32(mem_addr) _MMIO_DWORD(mem_addr)
177
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
178
#define _SFR_IO16(io_addr) _MMIO_WORD((io_addr) + __SFR_OFFSET)
179
180
#define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))
181
#define _SFR_IO_ADDR(sfr) (_SFR_MEM_ADDR(sfr) - __SFR_OFFSET)
182
#define _SFR_IO_REG_P(sfr) (_SFR_MEM_ADDR(sfr) < 0x40 + __SFR_OFFSET)
183
184
#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)
185
186
#endif
/* !_SFR_ASM_COMPAT */
187
188
#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
189
#define _SFR_WORD(sfr) _MMIO_WORD(_SFR_ADDR(sfr))
190
#define _SFR_DWORD(sfr) _MMIO_DWORD(_SFR_ADDR(sfr))
191
192
/** \name Bit manipulation */
193
194
/**@{*/
195
/** \def _BV
196
\ingroup avr_sfr
197
198
\code #include <avr/io.h>\endcode
199
200
Converts a bit number into a byte value.
201
202
\note The bit shift is performed by the compiler which then inserts the
203
result into the code. Thus, there is no run-time overhead when using
204
_BV(). */
205
206
#define _BV(bit) (1 << (bit))
207
208
/**@}*/
209
210
#ifndef _VECTOR
211
#define _VECTOR(N) __vector_ ## N
212
#endif
213
214
#ifndef __ASSEMBLER__
215
216
217
/** \name IO register bit manipulation */
218
219
/**@{*/
220
221
222
223
/** \def bit_is_set
224
\ingroup avr_sfr
225
226
\code #include <avr/io.h>\endcode
227
228
Test whether bit \c bit in IO register \c sfr is set.
229
This will return a 0 if the bit is clear, and non-zero
230
if the bit is set. */
231
232
#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))
233
234
/** \def bit_is_clear
235
\ingroup avr_sfr
236
237
\code #include <avr/io.h>\endcode
238
239
Test whether bit \c bit in IO register \c sfr is clear.
240
This will return non-zero if the bit is clear, and a 0
241
if the bit is set. */
242
243
#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))
244
245
/** \def loop_until_bit_is_set
246
\ingroup avr_sfr
247
248
\code #include <avr/io.h>\endcode
249
250
Wait until bit \c bit in IO register \c sfr is set. */
251
252
#define loop_until_bit_is_set(sfr, bit) do { } while (bit_is_clear(sfr, bit))
253
254
/** \def loop_until_bit_is_clear
255
\ingroup avr_sfr
256
257
\code #include <avr/io.h>\endcode
258
259
Wait until bit \c bit in IO register \c sfr is clear. */
260
261
#define loop_until_bit_is_clear(sfr, bit) do { } while (bit_is_set(sfr, bit))
262
263
/**@}*/
264
265
#endif
/* !__ASSEMBLER__ */
266
267
#endif
/* _SFR_DEFS_H_ */
inttypes.h
Generated on Sun Dec 28 2025 13:38:37 for AVR-LibC by
1.9.6