$treeview $search $mathjax $extrastylesheet
avr-libc  2.0.0
$projectbrief
$projectbrief
$searchbox

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.
00001 /* Copyright (c) 2007, Atmel Corporation
00002    All rights reserved.
00003 
00004    Redistribution and use in source and binary forms, with or without
00005    modification, are permitted provided that the following conditions are met:
00006 
00007    * Redistributions of source code must retain the above copyright
00008      notice, this list of conditions and the following disclaimer.
00009 
00010    * Redistributions in binary form must reproduce the above copyright
00011      notice, this list of conditions and the following disclaimer in
00012      the documentation and/or other materials provided with the
00013      distribution.
00014 
00015    * Neither the name of the copyright holders nor the names of
00016      contributors may be used to endorse or promote products derived
00017      from this software without specific prior written permission.
00018 
00019   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029   POSSIBILITY OF SUCH DAMAGE. */
00030 
00031 /* $Id$ */
00032 
00033 /* avr/fuse.h - Fuse API */
00034 
00035 #ifndef _AVR_FUSE_H_
00036 #define _AVR_FUSE_H_ 1
00037 
00038 /* This file must be explicitly included by <avr/io.h>. */
00039 #if !defined(_AVR_IO_H_)
00040 #error "You must #include <avr/io.h> and not <avr/fuse.h> by itself."
00041 #endif
00042 
00043 
00044 /** \file */
00045 /** \defgroup avr_fuse <avr/fuse.h>: Fuse Support
00046 
00047     \par Introduction
00048 
00049     The Fuse API allows a user to specify the fuse settings for the specific
00050     AVR device they are compiling for. These fuse settings will be placed
00051     in a special section in the ELF output file, after linking.
00052 
00053     Programming tools can take advantage of the fuse information embedded in
00054     the ELF file, by extracting this information and determining if the fuses
00055     need to be programmed before programming the Flash and EEPROM memories.
00056     This also allows a single ELF file to contain all the
00057     information needed to program an AVR. 
00058 
00059     To use the Fuse API, include the <avr/io.h> header file, which in turn
00060     automatically includes the individual I/O header file and the <avr/fuse.h>
00061     file. These other two files provides everything necessary to set the AVR
00062     fuses.
00063     
00064     \par Fuse API
00065     
00066     Each I/O header file must define the FUSE_MEMORY_SIZE macro which is
00067     defined to the number of fuse bytes that exist in the AVR device.
00068     
00069     A new type, __fuse_t, is defined as a structure. The number of fields in 
00070     this structure are determined by the number of fuse bytes in the 
00071     FUSE_MEMORY_SIZE macro.
00072     
00073     If FUSE_MEMORY_SIZE == 1, there is only a single field: byte, of type
00074     unsigned char.
00075     
00076     If FUSE_MEMORY_SIZE == 2, there are two fields: low, and high, of type
00077     unsigned char.
00078     
00079     If FUSE_MEMORY_SIZE == 3, there are three fields: low, high, and extended,
00080     of type unsigned char.
00081     
00082     If FUSE_MEMORY_SIZE > 3, there is a single field: byte, which is an array
00083     of unsigned char with the size of the array being FUSE_MEMORY_SIZE.
00084     
00085     A convenience macro, FUSEMEM, is defined as a GCC attribute for a 
00086     custom-named section of ".fuse".
00087     
00088     A convenience macro, FUSES, is defined that declares a variable, __fuse, of
00089     type __fuse_t with the attribute defined by FUSEMEM. This variable
00090     allows the end user to easily set the fuse data.
00091 
00092     \note If a device-specific I/O header file has previously defined FUSEMEM,
00093     then FUSEMEM is not redefined. If a device-specific I/O header file has
00094     previously defined FUSES, then FUSES is not redefined.
00095 
00096     Each AVR device I/O header file has a set of defined macros which specify the
00097     actual fuse bits available on that device. The AVR fuses have inverted
00098     values, logical 1 for an unprogrammed (disabled) bit and logical 0 for a
00099     programmed (enabled) bit. The defined macros for each individual fuse
00100     bit represent this in their definition by a bit-wise inversion of a mask.
00101     For example, the FUSE_EESAVE fuse in the ATmega128 is defined as:
00102     \code
00103     #define FUSE_EESAVE      ~_BV(3)
00104     \endcode
00105     \note The _BV macro creates a bit mask from a bit number. It is then 
00106     inverted to represent logical values for a fuse memory byte.
00107     
00108     To combine the fuse bits macros together to represent a whole fuse byte,
00109     use the bitwise AND operator, like so:
00110     \code
00111     (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN)
00112     \endcode
00113     
00114     Each device I/O header file also defines macros that provide default values
00115     for each fuse byte that is available. LFUSE_DEFAULT is defined for a Low
00116     Fuse byte. HFUSE_DEFAULT is defined for a High Fuse byte. EFUSE_DEFAULT
00117     is defined for an Extended Fuse byte.
00118     
00119     If FUSE_MEMORY_SIZE > 3, then the I/O header file defines macros that
00120     provide default values for each fuse byte like so:
00121     FUSE0_DEFAULT
00122     FUSE1_DEFAULT
00123     FUSE2_DEFAULT
00124     FUSE3_DEFAULT
00125     FUSE4_DEFAULT
00126     ....
00127     
00128     \par API Usage Example
00129     
00130     Putting all of this together is easy. Using C99's designated initializers:
00131     
00132     \code
00133     #include <avr/io.h>
00134 
00135     FUSES = 
00136     {
00137         .low = LFUSE_DEFAULT,
00138         .high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
00139         .extended = EFUSE_DEFAULT,
00140     };
00141 
00142     int main(void)
00143     {
00144         return 0;
00145     }
00146     \endcode
00147     
00148     Or, using the variable directly instead of the FUSES macro,
00149     
00150     \code
00151     #include <avr/io.h>
00152 
00153     __fuse_t __fuse __attribute__((section (".fuse"))) = 
00154     {
00155         .low = LFUSE_DEFAULT,
00156         .high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
00157         .extended = EFUSE_DEFAULT,
00158     };
00159 
00160     int main(void)
00161     {
00162         return 0;
00163     }
00164     \endcode
00165     
00166     If you are compiling in C++, you cannot use the designated intializers so
00167     you must do:
00168 
00169     \code
00170     #include <avr/io.h>
00171 
00172     FUSES = 
00173     {
00174         LFUSE_DEFAULT, // .low
00175         (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN), // .high
00176         EFUSE_DEFAULT, // .extended
00177     };
00178 
00179     int main(void)
00180     {
00181         return 0;
00182     }
00183     \endcode
00184     
00185     
00186     However there are a number of caveats that you need to be aware of to
00187     use this API properly.
00188     
00189     Be sure to include <avr/io.h> to get all of the definitions for the API.
00190     The FUSES macro defines a global variable to store the fuse data. This 
00191     variable is assigned to its own linker section. Assign the desired fuse 
00192     values immediately in the variable initialization.
00193     
00194     The .fuse section in the ELF file will get its values from the initial 
00195     variable assignment ONLY. This means that you can NOT assign values to 
00196     this variable in functions and the new values will not be put into the
00197     ELF .fuse section.
00198     
00199     The global variable is declared in the FUSES macro has two leading 
00200     underscores, which means that it is reserved for the "implementation",
00201     meaning the library, so it will not conflict with a user-named variable.
00202     
00203     You must initialize ALL fields in the __fuse_t structure. This is because
00204     the fuse bits in all bytes default to a logical 1, meaning unprogrammed. 
00205     Normal uninitialized data defaults to all locgial zeros. So it is vital that
00206     all fuse bytes are initialized, even with default data. If they are not,
00207     then the fuse bits may not programmed to the desired settings.
00208     
00209     Be sure to have the -mmcu=<em>device</em> flag in your compile command line and
00210     your linker command line to have the correct device selected and to have 
00211     the correct I/O header file included when you include <avr/io.h>.
00212 
00213     You can print out the contents of the .fuse section in the ELF file by
00214     using this command line:
00215     \code
00216     avr-objdump -s -j .fuse <ELF file>
00217     \endcode
00218     The section contents shows the address on the left, then the data going from
00219     lower address to a higher address, left to right.
00220 
00221 */
00222 
00223 #if !(defined(__ASSEMBLER__) || defined(__DOXYGEN__))
00224 
00225 #ifndef FUSEMEM
00226 #define FUSEMEM  __attribute__((__used__, __section__ (".fuse")))
00227 #endif
00228 
00229 #if FUSE_MEMORY_SIZE > 3
00230 
00231 typedef struct
00232 {
00233     unsigned char byte[FUSE_MEMORY_SIZE];
00234 } __fuse_t;
00235 
00236 
00237 #elif FUSE_MEMORY_SIZE == 3
00238 
00239 typedef struct
00240 {
00241     unsigned char low;
00242     unsigned char high;
00243     unsigned char extended;
00244 } __fuse_t;
00245 
00246 #elif FUSE_MEMORY_SIZE == 2
00247 
00248 typedef struct
00249 {
00250     unsigned char low;
00251     unsigned char high;
00252 } __fuse_t;
00253 
00254 #elif FUSE_MEMORY_SIZE == 1
00255 
00256 typedef struct
00257 {
00258     unsigned char byte;
00259 } __fuse_t;
00260 
00261 #endif
00262 
00263 #if !defined(FUSES)
00264   #if defined(__AVR_XMEGA__)
00265     #define FUSES NVM_FUSES_t __fuse FUSEMEM
00266   #else
00267     #define FUSES __fuse_t __fuse FUSEMEM
00268   #endif
00269 #endif
00270 
00271 
00272 #endif /* !(__ASSEMBLER__ || __DOXYGEN__) */
00273 
00274 #endif /* _AVR_FUSE_H_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Defines