From: Stephan Baerwolf Date: Sun, 19 Aug 2012 23:55:38 +0000 (+0200) Subject: extend "spminterface.h" by implementing "do_spm" X-Git-Tag: v0.3~2 X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/commitdiff_plain/192ac893bcf0acc26c25fdd9bf213fecf80128fd extend "spminterface.h" by implementing "do_spm" Signed-off-by: Stephan Baerwolf --- diff --git a/firmware/spminterface.h b/firmware/spminterface.h index d67c3e9..2fca2cd 100644 --- a/firmware/spminterface.h +++ b/firmware/spminterface.h @@ -90,6 +90,70 @@ ret #ifndef BOOTLOADER_ADDRESS // this header is the interface for user-code +#ifndef funcaddr___bootloader__do_spm + #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__) + #define funcaddr___bootloader__do_spm 0x1826 + + #else + #error "unknown MCU - where is bootloader__do_spm located?" + #endif +#endif + + +/* + * Call the "bootloader__do_spm"-function, located within the BLS via comfortable C-interface + * During operation code will block - disable or reset watchdog before call. + * + * + * REMEMBER: interrupts have to be disabled! (otherwise code may crash non-deterministic) + * + */ +void do_spm(const uint32_t flash_byteaddress, const uint8_t spmcrval, const uint8_t r1_highdatabyte, const uint8_t r0_lowdatabyte) { + uint8_t loaddr = (flash_byteaddress >> 0) & 0xff; + uint8_t hiaddr = (flash_byteaddress >> 8) & 0xff; + uint8_t adaddr = (flash_byteaddress >> 16) & 0xff; + + asm volatile ( + "push r0\n\t" + "push r1\n\t" + + "mov r13, %[hiaddr]\n\t" + "mov r12, %[loaddr]\n\t" + "mov r11, %[adaddr]\n\t" + + + /* high8 of address of bootloader__do_spm */ + "ldi r18, %[hi8spmfunc]\n\t" + "mov r31, r18\n\t" + + /* low8 of address of bootloader__do_spm */ + "ldi r18, %[lo8spmfunc]\n\t" + "mov r30, r18\n\t" + + /* also load the spmcrval */ + "mov r18, %[spmcrval]\n\t" + + /* correkt address of bootloader__do_spm from bytes into words */ + "lsr r31\n\t" + "ror r30\n\t" + + "mov r1, %[hidata]\n\t" + "mov r0, %[lodata]\n\t" + + /* finally call the bootloader-function */ + "icall\n\r" + + "pop r1\n\t" + "pop r0\n\t" + + : + : [loaddr] "r" (loaddr), [hiaddr] "r" (hiaddr), [adaddr] "r" (adaddr), [spmcrval] "r" (spmcrval), + [lodata] "r" (r0_lowdatabyte), [hidata] "r" (r1_highdatabyte), + [hi8spmfunc] "M" (funcaddr___bootloader__do_spm >> 8), [lo8spmfunc] "M" (funcaddr___bootloader__do_spm & 0xff) + + : "r0","r1","r11","r12","r13","r18" + ); +}