1047 lines
37 KiB
Plaintext
1047 lines
37 KiB
Plaintext
|
|
optiboot_atmega328.elf: file format elf32-avr
|
|
|
|
Sections:
|
|
Idx Name Size VMA LMA File off Algn
|
|
0 .text 000003f8 00007c00 00007c00 00000054 2**1
|
|
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
|
1 .version 00000002 00007ffe 00007ffe 0000044c 2**0
|
|
CONTENTS, READONLY
|
|
2 .debug_aranges 00000028 00000000 00000000 0000044e 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
3 .debug_pubnames 000000b8 00000000 00000000 00000476 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
4 .debug_info 000003d5 00000000 00000000 0000052e 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
5 .debug_abbrev 000001a4 00000000 00000000 00000903 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
6 .debug_line 0000065d 00000000 00000000 00000aa7 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
7 .debug_frame 000000d0 00000000 00000000 00001104 2**2
|
|
CONTENTS, READONLY, DEBUGGING
|
|
8 .debug_str 00000191 00000000 00000000 000011d4 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
9 .debug_loc 000003ac 00000000 00000000 00001365 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
10 .debug_ranges 000000a0 00000000 00000000 00001711 2**0
|
|
CONTENTS, READONLY, DEBUGGING
|
|
|
|
Disassembly of section .text:
|
|
|
|
00007c00 <main>:
|
|
}
|
|
/******************* END SPI FLASH Code ****************************/
|
|
|
|
|
|
/* main program starts here */
|
|
int main(void) {
|
|
7c00: 11 24 eor r1, r1
|
|
#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
|
|
SP=RAMEND; // This is done by hardware reset
|
|
#endif
|
|
|
|
// Adaboot no-wait mod
|
|
ch = MCUSR;
|
|
7c02: 04 b7 in r16, 0x34 ; 52
|
|
MCUSR = 0;
|
|
7c04: 14 be out 0x34, r1 ; 52
|
|
|
|
#ifdef DEBUG_ON
|
|
putch('S');
|
|
#endif
|
|
|
|
if (!(ch & _BV(EXTRF))) //if not external reset
|
|
7c06: 01 fd sbrc r16, 1
|
|
7c08: 07 c0 rjmp .+14 ; 0x7c18 <main+0x18>
|
|
{
|
|
if (ch & _BV(WDRF)) //if reset by watchdog
|
|
7c0a: 03 fd sbrc r16, 3
|
|
CheckFlashImage();
|
|
7c0c: 27 d1 rcall .+590 ; 0x7e5c <CheckFlashImage>
|
|
#ifdef DEBUG_ON
|
|
putch('A');
|
|
#endif
|
|
SPCR &= ~_BV(SPE) & ~_BV(MSTR);
|
|
7c0e: 8c b5 in r24, 0x2c ; 44
|
|
7c10: 8f 7a andi r24, 0xAF ; 175
|
|
7c12: 8c bd out 0x2c, r24 ; 44
|
|
appStart(ch);
|
|
7c14: 80 2f mov r24, r16
|
|
7c16: ea d1 rcall .+980 ; 0x7fec <appStart>
|
|
}
|
|
|
|
#if LED_START_FLASHES > 0
|
|
// Set up Timer 1 for timeout counter
|
|
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
|
|
7c18: 85 e0 ldi r24, 0x05 ; 5
|
|
7c1a: 80 93 81 00 sts 0x0081, r24
|
|
UCSRA = _BV(U2X); //Double speed mode USART
|
|
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
|
|
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
|
|
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
|
|
#else
|
|
UART_SRA = _BV(U2X0); //Double speed mode USART0
|
|
7c1e: 82 e0 ldi r24, 0x02 ; 2
|
|
7c20: 80 93 c0 00 sts 0x00C0, r24
|
|
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
|
|
7c24: 88 e1 ldi r24, 0x18 ; 24
|
|
7c26: 80 93 c1 00 sts 0x00C1, r24
|
|
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
|
|
7c2a: 86 e0 ldi r24, 0x06 ; 6
|
|
7c2c: 80 93 c2 00 sts 0x00C2, r24
|
|
UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
|
|
7c30: 87 e6 ldi r24, 0x67 ; 103
|
|
7c32: 80 93 c4 00 sts 0x00C4, r24
|
|
#endif
|
|
#endif
|
|
|
|
// Set up watchdog to trigger after 500ms
|
|
watchdogConfig(WATCHDOG_1S);
|
|
7c36: 8e e0 ldi r24, 0x0E ; 14
|
|
7c38: fb d0 rcall .+502 ; 0x7e30 <watchdogConfig>
|
|
|
|
#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
|
|
/* Set LED pin as output */
|
|
LED_DDR |= _BV(LED);
|
|
7c3a: 55 9a sbi 0x0a, 5 ; 10
|
|
7c3c: 86 e0 ldi r24, 0x06 ; 6
|
|
}
|
|
|
|
#if LED_START_FLASHES > 0
|
|
void flash_led(uint8_t count) {
|
|
do {
|
|
TCNT1 = -(F_CPU/(1024*16));
|
|
7c3e: 28 e1 ldi r18, 0x18 ; 24
|
|
7c40: 3e ef ldi r19, 0xFE ; 254
|
|
TIFR1 = _BV(TOV1);
|
|
7c42: 91 e0 ldi r25, 0x01 ; 1
|
|
}
|
|
|
|
#if LED_START_FLASHES > 0
|
|
void flash_led(uint8_t count) {
|
|
do {
|
|
TCNT1 = -(F_CPU/(1024*16));
|
|
7c44: 30 93 85 00 sts 0x0085, r19
|
|
7c48: 20 93 84 00 sts 0x0084, r18
|
|
TIFR1 = _BV(TOV1);
|
|
7c4c: 96 bb out 0x16, r25 ; 22
|
|
while(!(TIFR1 & _BV(TOV1)));
|
|
7c4e: b0 9b sbis 0x16, 0 ; 22
|
|
7c50: fe cf rjmp .-4 ; 0x7c4e <main+0x4e>
|
|
#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
|
|
LED_PORT ^= _BV(LED);
|
|
#else
|
|
LED_PIN |= _BV(LED);
|
|
7c52: 4d 9a sbi 0x09, 5 ; 9
|
|
}
|
|
#endif
|
|
|
|
// Watchdog functions. These are only safe with interrupts turned off.
|
|
void watchdogReset() {
|
|
__asm__ __volatile__ (
|
|
7c54: a8 95 wdr
|
|
LED_PORT ^= _BV(LED);
|
|
#else
|
|
LED_PIN |= _BV(LED);
|
|
#endif
|
|
watchdogReset();
|
|
} while (--count);
|
|
7c56: 81 50 subi r24, 0x01 ; 1
|
|
7c58: a9 f7 brne .-22 ; 0x7c44 <main+0x44>
|
|
7c5a: ee 24 eor r14, r14
|
|
7c5c: ff 24 eor r15, r15
|
|
ch = SPM_PAGESIZE / 2;
|
|
do {
|
|
uint16_t a;
|
|
a = *bufPtr++;
|
|
a |= (*bufPtr++) << 8;
|
|
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
|
|
7c5e: aa 24 eor r10, r10
|
|
7c60: a3 94 inc r10
|
|
addrPtr += 2;
|
|
} while (--ch);
|
|
|
|
// Write from programming buffer
|
|
__boot_page_write_short((uint16_t)(void*)address);
|
|
7c62: b5 e0 ldi r27, 0x05 ; 5
|
|
7c64: cb 2e mov r12, r27
|
|
boot_spm_busy_wait();
|
|
|
|
#if defined(RWWSRE)
|
|
// Reenable read access to flash
|
|
boot_rww_enable();
|
|
7c66: a1 e1 ldi r26, 0x11 ; 17
|
|
7c68: ba 2e mov r11, r26
|
|
|
|
// If we are in NRWW section, page erase has to be delayed until now.
|
|
// Todo: Take RAMPZ into account (not doing so just means that we will
|
|
// treat the top of both "pages" of flash as NRWW, for a slight speed
|
|
// decrease, so fixing this is not urgent.)
|
|
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
|
7c6a: f3 e0 ldi r31, 0x03 ; 3
|
|
7c6c: df 2e mov r13, r31
|
|
#endif
|
|
|
|
/* Forever loop */
|
|
for (;;) {
|
|
/* get character from UART */
|
|
ch = getch();
|
|
7c6e: d2 d0 rcall .+420 ; 0x7e14 <getch>
|
|
|
|
if(ch == STK_GET_PARAMETER) {
|
|
7c70: 81 34 cpi r24, 0x41 ; 65
|
|
7c72: 61 f4 brne .+24 ; 0x7c8c <main+0x8c>
|
|
unsigned char which = getch();
|
|
7c74: cf d0 rcall .+414 ; 0x7e14 <getch>
|
|
7c76: 08 2f mov r16, r24
|
|
verifySpace();
|
|
7c78: e1 d0 rcall .+450 ; 0x7e3c <verifySpace>
|
|
if (which == 0x82) {
|
|
7c7a: 02 38 cpi r16, 0x82 ; 130
|
|
7c7c: 29 f1 breq .+74 ; 0x7cc8 <main+0xc8>
|
|
/*
|
|
* Send optiboot version as "minor SW version"
|
|
*/
|
|
putch(OPTIBOOT_MINVER);
|
|
} else if (which == 0x81) {
|
|
7c7e: 01 38 cpi r16, 0x81 ; 129
|
|
7c80: 11 f4 brne .+4 ; 0x7c86 <main+0x86>
|
|
putch(OPTIBOOT_MAJVER);
|
|
7c82: 85 e0 ldi r24, 0x05 ; 5
|
|
7c84: 01 c0 rjmp .+2 ; 0x7c88 <main+0x88>
|
|
} else {
|
|
/*
|
|
* GET PARAMETER returns a generic 0x03 reply for
|
|
* other parameters - enough to keep Avrdude happy
|
|
*/
|
|
putch(0x03);
|
|
7c86: 83 e0 ldi r24, 0x03 ; 3
|
|
7c88: bd d0 rcall .+378 ; 0x7e04 <putch>
|
|
7c8a: 7f c0 rjmp .+254 ; 0x7d8a <main+0x18a>
|
|
}
|
|
}
|
|
else if(ch == STK_SET_DEVICE) {
|
|
7c8c: 82 34 cpi r24, 0x42 ; 66
|
|
7c8e: 11 f4 brne .+4 ; 0x7c94 <main+0x94>
|
|
// SET DEVICE is ignored
|
|
getNch(20);
|
|
7c90: 84 e1 ldi r24, 0x14 ; 20
|
|
7c92: 03 c0 rjmp .+6 ; 0x7c9a <main+0x9a>
|
|
}
|
|
else if(ch == STK_SET_DEVICE_EXT) {
|
|
7c94: 85 34 cpi r24, 0x45 ; 69
|
|
7c96: 19 f4 brne .+6 ; 0x7c9e <main+0x9e>
|
|
// SET DEVICE EXT is ignored
|
|
getNch(5);
|
|
7c98: 85 e0 ldi r24, 0x05 ; 5
|
|
7c9a: d8 d0 rcall .+432 ; 0x7e4c <verifySpace+0x10>
|
|
7c9c: 76 c0 rjmp .+236 ; 0x7d8a <main+0x18a>
|
|
}
|
|
else if(ch == STK_LOAD_ADDRESS) {
|
|
7c9e: 85 35 cpi r24, 0x55 ; 85
|
|
7ca0: 79 f4 brne .+30 ; 0x7cc0 <main+0xc0>
|
|
// LOAD ADDRESS
|
|
uint16_t newAddress;
|
|
newAddress = getch();
|
|
7ca2: b8 d0 rcall .+368 ; 0x7e14 <getch>
|
|
newAddress = (newAddress & 0xff) | (getch() << 8);
|
|
7ca4: e8 2e mov r14, r24
|
|
7ca6: ff 24 eor r15, r15
|
|
7ca8: b5 d0 rcall .+362 ; 0x7e14 <getch>
|
|
7caa: 08 2f mov r16, r24
|
|
7cac: 10 e0 ldi r17, 0x00 ; 0
|
|
7cae: 10 2f mov r17, r16
|
|
7cb0: 00 27 eor r16, r16
|
|
7cb2: 0e 29 or r16, r14
|
|
7cb4: 1f 29 or r17, r15
|
|
#ifdef RAMPZ
|
|
// Transfer top bit to RAMPZ
|
|
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
|
|
#endif
|
|
newAddress += newAddress; // Convert from word address to byte address
|
|
7cb6: 00 0f add r16, r16
|
|
7cb8: 11 1f adc r17, r17
|
|
address = newAddress;
|
|
verifySpace();
|
|
7cba: c0 d0 rcall .+384 ; 0x7e3c <verifySpace>
|
|
7cbc: 78 01 movw r14, r16
|
|
7cbe: 65 c0 rjmp .+202 ; 0x7d8a <main+0x18a>
|
|
}
|
|
else if(ch == STK_UNIVERSAL) {
|
|
7cc0: 86 35 cpi r24, 0x56 ; 86
|
|
7cc2: 21 f4 brne .+8 ; 0x7ccc <main+0xcc>
|
|
// UNIVERSAL command is ignored
|
|
getNch(4);
|
|
7cc4: 84 e0 ldi r24, 0x04 ; 4
|
|
7cc6: c2 d0 rcall .+388 ; 0x7e4c <verifySpace+0x10>
|
|
putch(0x00);
|
|
7cc8: 80 e0 ldi r24, 0x00 ; 0
|
|
7cca: de cf rjmp .-68 ; 0x7c88 <main+0x88>
|
|
}
|
|
/* Write memory, length is big endian and is in bytes */
|
|
else if(ch == STK_PROG_PAGE) {
|
|
7ccc: 84 36 cpi r24, 0x64 ; 100
|
|
7cce: 09 f0 breq .+2 ; 0x7cd2 <main+0xd2>
|
|
7cd0: 40 c0 rjmp .+128 ; 0x7d52 <main+0x152>
|
|
// PROGRAM PAGE - we support flash programming only, not EEPROM
|
|
uint8_t *bufPtr;
|
|
uint16_t addrPtr;
|
|
|
|
getch(); /* getlen() */
|
|
7cd2: a0 d0 rcall .+320 ; 0x7e14 <getch>
|
|
length = getch();
|
|
7cd4: 9f d0 rcall .+318 ; 0x7e14 <getch>
|
|
7cd6: 08 2f mov r16, r24
|
|
getch();
|
|
7cd8: 9d d0 rcall .+314 ; 0x7e14 <getch>
|
|
|
|
// If we are in RWW section, immediately start page erase
|
|
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
|
7cda: 80 e0 ldi r24, 0x00 ; 0
|
|
7cdc: e8 16 cp r14, r24
|
|
7cde: 80 e7 ldi r24, 0x70 ; 112
|
|
7ce0: f8 06 cpc r15, r24
|
|
7ce2: 18 f4 brcc .+6 ; 0x7cea <main+0xea>
|
|
7ce4: f7 01 movw r30, r14
|
|
7ce6: d7 be out 0x37, r13 ; 55
|
|
7ce8: e8 95 spm
|
|
7cea: c0 e0 ldi r28, 0x00 ; 0
|
|
7cec: d1 e0 ldi r29, 0x01 ; 1
|
|
|
|
// While that is going on, read in page contents
|
|
bufPtr = buff;
|
|
do *bufPtr++ = getch();
|
|
7cee: 92 d0 rcall .+292 ; 0x7e14 <getch>
|
|
7cf0: 89 93 st Y+, r24
|
|
while (--length);
|
|
7cf2: 0c 17 cp r16, r28
|
|
7cf4: e1 f7 brne .-8 ; 0x7cee <main+0xee>
|
|
|
|
// If we are in NRWW section, page erase has to be delayed until now.
|
|
// Todo: Take RAMPZ into account (not doing so just means that we will
|
|
// treat the top of both "pages" of flash as NRWW, for a slight speed
|
|
// decrease, so fixing this is not urgent.)
|
|
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
|
7cf6: f0 e0 ldi r31, 0x00 ; 0
|
|
7cf8: ef 16 cp r14, r31
|
|
7cfa: f0 e7 ldi r31, 0x70 ; 112
|
|
7cfc: ff 06 cpc r15, r31
|
|
7cfe: 18 f0 brcs .+6 ; 0x7d06 <main+0x106>
|
|
7d00: f7 01 movw r30, r14
|
|
7d02: d7 be out 0x37, r13 ; 55
|
|
7d04: e8 95 spm
|
|
|
|
// Read command terminator, start reply
|
|
verifySpace();
|
|
7d06: 9a d0 rcall .+308 ; 0x7e3c <verifySpace>
|
|
|
|
// If only a partial page is to be programmed, the erase might not be complete.
|
|
// So check that here
|
|
boot_spm_busy_wait();
|
|
7d08: 07 b6 in r0, 0x37 ; 55
|
|
7d0a: 00 fc sbrc r0, 0
|
|
7d0c: fd cf rjmp .-6 ; 0x7d08 <main+0x108>
|
|
7d0e: a7 01 movw r20, r14
|
|
7d10: a0 e0 ldi r26, 0x00 ; 0
|
|
7d12: b1 e0 ldi r27, 0x01 ; 1
|
|
bufPtr = buff;
|
|
addrPtr = (uint16_t)(void*)address;
|
|
ch = SPM_PAGESIZE / 2;
|
|
do {
|
|
uint16_t a;
|
|
a = *bufPtr++;
|
|
7d14: 2c 91 ld r18, X
|
|
7d16: 30 e0 ldi r19, 0x00 ; 0
|
|
a |= (*bufPtr++) << 8;
|
|
7d18: 11 96 adiw r26, 0x01 ; 1
|
|
7d1a: 8c 91 ld r24, X
|
|
7d1c: 11 97 sbiw r26, 0x01 ; 1
|
|
7d1e: 90 e0 ldi r25, 0x00 ; 0
|
|
7d20: 98 2f mov r25, r24
|
|
7d22: 88 27 eor r24, r24
|
|
7d24: 82 2b or r24, r18
|
|
7d26: 93 2b or r25, r19
|
|
}
|
|
/******************* END SPI FLASH Code ****************************/
|
|
|
|
|
|
/* main program starts here */
|
|
int main(void) {
|
|
7d28: 12 96 adiw r26, 0x02 ; 2
|
|
ch = SPM_PAGESIZE / 2;
|
|
do {
|
|
uint16_t a;
|
|
a = *bufPtr++;
|
|
a |= (*bufPtr++) << 8;
|
|
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
|
|
7d2a: fa 01 movw r30, r20
|
|
7d2c: 0c 01 movw r0, r24
|
|
7d2e: a7 be out 0x37, r10 ; 55
|
|
7d30: e8 95 spm
|
|
7d32: 11 24 eor r1, r1
|
|
addrPtr += 2;
|
|
7d34: 4e 5f subi r20, 0xFE ; 254
|
|
7d36: 5f 4f sbci r21, 0xFF ; 255
|
|
} while (--ch);
|
|
7d38: f1 e0 ldi r31, 0x01 ; 1
|
|
7d3a: a0 38 cpi r26, 0x80 ; 128
|
|
7d3c: bf 07 cpc r27, r31
|
|
7d3e: 51 f7 brne .-44 ; 0x7d14 <main+0x114>
|
|
|
|
// Write from programming buffer
|
|
__boot_page_write_short((uint16_t)(void*)address);
|
|
7d40: f7 01 movw r30, r14
|
|
7d42: c7 be out 0x37, r12 ; 55
|
|
7d44: e8 95 spm
|
|
boot_spm_busy_wait();
|
|
7d46: 07 b6 in r0, 0x37 ; 55
|
|
7d48: 00 fc sbrc r0, 0
|
|
7d4a: fd cf rjmp .-6 ; 0x7d46 <main+0x146>
|
|
|
|
#if defined(RWWSRE)
|
|
// Reenable read access to flash
|
|
boot_rww_enable();
|
|
7d4c: b7 be out 0x37, r11 ; 55
|
|
7d4e: e8 95 spm
|
|
7d50: 1c c0 rjmp .+56 ; 0x7d8a <main+0x18a>
|
|
#endif
|
|
|
|
}
|
|
/* Read memory block mode, length is big endian. */
|
|
else if(ch == STK_READ_PAGE) {
|
|
7d52: 84 37 cpi r24, 0x74 ; 116
|
|
7d54: 61 f4 brne .+24 ; 0x7d6e <main+0x16e>
|
|
// READ PAGE - we only read flash
|
|
getch(); /* getlen() */
|
|
7d56: 5e d0 rcall .+188 ; 0x7e14 <getch>
|
|
length = getch();
|
|
7d58: 5d d0 rcall .+186 ; 0x7e14 <getch>
|
|
7d5a: 08 2f mov r16, r24
|
|
getch();
|
|
7d5c: 5b d0 rcall .+182 ; 0x7e14 <getch>
|
|
|
|
verifySpace();
|
|
7d5e: 6e d0 rcall .+220 ; 0x7e3c <verifySpace>
|
|
__asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
|
|
#else
|
|
// read a Flash byte and increment the address
|
|
__asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
|
|
#endif
|
|
putch(ch);
|
|
7d60: f7 01 movw r30, r14
|
|
7d62: 85 91 lpm r24, Z+
|
|
7d64: 7f 01 movw r14, r30
|
|
7d66: 4e d0 rcall .+156 ; 0x7e04 <putch>
|
|
} while (--length);
|
|
7d68: 01 50 subi r16, 0x01 ; 1
|
|
7d6a: d1 f7 brne .-12 ; 0x7d60 <main+0x160>
|
|
7d6c: 0e c0 rjmp .+28 ; 0x7d8a <main+0x18a>
|
|
}
|
|
|
|
/* Get device signature bytes */
|
|
else if(ch == STK_READ_SIGN) {
|
|
7d6e: 85 37 cpi r24, 0x75 ; 117
|
|
7d70: 39 f4 brne .+14 ; 0x7d80 <main+0x180>
|
|
// READ SIGN - return what Avrdude wants to hear
|
|
verifySpace();
|
|
7d72: 64 d0 rcall .+200 ; 0x7e3c <verifySpace>
|
|
putch(SIGNATURE_0);
|
|
7d74: 8e e1 ldi r24, 0x1E ; 30
|
|
7d76: 46 d0 rcall .+140 ; 0x7e04 <putch>
|
|
putch(SIGNATURE_1);
|
|
7d78: 85 e9 ldi r24, 0x95 ; 149
|
|
7d7a: 44 d0 rcall .+136 ; 0x7e04 <putch>
|
|
putch(SIGNATURE_2);
|
|
7d7c: 8f e0 ldi r24, 0x0F ; 15
|
|
7d7e: 84 cf rjmp .-248 ; 0x7c88 <main+0x88>
|
|
}
|
|
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
|
|
7d80: 81 35 cpi r24, 0x51 ; 81
|
|
7d82: 11 f4 brne .+4 ; 0x7d88 <main+0x188>
|
|
// Adaboot no-wait mod
|
|
watchdogConfig(WATCHDOG_16MS);
|
|
7d84: 88 e0 ldi r24, 0x08 ; 8
|
|
7d86: 54 d0 rcall .+168 ; 0x7e30 <watchdogConfig>
|
|
verifySpace();
|
|
}
|
|
else {
|
|
// This covers the response to commands like STK_ENTER_PROGMODE
|
|
verifySpace();
|
|
7d88: 59 d0 rcall .+178 ; 0x7e3c <verifySpace>
|
|
}
|
|
putch(STK_OK);
|
|
7d8a: 80 e1 ldi r24, 0x10 ; 16
|
|
7d8c: 3b d0 rcall .+118 ; 0x7e04 <putch>
|
|
7d8e: 6f cf rjmp .-290 ; 0x7c6e <main+0x6e>
|
|
|
|
00007d90 <SPI_transfer>:
|
|
#define SPIFLASH_JEDECID 0x9F // read JEDEC ID
|
|
//#define DEBUG_ON // uncomment to enable Serial debugging
|
|
// (will output different characters depending on which path the bootloader takes)
|
|
|
|
uint8_t SPI_transfer(uint8_t _data) {
|
|
SPDR = _data;
|
|
7d90: 8e bd out 0x2e, r24 ; 46
|
|
while (!(SPSR & _BV(SPIF)));
|
|
7d92: 0d b4 in r0, 0x2d ; 45
|
|
7d94: 07 fe sbrs r0, 7
|
|
7d96: fd cf rjmp .-6 ; 0x7d92 <SPI_transfer+0x2>
|
|
return SPDR;
|
|
7d98: 8e b5 in r24, 0x2e ; 46
|
|
}
|
|
7d9a: 08 95 ret
|
|
|
|
00007d9c <FLASH_busy>:
|
|
|
|
uint8_t FLASH_busy()
|
|
{
|
|
FLASH_SELECT;
|
|
7d9c: 28 98 cbi 0x05, 0 ; 5
|
|
SPI_transfer(SPIFLASH_STATUSREAD);
|
|
7d9e: 85 e0 ldi r24, 0x05 ; 5
|
|
7da0: f7 df rcall .-18 ; 0x7d90 <SPI_transfer>
|
|
uint8_t status = SPI_transfer(0);
|
|
7da2: 80 e0 ldi r24, 0x00 ; 0
|
|
7da4: f5 df rcall .-22 ; 0x7d90 <SPI_transfer>
|
|
FLASH_UNSELECT;
|
|
7da6: 28 9a sbi 0x05, 0 ; 5
|
|
return status & 1;
|
|
}
|
|
7da8: 81 70 andi r24, 0x01 ; 1
|
|
7daa: 08 95 ret
|
|
|
|
00007dac <FLASH_command>:
|
|
|
|
void FLASH_command(uint8_t cmd, uint8_t isWrite){
|
|
7dac: 1f 93 push r17
|
|
7dae: 18 2f mov r17, r24
|
|
if (isWrite)
|
|
7db0: 66 23 and r22, r22
|
|
7db2: 21 f0 breq .+8 ; 0x7dbc <FLASH_command+0x10>
|
|
{
|
|
FLASH_command(SPIFLASH_WRITEENABLE, 0); // Write Enable
|
|
7db4: 86 e0 ldi r24, 0x06 ; 6
|
|
7db6: 60 e0 ldi r22, 0x00 ; 0
|
|
7db8: f9 df rcall .-14 ; 0x7dac <FLASH_command>
|
|
FLASH_UNSELECT;
|
|
7dba: 28 9a sbi 0x05, 0 ; 5
|
|
}
|
|
while(FLASH_busy()); //wait for chip to become available
|
|
7dbc: ef df rcall .-34 ; 0x7d9c <FLASH_busy>
|
|
7dbe: 88 23 and r24, r24
|
|
7dc0: e9 f7 brne .-6 ; 0x7dbc <FLASH_command+0x10>
|
|
FLASH_SELECT;
|
|
7dc2: 28 98 cbi 0x05, 0 ; 5
|
|
SPI_transfer(cmd);
|
|
7dc4: 81 2f mov r24, r17
|
|
7dc6: e4 df rcall .-56 ; 0x7d90 <SPI_transfer>
|
|
}
|
|
7dc8: 1f 91 pop r17
|
|
7dca: 08 95 ret
|
|
|
|
00007dcc <FLASH_readByte>:
|
|
|
|
uint8_t FLASH_readByte(uint32_t addr) {
|
|
7dcc: ef 92 push r14
|
|
7dce: ff 92 push r15
|
|
7dd0: 0f 93 push r16
|
|
7dd2: 1f 93 push r17
|
|
7dd4: 7b 01 movw r14, r22
|
|
7dd6: 8c 01 movw r16, r24
|
|
FLASH_command(SPIFLASH_ARRAYREADLOWFREQ, 0);
|
|
7dd8: 83 e0 ldi r24, 0x03 ; 3
|
|
7dda: 60 e0 ldi r22, 0x00 ; 0
|
|
7ddc: e7 df rcall .-50 ; 0x7dac <FLASH_command>
|
|
SPI_transfer(addr >> 16);
|
|
7dde: c8 01 movw r24, r16
|
|
7de0: aa 27 eor r26, r26
|
|
7de2: bb 27 eor r27, r27
|
|
7de4: d5 df rcall .-86 ; 0x7d90 <SPI_transfer>
|
|
SPI_transfer(addr >> 8);
|
|
7de6: bb 27 eor r27, r27
|
|
7de8: a1 2f mov r26, r17
|
|
7dea: 90 2f mov r25, r16
|
|
7dec: 8f 2d mov r24, r15
|
|
7dee: d0 df rcall .-96 ; 0x7d90 <SPI_transfer>
|
|
SPI_transfer(addr);
|
|
7df0: 8e 2d mov r24, r14
|
|
7df2: ce df rcall .-100 ; 0x7d90 <SPI_transfer>
|
|
//SPI.transfer(0); //"dont care", needed with SPIFLASH_ARRAYREAD command only
|
|
uint8_t result = SPI_transfer(0);
|
|
7df4: 80 e0 ldi r24, 0x00 ; 0
|
|
7df6: cc df rcall .-104 ; 0x7d90 <SPI_transfer>
|
|
FLASH_UNSELECT;
|
|
7df8: 28 9a sbi 0x05, 0 ; 5
|
|
return result;
|
|
}
|
|
7dfa: 1f 91 pop r17
|
|
7dfc: 0f 91 pop r16
|
|
7dfe: ff 90 pop r15
|
|
7e00: ef 90 pop r14
|
|
7e02: 08 95 ret
|
|
|
|
00007e04 <putch>:
|
|
}
|
|
putch(STK_OK);
|
|
}
|
|
}
|
|
|
|
void putch(char ch) {
|
|
7e04: 98 2f mov r25, r24
|
|
#ifndef SOFT_UART
|
|
while (!(UART_SRA & _BV(UDRE0)));
|
|
7e06: 80 91 c0 00 lds r24, 0x00C0
|
|
7e0a: 85 ff sbrs r24, 5
|
|
7e0c: fc cf rjmp .-8 ; 0x7e06 <putch+0x2>
|
|
UART_UDR = ch;
|
|
7e0e: 90 93 c6 00 sts 0x00C6, r25
|
|
[uartBit] "I" (UART_TX_BIT)
|
|
:
|
|
"r25"
|
|
);
|
|
#endif
|
|
}
|
|
7e12: 08 95 ret
|
|
|
|
00007e14 <getch>:
|
|
|
|
#ifdef LED_DATA_FLASH
|
|
#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
|
|
LED_PORT ^= _BV(LED);
|
|
#else
|
|
LED_PIN |= _BV(LED);
|
|
7e14: 4d 9a sbi 0x09, 5 ; 9
|
|
[uartBit] "I" (UART_RX_BIT)
|
|
:
|
|
"r25"
|
|
);
|
|
#else
|
|
while(!(UART_SRA & _BV(RXC0)))
|
|
7e16: 80 91 c0 00 lds r24, 0x00C0
|
|
7e1a: 87 ff sbrs r24, 7
|
|
7e1c: fc cf rjmp .-8 ; 0x7e16 <getch+0x2>
|
|
;
|
|
if (!(UART_SRA & _BV(FE0))) {
|
|
7e1e: 80 91 c0 00 lds r24, 0x00C0
|
|
7e22: 84 fd sbrc r24, 4
|
|
7e24: 01 c0 rjmp .+2 ; 0x7e28 <getch+0x14>
|
|
}
|
|
#endif
|
|
|
|
// Watchdog functions. These are only safe with interrupts turned off.
|
|
void watchdogReset() {
|
|
__asm__ __volatile__ (
|
|
7e26: a8 95 wdr
|
|
* don't care that an invalid char is returned...)
|
|
*/
|
|
watchdogReset();
|
|
}
|
|
|
|
ch = UART_UDR;
|
|
7e28: 80 91 c6 00 lds r24, 0x00C6
|
|
|
|
#ifdef LED_DATA_FLASH
|
|
#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
|
|
LED_PORT ^= _BV(LED);
|
|
#else
|
|
LED_PIN |= _BV(LED);
|
|
7e2c: 4d 9a sbi 0x09, 5 ; 9
|
|
#endif
|
|
#endif
|
|
|
|
return ch;
|
|
}
|
|
7e2e: 08 95 ret
|
|
|
|
00007e30 <watchdogConfig>:
|
|
"wdr\n"
|
|
);
|
|
}
|
|
|
|
void watchdogConfig(uint8_t x) {
|
|
WDTCSR = _BV(WDCE) | _BV(WDE);
|
|
7e30: e0 e6 ldi r30, 0x60 ; 96
|
|
7e32: f0 e0 ldi r31, 0x00 ; 0
|
|
7e34: 98 e1 ldi r25, 0x18 ; 24
|
|
7e36: 90 83 st Z, r25
|
|
WDTCSR = x;
|
|
7e38: 80 83 st Z, r24
|
|
}
|
|
7e3a: 08 95 ret
|
|
|
|
00007e3c <verifySpace>:
|
|
do getch(); while (--count);
|
|
verifySpace();
|
|
}
|
|
|
|
void verifySpace() {
|
|
if (getch() != CRC_EOP) {
|
|
7e3c: eb df rcall .-42 ; 0x7e14 <getch>
|
|
7e3e: 80 32 cpi r24, 0x20 ; 32
|
|
7e40: 19 f0 breq .+6 ; 0x7e48 <verifySpace+0xc>
|
|
watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
|
|
7e42: 88 e0 ldi r24, 0x08 ; 8
|
|
7e44: f5 df rcall .-22 ; 0x7e30 <watchdogConfig>
|
|
7e46: ff cf rjmp .-2 ; 0x7e46 <verifySpace+0xa>
|
|
while (1) // and busy-loop so that WD causes
|
|
; // a reset and app start.
|
|
}
|
|
putch(STK_INSYNC);
|
|
7e48: 84 e1 ldi r24, 0x14 ; 20
|
|
}
|
|
7e4a: dc cf rjmp .-72 ; 0x7e04 <putch>
|
|
::[count] "M" (UART_B_VALUE)
|
|
);
|
|
}
|
|
#endif
|
|
|
|
void getNch(uint8_t count) {
|
|
7e4c: 1f 93 push r17
|
|
|
|
00007e4e <getNch>:
|
|
7e4e: 18 2f mov r17, r24
|
|
do getch(); while (--count);
|
|
7e50: e1 df rcall .-62 ; 0x7e14 <getch>
|
|
7e52: 11 50 subi r17, 0x01 ; 1
|
|
7e54: e9 f7 brne .-6 ; 0x7e50 <getNch+0x2>
|
|
verifySpace();
|
|
7e56: f2 df rcall .-28 ; 0x7e3c <verifySpace>
|
|
}
|
|
7e58: 1f 91 pop r17
|
|
7e5a: 08 95 ret
|
|
|
|
00007e5c <CheckFlashImage>:
|
|
uint8_t result = SPI_transfer(0);
|
|
FLASH_UNSELECT;
|
|
return result;
|
|
}
|
|
|
|
void CheckFlashImage() {
|
|
7e5c: 9f 92 push r9
|
|
7e5e: af 92 push r10
|
|
7e60: bf 92 push r11
|
|
7e62: cf 92 push r12
|
|
7e64: df 92 push r13
|
|
7e66: ef 92 push r14
|
|
7e68: ff 92 push r15
|
|
7e6a: 0f 93 push r16
|
|
7e6c: 1f 93 push r17
|
|
7e6e: cf 93 push r28
|
|
7e70: df 93 push r29
|
|
#ifdef DEBUG_ON
|
|
putch('F');
|
|
#endif
|
|
watchdogConfig(WATCHDOG_OFF);
|
|
7e72: 80 e0 ldi r24, 0x00 ; 0
|
|
7e74: dd df rcall .-70 ; 0x7e30 <watchdogConfig>
|
|
|
|
//SPI INIT
|
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
|
|
DDRB |= _BV(FLASHSS) | _BV(SS) | _BV(PB3) | _BV(PB5); //OUTPUTS for FLASH_SS and SS, MOSI, SCK
|
|
7e76: 84 b1 in r24, 0x04 ; 4
|
|
7e78: 8d 62 ori r24, 0x2D ; 45
|
|
7e7a: 84 b9 out 0x04, r24 ; 4
|
|
FLASH_UNSELECT; //unselect FLASH chip
|
|
7e7c: 28 9a sbi 0x05, 0 ; 5
|
|
PORTB |= _BV(SS); //set SS HIGH
|
|
7e7e: 2a 9a sbi 0x05, 2 ; 5
|
|
//SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE0 ; //SPI MODE 0
|
|
//SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK); //clock divider = 2
|
|
//SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
|
|
|
|
// Warning: if the SS pin ever becomes a LOW INPUT then SPI automatically switches to Slave, so the data direction of the SS pin MUST be kept as OUTPUT.
|
|
SPCR |= _BV(MSTR) | _BV(SPE); //enable SPI and set SPI to MASTER mode
|
|
7e80: 8c b5 in r24, 0x2c ; 44
|
|
7e82: 80 65 ori r24, 0x50 ; 80
|
|
7e84: 8c bd out 0x2c, r24 ; 44
|
|
|
|
//read first byte of JEDECID, if chip is present it should return a non-0 and non-FF value
|
|
FLASH_SELECT;
|
|
7e86: 28 98 cbi 0x05, 0 ; 5
|
|
SPI_transfer(SPIFLASH_JEDECID);
|
|
7e88: 8f e9 ldi r24, 0x9F ; 159
|
|
7e8a: 82 df rcall .-252 ; 0x7d90 <SPI_transfer>
|
|
uint8_t deviceId = SPI_transfer(0);
|
|
7e8c: 80 e0 ldi r24, 0x00 ; 0
|
|
7e8e: 80 df rcall .-256 ; 0x7d90 <SPI_transfer>
|
|
FLASH_UNSELECT;
|
|
7e90: 28 9a sbi 0x05, 0 ; 5
|
|
if (deviceId==0 || deviceId==0xFF) return;
|
|
7e92: 81 50 subi r24, 0x01 ; 1
|
|
7e94: 8e 3f cpi r24, 0xFE ; 254
|
|
7e96: 08 f0 brcs .+2 ; 0x7e9a <CheckFlashImage+0x3e>
|
|
7e98: 9d c0 rjmp .+314 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
|
|
//global unprotect
|
|
FLASH_command(SPIFLASH_STATUSWRITE, 1);
|
|
7e9a: 81 e0 ldi r24, 0x01 ; 1
|
|
7e9c: 61 e0 ldi r22, 0x01 ; 1
|
|
7e9e: 86 df rcall .-244 ; 0x7dac <FLASH_command>
|
|
SPI_transfer(0);
|
|
7ea0: 80 e0 ldi r24, 0x00 ; 0
|
|
7ea2: 76 df rcall .-276 ; 0x7d90 <SPI_transfer>
|
|
FLASH_UNSELECT;
|
|
7ea4: 28 9a sbi 0x05, 0 ; 5
|
|
|
|
//check if any flash image exists on external FLASH chip
|
|
if (FLASH_readByte(0)=='F' && FLASH_readByte(1)=='L' && FLASH_readByte(2)=='X' && FLASH_readByte(6)==':' && FLASH_readByte(9)==':')
|
|
7ea6: 60 e0 ldi r22, 0x00 ; 0
|
|
7ea8: 70 e0 ldi r23, 0x00 ; 0
|
|
7eaa: 80 e0 ldi r24, 0x00 ; 0
|
|
7eac: 90 e0 ldi r25, 0x00 ; 0
|
|
7eae: 8e df rcall .-228 ; 0x7dcc <FLASH_readByte>
|
|
7eb0: 86 34 cpi r24, 0x46 ; 70
|
|
7eb2: 09 f0 breq .+2 ; 0x7eb6 <CheckFlashImage+0x5a>
|
|
7eb4: 8f c0 rjmp .+286 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
7eb6: 61 e0 ldi r22, 0x01 ; 1
|
|
7eb8: 70 e0 ldi r23, 0x00 ; 0
|
|
7eba: 80 e0 ldi r24, 0x00 ; 0
|
|
7ebc: 90 e0 ldi r25, 0x00 ; 0
|
|
7ebe: 86 df rcall .-244 ; 0x7dcc <FLASH_readByte>
|
|
7ec0: 8c 34 cpi r24, 0x4C ; 76
|
|
7ec2: 09 f0 breq .+2 ; 0x7ec6 <CheckFlashImage+0x6a>
|
|
7ec4: 87 c0 rjmp .+270 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
7ec6: 62 e0 ldi r22, 0x02 ; 2
|
|
7ec8: 70 e0 ldi r23, 0x00 ; 0
|
|
7eca: 80 e0 ldi r24, 0x00 ; 0
|
|
7ecc: 90 e0 ldi r25, 0x00 ; 0
|
|
7ece: 7e df rcall .-260 ; 0x7dcc <FLASH_readByte>
|
|
7ed0: 88 35 cpi r24, 0x58 ; 88
|
|
7ed2: 09 f0 breq .+2 ; 0x7ed6 <CheckFlashImage+0x7a>
|
|
7ed4: 7f c0 rjmp .+254 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
7ed6: 66 e0 ldi r22, 0x06 ; 6
|
|
7ed8: 70 e0 ldi r23, 0x00 ; 0
|
|
7eda: 80 e0 ldi r24, 0x00 ; 0
|
|
7edc: 90 e0 ldi r25, 0x00 ; 0
|
|
7ede: 76 df rcall .-276 ; 0x7dcc <FLASH_readByte>
|
|
7ee0: 8a 33 cpi r24, 0x3A ; 58
|
|
7ee2: 09 f0 breq .+2 ; 0x7ee6 <CheckFlashImage+0x8a>
|
|
7ee4: 77 c0 rjmp .+238 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
7ee6: 69 e0 ldi r22, 0x09 ; 9
|
|
7ee8: 70 e0 ldi r23, 0x00 ; 0
|
|
7eea: 80 e0 ldi r24, 0x00 ; 0
|
|
7eec: 90 e0 ldi r25, 0x00 ; 0
|
|
7eee: 6e df rcall .-292 ; 0x7dcc <FLASH_readByte>
|
|
7ef0: 8a 33 cpi r24, 0x3A ; 58
|
|
7ef2: 09 f0 breq .+2 ; 0x7ef6 <CheckFlashImage+0x9a>
|
|
7ef4: 6f c0 rjmp .+222 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
{
|
|
#ifdef DEBUG_ON
|
|
putch('L');
|
|
#endif
|
|
|
|
uint16_t imagesize = (FLASH_readByte(7)<<8) | FLASH_readByte(8);
|
|
7ef6: 67 e0 ldi r22, 0x07 ; 7
|
|
7ef8: 70 e0 ldi r23, 0x00 ; 0
|
|
7efa: 80 e0 ldi r24, 0x00 ; 0
|
|
7efc: 90 e0 ldi r25, 0x00 ; 0
|
|
7efe: 66 df rcall .-308 ; 0x7dcc <FLASH_readByte>
|
|
7f00: 08 2f mov r16, r24
|
|
7f02: 68 e0 ldi r22, 0x08 ; 8
|
|
7f04: 70 e0 ldi r23, 0x00 ; 0
|
|
7f06: 80 e0 ldi r24, 0x00 ; 0
|
|
7f08: 90 e0 ldi r25, 0x00 ; 0
|
|
7f0a: 60 df rcall .-320 ; 0x7dcc <FLASH_readByte>
|
|
7f0c: 10 e0 ldi r17, 0x00 ; 0
|
|
7f0e: f0 2e mov r15, r16
|
|
7f10: ee 24 eor r14, r14
|
|
7f12: 90 e0 ldi r25, 0x00 ; 0
|
|
7f14: e8 2a or r14, r24
|
|
7f16: f9 2a or r15, r25
|
|
if (imagesize%2!=0) return; //basic check that we got even # of bytes
|
|
7f18: e0 fc sbrc r14, 0
|
|
7f1a: 5c c0 rjmp .+184 ; 0x7fd4 <CheckFlashImage+0x178>
|
|
|
|
uint16_t b, i, nextAddress=0;
|
|
|
|
LED_PIN |= _BV(LED);
|
|
7f1c: 4d 9a sbi 0x09, 5 ; 9
|
|
7f1e: c0 e0 ldi r28, 0x00 ; 0
|
|
7f20: d0 e0 ldi r29, 0x00 ; 0
|
|
7f22: cc 24 eor r12, r12
|
|
7f24: dd 24 eor r13, r13
|
|
#endif
|
|
|
|
//read 2 bytes (16 bits) from flash image, transfer them to page buffer
|
|
b = FLASH_readByte(i+10); // flash image starts at position 10 on the external flash memory: FLX:XX:FLASH_IMAGE_BYTES_HERE...... (XX = two size bytes)
|
|
b |= FLASH_readByte(i+11) << 8; //bytes are stored big endian on external flash, need to flip the bytes to little endian for transfer to internal flash
|
|
__boot_page_fill_short((uint16_t)(void*)i,b);
|
|
7f26: 99 24 eor r9, r9
|
|
7f28: 93 94 inc r9
|
|
|
|
//when 1 page is full (or we're on the last page), write it to the internal flash memory
|
|
if ((i+2)%SPM_PAGESIZE==0 || (i+2==imagesize))
|
|
{
|
|
__boot_page_erase_short((uint16_t)(void*)nextAddress); //(i+2-SPM_PAGESIZE)
|
|
7f2a: 43 e0 ldi r20, 0x03 ; 3
|
|
7f2c: a4 2e mov r10, r20
|
|
boot_spm_busy_wait();
|
|
// Write from programming buffer
|
|
__boot_page_write_short((uint16_t)(void*)nextAddress ); //(i+2-SPM_PAGESIZE)
|
|
7f2e: 35 e0 ldi r19, 0x05 ; 5
|
|
7f30: b3 2e mov r11, r19
|
|
7f32: 30 c0 rjmp .+96 ; 0x7f94 <CheckFlashImage+0x138>
|
|
#ifdef DEBUG_ON
|
|
putch('*');
|
|
#endif
|
|
|
|
//read 2 bytes (16 bits) from flash image, transfer them to page buffer
|
|
b = FLASH_readByte(i+10); // flash image starts at position 10 on the external flash memory: FLX:XX:FLASH_IMAGE_BYTES_HERE...... (XX = two size bytes)
|
|
7f34: 2a 96 adiw r28, 0x0a ; 10
|
|
7f36: be 01 movw r22, r28
|
|
7f38: 80 e0 ldi r24, 0x00 ; 0
|
|
7f3a: 90 e0 ldi r25, 0x00 ; 0
|
|
7f3c: 47 df rcall .-370 ; 0x7dcc <FLASH_readByte>
|
|
7f3e: 08 2f mov r16, r24
|
|
7f40: 10 e0 ldi r17, 0x00 ; 0
|
|
b |= FLASH_readByte(i+11) << 8; //bytes are stored big endian on external flash, need to flip the bytes to little endian for transfer to internal flash
|
|
7f42: 21 96 adiw r28, 0x01 ; 1
|
|
7f44: be 01 movw r22, r28
|
|
7f46: 80 e0 ldi r24, 0x00 ; 0
|
|
7f48: 90 e0 ldi r25, 0x00 ; 0
|
|
7f4a: 2b 97 sbiw r28, 0x0b ; 11
|
|
7f4c: 3f df rcall .-386 ; 0x7dcc <FLASH_readByte>
|
|
__boot_page_fill_short((uint16_t)(void*)i,b);
|
|
7f4e: 90 e0 ldi r25, 0x00 ; 0
|
|
7f50: 98 2f mov r25, r24
|
|
7f52: 88 27 eor r24, r24
|
|
7f54: 80 2b or r24, r16
|
|
7f56: 91 2b or r25, r17
|
|
7f58: fe 01 movw r30, r28
|
|
7f5a: 0c 01 movw r0, r24
|
|
7f5c: 97 be out 0x37, r9 ; 55
|
|
7f5e: e8 95 spm
|
|
7f60: 11 24 eor r1, r1
|
|
|
|
//when 1 page is full (or we're on the last page), write it to the internal flash memory
|
|
if ((i+2)%SPM_PAGESIZE==0 || (i+2==imagesize))
|
|
7f62: 22 96 adiw r28, 0x02 ; 2
|
|
7f64: ce 01 movw r24, r28
|
|
7f66: 8f 77 andi r24, 0x7F ; 127
|
|
7f68: 90 70 andi r25, 0x00 ; 0
|
|
7f6a: 89 2b or r24, r25
|
|
7f6c: 19 f0 breq .+6 ; 0x7f74 <CheckFlashImage+0x118>
|
|
7f6e: ce 15 cp r28, r14
|
|
7f70: df 05 cpc r29, r15
|
|
7f72: 81 f4 brne .+32 ; 0x7f94 <CheckFlashImage+0x138>
|
|
{
|
|
__boot_page_erase_short((uint16_t)(void*)nextAddress); //(i+2-SPM_PAGESIZE)
|
|
7f74: f6 01 movw r30, r12
|
|
7f76: a7 be out 0x37, r10 ; 55
|
|
7f78: e8 95 spm
|
|
boot_spm_busy_wait();
|
|
7f7a: 07 b6 in r0, 0x37 ; 55
|
|
7f7c: 00 fc sbrc r0, 0
|
|
7f7e: fd cf rjmp .-6 ; 0x7f7a <CheckFlashImage+0x11e>
|
|
// Write from programming buffer
|
|
__boot_page_write_short((uint16_t)(void*)nextAddress ); //(i+2-SPM_PAGESIZE)
|
|
7f80: f6 01 movw r30, r12
|
|
7f82: b7 be out 0x37, r11 ; 55
|
|
7f84: e8 95 spm
|
|
boot_spm_busy_wait();
|
|
7f86: 07 b6 in r0, 0x37 ; 55
|
|
7f88: 00 fc sbrc r0, 0
|
|
7f8a: fd cf rjmp .-6 ; 0x7f86 <CheckFlashImage+0x12a>
|
|
nextAddress += SPM_PAGESIZE;
|
|
7f8c: 80 e8 ldi r24, 0x80 ; 128
|
|
7f8e: 90 e0 ldi r25, 0x00 ; 0
|
|
7f90: c8 0e add r12, r24
|
|
7f92: d9 1e adc r13, r25
|
|
if (imagesize%2!=0) return; //basic check that we got even # of bytes
|
|
|
|
uint16_t b, i, nextAddress=0;
|
|
|
|
LED_PIN |= _BV(LED);
|
|
for (i=0; i<imagesize; i+=2)
|
|
7f94: ce 15 cp r28, r14
|
|
7f96: df 05 cpc r29, r15
|
|
7f98: 08 f4 brcc .+2 ; 0x7f9c <CheckFlashImage+0x140>
|
|
7f9a: cc cf rjmp .-104 ; 0x7f34 <CheckFlashImage+0xd8>
|
|
__boot_page_write_short((uint16_t)(void*)nextAddress ); //(i+2-SPM_PAGESIZE)
|
|
boot_spm_busy_wait();
|
|
nextAddress += SPM_PAGESIZE;
|
|
}
|
|
}
|
|
LED_PIN &= ~_BV(LED);
|
|
7f9c: 4d 98 cbi 0x09, 5 ; 9
|
|
|
|
#if defined(RWWSRE)
|
|
// Reenable read access to flash
|
|
boot_rww_enable();
|
|
7f9e: 81 e1 ldi r24, 0x11 ; 17
|
|
7fa0: 87 bf out 0x37, r24 ; 55
|
|
7fa2: e8 95 spm
|
|
#ifdef DEBUG_ON
|
|
putch('E');
|
|
#endif
|
|
|
|
//erase the first 32/64K block where flash image resided (atmega328 should be less than 31K, and atmega1284 can be up to 64K)
|
|
if (imagesize+10<=32768) FLASH_command(SPIFLASH_BLOCKERASE_32K, 1);
|
|
7fa4: ea e0 ldi r30, 0x0A ; 10
|
|
7fa6: f0 e0 ldi r31, 0x00 ; 0
|
|
7fa8: ee 0e add r14, r30
|
|
7faa: ff 1e adc r15, r31
|
|
7fac: f1 e0 ldi r31, 0x01 ; 1
|
|
7fae: ef 16 cp r14, r31
|
|
7fb0: f0 e8 ldi r31, 0x80 ; 128
|
|
7fb2: ff 06 cpc r15, r31
|
|
7fb4: 10 f4 brcc .+4 ; 0x7fba <CheckFlashImage+0x15e>
|
|
7fb6: 82 e5 ldi r24, 0x52 ; 82
|
|
7fb8: 01 c0 rjmp .+2 ; 0x7fbc <CheckFlashImage+0x160>
|
|
else FLASH_command(SPIFLASH_BLOCKERASE_64K, 1);
|
|
7fba: 88 ed ldi r24, 0xD8 ; 216
|
|
7fbc: 61 e0 ldi r22, 0x01 ; 1
|
|
7fbe: f6 de rcall .-532 ; 0x7dac <FLASH_command>
|
|
SPI_transfer(0);
|
|
7fc0: 80 e0 ldi r24, 0x00 ; 0
|
|
7fc2: e6 de rcall .-564 ; 0x7d90 <SPI_transfer>
|
|
SPI_transfer(0);
|
|
7fc4: 80 e0 ldi r24, 0x00 ; 0
|
|
7fc6: e4 de rcall .-568 ; 0x7d90 <SPI_transfer>
|
|
SPI_transfer(0);
|
|
7fc8: 80 e0 ldi r24, 0x00 ; 0
|
|
7fca: e2 de rcall .-572 ; 0x7d90 <SPI_transfer>
|
|
FLASH_UNSELECT;
|
|
7fcc: 28 9a sbi 0x05, 0 ; 5
|
|
|
|
//now trigger a watchdog reset
|
|
watchdogConfig(WATCHDOG_16MS); // short WDT timeout
|
|
7fce: 88 e0 ldi r24, 0x08 ; 8
|
|
7fd0: 2f df rcall .-418 ; 0x7e30 <watchdogConfig>
|
|
7fd2: ff cf rjmp .-2 ; 0x7fd2 <CheckFlashImage+0x176>
|
|
while (1); // and busy-loop so that WD causes a reset and app start
|
|
}
|
|
#ifdef DEBUG_ON
|
|
putch('X');
|
|
#endif
|
|
}
|
|
7fd4: df 91 pop r29
|
|
7fd6: cf 91 pop r28
|
|
7fd8: 1f 91 pop r17
|
|
7fda: 0f 91 pop r16
|
|
7fdc: ff 90 pop r15
|
|
7fde: ef 90 pop r14
|
|
7fe0: df 90 pop r13
|
|
7fe2: cf 90 pop r12
|
|
7fe4: bf 90 pop r11
|
|
7fe6: af 90 pop r10
|
|
7fe8: 9f 90 pop r9
|
|
7fea: 08 95 ret
|
|
|
|
00007fec <appStart>:
|
|
|
|
void appStart(uint8_t rstFlags) {
|
|
// save the reset flags in the designated register
|
|
// This can be saved in a main program by putting code in .init0 (which
|
|
// executes before normal c init code) to save R2 to a global variable.
|
|
__asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
|
|
7fec: 28 2e mov r2, r24
|
|
|
|
watchdogConfig(WATCHDOG_OFF);
|
|
7fee: 80 e0 ldi r24, 0x00 ; 0
|
|
7ff0: 1f df rcall .-450 ; 0x7e30 <watchdogConfig>
|
|
__asm__ __volatile__ (
|
|
7ff2: ee 27 eor r30, r30
|
|
7ff4: ff 27 eor r31, r31
|
|
7ff6: 09 94 ijmp
|