avr-libc  2.1.0
Standard C library for AVR-GCC

AVR Libc Home Page

AVRs

AVR Libc Development Pages

Main Page

User Manual

Library Reference

FAQ

Example Projects

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_8h_source.html,v 1.1.1.7 2022/01/29 09:21:58 joerg_wunsch Exp $ */
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 #if !(defined(__ASSEMBLER__) || defined(__DOXYGEN__))
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__ || __DOXYGEN__) */
273 
274 #endif /* _AVR_FUSE_H_ */