2004-02-25 Theodore A. Roth
* include/avr/boot.h: Change example to show a more efficient usage
of the API.
(__boot_page_fill_normal): Remove checks for spm and eeprom busy. These
are redundant checks in normal usage and just bloat the bootloader.
(__boot_page_fill_alternate): Ditto.
(__boot_page_fill_extended): Ditto.
(__boot_page_erase_normal): Ditto.
(__boot_page_erase_alternate): Ditto.
(__boot_page_erase_extended): Ditto.
(__boot_page_write_normal): Ditto.
(__boot_page_write_alternate): Ditto.
(__boot_page_write_extended): Ditto.
(__boot_rww_enable): Ditto.
(__boot_rww_enable_alternate): Ditto.
(__boot_lock_bits_set): Ditto.
(__boot_lock_bits_set_alternate): Ditto.
(boot_page_fill_safe): New macro.
(boot_page_erase_safe): New macro.
(boot_page_write_safe): New macro.
(boot_rww_enable_safe): New macro.
(boot_lock_bits_set_safe): New macro.
Index: include/avr/boot.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/include/avr/boot.h,v
retrieving revision 1.9
diff -u -p -p -r1.9 boot.h
--- include/avr/boot.h 26 Feb 2004 00:27:25 -0000 1.9
+++ include/avr/boot.h 26 Feb 2004 01:36:42 -0000
@@ -51,49 +51,46 @@
The following code shows typical usage of the boot API.
\code
+ #include
#include
#include
- #define ADDRESS 0x1C000UL
-
- void boot_test(void)
+ void boot_program_page (uint32_t page, uint8_t *buf)
{
- unsigned char buffer[8];
-
+ int i;
+ uint8_t sreg;
+
+ // Disable interrupts.
+
+ sreg = SREG;
cli();
- // Erase page.
- boot_page_erase((unsigned long)ADDRESS);
- while(boot_rww_busy())
- {
- boot_rww_enable();
- }
-
- // Write data to buffer a word at a time. Note incrementing address
- // by 2. SPM_PAGESIZE is defined in the microprocessor IO header file.
- for(unsigned long i = ADDRESS; i < ADDRESS + SPM_PAGESIZE; i += 2)
- {
- boot_page_fill(i, (i-ADDRESS) + ((i-ADDRESS+1) << 8));
- }
-
- // Write page.
- boot_page_write((unsigned long)ADDRESS);
- while(boot_rww_busy())
- {
- boot_rww_enable();
- }
-
- sei();
-
- // Read back the values and display.
- // (The show() function is undefined and is used here as an example
- // only.)
- for(unsigned long i = ADDRESS; i < ADDRESS + 256; i++)
+ eeprom_busy_wait ();
+
+ boot_page_erase (page);
+ boot_spm_busy_wait (); // Wait until the memory is erased.
+
+ for (i=0; i
@@ -180,8 +177,6 @@
#define __boot_page_fill_normal(address, data) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
@@ -199,8 +194,6 @@
#define __boot_page_fill_alternate(address, data)\
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
@@ -220,8 +213,6 @@
#define __boot_page_fill_extended(address, data) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r0, %4\n\t" \
@@ -241,8 +232,6 @@
#define __boot_page_erase_normal(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
@@ -257,8 +246,6 @@
#define __boot_page_erase_alternate(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
@@ -275,8 +262,6 @@
#define __boot_page_erase_extended(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
@@ -293,8 +278,6 @@
#define __boot_page_write_normal(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
@@ -309,8 +292,6 @@
#define __boot_page_write_alternate(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
@@ -327,8 +308,6 @@
#define __boot_page_write_extended(address) \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
@@ -345,8 +324,6 @@
#define __boot_rww_enable() \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
@@ -358,8 +335,6 @@
#define __boot_rww_enable_alternate() \
({ \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
@@ -374,8 +349,6 @@
#define __boot_lock_bits_set(lock_bits) \
({ \
uint8_t value = (uint8_t)(lock_bits | __BOOT_LOCK_BITS_MASK); \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
@@ -393,8 +366,6 @@
#define __boot_lock_bits_set_alternate(lock_bits) \
({ \
uint8_t value = (uint8_t)(lock_bits | __BOOT_LOCK_BITS_MASK); \
- boot_spm_busy_wait(); \
- eeprom_busy_wait(); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
@@ -485,5 +456,52 @@
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
#endif
+
+#define __boot_eeprom_spm_safe(func, address, data) \
+do { \
+ boot_spm_busy_wait(); \
+ eeprom_busy_wait(); \
+ func (address, data); \
+} while (0)
+
+/** \ingroup avr_boot
+
+ Same as boot_page_fill() except it waits for eeprom and spm operations to
+ complete before filling the page. */
+
+#define boot_page_fill_safe(address, data) \
+ __boot_eeprom_spm_safe (boot_page_fill, address, data)
+
+/** \ingroup avr_boot
+
+ Same as boot_page_erase() except it waits for eeprom and spm operations to
+ complete before erasing the page. */
+
+#define boot_page_erase_safe(address, data) \
+ __boot_eeprom_spm_safe (boot_page_erase, address, data)
+
+/** \ingroup avr_boot
+
+ Same as boot_page_write() except it waits for eeprom and spm operations to
+ complete before writing the page. */
+
+#define boot_page_write_safe(address, data) \
+ __boot_eeprom_spm_safe (boot_page_wrte, address, data)
+
+/** \ingroup avr_boot
+
+ Same as boot_rww_enable() except waits for eeprom and spm operations to
+ complete before enabling the RWW mameory. */
+
+#define boot_rww_enable_safe(address, data) \
+ __boot_eeprom_spm_safe (boot_rww_enable, address, data)
+
+/** \ingroup avr_boot
+
+ Same as boot_lock_bits_set() except waits for eeprom and spm operations to
+ complete before setting the lock bits. */
+
+#define boot_lock_bits_set_safe(address, data) \
+ __boot_eeprom_spm_safe (boot_lock_bits_set, address, data)
#endif /* _AVR_BOOT_H_ */