diff options
Diffstat (limited to 'bootloaders/optiboot')
| -rw-r--r-- | bootloaders/optiboot/optiboot_atmega168.hex | 35 | ||||
| -rw-r--r-- | bootloaders/optiboot/optiboot_atmega168.lst | 598 | ||||
| -rw-r--r-- | bootloaders/optiboot/optiboot_atmega8.hex | 33 | ||||
| -rw-r--r-- | bootloaders/optiboot/optiboot_atmega8.lst | 604 | 
4 files changed, 1270 insertions, 0 deletions
diff --git a/bootloaders/optiboot/optiboot_atmega168.hex b/bootloaders/optiboot/optiboot_atmega168.hex new file mode 100644 index 0000000..c2f2b5b --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega168.hex @@ -0,0 +1,35 @@ +:103E0000112484B714BE81FFF0D085E08093810037
 +:103E100082E08093C00088E18093C10086E08093B7
 +:103E2000C20080E18093C4008EE0C9D0259A86E06C
 +:103E300020E33CEF91E0309385002093840096BB13
 +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
 +:103E6000A2D0813461F49FD0082FAFD0023811F076
 +:103E7000013811F484E001C083E08DD089C0823420
 +:103E800011F484E103C0853419F485E0A6D080C024
 +:103E9000853579F488D0E82EFF2485D0082F10E0EE
 +:103EA000102F00270E291F29000F111F8ED0680127
 +:103EB0006FC0863521F484E090D080E0DECF843678
 +:103EC00009F040C070D06FD0082F6DD080E0C816C8
 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14
 +:103F0000A601A0E0B1E02C9130E011968C911197C0
 +:103F100090E0982F8827822B932B1296FA010C01A0
 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86
 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092
 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED
 +:103F80000AD086E07ACF813511F488E018D01DD0B0
 +:103F900080E101D065CF982F8091C00085FFFCCFD4
 +:103FA0009093C60008958091C00087FFFCCF809158
 +:103FB000C00084FD01C0A8958091C6000895E0E688
 +:103FC000F0E098E1908380830895EDDF803219F06E
 +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
 +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
 +:043FF000FF2709940A
 +:023FFE000404B9
 +:0400000300003E00BB
 +:00000001FF
 diff --git a/bootloaders/optiboot/optiboot_atmega168.lst b/bootloaders/optiboot/optiboot_atmega168.lst new file mode 100644 index 0000000..06316db --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega168.lst @@ -0,0 +1,598 @@ + +optiboot_atmega168.elf:     file format elf32-avr + +Sections: +Idx Name          Size      VMA       LMA       File off  Algn +  0 .text         000001f4  00003e00  00003e00  00000054  2**1 +                  CONTENTS, ALLOC, LOAD, READONLY, CODE +  1 .version      00000002  00003ffe  00003ffe  00000248  2**0 +                  CONTENTS, READONLY +  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0 +                  CONTENTS, READONLY, DEBUGGING +  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0 +                  CONTENTS, READONLY, DEBUGGING +  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0 +                  CONTENTS, READONLY, DEBUGGING +  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0 +                  CONTENTS, READONLY, DEBUGGING +  6 .debug_line   00000488  00000000  00000000  000006f1  2**0 +                  CONTENTS, READONLY, DEBUGGING +  7 .debug_frame  00000080  00000000  00000000  00000b7c  2**2 +                  CONTENTS, READONLY, DEBUGGING +  8 .debug_str    0000014f  00000000  00000000  00000bfc  2**0 +                  CONTENTS, READONLY, DEBUGGING +  9 .debug_loc    000002d8  00000000  00000000  00000d4b  2**0 +                  CONTENTS, READONLY, DEBUGGING + 10 .debug_ranges 00000078  00000000  00000000  00001023  2**0 +                  CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00003e00 <main>: +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    3e00:	11 24       	eor	r1, r1 +#ifdef __AVR_ATmega8__ +  SP=RAMEND;  // This is done by hardware reset +#endif + +  // Adaboot no-wait mod +  ch = MCUSR; +    3e02:	84 b7       	in	r24, 0x34	; 52 +  MCUSR = 0; +    3e04:	14 be       	out	0x34, r1	; 52 +  if (!(ch & _BV(EXTRF))) appStart(); +    3e06:	81 ff       	sbrs	r24, 1 +    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart> + +#if LED_START_FLASHES > 0 +  // Set up Timer 1 for timeout counter +  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 +    3e0a:	85 e0       	ldi	r24, 0x05	; 5 +    3e0c:	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 +  UCSR0A = _BV(U2X0); //Double speed mode USART0 +    3e10:	82 e0       	ldi	r24, 0x02	; 2 +    3e12:	80 93 c0 00 	sts	0x00C0, r24 +  UCSR0B = _BV(RXEN0) | _BV(TXEN0); +    3e16:	88 e1       	ldi	r24, 0x18	; 24 +    3e18:	80 93 c1 00 	sts	0x00C1, r24 +  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); +    3e1c:	86 e0       	ldi	r24, 0x06	; 6 +    3e1e:	80 93 c2 00 	sts	0x00C2, r24 +  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +    3e22:	80 e1       	ldi	r24, 0x10	; 16 +    3e24:	80 93 c4 00 	sts	0x00C4, r24 +#endif +#endif + +  // Set up watchdog to trigger after 500ms +  watchdogConfig(WATCHDOG_1S); +    3e28:	8e e0       	ldi	r24, 0x0E	; 14 +    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig> + +  /* Set LED pin as output */ +  LED_DDR |= _BV(LED); +    3e2c:	25 9a       	sbi	0x04, 5	; 4 +    3e2e:	86 e0       	ldi	r24, 0x06	; 6 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { +  do { +    TCNT1 = -(F_CPU/(1024*16)); +    3e30:	20 e3       	ldi	r18, 0x30	; 48 +    3e32:	3c ef       	ldi	r19, 0xFC	; 252 +    TIFR1 = _BV(TOV1); +    3e34:	91 e0       	ldi	r25, 0x01	; 1 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { +  do { +    TCNT1 = -(F_CPU/(1024*16)); +    3e36:	30 93 85 00 	sts	0x0085, r19 +    3e3a:	20 93 84 00 	sts	0x0084, r18 +    TIFR1 = _BV(TOV1); +    3e3e:	96 bb       	out	0x16, r25	; 22 +    while(!(TIFR1 & _BV(TOV1))); +    3e40:	b0 9b       	sbis	0x16, 0	; 22 +    3e42:	fe cf       	rjmp	.-4      	; 0x3e40 <main+0x40> +#ifdef __AVR_ATmega8__ +    LED_PORT ^= _BV(LED); +#else +    LED_PIN |= _BV(LED); +    3e44:	1d 9a       	sbi	0x03, 5	; 3 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { +  __asm__ __volatile__ ( +    3e46:	a8 95       	wdr +    LED_PORT ^= _BV(LED); +#else +    LED_PIN |= _BV(LED); +#endif +    watchdogReset(); +  } while (--count); +    3e48:	81 50       	subi	r24, 0x01	; 1 +    3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36> +    3e4c:	cc 24       	eor	r12, r12 +    3e4e:	dd 24       	eor	r13, r13 +      ch = SPM_PAGESIZE / 2; +      do { +        uint16_t a; +        a = *bufPtr++; +        a |= (*bufPtr++) << 8; +        __boot_page_fill_short((uint16_t)(void*)addrPtr,a); +    3e50:	88 24       	eor	r8, r8 +    3e52:	83 94       	inc	r8 +        addrPtr += 2; +      } while (--ch); + +      // Write from programming buffer +      __boot_page_write_short((uint16_t)(void*)address); +    3e54:	b5 e0       	ldi	r27, 0x05	; 5 +    3e56:	ab 2e       	mov	r10, r27 +      boot_spm_busy_wait(); + +#if defined(RWWSRE) +      // Reenable read access to flash +      boot_rww_enable(); +    3e58:	a1 e1       	ldi	r26, 0x11	; 17 +    3e5a:	9a 2e       	mov	r9, r26 +      do *bufPtr++ = getch(); +      while (--length); + +      // If we are in NRWW section, page erase has to be delayed until now. +      // Todo: Take RAMPZ into account +      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    3e5c:	f3 e0       	ldi	r31, 0x03	; 3 +    3e5e:	bf 2e       	mov	r11, r31 +#endif + +  /* Forever loop */ +  for (;;) { +    /* get character from UART */ +    ch = getch(); +    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch> + +    if(ch == STK_GET_PARAMETER) { +    3e62:	81 34       	cpi	r24, 0x41	; 65 +    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e> +      unsigned char which = getch(); +    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch> +    3e68:	08 2f       	mov	r16, r24 +      verifySpace(); +    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace> +      if (which == 0x82) { +    3e6c:	02 38       	cpi	r16, 0x82	; 130 +    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74> +	/* +	 * Send optiboot version as "minor SW version" +	 */ +	putch(OPTIBOOT_MINVER); +      } else if (which == 0x81) { +    3e70:	01 38       	cpi	r16, 0x81	; 129 +    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78> +	  putch(OPTIBOOT_MAJVER); +    3e74:	84 e0       	ldi	r24, 0x04	; 4 +    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a> +      } else { +	/* +	 * GET PARAMETER returns a generic 0x03 reply for +         * other parameters - enough to keep Avrdude happy +	 */ +	putch(0x03); +    3e78:	83 e0       	ldi	r24, 0x03	; 3 +    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch> +    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190> +      } +    } +    else if(ch == STK_SET_DEVICE) { +    3e7e:	82 34       	cpi	r24, 0x42	; 66 +    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86> +      // SET DEVICE is ignored +      getNch(20); +    3e82:	84 e1       	ldi	r24, 0x14	; 20 +    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c> +    } +    else if(ch == STK_SET_DEVICE_EXT) { +    3e86:	85 34       	cpi	r24, 0x45	; 69 +    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90> +      // SET DEVICE EXT is ignored +      getNch(5); +    3e8a:	85 e0       	ldi	r24, 0x05	; 5 +    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch> +    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190> +    } +    else if(ch == STK_LOAD_ADDRESS) { +    3e90:	85 35       	cpi	r24, 0x55	; 85 +    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2> +      // LOAD ADDRESS +      uint16_t newAddress; +      newAddress = getch(); +    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch> +      newAddress = (newAddress & 0xff) | (getch() << 8); +    3e96:	e8 2e       	mov	r14, r24 +    3e98:	ff 24       	eor	r15, r15 +    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch> +    3e9c:	08 2f       	mov	r16, r24 +    3e9e:	10 e0       	ldi	r17, 0x00	; 0 +    3ea0:	10 2f       	mov	r17, r16 +    3ea2:	00 27       	eor	r16, r16 +    3ea4:	0e 29       	or	r16, r14 +    3ea6:	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 +    3ea8:	00 0f       	add	r16, r16 +    3eaa:	11 1f       	adc	r17, r17 +      address = newAddress; +      verifySpace(); +    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace> +    3eae:	68 01       	movw	r12, r16 +    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190> +    } +    else if(ch == STK_UNIVERSAL) { +    3eb2:	86 35       	cpi	r24, 0x56	; 86 +    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe> +      // UNIVERSAL command is ignored +      getNch(4); +    3eb6:	84 e0       	ldi	r24, 0x04	; 4 +    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch> +      putch(0x00); +    3eba:	80 e0       	ldi	r24, 0x00	; 0 +    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a> +    } +    /* Write memory, length is big endian and is in bytes */ +    else if(ch == STK_PROG_PAGE) { +    3ebe:	84 36       	cpi	r24, 0x64	; 100 +    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4> +    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144> +      // PROGRAM PAGE - we support flash programming only, not EEPROM +      uint8_t *bufPtr; +      uint16_t addrPtr; + +      getch();			/* getlen() */ +    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch> +      length = getch(); +    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch> +    3ec8:	08 2f       	mov	r16, r24 +      getch(); +    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch> + +      // If we are in RWW section, immediately start page erase +      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    3ecc:	80 e0       	ldi	r24, 0x00	; 0 +    3ece:	c8 16       	cp	r12, r24 +    3ed0:	88 e3       	ldi	r24, 0x38	; 56 +    3ed2:	d8 06       	cpc	r13, r24 +    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc> +    3ed6:	f6 01       	movw	r30, r12 +    3ed8:	b7 be       	out	0x37, r11	; 55 +    3eda:	e8 95       	spm +    3edc:	c0 e0       	ldi	r28, 0x00	; 0 +    3ede:	d1 e0       	ldi	r29, 0x01	; 1 + +      // While that is going on, read in page contents +      bufPtr = buff; +      do *bufPtr++ = getch(); +    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch> +    3ee2:	89 93       	st	Y+, r24 +      while (--length); +    3ee4:	0c 17       	cp	r16, r28 +    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0> + +      // If we are in NRWW section, page erase has to be delayed until now. +      // Todo: Take RAMPZ into account +      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    3ee8:	f0 e0       	ldi	r31, 0x00	; 0 +    3eea:	cf 16       	cp	r12, r31 +    3eec:	f8 e3       	ldi	r31, 0x38	; 56 +    3eee:	df 06       	cpc	r13, r31 +    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8> +    3ef2:	f6 01       	movw	r30, r12 +    3ef4:	b7 be       	out	0x37, r11	; 55 +    3ef6:	e8 95       	spm + +      // Read command terminator, start reply +      verifySpace(); +    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace> + +      // If only a partial page is to be programmed, the erase might not be complete. +      // So check that here +      boot_spm_busy_wait(); +    3efa:	07 b6       	in	r0, 0x37	; 55 +    3efc:	00 fc       	sbrc	r0, 0 +    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa> +    3f00:	a6 01       	movw	r20, r12 +    3f02:	a0 e0       	ldi	r26, 0x00	; 0 +    3f04:	b1 e0       	ldi	r27, 0x01	; 1 +      bufPtr = buff; +      addrPtr = (uint16_t)(void*)address; +      ch = SPM_PAGESIZE / 2; +      do { +        uint16_t a; +        a = *bufPtr++; +    3f06:	2c 91       	ld	r18, X +    3f08:	30 e0       	ldi	r19, 0x00	; 0 +        a |= (*bufPtr++) << 8; +    3f0a:	11 96       	adiw	r26, 0x01	; 1 +    3f0c:	8c 91       	ld	r24, X +    3f0e:	11 97       	sbiw	r26, 0x01	; 1 +    3f10:	90 e0       	ldi	r25, 0x00	; 0 +    3f12:	98 2f       	mov	r25, r24 +    3f14:	88 27       	eor	r24, r24 +    3f16:	82 2b       	or	r24, r18 +    3f18:	93 2b       	or	r25, r19 +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    3f1a:	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); +    3f1c:	fa 01       	movw	r30, r20 +    3f1e:	0c 01       	movw	r0, r24 +    3f20:	87 be       	out	0x37, r8	; 55 +    3f22:	e8 95       	spm +    3f24:	11 24       	eor	r1, r1 +        addrPtr += 2; +    3f26:	4e 5f       	subi	r20, 0xFE	; 254 +    3f28:	5f 4f       	sbci	r21, 0xFF	; 255 +      } while (--ch); +    3f2a:	f1 e0       	ldi	r31, 0x01	; 1 +    3f2c:	a0 38       	cpi	r26, 0x80	; 128 +    3f2e:	bf 07       	cpc	r27, r31 +    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106> + +      // Write from programming buffer +      __boot_page_write_short((uint16_t)(void*)address); +    3f32:	f6 01       	movw	r30, r12 +    3f34:	a7 be       	out	0x37, r10	; 55 +    3f36:	e8 95       	spm +      boot_spm_busy_wait(); +    3f38:	07 b6       	in	r0, 0x37	; 55 +    3f3a:	00 fc       	sbrc	r0, 0 +    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138> + +#if defined(RWWSRE) +      // Reenable read access to flash +      boot_rww_enable(); +    3f3e:	97 be       	out	0x37, r9	; 55 +    3f40:	e8 95       	spm +    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190> +#endif + +    } +    /* Read memory block mode, length is big endian.  */ +    else if(ch == STK_READ_PAGE) { +    3f44:	84 37       	cpi	r24, 0x74	; 116 +    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174> +      // READ PAGE - we only read flash +      getch();			/* getlen() */ +    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch> +      length = getch(); +    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch> +    3f4c:	f8 2e       	mov	r15, r24 +      getch(); +    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch> + +      verifySpace(); +    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace> +    3f52:	f6 01       	movw	r30, r12 +    3f54:	ef 2c       	mov	r14, r15 +        putch(result); +        address++; +      } +      while (--length); +#else +      do putch(pgm_read_byte_near(address++)); +    3f56:	8f 01       	movw	r16, r30 +    3f58:	0f 5f       	subi	r16, 0xFF	; 255 +    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255 +    3f5c:	84 91       	lpm	r24, Z+ +    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch> +      while (--length); +    3f60:	ea 94       	dec	r14 +    3f62:	f8 01       	movw	r30, r16 +    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156> +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    3f66:	08 94       	sec +    3f68:	c1 1c       	adc	r12, r1 +    3f6a:	d1 1c       	adc	r13, r1 +    3f6c:	fa 94       	dec	r15 +    3f6e:	cf 0c       	add	r12, r15 +    3f70:	d1 1c       	adc	r13, r1 +    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190> +#endif +#endif +    } + +    /* Get device signature bytes  */ +    else if(ch == STK_READ_SIGN) { +    3f74:	85 37       	cpi	r24, 0x75	; 117 +    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186> +      // READ SIGN - return what Avrdude wants to hear +      verifySpace(); +    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace> +      putch(SIGNATURE_0); +    3f7a:	8e e1       	ldi	r24, 0x1E	; 30 +    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch> +      putch(SIGNATURE_1); +    3f7e:	84 e9       	ldi	r24, 0x94	; 148 +    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch> +      putch(SIGNATURE_2); +    3f82:	86 e0       	ldi	r24, 0x06	; 6 +    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a> +    } +    else if (ch == 'Q') { +    3f86:	81 35       	cpi	r24, 0x51	; 81 +    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e> +      // Adaboot no-wait mod +      watchdogConfig(WATCHDOG_16MS); +    3f8a:	88 e0       	ldi	r24, 0x08	; 8 +    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig> +      verifySpace(); +    } +    else { +      // This covers the response to commands like STK_ENTER_PROGMODE +      verifySpace(); +    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace> +    } +    putch(STK_OK); +    3f90:	80 e1       	ldi	r24, 0x10	; 16 +    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch> +    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60> + +00003f96 <putch>: +  } +} + +void putch(char ch) { +    3f96:	98 2f       	mov	r25, r24 +#ifndef SOFT_UART +  while (!(UCSR0A & _BV(UDRE0))); +    3f98:	80 91 c0 00 	lds	r24, 0x00C0 +    3f9c:	85 ff       	sbrs	r24, 5 +    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2> +  UDR0 = ch; +    3fa0:	90 93 c6 00 	sts	0x00C6, r25 +      [uartBit] "I" (UART_TX_BIT) +    : +      "r25" +  ); +#endif +} +    3fa4:	08 95       	ret + +00003fa6 <getch>: +      [uartBit] "I" (UART_RX_BIT) +    : +      "r25" +); +#else +  while(!(UCSR0A & _BV(RXC0))) +    3fa6:	80 91 c0 00 	lds	r24, 0x00C0 +    3faa:	87 ff       	sbrs	r24, 7 +    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch> +    ; +  if (!(UCSR0A & _BV(FE0))) { +    3fae:	80 91 c0 00 	lds	r24, 0x00C0 +    3fb2:	84 fd       	sbrc	r24, 4 +    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12> +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { +  __asm__ __volatile__ ( +    3fb6:	a8 95       	wdr +       * don't care that an invalid char is returned...) +       */ +    watchdogReset(); +  } +   +  ch = UDR0; +    3fb8:	80 91 c6 00 	lds	r24, 0x00C6 +  LED_PIN |= _BV(LED); +#endif +#endif + +  return ch; +} +    3fbc:	08 95       	ret + +00003fbe <watchdogConfig>: +    "wdr\n" +  ); +} + +void watchdogConfig(uint8_t x) { +  WDTCSR = _BV(WDCE) | _BV(WDE); +    3fbe:	e0 e6       	ldi	r30, 0x60	; 96 +    3fc0:	f0 e0       	ldi	r31, 0x00	; 0 +    3fc2:	98 e1       	ldi	r25, 0x18	; 24 +    3fc4:	90 83       	st	Z, r25 +  WDTCSR = x; +    3fc6:	80 83       	st	Z, r24 +} +    3fc8:	08 95       	ret + +00003fca <verifySpace>: +  do getch(); while (--count); +  verifySpace(); +} + +void verifySpace() { +  if (getch() != CRC_EOP) { +    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch> +    3fcc:	80 32       	cpi	r24, 0x20	; 32 +    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc> +    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout +    3fd0:	88 e0       	ldi	r24, 0x08	; 8 +    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig> +    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa> +    while (1)			      // and busy-loop so that WD causes +      ;				      //  a reset and app start. +  } +  putch(STK_INSYNC); +    3fd6:	84 e1       	ldi	r24, 0x14	; 20 +} +    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch> + +00003fda <getNch>: +    ::[count] "M" (UART_B_VALUE) +  ); +} +#endif + +void getNch(uint8_t count) { +    3fda:	1f 93       	push	r17 +    3fdc:	18 2f       	mov	r17, r24 +  do getch(); while (--count); +    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch> +    3fe0:	11 50       	subi	r17, 0x01	; 1 +    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4> +  verifySpace(); +    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace> +} +    3fe6:	1f 91       	pop	r17 +    3fe8:	08 95       	ret + +00003fea <appStart>: +  WDTCSR = _BV(WDCE) | _BV(WDE); +  WDTCSR = x; +} + +void appStart() { +  watchdogConfig(WATCHDOG_OFF); +    3fea:	80 e0       	ldi	r24, 0x00	; 0 +    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig> +  __asm__ __volatile__ ( +    3fee:	ee 27       	eor	r30, r30 +    3ff0:	ff 27       	eor	r31, r31 +    3ff2:	09 94       	ijmp diff --git a/bootloaders/optiboot/optiboot_atmega8.hex b/bootloaders/optiboot/optiboot_atmega8.hex new file mode 100644 index 0000000..b04f276 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega8.hex @@ -0,0 +1,33 @@ +:101E000011248FE594E09EBF8DBF84B714BE81FF7F
 +:101E1000E2D085E08EBD82E08BB988E18AB986E8A0
 +:101E200080BD80E189B98EE0C2D0BD9A96E020E302
 +:101E30003CEF54E040E23DBD2CBD58BF08B602FE69
 +:101E4000FDCF88B3842788BBA8959150A1F7CC24F7
 +:101E5000DD2488248394B5E0AB2EA1E19A2EF3E033
 +:101E6000BF2E9ED0813461F49BD0082FA4D00238BD
 +:101E700011F0013811F484E001C083E08DD089C0F5
 +:101E8000823411F484E103C0853419F485E09BD0D9
 +:101E900080C0853579F484D0E82EFF2481D0082FC6
 +:101EA00010E0102F00270E291F29000F111F83D0CB
 +:101EB00068016FC0863521F484E085D080E0DECFF4
 +:101EC000843609F040C06CD06BD0082F69D080E018
 +:101ED000C81688E1D80618F4F601B7BEE895C0E048
 +:101EE000D1E05ED089930C17E1F7F0E0CF16F8E16E
 +:101EF000DF0618F0F601B7BEE8955DD007B600FC26
 +:101F0000FDCFA601A0E0B1E02C9130E011968C91BC
 +:101F1000119790E0982F8827822B932B1296FA0125
 +:101F20000C0187BEE89511244E5F5F4FF1E0A034AD
 +:101F3000BF0751F7F601A7BEE89507B600FCFDCF35
 +:101F400097BEE89526C08437B1F42AD029D0F82E60
 +:101F500027D031D0F601EF2C8F010F5F1F4F8491F6
 +:101F60001BD0EA94F801C1F70894C11CD11CFA9463
 +:101F7000CF0CD11C0EC0853739F41DD08EE10CD0AA
 +:101F800083E90AD087E07ACF813511F488E00FD059
 +:101F900012D080E101D065CF5D9BFECF8CB9089552
 +:101FA0005F9BFECF5C9901C0A8958CB1089598E124
 +:101FB00091BD81BD0895F4DF803219F088E0F7DF2C
 +:101FC000FFCF84E1E9CF1F93182FEADF1150E9F723
 +:101FD000F2DF1F91089580E0EADFEE27FF270994E2
 +:021FFE000404D9
 +:0400000300001E00DB
 +:00000001FF
 diff --git a/bootloaders/optiboot/optiboot_atmega8.lst b/bootloaders/optiboot/optiboot_atmega8.lst new file mode 100644 index 0000000..d921895 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega8.lst @@ -0,0 +1,604 @@ + +optiboot_atmega8.elf:     file format elf32-avr + +Sections: +Idx Name          Size      VMA       LMA       File off  Algn +  0 .text         000001e0  00001e00  00001e00  00000054  2**1 +                  CONTENTS, ALLOC, LOAD, READONLY, CODE +  1 .version      00000002  00001ffe  00001ffe  00000234  2**0 +                  CONTENTS, READONLY +  2 .debug_aranges 00000028  00000000  00000000  00000236  2**0 +                  CONTENTS, READONLY, DEBUGGING +  3 .debug_pubnames 0000005f  00000000  00000000  0000025e  2**0 +                  CONTENTS, READONLY, DEBUGGING +  4 .debug_info   000002a6  00000000  00000000  000002bd  2**0 +                  CONTENTS, READONLY, DEBUGGING +  5 .debug_abbrev 00000169  00000000  00000000  00000563  2**0 +                  CONTENTS, READONLY, DEBUGGING +  6 .debug_line   00000498  00000000  00000000  000006cc  2**0 +                  CONTENTS, READONLY, DEBUGGING +  7 .debug_frame  00000080  00000000  00000000  00000b64  2**2 +                  CONTENTS, READONLY, DEBUGGING +  8 .debug_str    0000014f  00000000  00000000  00000be4  2**0 +                  CONTENTS, READONLY, DEBUGGING +  9 .debug_loc    000002ba  00000000  00000000  00000d33  2**0 +                  CONTENTS, READONLY, DEBUGGING + 10 .debug_ranges 00000078  00000000  00000000  00000fed  2**0 +                  CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00001e00 <main>: +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    1e00:	11 24       	eor	r1, r1 +  // +  // If not, uncomment the following instructions: +  // cli(); +  asm volatile ("clr __zero_reg__"); +#ifdef __AVR_ATmega8__ +  SP=RAMEND;  // This is done by hardware reset +    1e02:	8f e5       	ldi	r24, 0x5F	; 95 +    1e04:	94 e0       	ldi	r25, 0x04	; 4 +    1e06:	9e bf       	out	0x3e, r25	; 62 +    1e08:	8d bf       	out	0x3d, r24	; 61 +#endif + +  // Adaboot no-wait mod +  ch = MCUSR; +    1e0a:	84 b7       	in	r24, 0x34	; 52 +  MCUSR = 0; +    1e0c:	14 be       	out	0x34, r1	; 52 +  if (!(ch & _BV(EXTRF))) appStart(); +    1e0e:	81 ff       	sbrs	r24, 1 +    1e10:	e2 d0       	rcall	.+452    	; 0x1fd6 <appStart> + +#if LED_START_FLASHES > 0 +  // Set up Timer 1 for timeout counter +  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 +    1e12:	85 e0       	ldi	r24, 0x05	; 5 +    1e14:	8e bd       	out	0x2e, r24	; 46 +#endif +#ifndef SOFT_UART +#ifdef __AVR_ATmega8__ +  UCSRA = _BV(U2X); //Double speed mode USART +    1e16:	82 e0       	ldi	r24, 0x02	; 2 +    1e18:	8b b9       	out	0x0b, r24	; 11 +  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx +    1e1a:	88 e1       	ldi	r24, 0x18	; 24 +    1e1c:	8a b9       	out	0x0a, r24	; 10 +  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1 +    1e1e:	86 e8       	ldi	r24, 0x86	; 134 +    1e20:	80 bd       	out	0x20, r24	; 32 +  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +    1e22:	80 e1       	ldi	r24, 0x10	; 16 +    1e24:	89 b9       	out	0x09, r24	; 9 +  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#endif +#endif + +  // Set up watchdog to trigger after 500ms +  watchdogConfig(WATCHDOG_1S); +    1e26:	8e e0       	ldi	r24, 0x0E	; 14 +    1e28:	c2 d0       	rcall	.+388    	; 0x1fae <watchdogConfig> + +  /* Set LED pin as output */ +  LED_DDR |= _BV(LED); +    1e2a:	bd 9a       	sbi	0x17, 5	; 23 +    1e2c:	96 e0       	ldi	r25, 0x06	; 6 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { +  do { +    TCNT1 = -(F_CPU/(1024*16)); +    1e2e:	20 e3       	ldi	r18, 0x30	; 48 +    1e30:	3c ef       	ldi	r19, 0xFC	; 252 +    TIFR1 = _BV(TOV1); +    1e32:	54 e0       	ldi	r21, 0x04	; 4 +    while(!(TIFR1 & _BV(TOV1))); +#ifdef __AVR_ATmega8__ +    LED_PORT ^= _BV(LED); +    1e34:	40 e2       	ldi	r20, 0x20	; 32 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { +  do { +    TCNT1 = -(F_CPU/(1024*16)); +    1e36:	3d bd       	out	0x2d, r19	; 45 +    1e38:	2c bd       	out	0x2c, r18	; 44 +    TIFR1 = _BV(TOV1); +    1e3a:	58 bf       	out	0x38, r21	; 56 +    while(!(TIFR1 & _BV(TOV1))); +    1e3c:	08 b6       	in	r0, 0x38	; 56 +    1e3e:	02 fe       	sbrs	r0, 2 +    1e40:	fd cf       	rjmp	.-6      	; 0x1e3c <main+0x3c> +#ifdef __AVR_ATmega8__ +    LED_PORT ^= _BV(LED); +    1e42:	88 b3       	in	r24, 0x18	; 24 +    1e44:	84 27       	eor	r24, r20 +    1e46:	88 bb       	out	0x18, r24	; 24 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { +  __asm__ __volatile__ ( +    1e48:	a8 95       	wdr +    LED_PORT ^= _BV(LED); +#else +    LED_PIN |= _BV(LED); +#endif +    watchdogReset(); +  } while (--count); +    1e4a:	91 50       	subi	r25, 0x01	; 1 +    1e4c:	a1 f7       	brne	.-24     	; 0x1e36 <main+0x36> +    1e4e:	cc 24       	eor	r12, r12 +    1e50:	dd 24       	eor	r13, r13 +      ch = SPM_PAGESIZE / 2; +      do { +        uint16_t a; +        a = *bufPtr++; +        a |= (*bufPtr++) << 8; +        __boot_page_fill_short((uint16_t)(void*)addrPtr,a); +    1e52:	88 24       	eor	r8, r8 +    1e54:	83 94       	inc	r8 +        addrPtr += 2; +      } while (--ch); + +      // Write from programming buffer +      __boot_page_write_short((uint16_t)(void*)address); +    1e56:	b5 e0       	ldi	r27, 0x05	; 5 +    1e58:	ab 2e       	mov	r10, r27 +      boot_spm_busy_wait(); + +#if defined(RWWSRE) +      // Reenable read access to flash +      boot_rww_enable(); +    1e5a:	a1 e1       	ldi	r26, 0x11	; 17 +    1e5c:	9a 2e       	mov	r9, r26 +      do *bufPtr++ = getch(); +      while (--length); + +      // If we are in NRWW section, page erase has to be delayed until now. +      // Todo: Take RAMPZ into account +      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    1e5e:	f3 e0       	ldi	r31, 0x03	; 3 +    1e60:	bf 2e       	mov	r11, r31 +#endif + +  /* Forever loop */ +  for (;;) { +    /* get character from UART */ +    ch = getch(); +    1e62:	9e d0       	rcall	.+316    	; 0x1fa0 <getch> + +    if(ch == STK_GET_PARAMETER) { +    1e64:	81 34       	cpi	r24, 0x41	; 65 +    1e66:	61 f4       	brne	.+24     	; 0x1e80 <main+0x80> +      unsigned char which = getch(); +    1e68:	9b d0       	rcall	.+310    	; 0x1fa0 <getch> +    1e6a:	08 2f       	mov	r16, r24 +      verifySpace(); +    1e6c:	a4 d0       	rcall	.+328    	; 0x1fb6 <verifySpace> +      if (which == 0x82) { +    1e6e:	02 38       	cpi	r16, 0x82	; 130 +    1e70:	11 f0       	breq	.+4      	; 0x1e76 <main+0x76> +	/* +	 * Send optiboot version as "minor SW version" +	 */ +	putch(OPTIBOOT_MINVER); +      } else if (which == 0x81) { +    1e72:	01 38       	cpi	r16, 0x81	; 129 +    1e74:	11 f4       	brne	.+4      	; 0x1e7a <main+0x7a> +	  putch(OPTIBOOT_MAJVER); +    1e76:	84 e0       	ldi	r24, 0x04	; 4 +    1e78:	01 c0       	rjmp	.+2      	; 0x1e7c <main+0x7c> +      } else { +	/* +	 * GET PARAMETER returns a generic 0x03 reply for +         * other parameters - enough to keep Avrdude happy +	 */ +	putch(0x03); +    1e7a:	83 e0       	ldi	r24, 0x03	; 3 +    1e7c:	8d d0       	rcall	.+282    	; 0x1f98 <putch> +    1e7e:	89 c0       	rjmp	.+274    	; 0x1f92 <main+0x192> +      } +    } +    else if(ch == STK_SET_DEVICE) { +    1e80:	82 34       	cpi	r24, 0x42	; 66 +    1e82:	11 f4       	brne	.+4      	; 0x1e88 <main+0x88> +      // SET DEVICE is ignored +      getNch(20); +    1e84:	84 e1       	ldi	r24, 0x14	; 20 +    1e86:	03 c0       	rjmp	.+6      	; 0x1e8e <main+0x8e> +    } +    else if(ch == STK_SET_DEVICE_EXT) { +    1e88:	85 34       	cpi	r24, 0x45	; 69 +    1e8a:	19 f4       	brne	.+6      	; 0x1e92 <main+0x92> +      // SET DEVICE EXT is ignored +      getNch(5); +    1e8c:	85 e0       	ldi	r24, 0x05	; 5 +    1e8e:	9b d0       	rcall	.+310    	; 0x1fc6 <getNch> +    1e90:	80 c0       	rjmp	.+256    	; 0x1f92 <main+0x192> +    } +    else if(ch == STK_LOAD_ADDRESS) { +    1e92:	85 35       	cpi	r24, 0x55	; 85 +    1e94:	79 f4       	brne	.+30     	; 0x1eb4 <main+0xb4> +      // LOAD ADDRESS +      uint16_t newAddress; +      newAddress = getch(); +    1e96:	84 d0       	rcall	.+264    	; 0x1fa0 <getch> +      newAddress = (newAddress & 0xff) | (getch() << 8); +    1e98:	e8 2e       	mov	r14, r24 +    1e9a:	ff 24       	eor	r15, r15 +    1e9c:	81 d0       	rcall	.+258    	; 0x1fa0 <getch> +    1e9e:	08 2f       	mov	r16, r24 +    1ea0:	10 e0       	ldi	r17, 0x00	; 0 +    1ea2:	10 2f       	mov	r17, r16 +    1ea4:	00 27       	eor	r16, r16 +    1ea6:	0e 29       	or	r16, r14 +    1ea8:	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 +    1eaa:	00 0f       	add	r16, r16 +    1eac:	11 1f       	adc	r17, r17 +      address = newAddress; +      verifySpace(); +    1eae:	83 d0       	rcall	.+262    	; 0x1fb6 <verifySpace> +    1eb0:	68 01       	movw	r12, r16 +    1eb2:	6f c0       	rjmp	.+222    	; 0x1f92 <main+0x192> +    } +    else if(ch == STK_UNIVERSAL) { +    1eb4:	86 35       	cpi	r24, 0x56	; 86 +    1eb6:	21 f4       	brne	.+8      	; 0x1ec0 <main+0xc0> +      // UNIVERSAL command is ignored +      getNch(4); +    1eb8:	84 e0       	ldi	r24, 0x04	; 4 +    1eba:	85 d0       	rcall	.+266    	; 0x1fc6 <getNch> +      putch(0x00); +    1ebc:	80 e0       	ldi	r24, 0x00	; 0 +    1ebe:	de cf       	rjmp	.-68     	; 0x1e7c <main+0x7c> +    } +    /* Write memory, length is big endian and is in bytes */ +    else if(ch == STK_PROG_PAGE) { +    1ec0:	84 36       	cpi	r24, 0x64	; 100 +    1ec2:	09 f0       	breq	.+2      	; 0x1ec6 <main+0xc6> +    1ec4:	40 c0       	rjmp	.+128    	; 0x1f46 <main+0x146> +      // PROGRAM PAGE - we support flash programming only, not EEPROM +      uint8_t *bufPtr; +      uint16_t addrPtr; + +      getch();			/* getlen() */ +    1ec6:	6c d0       	rcall	.+216    	; 0x1fa0 <getch> +      length = getch(); +    1ec8:	6b d0       	rcall	.+214    	; 0x1fa0 <getch> +    1eca:	08 2f       	mov	r16, r24 +      getch(); +    1ecc:	69 d0       	rcall	.+210    	; 0x1fa0 <getch> + +      // If we are in RWW section, immediately start page erase +      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    1ece:	80 e0       	ldi	r24, 0x00	; 0 +    1ed0:	c8 16       	cp	r12, r24 +    1ed2:	88 e1       	ldi	r24, 0x18	; 24 +    1ed4:	d8 06       	cpc	r13, r24 +    1ed6:	18 f4       	brcc	.+6      	; 0x1ede <main+0xde> +    1ed8:	f6 01       	movw	r30, r12 +    1eda:	b7 be       	out	0x37, r11	; 55 +    1edc:	e8 95       	spm +    1ede:	c0 e0       	ldi	r28, 0x00	; 0 +    1ee0:	d1 e0       	ldi	r29, 0x01	; 1 + +      // While that is going on, read in page contents +      bufPtr = buff; +      do *bufPtr++ = getch(); +    1ee2:	5e d0       	rcall	.+188    	; 0x1fa0 <getch> +    1ee4:	89 93       	st	Y+, r24 +      while (--length); +    1ee6:	0c 17       	cp	r16, r28 +    1ee8:	e1 f7       	brne	.-8      	; 0x1ee2 <main+0xe2> + +      // If we are in NRWW section, page erase has to be delayed until now. +      // Todo: Take RAMPZ into account +      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +    1eea:	f0 e0       	ldi	r31, 0x00	; 0 +    1eec:	cf 16       	cp	r12, r31 +    1eee:	f8 e1       	ldi	r31, 0x18	; 24 +    1ef0:	df 06       	cpc	r13, r31 +    1ef2:	18 f0       	brcs	.+6      	; 0x1efa <main+0xfa> +    1ef4:	f6 01       	movw	r30, r12 +    1ef6:	b7 be       	out	0x37, r11	; 55 +    1ef8:	e8 95       	spm + +      // Read command terminator, start reply +      verifySpace(); +    1efa:	5d d0       	rcall	.+186    	; 0x1fb6 <verifySpace> + +      // If only a partial page is to be programmed, the erase might not be complete. +      // So check that here +      boot_spm_busy_wait(); +    1efc:	07 b6       	in	r0, 0x37	; 55 +    1efe:	00 fc       	sbrc	r0, 0 +    1f00:	fd cf       	rjmp	.-6      	; 0x1efc <main+0xfc> +    1f02:	a6 01       	movw	r20, r12 +    1f04:	a0 e0       	ldi	r26, 0x00	; 0 +    1f06:	b1 e0       	ldi	r27, 0x01	; 1 +      bufPtr = buff; +      addrPtr = (uint16_t)(void*)address; +      ch = SPM_PAGESIZE / 2; +      do { +        uint16_t a; +        a = *bufPtr++; +    1f08:	2c 91       	ld	r18, X +    1f0a:	30 e0       	ldi	r19, 0x00	; 0 +        a |= (*bufPtr++) << 8; +    1f0c:	11 96       	adiw	r26, 0x01	; 1 +    1f0e:	8c 91       	ld	r24, X +    1f10:	11 97       	sbiw	r26, 0x01	; 1 +    1f12:	90 e0       	ldi	r25, 0x00	; 0 +    1f14:	98 2f       	mov	r25, r24 +    1f16:	88 27       	eor	r24, r24 +    1f18:	82 2b       	or	r24, r18 +    1f1a:	93 2b       	or	r25, r19 +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    1f1c:	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); +    1f1e:	fa 01       	movw	r30, r20 +    1f20:	0c 01       	movw	r0, r24 +    1f22:	87 be       	out	0x37, r8	; 55 +    1f24:	e8 95       	spm +    1f26:	11 24       	eor	r1, r1 +        addrPtr += 2; +    1f28:	4e 5f       	subi	r20, 0xFE	; 254 +    1f2a:	5f 4f       	sbci	r21, 0xFF	; 255 +      } while (--ch); +    1f2c:	f1 e0       	ldi	r31, 0x01	; 1 +    1f2e:	a0 34       	cpi	r26, 0x40	; 64 +    1f30:	bf 07       	cpc	r27, r31 +    1f32:	51 f7       	brne	.-44     	; 0x1f08 <main+0x108> + +      // Write from programming buffer +      __boot_page_write_short((uint16_t)(void*)address); +    1f34:	f6 01       	movw	r30, r12 +    1f36:	a7 be       	out	0x37, r10	; 55 +    1f38:	e8 95       	spm +      boot_spm_busy_wait(); +    1f3a:	07 b6       	in	r0, 0x37	; 55 +    1f3c:	00 fc       	sbrc	r0, 0 +    1f3e:	fd cf       	rjmp	.-6      	; 0x1f3a <main+0x13a> + +#if defined(RWWSRE) +      // Reenable read access to flash +      boot_rww_enable(); +    1f40:	97 be       	out	0x37, r9	; 55 +    1f42:	e8 95       	spm +    1f44:	26 c0       	rjmp	.+76     	; 0x1f92 <main+0x192> +#endif + +    } +    /* Read memory block mode, length is big endian.  */ +    else if(ch == STK_READ_PAGE) { +    1f46:	84 37       	cpi	r24, 0x74	; 116 +    1f48:	b1 f4       	brne	.+44     	; 0x1f76 <main+0x176> +      // READ PAGE - we only read flash +      getch();			/* getlen() */ +    1f4a:	2a d0       	rcall	.+84     	; 0x1fa0 <getch> +      length = getch(); +    1f4c:	29 d0       	rcall	.+82     	; 0x1fa0 <getch> +    1f4e:	f8 2e       	mov	r15, r24 +      getch(); +    1f50:	27 d0       	rcall	.+78     	; 0x1fa0 <getch> + +      verifySpace(); +    1f52:	31 d0       	rcall	.+98     	; 0x1fb6 <verifySpace> +    1f54:	f6 01       	movw	r30, r12 +    1f56:	ef 2c       	mov	r14, r15 +        putch(result); +        address++; +      } +      while (--length); +#else +      do putch(pgm_read_byte_near(address++)); +    1f58:	8f 01       	movw	r16, r30 +    1f5a:	0f 5f       	subi	r16, 0xFF	; 255 +    1f5c:	1f 4f       	sbci	r17, 0xFF	; 255 +    1f5e:	84 91       	lpm	r24, Z+ +    1f60:	1b d0       	rcall	.+54     	; 0x1f98 <putch> +      while (--length); +    1f62:	ea 94       	dec	r14 +    1f64:	f8 01       	movw	r30, r16 +    1f66:	c1 f7       	brne	.-16     	; 0x1f58 <main+0x158> +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { +    1f68:	08 94       	sec +    1f6a:	c1 1c       	adc	r12, r1 +    1f6c:	d1 1c       	adc	r13, r1 +    1f6e:	fa 94       	dec	r15 +    1f70:	cf 0c       	add	r12, r15 +    1f72:	d1 1c       	adc	r13, r1 +    1f74:	0e c0       	rjmp	.+28     	; 0x1f92 <main+0x192> +#endif +#endif +    } + +    /* Get device signature bytes  */ +    else if(ch == STK_READ_SIGN) { +    1f76:	85 37       	cpi	r24, 0x75	; 117 +    1f78:	39 f4       	brne	.+14     	; 0x1f88 <main+0x188> +      // READ SIGN - return what Avrdude wants to hear +      verifySpace(); +    1f7a:	1d d0       	rcall	.+58     	; 0x1fb6 <verifySpace> +      putch(SIGNATURE_0); +    1f7c:	8e e1       	ldi	r24, 0x1E	; 30 +    1f7e:	0c d0       	rcall	.+24     	; 0x1f98 <putch> +      putch(SIGNATURE_1); +    1f80:	83 e9       	ldi	r24, 0x93	; 147 +    1f82:	0a d0       	rcall	.+20     	; 0x1f98 <putch> +      putch(SIGNATURE_2); +    1f84:	87 e0       	ldi	r24, 0x07	; 7 +    1f86:	7a cf       	rjmp	.-268    	; 0x1e7c <main+0x7c> +    } +    else if (ch == 'Q') { +    1f88:	81 35       	cpi	r24, 0x51	; 81 +    1f8a:	11 f4       	brne	.+4      	; 0x1f90 <main+0x190> +      // Adaboot no-wait mod +      watchdogConfig(WATCHDOG_16MS); +    1f8c:	88 e0       	ldi	r24, 0x08	; 8 +    1f8e:	0f d0       	rcall	.+30     	; 0x1fae <watchdogConfig> +      verifySpace(); +    } +    else { +      // This covers the response to commands like STK_ENTER_PROGMODE +      verifySpace(); +    1f90:	12 d0       	rcall	.+36     	; 0x1fb6 <verifySpace> +    } +    putch(STK_OK); +    1f92:	80 e1       	ldi	r24, 0x10	; 16 +    1f94:	01 d0       	rcall	.+2      	; 0x1f98 <putch> +    1f96:	65 cf       	rjmp	.-310    	; 0x1e62 <main+0x62> + +00001f98 <putch>: +  } +} + +void putch(char ch) { +#ifndef SOFT_UART +  while (!(UCSR0A & _BV(UDRE0))); +    1f98:	5d 9b       	sbis	0x0b, 5	; 11 +    1f9a:	fe cf       	rjmp	.-4      	; 0x1f98 <putch> +  UDR0 = ch; +    1f9c:	8c b9       	out	0x0c, r24	; 12 +      [uartBit] "I" (UART_TX_BIT) +    : +      "r25" +  ); +#endif +} +    1f9e:	08 95       	ret + +00001fa0 <getch>: +      [uartBit] "I" (UART_RX_BIT) +    : +      "r25" +); +#else +  while(!(UCSR0A & _BV(RXC0))) +    1fa0:	5f 9b       	sbis	0x0b, 7	; 11 +    1fa2:	fe cf       	rjmp	.-4      	; 0x1fa0 <getch> +    ; +  if (!(UCSR0A & _BV(FE0))) { +    1fa4:	5c 99       	sbic	0x0b, 4	; 11 +    1fa6:	01 c0       	rjmp	.+2      	; 0x1faa <getch+0xa> +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { +  __asm__ __volatile__ ( +    1fa8:	a8 95       	wdr +       * don't care that an invalid char is returned...) +       */ +    watchdogReset(); +  } +   +  ch = UDR0; +    1faa:	8c b1       	in	r24, 0x0c	; 12 +  LED_PIN |= _BV(LED); +#endif +#endif + +  return ch; +} +    1fac:	08 95       	ret + +00001fae <watchdogConfig>: +    "wdr\n" +  ); +} + +void watchdogConfig(uint8_t x) { +  WDTCSR = _BV(WDCE) | _BV(WDE); +    1fae:	98 e1       	ldi	r25, 0x18	; 24 +    1fb0:	91 bd       	out	0x21, r25	; 33 +  WDTCSR = x; +    1fb2:	81 bd       	out	0x21, r24	; 33 +} +    1fb4:	08 95       	ret + +00001fb6 <verifySpace>: +  do getch(); while (--count); +  verifySpace(); +} + +void verifySpace() { +  if (getch() != CRC_EOP) { +    1fb6:	f4 df       	rcall	.-24     	; 0x1fa0 <getch> +    1fb8:	80 32       	cpi	r24, 0x20	; 32 +    1fba:	19 f0       	breq	.+6      	; 0x1fc2 <verifySpace+0xc> +    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout +    1fbc:	88 e0       	ldi	r24, 0x08	; 8 +    1fbe:	f7 df       	rcall	.-18     	; 0x1fae <watchdogConfig> +    1fc0:	ff cf       	rjmp	.-2      	; 0x1fc0 <verifySpace+0xa> +    while (1)			      // and busy-loop so that WD causes +      ;				      //  a reset and app start. +  } +  putch(STK_INSYNC); +    1fc2:	84 e1       	ldi	r24, 0x14	; 20 +} +    1fc4:	e9 cf       	rjmp	.-46     	; 0x1f98 <putch> + +00001fc6 <getNch>: +    ::[count] "M" (UART_B_VALUE) +  ); +} +#endif + +void getNch(uint8_t count) { +    1fc6:	1f 93       	push	r17 +    1fc8:	18 2f       	mov	r17, r24 +  do getch(); while (--count); +    1fca:	ea df       	rcall	.-44     	; 0x1fa0 <getch> +    1fcc:	11 50       	subi	r17, 0x01	; 1 +    1fce:	e9 f7       	brne	.-6      	; 0x1fca <getNch+0x4> +  verifySpace(); +    1fd0:	f2 df       	rcall	.-28     	; 0x1fb6 <verifySpace> +} +    1fd2:	1f 91       	pop	r17 +    1fd4:	08 95       	ret + +00001fd6 <appStart>: +  WDTCSR = _BV(WDCE) | _BV(WDE); +  WDTCSR = x; +} + +void appStart() { +  watchdogConfig(WATCHDOG_OFF); +    1fd6:	80 e0       	ldi	r24, 0x00	; 0 +    1fd8:	ea df       	rcall	.-44     	; 0x1fae <watchdogConfig> +  __asm__ __volatile__ ( +    1fda:	ee 27       	eor	r30, r30 +    1fdc:	ff 27       	eor	r31, r31 +    1fde:	09 94       	ijmp  | 
