32 #define _AVR_BOOT_H_ 1
104 #include <avr/eeprom.h>
111 # define __SPM_REG SPMCSR
114 # define __SPM_REG SPMCR
116 # error AVR processor does not provide bootloader support!
123 # define __SPM_ENABLE SPMEN
124 #elif defined(SELFPRGEN)
125 # define __SPM_ENABLE SELFPRGEN
127 # error Cannot find SPM Enable bit definition!
138 #define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))
143 #define __COMMON_ASB ASB
145 #define __COMMON_ASB RWWSB
149 #define __COMMON_ASRE ASRE
151 #define __COMMON_ASRE RWWSRE
166 #define boot_spm_interrupt_enable() (__SPM_REG |= (uint8_t)_BV(SPMIE))
172 #define boot_spm_interrupt_disable() (__SPM_REG &= (uint8_t)~_BV(SPMIE))
178 #define boot_is_spm_interrupt() (__SPM_REG & (uint8_t)_BV(SPMIE))
184 #define boot_rww_busy() (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
190 #define boot_spm_busy() (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE))
196 #define boot_spm_busy_wait() do{}while(boot_spm_busy())
199 #define __BOOT_PAGE_ERASE (_BV(__SPM_ENABLE) | _BV(PGERS))
200 #define __BOOT_PAGE_WRITE (_BV(__SPM_ENABLE) | _BV(PGWRT))
201 #define __BOOT_PAGE_FILL _BV(__SPM_ENABLE)
202 #define __BOOT_RWW_ENABLE (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE))
204 #define __BOOT_LOCK_BITS_SET (_BV(__SPM_ENABLE) | _BV(BLBSET))
206 #define __BOOT_LOCK_BITS_SET (_BV(__SPM_ENABLE) | _BV(RFLB))
209 #define __boot_page_fill_normal(address, data) \
211 __asm__ __volatile__ \
218 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
219 "r" ((uint8_t)(__BOOT_PAGE_FILL)), \
220 "z" ((uint16_t)(address)), \
221 "r" ((uint16_t)(data)) \
226 #define __boot_page_fill_alternate(address, data)\
228 __asm__ __volatile__ \
237 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
238 "r" ((uint8_t)(__BOOT_PAGE_FILL)), \
239 "z" ((uint16_t)(address)), \
240 "r" ((uint16_t)(data)) \
245 #define __boot_page_fill_extended(address, data) \
247 __asm__ __volatile__ \
250 "movw r30, %A3\n\t" \
256 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
257 "i" (_SFR_MEM_ADDR(RAMPZ)), \
258 "r" ((uint8_t)(__BOOT_PAGE_FILL)), \
259 "r" ((uint32_t)(address)), \
260 "r" ((uint16_t)(data)) \
261 : "r0", "r30", "r31" \
265 #define __boot_page_erase_normal(address) \
267 __asm__ __volatile__ \
272 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
273 "r" ((uint8_t)(__BOOT_PAGE_ERASE)), \
274 "z" ((uint16_t)(address)) \
278 #define __boot_page_erase_alternate(address) \
280 __asm__ __volatile__ \
287 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
288 "r" ((uint8_t)(__BOOT_PAGE_ERASE)), \
289 "z" ((uint16_t)(address)) \
293 #define __boot_page_erase_extended(address) \
295 __asm__ __volatile__ \
297 "movw r30, %A3\n\t" \
302 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
303 "i" (_SFR_MEM_ADDR(RAMPZ)), \
304 "r" ((uint8_t)(__BOOT_PAGE_ERASE)), \
305 "r" ((uint32_t)(address)) \
310 #define __boot_page_write_normal(address) \
312 __asm__ __volatile__ \
317 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
318 "r" ((uint8_t)(__BOOT_PAGE_WRITE)), \
319 "z" ((uint16_t)(address)) \
323 #define __boot_page_write_alternate(address) \
325 __asm__ __volatile__ \
332 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
333 "r" ((uint8_t)(__BOOT_PAGE_WRITE)), \
334 "z" ((uint16_t)(address)) \
338 #define __boot_page_write_extended(address) \
340 __asm__ __volatile__ \
342 "movw r30, %A3\n\t" \
347 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
348 "i" (_SFR_MEM_ADDR(RAMPZ)), \
349 "r" ((uint8_t)(__BOOT_PAGE_WRITE)), \
350 "r" ((uint32_t)(address)) \
355 #define __boot_rww_enable() \
357 __asm__ __volatile__ \
362 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
363 "r" ((uint8_t)(__BOOT_RWW_ENABLE)) \
367 #define __boot_rww_enable_alternate() \
369 __asm__ __volatile__ \
376 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
377 "r" ((uint8_t)(__BOOT_RWW_ENABLE)) \
398 #define __boot_lock_bits_set(lock_bits) \
400 uint8_t value = (uint8_t)(~(lock_bits)); \
401 __asm__ __volatile__ \
409 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
410 "r" ((uint8_t)(__BOOT_LOCK_BITS_SET)), \
412 : "r0", "r30", "r31" \
416 #define __boot_lock_bits_set_alternate(lock_bits) \
418 uint8_t value = (uint8_t)(~(lock_bits)); \
419 __asm__ __volatile__ \
429 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
430 "r" ((uint8_t)(__BOOT_LOCK_BITS_SET)), \
432 : "r0", "r30", "r31" \
460 #define GET_LOW_FUSE_BITS (0x0000)
465 #define GET_LOCK_BITS (0x0001)
470 #define GET_EXTENDED_FUSE_BITS (0x0002)
475 #define GET_HIGH_FUSE_BITS (0x0003)
489 #define boot_lock_fuse_bits_get(address) \
492 __asm__ __volatile__ \
497 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
498 "r" ((uint8_t)(__BOOT_LOCK_BITS_SET)), \
499 "z" ((uint16_t)(address)) \
505 #define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
518 #define boot_signature_byte_get(addr) \
521 __asm__ __volatile__ \
526 : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
527 "r" ((uint8_t)(__BOOT_SIGROW_READ)), \
528 "z" ((uint16_t)(addr)) \
594 #if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
595 || defined(__AVR_ATmega323__)
598 #define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
599 #define boot_page_erase(address) __boot_page_erase_alternate(address)
600 #define boot_page_write(address) __boot_page_write_alternate(address)
601 #define boot_rww_enable() __boot_rww_enable_alternate()
602 #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
604 #elif (FLASHEND > USHRT_MAX)
607 #define boot_page_fill(address, data) __boot_page_fill_extended(address, data)
608 #define boot_page_erase(address) __boot_page_erase_extended(address)
609 #define boot_page_write(address) __boot_page_write_extended(address)
610 #define boot_rww_enable() __boot_rww_enable()
611 #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
616 #define boot_page_fill(address, data) __boot_page_fill_normal(address, data)
617 #define boot_page_erase(address) __boot_page_erase_normal(address)
618 #define boot_page_write(address) __boot_page_write_normal(address)
619 #define boot_rww_enable() __boot_rww_enable()
620 #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
629 #define boot_page_fill_safe(address, data) \
631 boot_spm_busy_wait(); \
632 eeprom_busy_wait(); \
633 boot_page_fill(address, data); \
641 #define boot_page_erase_safe(address) \
643 boot_spm_busy_wait(); \
644 eeprom_busy_wait(); \
645 boot_page_erase (address); \
653 #define boot_page_write_safe(address) \
655 boot_spm_busy_wait(); \
656 eeprom_busy_wait(); \
657 boot_page_write (address); \
665 #define boot_rww_enable_safe() \
667 boot_spm_busy_wait(); \
668 eeprom_busy_wait(); \
677 #define boot_lock_bits_set_safe(lock_bits) \
679 boot_spm_busy_wait(); \
680 eeprom_busy_wait(); \
681 boot_lock_bits_set (lock_bits); \