diff --git a/boards.txt b/boards.txt index 10acdce..98b63df 100644 --- a/boards.txt +++ b/boards.txt @@ -19,6 +19,25 @@ mighty_opt.build.variant=standard ############################################################## +mighty_opt8.name=Mighty 1284p 8MHz using Optiboot +mighty_opt8.upload.protocol=arduino +mighty_opt8.upload.maximum_size=129568 +mighty_opt8.upload.speed=57600 +mighty_opt8.bootloader.low_fuses=0xff +mighty_opt8.bootloader.high_fuses=0xdc +mighty_opt8.bootloader.extended_fuses=0xfd +mighty_opt8.bootloader.path=optiboot +mighty_opt8.bootloader.file=optiboot_atmega1284p_8MHz.hex +mighty_opt8.bootloader.unlock_bits=0x3F +mighty_opt8.bootloader.lock_bits=0x0F +mighty_opt8.build.mcu=atmega1284p +mighty_opt8.build.f_cpu=8000000L +#mighty_opt8.build.core=arduino:arduino +mighty_opt8.build.core=standard +mighty_opt8.build.variant=standard + +############################################################## + avr_developers.name=avr-developers.com pinouts 16MHz using Optiboot avr_developers.upload.protocol=arduino avr_developers.upload.maximum_size=130048 @@ -92,3 +111,42 @@ mighty8.build.f_cpu=8000000L #mighty8.build.core=arduino:arduino mighty8.build.core=standard mighty8.build.variant=standard + +############################################################## + +mighty_int8.name=Mighty 1284p 8MHz, internal oscillator +mighty_int8.upload.protocol=stk500v1 +mighty_int8.upload.maximum_size=129024 +mighty_int8.upload.speed=28800 +mighty_int8.bootloader.low_fuses=0xe2 +mighty_int8.bootloader.high_fuses=0xdc +mighty_int8.bootloader.extended_fuses=0xfd +mighty_int8.bootloader.path=standard +mighty_int8.bootloader.file=ATmegaBOOT_1284P_8MHz.hex +mighty_int8.bootloader.unlock_bits=0x3F +mighty_int8.bootloader.lock_bits=0x0F +mighty_int8.build.mcu=atmega1284p +mighty_int8.build.f_cpu=8000000L +#mighty_int8.build.core=arduino:arduino +mighty_int8.build.core=standard +mighty_int8.build.variant=standard + +############################################################## + +mighty_int8_opt.name=Mighty 1284p 8MHz, optiboot, internal oscillator +mighty_int8_opt.upload.protocol=arduino +mighty_int8_opt.upload.maximum_size=130048 +mighty_int8_opt.upload.speed=57600 +mighty_int8_opt.bootloader.low_fuses=0xe2 +mighty_int8_opt.bootloader.high_fuses=0xdc +mighty_int8_opt.bootloader.extended_fuses=0xfd +mighty_int8_opt.bootloader.path=optiboot +mighty_int8_opt.bootloader.file=optiboot_atmega1284p_8MHz_osc.hex +mighty_int8_opt.bootloader.unlock_bits=0x3F +mighty_int8_opt.bootloader.lock_bits=0x0F +mighty_int8_opt.build.mcu=atmega1284p +mighty_int8_opt.build.f_cpu=8000000L +#mighty_int8_opt.build.core=arduino:arduino +mighty_int8_opt.build.core=standard +mighty_int8_opt.build.variant=standard + diff --git a/bootloaders/optiboot/Makefile b/bootloaders/optiboot/Makefile index 89dff32..6636d6e 100644 --- a/bootloaders/optiboot/Makefile +++ b/bootloaders/optiboot/Makefile @@ -412,6 +412,44 @@ atmega328_pro8_isp: LFUSE = FF atmega328_pro8_isp: EFUSE = 05 atmega328_pro8_isp: isp +atmega1284_int8: TARGET = atmega1284p_8MHz_osc +atmega1284_int8: MCU_TARGET = atmega1284p +atmega1284_int8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=57600' '-DBIGBOOT' +atmega1284_int8: AVR_FREQ = 8000000L +atmega1284_int8: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 +atmega1284_int8: $(PROGRAM)_atmega1284p_8MHz_osc.hex +atmega1284_int8: $(PROGRAM)_atmega1284p_8MHz_osc.lst + +atmega1284_8MHz_osc_isp: atmega1284_int8 +atmega1284_8MHz_osc_isp: TARGET = atmega1284p_8MHz_osc +atmega1284_8MHz_osc_isp: MCU_TARGET = atmega1284p +# 1024 byte boot +atmega1284_8MHz_osc_isp: HFUSE = DC +# Int. RC Osc. 6CK+65ms +atmega1284_8MHz_osc_isp: LFUSE = E2 +# 2.7V brownout +atmega1284_8MHz_osc_isp: EFUSE = FD +atmega1284_8MHz_osc_isp: isp + +atmega1284_8MHz: TARGET = atmega1284p_8MHz +atmega1284_8MHz: MCU_TARGET = atmega1284p +atmega1284_8MHz: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=57600' '-DBIGBOOT' +atmega1284_8MHz: AVR_FREQ = 8000000L +atmega1284_8MHz: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 +atmega1284_8MHz: $(PROGRAM)_atmega1284p_8MHz.hex +atmega1284_8MHz: $(PROGRAM)_atmega1284p_8MHz.lst + +atmega1284_8MHz_isp: atmega1284_8MHz +atmega1284_8MHz_isp: TARGET = atmega1284p_8MHz +atmega1284_8MHz_isp: MCU_TARGET = atmega1284p +# 1024 byte boot +atmega1284_8MHz_isp: HFUSE = DC +# Int. RC Osc. 6CK+65ms +atmega1284_8MHz_isp: LFUSE = FF +# 2.7V brownout +atmega1284_8MHz_isp: EFUSE = FD +atmega1284_8MHz_isp: isp + # 1MHz clocked platforms # # These are capable of 9600 baud diff --git a/bootloaders/optiboot/optiboot_atmega1284p_8MHz.hex b/bootloaders/optiboot/optiboot_atmega1284p_8MHz.hex new file mode 100644 index 0000000..ef16795 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega1284p_8MHz.hex @@ -0,0 +1,36 @@ +:020000000504F5 +:020000021000EC +:10FC00000F92CDB7DEB7112484B714BE81FFF2D0B6 +:10FC100085E08093810082E08093C00088E180933A +:10FC2000C10086E08093C20080E18093C4008EE032 +:10FC3000CBD0209A26E088E19EEF31E090938500BA +:10FC40008093840036BBB09BFECF189AA8952150B4 +:10FC5000A9F788249924DD24D394E1E1EE2E73E002 +:10FC6000F72EA6D0813471F4A3D08983B3D08981D3 +:10FC7000823809F48CC0813811F484E001C083E03B +:10FC800090D08CC0823411F484E103C0853419F41F +:10FC900085E0A8D083C0853591F48AD0082F10E084 +:10FCA00087D090E0382F2227202B312B832F881FDD +:10FCB0008827881F8BBF4901880C991C6EC0863528 +:10FCC00021F484E08FD080E0DBCF843609F041C09E +:10FCD0006FD06ED0C82E6CD080E0881680EE98066B +:10FCE00018F4F401F7BEE89500E011E061D0F801E6 +:10FCF00081938F01CE16D1F7F0E08F16F0EE9F06BC +:10FD000018F0F401F7BEE89565D007B600FCFDCF0A +:10FD1000F401A0E0B1E02C9130E011968C911197A4 +:10FD200090E0982F8827822B932B12960C01D7BE38 +:10FD3000E8951124329682E0A030B80761F785E09B +:10FD4000F40187BFE89507B600FCFDCFE7BEE89554 +:10FD500025C08437A9F42CD02BD0B82E29D03AD086 +:10FD6000CB2C8401F80186911CD00F5F1F4FCA94E1 +:10FD7000C9F70894811C911CBA948B0C911C0EC07D +:10FD8000853739F427D08EE10CD087E90AD085E099 +:10FD900077CF813511F488E017D01CD080E101D0F5 +:10FDA00060CF9091C00095FFFCCF8093C60008956E +:10FDB0008091C00087FFFCCF8091C00084FD01C00E +:10FDC000A8958091C6000895E0E6F0E098E1908360 +:10FDD00080830895EDDF803219F088E0F5DFFFCFF2 +:10FDE00084E1DFCFCF93C82FE3DFC150E9F7F2DF23 +:0EFDF000CF91089580E0E8DFEE27FF27099409 +:040000031000FC00ED +:00000001FF diff --git a/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.hex b/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.hex new file mode 100644 index 0000000..ef16795 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.hex @@ -0,0 +1,36 @@ +:020000000504F5 +:020000021000EC +:10FC00000F92CDB7DEB7112484B714BE81FFF2D0B6 +:10FC100085E08093810082E08093C00088E180933A +:10FC2000C10086E08093C20080E18093C4008EE032 +:10FC3000CBD0209A26E088E19EEF31E090938500BA +:10FC40008093840036BBB09BFECF189AA8952150B4 +:10FC5000A9F788249924DD24D394E1E1EE2E73E002 +:10FC6000F72EA6D0813471F4A3D08983B3D08981D3 +:10FC7000823809F48CC0813811F484E001C083E03B +:10FC800090D08CC0823411F484E103C0853419F41F +:10FC900085E0A8D083C0853591F48AD0082F10E084 +:10FCA00087D090E0382F2227202B312B832F881FDD +:10FCB0008827881F8BBF4901880C991C6EC0863528 +:10FCC00021F484E08FD080E0DBCF843609F041C09E +:10FCD0006FD06ED0C82E6CD080E0881680EE98066B +:10FCE00018F4F401F7BEE89500E011E061D0F801E6 +:10FCF00081938F01CE16D1F7F0E08F16F0EE9F06BC +:10FD000018F0F401F7BEE89565D007B600FCFDCF0A +:10FD1000F401A0E0B1E02C9130E011968C911197A4 +:10FD200090E0982F8827822B932B12960C01D7BE38 +:10FD3000E8951124329682E0A030B80761F785E09B +:10FD4000F40187BFE89507B600FCFDCFE7BEE89554 +:10FD500025C08437A9F42CD02BD0B82E29D03AD086 +:10FD6000CB2C8401F80186911CD00F5F1F4FCA94E1 +:10FD7000C9F70894811C911CBA948B0C911C0EC07D +:10FD8000853739F427D08EE10CD087E90AD085E099 +:10FD900077CF813511F488E017D01CD080E101D0F5 +:10FDA00060CF9091C00095FFFCCF8093C60008956E +:10FDB0008091C00087FFFCCF8091C00084FD01C00E +:10FDC000A8958091C6000895E0E6F0E098E1908360 +:10FDD00080830895EDDF803219F088E0F5DFFFCFF2 +:10FDE00084E1DFCFCF93C82FE3DFC150E9F7F2DF23 +:0EFDF000CF91089580E0E8DFEE27FF27099409 +:040000031000FC00ED +:00000001FF diff --git a/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.lst b/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.lst new file mode 100644 index 0000000..7326715 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega1284p_8MHz_osc.lst @@ -0,0 +1,619 @@ + +optiboot_atmega1284p_8MHz_osc.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 000001fe 0001fc00 0001fc00 00000054 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .version 00000002 00000000 00000000 00000252 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 00000254 2**0 + CONTENTS, READONLY, DEBUGGING + 3 .debug_pubnames 0000005f 00000000 00000000 0000027c 2**0 + CONTENTS, READONLY, DEBUGGING + 4 .debug_info 00000298 00000000 00000000 000002db 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_abbrev 0000015d 00000000 00000000 00000573 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 00000464 00000000 00000000 000006d0 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_frame 00000080 00000000 00000000 00000b34 2**2 + CONTENTS, READONLY, DEBUGGING + 8 .debug_str 0000013e 00000000 00000000 00000bb4 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_loc 000002a0 00000000 00000000 00000cf2 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_pubtypes 0000002b 00000000 00000000 00000f92 2**0 + CONTENTS, READONLY, DEBUGGING + 11 .debug_ranges 00000048 00000000 00000000 00000fbd 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +0001fc00
: +#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) { + 1fc00: 0f 92 push r0 + 1fc02: cd b7 in r28, 0x3d ; 61 + 1fc04: de b7 in r29, 0x3e ; 62 + // SP points to RAMEND + // r1 contains zero + // + // If not, uncomment the following instructions: + // cli(); + asm volatile ("clr __zero_reg__"); + 1fc06: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif + + // Adaboot no-wait mod + ch = MCUSR; + 1fc08: 84 b7 in r24, 0x34 ; 52 + MCUSR = 0; + 1fc0a: 14 be out 0x34, r1 ; 52 + if (!(ch & _BV(EXTRF))) appStart(); + 1fc0c: 81 ff sbrs r24, 1 + 1fc0e: f2 d0 rcall .+484 ; 0x1fdf4 + +#if LED_START_FLASHES > 0 + // Set up Timer 1 for timeout counter + TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 + 1fc10: 85 e0 ldi r24, 0x05 ; 5 + 1fc12: 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 + 1fc16: 82 e0 ldi r24, 0x02 ; 2 + 1fc18: 80 93 c0 00 sts 0x00C0, r24 + UCSR0B = _BV(RXEN0) | _BV(TXEN0); + 1fc1c: 88 e1 ldi r24, 0x18 ; 24 + 1fc1e: 80 93 c1 00 sts 0x00C1, r24 + UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); + 1fc22: 86 e0 ldi r24, 0x06 ; 6 + 1fc24: 80 93 c2 00 sts 0x00C2, r24 + UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); + 1fc28: 80 e1 ldi r24, 0x10 ; 16 + 1fc2a: 80 93 c4 00 sts 0x00C4, r24 +#endif +#endif + + // Set up watchdog to trigger after 500ms + watchdogConfig(WATCHDOG_1S); + 1fc2e: 8e e0 ldi r24, 0x0E ; 14 + 1fc30: cb d0 rcall .+406 ; 0x1fdc8 + + /* Set LED pin as output */ + LED_DDR |= _BV(LED); + 1fc32: 20 9a sbi 0x04, 0 ; 4 + 1fc34: 26 e0 ldi r18, 0x06 ; 6 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 1fc36: 88 e1 ldi r24, 0x18 ; 24 + 1fc38: 9e ef ldi r25, 0xFE ; 254 + TIFR1 = _BV(TOV1); + 1fc3a: 31 e0 ldi r19, 0x01 ; 1 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 1fc3c: 90 93 85 00 sts 0x0085, r25 + 1fc40: 80 93 84 00 sts 0x0084, r24 + TIFR1 = _BV(TOV1); + 1fc44: 36 bb out 0x16, r19 ; 22 + while(!(TIFR1 & _BV(TOV1))); + 1fc46: b0 9b sbis 0x16, 0 ; 22 + 1fc48: fe cf rjmp .-4 ; 0x1fc46 +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else + LED_PIN |= _BV(LED); + 1fc4a: 18 9a sbi 0x03, 0 ; 3 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 1fc4c: a8 95 wdr + LED_PORT ^= _BV(LED); +#else + LED_PIN |= _BV(LED); +#endif + watchdogReset(); + } while (--count); + 1fc4e: 21 50 subi r18, 0x01 ; 1 + 1fc50: a9 f7 brne .-22 ; 0x1fc3c + 1fc52: 88 24 eor r8, r8 + 1fc54: 99 24 eor r9, r9 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 1fc56: dd 24 eor r13, r13 + 1fc58: d3 94 inc r13 + __boot_page_write_short((uint16_t)(void*)address); + boot_spm_busy_wait(); + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 1fc5a: e1 e1 ldi r30, 0x11 ; 17 + 1fc5c: ee 2e mov r14, r30 + 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); + 1fc5e: 73 e0 ldi r23, 0x03 ; 3 + 1fc60: f7 2e mov r15, r23 +#endif + + /* Forever loop */ + for (;;) { + /* get character from UART */ + ch = getch(); + 1fc62: a6 d0 rcall .+332 ; 0x1fdb0 + + if(ch == STK_GET_PARAMETER) { + 1fc64: 81 34 cpi r24, 0x41 ; 65 + 1fc66: 71 f4 brne .+28 ; 0x1fc84 + unsigned char which = getch(); + 1fc68: a3 d0 rcall .+326 ; 0x1fdb0 + verifySpace(); + 1fc6a: 89 83 std Y+1, r24 ; 0x01 + 1fc6c: b3 d0 rcall .+358 ; 0x1fdd4 + if (which == 0x82) { + 1fc6e: 89 81 ldd r24, Y+1 ; 0x01 + 1fc70: 82 38 cpi r24, 0x82 ; 130 + 1fc72: 09 f4 brne .+2 ; 0x1fc76 + 1fc74: 8c c0 rjmp .+280 ; 0x1fd8e + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 1fc76: 81 38 cpi r24, 0x81 ; 129 + 1fc78: 11 f4 brne .+4 ; 0x1fc7e + putch(OPTIBOOT_MAJVER); + 1fc7a: 84 e0 ldi r24, 0x04 ; 4 + 1fc7c: 01 c0 rjmp .+2 ; 0x1fc80 + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 1fc7e: 83 e0 ldi r24, 0x03 ; 3 + 1fc80: 90 d0 rcall .+288 ; 0x1fda2 + 1fc82: 8c c0 rjmp .+280 ; 0x1fd9c + } + } + else if(ch == STK_SET_DEVICE) { + 1fc84: 82 34 cpi r24, 0x42 ; 66 + 1fc86: 11 f4 brne .+4 ; 0x1fc8c + // SET DEVICE is ignored + getNch(20); + 1fc88: 84 e1 ldi r24, 0x14 ; 20 + 1fc8a: 03 c0 rjmp .+6 ; 0x1fc92 + } + else if(ch == STK_SET_DEVICE_EXT) { + 1fc8c: 85 34 cpi r24, 0x45 ; 69 + 1fc8e: 19 f4 brne .+6 ; 0x1fc96 + // SET DEVICE EXT is ignored + getNch(5); + 1fc90: 85 e0 ldi r24, 0x05 ; 5 + 1fc92: a8 d0 rcall .+336 ; 0x1fde4 + 1fc94: 83 c0 rjmp .+262 ; 0x1fd9c + } + else if(ch == STK_LOAD_ADDRESS) { + 1fc96: 85 35 cpi r24, 0x55 ; 85 + 1fc98: 91 f4 brne .+36 ; 0x1fcbe + // LOAD ADDRESS + uint16_t newAddress; + newAddress = getch(); + 1fc9a: 8a d0 rcall .+276 ; 0x1fdb0 + newAddress = (newAddress & 0xff) | (getch() << 8); + 1fc9c: 08 2f mov r16, r24 + 1fc9e: 10 e0 ldi r17, 0x00 ; 0 + 1fca0: 87 d0 rcall .+270 ; 0x1fdb0 + 1fca2: 90 e0 ldi r25, 0x00 ; 0 + 1fca4: 38 2f mov r19, r24 + 1fca6: 22 27 eor r18, r18 + 1fca8: 20 2b or r18, r16 + 1fcaa: 31 2b or r19, r17 +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; + 1fcac: 83 2f mov r24, r19 + 1fcae: 88 1f adc r24, r24 + 1fcb0: 88 27 eor r24, r24 + 1fcb2: 88 1f adc r24, r24 + 1fcb4: 8b bf out 0x3b, r24 ; 59 +#endif + newAddress += newAddress; // Convert from word address to byte address + 1fcb6: 49 01 movw r8, r18 + 1fcb8: 88 0c add r8, r8 + 1fcba: 99 1c adc r9, r9 + 1fcbc: 6e c0 rjmp .+220 ; 0x1fd9a + address = newAddress; + verifySpace(); + } + else if(ch == STK_UNIVERSAL) { + 1fcbe: 86 35 cpi r24, 0x56 ; 86 + 1fcc0: 21 f4 brne .+8 ; 0x1fcca + // UNIVERSAL command is ignored + getNch(4); + 1fcc2: 84 e0 ldi r24, 0x04 ; 4 + 1fcc4: 8f d0 rcall .+286 ; 0x1fde4 + putch(0x00); + 1fcc6: 80 e0 ldi r24, 0x00 ; 0 + 1fcc8: db cf rjmp .-74 ; 0x1fc80 + } + /* Write memory, length is big endian and is in bytes */ + else if(ch == STK_PROG_PAGE) { + 1fcca: 84 36 cpi r24, 0x64 ; 100 + 1fccc: 09 f0 breq .+2 ; 0x1fcd0 + 1fcce: 41 c0 rjmp .+130 ; 0x1fd52 + // PROGRAM PAGE - we support flash programming only, not EEPROM + uint8_t *bufPtr; + uint16_t addrPtr; + + getch(); /* getlen() */ + 1fcd0: 6f d0 rcall .+222 ; 0x1fdb0 + length = getch(); + 1fcd2: 6e d0 rcall .+220 ; 0x1fdb0 + 1fcd4: c8 2e mov r12, r24 + getch(); + 1fcd6: 6c d0 rcall .+216 ; 0x1fdb0 + + // If we are in RWW section, immediately start page erase + if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 1fcd8: 80 e0 ldi r24, 0x00 ; 0 + 1fcda: 88 16 cp r8, r24 + 1fcdc: 80 ee ldi r24, 0xE0 ; 224 + 1fcde: 98 06 cpc r9, r24 + 1fce0: 18 f4 brcc .+6 ; 0x1fce8 + 1fce2: f4 01 movw r30, r8 + 1fce4: f7 be out 0x37, r15 ; 55 + 1fce6: e8 95 spm + 1fce8: 00 e0 ldi r16, 0x00 ; 0 + 1fcea: 11 e0 ldi r17, 0x01 ; 1 + + // While that is going on, read in page contents + bufPtr = buff; + do *bufPtr++ = getch(); + 1fcec: 61 d0 rcall .+194 ; 0x1fdb0 + 1fcee: f8 01 movw r30, r16 + 1fcf0: 81 93 st Z+, r24 + 1fcf2: 8f 01 movw r16, r30 + while (--length); + 1fcf4: ce 16 cp r12, r30 + 1fcf6: d1 f7 brne .-12 ; 0x1fcec + + // 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); + 1fcf8: f0 e0 ldi r31, 0x00 ; 0 + 1fcfa: 8f 16 cp r8, r31 + 1fcfc: f0 ee ldi r31, 0xE0 ; 224 + 1fcfe: 9f 06 cpc r9, r31 + 1fd00: 18 f0 brcs .+6 ; 0x1fd08 + 1fd02: f4 01 movw r30, r8 + 1fd04: f7 be out 0x37, r15 ; 55 + 1fd06: e8 95 spm + + // Read command terminator, start reply + verifySpace(); + 1fd08: 65 d0 rcall .+202 ; 0x1fdd4 + + // If only a partial page is to be programmed, the erase might not be complete. + // So check that here + boot_spm_busy_wait(); + 1fd0a: 07 b6 in r0, 0x37 ; 55 + 1fd0c: 00 fc sbrc r0, 0 + 1fd0e: fd cf rjmp .-6 ; 0x1fd0a + 1fd10: f4 01 movw r30, r8 + 1fd12: a0 e0 ldi r26, 0x00 ; 0 + 1fd14: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + 1fd16: 2c 91 ld r18, X + 1fd18: 30 e0 ldi r19, 0x00 ; 0 + a |= (*bufPtr++) << 8; + 1fd1a: 11 96 adiw r26, 0x01 ; 1 + 1fd1c: 8c 91 ld r24, X + 1fd1e: 11 97 sbiw r26, 0x01 ; 1 + 1fd20: 90 e0 ldi r25, 0x00 ; 0 + 1fd22: 98 2f mov r25, r24 + 1fd24: 88 27 eor r24, r24 + 1fd26: 82 2b or r24, r18 + 1fd28: 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) { + 1fd2a: 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); + 1fd2c: 0c 01 movw r0, r24 + 1fd2e: d7 be out 0x37, r13 ; 55 + 1fd30: e8 95 spm + 1fd32: 11 24 eor r1, r1 + addrPtr += 2; + 1fd34: 32 96 adiw r30, 0x02 ; 2 + } while (--ch); + 1fd36: 82 e0 ldi r24, 0x02 ; 2 + 1fd38: a0 30 cpi r26, 0x00 ; 0 + 1fd3a: b8 07 cpc r27, r24 + 1fd3c: 61 f7 brne .-40 ; 0x1fd16 + + // Write from programming buffer + __boot_page_write_short((uint16_t)(void*)address); + 1fd3e: 85 e0 ldi r24, 0x05 ; 5 + 1fd40: f4 01 movw r30, r8 + 1fd42: 87 bf out 0x37, r24 ; 55 + 1fd44: e8 95 spm + boot_spm_busy_wait(); + 1fd46: 07 b6 in r0, 0x37 ; 55 + 1fd48: 00 fc sbrc r0, 0 + 1fd4a: fd cf rjmp .-6 ; 0x1fd46 + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 1fd4c: e7 be out 0x37, r14 ; 55 + 1fd4e: e8 95 spm + 1fd50: 25 c0 rjmp .+74 ; 0x1fd9c +#endif + + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) { + 1fd52: 84 37 cpi r24, 0x74 ; 116 + 1fd54: a9 f4 brne .+42 ; 0x1fd80 + // READ PAGE - we only read flash + getch(); /* getlen() */ + 1fd56: 2c d0 rcall .+88 ; 0x1fdb0 + length = getch(); + 1fd58: 2b d0 rcall .+86 ; 0x1fdb0 + 1fd5a: b8 2e mov r11, r24 + getch(); + 1fd5c: 29 d0 rcall .+82 ; 0x1fdb0 + + verifySpace(); + 1fd5e: 3a d0 rcall .+116 ; 0x1fdd4 + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) { + // READ PAGE - we only read flash + getch(); /* getlen() */ + length = getch(); + 1fd60: cb 2c mov r12, r11 + getch(); + + verifySpace(); + 1fd62: 84 01 movw r16, r8 +// Since RAMPZ should already be set, we need to use EPLM directly. +// do putch(pgm_read_byte_near(address++)); +// while (--length); + do { + uint8_t result; + __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address)); + 1fd64: f8 01 movw r30, r16 + 1fd66: 86 91 elpm r24, Z+ + putch(result); + 1fd68: 1c d0 rcall .+56 ; 0x1fda2 + address++; + 1fd6a: 0f 5f subi r16, 0xFF ; 255 + 1fd6c: 1f 4f sbci r17, 0xFF ; 255 + } + while (--length); + 1fd6e: ca 94 dec r12 + 1fd70: c9 f7 brne .-14 ; 0x1fd64 +#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) { + 1fd72: 08 94 sec + 1fd74: 81 1c adc r8, r1 + 1fd76: 91 1c adc r9, r1 + 1fd78: ba 94 dec r11 + 1fd7a: 8b 0c add r8, r11 + 1fd7c: 91 1c adc r9, r1 + 1fd7e: 0e c0 rjmp .+28 ; 0x1fd9c +#endif +#endif + } + + /* Get device signature bytes */ + else if(ch == STK_READ_SIGN) { + 1fd80: 85 37 cpi r24, 0x75 ; 117 + 1fd82: 39 f4 brne .+14 ; 0x1fd92 + // READ SIGN - return what Avrdude wants to hear + verifySpace(); + 1fd84: 27 d0 rcall .+78 ; 0x1fdd4 + putch(SIGNATURE_0); + 1fd86: 8e e1 ldi r24, 0x1E ; 30 + 1fd88: 0c d0 rcall .+24 ; 0x1fda2 + putch(SIGNATURE_1); + 1fd8a: 87 e9 ldi r24, 0x97 ; 151 + 1fd8c: 0a d0 rcall .+20 ; 0x1fda2 + putch(SIGNATURE_2); + 1fd8e: 85 e0 ldi r24, 0x05 ; 5 + 1fd90: 77 cf rjmp .-274 ; 0x1fc80 + } + else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ + 1fd92: 81 35 cpi r24, 0x51 ; 81 + 1fd94: 11 f4 brne .+4 ; 0x1fd9a + // Adaboot no-wait mod + watchdogConfig(WATCHDOG_16MS); + 1fd96: 88 e0 ldi r24, 0x08 ; 8 + 1fd98: 17 d0 rcall .+46 ; 0x1fdc8 + verifySpace(); + } + else { + // This covers the response to commands like STK_ENTER_PROGMODE + verifySpace(); + 1fd9a: 1c d0 rcall .+56 ; 0x1fdd4 + } + putch(STK_OK); + 1fd9c: 80 e1 ldi r24, 0x10 ; 16 + 1fd9e: 01 d0 rcall .+2 ; 0x1fda2 + } + 1fda0: 60 cf rjmp .-320 ; 0x1fc62 + +0001fda2 : +} + +void putch(char ch) { +#ifndef SOFT_UART + while (!(UCSR0A & _BV(UDRE0))); + 1fda2: 90 91 c0 00 lds r25, 0x00C0 + 1fda6: 95 ff sbrs r25, 5 + 1fda8: fc cf rjmp .-8 ; 0x1fda2 + UDR0 = ch; + 1fdaa: 80 93 c6 00 sts 0x00C6, r24 + [uartBit] "I" (UART_TX_BIT) + : + "r25" + ); +#endif +} + 1fdae: 08 95 ret + +0001fdb0 : + [uartBit] "I" (UART_RX_BIT) + : + "r25" +); +#else + while(!(UCSR0A & _BV(RXC0))) + 1fdb0: 80 91 c0 00 lds r24, 0x00C0 + 1fdb4: 87 ff sbrs r24, 7 + 1fdb6: fc cf rjmp .-8 ; 0x1fdb0 + ; + if (!(UCSR0A & _BV(FE0))) { + 1fdb8: 80 91 c0 00 lds r24, 0x00C0 + 1fdbc: 84 fd sbrc r24, 4 + 1fdbe: 01 c0 rjmp .+2 ; 0x1fdc2 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 1fdc0: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + + ch = UDR0; + 1fdc2: 80 91 c6 00 lds r24, 0x00C6 + LED_PIN |= _BV(LED); +#endif +#endif + + return ch; +} + 1fdc6: 08 95 ret + +0001fdc8 : + "wdr\n" + ); +} + +void watchdogConfig(uint8_t x) { + WDTCSR = _BV(WDCE) | _BV(WDE); + 1fdc8: e0 e6 ldi r30, 0x60 ; 96 + 1fdca: f0 e0 ldi r31, 0x00 ; 0 + 1fdcc: 98 e1 ldi r25, 0x18 ; 24 + 1fdce: 90 83 st Z, r25 + WDTCSR = x; + 1fdd0: 80 83 st Z, r24 +} + 1fdd2: 08 95 ret + +0001fdd4 : + do getch(); while (--count); + verifySpace(); +} + +void verifySpace() { + if (getch() != CRC_EOP) { + 1fdd4: ed df rcall .-38 ; 0x1fdb0 + 1fdd6: 80 32 cpi r24, 0x20 ; 32 + 1fdd8: 19 f0 breq .+6 ; 0x1fde0 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 1fdda: 88 e0 ldi r24, 0x08 ; 8 + 1fddc: f5 df rcall .-22 ; 0x1fdc8 + 1fdde: ff cf rjmp .-2 ; 0x1fdde + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } + putch(STK_INSYNC); + 1fde0: 84 e1 ldi r24, 0x14 ; 20 +} + 1fde2: df cf rjmp .-66 ; 0x1fda2 + +0001fde4 : + ::[count] "M" (UART_B_VALUE) + ); +} +#endif + +void getNch(uint8_t count) { + 1fde4: cf 93 push r28 + 1fde6: c8 2f mov r28, r24 + do getch(); while (--count); + 1fde8: e3 df rcall .-58 ; 0x1fdb0 + 1fdea: c1 50 subi r28, 0x01 ; 1 + 1fdec: e9 f7 brne .-6 ; 0x1fde8 + verifySpace(); + 1fdee: f2 df rcall .-28 ; 0x1fdd4 +} + 1fdf0: cf 91 pop r28 + 1fdf2: 08 95 ret + +0001fdf4 : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 1fdf4: 80 e0 ldi r24, 0x00 ; 0 + 1fdf6: e8 df rcall .-48 ; 0x1fdc8 + __asm__ __volatile__ ( + 1fdf8: ee 27 eor r30, r30 + 1fdfa: ff 27 eor r31, r31 + 1fdfc: 09 94 ijmp