AVR Libc Home Page
AVR Libc Development Pages
Main Page
User Manual
Library Reference
FAQ
Alphabetical Index
Example Projects
include
avr
fuse.h
Go to the documentation of this file.
1
/* Copyright (c) 2007, Atmel Corporation
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
/* $Id: fuse.h 2297 2012-06-19 06:56:49Z joerg_wunsch $ */
32
33
/* avr/fuse.h - Fuse API */
34
35
#ifndef _AVR_FUSE_H_
36
#define _AVR_FUSE_H_ 1
37
38
/* This file must be explicitly included by <avr/io.h>. */
39
#if !defined(_AVR_IO_H_)
40
#error "You must #include <avr/io.h> and not <avr/fuse.h> by itself."
41
#endif
42
43
44
/** \file */
45
/** \defgroup avr_fuse <avr/fuse.h>: Fuse Support
46
47
\par Introduction
48
49
The Fuse API allows a user to specify the fuse settings for the specific
50
AVR device they are compiling for. These fuse settings will be placed
51
in a special section in the ELF output file, after linking.
52
53
Programming tools can take advantage of the fuse information embedded in
54
the ELF file, by extracting this information and determining if the fuses
55
need to be programmed before programming the Flash and EEPROM memories.
56
This also allows a single ELF file to contain all the
57
information needed to program an AVR.
58
59
To use the Fuse API, include the <avr/io.h> header file, which in turn
60
automatically includes the individual I/O header file and the <avr/fuse.h>
61
file. These other two files provides everything necessary to set the AVR
62
fuses.
63
64
\par Fuse API
65
66
Each I/O header file must define the FUSE_MEMORY_SIZE macro which is
67
defined to the number of fuse bytes that exist in the AVR device.
68
69
A new type, __fuse_t, is defined as a structure. The number of fields in
70
this structure are determined by the number of fuse bytes in the
71
FUSE_MEMORY_SIZE macro.
72
73
If FUSE_MEMORY_SIZE == 1, there is only a single field: byte, of type
74
unsigned char.
75
76
If FUSE_MEMORY_SIZE == 2, there are two fields: low, and high, of type
77
unsigned char.
78
79
If FUSE_MEMORY_SIZE == 3, there are three fields: low, high, and extended,
80
of type unsigned char.
81
82
If FUSE_MEMORY_SIZE > 3, there is a single field: byte, which is an array
83
of unsigned char with the size of the array being FUSE_MEMORY_SIZE.
84
85
A convenience macro, FUSEMEM, is defined as a GCC attribute for a
86
custom-named section of ".fuse".
87
88
A convenience macro, FUSES, is defined that declares a variable, __fuse, of
89
type __fuse_t with the attribute defined by FUSEMEM. This variable
90
allows the end user to easily set the fuse data.
91
92
\note If a device-specific I/O header file has previously defined FUSEMEM,
93
then FUSEMEM is not redefined. If a device-specific I/O header file has
94
previously defined FUSES, then FUSES is not redefined.
95
96
Each AVR device I/O header file has a set of defined macros which specify the
97
actual fuse bits available on that device. The AVR fuses have inverted
98
values, logical 1 for an unprogrammed (disabled) bit and logical 0 for a
99
programmed (enabled) bit. The defined macros for each individual fuse
100
bit represent this in their definition by a bit-wise inversion of a mask.
101
For example, the FUSE_EESAVE fuse in the ATmega128 is defined as:
102
\code
103
#define FUSE_EESAVE ~_BV(3)
104
\endcode
105
\note The _BV macro creates a bit mask from a bit number. It is then
106
inverted to represent logical values for a fuse memory byte.
107
108
To combine the fuse bits macros together to represent a whole fuse byte,
109
use the bitwise AND operator, like so:
110
\code
111
(FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN)
112
\endcode
113
114
Each device I/O header file also defines macros that provide default values
115
for each fuse byte that is available. LFUSE_DEFAULT is defined for a Low
116
Fuse byte. HFUSE_DEFAULT is defined for a High Fuse byte. EFUSE_DEFAULT
117
is defined for an Extended Fuse byte.
118
119
If FUSE_MEMORY_SIZE > 3, then the I/O header file defines macros that
120
provide default values for each fuse byte like so:
121
FUSE0_DEFAULT
122
FUSE1_DEFAULT
123
FUSE2_DEFAULT
124
FUSE3_DEFAULT
125
FUSE4_DEFAULT
126
....
127
128
\par API Usage Example
129
130
Putting all of this together is easy. Using C99's designated initializers:
131
132
\code
133
#include <avr/io.h>
134
135
FUSES =
136
{
137
.low = LFUSE_DEFAULT,
138
.high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
139
.extended = EFUSE_DEFAULT,
140
};
141
142
int main(void)
143
{
144
return 0;
145
}
146
\endcode
147
148
Or, using the variable directly instead of the FUSES macro,
149
150
\code
151
#include <avr/io.h>
152
153
__fuse_t __fuse __attribute__((section (".fuse"))) =
154
{
155
.low = LFUSE_DEFAULT,
156
.high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
157
.extended = EFUSE_DEFAULT,
158
};
159
160
int main(void)
161
{
162
return 0;
163
}
164
\endcode
165
166
If you are compiling in C++, you cannot use the designated intializers so
167
you must do:
168
169
\code
170
#include <avr/io.h>
171
172
FUSES =
173
{
174
LFUSE_DEFAULT, // .low
175
(FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN), // .high
176
EFUSE_DEFAULT, // .extended
177
};
178
179
int main(void)
180
{
181
return 0;
182
}
183
\endcode
184
185
186
However there are a number of caveats that you need to be aware of to
187
use this API properly.
188
189
Be sure to include <avr/io.h> to get all of the definitions for the API.
190
The FUSES macro defines a global variable to store the fuse data. This
191
variable is assigned to its own linker section. Assign the desired fuse
192
values immediately in the variable initialization.
193
194
The .fuse section in the ELF file will get its values from the initial
195
variable assignment ONLY. This means that you can NOT assign values to
196
this variable in functions and the new values will not be put into the
197
ELF .fuse section.
198
199
The global variable is declared in the FUSES macro has two leading
200
underscores, which means that it is reserved for the "implementation",
201
meaning the library, so it will not conflict with a user-named variable.
202
203
You must initialize ALL fields in the __fuse_t structure. This is because
204
the fuse bits in all bytes default to a logical 1, meaning unprogrammed.
205
Normal uninitialized data defaults to all locgial zeros. So it is vital that
206
all fuse bytes are initialized, even with default data. If they are not,
207
then the fuse bits may not programmed to the desired settings.
208
209
Be sure to have the -mmcu=<em>device</em> flag in your compile command line and
210
your linker command line to have the correct device selected and to have
211
the correct I/O header file included when you include <avr/io.h>.
212
213
You can print out the contents of the .fuse section in the ELF file by
214
using this command line:
215
\code
216
avr-objdump -s -j .fuse <ELF file>
217
\endcode
218
The section contents shows the address on the left, then the data going from
219
lower address to a higher address, left to right.
220
221
*/
222
223
#ifndef __ASSEMBLER__
224
225
#ifndef FUSEMEM
226
#define FUSEMEM __attribute__((__used__, __section__ (".fuse")))
227
#endif
228
229
#if FUSE_MEMORY_SIZE > 3
230
231
typedef
struct
232
{
233
unsigned
char
byte[FUSE_MEMORY_SIZE];
234
} __fuse_t;
235
236
237
#elif FUSE_MEMORY_SIZE == 3
238
239
typedef
struct
240
{
241
unsigned
char
low;
242
unsigned
char
high;
243
unsigned
char
extended;
244
} __fuse_t;
245
246
#elif FUSE_MEMORY_SIZE == 2
247
248
typedef
struct
249
{
250
unsigned
char
low;
251
unsigned
char
high;
252
} __fuse_t;
253
254
#elif FUSE_MEMORY_SIZE == 1
255
256
typedef
struct
257
{
258
unsigned
char
byte;
259
} __fuse_t;
260
261
#endif
262
263
#if !defined(FUSES)
264
#if defined(__AVR_XMEGA__)
265
#define FUSES NVM_FUSES_t __fuse FUSEMEM
266
#else
267
#define FUSES __fuse_t __fuse FUSEMEM
268
#endif
269
#endif
270
271
272
#endif
/* !__ASSEMBLER__ */
273
274
#endif
/* _AVR_FUSE_H_ */
Automatically generated by Doxygen 1.8.7 on Tue Aug 12 2014.