summaryrefslogtreecommitdiff
path: root/cpukit/score/cpu/avr/avr/lock.h
blob: 182f0f4cd896009ab51384338588fd5d29883fa8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/**
 * @file avr/lock.h
 *
 * @brief Lock Bits API
 *  \par Introduction
 *
 *  The Lockbit API allows a user to specify the lockbit settings for the
 *  specific AVR device they are compiling for. These lockbit settings will be
 *  placed in a special section in the ELF output file, after linking.
 *
 *  Programming tools can take advantage of the lockbit information embedded in
 *  the ELF file, by extracting this information and determining if the lockbits
 *  need to be programmed after programming the Flash and EEPROM memories.
 *  This also allows a single ELF file to contain all the
 *  information needed to program an AVR.
 *
 *  To use the Lockbit API, include the <avr/io.h> header file, which in turn
 *  automatically includes the individual I/O header file and the <avr/lock.h>
 *  file. These other two files provides everything necessary to set the AVR
 *  lockbits.
 *
 *  \par Lockbit API
 *
 *  Each I/O header file may define up to 3 macros that controls what kinds
 *  of lockbits are available to the user.
 *
 *  If __LOCK_BITS_EXIST is defined, then two lock bits are available to the
 *  user and 3 mode settings are defined for these two bits.
 *
 *  If __BOOT_LOCK_BITS_0_EXIST is defined, then the two BLB0 lock bits are
 *  available to the user and 4 mode settings are defined for these two bits.
 *
 *  If __BOOT_LOCK_BITS_1_EXIST is defined, then the two BLB1 lock bits are
 *  available to the user and 4 mode settings are defined for these two bits.
 *
 *  If __BOOT_LOCK_APPLICATION_TABLE_BITS_EXIST is defined then two lock bits
 *  are available to set the locking mode for the Application Table Section
 *  (which is used in the XMEGA family).
 *
 *  If __BOOT_LOCK_APPLICATION_BITS_EXIST is defined then two lock bits are
 *  available to set the locking mode for the Application Section (which is used
 *  in the XMEGA family).
 *
 *  If __BOOT_LOCK_BOOT_BITS_EXIST is defined then two lock bits are available
 *  to set the locking mode for the Boot Loader Section (which is used in the
 *  XMEGA family).
 *
 *  The AVR lockbit modes have inverted values, logical 1 for an unprogrammed
 *  (disabled) bit and logical 0 for a programmed (enabled) bit. The defined
 *  macros for each individual lock bit represent this in their definition by a
 *  bit-wise inversion of a mask. For example, the LB_MODE_3 macro is defined
 *  as:
 *  \code
 *  #define LB_MODE_3  (0xFC)
 *  \endcode
 *
 *  To combine the lockbit mode macros together to represent a whole byte,
 *  use the bitwise AND operator, like so:
 *  \code
 *  (LB_MODE_3 & BLB0_MODE_2)
 *  \endcode
 *
 *  <avr/lock.h> also defines a macro that provides a default lockbit value:
 *  LOCKBITS_DEFAULT which is defined to be 0xFF.
 *
 *  See the AVR device specific datasheet for more details about these
 *  lock bits and the available mode settings.
 *
 *  A convenience macro, LOCKMEM, is defined as a GCC attribute for a
 *  custom-named section of ".lock".
 *
 *  A convenience macro, LOCKBITS, is defined that declares a variable, __lock,
 *  of type unsigned char with the attribute defined by LOCKMEM. This variable
 *  allows the end user to easily set the lockbit data.
 *
 *  \note If a device-specific I/O header file has previously defined LOCKMEM,
 *  then LOCKMEM is not redefined. If a device-specific I/O header file has
 *  previously defined LOCKBITS, then LOCKBITS is not redefined. LOCKBITS is
 *  currently known to be defined in the I/O header files for the XMEGA devices.
 *
 *  \par API Usage Example
 *
 *  Putting all of this together is easy:
 *
 *  \code
 *  #include <avr/io.h>
 *
 *  LOCKBITS = (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4);
 *
 *  int main(void)
 *  {
 *      return 0;
 *  }
 *  \endcode
 *
 *  Or:
 *
 *  \code
 *  #include <avr/io.h>
 *
 *  unsigned char __lock __attribute__((section (".lock"))) =
 *      (LB_MODE_1 & BLB0_MODE_3 & BLB1_MODE_4);
 *
 *  int main(void)
 *  {
 *      return 0;
 *  }
 *  \endcode
 *
 *
 *
 *  However there are a number of caveats that you need to be aware of to
 *  use this API properly.
 *
 *  Be sure to include <avr/io.h> to get all of the definitions for the API.
 *  The LOCKBITS macro defines a global variable to store the lockbit data. This
 *  variable is assigned to its own linker section. Assign the desired lockbit
 *  values immediately in the variable initialization.
 *
 *  The .lock section in the ELF file will get its values from the initial
 *  variable assignment ONLY. This means that you can NOT assign values to
 *  this variable in functions and the new values will not be put into the
 *  ELF .lock section.
 *
 *  The global variable is declared in the LOCKBITS macro has two leading
 *  underscores, which means that it is reserved for the "implementation",
 *  meaning the library, so it will not conflict with a user-named variable.
 *
 *  You must initialize the lockbit variable to some meaningful value, even
 *  if it is the default value. This is because the lockbits default to a
 *  logical 1, meaning unprogrammed. Normal uninitialized data defaults to all
 *  locgial zeros. So it is vital that all lockbits are initialized, even with
 *  default data. If they are not, then the lockbits may not programmed to the
 *  desired settings and can possibly put your device into an unrecoverable
 *  state.
 *
 *  Be sure to have the -mmcu=<em>device</em> flag in your compile command line and
 *  your linker command line to have the correct device selected and to have
 *  the correct I/O header file included when you include <avr/io.h>.
 *
 *  You can print out the contents of the .lock section in the ELF file by
 *  using this command line:
 *  \code
 *  avr-objdump -s -j .lock <ELF file>
 *  \endcode
 */

