📄 avr_libc_1_0_boot.h
字号:
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_PAGE_ERASE),\
"r" ((unsigned short)address) \
: "r30", "r31" \
); \
})
#define __boot_page_erase_alternate(address) \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_PAGE_ERASE),\
"r" ((unsigned short)address) \
: "r30", "r31" \
); \
})
#define __boot_page_erase_extended(address) \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG), \
"=m" (RAMPZ) \
: "r" ((unsigned char)__BOOT_PAGE_ERASE),\
"r" ((unsigned long)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_normal(address) \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_PAGE_WRITE),\
"r" ((unsigned short)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_alternate(address) \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_PAGE_WRITE),\
"r" ((unsigned short)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_extended(address) \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG), \
"=m" (RAMPZ) \
: "r" ((unsigned char)__BOOT_PAGE_WRITE),\
"r" ((unsigned long)address) \
: "r30", "r31" \
); \
})
#define __boot_rww_enable() \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_RWW_ENABLE) \
); \
})
#define __boot_rww_enable_alternate() \
({ \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_RWW_ENABLE) \
); \
})
#define __boot_lock_bits_set(lock_bits) \
({ \
unsigned char value = (unsigned char)(lock_bits | __BOOT_LOCK_BITS_MASK); \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
})
#define __boot_lock_bits_set_alternate(lock_bits) \
({ \
unsigned char value = (unsigned char)(lock_bits | __BOOT_LOCK_BITS_MASK); \
boot_spm_busy_wait(); \
while(!eeprom_is_ready()); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((unsigned char)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
})
/** \ingroup avr_boot
\def boot_page_fill(address, data)
Fill the bootloader temporary page buffer for flash
address with data word.
\note The address is a byte address. The data is a word. The AVR
writes data to the buffer a word at a time, but addresses the buffer
per byte! So, increment your address by 2 between calls, and send 2
data bytes in a word format! The LSB of the data is written to the lower
address; the MSB of the data is written to the higher address.*/
/** \ingroup avr_boot
\def boot_page_erase(address)
Erase the flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_page_write(address)
Write the bootloader temporary page buffer
to flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_rww_enable()
Enable the Read-While-Write memory section. */
/** \ingroup avr_boot
\def boot_lock_bits_set(lock_bits)
Set the bootloader lock bits. */
/* Normal versions of the macros use 16-bit addresses.
Extended versions of the macros use 32-bit addresses.
Alternate versions of the macros use 16-bit addresses and require special
instruction sequences after LPM.
FLASHEND is defined in the ioXXXX.h file.
USHRT_MAX is defined in <limits.h>. */
#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
|| defined(__AVR_ATmega323__)
/* Alternate: ATmega161/163/323 and 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
#define boot_page_erase(address) __boot_page_erase_alternate(address)
#define boot_page_write(address) __boot_page_write_alternate(address)
#define boot_rww_enable() __boot_rww_enable_alternate()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
#elif (FLASHEND > USHRT_MAX)
/* Extended: >16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_extended(address, data)
#define boot_page_erase(address) __boot_page_erase_extended(address)
#define boot_page_write(address) __boot_page_write_extended(address)
#define boot_rww_enable() __boot_rww_enable()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
#else
/* Normal: 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_normal(address, data)
#define boot_page_erase(address) __boot_page_erase_normal(address)
#define boot_page_write(address) __boot_page_write_normal(address)
#define boot_rww_enable() __boot_rww_enable()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
#endif
#endif /* _AVR_BOOT_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -