summaryrefslogtreecommitdiff
path: root/include/avr/lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/avr/lock.h')
-rw-r--r--include/avr/lock.h243
1 files changed, 243 insertions, 0 deletions
diff --git a/include/avr/lock.h b/include/avr/lock.h
new file mode 100644
index 0000000000..182f0f4cd8
--- /dev/null
+++ b/include/avr/lock.h
@@ -0,0 +1,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_ */