/*
 *  Copyright (c) 2007, Atmel Corporation
 *  All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * * Neither the name of the copyright holders nor the names of
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _AVR_LOCK_H_
#define _AVR_LOCK_H_  1

/**
 *  @defgroup avr_lock Lockbit Support
 *
 *  @ingroup avr
 */
/**@{*/

#ifndef __ASSEMBLER__

#ifndef LOCKMEM
#define LOCKMEM  __attribute__((section (".lock")))
#endif

#ifndef LOCKBITS
#define LOCKBITS unsigned char __lock LOCKMEM
#endif

#endif  /* !__ASSEMBLER */


/* Lock Bit Modes */
#if defined(__LOCK_BITS_EXIST)
#define LB_MODE_1  (0xFF)
#define LB_MODE_2  (0xFE)
#define LB_MODE_3  (0xFC)
#endif

#if defined(__BOOT_LOCK_BITS_0_EXIST)
#define BLB0_MODE_1  (0xFF)
#define BLB0_MODE_2  (0xFB)
#define BLB0_MODE_3  (0xF3)
#define BLB0_MODE_4  (0xF7)
#endif

#if defined(__BOOT_LOCK_BITS_1_EXIST)
#define BLB1_MODE_1  (0xFF)
#define BLB1_MODE_2  (0xEF)
#define BLB1_MODE_3  (0xCF)
#define BLB1_MODE_4  (0xDF)
#endif

#if defined(__BOOT_LOCK_APPLICATION_TABLE_BITS_EXIST)
#define BLBAT0 ~_BV(2)
#define BLBAT1 ~_BV(3)
#endif

#if defined(__BOOT_LOCK_APPLICATION_BITS_EXIST)
#define BLBA0 ~_BV(4)
#define BLBA1 ~_BV(5)
#endif

#if defined(__BOOT_LOCK_BOOT_BITS_EXIST)
#define BLBB0 ~_BV(6)
#define BLBB1 ~_BV(7)
#endif


#define LOCKBITS_DEFAULT (0xFF)

/**@}*/
#endif /* _AVR_LOCK_H_ */