2006-05-01 19:10:39 +02:00
|
|
|
//
|
|
|
|
// Low-level bootloader routines to replace "assembly.s90"
|
2006-05-01 19:12:13 +02:00
|
|
|
// from the original ATMEL Butterfly bootloader code
|
|
|
|
// which are not included in avr-libc's boot.h by the
|
|
|
|
// time of writing this.
|
2006-05-01 19:10:39 +02:00
|
|
|
//
|
|
|
|
// 3/2004 Martin Thomas, Kaiserslautern, Germany
|
|
|
|
//
|
|
|
|
|
2006-05-01 19:12:13 +02:00
|
|
|
#include "lowlevel.h"
|
2006-05-01 19:10:39 +02:00
|
|
|
|
2006-05-01 19:12:13 +02:00
|
|
|
unsigned int read_program_memory(unsigned int adr, unsigned char param)
|
2006-05-01 19:10:39 +02:00
|
|
|
// to read lockbits give param=0x09, if param!=0 it is written to SPMCSR
|
|
|
|
// this is a "translation" from the original code to gcc-inline-assembler
|
|
|
|
{
|
|
|
|
unsigned int retval;
|
|
|
|
|
|
|
|
asm volatile
|
|
|
|
(
|
|
|
|
"movw r30, %3\n\t"
|
|
|
|
"sbrc %2,0x00\n\t"
|
|
|
|
"sts %0, %2\n\t"
|
|
|
|
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ
|
|
|
|
"elpm\n\t" // read LSB
|
|
|
|
#else
|
|
|
|
"lpm\n\t" // R0 is now the LSB of the return value
|
|
|
|
#endif
|
|
|
|
"mov %A1,r0\n\t"
|
|
|
|
"inc r30\n\t"
|
|
|
|
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ
|
|
|
|
"elpm\n\t" // read MSB
|
|
|
|
#else
|
|
|
|
"lpm\n\t" // R0 is now the MSB of the return value
|
|
|
|
#endif
|
|
|
|
"mov %B1,r0\n\t"
|
|
|
|
: "=m" (SPM_REG),
|
|
|
|
"=r" (retval)
|
|
|
|
: "r" ((unsigned char)param),
|
|
|
|
"r" ((unsigned short)adr)
|
|
|
|
: "r30", "r31", "r0"
|
|
|
|
);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|