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_ */