AVR-LibC  2.3.0git
Standard C library for AVR-GCC
 

AVR-LibC Documen­tation

AVR-LibC Development Pages

Main Page

User Manual

Library Refe­rence

FAQ

Example Projects

File List

Index

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