source: rtems/cpukit/score/cpu/avr/avr/fuse.h @ 04a62dce

4.104.11
Last change on this file since 04a62dce was 04a62dce, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 6, 2009 at 2:52:07 PM

2009-08-05 Josh Switnicki <josh.switnicki@…>

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