diff --git a/optiboot/bootloaders/optiboot/Makefile b/optiboot/bootloaders/optiboot/Makefile index 13600c1..b9f3ed5 100644 --- a/optiboot/bootloaders/optiboot/Makefile +++ b/optiboot/bootloaders/optiboot/Makefile @@ -19,13 +19,70 @@ # program name should not be changed... PROGRAM = optiboot +# The default behavior is to build using tools that are in the users +# current path variables, but we can also build using an installed +# Arduino user IDE setup, or the Arduino source tree. +# Uncomment this next lines to build within the arduino environment, +# using the arduino-included avrgcc toolset (mac and pc) +# ENV ?= arduino +# ENV ?= arduinodev +# OS ?= macosx +# OS ?= windows + + # enter the parameters for the avrdude isp tool ISPTOOL = stk500v2 ISPPORT = usb ISPSPEED = -b 115200 MCU_TARGET = atmega168 -LDSECTION = --section-start=.text=0x3e00 +LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe + +# Build environments +# Start of some ugly makefile-isms to allow optiboot to be built +# in several different environments. See the README.TXT file for +# details. + +# default +fixpath = $(1) + +ifeq ($(ENV), arduino) +# For Arduino, we assume that we're connected to the optiboot directory +# included with the arduino distribution, which means that the full set +# of avr-tools are "right up there" in standard places. +TOOLROOT = ../../../tools +GCCROOT = $(TOOLROOT)/avr/bin/ +AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf + +ifeq ($(OS), windows) +# On windows, SOME of the tool paths will need to have backslashes instead +# of forward slashes (because they use windows cmd.exe for execution instead +# of a unix/mingw shell?) We also have to ensure that a consistent shell +# is used even if a unix shell is installed (ie as part of WINAVR) +fixpath = $(subst /,\,$1) +SHELL = cmd.exe +endif + +else ifeq ($(ENV), arduinodev) +# Arduino IDE source code environment. Use the unpacked compilers created +# by the build (you'll need to do "ant build" first.) +ifeq ($(OS), macosx) +TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools +endif +ifeq ($(OS), windows) +TOOLROOT = ../../../../build/windows/work/hardware/tools +endif + +GCCROOT = $(TOOLROOT)/avr/bin/ +AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf + +else +GCCROOT = +AVRDUDE_CONF = +endif +# +# End of build environment code. + # the efuse should really be 0xf8; since, however, only the lower # three bits of that byte are used on the atmega168, avrdude gets @@ -33,14 +90,17 @@ LDSECTION = --section-start=.text=0x3e00 # http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/ # # similarly, the lock bits should be 0xff instead of 0x3f (to -# unlock the bootloader section) and 0xcf instead of 0x0f (to +# unlock the bootloader section) and 0xcf instead of 0x2f (to # lock it), but since the high two bits of the lock byte are # unused, avrdude would get confused. -ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ --e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m -ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ --U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m +ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \ + -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ + -e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \ + -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m +ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \ + -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ + -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe" STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \ @@ -53,23 +113,25 @@ OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls DEFS = LIBS = -CC = avr-gcc +CC = $(GCCROOT)avr-gcc # Override is only needed by avr-lib build system. override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS) -override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles -Wl,--gc-sections +override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump +OBJCOPY = $(GCCROOT)avr-objcopy +OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump) + +SIZE = $(GCCROOT)avr-size # Test platforms # Virtual boot block test virboot328: TARGET = atmega328 virboot328: MCU_TARGET = atmega328p -virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT +virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT' virboot328: AVR_FREQ = 16000000L -virboot328: LDSECTION = --section-start=.text=0x7e00 +virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe virboot328: $(PROGRAM)_atmega328.hex virboot328: $(PROGRAM)_atmega328.lst @@ -84,6 +146,7 @@ pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' pro20: AVR_FREQ = 20000000L pro20: $(PROGRAM)_pro_20mhz.hex pro20: $(PROGRAM)_pro_20mhz.lst + pro20_isp: pro20 pro20_isp: TARGET = pro_20mhz # 2.7V brownout @@ -105,6 +168,7 @@ pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' pro16: AVR_FREQ = 16000000L pro16: $(PROGRAM)_pro_16MHz.hex pro16: $(PROGRAM)_pro_16MHz.lst + pro16_isp: pro16 pro16_isp: TARGET = pro_16MHz # 2.7V brownout @@ -115,13 +179,34 @@ pro16_isp: LFUSE = C6 pro16_isp: EFUSE = 04 pro16_isp: isp -# Diecimila and NG use identical bootloaders +# Diecimila, Duemilanove with m168, and NG use identical bootloaders +# Call it "atmega168" for generality and clarity, keep "diecimila" for +# backward compatibility of makefile +# +atmega168: TARGET = atmega168 +atmega168: MCU_TARGET = atmega168 +atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' +atmega168: AVR_FREQ = 16000000L +atmega168: $(PROGRAM)_atmega168.hex +atmega168: $(PROGRAM)_atmega168.lst + +atmega168_isp: atmega168 +atmega168_isp: TARGET = atmega168 +# 2.7V brownout +atmega168_isp: HFUSE = DD +# Low power xtal (16MHz) 16KCK/14CK+65ms +atmega168_isp: LFUSE = FF +# 512 byte boot +atmega168_isp: EFUSE = 04 +atmega168_isp: isp + diecimila: TARGET = diecimila diecimila: MCU_TARGET = atmega168 diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' diecimila: AVR_FREQ = 16000000L diecimila: $(PROGRAM)_diecimila.hex diecimila: $(PROGRAM)_diecimila.lst + diecimila_isp: diecimila diecimila_isp: TARGET = diecimila # 2.7V brownout @@ -136,13 +221,14 @@ atmega328: TARGET = atmega328 atmega328: MCU_TARGET = atmega328p atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega328: AVR_FREQ = 16000000L -atmega328: LDSECTION = --section-start=.text=0x7e00 +atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe atmega328: $(PROGRAM)_atmega328.hex atmega328: $(PROGRAM)_atmega328.lst + atmega328_isp: atmega328 atmega328_isp: TARGET = atmega328 atmega328_isp: MCU_TARGET = atmega328p -# 512 byte boot +# 512 byte boot, SPIEN atmega328_isp: HFUSE = DE # Low power xtal (16MHz) 16KCK/14CK+65ms atmega328_isp: LFUSE = FF @@ -151,13 +237,15 @@ atmega328_isp: EFUSE = 05 atmega328_isp: isp # Sanguino has a minimum boot size of 1024 bytes, so enable extra functions +# sanguino: TARGET = atmega644p sanguino: MCU_TARGET = atmega644p sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' sanguino: AVR_FREQ = 16000000L -sanguino: LDSECTION = --section-start=.text=0xfc00 +sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00 sanguino: $(PROGRAM)_atmega644p.hex sanguino: $(PROGRAM)_atmega644p.lst + sanguino_isp: sanguino sanguino_isp: TARGET = atmega644p sanguino_isp: MCU_TARGET = atmega644p @@ -170,13 +258,14 @@ sanguino_isp: EFUSE = 05 sanguino_isp: isp # Mega has a minimum boot size of 1024 bytes, so enable extra functions -mega: TARGET = atmega1280 +#mega: TARGET = atmega1280 mega: MCU_TARGET = atmega1280 mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' mega: AVR_FREQ = 16000000L -mega: LDSECTION = --section-start=.text=0x1fc00 +mega: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 mega: $(PROGRAM)_atmega1280.hex mega: $(PROGRAM)_atmega1280.lst + mega_isp: mega mega_isp: TARGET = atmega1280 mega_isp: MCU_TARGET = atmega1280 @@ -194,25 +283,29 @@ atmega8: TARGET = atmega8 atmega8: MCU_TARGET = atmega8 atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega8: AVR_FREQ = 16000000L -atmega8: LDSECTION = --section-start=.text=0x1e00 +atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe atmega8: $(PROGRAM)_atmega8.hex atmega8: $(PROGRAM)_atmega8.lst + atmega8_isp: atmega8 atmega8_isp: TARGET = atmega8 atmega8_isp: MCU_TARGET = atmega8 -# 2.7V brownout -atmega8_isp: HFUSE = DC -# Low power xtal (16MHz) 16KCK/14CK+65ms +# SPIEN, CKOPT, Bootsize=512B +atmega8_isp: HFUSE = CC +# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms atmega8_isp: LFUSE = BF atmega8_isp: isp # ATmega88 +# atmega88: TARGET = atmega88 atmega88: MCU_TARGET = atmega88 atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega88: AVR_FREQ = 16000000L +atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe atmega88: $(PROGRAM)_atmega88.hex atmega88: $(PROGRAM)_atmega88.lst + atmega88_isp: atmega88 atmega88_isp: TARGET = atmega88 atmega88_isp: MCU_TARGET = atmega88 @@ -224,6 +317,7 @@ atemga88_isp: LFUSE = FF atmega88_isp: EFUSE = 04 atmega88_isp: isp + # 8MHz clocked platforms # # These are capable of 115200 baud @@ -235,6 +329,7 @@ lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' lilypad: AVR_FREQ = 8000000L lilypad: $(PROGRAM)_lilypad.hex lilypad: $(PROGRAM)_lilypad.lst + lilypad_isp: lilypad lilypad_isp: TARGET = lilypad # 2.7V brownout @@ -242,7 +337,7 @@ lilypad_isp: HFUSE = DD # Internal 8MHz osc (8MHz) Slow rising power lilypad_isp: LFUSE = E2 # 512 byte boot -lilypad_isp: EFUSE = 02 +lilypad_isp: EFUSE = 04 lilypad_isp: isp lilypad_resonator: TARGET = lilypad_resonator @@ -251,6 +346,7 @@ lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' lilypad_resonator: AVR_FREQ = 8000000L lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst + lilypad_resonator_isp: lilypad_resonator lilypad_resonator_isp: TARGET = lilypad_resonator # 2.7V brownout @@ -258,7 +354,7 @@ lilypad_resonator_isp: HFUSE = DD # Full swing xtal (20MHz) 258CK/14CK+4.1ms lilypad_resonator_isp: LFUSE = C6 # 512 byte boot -lilypad_resonator_isp: EFUSE = 02 +lilypad_resonator_isp: EFUSE = 04 lilypad_resonator_isp: isp pro8: TARGET = pro_8MHz @@ -267,6 +363,7 @@ pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' pro8: AVR_FREQ = 8000000L pro8: $(PROGRAM)_pro_8MHz.hex pro8: $(PROGRAM)_pro_8MHz.lst + pro8_isp: pro8 pro8_isp: TARGET = pro_8MHz # 2.7V brownout @@ -274,20 +371,21 @@ pro8_isp: HFUSE = DD # Full swing xtal (20MHz) 258CK/14CK+4.1ms pro8_isp: LFUSE = C6 # 512 byte boot -pro8_isp: EFUSE = 02 +pro8_isp: EFUSE = 04 pro8_isp: isp atmega328_pro8: TARGET = atmega328_pro_8MHz atmega328_pro8: MCU_TARGET = atmega328p atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega328_pro8: AVR_FREQ = 8000000L -atmega328_pro8: LDSECTION = --section-start=.text=0x7e00 +atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst + atmega328_pro8_isp: atmega328_pro8 atmega328_pro8_isp: TARGET = atmega328_pro_8MHz atmega328_pro8_isp: MCU_TARGET = atmega328p -# 512 byte boot +# 512 byte boot, SPIEN atmega328_pro8_isp: HFUSE = DE # Low power xtal (16MHz) 16KCK/14CK+65ms atmega328_pro8_isp: LFUSE = FF @@ -305,9 +403,10 @@ luminet: MCU_TARGET = attiny84 luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600' luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION' luminet: AVR_FREQ = 1000000L -luminet: LDSECTION = --section-start=.text=0x1d00 +luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe luminet: $(PROGRAM)_luminet.hex luminet: $(PROGRAM)_luminet.lst + luminet_isp: luminet luminet_isp: TARGET = luminet luminet_isp: MCU_TARGET = attiny84 @@ -334,6 +433,7 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex %.elf: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + $(SIZE) $@ clean: rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex @@ -342,10 +442,10 @@ clean: $(OBJDUMP) -h -S $< > $@ %.hex: %.elf - $(OBJCOPY) -j .text -j .data -O ihex $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@ %.srec: %.elf - $(OBJCOPY) -j .text -j .data -O srec $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@ %.bin: %.elf - $(OBJCOPY) -j .text -j .data -O binary $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@ diff --git a/optiboot/bootloaders/optiboot/README.TXT b/optiboot/bootloaders/optiboot/README.TXT new file mode 100644 index 0000000..cd79cd9 --- /dev/null +++ b/optiboot/bootloaders/optiboot/README.TXT @@ -0,0 +1,81 @@ +This directory contains the Optiboot small bootloader for AVR +microcontrollers, somewhat modified specifically for the Arduino +environment. + +Optiboot is more fully described here: http://code.google.com/p/optiboot/ +and is the work of Peter Knight (aka Cathedrow), building on work of Jason P +Kyle, Spiff, and Ladyada. Arduino-specific modification are by Bill +Westfield (aka WestfW) + +Arduino-specific issues are tracked as part of the Arduino project +at http://code.google.com/p/arduino + + +------------------------------------------------------------ +Building optiboot for Arduino. + +Production builds of optiboot for Arduino are done on a Mac in "unix mode" +using CrossPack-AVR-20100115. CrossPack tracks WINAVR (for windows), which +is just a package of avr-gcc and related utilities, so similar builds should +work on Windows or Linux systems. + +One of the Arduino-specific changes is modifications to the makefile to +allow building optiboot using only the tools installed as part of the +Arduino environment, or the Arduino source development tree. All three +build procedures should yield identical binaries (.hex files) (although +this may change if compiler versions drift apart between CrossPack and +the Arduino IDE.) + + +Building Optiboot in the Arduino IDE Install. + +Work in the .../hardware/arduino/bootloaders/optiboot/ and use the +"omake " command, which just generates a command that uses +the arduino-included "make" utility with a command like: + make OS=windows ENV=arduino +or make OS=macosx ENV=arduino +On windows, this assumes you're using the windows command shell. If +you're using a cygwin or mingw shell, or have one of those in your +path, the build will probably break due to slash vs backslash issues. +On a Mac, if you have the developer tools installed, you can use the +Apple-supplied version of make. +The makefile uses relative paths ("../../../tools/" and such) to find +the programs it needs, so you need to work in the existing optiboot +directory (or something created at the same "level") for it to work. + + +Building Optiboot in the Arduino Source Development Install. + +In this case, there is no special shell script, and you're assumed to +have "make" installed somewhere in your path. +Build the Arduino source ("ant build") to unpack the tools into the +expected directory. +Work in Arduino/hardware/arduino/bootloaders/optiboot and use + make OS=windows ENV=arduinodev +or make OS=macosx ENV=arduinodev + + +Programming Chips Using the _isp Targets + +The CPU targets have corresponding ISP targets that will actuall +program the bootloader into a chip. "atmega328_isp" for the atmega328, +for example. These will set the fuses and lock bits as appropriate as +well as uploading the bootloader code. + +The makefiles default to using a USB programmer, but you can use +a serial programmer like ArduinoISP by changing the appropriate +variables when you invoke make: + + make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN \ + ISPSPEED=-b19200 atmega328_isp + +The "atmega8_isp" target does not currently work, because the mega8 +doesn't have the "extended" fuse that the generic ISP target wants to +pass on to avrdude. You'll need to run avrdude manually. + + +Standard Targets + +I've reduced the pre-built and source-version-controlled targets +(.hex and .lst files included in the git repository) to just the +three basic 16MHz targets: atmega8, atmega16, atmega328. diff --git a/optiboot/bootloaders/optiboot/makeall b/optiboot/bootloaders/optiboot/makeall index b0c3bef..f076bc7 100755 --- a/optiboot/bootloaders/optiboot/makeall +++ b/optiboot/bootloaders/optiboot/makeall @@ -1,14 +1,20 @@ #!/bin/bash make clean +# +# The "big three" standard bootloaders. +make atmega8 +make atmega168 +make atmega328 +# +# additional buildable platforms of +# somewhat questionable support level make lilypad make lilypad_resonator make pro8 make pro16 make pro20 -make diecimila -make atmega328 +make atmega328_pro8 make sanguino make mega -make atmega8 make atmega88 make luminet diff --git a/optiboot/bootloaders/optiboot/omake b/optiboot/bootloaders/optiboot/omake new file mode 100644 index 0000000..cc7c6bc --- /dev/null +++ b/optiboot/bootloaders/optiboot/omake @@ -0,0 +1,2 @@ +echo ../../../tools/avr/bin/make OS=macosx ENV=arduino $* +../../../tools/avr/bin/make OS=macosx ENV=arduino $* diff --git a/optiboot/bootloaders/optiboot/omake.bat b/optiboot/bootloaders/optiboot/omake.bat new file mode 100644 index 0000000..f6815da --- /dev/null +++ b/optiboot/bootloaders/optiboot/omake.bat @@ -0,0 +1 @@ +..\..\..\tools\avr\utils\bin\make OS=windows ENV=arduino %* diff --git a/optiboot/bootloaders/optiboot/optiboot.c b/optiboot/bootloaders/optiboot/optiboot.c index 6c08887..d499d85 100644 --- a/optiboot/bootloaders/optiboot/optiboot.c +++ b/optiboot/bootloaders/optiboot/optiboot.c @@ -3,6 +3,9 @@ /* */ /* http://optiboot.googlecode.com */ /* */ +/* Arduino-maintained version : See README.TXT */ +/* http://code.google.com/p/arduino/ */ +/* */ /* Heavily optimised bootloader that is faster and */ /* smaller than the Arduino standard bootloader */ /* */ @@ -111,7 +114,45 @@ /* 500,1000,2000,4000,8000 supported. */ /* */ /**********************************************************/ + +/**********************************************************/ +/* Version Numbers! */ +/* */ +/* Arduino Optiboot now includes this Version number in */ +/* the source and object code. */ +/* */ +/* Version 3 was released as zip from the optiboot */ +/* repository and was distributed with Arduino 0022. */ +/* Version 4 starts with the arduino repository commit */ +/* that brought the arduino repository up-to-date with */ +/* the optiboot source tree changes since v3. */ +/* */ +/**********************************************************/ +/**********************************************************/ +/* Edit History: */ +/* */ +/* 4.4 WestfW: add initialization of address to keep */ +/* the compiler happy. Change SC'ed targets. */ +/* Return the SW version via READ PARAM */ +/* 4.3 WestfW: catch framing errors in getch(), so that */ +/* AVRISP works without HW kludges. */ +/* http://code.google.com/p/arduino/issues/detail?id=368n*/ +/* 4.2 WestfW: reduce code size, fix timeouts, change */ +/* verifySpace to use WDT instead of appstart */ +/* 4.1 WestfW: put version number in binary. */ +/**********************************************************/ + +#define OPTIBOOT_MAJVER 4 +#define OPTIBOOT_MINVER 4 + +#define MAKESTR(a) #a +#define MAKEVER(a, b) MAKESTR(a*256+b) + +asm(" .section .version\n" + "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n" + " .section .text\n"); + #include #include #include @@ -120,6 +161,7 @@ // This saves cycles and program memory. #include "boot.h" + // We don't use as those routines have interrupt overhead we don't need. #include "pin_defs.h" @@ -164,8 +206,8 @@ #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE)) #define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE)) #ifndef __AVR_ATmega8__ -#define WATCHDOG_4S (_BV(WDE3) | _BV(WDE)) -#define WATCHDOG_8S (_BV(WDE3) | _BV(WDE0) | _BV(WDE)) +#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE)) +#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE)) #endif /* Function Prototypes */ @@ -210,8 +252,6 @@ void appStart() __attribute__ ((naked)); /* These definitions are NOT zero initialised, but that doesn't matter */ /* This allows us to drop the zero init code, saving us memory */ #define buff ((uint8_t*)(RAMSTART)) -#define address (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2)) -#define length (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+2)) #ifdef VIRTUAL_BOOT_PARTITION #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) @@ -219,6 +259,17 @@ void appStart() __attribute__ ((naked)); /* main program starts here */ int main(void) { + uint8_t ch; + + /* + * Making these local and in registers prevents the need for initializing + * them, and also saves space because code no longer stores to memory. + * (initializing address keeps the compiler happy, but isn't really + * necessary, and uses 4 bytes of flash.) + */ + register uint16_t address = 0; + register uint8_t length; + // After the zero init loop, this is the first code to run. // // This code makes the following assumptions: @@ -228,15 +279,11 @@ int main(void) { // // If not, uncomment the following instructions: // cli(); - + asm volatile ("clr __zero_reg__"); #ifdef __AVR_ATmega8__ SP=RAMEND; // This is done by hardware reset #endif - // asm volatile ("clr __zero_reg__"); - - uint8_t ch; - // Adaboot no-wait mod ch = MCUSR; MCUSR = 0; @@ -282,9 +329,22 @@ int main(void) { ch = getch(); if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - putch(0x03); + unsigned char which = getch(); + verifySpace(); + if (which == 0x82) { + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + putch(OPTIBOOT_MAJVER); + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + } } else if(ch == STK_SET_DEVICE) { // SET DEVICE is ignored @@ -318,11 +378,13 @@ int main(void) { uint8_t *bufPtr; uint16_t addrPtr; - getLen(); + getch(); /* getlen() */ + length = getch(); + getch(); // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); @@ -334,7 +396,7 @@ int main(void) { // Read command terminator, start reply verifySpace(); - + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); @@ -369,7 +431,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); boot_spm_busy_wait(); @@ -383,7 +445,10 @@ int main(void) { /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { // READ PAGE - we only read flash - getLen(); + getch(); /* getlen() */ + length = getch(); + getch(); + verifySpace(); #ifdef VIRTUAL_BOOT_PARTITION do { @@ -468,8 +533,6 @@ void putch(char ch) { uint8_t getch(void) { uint8_t ch; - watchdogReset(); - #ifdef LED_DATA_FLASH #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); @@ -487,7 +550,7 @@ uint8_t getch(void) { " rcall uartDelay\n" // Wait 1 bit period " clc\n" " sbic %[uartPin],%[uartBit]\n" - " sec\n" + " sec\n" " dec %[bitCnt]\n" " breq 3f\n" " ror %[ch]\n" @@ -503,7 +566,20 @@ uint8_t getch(void) { "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); + while(!(UCSR0A & _BV(RXC0))) + ; + if (!(UCSR0A & _BV(FE0))) { + /* + * A Framing Error indicates (probably) that something is talking + * to us at the wrong bit rate. Assume that this is because it + * expects to be talking to the application, and DON'T reset the + * watchdog. This should cause the bootloader to abort and run + * the application "soon", if it keeps happening. (Note that we + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; #endif @@ -543,7 +619,11 @@ void getNch(uint8_t count) { } void verifySpace() { - if (getch() != CRC_EOP) appStart(); + if (getch() != CRC_EOP) { + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); } @@ -563,12 +643,6 @@ void flash_led(uint8_t count) { } #endif -uint8_t getLen() { - getch(); - length = getch(); - return getch(); -} - // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega1280.hex b/optiboot/bootloaders/optiboot/optiboot_atmega1280.hex index 7ad0546..1a4ebee 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega1280.hex +++ b/optiboot/bootloaders/optiboot/optiboot_atmega1280.hex @@ -1,36 +1,36 @@ +:020000000404F6 :020000021000EC -:10FC000084B714BE81FFEDD085E08093810082E04F -:10FC10008093C00088E18093C10086E08093C20099 -:10FC200080E18093C4008EE0D6D0279A86E020E35E -:10FC30003CEF91E0309385002093840096BBB09B0D -:10FC4000FECF1F9AA8958150A9F7EE24E394A5E072 -:10FC5000DA2EF1E1FF2EB2D0813419F481E0CCD05C -:10FC60009BC0823411F484E103C0853419F485E02B -:10FC7000C3D099C08535A9F4A1D0082F10E09ED03B -:10FC800090E0982F8827802B912B292F221F222745 -:10FC9000221F2BBF880F991F9093010480930004AB -:10FCA00081C0863529F484E0A7D080E07FD07BC076 -:10FCB000843609F04EC08AD0E0910004F09101042E -:10FCC00080EEE030F80718F483E087BFE895C0E0E5 -:10FCD000D2E074D089938091020481508093020411 -:10FCE0008823B9F7E0910004F091010480EEE03040 -:10FCF000F80718F083E087BFE89578D007B600FCD6 -:10FD0000FDCF4091000450910104A0E0B2E02C919D -:10FD100030E011968C91119790E0982F8827822BD4 -:10FD2000932B1296FA010C01E7BEE89511244E5F61 -:10FD30005F4FF3E0A030BF0751F7E0910004F0916E -:10FD40000104D7BEE89507B600FCFDCFF7BEE895E5 -:10FD50002AC08437D1F43AD049D0E0910004F09120 -:10FD60000104E6918E2F22D080910004909101042D -:10FD700001969093010480930004809102048150C5 -:10FD800080930204882349F70EC0853739F42ED0BA -:10FD90008EE10CD087E90AD083E088CF813511F459 -:10FDA00088E019D023D080E101D055CF982F8091E1 -:10FDB000C00085FFFCCF9093C6000895A895809160 -:10FDC000C00087FFFCCF8091C6000895F7DFF6DF03 -:10FDD00080930204F3CFE0E6F0E098E19083808323 -:10FDE000089580E0F8DFEE27FF270994E7DF8032EF -:10FDF00009F0F7DF84E1DACF1F93182FDFDF11500E -:08FE0000E9F7F4DF1F910895FA +:10FC0000112484B714BE81FFF2D085E08093810077 +:10FC100082E08093C00088E18093C10086E08093F9 +:10FC2000C20080E18093C4008EE0CBD0279A86E0AA +:10FC300020E33CEF91E0309385002093840096BB55 +:10FC4000B09BFECF1F9AA8958150A9F7CC24DD2444 +:10FC500099249394A5E0BA2EF1E1AF2EA6D0813479 +:10FC600061F4A3D0082FB3D0023811F0013811F499 +:10FC700084E001C083E091D08DC0823411F484E12E +:10FC800003C0853419F485E0AAD084C08535A1F479 +:10FC90008CD0082F10E089D0E82EFF24FE2CEE2413 +:10FCA000E02AF12A8F2D881F8827881F8BBFEE0C32 +:10FCB000FF1C8DD067016EC0863521F484E08FD0A3 +:10FCC00080E0D9CF843609F042C06FD06ED0082FC3 +:10FCD0006CD080E0C81680EED80620F483E0F601F0 +:10FCE00087BFE895C0E0D2E060D089930C17E1F7B8 +:10FCF000F0E0CF16F0EEDF0620F083E0F60187BFDC +:10FD0000E89565D007B600FCFDCFA601A0E0B2E003 +:10FD10002C9130E011968C91119790E0982F8827C4 +:10FD2000822B932B1296FA010C0197BEE8951124B1 +:10FD30004E5F5F4FF3E0A030BF0751F7F601B7BE4B +:10FD4000E89507B600FCFDCFA7BEE89523C0843731 +:10FD5000A1F42BD02AD0E82E28D039D0E6010E2DE0 +:10FD6000FE0186911AD021960150D1F70894C11C4A +:10FD7000D11CEA94CE0CD11C0DC0853731F427D0AC +:10FD80008EE10BD087E909D075CF813511F488E079 +:10FD900018D01DD080E101D061CF982F8091C00094 +:10FDA00085FFFCCF9093C60008958091C00087FF27 +:10FDB000FCCF8091C00084FD01C0A8958091C60051 +:10FDC0000895E0E6F0E098E1908380830895EDDF08 +:10FDD000803219F088E0F5DFFFCF84E1DECF1F939A +:10FDE000182FE3DF1150E9F7F2DF1F91089580E04B +:08FDF000E8DFEE27FF2709946C :040000031000FC00ED :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega1280.lst b/optiboot/bootloaders/optiboot/optiboot_atmega1280.lst index f7cbd45..a32e38f 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega1280.lst +++ b/optiboot/bootloaders/optiboot/optiboot_atmega1280.lst @@ -3,25 +3,27 @@ optiboot_atmega1280.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 00000208 0001fc00 0001fc00 00000054 2**1 + 0 .text 000001f8 0001fc00 0001fc00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000025c 2**0 + 1 .debug_aranges 00000028 00000000 00000000 0000024c 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000284 2**0 + 2 .debug_pubnames 0000005f 00000000 00000000 00000274 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000278 00000000 00000000 000002ee 2**0 + 3 .debug_info 0000029c 00000000 00000000 000002d3 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001a1 00000000 00000000 00000566 2**0 + 4 .debug_abbrev 0000016b 00000000 00000000 0000056f 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003f4 00000000 00000000 00000707 2**0 + 5 .debug_line 00000471 00000000 00000000 000006da 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000afc 2**2 + 6 .debug_frame 00000080 00000000 00000000 00000b4c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000136 00000000 00000000 00000b8c 2**0 + 7 .debug_str 00000138 00000000 00000000 00000bcc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001b1 00000000 00000000 00000cc2 2**0 + 8 .debug_loc 000002b3 00000000 00000000 00000d04 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e73 2**0 + 9 .version 00000002 00000000 00000000 00000fb7 2**0 + CONTENTS, READONLY + 10 .debug_ranges 00000078 00000000 00000000 00000fb9 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,528 +35,563 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 1fc00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 1fc00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif // Adaboot no-wait mod ch = MCUSR; + 1fc02: 84 b7 in r24, 0x34 ; 52 MCUSR = 0; - 1fc02: 14 be out 0x34, r1 ; 52 + 1fc04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 1fc04: 81 ff sbrs r24, 1 - 1fc06: ed d0 rcall .+474 ; 0x1fde2 + 1fc06: 81 ff sbrs r24, 1 + 1fc08: f2 d0 rcall .+484 ; 0x1fdee #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 1fc08: 85 e0 ldi r24, 0x05 ; 5 - 1fc0a: 80 93 81 00 sts 0x0081, r24 + 1fc0a: 85 e0 ldi r24, 0x05 ; 5 + 1fc0c: 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 - 1fc0e: 82 e0 ldi r24, 0x02 ; 2 - 1fc10: 80 93 c0 00 sts 0x00C0, r24 + 1fc10: 82 e0 ldi r24, 0x02 ; 2 + 1fc12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 1fc14: 88 e1 ldi r24, 0x18 ; 24 - 1fc16: 80 93 c1 00 sts 0x00C1, r24 + 1fc16: 88 e1 ldi r24, 0x18 ; 24 + 1fc18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 1fc1a: 86 e0 ldi r24, 0x06 ; 6 - 1fc1c: 80 93 c2 00 sts 0x00C2, r24 + 1fc1c: 86 e0 ldi r24, 0x06 ; 6 + 1fc1e: 80 93 c2 00 sts 0x00C2, r24 UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 1fc20: 80 e1 ldi r24, 0x10 ; 16 - 1fc22: 80 93 c4 00 sts 0x00C4, r24 + 1fc22: 80 e1 ldi r24, 0x10 ; 16 + 1fc24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 1fc26: 8e e0 ldi r24, 0x0E ; 14 - 1fc28: d6 d0 rcall .+428 ; 0x1fdd6 + 1fc28: 8e e0 ldi r24, 0x0E ; 14 + 1fc2a: cb d0 rcall .+406 ; 0x1fdc2 /* Set LED pin as output */ LED_DDR |= _BV(LED); - 1fc2a: 27 9a sbi 0x04, 7 ; 4 - 1fc2c: 86 e0 ldi r24, 0x06 ; 6 + 1fc2c: 27 9a sbi 0x04, 7 ; 4 + 1fc2e: 86 e0 ldi r24, 0x06 ; 6 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 1fc2e: 20 e3 ldi r18, 0x30 ; 48 - 1fc30: 3c ef ldi r19, 0xFC ; 252 + 1fc30: 20 e3 ldi r18, 0x30 ; 48 + 1fc32: 3c ef ldi r19, 0xFC ; 252 TIFR1 = _BV(TOV1); - 1fc32: 91 e0 ldi r25, 0x01 ; 1 + 1fc34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 1fc34: 30 93 85 00 sts 0x0085, r19 - 1fc38: 20 93 84 00 sts 0x0084, r18 + 1fc36: 30 93 85 00 sts 0x0085, r19 + 1fc3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 1fc3c: 96 bb out 0x16, r25 ; 22 + 1fc3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 1fc3e: b0 9b sbis 0x16, 0 ; 22 - 1fc40: fe cf rjmp .-4 ; 0x1fc3e + 1fc40: b0 9b sbis 0x16, 0 ; 22 + 1fc42: fe cf rjmp .-4 ; 0x1fc40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 1fc42: 1f 9a sbi 0x03, 7 ; 3 - return getch(); + 1fc44: 1f 9a sbi 0x03, 7 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 1fc44: a8 95 wdr + 1fc46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 1fc46: 81 50 subi r24, 0x01 ; 1 - 1fc48: a9 f7 brne .-22 ; 0x1fc34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1fc4a: ee 24 eor r14, r14 - 1fc4c: e3 94 inc r14 + 1fc48: 81 50 subi r24, 0x01 ; 1 + 1fc4a: a9 f7 brne .-22 ; 0x1fc36 + 1fc4c: cc 24 eor r12, r12 + 1fc4e: 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); + 1fc50: 99 24 eor r9, r9 + 1fc52: 93 94 inc r9 addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 1fc4e: a5 e0 ldi r26, 0x05 ; 5 - 1fc50: da 2e mov r13, r26 + 1fc54: a5 e0 ldi r26, 0x05 ; 5 + 1fc56: ba 2e mov r11, r26 boot_spm_busy_wait(); #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 1fc52: f1 e1 ldi r31, 0x11 ; 17 - 1fc54: ff 2e mov r15, r31 + 1fc58: f1 e1 ldi r31, 0x11 ; 17 + 1fc5a: af 2e mov r10, r31 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - 1fc56: b2 d0 rcall .+356 ; 0x1fdbc + 1fc5c: a6 d0 rcall .+332 ; 0x1fdaa if(ch == STK_GET_PARAMETER) { - 1fc58: 81 34 cpi r24, 0x41 ; 65 - 1fc5a: 19 f4 brne .+6 ; 0x1fc62 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1fc5c: 81 e0 ldi r24, 0x01 ; 1 - 1fc5e: cc d0 rcall .+408 ; 0x1fdf8 - 1fc60: 9b c0 rjmp .+310 ; 0x1fd98 - putch(0x03); + 1fc5e: 81 34 cpi r24, 0x41 ; 65 + 1fc60: 61 f4 brne .+24 ; 0x1fc7a + unsigned char which = getch(); + 1fc62: a3 d0 rcall .+326 ; 0x1fdaa + 1fc64: 08 2f mov r16, r24 + verifySpace(); + 1fc66: b3 d0 rcall .+358 ; 0x1fdce + if (which == 0x82) { + 1fc68: 02 38 cpi r16, 0x82 ; 130 + 1fc6a: 11 f0 breq .+4 ; 0x1fc70 + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 1fc6c: 01 38 cpi r16, 0x81 ; 129 + 1fc6e: 11 f4 brne .+4 ; 0x1fc74 + putch(OPTIBOOT_MAJVER); + 1fc70: 84 e0 ldi r24, 0x04 ; 4 + 1fc72: 01 c0 rjmp .+2 ; 0x1fc76 + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 1fc74: 83 e0 ldi r24, 0x03 ; 3 + 1fc76: 91 d0 rcall .+290 ; 0x1fd9a + 1fc78: 8d c0 rjmp .+282 ; 0x1fd94 + } } else if(ch == STK_SET_DEVICE) { - 1fc62: 82 34 cpi r24, 0x42 ; 66 - 1fc64: 11 f4 brne .+4 ; 0x1fc6a + 1fc7a: 82 34 cpi r24, 0x42 ; 66 + 1fc7c: 11 f4 brne .+4 ; 0x1fc82 // SET DEVICE is ignored getNch(20); - 1fc66: 84 e1 ldi r24, 0x14 ; 20 - 1fc68: 03 c0 rjmp .+6 ; 0x1fc70 + 1fc7e: 84 e1 ldi r24, 0x14 ; 20 + 1fc80: 03 c0 rjmp .+6 ; 0x1fc88 } else if(ch == STK_SET_DEVICE_EXT) { - 1fc6a: 85 34 cpi r24, 0x45 ; 69 - 1fc6c: 19 f4 brne .+6 ; 0x1fc74 + 1fc82: 85 34 cpi r24, 0x45 ; 69 + 1fc84: 19 f4 brne .+6 ; 0x1fc8c // SET DEVICE EXT is ignored getNch(5); - 1fc6e: 85 e0 ldi r24, 0x05 ; 5 - 1fc70: c3 d0 rcall .+390 ; 0x1fdf8 - 1fc72: 99 c0 rjmp .+306 ; 0x1fda6 + 1fc86: 85 e0 ldi r24, 0x05 ; 5 + 1fc88: aa d0 rcall .+340 ; 0x1fdde + 1fc8a: 84 c0 rjmp .+264 ; 0x1fd94 } else if(ch == STK_LOAD_ADDRESS) { - 1fc74: 85 35 cpi r24, 0x55 ; 85 - 1fc76: a9 f4 brne .+42 ; 0x1fca2 + 1fc8c: 85 35 cpi r24, 0x55 ; 85 + 1fc8e: a1 f4 brne .+40 ; 0x1fcb8 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 1fc78: a1 d0 rcall .+322 ; 0x1fdbc + 1fc90: 8c d0 rcall .+280 ; 0x1fdaa newAddress = (newAddress & 0xff) | (getch() << 8); - 1fc7a: 08 2f mov r16, r24 - 1fc7c: 10 e0 ldi r17, 0x00 ; 0 - 1fc7e: 9e d0 rcall .+316 ; 0x1fdbc - 1fc80: 90 e0 ldi r25, 0x00 ; 0 - 1fc82: 98 2f mov r25, r24 - 1fc84: 88 27 eor r24, r24 - 1fc86: 80 2b or r24, r16 - 1fc88: 91 2b or r25, r17 + 1fc92: 08 2f mov r16, r24 + 1fc94: 10 e0 ldi r17, 0x00 ; 0 + 1fc96: 89 d0 rcall .+274 ; 0x1fdaa + 1fc98: e8 2e mov r14, r24 + 1fc9a: ff 24 eor r15, r15 + 1fc9c: fe 2c mov r15, r14 + 1fc9e: ee 24 eor r14, r14 + 1fca0: e0 2a or r14, r16 + 1fca2: f1 2a or r15, r17 #ifdef RAMPZ // Transfer top bit to RAMPZ RAMPZ = (newAddress & 0x8000) ? 1 : 0; - 1fc8a: 29 2f mov r18, r25 - 1fc8c: 22 1f adc r18, r18 - 1fc8e: 22 27 eor r18, r18 - 1fc90: 22 1f adc r18, r18 - 1fc92: 2b bf out 0x3b, r18 ; 59 + 1fca4: 8f 2d mov r24, r15 + 1fca6: 88 1f adc r24, r24 + 1fca8: 88 27 eor r24, r24 + 1fcaa: 88 1f adc r24, r24 + 1fcac: 8b bf out 0x3b, r24 ; 59 #endif newAddress += newAddress; // Convert from word address to byte address - 1fc94: 88 0f add r24, r24 - 1fc96: 99 1f adc r25, r25 + 1fcae: ee 0c add r14, r14 + 1fcb0: ff 1c adc r15, r15 address = newAddress; - 1fc98: 90 93 01 04 sts 0x0401, r25 - 1fc9c: 80 93 00 04 sts 0x0400, r24 - 1fca0: 81 c0 rjmp .+258 ; 0x1fda4 verifySpace(); + 1fcb2: 8d d0 rcall .+282 ; 0x1fdce + 1fcb4: 67 01 movw r12, r14 + 1fcb6: 6e c0 rjmp .+220 ; 0x1fd94 } else if(ch == STK_UNIVERSAL) { - 1fca2: 86 35 cpi r24, 0x56 ; 86 - 1fca4: 29 f4 brne .+10 ; 0x1fcb0 + 1fcb8: 86 35 cpi r24, 0x56 ; 86 + 1fcba: 21 f4 brne .+8 ; 0x1fcc4 // UNIVERSAL command is ignored getNch(4); - 1fca6: 84 e0 ldi r24, 0x04 ; 4 - 1fca8: a7 d0 rcall .+334 ; 0x1fdf8 + 1fcbc: 84 e0 ldi r24, 0x04 ; 4 + 1fcbe: 8f d0 rcall .+286 ; 0x1fdde putch(0x00); - 1fcaa: 80 e0 ldi r24, 0x00 ; 0 - 1fcac: 7f d0 rcall .+254 ; 0x1fdac - 1fcae: 7b c0 rjmp .+246 ; 0x1fda6 + 1fcc0: 80 e0 ldi r24, 0x00 ; 0 + 1fcc2: d9 cf rjmp .-78 ; 0x1fc76 } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 1fcb0: 84 36 cpi r24, 0x64 ; 100 - 1fcb2: 09 f0 breq .+2 ; 0x1fcb6 - 1fcb4: 4e c0 rjmp .+156 ; 0x1fd52 + 1fcc4: 84 36 cpi r24, 0x64 ; 100 + 1fcc6: 09 f0 breq .+2 ; 0x1fcca + 1fcc8: 42 c0 rjmp .+132 ; 0x1fd4e // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 1fcb6: 8a d0 rcall .+276 ; 0x1fdcc + getch(); /* getlen() */ + 1fcca: 6f d0 rcall .+222 ; 0x1fdaa + length = getch(); + 1fccc: 6e d0 rcall .+220 ; 0x1fdaa + 1fcce: 08 2f mov r16, r24 + getch(); + 1fcd0: 6c d0 rcall .+216 ; 0x1fdaa // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 1fcb8: e0 91 00 04 lds r30, 0x0400 - 1fcbc: f0 91 01 04 lds r31, 0x0401 - 1fcc0: 80 ee ldi r24, 0xE0 ; 224 - 1fcc2: e0 30 cpi r30, 0x00 ; 0 - 1fcc4: f8 07 cpc r31, r24 - 1fcc6: 18 f4 brcc .+6 ; 0x1fcce - 1fcc8: 83 e0 ldi r24, 0x03 ; 3 - 1fcca: 87 bf out 0x37, r24 ; 55 - 1fccc: e8 95 spm - 1fcce: c0 e0 ldi r28, 0x00 ; 0 - 1fcd0: d2 e0 ldi r29, 0x02 ; 2 - + 1fcd2: 80 e0 ldi r24, 0x00 ; 0 + 1fcd4: c8 16 cp r12, r24 + 1fcd6: 80 ee ldi r24, 0xE0 ; 224 + 1fcd8: d8 06 cpc r13, r24 + 1fcda: 20 f4 brcc .+8 ; 0x1fce4 + 1fcdc: 83 e0 ldi r24, 0x03 ; 3 + 1fcde: f6 01 movw r30, r12 + 1fce0: 87 bf out 0x37, r24 ; 55 + 1fce2: e8 95 spm + 1fce4: c0 e0 ldi r28, 0x00 ; 0 + 1fce6: d2 e0 ldi r29, 0x02 ; 2 + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - 1fcd2: 74 d0 rcall .+232 ; 0x1fdbc - 1fcd4: 89 93 st Y+, r24 + 1fce8: 60 d0 rcall .+192 ; 0x1fdaa + 1fcea: 89 93 st Y+, r24 while (--length); - 1fcd6: 80 91 02 04 lds r24, 0x0402 - 1fcda: 81 50 subi r24, 0x01 ; 1 - 1fcdc: 80 93 02 04 sts 0x0402, r24 - 1fce0: 88 23 and r24, r24 - 1fce2: b9 f7 brne .-18 ; 0x1fcd2 + 1fcec: 0c 17 cp r16, r28 + 1fcee: e1 f7 brne .-8 ; 0x1fce8 // 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); - 1fce4: e0 91 00 04 lds r30, 0x0400 - 1fce8: f0 91 01 04 lds r31, 0x0401 - 1fcec: 80 ee ldi r24, 0xE0 ; 224 - 1fcee: e0 30 cpi r30, 0x00 ; 0 - 1fcf0: f8 07 cpc r31, r24 - 1fcf2: 18 f0 brcs .+6 ; 0x1fcfa - 1fcf4: 83 e0 ldi r24, 0x03 ; 3 - 1fcf6: 87 bf out 0x37, r24 ; 55 - 1fcf8: e8 95 spm + 1fcf0: f0 e0 ldi r31, 0x00 ; 0 + 1fcf2: cf 16 cp r12, r31 + 1fcf4: f0 ee ldi r31, 0xE0 ; 224 + 1fcf6: df 06 cpc r13, r31 + 1fcf8: 20 f0 brcs .+8 ; 0x1fd02 + 1fcfa: 83 e0 ldi r24, 0x03 ; 3 + 1fcfc: f6 01 movw r30, r12 + 1fcfe: 87 bf out 0x37, r24 ; 55 + 1fd00: e8 95 spm // Read command terminator, start reply verifySpace(); - 1fcfa: 78 d0 rcall .+240 ; 0x1fdec - + 1fd02: 65 d0 rcall .+202 ; 0x1fdce + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 1fcfc: 07 b6 in r0, 0x37 ; 55 - 1fcfe: 00 fc sbrc r0, 0 - 1fd00: fd cf rjmp .-6 ; 0x1fcfc - } -#endif - - // Copy buffer into programming buffer + 1fd04: 07 b6 in r0, 0x37 ; 55 + 1fd06: 00 fc sbrc r0, 0 + 1fd08: fd cf rjmp .-6 ; 0x1fd04 + 1fd0a: a6 01 movw r20, r12 + 1fd0c: a0 e0 ldi r26, 0x00 ; 0 + 1fd0e: b2 e0 ldi r27, 0x02 ; 2 bufPtr = buff; addrPtr = (uint16_t)(void*)address; - 1fd02: 40 91 00 04 lds r20, 0x0400 - 1fd06: 50 91 01 04 lds r21, 0x0401 - 1fd0a: a0 e0 ldi r26, 0x00 ; 0 - 1fd0c: b2 e0 ldi r27, 0x02 ; 2 ch = SPM_PAGESIZE / 2; do { uint16_t a; a = *bufPtr++; - 1fd0e: 2c 91 ld r18, X - 1fd10: 30 e0 ldi r19, 0x00 ; 0 + 1fd10: 2c 91 ld r18, X + 1fd12: 30 e0 ldi r19, 0x00 ; 0 a |= (*bufPtr++) << 8; - 1fd12: 11 96 adiw r26, 0x01 ; 1 - 1fd14: 8c 91 ld r24, X - 1fd16: 11 97 sbiw r26, 0x01 ; 1 - 1fd18: 90 e0 ldi r25, 0x00 ; 0 - 1fd1a: 98 2f mov r25, r24 - 1fd1c: 88 27 eor r24, r24 - 1fd1e: 82 2b or r24, r18 - 1fd20: 93 2b or r25, r19 + 1fd14: 11 96 adiw r26, 0x01 ; 1 + 1fd16: 8c 91 ld r24, X + 1fd18: 11 97 sbiw r26, 0x01 ; 1 + 1fd1a: 90 e0 ldi r25, 0x00 ; 0 + 1fd1c: 98 2f mov r25, r24 + 1fd1e: 88 27 eor r24, r24 + 1fd20: 82 2b or r24, r18 + 1fd22: 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) { - 1fd22: 12 96 adiw r26, 0x02 ; 2 + 1fd24: 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); - 1fd24: fa 01 movw r30, r20 - 1fd26: 0c 01 movw r0, r24 - 1fd28: e7 be out 0x37, r14 ; 55 - 1fd2a: e8 95 spm - 1fd2c: 11 24 eor r1, r1 + 1fd26: fa 01 movw r30, r20 + 1fd28: 0c 01 movw r0, r24 + 1fd2a: 97 be out 0x37, r9 ; 55 + 1fd2c: e8 95 spm + 1fd2e: 11 24 eor r1, r1 addrPtr += 2; - 1fd2e: 4e 5f subi r20, 0xFE ; 254 - 1fd30: 5f 4f sbci r21, 0xFF ; 255 + 1fd30: 4e 5f subi r20, 0xFE ; 254 + 1fd32: 5f 4f sbci r21, 0xFF ; 255 } while (--ch); - 1fd32: f3 e0 ldi r31, 0x03 ; 3 - 1fd34: a0 30 cpi r26, 0x00 ; 0 - 1fd36: bf 07 cpc r27, r31 - 1fd38: 51 f7 brne .-44 ; 0x1fd0e - + 1fd34: f3 e0 ldi r31, 0x03 ; 3 + 1fd36: a0 30 cpi r26, 0x00 ; 0 + 1fd38: bf 07 cpc r27, r31 + 1fd3a: 51 f7 brne .-44 ; 0x1fd10 + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 1fd3a: e0 91 00 04 lds r30, 0x0400 - 1fd3e: f0 91 01 04 lds r31, 0x0401 - 1fd42: d7 be out 0x37, r13 ; 55 - 1fd44: e8 95 spm + 1fd3c: f6 01 movw r30, r12 + 1fd3e: b7 be out 0x37, r11 ; 55 + 1fd40: 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 + 1fd42: 07 b6 in r0, 0x37 ; 55 + 1fd44: 00 fc sbrc r0, 0 + 1fd46: fd cf rjmp .-6 ; 0x1fd42 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 1fd4c: f7 be out 0x37, r15 ; 55 - 1fd4e: e8 95 spm - 1fd50: 2a c0 rjmp .+84 ; 0x1fda6 + 1fd48: a7 be out 0x37, r10 ; 55 + 1fd4a: e8 95 spm + 1fd4c: 23 c0 rjmp .+70 ; 0x1fd94 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 1fd52: 84 37 cpi r24, 0x74 ; 116 - 1fd54: d1 f4 brne .+52 ; 0x1fd8a + 1fd4e: 84 37 cpi r24, 0x74 ; 116 + 1fd50: a1 f4 brne .+40 ; 0x1fd7a // READ PAGE - we only read flash - getLen(); - 1fd56: 3a d0 rcall .+116 ; 0x1fdcc + getch(); /* getlen() */ + 1fd52: 2b d0 rcall .+86 ; 0x1fdaa + length = getch(); + 1fd54: 2a d0 rcall .+84 ; 0x1fdaa + 1fd56: e8 2e mov r14, r24 + getch(); + 1fd58: 28 d0 rcall .+80 ; 0x1fdaa + verifySpace(); - 1fd58: 49 d0 rcall .+146 ; 0x1fdec + 1fd5a: 39 d0 rcall .+114 ; 0x1fdce + 1fd5c: e6 01 movw r28, r12 + 1fd5e: 0e 2d mov r16, r14 #ifdef __AVR_ATmega1280__ // do putch(pgm_read_byte_near(address++)); // while (--length); do { uint8_t result; __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address)); - 1fd5a: e0 91 00 04 lds r30, 0x0400 - 1fd5e: f0 91 01 04 lds r31, 0x0401 - 1fd62: e6 91 elpm r30, Z+ + 1fd60: fe 01 movw r30, r28 + 1fd62: 86 91 elpm r24, Z+ putch(result); - 1fd64: 8e 2f mov r24, r30 - 1fd66: 22 d0 rcall .+68 ; 0x1fdac + 1fd64: 1a d0 rcall .+52 ; 0x1fd9a address++; - 1fd68: 80 91 00 04 lds r24, 0x0400 - 1fd6c: 90 91 01 04 lds r25, 0x0401 - 1fd70: 01 96 adiw r24, 0x01 ; 1 - 1fd72: 90 93 01 04 sts 0x0401, r25 - 1fd76: 80 93 00 04 sts 0x0400, r24 + 1fd66: 21 96 adiw r28, 0x01 ; 1 } while (--length); - 1fd7a: 80 91 02 04 lds r24, 0x0402 - 1fd7e: 81 50 subi r24, 0x01 ; 1 - 1fd80: 80 93 02 04 sts 0x0402, r24 - 1fd84: 88 23 and r24, r24 - 1fd86: 49 f7 brne .-46 ; 0x1fd5a - 1fd88: 0e c0 rjmp .+28 ; 0x1fda6 + 1fd68: 01 50 subi r16, 0x01 ; 1 + 1fd6a: d1 f7 brne .-12 ; 0x1fd60 +#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) { + 1fd6c: 08 94 sec + 1fd6e: c1 1c adc r12, r1 + 1fd70: d1 1c adc r13, r1 + 1fd72: ea 94 dec r14 + 1fd74: ce 0c add r12, r14 + 1fd76: d1 1c adc r13, r1 + 1fd78: 0d c0 rjmp .+26 ; 0x1fd94 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 1fd8a: 85 37 cpi r24, 0x75 ; 117 - 1fd8c: 39 f4 brne .+14 ; 0x1fd9c + 1fd7a: 85 37 cpi r24, 0x75 ; 117 + 1fd7c: 31 f4 brne .+12 ; 0x1fd8a // READ SIGN - return what Avrdude wants to hear verifySpace(); - 1fd8e: 2e d0 rcall .+92 ; 0x1fdec + 1fd7e: 27 d0 rcall .+78 ; 0x1fdce putch(SIGNATURE_0); - 1fd90: 8e e1 ldi r24, 0x1E ; 30 - 1fd92: 0c d0 rcall .+24 ; 0x1fdac + 1fd80: 8e e1 ldi r24, 0x1E ; 30 + 1fd82: 0b d0 rcall .+22 ; 0x1fd9a putch(SIGNATURE_1); - 1fd94: 87 e9 ldi r24, 0x97 ; 151 - 1fd96: 0a d0 rcall .+20 ; 0x1fdac + 1fd84: 87 e9 ldi r24, 0x97 ; 151 + 1fd86: 09 d0 rcall .+18 ; 0x1fd9a + 1fd88: 75 cf rjmp .-278 ; 0x1fc74 putch(SIGNATURE_2); - 1fd98: 83 e0 ldi r24, 0x03 ; 3 - 1fd9a: 88 cf rjmp .-240 ; 0x1fcac } else if (ch == 'Q') { - 1fd9c: 81 35 cpi r24, 0x51 ; 81 - 1fd9e: 11 f4 brne .+4 ; 0x1fda4 + 1fd8a: 81 35 cpi r24, 0x51 ; 81 + 1fd8c: 11 f4 brne .+4 ; 0x1fd92 // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 1fda0: 88 e0 ldi r24, 0x08 ; 8 - 1fda2: 19 d0 rcall .+50 ; 0x1fdd6 + 1fd8e: 88 e0 ldi r24, 0x08 ; 8 + 1fd90: 18 d0 rcall .+48 ; 0x1fdc2 verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 1fda4: 23 d0 rcall .+70 ; 0x1fdec + 1fd92: 1d d0 rcall .+58 ; 0x1fdce } putch(STK_OK); - 1fda6: 80 e1 ldi r24, 0x10 ; 16 - 1fda8: 01 d0 rcall .+2 ; 0x1fdac - 1fdaa: 55 cf rjmp .-342 ; 0x1fc56 + 1fd94: 80 e1 ldi r24, 0x10 ; 16 + 1fd96: 01 d0 rcall .+2 ; 0x1fd9a + 1fd98: 61 cf rjmp .-318 ; 0x1fc5c -0001fdac : +0001fd9a : } } void putch(char ch) { - 1fdac: 98 2f mov r25, r24 + 1fd9a: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 1fdae: 80 91 c0 00 lds r24, 0x00C0 - 1fdb2: 85 ff sbrs r24, 5 - 1fdb4: fc cf rjmp .-8 ; 0x1fdae + 1fd9c: 80 91 c0 00 lds r24, 0x00C0 + 1fda0: 85 ff sbrs r24, 5 + 1fda2: fc cf rjmp .-8 ; 0x1fd9c UDR0 = ch; - 1fdb6: 90 93 c6 00 sts 0x00C6, r25 + 1fda4: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 1fdba: 08 95 ret + 1fda8: 08 95 ret -0001fdbc : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 1fdbc: a8 95 wdr +0001fdaa : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 1fdbe: 80 91 c0 00 lds r24, 0x00C0 - 1fdc2: 87 ff sbrs r24, 7 - 1fdc4: fc cf rjmp .-8 ; 0x1fdbe + while(!(UCSR0A & _BV(RXC0))) + 1fdaa: 80 91 c0 00 lds r24, 0x00C0 + 1fdae: 87 ff sbrs r24, 7 + 1fdb0: fc cf rjmp .-8 ; 0x1fdaa + ; + if (!(UCSR0A & _BV(FE0))) { + 1fdb2: 80 91 c0 00 lds r24, 0x00C0 + 1fdb6: 84 fd sbrc r24, 4 + 1fdb8: 01 c0 rjmp .+2 ; 0x1fdbc +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 1fdba: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; - 1fdc6: 80 91 c6 00 lds r24, 0x00C6 + 1fdbc: 80 91 c6 00 lds r24, 0x00C6 LED_PIN |= _BV(LED); #endif #endif return ch; } - 1fdca: 08 95 ret + 1fdc0: 08 95 ret -0001fdcc : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 1fdcc: f7 df rcall .-18 ; 0x1fdbc - length = getch(); - 1fdce: f6 df rcall .-20 ; 0x1fdbc - 1fdd0: 80 93 02 04 sts 0x0402, r24 - return getch(); -} - 1fdd4: f3 cf rjmp .-26 ; 0x1fdbc - -0001fdd6 : +0001fdc2 : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 1fdd6: e0 e6 ldi r30, 0x60 ; 96 - 1fdd8: f0 e0 ldi r31, 0x00 ; 0 - 1fdda: 98 e1 ldi r25, 0x18 ; 24 - 1fddc: 90 83 st Z, r25 + 1fdc2: e0 e6 ldi r30, 0x60 ; 96 + 1fdc4: f0 e0 ldi r31, 0x00 ; 0 + 1fdc6: 98 e1 ldi r25, 0x18 ; 24 + 1fdc8: 90 83 st Z, r25 WDTCSR = x; - 1fdde: 80 83 st Z, r24 + 1fdca: 80 83 st Z, r24 } - 1fde0: 08 95 ret + 1fdcc: 08 95 ret -0001fde2 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 1fde2: 80 e0 ldi r24, 0x00 ; 0 - 1fde4: f8 df rcall .-16 ; 0x1fdd6 - __asm__ __volatile__ ( - 1fde6: ee 27 eor r30, r30 - 1fde8: ff 27 eor r31, r31 - 1fdea: 09 94 ijmp - -0001fdec : +0001fdce : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 1fdec: e7 df rcall .-50 ; 0x1fdbc - 1fdee: 80 32 cpi r24, 0x20 ; 32 - 1fdf0: 09 f0 breq .+2 ; 0x1fdf4 - 1fdf2: f7 df rcall .-18 ; 0x1fde2 + if (getch() != CRC_EOP) { + 1fdce: ed df rcall .-38 ; 0x1fdaa + 1fdd0: 80 32 cpi r24, 0x20 ; 32 + 1fdd2: 19 f0 breq .+6 ; 0x1fdda + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 1fdd4: 88 e0 ldi r24, 0x08 ; 8 + 1fdd6: f5 df rcall .-22 ; 0x1fdc2 + 1fdd8: ff cf rjmp .-2 ; 0x1fdd8 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 1fdf4: 84 e1 ldi r24, 0x14 ; 20 + 1fdda: 84 e1 ldi r24, 0x14 ; 20 } - 1fdf6: da cf rjmp .-76 ; 0x1fdac + 1fddc: de cf rjmp .-68 ; 0x1fd9a -0001fdf8 : +0001fdde : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 1fdf8: 1f 93 push r17 - 1fdfa: 18 2f mov r17, r24 + 1fdde: 1f 93 push r17 + 1fde0: 18 2f mov r17, r24 do getch(); while (--count); - 1fdfc: df df rcall .-66 ; 0x1fdbc - 1fdfe: 11 50 subi r17, 0x01 ; 1 - 1fe00: e9 f7 brne .-6 ; 0x1fdfc + 1fde2: e3 df rcall .-58 ; 0x1fdaa + 1fde4: 11 50 subi r17, 0x01 ; 1 + 1fde6: e9 f7 brne .-6 ; 0x1fde2 verifySpace(); - 1fe02: f4 df rcall .-24 ; 0x1fdec + 1fde8: f2 df rcall .-28 ; 0x1fdce } - 1fe04: 1f 91 pop r17 - 1fe06: 08 95 ret + 1fdea: 1f 91 pop r17 + 1fdec: 08 95 ret + +0001fdee : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 1fdee: 80 e0 ldi r24, 0x00 ; 0 + 1fdf0: e8 df rcall .-48 ; 0x1fdc2 + __asm__ __volatile__ ( + 1fdf2: ee 27 eor r30, r30 + 1fdf4: ff 27 eor r31, r31 + 1fdf6: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega328.hex b/optiboot/bootloaders/optiboot/optiboot_atmega328.hex index b54f8ae..a219f08 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega328.hex +++ b/optiboot/bootloaders/optiboot/optiboot_atmega328.hex @@ -1,34 +1,35 @@ -:107E000084B714BE81FFE6D085E08093810082E0D4 -:107E10008093C00088E18093C10086E08093C20017 -:107E200080E18093C4008EE0CFD0259A86E020E3E5 -:107E30003CEF91E0309385002093840096BBB09B8B -:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 -:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0 -:107E600083E020C0823411F484E103C0853419F426 -:107E700085E0BBD091C0853581F499D0082F10E002 -:107E800096D090E0982F8827802B912B880F991FF0 -:107E900090930102809300027EC0863529F484E02D -:107EA000A4D080E07CD078C0843609F04EC087D062 -:107EB000E0910002F091010280E7E030F80718F449 -:107EC00083E087BFE895C0E0D1E071D089938091CD -:107ED00002028150809302028823B9F7E0910002E8 -:107EE000F091010280E7E030F80718F083E087BFE7 -:107EF000E89575D007B600FCFDCF40910002509187 -:107F00000102A0E0B1E02C9130E011968C91119724 +:107E0000112484B714BE81FFF0D085E080938100F7 +:107E100082E08093C00088E18093C10086E0809377 +:107E2000C20080E18093C4008EE0C9D0259A86E02C +:107E300020E33CEF91E0309385002093840096BBD3 +:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4 +:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7 +:107E6000A2D0813461F49FD0082FAFD0023811F036 +:107E7000013811F484E001C083E08DD089C08234E0 +:107E800011F484E103C0853419F485E0A6D080C0E4 +:107E9000853579F488D0E82EFF2485D0082F10E0AE +:107EA000102F00270E291F29000F111F8ED06801E7 +:107EB0006FC0863521F484E090D080E0DECF843638 +:107EC00009F040C070D06FD0082F6DD080E0C81688 +:107ED00080E7D80618F4F601B7BEE895C0E0D1E017 +:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8 +:107EF00018F0F601B7BEE89568D007B600FCFDCFD4 +:107F0000A601A0E0B1E02C9130E011968C91119780 :107F100090E0982F8827822B932B1296FA010C0160 -:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740 -:107F300051F7E0910002F0910102E7BEE89507B623 -:107F400000FCFDCFF7BEE89527C08437B9F437D0E1 -:107F500046D0E0910002F09101023196F0930102C7 -:107F6000E09300023197E4918E2F19D080910202A4 -:107F7000815080930202882361F70EC0853739F45F -:107F80002ED08EE10CD085E90AD08FE08BCF8135E1 -:107F900011F488E019D023D080E101D05CCF982F74 -:107FA0008091C00085FFFCCF9093C6000895A895EE -:107FB0008091C00087FFFCCF8091C6000895F7DF55 -:107FC000F6DF80930202F3CFE0E6F0E098E19083E1 -:107FD0008083089580E0F8DFEE27FF270994E7DF2C -:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B -:0A7FF0001150E9F7F4DF1F91089526 +:107F200087BEE89511244E5F5F4FF1E0A038BF0790 +:107F300051F7F601A7BEE89507B600FCFDCF97BE46 +:107F4000E89526C08437B1F42ED02DD0F82E2BD052 +:107F50003CD0F601EF2C8F010F5F1F4F84911BD097 +:107F6000EA94F801C1F70894C11CD11CFA94CF0C13 +:107F7000D11C0EC0853739F428D08EE10CD085E9AC +:107F80000AD08FE07ACF813511F488E018D01DD067 +:107F900080E101D065CF982F8091C00085FFFCCF94 +:107FA0009093C60008958091C00087FFFCCF809118 +:107FB000C00084FD01C0A8958091C6000895E0E648 +:107FC000F0E098E1908380830895EDDF803219F02E +:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA +:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6 +:047FF000FF270994CA +:027FFE00040479 :0400000300007E007B :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega328.lst b/optiboot/bootloaders/optiboot/optiboot_atmega328.lst index bed3984..20cf5a5 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega328.lst +++ b/optiboot/bootloaders/optiboot/optiboot_atmega328.lst @@ -3,25 +3,27 @@ optiboot_atmega328.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00007e00 00007e00 00000054 2**1 + 0 .text 000001f4 00007e00 00007e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00007ffe 00007ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 7e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 7e00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif // Adaboot no-wait mod ch = MCUSR; + 7e02: 84 b7 in r24, 0x34 ; 52 MCUSR = 0; - 7e02: 14 be out 0x34, r1 ; 52 + 7e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 7e04: 81 ff sbrs r24, 1 - 7e06: e6 d0 rcall .+460 ; 0x7fd4 + 7e06: 81 ff sbrs r24, 1 + 7e08: f0 d0 rcall .+480 ; 0x7fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 7e08: 85 e0 ldi r24, 0x05 ; 5 - 7e0a: 80 93 81 00 sts 0x0081, r24 + 7e0a: 85 e0 ldi r24, 0x05 ; 5 + 7e0c: 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 - 7e0e: 82 e0 ldi r24, 0x02 ; 2 - 7e10: 80 93 c0 00 sts 0x00C0, r24 + 7e10: 82 e0 ldi r24, 0x02 ; 2 + 7e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 7e14: 88 e1 ldi r24, 0x18 ; 24 - 7e16: 80 93 c1 00 sts 0x00C1, r24 + 7e16: 88 e1 ldi r24, 0x18 ; 24 + 7e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 7e1a: 86 e0 ldi r24, 0x06 ; 6 - 7e1c: 80 93 c2 00 sts 0x00C2, r24 + 7e1c: 86 e0 ldi r24, 0x06 ; 6 + 7e1e: 80 93 c2 00 sts 0x00C2, r24 UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 7e20: 80 e1 ldi r24, 0x10 ; 16 - 7e22: 80 93 c4 00 sts 0x00C4, r24 + 7e22: 80 e1 ldi r24, 0x10 ; 16 + 7e24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 7e26: 8e e0 ldi r24, 0x0E ; 14 - 7e28: cf d0 rcall .+414 ; 0x7fc8 + 7e28: 8e e0 ldi r24, 0x0E ; 14 + 7e2a: c9 d0 rcall .+402 ; 0x7fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 7e2a: 25 9a sbi 0x04, 5 ; 4 - 7e2c: 86 e0 ldi r24, 0x06 ; 6 + 7e2c: 25 9a sbi 0x04, 5 ; 4 + 7e2e: 86 e0 ldi r24, 0x06 ; 6 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 7e2e: 20 e3 ldi r18, 0x30 ; 48 - 7e30: 3c ef ldi r19, 0xFC ; 252 + 7e30: 20 e3 ldi r18, 0x30 ; 48 + 7e32: 3c ef ldi r19, 0xFC ; 252 TIFR1 = _BV(TOV1); - 7e32: 91 e0 ldi r25, 0x01 ; 1 + 7e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 7e34: 30 93 85 00 sts 0x0085, r19 - 7e38: 20 93 84 00 sts 0x0084, r18 + 7e36: 30 93 85 00 sts 0x0085, r19 + 7e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 7e3c: 96 bb out 0x16, r25 ; 22 + 7e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 7e3e: b0 9b sbis 0x16, 0 ; 22 - 7e40: fe cf rjmp .-4 ; 0x7e3e + 7e40: b0 9b sbis 0x16, 0 ; 22 + 7e42: fe cf rjmp .-4 ; 0x7e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 7e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 7e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 7e44: a8 95 wdr + 7e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 7e46: 81 50 subi r24, 0x01 ; 1 - 7e48: a9 f7 brne .-22 ; 0x7e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e4a: dd 24 eor r13, r13 - 7e4c: d3 94 inc r13 + 7e48: 81 50 subi r24, 0x01 ; 1 + 7e4a: a9 f7 brne .-22 ; 0x7e36 + 7e4c: cc 24 eor r12, r12 + 7e4e: 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); + 7e50: 88 24 eor r8, r8 + 7e52: 83 94 inc r8 addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 7e4e: a5 e0 ldi r26, 0x05 ; 5 - 7e50: ea 2e mov r14, r26 + 7e54: b5 e0 ldi r27, 0x05 ; 5 + 7e56: ab 2e mov r10, r27 boot_spm_busy_wait(); #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7e52: f1 e1 ldi r31, 0x11 ; 17 - 7e54: ff 2e mov r15, r31 + 7e58: a1 e1 ldi r26, 0x11 ; 17 + 7e5a: 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); + 7e5c: f3 e0 ldi r31, 0x03 ; 3 + 7e5e: bf 2e mov r11, r31 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - 7e56: ab d0 rcall .+342 ; 0x7fae + 7e60: a2 d0 rcall .+324 ; 0x7fa6 if(ch == STK_GET_PARAMETER) { - 7e58: 81 34 cpi r24, 0x41 ; 65 - 7e5a: 21 f4 brne .+8 ; 0x7e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e5c: 81 e0 ldi r24, 0x01 ; 1 - 7e5e: c5 d0 rcall .+394 ; 0x7fea - putch(0x03); - 7e60: 83 e0 ldi r24, 0x03 ; 3 - 7e62: 20 c0 rjmp .+64 ; 0x7ea4 + 7e62: 81 34 cpi r24, 0x41 ; 65 + 7e64: 61 f4 brne .+24 ; 0x7e7e + unsigned char which = getch(); + 7e66: 9f d0 rcall .+318 ; 0x7fa6 + 7e68: 08 2f mov r16, r24 + verifySpace(); + 7e6a: af d0 rcall .+350 ; 0x7fca + if (which == 0x82) { + 7e6c: 02 38 cpi r16, 0x82 ; 130 + 7e6e: 11 f0 breq .+4 ; 0x7e74 + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 7e70: 01 38 cpi r16, 0x81 ; 129 + 7e72: 11 f4 brne .+4 ; 0x7e78 + putch(OPTIBOOT_MAJVER); + 7e74: 84 e0 ldi r24, 0x04 ; 4 + 7e76: 01 c0 rjmp .+2 ; 0x7e7a + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 7e78: 83 e0 ldi r24, 0x03 ; 3 + 7e7a: 8d d0 rcall .+282 ; 0x7f96 + 7e7c: 89 c0 rjmp .+274 ; 0x7f90 + } } else if(ch == STK_SET_DEVICE) { - 7e64: 82 34 cpi r24, 0x42 ; 66 - 7e66: 11 f4 brne .+4 ; 0x7e6c + 7e7e: 82 34 cpi r24, 0x42 ; 66 + 7e80: 11 f4 brne .+4 ; 0x7e86 // SET DEVICE is ignored getNch(20); - 7e68: 84 e1 ldi r24, 0x14 ; 20 - 7e6a: 03 c0 rjmp .+6 ; 0x7e72 + 7e82: 84 e1 ldi r24, 0x14 ; 20 + 7e84: 03 c0 rjmp .+6 ; 0x7e8c } else if(ch == STK_SET_DEVICE_EXT) { - 7e6c: 85 34 cpi r24, 0x45 ; 69 - 7e6e: 19 f4 brne .+6 ; 0x7e76 + 7e86: 85 34 cpi r24, 0x45 ; 69 + 7e88: 19 f4 brne .+6 ; 0x7e90 // SET DEVICE EXT is ignored getNch(5); - 7e70: 85 e0 ldi r24, 0x05 ; 5 - 7e72: bb d0 rcall .+374 ; 0x7fea - 7e74: 91 c0 rjmp .+290 ; 0x7f98 + 7e8a: 85 e0 ldi r24, 0x05 ; 5 + 7e8c: a6 d0 rcall .+332 ; 0x7fda + 7e8e: 80 c0 rjmp .+256 ; 0x7f90 } else if(ch == STK_LOAD_ADDRESS) { - 7e76: 85 35 cpi r24, 0x55 ; 85 - 7e78: 81 f4 brne .+32 ; 0x7e9a + 7e90: 85 35 cpi r24, 0x55 ; 85 + 7e92: 79 f4 brne .+30 ; 0x7eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 7e7a: 99 d0 rcall .+306 ; 0x7fae + 7e94: 88 d0 rcall .+272 ; 0x7fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 7e7c: 08 2f mov r16, r24 - 7e7e: 10 e0 ldi r17, 0x00 ; 0 - 7e80: 96 d0 rcall .+300 ; 0x7fae - 7e82: 90 e0 ldi r25, 0x00 ; 0 - 7e84: 98 2f mov r25, r24 - 7e86: 88 27 eor r24, r24 - 7e88: 80 2b or r24, r16 - 7e8a: 91 2b or r25, r17 + 7e96: e8 2e mov r14, r24 + 7e98: ff 24 eor r15, r15 + 7e9a: 85 d0 rcall .+266 ; 0x7fa6 + 7e9c: 08 2f mov r16, r24 + 7e9e: 10 e0 ldi r17, 0x00 ; 0 + 7ea0: 10 2f mov r17, r16 + 7ea2: 00 27 eor r16, r16 + 7ea4: 0e 29 or r16, r14 + 7ea6: 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 - 7e8c: 88 0f add r24, r24 - 7e8e: 99 1f adc r25, r25 + 7ea8: 00 0f add r16, r16 + 7eaa: 11 1f adc r17, r17 address = newAddress; - 7e90: 90 93 01 02 sts 0x0201, r25 - 7e94: 80 93 00 02 sts 0x0200, r24 - 7e98: 7e c0 rjmp .+252 ; 0x7f96 verifySpace(); + 7eac: 8e d0 rcall .+284 ; 0x7fca + 7eae: 68 01 movw r12, r16 + 7eb0: 6f c0 rjmp .+222 ; 0x7f90 } else if(ch == STK_UNIVERSAL) { - 7e9a: 86 35 cpi r24, 0x56 ; 86 - 7e9c: 29 f4 brne .+10 ; 0x7ea8 + 7eb2: 86 35 cpi r24, 0x56 ; 86 + 7eb4: 21 f4 brne .+8 ; 0x7ebe // UNIVERSAL command is ignored getNch(4); - 7e9e: 84 e0 ldi r24, 0x04 ; 4 - 7ea0: a4 d0 rcall .+328 ; 0x7fea + 7eb6: 84 e0 ldi r24, 0x04 ; 4 + 7eb8: 90 d0 rcall .+288 ; 0x7fda putch(0x00); - 7ea2: 80 e0 ldi r24, 0x00 ; 0 - 7ea4: 7c d0 rcall .+248 ; 0x7f9e - 7ea6: 78 c0 rjmp .+240 ; 0x7f98 + 7eba: 80 e0 ldi r24, 0x00 ; 0 + 7ebc: de cf rjmp .-68 ; 0x7e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 7ea8: 84 36 cpi r24, 0x64 ; 100 - 7eaa: 09 f0 breq .+2 ; 0x7eae - 7eac: 4e c0 rjmp .+156 ; 0x7f4a + 7ebe: 84 36 cpi r24, 0x64 ; 100 + 7ec0: 09 f0 breq .+2 ; 0x7ec4 + 7ec2: 40 c0 rjmp .+128 ; 0x7f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 7eae: 87 d0 rcall .+270 ; 0x7fbe + getch(); /* getlen() */ + 7ec4: 70 d0 rcall .+224 ; 0x7fa6 + length = getch(); + 7ec6: 6f d0 rcall .+222 ; 0x7fa6 + 7ec8: 08 2f mov r16, r24 + getch(); + 7eca: 6d d0 rcall .+218 ; 0x7fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 7eb0: e0 91 00 02 lds r30, 0x0200 - 7eb4: f0 91 01 02 lds r31, 0x0201 - 7eb8: 80 e7 ldi r24, 0x70 ; 112 - 7eba: e0 30 cpi r30, 0x00 ; 0 - 7ebc: f8 07 cpc r31, r24 - 7ebe: 18 f4 brcc .+6 ; 0x7ec6 - 7ec0: 83 e0 ldi r24, 0x03 ; 3 - 7ec2: 87 bf out 0x37, r24 ; 55 - 7ec4: e8 95 spm - 7ec6: c0 e0 ldi r28, 0x00 ; 0 - 7ec8: d1 e0 ldi r29, 0x01 ; 1 - + 7ecc: 80 e0 ldi r24, 0x00 ; 0 + 7ece: c8 16 cp r12, r24 + 7ed0: 80 e7 ldi r24, 0x70 ; 112 + 7ed2: d8 06 cpc r13, r24 + 7ed4: 18 f4 brcc .+6 ; 0x7edc + 7ed6: f6 01 movw r30, r12 + 7ed8: b7 be out 0x37, r11 ; 55 + 7eda: e8 95 spm + 7edc: c0 e0 ldi r28, 0x00 ; 0 + 7ede: d1 e0 ldi r29, 0x01 ; 1 + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - 7eca: 71 d0 rcall .+226 ; 0x7fae - 7ecc: 89 93 st Y+, r24 + 7ee0: 62 d0 rcall .+196 ; 0x7fa6 + 7ee2: 89 93 st Y+, r24 while (--length); - 7ece: 80 91 02 02 lds r24, 0x0202 - 7ed2: 81 50 subi r24, 0x01 ; 1 - 7ed4: 80 93 02 02 sts 0x0202, r24 - 7ed8: 88 23 and r24, r24 - 7eda: b9 f7 brne .-18 ; 0x7eca + 7ee4: 0c 17 cp r16, r28 + 7ee6: e1 f7 brne .-8 ; 0x7ee0 // 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); - 7edc: e0 91 00 02 lds r30, 0x0200 - 7ee0: f0 91 01 02 lds r31, 0x0201 - 7ee4: 80 e7 ldi r24, 0x70 ; 112 - 7ee6: e0 30 cpi r30, 0x00 ; 0 - 7ee8: f8 07 cpc r31, r24 - 7eea: 18 f0 brcs .+6 ; 0x7ef2 - 7eec: 83 e0 ldi r24, 0x03 ; 3 - 7eee: 87 bf out 0x37, r24 ; 55 - 7ef0: e8 95 spm + 7ee8: f0 e0 ldi r31, 0x00 ; 0 + 7eea: cf 16 cp r12, r31 + 7eec: f0 e7 ldi r31, 0x70 ; 112 + 7eee: df 06 cpc r13, r31 + 7ef0: 18 f0 brcs .+6 ; 0x7ef8 + 7ef2: f6 01 movw r30, r12 + 7ef4: b7 be out 0x37, r11 ; 55 + 7ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 7ef2: 75 d0 rcall .+234 ; 0x7fde - + 7ef8: 68 d0 rcall .+208 ; 0x7fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 7ef4: 07 b6 in r0, 0x37 ; 55 - 7ef6: 00 fc sbrc r0, 0 - 7ef8: fd cf rjmp .-6 ; 0x7ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 7efa: 40 91 00 02 lds r20, 0x0200 - 7efe: 50 91 01 02 lds r21, 0x0201 + 7efa: 07 b6 in r0, 0x37 ; 55 + 7efc: 00 fc sbrc r0, 0 + 7efe: fd cf rjmp .-6 ; 0x7efa + 7f00: a6 01 movw r20, r12 7f02: a0 e0 ldi r26, 0x00 ; 0 7f04: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; ch = SPM_PAGESIZE / 2; do { uint16_t a; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 7f1c: fa 01 movw r30, r20 7f1e: 0c 01 movw r0, r24 - 7f20: d7 be out 0x37, r13 ; 55 + 7f20: 87 be out 0x37, r8 ; 55 7f22: e8 95 spm 7f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 7f2c: a0 38 cpi r26, 0x80 ; 128 7f2e: bf 07 cpc r27, r31 7f30: 51 f7 brne .-44 ; 0x7f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 7f32: e0 91 00 02 lds r30, 0x0200 - 7f36: f0 91 01 02 lds r31, 0x0201 - 7f3a: e7 be out 0x37, r14 ; 55 - 7f3c: e8 95 spm + 7f32: f6 01 movw r30, r12 + 7f34: a7 be out 0x37, r10 ; 55 + 7f36: e8 95 spm boot_spm_busy_wait(); - 7f3e: 07 b6 in r0, 0x37 ; 55 - 7f40: 00 fc sbrc r0, 0 - 7f42: fd cf rjmp .-6 ; 0x7f3e + 7f38: 07 b6 in r0, 0x37 ; 55 + 7f3a: 00 fc sbrc r0, 0 + 7f3c: fd cf rjmp .-6 ; 0x7f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7f44: f7 be out 0x37, r15 ; 55 - 7f46: e8 95 spm - 7f48: 27 c0 rjmp .+78 ; 0x7f98 + 7f3e: 97 be out 0x37, r9 ; 55 + 7f40: e8 95 spm + 7f42: 26 c0 rjmp .+76 ; 0x7f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 7f4a: 84 37 cpi r24, 0x74 ; 116 - 7f4c: b9 f4 brne .+46 ; 0x7f7c + 7f44: 84 37 cpi r24, 0x74 ; 116 + 7f46: b1 f4 brne .+44 ; 0x7f74 // READ PAGE - we only read flash - getLen(); - 7f4e: 37 d0 rcall .+110 ; 0x7fbe + getch(); /* getlen() */ + 7f48: 2e d0 rcall .+92 ; 0x7fa6 + length = getch(); + 7f4a: 2d d0 rcall .+90 ; 0x7fa6 + 7f4c: f8 2e mov r15, r24 + getch(); + 7f4e: 2b d0 rcall .+86 ; 0x7fa6 + verifySpace(); - 7f50: 46 d0 rcall .+140 ; 0x7fde + 7f50: 3c d0 rcall .+120 ; 0x7fca + 7f52: f6 01 movw r30, r12 + 7f54: ef 2c mov r14, r15 putch(result); address++; } while (--length); #else do putch(pgm_read_byte_near(address++)); - 7f52: e0 91 00 02 lds r30, 0x0200 - 7f56: f0 91 01 02 lds r31, 0x0201 - 7f5a: 31 96 adiw r30, 0x01 ; 1 - 7f5c: f0 93 01 02 sts 0x0201, r31 - 7f60: e0 93 00 02 sts 0x0200, r30 - 7f64: 31 97 sbiw r30, 0x01 ; 1 - 7f66: e4 91 lpm r30, Z+ - 7f68: 8e 2f mov r24, r30 - 7f6a: 19 d0 rcall .+50 ; 0x7f9e + 7f56: 8f 01 movw r16, r30 + 7f58: 0f 5f subi r16, 0xFF ; 255 + 7f5a: 1f 4f sbci r17, 0xFF ; 255 + 7f5c: 84 91 lpm r24, Z+ + 7f5e: 1b d0 rcall .+54 ; 0x7f96 while (--length); - 7f6c: 80 91 02 02 lds r24, 0x0202 - 7f70: 81 50 subi r24, 0x01 ; 1 - 7f72: 80 93 02 02 sts 0x0202, r24 - 7f76: 88 23 and r24, r24 - 7f78: 61 f7 brne .-40 ; 0x7f52 - 7f7a: 0e c0 rjmp .+28 ; 0x7f98 + 7f60: ea 94 dec r14 + 7f62: f8 01 movw r30, r16 + 7f64: c1 f7 brne .-16 ; 0x7f56 +#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) { + 7f66: 08 94 sec + 7f68: c1 1c adc r12, r1 + 7f6a: d1 1c adc r13, r1 + 7f6c: fa 94 dec r15 + 7f6e: cf 0c add r12, r15 + 7f70: d1 1c adc r13, r1 + 7f72: 0e c0 rjmp .+28 ; 0x7f90 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 7f7c: 85 37 cpi r24, 0x75 ; 117 - 7f7e: 39 f4 brne .+14 ; 0x7f8e + 7f74: 85 37 cpi r24, 0x75 ; 117 + 7f76: 39 f4 brne .+14 ; 0x7f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 7f80: 2e d0 rcall .+92 ; 0x7fde + 7f78: 28 d0 rcall .+80 ; 0x7fca putch(SIGNATURE_0); - 7f82: 8e e1 ldi r24, 0x1E ; 30 - 7f84: 0c d0 rcall .+24 ; 0x7f9e + 7f7a: 8e e1 ldi r24, 0x1E ; 30 + 7f7c: 0c d0 rcall .+24 ; 0x7f96 putch(SIGNATURE_1); - 7f86: 85 e9 ldi r24, 0x95 ; 149 - 7f88: 0a d0 rcall .+20 ; 0x7f9e + 7f7e: 85 e9 ldi r24, 0x95 ; 149 + 7f80: 0a d0 rcall .+20 ; 0x7f96 putch(SIGNATURE_2); - 7f8a: 8f e0 ldi r24, 0x0F ; 15 - 7f8c: 8b cf rjmp .-234 ; 0x7ea4 + 7f82: 8f e0 ldi r24, 0x0F ; 15 + 7f84: 7a cf rjmp .-268 ; 0x7e7a } else if (ch == 'Q') { - 7f8e: 81 35 cpi r24, 0x51 ; 81 - 7f90: 11 f4 brne .+4 ; 0x7f96 + 7f86: 81 35 cpi r24, 0x51 ; 81 + 7f88: 11 f4 brne .+4 ; 0x7f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 7f92: 88 e0 ldi r24, 0x08 ; 8 - 7f94: 19 d0 rcall .+50 ; 0x7fc8 + 7f8a: 88 e0 ldi r24, 0x08 ; 8 + 7f8c: 18 d0 rcall .+48 ; 0x7fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 7f96: 23 d0 rcall .+70 ; 0x7fde + 7f8e: 1d d0 rcall .+58 ; 0x7fca } putch(STK_OK); - 7f98: 80 e1 ldi r24, 0x10 ; 16 - 7f9a: 01 d0 rcall .+2 ; 0x7f9e - 7f9c: 5c cf rjmp .-328 ; 0x7e56 + 7f90: 80 e1 ldi r24, 0x10 ; 16 + 7f92: 01 d0 rcall .+2 ; 0x7f96 + 7f94: 65 cf rjmp .-310 ; 0x7e60 -00007f9e : +00007f96 : } } void putch(char ch) { - 7f9e: 98 2f mov r25, r24 + 7f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 7fa0: 80 91 c0 00 lds r24, 0x00C0 - 7fa4: 85 ff sbrs r24, 5 - 7fa6: fc cf rjmp .-8 ; 0x7fa0 + 7f98: 80 91 c0 00 lds r24, 0x00C0 + 7f9c: 85 ff sbrs r24, 5 + 7f9e: fc cf rjmp .-8 ; 0x7f98 UDR0 = ch; - 7fa8: 90 93 c6 00 sts 0x00C6, r25 + 7fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 7fac: 08 95 ret + 7fa4: 08 95 ret -00007fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 7fae: a8 95 wdr +00007fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 7fb0: 80 91 c0 00 lds r24, 0x00C0 - 7fb4: 87 ff sbrs r24, 7 - 7fb6: fc cf rjmp .-8 ; 0x7fb0 + while(!(UCSR0A & _BV(RXC0))) + 7fa6: 80 91 c0 00 lds r24, 0x00C0 + 7faa: 87 ff sbrs r24, 7 + 7fac: fc cf rjmp .-8 ; 0x7fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 7fae: 80 91 c0 00 lds r24, 0x00C0 + 7fb2: 84 fd sbrc r24, 4 + 7fb4: 01 c0 rjmp .+2 ; 0x7fb8 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 7fb6: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; 7fb8: 80 91 c6 00 lds r24, 0x00C6 LED_PIN |= _BV(LED); @@ -474,79 +526,73 @@ void watchdogReset() { } 7fbc: 08 95 ret -00007fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 7fbe: f7 df rcall .-18 ; 0x7fae - length = getch(); - 7fc0: f6 df rcall .-20 ; 0x7fae - 7fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 7fc6: f3 cf rjmp .-26 ; 0x7fae - -00007fc8 : +00007fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 7fc8: e0 e6 ldi r30, 0x60 ; 96 - 7fca: f0 e0 ldi r31, 0x00 ; 0 - 7fcc: 98 e1 ldi r25, 0x18 ; 24 - 7fce: 90 83 st Z, r25 + 7fbe: e0 e6 ldi r30, 0x60 ; 96 + 7fc0: f0 e0 ldi r31, 0x00 ; 0 + 7fc2: 98 e1 ldi r25, 0x18 ; 24 + 7fc4: 90 83 st Z, r25 WDTCSR = x; - 7fd0: 80 83 st Z, r24 + 7fc6: 80 83 st Z, r24 } - 7fd2: 08 95 ret + 7fc8: 08 95 ret -00007fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 7fd4: 80 e0 ldi r24, 0x00 ; 0 - 7fd6: f8 df rcall .-16 ; 0x7fc8 - __asm__ __volatile__ ( - 7fd8: ee 27 eor r30, r30 - 7fda: ff 27 eor r31, r31 - 7fdc: 09 94 ijmp - -00007fde : +00007fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 7fde: e7 df rcall .-50 ; 0x7fae - 7fe0: 80 32 cpi r24, 0x20 ; 32 - 7fe2: 09 f0 breq .+2 ; 0x7fe6 - 7fe4: f7 df rcall .-18 ; 0x7fd4 + if (getch() != CRC_EOP) { + 7fca: ed df rcall .-38 ; 0x7fa6 + 7fcc: 80 32 cpi r24, 0x20 ; 32 + 7fce: 19 f0 breq .+6 ; 0x7fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 7fd0: 88 e0 ldi r24, 0x08 ; 8 + 7fd2: f5 df rcall .-22 ; 0x7fbe + 7fd4: ff cf rjmp .-2 ; 0x7fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 7fe6: 84 e1 ldi r24, 0x14 ; 20 + 7fd6: 84 e1 ldi r24, 0x14 ; 20 } - 7fe8: da cf rjmp .-76 ; 0x7f9e + 7fd8: de cf rjmp .-68 ; 0x7f96 -00007fea : +00007fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 7fea: 1f 93 push r17 - 7fec: 18 2f mov r17, r24 + 7fda: 1f 93 push r17 + 7fdc: 18 2f mov r17, r24 do getch(); while (--count); - 7fee: df df rcall .-66 ; 0x7fae - 7ff0: 11 50 subi r17, 0x01 ; 1 - 7ff2: e9 f7 brne .-6 ; 0x7fee + 7fde: e3 df rcall .-58 ; 0x7fa6 + 7fe0: 11 50 subi r17, 0x01 ; 1 + 7fe2: e9 f7 brne .-6 ; 0x7fde verifySpace(); - 7ff4: f4 df rcall .-24 ; 0x7fde + 7fe4: f2 df rcall .-28 ; 0x7fca } - 7ff6: 1f 91 pop r17 - 7ff8: 08 95 ret + 7fe6: 1f 91 pop r17 + 7fe8: 08 95 ret + +00007fea : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 7fea: 80 e0 ldi r24, 0x00 ; 0 + 7fec: e8 df rcall .-48 ; 0x7fbe + __asm__ __volatile__ ( + 7fee: ee 27 eor r30, r30 + 7ff0: ff 27 eor r31, r31 + 7ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex b/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex index 35dc74f..ff62ed0 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex +++ b/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex @@ -1,34 +1,35 @@ -:107E000085E08093810082E08093C00088E18093C8 -:107E1000C10086E08093C20088E08093C40084B7EC -:107E200014BE81FFD7D08DE0CFD0259A86E028E11F -:107E30003EEF91E0309385002093840096BBB09B89 -:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 -:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0 -:107E600083E020C0823411F484E103C0853419F426 -:107E700085E0BBD091C0853581F499D0082F10E002 -:107E800096D090E0982F8827802B912B880F991FF0 -:107E900090930102809300027EC0863529F484E02D -:107EA000A4D080E07CD078C0843609F04EC087D062 -:107EB000E0910002F091010280E7E030F80718F449 -:107EC00083E087BFE895C0E0D1E071D089938091CD -:107ED00002028150809302028823B9F7E0910002E8 -:107EE000F091010280E7E030F80718F083E087BFE7 -:107EF000E89575D007B600FCFDCF40910002509187 -:107F00000102A0E0B1E02C9130E011968C91119724 +:107E0000112484B714BE81FFF0D085E080938100F7 +:107E100082E08093C00088E18093C10086E0809377 +:107E2000C20088E08093C4008EE0C9D0259A86E025 +:107E300028E13EEF91E0309385002093840096BBCB +:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4 +:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7 +:107E6000A2D0813461F49FD0082FAFD0023811F036 +:107E7000013811F484E001C083E08DD089C08234E0 +:107E800011F484E103C0853419F485E0A6D080C0E4 +:107E9000853579F488D0E82EFF2485D0082F10E0AE +:107EA000102F00270E291F29000F111F8ED06801E7 +:107EB0006FC0863521F484E090D080E0DECF843638 +:107EC00009F040C070D06FD0082F6DD080E0C81688 +:107ED00080E7D80618F4F601B7BEE895C0E0D1E017 +:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8 +:107EF00018F0F601B7BEE89568D007B600FCFDCFD4 +:107F0000A601A0E0B1E02C9130E011968C91119780 :107F100090E0982F8827822B932B1296FA010C0160 -:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740 -:107F300051F7E0910002F0910102E7BEE89507B623 -:107F400000FCFDCFF7BEE89527C08437B9F437D0E1 -:107F500046D0E0910002F09101023196F0930102C7 -:107F6000E09300023197E4918E2F19D080910202A4 -:107F7000815080930202882361F70EC0853739F45F -:107F80002ED08EE10CD085E90AD08FE08BCF8135E1 -:107F900011F488E019D023D080E101D05CCF982F74 -:107FA0008091C00085FFFCCF9093C6000895A895EE -:107FB0008091C00087FFFCCF8091C6000895F7DF55 -:107FC000F6DF80930202F3CFE0E6F0E098E19083E1 -:107FD0008083089580E0F8DFEE27FF270994E7DF2C -:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B -:0A7FF0001150E9F7F4DF1F91089526 +:107F200087BEE89511244E5F5F4FF1E0A038BF0790 +:107F300051F7F601A7BEE89507B600FCFDCF97BE46 +:107F4000E89526C08437B1F42ED02DD0F82E2BD052 +:107F50003CD0F601EF2C8F010F5F1F4F84911BD097 +:107F6000EA94F801C1F70894C11CD11CFA94CF0C13 +:107F7000D11C0EC0853739F428D08EE10CD085E9AC +:107F80000AD08FE07ACF813511F488E018D01DD067 +:107F900080E101D065CF982F8091C00085FFFCCF94 +:107FA0009093C60008958091C00087FFFCCF809118 +:107FB000C00084FD01C0A8958091C6000895E0E648 +:107FC000F0E098E1908380830895EDDF803219F02E +:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA +:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6 +:047FF000FF270994CA +:027FFE00040479 :0400000300007E007B :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst b/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst index 5498879..032ad5a 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst +++ b/optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst @@ -3,25 +3,27 @@ optiboot_atmega328_pro_8MHz.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00007e00 00007e00 00000054 2**1 + 0 .text 000001f4 00007e00 00007e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00007ffe 00007ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e3 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000140 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc8 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000ea9 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,256 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 7e00: 85 e0 ldi r24, 0x05 ; 5 - 7e02: 80 93 81 00 sts 0x0081, r24 -#if LED_START_FLASHES > 0 - // Set up Timer 1 for timeout counter - TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 -#endif -#ifndef SOFT_UART - UCSR0A = _BV(U2X0); //Double speed mode USART0 - 7e06: 82 e0 ldi r24, 0x02 ; 2 - 7e08: 80 93 c0 00 sts 0x00C0, r24 - UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 7e0c: 88 e1 ldi r24, 0x18 ; 24 - 7e0e: 80 93 c1 00 sts 0x00C1, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 7e12: 86 e0 ldi r24, 0x06 ; 6 - 7e14: 80 93 c2 00 sts 0x00C2, r24 - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 7e18: 88 e0 ldi r24, 0x08 ; 8 - 7e1a: 80 93 c4 00 sts 0x00C4, r24 + 7e00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset #endif // Adaboot no-wait mod ch = MCUSR; - 7e1e: 84 b7 in r24, 0x34 ; 52 + 7e02: 84 b7 in r24, 0x34 ; 52 MCUSR = 0; - 7e20: 14 be out 0x34, r1 ; 52 + 7e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 7e22: 81 ff sbrs r24, 1 - 7e24: d7 d0 rcall .+430 ; 0x7fd4 + 7e06: 81 ff sbrs r24, 1 + 7e08: f0 d0 rcall .+480 ; 0x7fea + +#if LED_START_FLASHES > 0 + // Set up Timer 1 for timeout counter + TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 + 7e0a: 85 e0 ldi r24, 0x05 ; 5 + 7e0c: 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 + 7e10: 82 e0 ldi r24, 0x02 ; 2 + 7e12: 80 93 c0 00 sts 0x00C0, r24 + UCSR0B = _BV(RXEN0) | _BV(TXEN0); + 7e16: 88 e1 ldi r24, 0x18 ; 24 + 7e18: 80 93 c1 00 sts 0x00C1, r24 + UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); + 7e1c: 86 e0 ldi r24, 0x06 ; 6 + 7e1e: 80 93 c2 00 sts 0x00C2, r24 + UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); + 7e22: 88 e0 ldi r24, 0x08 ; 8 + 7e24: 80 93 c4 00 sts 0x00C4, r24 +#endif +#endif // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 7e26: 8d e0 ldi r24, 0x0D ; 13 - 7e28: cf d0 rcall .+414 ; 0x7fc8 + watchdogConfig(WATCHDOG_1S); + 7e28: 8e e0 ldi r24, 0x0E ; 14 + 7e2a: c9 d0 rcall .+402 ; 0x7fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 7e2a: 25 9a sbi 0x04, 5 ; 4 - 7e2c: 86 e0 ldi r24, 0x06 ; 6 + 7e2c: 25 9a sbi 0x04, 5 ; 4 + 7e2e: 86 e0 ldi r24, 0x06 ; 6 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 7e2e: 28 e1 ldi r18, 0x18 ; 24 - 7e30: 3e ef ldi r19, 0xFE ; 254 + 7e30: 28 e1 ldi r18, 0x18 ; 24 + 7e32: 3e ef ldi r19, 0xFE ; 254 TIFR1 = _BV(TOV1); - 7e32: 91 e0 ldi r25, 0x01 ; 1 + 7e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 7e34: 30 93 85 00 sts 0x0085, r19 - 7e38: 20 93 84 00 sts 0x0084, r18 + 7e36: 30 93 85 00 sts 0x0085, r19 + 7e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 7e3c: 96 bb out 0x16, r25 ; 22 + 7e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 7e3e: b0 9b sbis 0x16, 0 ; 22 - 7e40: fe cf rjmp .-4 ; 0x7e3e + 7e40: b0 9b sbis 0x16, 0 ; 22 + 7e42: fe cf rjmp .-4 ; 0x7e40 +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); - 7e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 7e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 7e44: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); + 7e46: a8 95 wdr + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); +#endif watchdogReset(); } while (--count); - 7e46: 81 50 subi r24, 0x01 ; 1 - 7e48: a9 f7 brne .-22 ; 0x7e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e4a: dd 24 eor r13, r13 - 7e4c: d3 94 inc r13 + 7e48: 81 50 subi r24, 0x01 ; 1 + 7e4a: a9 f7 brne .-22 ; 0x7e36 + 7e4c: cc 24 eor r12, r12 + 7e4e: 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); + 7e50: 88 24 eor r8, r8 + 7e52: 83 94 inc r8 addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 7e4e: a5 e0 ldi r26, 0x05 ; 5 - 7e50: ea 2e mov r14, r26 + 7e54: b5 e0 ldi r27, 0x05 ; 5 + 7e56: ab 2e mov r10, r27 boot_spm_busy_wait(); #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7e52: f1 e1 ldi r31, 0x11 ; 17 - 7e54: ff 2e mov r15, r31 + 7e58: a1 e1 ldi r26, 0x11 ; 17 + 7e5a: 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); + 7e5c: f3 e0 ldi r31, 0x03 ; 3 + 7e5e: bf 2e mov r11, r31 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - 7e56: ab d0 rcall .+342 ; 0x7fae + 7e60: a2 d0 rcall .+324 ; 0x7fa6 if(ch == STK_GET_PARAMETER) { - 7e58: 81 34 cpi r24, 0x41 ; 65 - 7e5a: 21 f4 brne .+8 ; 0x7e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e5c: 81 e0 ldi r24, 0x01 ; 1 - 7e5e: c5 d0 rcall .+394 ; 0x7fea - putch(0x03); - 7e60: 83 e0 ldi r24, 0x03 ; 3 - 7e62: 20 c0 rjmp .+64 ; 0x7ea4 + 7e62: 81 34 cpi r24, 0x41 ; 65 + 7e64: 61 f4 brne .+24 ; 0x7e7e + unsigned char which = getch(); + 7e66: 9f d0 rcall .+318 ; 0x7fa6 + 7e68: 08 2f mov r16, r24 + verifySpace(); + 7e6a: af d0 rcall .+350 ; 0x7fca + if (which == 0x82) { + 7e6c: 02 38 cpi r16, 0x82 ; 130 + 7e6e: 11 f0 breq .+4 ; 0x7e74 + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 7e70: 01 38 cpi r16, 0x81 ; 129 + 7e72: 11 f4 brne .+4 ; 0x7e78 + putch(OPTIBOOT_MAJVER); + 7e74: 84 e0 ldi r24, 0x04 ; 4 + 7e76: 01 c0 rjmp .+2 ; 0x7e7a + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 7e78: 83 e0 ldi r24, 0x03 ; 3 + 7e7a: 8d d0 rcall .+282 ; 0x7f96 + 7e7c: 89 c0 rjmp .+274 ; 0x7f90 + } } else if(ch == STK_SET_DEVICE) { - 7e64: 82 34 cpi r24, 0x42 ; 66 - 7e66: 11 f4 brne .+4 ; 0x7e6c + 7e7e: 82 34 cpi r24, 0x42 ; 66 + 7e80: 11 f4 brne .+4 ; 0x7e86 // SET DEVICE is ignored getNch(20); - 7e68: 84 e1 ldi r24, 0x14 ; 20 - 7e6a: 03 c0 rjmp .+6 ; 0x7e72 + 7e82: 84 e1 ldi r24, 0x14 ; 20 + 7e84: 03 c0 rjmp .+6 ; 0x7e8c } else if(ch == STK_SET_DEVICE_EXT) { - 7e6c: 85 34 cpi r24, 0x45 ; 69 - 7e6e: 19 f4 brne .+6 ; 0x7e76 + 7e86: 85 34 cpi r24, 0x45 ; 69 + 7e88: 19 f4 brne .+6 ; 0x7e90 // SET DEVICE EXT is ignored getNch(5); - 7e70: 85 e0 ldi r24, 0x05 ; 5 - 7e72: bb d0 rcall .+374 ; 0x7fea - 7e74: 91 c0 rjmp .+290 ; 0x7f98 + 7e8a: 85 e0 ldi r24, 0x05 ; 5 + 7e8c: a6 d0 rcall .+332 ; 0x7fda + 7e8e: 80 c0 rjmp .+256 ; 0x7f90 } else if(ch == STK_LOAD_ADDRESS) { - 7e76: 85 35 cpi r24, 0x55 ; 85 - 7e78: 81 f4 brne .+32 ; 0x7e9a + 7e90: 85 35 cpi r24, 0x55 ; 85 + 7e92: 79 f4 brne .+30 ; 0x7eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 7e7a: 99 d0 rcall .+306 ; 0x7fae + 7e94: 88 d0 rcall .+272 ; 0x7fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 7e7c: 08 2f mov r16, r24 - 7e7e: 10 e0 ldi r17, 0x00 ; 0 - 7e80: 96 d0 rcall .+300 ; 0x7fae - 7e82: 90 e0 ldi r25, 0x00 ; 0 - 7e84: 98 2f mov r25, r24 - 7e86: 88 27 eor r24, r24 - 7e88: 80 2b or r24, r16 - 7e8a: 91 2b or r25, r17 + 7e96: e8 2e mov r14, r24 + 7e98: ff 24 eor r15, r15 + 7e9a: 85 d0 rcall .+266 ; 0x7fa6 + 7e9c: 08 2f mov r16, r24 + 7e9e: 10 e0 ldi r17, 0x00 ; 0 + 7ea0: 10 2f mov r17, r16 + 7ea2: 00 27 eor r16, r16 + 7ea4: 0e 29 or r16, r14 + 7ea6: 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 - 7e8c: 88 0f add r24, r24 - 7e8e: 99 1f adc r25, r25 + 7ea8: 00 0f add r16, r16 + 7eaa: 11 1f adc r17, r17 address = newAddress; - 7e90: 90 93 01 02 sts 0x0201, r25 - 7e94: 80 93 00 02 sts 0x0200, r24 - 7e98: 7e c0 rjmp .+252 ; 0x7f96 verifySpace(); + 7eac: 8e d0 rcall .+284 ; 0x7fca + 7eae: 68 01 movw r12, r16 + 7eb0: 6f c0 rjmp .+222 ; 0x7f90 } else if(ch == STK_UNIVERSAL) { - 7e9a: 86 35 cpi r24, 0x56 ; 86 - 7e9c: 29 f4 brne .+10 ; 0x7ea8 + 7eb2: 86 35 cpi r24, 0x56 ; 86 + 7eb4: 21 f4 brne .+8 ; 0x7ebe // UNIVERSAL command is ignored getNch(4); - 7e9e: 84 e0 ldi r24, 0x04 ; 4 - 7ea0: a4 d0 rcall .+328 ; 0x7fea + 7eb6: 84 e0 ldi r24, 0x04 ; 4 + 7eb8: 90 d0 rcall .+288 ; 0x7fda putch(0x00); - 7ea2: 80 e0 ldi r24, 0x00 ; 0 - 7ea4: 7c d0 rcall .+248 ; 0x7f9e - 7ea6: 78 c0 rjmp .+240 ; 0x7f98 + 7eba: 80 e0 ldi r24, 0x00 ; 0 + 7ebc: de cf rjmp .-68 ; 0x7e7a } - /* Write memory, length is big endian and is in bytes */ + /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 7ea8: 84 36 cpi r24, 0x64 ; 100 - 7eaa: 09 f0 breq .+2 ; 0x7eae - 7eac: 4e c0 rjmp .+156 ; 0x7f4a + 7ebe: 84 36 cpi r24, 0x64 ; 100 + 7ec0: 09 f0 breq .+2 ; 0x7ec4 + 7ec2: 40 c0 rjmp .+128 ; 0x7f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 7eae: 87 d0 rcall .+270 ; 0x7fbe + getch(); /* getlen() */ + 7ec4: 70 d0 rcall .+224 ; 0x7fa6 + length = getch(); + 7ec6: 6f d0 rcall .+222 ; 0x7fa6 + 7ec8: 08 2f mov r16, r24 + getch(); + 7eca: 6d d0 rcall .+218 ; 0x7fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 7eb0: e0 91 00 02 lds r30, 0x0200 - 7eb4: f0 91 01 02 lds r31, 0x0201 - 7eb8: 80 e7 ldi r24, 0x70 ; 112 - 7eba: e0 30 cpi r30, 0x00 ; 0 - 7ebc: f8 07 cpc r31, r24 - 7ebe: 18 f4 brcc .+6 ; 0x7ec6 - 7ec0: 83 e0 ldi r24, 0x03 ; 3 - 7ec2: 87 bf out 0x37, r24 ; 55 - 7ec4: e8 95 spm - 7ec6: c0 e0 ldi r28, 0x00 ; 0 - 7ec8: d1 e0 ldi r29, 0x01 ; 1 - + 7ecc: 80 e0 ldi r24, 0x00 ; 0 + 7ece: c8 16 cp r12, r24 + 7ed0: 80 e7 ldi r24, 0x70 ; 112 + 7ed2: d8 06 cpc r13, r24 + 7ed4: 18 f4 brcc .+6 ; 0x7edc + 7ed6: f6 01 movw r30, r12 + 7ed8: b7 be out 0x37, r11 ; 55 + 7eda: e8 95 spm + 7edc: c0 e0 ldi r28, 0x00 ; 0 + 7ede: d1 e0 ldi r29, 0x01 ; 1 + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - 7eca: 71 d0 rcall .+226 ; 0x7fae - 7ecc: 89 93 st Y+, r24 + 7ee0: 62 d0 rcall .+196 ; 0x7fa6 + 7ee2: 89 93 st Y+, r24 while (--length); - 7ece: 80 91 02 02 lds r24, 0x0202 - 7ed2: 81 50 subi r24, 0x01 ; 1 - 7ed4: 80 93 02 02 sts 0x0202, r24 - 7ed8: 88 23 and r24, r24 - 7eda: b9 f7 brne .-18 ; 0x7eca + 7ee4: 0c 17 cp r16, r28 + 7ee6: e1 f7 brne .-8 ; 0x7ee0 // 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); - 7edc: e0 91 00 02 lds r30, 0x0200 - 7ee0: f0 91 01 02 lds r31, 0x0201 - 7ee4: 80 e7 ldi r24, 0x70 ; 112 - 7ee6: e0 30 cpi r30, 0x00 ; 0 - 7ee8: f8 07 cpc r31, r24 - 7eea: 18 f0 brcs .+6 ; 0x7ef2 - 7eec: 83 e0 ldi r24, 0x03 ; 3 - 7eee: 87 bf out 0x37, r24 ; 55 - 7ef0: e8 95 spm + 7ee8: f0 e0 ldi r31, 0x00 ; 0 + 7eea: cf 16 cp r12, r31 + 7eec: f0 e7 ldi r31, 0x70 ; 112 + 7eee: df 06 cpc r13, r31 + 7ef0: 18 f0 brcs .+6 ; 0x7ef8 + 7ef2: f6 01 movw r30, r12 + 7ef4: b7 be out 0x37, r11 ; 55 + 7ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 7ef2: 75 d0 rcall .+234 ; 0x7fde - + 7ef8: 68 d0 rcall .+208 ; 0x7fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 7ef4: 07 b6 in r0, 0x37 ; 55 - 7ef6: 00 fc sbrc r0, 0 - 7ef8: fd cf rjmp .-6 ; 0x7ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 7efa: 40 91 00 02 lds r20, 0x0200 - 7efe: 50 91 01 02 lds r21, 0x0201 + 7efa: 07 b6 in r0, 0x37 ; 55 + 7efc: 00 fc sbrc r0, 0 + 7efe: fd cf rjmp .-6 ; 0x7efa + 7f00: a6 01 movw r20, r12 7f02: a0 e0 ldi r26, 0x00 ; 0 7f04: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; ch = SPM_PAGESIZE / 2; do { uint16_t a; @@ -313,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 7f1c: fa 01 movw r30, r20 7f1e: 0c 01 movw r0, r24 - 7f20: d7 be out 0x37, r13 ; 55 + 7f20: 87 be out 0x37, r8 ; 55 7f22: e8 95 spm 7f24: 11 24 eor r1, r1 addrPtr += 2; @@ -324,219 +363,236 @@ int main(void) { 7f2c: a0 38 cpi r26, 0x80 ; 128 7f2e: bf 07 cpc r27, r31 7f30: 51 f7 brne .-44 ; 0x7f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 7f32: e0 91 00 02 lds r30, 0x0200 - 7f36: f0 91 01 02 lds r31, 0x0201 - 7f3a: e7 be out 0x37, r14 ; 55 - 7f3c: e8 95 spm + 7f32: f6 01 movw r30, r12 + 7f34: a7 be out 0x37, r10 ; 55 + 7f36: e8 95 spm boot_spm_busy_wait(); - 7f3e: 07 b6 in r0, 0x37 ; 55 - 7f40: 00 fc sbrc r0, 0 - 7f42: fd cf rjmp .-6 ; 0x7f3e + 7f38: 07 b6 in r0, 0x37 ; 55 + 7f3a: 00 fc sbrc r0, 0 + 7f3c: fd cf rjmp .-6 ; 0x7f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7f44: f7 be out 0x37, r15 ; 55 - 7f46: e8 95 spm - 7f48: 27 c0 rjmp .+78 ; 0x7f98 + 7f3e: 97 be out 0x37, r9 ; 55 + 7f40: e8 95 spm + 7f42: 26 c0 rjmp .+76 ; 0x7f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 7f4a: 84 37 cpi r24, 0x74 ; 116 - 7f4c: b9 f4 brne .+46 ; 0x7f7c + 7f44: 84 37 cpi r24, 0x74 ; 116 + 7f46: b1 f4 brne .+44 ; 0x7f74 // READ PAGE - we only read flash - getLen(); - 7f4e: 37 d0 rcall .+110 ; 0x7fbe + getch(); /* getlen() */ + 7f48: 2e d0 rcall .+92 ; 0x7fa6 + length = getch(); + 7f4a: 2d d0 rcall .+90 ; 0x7fa6 + 7f4c: f8 2e mov r15, r24 + getch(); + 7f4e: 2b d0 rcall .+86 ; 0x7fa6 + verifySpace(); - 7f50: 46 d0 rcall .+140 ; 0x7fde + 7f50: 3c d0 rcall .+120 ; 0x7fca + 7f52: f6 01 movw r30, r12 + 7f54: ef 2c mov r14, r15 putch(result); address++; } while (--length); #else do putch(pgm_read_byte_near(address++)); - 7f52: e0 91 00 02 lds r30, 0x0200 - 7f56: f0 91 01 02 lds r31, 0x0201 - 7f5a: 31 96 adiw r30, 0x01 ; 1 - 7f5c: f0 93 01 02 sts 0x0201, r31 - 7f60: e0 93 00 02 sts 0x0200, r30 - 7f64: 31 97 sbiw r30, 0x01 ; 1 - 7f66: e4 91 lpm r30, Z+ - 7f68: 8e 2f mov r24, r30 - 7f6a: 19 d0 rcall .+50 ; 0x7f9e + 7f56: 8f 01 movw r16, r30 + 7f58: 0f 5f subi r16, 0xFF ; 255 + 7f5a: 1f 4f sbci r17, 0xFF ; 255 + 7f5c: 84 91 lpm r24, Z+ + 7f5e: 1b d0 rcall .+54 ; 0x7f96 while (--length); - 7f6c: 80 91 02 02 lds r24, 0x0202 - 7f70: 81 50 subi r24, 0x01 ; 1 - 7f72: 80 93 02 02 sts 0x0202, r24 - 7f76: 88 23 and r24, r24 - 7f78: 61 f7 brne .-40 ; 0x7f52 - 7f7a: 0e c0 rjmp .+28 ; 0x7f98 + 7f60: ea 94 dec r14 + 7f62: f8 01 movw r30, r16 + 7f64: c1 f7 brne .-16 ; 0x7f56 +#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) { + 7f66: 08 94 sec + 7f68: c1 1c adc r12, r1 + 7f6a: d1 1c adc r13, r1 + 7f6c: fa 94 dec r15 + 7f6e: cf 0c add r12, r15 + 7f70: d1 1c adc r13, r1 + 7f72: 0e c0 rjmp .+28 ; 0x7f90 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 7f7c: 85 37 cpi r24, 0x75 ; 117 - 7f7e: 39 f4 brne .+14 ; 0x7f8e + 7f74: 85 37 cpi r24, 0x75 ; 117 + 7f76: 39 f4 brne .+14 ; 0x7f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 7f80: 2e d0 rcall .+92 ; 0x7fde + 7f78: 28 d0 rcall .+80 ; 0x7fca putch(SIGNATURE_0); - 7f82: 8e e1 ldi r24, 0x1E ; 30 - 7f84: 0c d0 rcall .+24 ; 0x7f9e + 7f7a: 8e e1 ldi r24, 0x1E ; 30 + 7f7c: 0c d0 rcall .+24 ; 0x7f96 putch(SIGNATURE_1); - 7f86: 85 e9 ldi r24, 0x95 ; 149 - 7f88: 0a d0 rcall .+20 ; 0x7f9e + 7f7e: 85 e9 ldi r24, 0x95 ; 149 + 7f80: 0a d0 rcall .+20 ; 0x7f96 putch(SIGNATURE_2); - 7f8a: 8f e0 ldi r24, 0x0F ; 15 - 7f8c: 8b cf rjmp .-234 ; 0x7ea4 + 7f82: 8f e0 ldi r24, 0x0F ; 15 + 7f84: 7a cf rjmp .-268 ; 0x7e7a } else if (ch == 'Q') { - 7f8e: 81 35 cpi r24, 0x51 ; 81 - 7f90: 11 f4 brne .+4 ; 0x7f96 + 7f86: 81 35 cpi r24, 0x51 ; 81 + 7f88: 11 f4 brne .+4 ; 0x7f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 7f92: 88 e0 ldi r24, 0x08 ; 8 - 7f94: 19 d0 rcall .+50 ; 0x7fc8 + 7f8a: 88 e0 ldi r24, 0x08 ; 8 + 7f8c: 18 d0 rcall .+48 ; 0x7fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 7f96: 23 d0 rcall .+70 ; 0x7fde + 7f8e: 1d d0 rcall .+58 ; 0x7fca } putch(STK_OK); - 7f98: 80 e1 ldi r24, 0x10 ; 16 - 7f9a: 01 d0 rcall .+2 ; 0x7f9e - 7f9c: 5c cf rjmp .-328 ; 0x7e56 + 7f90: 80 e1 ldi r24, 0x10 ; 16 + 7f92: 01 d0 rcall .+2 ; 0x7f96 + 7f94: 65 cf rjmp .-310 ; 0x7e60 -00007f9e : +00007f96 : } } void putch(char ch) { - 7f9e: 98 2f mov r25, r24 + 7f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 7fa0: 80 91 c0 00 lds r24, 0x00C0 - 7fa4: 85 ff sbrs r24, 5 - 7fa6: fc cf rjmp .-8 ; 0x7fa0 + 7f98: 80 91 c0 00 lds r24, 0x00C0 + 7f9c: 85 ff sbrs r24, 5 + 7f9e: fc cf rjmp .-8 ; 0x7f98 UDR0 = ch; - 7fa8: 90 93 c6 00 sts 0x00C6, r25 + 7fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 7fac: 08 95 ret + 7fa4: 08 95 ret -00007fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 7fae: a8 95 wdr +00007fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 7fb0: 80 91 c0 00 lds r24, 0x00C0 - 7fb4: 87 ff sbrs r24, 7 - 7fb6: fc cf rjmp .-8 ; 0x7fb0 + while(!(UCSR0A & _BV(RXC0))) + 7fa6: 80 91 c0 00 lds r24, 0x00C0 + 7faa: 87 ff sbrs r24, 7 + 7fac: fc cf rjmp .-8 ; 0x7fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 7fae: 80 91 c0 00 lds r24, 0x00C0 + 7fb2: 84 fd sbrc r24, 4 + 7fb4: 01 c0 rjmp .+2 ; 0x7fb8 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 7fb6: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; 7fb8: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH LED_PIN |= _BV(LED); +#endif #endif return ch; } 7fbc: 08 95 ret -00007fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 7fbe: f7 df rcall .-18 ; 0x7fae - length = getch(); - 7fc0: f6 df rcall .-20 ; 0x7fae - 7fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 7fc6: f3 cf rjmp .-26 ; 0x7fae - -00007fc8 : +00007fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 7fc8: e0 e6 ldi r30, 0x60 ; 96 - 7fca: f0 e0 ldi r31, 0x00 ; 0 - 7fcc: 98 e1 ldi r25, 0x18 ; 24 - 7fce: 90 83 st Z, r25 + 7fbe: e0 e6 ldi r30, 0x60 ; 96 + 7fc0: f0 e0 ldi r31, 0x00 ; 0 + 7fc2: 98 e1 ldi r25, 0x18 ; 24 + 7fc4: 90 83 st Z, r25 WDTCSR = x; - 7fd0: 80 83 st Z, r24 + 7fc6: 80 83 st Z, r24 } - 7fd2: 08 95 ret + 7fc8: 08 95 ret -00007fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 7fd4: 80 e0 ldi r24, 0x00 ; 0 - 7fd6: f8 df rcall .-16 ; 0x7fc8 - __asm__ __volatile__ ( - 7fd8: ee 27 eor r30, r30 - 7fda: ff 27 eor r31, r31 - 7fdc: 09 94 ijmp - -00007fde : +00007fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 7fde: e7 df rcall .-50 ; 0x7fae - 7fe0: 80 32 cpi r24, 0x20 ; 32 - 7fe2: 09 f0 breq .+2 ; 0x7fe6 - 7fe4: f7 df rcall .-18 ; 0x7fd4 + if (getch() != CRC_EOP) { + 7fca: ed df rcall .-38 ; 0x7fa6 + 7fcc: 80 32 cpi r24, 0x20 ; 32 + 7fce: 19 f0 breq .+6 ; 0x7fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 7fd0: 88 e0 ldi r24, 0x08 ; 8 + 7fd2: f5 df rcall .-22 ; 0x7fbe + 7fd4: ff cf rjmp .-2 ; 0x7fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 7fe6: 84 e1 ldi r24, 0x14 ; 20 + 7fd6: 84 e1 ldi r24, 0x14 ; 20 } - 7fe8: da cf rjmp .-76 ; 0x7f9e + 7fd8: de cf rjmp .-68 ; 0x7f96 + +00007fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 7fea: 1f 93 push r17 - 7fec: 18 2f mov r17, r24 - -00007fee : + 7fda: 1f 93 push r17 + 7fdc: 18 2f mov r17, r24 do getch(); while (--count); - 7fee: df df rcall .-66 ; 0x7fae - 7ff0: 11 50 subi r17, 0x01 ; 1 - 7ff2: e9 f7 brne .-6 ; 0x7fee + 7fde: e3 df rcall .-58 ; 0x7fa6 + 7fe0: 11 50 subi r17, 0x01 ; 1 + 7fe2: e9 f7 brne .-6 ; 0x7fde verifySpace(); - 7ff4: f4 df rcall .-24 ; 0x7fde + 7fe4: f2 df rcall .-28 ; 0x7fca } - 7ff6: 1f 91 pop r17 - 7ff8: 08 95 ret + 7fe6: 1f 91 pop r17 + 7fe8: 08 95 ret + +00007fea : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 7fea: 80 e0 ldi r24, 0x00 ; 0 + 7fec: e8 df rcall .-48 ; 0x7fbe + __asm__ __volatile__ ( + 7fee: ee 27 eor r30, r30 + 7ff0: ff 27 eor r31, r31 + 7ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex b/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex index e10281d..96850d3 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex +++ b/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex @@ -1,34 +1,35 @@ -:10FC000084B714BE81FFE6D085E08093810082E056 -:10FC10008093C00088E18093C10086E08093C20099 -:10FC200080E18093C4008EE0CFD0209A86E020E36C -:10FC30003CEF91E0309385002093840096BBB09B0D -:10FC4000FECF189AA8958150A9F7DD24D394A5E09A -:10FC5000EA2EF1E1FF2EABD0813421F481E0C5D052 -:10FC600083E020C0823411F484E103C0853419F4A8 -:10FC700085E0BBD091C0853581F499D0082F10E084 -:10FC800096D090E0982F8827802B912B880F991F72 -:10FC900090930103809300037EC0863529F484E0AD -:10FCA000A4D080E07CD078C0843609F04EC087D0E4 -:10FCB000E0910003F091010380EEE030F80718F4C2 -:10FCC00083E087BFE895C0E0D1E071D0899380914F -:10FCD00002038150809302038823B9F7E091000367 -:10FCE000F091010380EEE030F80718F083E087BF61 -:10FCF000E89575D007B600FCFDCF40910003509108 -:10FD00000103A0E0B1E02C9130E011968C911197A5 +:020000000404F6 +:10FC0000112484B714BE81FFF0D085E08093810079 +:10FC100082E08093C00088E18093C10086E08093F9 +:10FC2000C20080E18093C4008EE0C9D0209A86E0B3 +:10FC300020E33CEF91E0309385002093840096BB55 +:10FC4000B09BFECF189AA8958150A9F7CC24DD244B +:10FC500088248394B5E0AB2EA1E19A2EF3E0BF2E69 +:10FC6000A2D0813461F49FD0082FAFD0023811F0B8 +:10FC7000013811F484E001C083E08DD089C0823462 +:10FC800011F484E103C0853419F485E0A6D080C066 +:10FC9000853579F488D0E82EFF2485D0082F10E030 +:10FCA000102F00270E291F29000F111F8ED0680169 +:10FCB0006FC0863521F484E090D080E0DECF8436BA +:10FCC00009F040C070D06FD0082F6DD080E0C8160A +:10FCD00080EED80618F4F601B7BEE895C0E0D1E092 +:10FCE00062D089930C17E1F7F0E0CF16F0EEDF0653 +:10FCF00018F0F601B7BEE89568D007B600FCFDCF56 +:10FD0000A601A0E0B1E02C9130E011968C91119702 :10FD100090E0982F8827822B932B1296FA010C01E2 -:10FD2000D7BEE89511244E5F5F4FF2E0A030BF07C9 -:10FD300051F7E0910003F0910103E7BEE89507B6A3 -:10FD400000FCFDCFF7BEE89527C08437B9F437D063 -:10FD500046D0E0910003F09101033196F093010346 -:10FD6000E09300033197E4918E2F19D08091020324 -:10FD7000815080930203882361F70EC0853739F4E0 -:10FD80002ED08EE10CD086E90AD08AE08BCF813567 -:10FD900011F488E019D023D080E101D05CCF982FF6 -:10FDA0008091C00085FFFCCF9093C6000895A89570 -:10FDB0008091C00087FFFCCF8091C6000895F7DFD7 -:10FDC000F6DF80930203F3CFE0E6F0E098E1908362 -:10FDD0008083089580E0F8DFEE27FF270994E7DFAE -:10FDE000803209F0F7DF84E1DACF1F93182FDFDFCD -:0AFDF0001150E9F7F4DF1F910895A8 +:10FD200087BEE89511244E5F5F4FF2E0A030BF0719 +:10FD300051F7F601A7BEE89507B600FCFDCF97BEC8 +:10FD4000E89526C08437B1F42ED02DD0F82E2BD0D4 +:10FD50003CD0F601EF2C8F010F5F1F4F84911BD019 +:10FD6000EA94F801C1F70894C11CD11CFA94CF0C95 +:10FD7000D11C0EC0853739F428D08EE10CD086E92D +:10FD80000AD089E07ACF813511F488E018D01DD0EF +:10FD900080E101D065CF982F8091C00085FFFCCF16 +:10FDA0009093C60008958091C00087FFFCCF80919A +:10FDB000C00084FD01C0A8958091C6000895E0E6CA +:10FDC000F0E098E1908380830895EDDF803219F0B0 +:10FDD00088E0F5DFFFCF84E1DECF1F93182FE3DF4C +:10FDE0001150E9F7F2DF1F91089580E0E8DFEE2778 +:04FDF000FF2709944C :040000030000FC00FD :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst b/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst index 9fd2a21..c0c844f 100644 --- a/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst +++ b/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst @@ -3,25 +3,27 @@ optiboot_atmega644p.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 0000fc00 0000fc00 00000054 2**1 + 0 .text 000001f4 0000fc00 0000fc00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .debug_aranges 00000028 00000000 00000000 00000248 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 2 .debug_pubnames 0000005f 00000000 00000000 00000270 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 3 .debug_info 000002a8 00000000 00000000 000002cf 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 4 .debug_abbrev 00000178 00000000 00000000 00000577 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 5 .debug_line 0000046b 00000000 00000000 000006ef 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 6 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 7 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 8 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 9 .version 00000002 00000000 00000000 00000ff7 2**0 + CONTENTS, READONLY + 10 .debug_ranges 00000078 00000000 00000000 00000ff9 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - fc00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + fc00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif // Adaboot no-wait mod ch = MCUSR; + fc02: 84 b7 in r24, 0x34 ; 52 MCUSR = 0; - fc02: 14 be out 0x34, r1 ; 52 + fc04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - fc04: 81 ff sbrs r24, 1 - fc06: e6 d0 rcall .+460 ; 0xfdd4 + fc06: 81 ff sbrs r24, 1 + fc08: f0 d0 rcall .+480 ; 0xfdea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - fc08: 85 e0 ldi r24, 0x05 ; 5 - fc0a: 80 93 81 00 sts 0x0081, r24 + fc0a: 85 e0 ldi r24, 0x05 ; 5 + fc0c: 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 - fc0e: 82 e0 ldi r24, 0x02 ; 2 - fc10: 80 93 c0 00 sts 0x00C0, r24 + fc10: 82 e0 ldi r24, 0x02 ; 2 + fc12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - fc14: 88 e1 ldi r24, 0x18 ; 24 - fc16: 80 93 c1 00 sts 0x00C1, r24 + fc16: 88 e1 ldi r24, 0x18 ; 24 + fc18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - fc1a: 86 e0 ldi r24, 0x06 ; 6 - fc1c: 80 93 c2 00 sts 0x00C2, r24 + fc1c: 86 e0 ldi r24, 0x06 ; 6 + fc1e: 80 93 c2 00 sts 0x00C2, r24 UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - fc20: 80 e1 ldi r24, 0x10 ; 16 - fc22: 80 93 c4 00 sts 0x00C4, r24 + fc22: 80 e1 ldi r24, 0x10 ; 16 + fc24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - fc26: 8e e0 ldi r24, 0x0E ; 14 - fc28: cf d0 rcall .+414 ; 0xfdc8 + fc28: 8e e0 ldi r24, 0x0E ; 14 + fc2a: c9 d0 rcall .+402 ; 0xfdbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - fc2a: 20 9a sbi 0x04, 0 ; 4 - fc2c: 86 e0 ldi r24, 0x06 ; 6 + fc2c: 20 9a sbi 0x04, 0 ; 4 + fc2e: 86 e0 ldi r24, 0x06 ; 6 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - fc2e: 20 e3 ldi r18, 0x30 ; 48 - fc30: 3c ef ldi r19, 0xFC ; 252 + fc30: 20 e3 ldi r18, 0x30 ; 48 + fc32: 3c ef ldi r19, 0xFC ; 252 TIFR1 = _BV(TOV1); - fc32: 91 e0 ldi r25, 0x01 ; 1 + fc34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - fc34: 30 93 85 00 sts 0x0085, r19 - fc38: 20 93 84 00 sts 0x0084, r18 + fc36: 30 93 85 00 sts 0x0085, r19 + fc3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - fc3c: 96 bb out 0x16, r25 ; 22 + fc3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - fc3e: b0 9b sbis 0x16, 0 ; 22 - fc40: fe cf rjmp .-4 ; 0xfc3e + fc40: b0 9b sbis 0x16, 0 ; 22 + fc42: fe cf rjmp .-4 ; 0xfc40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - fc42: 18 9a sbi 0x03, 0 ; 3 - return getch(); + fc44: 18 9a sbi 0x03, 0 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - fc44: a8 95 wdr + fc46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - fc46: 81 50 subi r24, 0x01 ; 1 - fc48: a9 f7 brne .-22 ; 0xfc34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - fc4a: dd 24 eor r13, r13 - fc4c: d3 94 inc r13 + fc48: 81 50 subi r24, 0x01 ; 1 + fc4a: a9 f7 brne .-22 ; 0xfc36 + fc4c: cc 24 eor r12, r12 + fc4e: 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); + fc50: 88 24 eor r8, r8 + fc52: 83 94 inc r8 addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - fc4e: a5 e0 ldi r26, 0x05 ; 5 - fc50: ea 2e mov r14, r26 + fc54: b5 e0 ldi r27, 0x05 ; 5 + fc56: ab 2e mov r10, r27 boot_spm_busy_wait(); #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - fc52: f1 e1 ldi r31, 0x11 ; 17 - fc54: ff 2e mov r15, r31 + fc58: a1 e1 ldi r26, 0x11 ; 17 + fc5a: 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); + fc5c: f3 e0 ldi r31, 0x03 ; 3 + fc5e: bf 2e mov r11, r31 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - fc56: ab d0 rcall .+342 ; 0xfdae + fc60: a2 d0 rcall .+324 ; 0xfda6 if(ch == STK_GET_PARAMETER) { - fc58: 81 34 cpi r24, 0x41 ; 65 - fc5a: 21 f4 brne .+8 ; 0xfc64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - fc5c: 81 e0 ldi r24, 0x01 ; 1 - fc5e: c5 d0 rcall .+394 ; 0xfdea - putch(0x03); - fc60: 83 e0 ldi r24, 0x03 ; 3 - fc62: 20 c0 rjmp .+64 ; 0xfca4 + fc62: 81 34 cpi r24, 0x41 ; 65 + fc64: 61 f4 brne .+24 ; 0xfc7e + unsigned char which = getch(); + fc66: 9f d0 rcall .+318 ; 0xfda6 + fc68: 08 2f mov r16, r24 + verifySpace(); + fc6a: af d0 rcall .+350 ; 0xfdca + if (which == 0x82) { + fc6c: 02 38 cpi r16, 0x82 ; 130 + fc6e: 11 f0 breq .+4 ; 0xfc74 + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + fc70: 01 38 cpi r16, 0x81 ; 129 + fc72: 11 f4 brne .+4 ; 0xfc78 + putch(OPTIBOOT_MAJVER); + fc74: 84 e0 ldi r24, 0x04 ; 4 + fc76: 01 c0 rjmp .+2 ; 0xfc7a + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + fc78: 83 e0 ldi r24, 0x03 ; 3 + fc7a: 8d d0 rcall .+282 ; 0xfd96 + fc7c: 89 c0 rjmp .+274 ; 0xfd90 + } } else if(ch == STK_SET_DEVICE) { - fc64: 82 34 cpi r24, 0x42 ; 66 - fc66: 11 f4 brne .+4 ; 0xfc6c + fc7e: 82 34 cpi r24, 0x42 ; 66 + fc80: 11 f4 brne .+4 ; 0xfc86 // SET DEVICE is ignored getNch(20); - fc68: 84 e1 ldi r24, 0x14 ; 20 - fc6a: 03 c0 rjmp .+6 ; 0xfc72 + fc82: 84 e1 ldi r24, 0x14 ; 20 + fc84: 03 c0 rjmp .+6 ; 0xfc8c } else if(ch == STK_SET_DEVICE_EXT) { - fc6c: 85 34 cpi r24, 0x45 ; 69 - fc6e: 19 f4 brne .+6 ; 0xfc76 + fc86: 85 34 cpi r24, 0x45 ; 69 + fc88: 19 f4 brne .+6 ; 0xfc90 // SET DEVICE EXT is ignored getNch(5); - fc70: 85 e0 ldi r24, 0x05 ; 5 - fc72: bb d0 rcall .+374 ; 0xfdea - fc74: 91 c0 rjmp .+290 ; 0xfd98 + fc8a: 85 e0 ldi r24, 0x05 ; 5 + fc8c: a6 d0 rcall .+332 ; 0xfdda + fc8e: 80 c0 rjmp .+256 ; 0xfd90 } else if(ch == STK_LOAD_ADDRESS) { - fc76: 85 35 cpi r24, 0x55 ; 85 - fc78: 81 f4 brne .+32 ; 0xfc9a + fc90: 85 35 cpi r24, 0x55 ; 85 + fc92: 79 f4 brne .+30 ; 0xfcb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - fc7a: 99 d0 rcall .+306 ; 0xfdae + fc94: 88 d0 rcall .+272 ; 0xfda6 newAddress = (newAddress & 0xff) | (getch() << 8); - fc7c: 08 2f mov r16, r24 - fc7e: 10 e0 ldi r17, 0x00 ; 0 - fc80: 96 d0 rcall .+300 ; 0xfdae - fc82: 90 e0 ldi r25, 0x00 ; 0 - fc84: 98 2f mov r25, r24 - fc86: 88 27 eor r24, r24 - fc88: 80 2b or r24, r16 - fc8a: 91 2b or r25, r17 + fc96: e8 2e mov r14, r24 + fc98: ff 24 eor r15, r15 + fc9a: 85 d0 rcall .+266 ; 0xfda6 + fc9c: 08 2f mov r16, r24 + fc9e: 10 e0 ldi r17, 0x00 ; 0 + fca0: 10 2f mov r17, r16 + fca2: 00 27 eor r16, r16 + fca4: 0e 29 or r16, r14 + fca6: 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 - fc8c: 88 0f add r24, r24 - fc8e: 99 1f adc r25, r25 + fca8: 00 0f add r16, r16 + fcaa: 11 1f adc r17, r17 address = newAddress; - fc90: 90 93 01 03 sts 0x0301, r25 - fc94: 80 93 00 03 sts 0x0300, r24 - fc98: 7e c0 rjmp .+252 ; 0xfd96 verifySpace(); + fcac: 8e d0 rcall .+284 ; 0xfdca + fcae: 68 01 movw r12, r16 + fcb0: 6f c0 rjmp .+222 ; 0xfd90 } else if(ch == STK_UNIVERSAL) { - fc9a: 86 35 cpi r24, 0x56 ; 86 - fc9c: 29 f4 brne .+10 ; 0xfca8 + fcb2: 86 35 cpi r24, 0x56 ; 86 + fcb4: 21 f4 brne .+8 ; 0xfcbe // UNIVERSAL command is ignored getNch(4); - fc9e: 84 e0 ldi r24, 0x04 ; 4 - fca0: a4 d0 rcall .+328 ; 0xfdea + fcb6: 84 e0 ldi r24, 0x04 ; 4 + fcb8: 90 d0 rcall .+288 ; 0xfdda putch(0x00); - fca2: 80 e0 ldi r24, 0x00 ; 0 - fca4: 7c d0 rcall .+248 ; 0xfd9e - fca6: 78 c0 rjmp .+240 ; 0xfd98 + fcba: 80 e0 ldi r24, 0x00 ; 0 + fcbc: de cf rjmp .-68 ; 0xfc7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - fca8: 84 36 cpi r24, 0x64 ; 100 - fcaa: 09 f0 breq .+2 ; 0xfcae - fcac: 4e c0 rjmp .+156 ; 0xfd4a + fcbe: 84 36 cpi r24, 0x64 ; 100 + fcc0: 09 f0 breq .+2 ; 0xfcc4 + fcc2: 40 c0 rjmp .+128 ; 0xfd44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - fcae: 87 d0 rcall .+270 ; 0xfdbe + getch(); /* getlen() */ + fcc4: 70 d0 rcall .+224 ; 0xfda6 + length = getch(); + fcc6: 6f d0 rcall .+222 ; 0xfda6 + fcc8: 08 2f mov r16, r24 + getch(); + fcca: 6d d0 rcall .+218 ; 0xfda6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - fcb0: e0 91 00 03 lds r30, 0x0300 - fcb4: f0 91 01 03 lds r31, 0x0301 - fcb8: 80 ee ldi r24, 0xE0 ; 224 - fcba: e0 30 cpi r30, 0x00 ; 0 - fcbc: f8 07 cpc r31, r24 - fcbe: 18 f4 brcc .+6 ; 0xfcc6 - fcc0: 83 e0 ldi r24, 0x03 ; 3 - fcc2: 87 bf out 0x37, r24 ; 55 - fcc4: e8 95 spm - fcc6: c0 e0 ldi r28, 0x00 ; 0 - fcc8: d1 e0 ldi r29, 0x01 ; 1 - + fccc: 80 e0 ldi r24, 0x00 ; 0 + fcce: c8 16 cp r12, r24 + fcd0: 80 ee ldi r24, 0xE0 ; 224 + fcd2: d8 06 cpc r13, r24 + fcd4: 18 f4 brcc .+6 ; 0xfcdc + fcd6: f6 01 movw r30, r12 + fcd8: b7 be out 0x37, r11 ; 55 + fcda: e8 95 spm + fcdc: c0 e0 ldi r28, 0x00 ; 0 + fcde: d1 e0 ldi r29, 0x01 ; 1 + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - fcca: 71 d0 rcall .+226 ; 0xfdae - fccc: 89 93 st Y+, r24 + fce0: 62 d0 rcall .+196 ; 0xfda6 + fce2: 89 93 st Y+, r24 while (--length); - fcce: 80 91 02 03 lds r24, 0x0302 - fcd2: 81 50 subi r24, 0x01 ; 1 - fcd4: 80 93 02 03 sts 0x0302, r24 - fcd8: 88 23 and r24, r24 - fcda: b9 f7 brne .-18 ; 0xfcca + fce4: 0c 17 cp r16, r28 + fce6: e1 f7 brne .-8 ; 0xfce0 // 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); - fcdc: e0 91 00 03 lds r30, 0x0300 - fce0: f0 91 01 03 lds r31, 0x0301 - fce4: 80 ee ldi r24, 0xE0 ; 224 - fce6: e0 30 cpi r30, 0x00 ; 0 - fce8: f8 07 cpc r31, r24 - fcea: 18 f0 brcs .+6 ; 0xfcf2 - fcec: 83 e0 ldi r24, 0x03 ; 3 - fcee: 87 bf out 0x37, r24 ; 55 - fcf0: e8 95 spm + fce8: f0 e0 ldi r31, 0x00 ; 0 + fcea: cf 16 cp r12, r31 + fcec: f0 ee ldi r31, 0xE0 ; 224 + fcee: df 06 cpc r13, r31 + fcf0: 18 f0 brcs .+6 ; 0xfcf8 + fcf2: f6 01 movw r30, r12 + fcf4: b7 be out 0x37, r11 ; 55 + fcf6: e8 95 spm // Read command terminator, start reply verifySpace(); - fcf2: 75 d0 rcall .+234 ; 0xfdde - + fcf8: 68 d0 rcall .+208 ; 0xfdca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - fcf4: 07 b6 in r0, 0x37 ; 55 - fcf6: 00 fc sbrc r0, 0 - fcf8: fd cf rjmp .-6 ; 0xfcf4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - fcfa: 40 91 00 03 lds r20, 0x0300 - fcfe: 50 91 01 03 lds r21, 0x0301 + fcfa: 07 b6 in r0, 0x37 ; 55 + fcfc: 00 fc sbrc r0, 0 + fcfe: fd cf rjmp .-6 ; 0xfcfa + fd00: a6 01 movw r20, r12 fd02: a0 e0 ldi r26, 0x00 ; 0 fd04: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; ch = SPM_PAGESIZE / 2; do { uint16_t a; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); fd1c: fa 01 movw r30, r20 fd1e: 0c 01 movw r0, r24 - fd20: d7 be out 0x37, r13 ; 55 + fd20: 87 be out 0x37, r8 ; 55 fd22: e8 95 spm fd24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { fd2c: a0 30 cpi r26, 0x00 ; 0 fd2e: bf 07 cpc r27, r31 fd30: 51 f7 brne .-44 ; 0xfd06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - fd32: e0 91 00 03 lds r30, 0x0300 - fd36: f0 91 01 03 lds r31, 0x0301 - fd3a: e7 be out 0x37, r14 ; 55 - fd3c: e8 95 spm + fd32: f6 01 movw r30, r12 + fd34: a7 be out 0x37, r10 ; 55 + fd36: e8 95 spm boot_spm_busy_wait(); - fd3e: 07 b6 in r0, 0x37 ; 55 - fd40: 00 fc sbrc r0, 0 - fd42: fd cf rjmp .-6 ; 0xfd3e + fd38: 07 b6 in r0, 0x37 ; 55 + fd3a: 00 fc sbrc r0, 0 + fd3c: fd cf rjmp .-6 ; 0xfd38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - fd44: f7 be out 0x37, r15 ; 55 - fd46: e8 95 spm - fd48: 27 c0 rjmp .+78 ; 0xfd98 + fd3e: 97 be out 0x37, r9 ; 55 + fd40: e8 95 spm + fd42: 26 c0 rjmp .+76 ; 0xfd90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - fd4a: 84 37 cpi r24, 0x74 ; 116 - fd4c: b9 f4 brne .+46 ; 0xfd7c + fd44: 84 37 cpi r24, 0x74 ; 116 + fd46: b1 f4 brne .+44 ; 0xfd74 // READ PAGE - we only read flash - getLen(); - fd4e: 37 d0 rcall .+110 ; 0xfdbe + getch(); /* getlen() */ + fd48: 2e d0 rcall .+92 ; 0xfda6 + length = getch(); + fd4a: 2d d0 rcall .+90 ; 0xfda6 + fd4c: f8 2e mov r15, r24 + getch(); + fd4e: 2b d0 rcall .+86 ; 0xfda6 + verifySpace(); - fd50: 46 d0 rcall .+140 ; 0xfdde + fd50: 3c d0 rcall .+120 ; 0xfdca + fd52: f6 01 movw r30, r12 + fd54: ef 2c mov r14, r15 putch(result); address++; } while (--length); #else do putch(pgm_read_byte_near(address++)); - fd52: e0 91 00 03 lds r30, 0x0300 - fd56: f0 91 01 03 lds r31, 0x0301 - fd5a: 31 96 adiw r30, 0x01 ; 1 - fd5c: f0 93 01 03 sts 0x0301, r31 - fd60: e0 93 00 03 sts 0x0300, r30 - fd64: 31 97 sbiw r30, 0x01 ; 1 - fd66: e4 91 lpm r30, Z+ - fd68: 8e 2f mov r24, r30 - fd6a: 19 d0 rcall .+50 ; 0xfd9e + fd56: 8f 01 movw r16, r30 + fd58: 0f 5f subi r16, 0xFF ; 255 + fd5a: 1f 4f sbci r17, 0xFF ; 255 + fd5c: 84 91 lpm r24, Z+ + fd5e: 1b d0 rcall .+54 ; 0xfd96 while (--length); - fd6c: 80 91 02 03 lds r24, 0x0302 - fd70: 81 50 subi r24, 0x01 ; 1 - fd72: 80 93 02 03 sts 0x0302, r24 - fd76: 88 23 and r24, r24 - fd78: 61 f7 brne .-40 ; 0xfd52 - fd7a: 0e c0 rjmp .+28 ; 0xfd98 + fd60: ea 94 dec r14 + fd62: f8 01 movw r30, r16 + fd64: c1 f7 brne .-16 ; 0xfd56 +#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) { + fd66: 08 94 sec + fd68: c1 1c adc r12, r1 + fd6a: d1 1c adc r13, r1 + fd6c: fa 94 dec r15 + fd6e: cf 0c add r12, r15 + fd70: d1 1c adc r13, r1 + fd72: 0e c0 rjmp .+28 ; 0xfd90 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - fd7c: 85 37 cpi r24, 0x75 ; 117 - fd7e: 39 f4 brne .+14 ; 0xfd8e + fd74: 85 37 cpi r24, 0x75 ; 117 + fd76: 39 f4 brne .+14 ; 0xfd86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - fd80: 2e d0 rcall .+92 ; 0xfdde + fd78: 28 d0 rcall .+80 ; 0xfdca putch(SIGNATURE_0); - fd82: 8e e1 ldi r24, 0x1E ; 30 - fd84: 0c d0 rcall .+24 ; 0xfd9e + fd7a: 8e e1 ldi r24, 0x1E ; 30 + fd7c: 0c d0 rcall .+24 ; 0xfd96 putch(SIGNATURE_1); - fd86: 86 e9 ldi r24, 0x96 ; 150 - fd88: 0a d0 rcall .+20 ; 0xfd9e + fd7e: 86 e9 ldi r24, 0x96 ; 150 + fd80: 0a d0 rcall .+20 ; 0xfd96 putch(SIGNATURE_2); - fd8a: 8a e0 ldi r24, 0x0A ; 10 - fd8c: 8b cf rjmp .-234 ; 0xfca4 + fd82: 89 e0 ldi r24, 0x09 ; 9 + fd84: 7a cf rjmp .-268 ; 0xfc7a } else if (ch == 'Q') { - fd8e: 81 35 cpi r24, 0x51 ; 81 - fd90: 11 f4 brne .+4 ; 0xfd96 + fd86: 81 35 cpi r24, 0x51 ; 81 + fd88: 11 f4 brne .+4 ; 0xfd8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - fd92: 88 e0 ldi r24, 0x08 ; 8 - fd94: 19 d0 rcall .+50 ; 0xfdc8 + fd8a: 88 e0 ldi r24, 0x08 ; 8 + fd8c: 18 d0 rcall .+48 ; 0xfdbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - fd96: 23 d0 rcall .+70 ; 0xfdde + fd8e: 1d d0 rcall .+58 ; 0xfdca } putch(STK_OK); - fd98: 80 e1 ldi r24, 0x10 ; 16 - fd9a: 01 d0 rcall .+2 ; 0xfd9e - fd9c: 5c cf rjmp .-328 ; 0xfc56 + fd90: 80 e1 ldi r24, 0x10 ; 16 + fd92: 01 d0 rcall .+2 ; 0xfd96 + fd94: 65 cf rjmp .-310 ; 0xfc60 -0000fd9e : +0000fd96 : } } void putch(char ch) { - fd9e: 98 2f mov r25, r24 + fd96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - fda0: 80 91 c0 00 lds r24, 0x00C0 - fda4: 85 ff sbrs r24, 5 - fda6: fc cf rjmp .-8 ; 0xfda0 + fd98: 80 91 c0 00 lds r24, 0x00C0 + fd9c: 85 ff sbrs r24, 5 + fd9e: fc cf rjmp .-8 ; 0xfd98 UDR0 = ch; - fda8: 90 93 c6 00 sts 0x00C6, r25 + fda0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - fdac: 08 95 ret + fda4: 08 95 ret -0000fdae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - fdae: a8 95 wdr +0000fda6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - fdb0: 80 91 c0 00 lds r24, 0x00C0 - fdb4: 87 ff sbrs r24, 7 - fdb6: fc cf rjmp .-8 ; 0xfdb0 + while(!(UCSR0A & _BV(RXC0))) + fda6: 80 91 c0 00 lds r24, 0x00C0 + fdaa: 87 ff sbrs r24, 7 + fdac: fc cf rjmp .-8 ; 0xfda6 + ; + if (!(UCSR0A & _BV(FE0))) { + fdae: 80 91 c0 00 lds r24, 0x00C0 + fdb2: 84 fd sbrc r24, 4 + fdb4: 01 c0 rjmp .+2 ; 0xfdb8 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + fdb6: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; fdb8: 80 91 c6 00 lds r24, 0x00C6 LED_PIN |= _BV(LED); @@ -474,79 +526,73 @@ void watchdogReset() { } fdbc: 08 95 ret -0000fdbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - fdbe: f7 df rcall .-18 ; 0xfdae - length = getch(); - fdc0: f6 df rcall .-20 ; 0xfdae - fdc2: 80 93 02 03 sts 0x0302, r24 - return getch(); -} - fdc6: f3 cf rjmp .-26 ; 0xfdae - -0000fdc8 : +0000fdbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - fdc8: e0 e6 ldi r30, 0x60 ; 96 - fdca: f0 e0 ldi r31, 0x00 ; 0 - fdcc: 98 e1 ldi r25, 0x18 ; 24 - fdce: 90 83 st Z, r25 + fdbe: e0 e6 ldi r30, 0x60 ; 96 + fdc0: f0 e0 ldi r31, 0x00 ; 0 + fdc2: 98 e1 ldi r25, 0x18 ; 24 + fdc4: 90 83 st Z, r25 WDTCSR = x; - fdd0: 80 83 st Z, r24 + fdc6: 80 83 st Z, r24 } - fdd2: 08 95 ret + fdc8: 08 95 ret -0000fdd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - fdd4: 80 e0 ldi r24, 0x00 ; 0 - fdd6: f8 df rcall .-16 ; 0xfdc8 - __asm__ __volatile__ ( - fdd8: ee 27 eor r30, r30 - fdda: ff 27 eor r31, r31 - fddc: 09 94 ijmp - -0000fdde : +0000fdca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - fdde: e7 df rcall .-50 ; 0xfdae - fde0: 80 32 cpi r24, 0x20 ; 32 - fde2: 09 f0 breq .+2 ; 0xfde6 - fde4: f7 df rcall .-18 ; 0xfdd4 + if (getch() != CRC_EOP) { + fdca: ed df rcall .-38 ; 0xfda6 + fdcc: 80 32 cpi r24, 0x20 ; 32 + fdce: 19 f0 breq .+6 ; 0xfdd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + fdd0: 88 e0 ldi r24, 0x08 ; 8 + fdd2: f5 df rcall .-22 ; 0xfdbe + fdd4: ff cf rjmp .-2 ; 0xfdd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - fde6: 84 e1 ldi r24, 0x14 ; 20 + fdd6: 84 e1 ldi r24, 0x14 ; 20 } - fde8: da cf rjmp .-76 ; 0xfd9e + fdd8: de cf rjmp .-68 ; 0xfd96 -0000fdea : +0000fdda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - fdea: 1f 93 push r17 - fdec: 18 2f mov r17, r24 + fdda: 1f 93 push r17 + fddc: 18 2f mov r17, r24 do getch(); while (--count); - fdee: df df rcall .-66 ; 0xfdae - fdf0: 11 50 subi r17, 0x01 ; 1 - fdf2: e9 f7 brne .-6 ; 0xfdee + fdde: e3 df rcall .-58 ; 0xfda6 + fde0: 11 50 subi r17, 0x01 ; 1 + fde2: e9 f7 brne .-6 ; 0xfdde verifySpace(); - fdf4: f4 df rcall .-24 ; 0xfdde + fde4: f2 df rcall .-28 ; 0xfdca } - fdf6: 1f 91 pop r17 - fdf8: 08 95 ret + fde6: 1f 91 pop r17 + fde8: 08 95 ret + +0000fdea : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + fdea: 80 e0 ldi r24, 0x00 ; 0 + fdec: e8 df rcall .-48 ; 0xfdbe + __asm__ __volatile__ ( + fdee: ee 27 eor r30, r30 + fdf0: ff 27 eor r31, r31 + fdf2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_lilypad.hex b/optiboot/bootloaders/optiboot/optiboot_lilypad.hex index 0d773dd..3cb2549 100644 --- a/optiboot/bootloaders/optiboot/optiboot_lilypad.hex +++ b/optiboot/bootloaders/optiboot/optiboot_lilypad.hex @@ -1,34 +1,35 @@ -:103E000084B714BE81FFE6D085E08093810082E014 -:103E10008093C00088E18093C10086E08093C20057 -:103E200088E08093C4008EE0CFD0259A86E028E118 -:103E30003EEF91E0309385002093840096BBB09BC9 -:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 -:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 -:103E600083E020C0823411F484E103C0853419F466 -:103E700085E0BBD091C0853581F499D0082F10E042 -:103E800096D090E0982F8827802B912B880F991F30 -:103E900090930102809300027EC0863529F484E06D -:103EA000A4D080E07CD078C0843609F04EC087D0A2 -:103EB000E0910002F091010288E3E030F80718F485 -:103EC00083E087BFE895C0E0D1E071D0899380910D -:103ED00002028150809302028823B9F7E091000228 -:103EE000F091010288E3E030F80718F083E087BF23 -:103EF000E89575D007B600FCFDCF409100025091C7 -:103F00000102A0E0B1E02C9130E011968C91119764 +:103E0000112484B714BE81FFF0D085E08093810037 +:103E100082E08093C00088E18093C10086E08093B7 +:103E2000C20088E08093C4008EE0C9D0259A86E065 +:103E300028E13EEF91E0309385002093840096BB0B +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27 +:103E6000A2D0813461F49FD0082FAFD0023811F076 +:103E7000013811F484E001C083E08DD089C0823420 +:103E800011F484E103C0853419F485E0A6D080C024 +:103E9000853579F488D0E82EFF2485D0082F10E0EE +:103EA000102F00270E291F29000F111F8ED0680127 +:103EB0006FC0863521F484E090D080E0DECF843678 +:103EC00009F040C070D06FD0082F6DD080E0C816C8 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14 +:103F0000A601A0E0B1E02C9130E011968C911197C0 :103F100090E0982F8827822B932B1296FA010C01A0 -:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 -:103F300051F7E0910002F0910102E7BEE89507B663 -:103F400000FCFDCFF7BEE89527C08437B9F437D021 -:103F500046D0E0910002F09101023196F093010207 -:103F6000E09300023197E4918E2F19D080910202E4 -:103F7000815080930202882361F70EC0853739F49F -:103F80002ED08EE10CD084E90AD086E08BCF81352B -:103F900011F488E019D023D080E101D05CCF982FB4 -:103FA0008091C00085FFFCCF9093C6000895A8952E -:103FB0008091C00087FFFCCF8091C6000895F7DF95 -:103FC000F6DF80930202F3CFE0E6F0E098E1908321 -:103FD0008083089580E0F8DFEE27FF270994E7DF6C -:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B -:0A3FF0001150E9F7F4DF1F91089566 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED +:103F80000AD086E07ACF813511F488E018D01DD0B0 +:103F900080E101D065CF982F8091C00085FFFCCFD4 +:103FA0009093C60008958091C00087FFFCCF809158 +:103FB000C00084FD01C0A8958091C6000895E0E688 +:103FC000F0E098E1908380830895EDDF803219F06E +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736 +:043FF000FF2709940A +:023FFE000404B9 :0400000300003E00BB :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_lilypad.lst b/optiboot/bootloaders/optiboot/optiboot_lilypad.lst index 1c7a497..5d15e9b 100644 --- a/optiboot/bootloaders/optiboot/optiboot_lilypad.lst +++ b/optiboot/bootloaders/optiboot/optiboot_lilypad.lst @@ -3,25 +3,27 @@ optiboot_lilypad.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00003e00 00003e00 00000054 2**1 + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 3e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 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; - 3e02: 14 be out 0x34, r1 ; 52 + 3e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 3e04: 81 ff sbrs r24, 1 - 3e06: e6 d0 rcall .+460 ; 0x3fd4 + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 3e08: 85 e0 ldi r24, 0x05 ; 5 - 3e0a: 80 93 81 00 sts 0x0081, r24 + 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 - 3e0e: 82 e0 ldi r24, 0x02 ; 2 - 3e10: 80 93 c0 00 sts 0x00C0, r24 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e14: 88 e1 ldi r24, 0x18 ; 24 - 3e16: 80 93 c1 00 sts 0x00C1, r24 + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e1a: 86 e0 ldi r24, 0x06 ; 6 - 3e1c: 80 93 c2 00 sts 0x00C2, r24 + 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 ); - 3e20: 88 e0 ldi r24, 0x08 ; 8 - 3e22: 80 93 c4 00 sts 0x00C4, r24 + 3e22: 88 e0 ldi r24, 0x08 ; 8 + 3e24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 3e26: 8e e0 ldi r24, 0x0E ; 14 - 3e28: cf d0 rcall .+414 ; 0x3fc8 + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 + 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)); - 3e2e: 28 e1 ldi r18, 0x18 ; 24 - 3e30: 3e ef ldi r19, 0xFE ; 254 + 3e30: 28 e1 ldi r18, 0x18 ; 24 + 3e32: 3e ef ldi r19, 0xFE ; 254 TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 + 3e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 + 3e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 3e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 3e44: a8 95 wdr + 3e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 + 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); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 + 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(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 + 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(); - 3e56: ab d0 rcall .+342 ; 0x3fae + 3e60: a2 d0 rcall .+324 ; 0x3fa6 if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: c5 d0 rcall .+394 ; 0x3fea - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 20 c0 rjmp .+64 ; 0x3ea4 + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 + /* + * 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 + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a + } 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 + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 + } } else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 // SET DEVICE is ignored getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c } else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 // SET DEVICE EXT is ignored getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: bb d0 rcall .+374 ; 0x3fea - 3e74: 91 c0 rjmp .+290 ; 0x3f98 + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 } else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: 81 f4 brne .+32 ; 0x3e9a + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 3e7a: 99 d0 rcall .+306 ; 0x3fae + 3e94: 88 d0 rcall .+272 ; 0x3fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 96 d0 rcall .+300 ; 0x3fae - 3e82: 90 e0 ldi r25, 0x00 ; 0 - 3e84: 98 2f mov r25, r24 - 3e86: 88 27 eor r24, r24 - 3e88: 80 2b or r24, r16 - 3e8a: 91 2b or r25, r17 + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 + 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 - 3e8c: 88 0f add r24, r24 - 3e8e: 99 1f adc r25, r25 + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 address = newAddress; - 3e90: 90 93 01 02 sts 0x0201, r25 - 3e94: 80 93 00 02 sts 0x0200, r24 - 3e98: 7e c0 rjmp .+252 ; 0x3f96 verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 } else if(ch == STK_UNIVERSAL) { - 3e9a: 86 35 cpi r24, 0x56 ; 86 - 3e9c: 29 f4 brne .+10 ; 0x3ea8 + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe // UNIVERSAL command is ignored getNch(4); - 3e9e: 84 e0 ldi r24, 0x04 ; 4 - 3ea0: a4 d0 rcall .+328 ; 0x3fea + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda putch(0x00); - 3ea2: 80 e0 ldi r24, 0x00 ; 0 - 3ea4: 7c d0 rcall .+248 ; 0x3f9e - 3ea6: 78 c0 rjmp .+240 ; 0x3f98 + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 3ea8: 84 36 cpi r24, 0x64 ; 100 - 3eaa: 09 f0 breq .+2 ; 0x3eae - 3eac: 4e c0 rjmp .+156 ; 0x3f4a + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 3eae: 87 d0 rcall .+270 ; 0x3fbe + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 3eb0: e0 91 00 02 lds r30, 0x0200 - 3eb4: f0 91 01 02 lds r31, 0x0201 - 3eb8: 88 e3 ldi r24, 0x38 ; 56 - 3eba: e0 30 cpi r30, 0x00 ; 0 - 3ebc: f8 07 cpc r31, r24 - 3ebe: 18 f4 brcc .+6 ; 0x3ec6 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 87 bf out 0x37, r24 ; 55 - 3ec4: e8 95 spm - 3ec6: c0 e0 ldi r28, 0x00 ; 0 - 3ec8: d1 e0 ldi r29, 0x01 ; 1 - + 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 + 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(); - 3eca: 71 d0 rcall .+226 ; 0x3fae - 3ecc: 89 93 st Y+, r24 + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 + 3ee2: 89 93 st Y+, r24 while (--length); - 3ece: 80 91 02 02 lds r24, 0x0202 - 3ed2: 81 50 subi r24, 0x01 ; 1 - 3ed4: 80 93 02 02 sts 0x0202, r24 - 3ed8: 88 23 and r24, r24 - 3eda: b9 f7 brne .-18 ; 0x3eca + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 // 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); - 3edc: e0 91 00 02 lds r30, 0x0200 - 3ee0: f0 91 01 02 lds r31, 0x0201 - 3ee4: 88 e3 ldi r24, 0x38 ; 56 - 3ee6: e0 30 cpi r30, 0x00 ; 0 - 3ee8: f8 07 cpc r31, r24 - 3eea: 18 f0 brcs .+6 ; 0x3ef2 - 3eec: 83 e0 ldi r24, 0x03 ; 3 - 3eee: 87 bf out 0x37, r24 ; 55 - 3ef0: e8 95 spm + 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 + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 3ef2: 75 d0 rcall .+234 ; 0x3fde - + 3ef8: 68 d0 rcall .+208 ; 0x3fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 3ef4: 07 b6 in r0, 0x37 ; 55 - 3ef6: 00 fc sbrc r0, 0 - 3ef8: fd cf rjmp .-6 ; 0x3ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3efa: 40 91 00 02 lds r20, 0x0200 - 3efe: 50 91 01 02 lds r21, 0x0201 + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa + 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; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 3f1c: fa 01 movw r30, r20 3f1e: 0c 01 movw r0, r24 - 3f20: d7 be out 0x37, r13 ; 55 + 3f20: 87 be out 0x37, r8 ; 55 3f22: e8 95 spm 3f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 3f2c: a0 38 cpi r26, 0x80 ; 128 3f2e: bf 07 cpc r27, r31 3f30: 51 f7 brne .-44 ; 0x3f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 3f32: e0 91 00 02 lds r30, 0x0200 - 3f36: f0 91 01 02 lds r31, 0x0201 - 3f3a: e7 be out 0x37, r14 ; 55 - 3f3c: e8 95 spm + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm boot_spm_busy_wait(); - 3f3e: 07 b6 in r0, 0x37 ; 55 - 3f40: 00 fc sbrc r0, 0 - 3f42: fd cf rjmp .-6 ; 0x3f3e + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 3f44: f7 be out 0x37, r15 ; 55 - 3f46: e8 95 spm - 3f48: 27 c0 rjmp .+78 ; 0x3f98 + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 3f4a: 84 37 cpi r24, 0x74 ; 116 - 3f4c: b9 f4 brne .+46 ; 0x3f7c + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 // READ PAGE - we only read flash - getLen(); - 3f4e: 37 d0 rcall .+110 ; 0x3fbe + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 + verifySpace(); - 3f50: 46 d0 rcall .+140 ; 0x3fde + 3f50: 3c d0 rcall .+120 ; 0x3fca + 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++)); - 3f52: e0 91 00 02 lds r30, 0x0200 - 3f56: f0 91 01 02 lds r31, 0x0201 - 3f5a: 31 96 adiw r30, 0x01 ; 1 - 3f5c: f0 93 01 02 sts 0x0201, r31 - 3f60: e0 93 00 02 sts 0x0200, r30 - 3f64: 31 97 sbiw r30, 0x01 ; 1 - 3f66: e4 91 lpm r30, Z+ - 3f68: 8e 2f mov r24, r30 - 3f6a: 19 d0 rcall .+50 ; 0x3f9e + 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 while (--length); - 3f6c: 80 91 02 02 lds r24, 0x0202 - 3f70: 81 50 subi r24, 0x01 ; 1 - 3f72: 80 93 02 02 sts 0x0202, r24 - 3f76: 88 23 and r24, r24 - 3f78: 61 f7 brne .-40 ; 0x3f52 - 3f7a: 0e c0 rjmp .+28 ; 0x3f98 + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 +#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 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 3f7c: 85 37 cpi r24, 0x75 ; 117 - 3f7e: 39 f4 brne .+14 ; 0x3f8e + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 3f80: 2e d0 rcall .+92 ; 0x3fde + 3f78: 28 d0 rcall .+80 ; 0x3fca putch(SIGNATURE_0); - 3f82: 8e e1 ldi r24, 0x1E ; 30 - 3f84: 0c d0 rcall .+24 ; 0x3f9e + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 putch(SIGNATURE_1); - 3f86: 84 e9 ldi r24, 0x94 ; 148 - 3f88: 0a d0 rcall .+20 ; 0x3f9e + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 putch(SIGNATURE_2); - 3f8a: 86 e0 ldi r24, 0x06 ; 6 - 3f8c: 8b cf rjmp .-234 ; 0x3ea4 + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a } else if (ch == 'Q') { - 3f8e: 81 35 cpi r24, 0x51 ; 81 - 3f90: 11 f4 brne .+4 ; 0x3f96 + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 3f92: 88 e0 ldi r24, 0x08 ; 8 - 3f94: 19 d0 rcall .+50 ; 0x3fc8 + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 3f96: 23 d0 rcall .+70 ; 0x3fde + 3f8e: 1d d0 rcall .+58 ; 0x3fca } putch(STK_OK); - 3f98: 80 e1 ldi r24, 0x10 ; 16 - 3f9a: 01 d0 rcall .+2 ; 0x3f9e - 3f9c: 5c cf rjmp .-328 ; 0x3e56 + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 + 3f94: 65 cf rjmp .-310 ; 0x3e60 -00003f9e : +00003f96 : } } void putch(char ch) { - 3f9e: 98 2f mov r25, r24 + 3f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 3fa0: 80 91 c0 00 lds r24, 0x00C0 - 3fa4: 85 ff sbrs r24, 5 - 3fa6: fc cf rjmp .-8 ; 0x3fa0 + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 UDR0 = ch; - 3fa8: 90 93 c6 00 sts 0x00C6, r25 + 3fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 3fac: 08 95 ret + 3fa4: 08 95 ret -00003fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fae: a8 95 wdr +00003fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 3fb0: 80 91 c0 00 lds r24, 0x00C0 - 3fb4: 87 ff sbrs r24, 7 - 3fb6: fc cf rjmp .-8 ; 0x3fb0 + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 +} +#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); @@ -474,79 +526,73 @@ void watchdogReset() { } 3fbc: 08 95 ret -00003fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fbe: f7 df rcall .-18 ; 0x3fae - length = getch(); - 3fc0: f6 df rcall .-20 ; 0x3fae - 3fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc6: f3 cf rjmp .-26 ; 0x3fae - -00003fc8 : +00003fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 3fc8: e0 e6 ldi r30, 0x60 ; 96 - 3fca: f0 e0 ldi r31, 0x00 ; 0 - 3fcc: 98 e1 ldi r25, 0x18 ; 24 - 3fce: 90 83 st Z, r25 + 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; - 3fd0: 80 83 st Z, r24 + 3fc6: 80 83 st Z, r24 } - 3fd2: 08 95 ret + 3fc8: 08 95 ret -00003fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd4: 80 e0 ldi r24, 0x00 ; 0 - 3fd6: f8 df rcall .-16 ; 0x3fc8 - __asm__ __volatile__ ( - 3fd8: ee 27 eor r30, r30 - 3fda: ff 27 eor r31, r31 - 3fdc: 09 94 ijmp - -00003fde : +00003fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fde: e7 df rcall .-50 ; 0x3fae - 3fe0: 80 32 cpi r24, 0x20 ; 32 - 3fe2: 09 f0 breq .+2 ; 0x3fe6 - 3fe4: f7 df rcall .-18 ; 0x3fd4 + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe + 3fd4: ff cf rjmp .-2 ; 0x3fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 3fe6: 84 e1 ldi r24, 0x14 ; 20 + 3fd6: 84 e1 ldi r24, 0x14 ; 20 } - 3fe8: da cf rjmp .-76 ; 0x3f9e + 3fd8: de cf rjmp .-68 ; 0x3f96 -00003fea : +00003fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 3fea: 1f 93 push r17 - 3fec: 18 2f mov r17, r24 + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 do getch(); while (--count); - 3fee: df df rcall .-66 ; 0x3fae - 3ff0: 11 50 subi r17, 0x01 ; 1 - 3ff2: e9 f7 brne .-6 ; 0x3fee + 3fde: e3 df rcall .-58 ; 0x3fa6 + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde verifySpace(); - 3ff4: f4 df rcall .-24 ; 0x3fde + 3fe4: f2 df rcall .-28 ; 0x3fca } - 3ff6: 1f 91 pop r17 - 3ff8: 08 95 ret + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea : + 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 + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex b/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex index 0d773dd..3cb2549 100644 --- a/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex +++ b/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex @@ -1,34 +1,35 @@ -:103E000084B714BE81FFE6D085E08093810082E014 -:103E10008093C00088E18093C10086E08093C20057 -:103E200088E08093C4008EE0CFD0259A86E028E118 -:103E30003EEF91E0309385002093840096BBB09BC9 -:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 -:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 -:103E600083E020C0823411F484E103C0853419F466 -:103E700085E0BBD091C0853581F499D0082F10E042 -:103E800096D090E0982F8827802B912B880F991F30 -:103E900090930102809300027EC0863529F484E06D -:103EA000A4D080E07CD078C0843609F04EC087D0A2 -:103EB000E0910002F091010288E3E030F80718F485 -:103EC00083E087BFE895C0E0D1E071D0899380910D -:103ED00002028150809302028823B9F7E091000228 -:103EE000F091010288E3E030F80718F083E087BF23 -:103EF000E89575D007B600FCFDCF409100025091C7 -:103F00000102A0E0B1E02C9130E011968C91119764 +:103E0000112484B714BE81FFF0D085E08093810037 +:103E100082E08093C00088E18093C10086E08093B7 +:103E2000C20088E08093C4008EE0C9D0259A86E065 +:103E300028E13EEF91E0309385002093840096BB0B +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27 +:103E6000A2D0813461F49FD0082FAFD0023811F076 +:103E7000013811F484E001C083E08DD089C0823420 +:103E800011F484E103C0853419F485E0A6D080C024 +:103E9000853579F488D0E82EFF2485D0082F10E0EE +:103EA000102F00270E291F29000F111F8ED0680127 +:103EB0006FC0863521F484E090D080E0DECF843678 +:103EC00009F040C070D06FD0082F6DD080E0C816C8 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14 +:103F0000A601A0E0B1E02C9130E011968C911197C0 :103F100090E0982F8827822B932B1296FA010C01A0 -:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 -:103F300051F7E0910002F0910102E7BEE89507B663 -:103F400000FCFDCFF7BEE89527C08437B9F437D021 -:103F500046D0E0910002F09101023196F093010207 -:103F6000E09300023197E4918E2F19D080910202E4 -:103F7000815080930202882361F70EC0853739F49F -:103F80002ED08EE10CD084E90AD086E08BCF81352B -:103F900011F488E019D023D080E101D05CCF982FB4 -:103FA0008091C00085FFFCCF9093C6000895A8952E -:103FB0008091C00087FFFCCF8091C6000895F7DF95 -:103FC000F6DF80930202F3CFE0E6F0E098E1908321 -:103FD0008083089580E0F8DFEE27FF270994E7DF6C -:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B -:0A3FF0001150E9F7F4DF1F91089566 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED +:103F80000AD086E07ACF813511F488E018D01DD0B0 +:103F900080E101D065CF982F8091C00085FFFCCFD4 +:103FA0009093C60008958091C00087FFFCCF809158 +:103FB000C00084FD01C0A8958091C6000895E0E688 +:103FC000F0E098E1908380830895EDDF803219F06E +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736 +:043FF000FF2709940A +:023FFE000404B9 :0400000300003E00BB :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst b/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst index 2406145..345680a 100644 --- a/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst +++ b/optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst @@ -3,25 +3,27 @@ optiboot_lilypad_resonator.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00003e00 00003e00 00000054 2**1 + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 3e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 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; - 3e02: 14 be out 0x34, r1 ; 52 + 3e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 3e04: 81 ff sbrs r24, 1 - 3e06: e6 d0 rcall .+460 ; 0x3fd4 + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 3e08: 85 e0 ldi r24, 0x05 ; 5 - 3e0a: 80 93 81 00 sts 0x0081, r24 + 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 - 3e0e: 82 e0 ldi r24, 0x02 ; 2 - 3e10: 80 93 c0 00 sts 0x00C0, r24 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e14: 88 e1 ldi r24, 0x18 ; 24 - 3e16: 80 93 c1 00 sts 0x00C1, r24 + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e1a: 86 e0 ldi r24, 0x06 ; 6 - 3e1c: 80 93 c2 00 sts 0x00C2, r24 + 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 ); - 3e20: 88 e0 ldi r24, 0x08 ; 8 - 3e22: 80 93 c4 00 sts 0x00C4, r24 + 3e22: 88 e0 ldi r24, 0x08 ; 8 + 3e24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 3e26: 8e e0 ldi r24, 0x0E ; 14 - 3e28: cf d0 rcall .+414 ; 0x3fc8 + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 + 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)); - 3e2e: 28 e1 ldi r18, 0x18 ; 24 - 3e30: 3e ef ldi r19, 0xFE ; 254 + 3e30: 28 e1 ldi r18, 0x18 ; 24 + 3e32: 3e ef ldi r19, 0xFE ; 254 TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 + 3e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 + 3e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 3e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 3e44: a8 95 wdr + 3e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 + 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); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 + 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(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 + 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(); - 3e56: ab d0 rcall .+342 ; 0x3fae + 3e60: a2 d0 rcall .+324 ; 0x3fa6 if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: c5 d0 rcall .+394 ; 0x3fea - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 20 c0 rjmp .+64 ; 0x3ea4 + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 + /* + * 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 + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a + } 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 + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 + } } else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 // SET DEVICE is ignored getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c } else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 // SET DEVICE EXT is ignored getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: bb d0 rcall .+374 ; 0x3fea - 3e74: 91 c0 rjmp .+290 ; 0x3f98 + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 } else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: 81 f4 brne .+32 ; 0x3e9a + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 3e7a: 99 d0 rcall .+306 ; 0x3fae + 3e94: 88 d0 rcall .+272 ; 0x3fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 96 d0 rcall .+300 ; 0x3fae - 3e82: 90 e0 ldi r25, 0x00 ; 0 - 3e84: 98 2f mov r25, r24 - 3e86: 88 27 eor r24, r24 - 3e88: 80 2b or r24, r16 - 3e8a: 91 2b or r25, r17 + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 + 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 - 3e8c: 88 0f add r24, r24 - 3e8e: 99 1f adc r25, r25 + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 address = newAddress; - 3e90: 90 93 01 02 sts 0x0201, r25 - 3e94: 80 93 00 02 sts 0x0200, r24 - 3e98: 7e c0 rjmp .+252 ; 0x3f96 verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 } else if(ch == STK_UNIVERSAL) { - 3e9a: 86 35 cpi r24, 0x56 ; 86 - 3e9c: 29 f4 brne .+10 ; 0x3ea8 + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe // UNIVERSAL command is ignored getNch(4); - 3e9e: 84 e0 ldi r24, 0x04 ; 4 - 3ea0: a4 d0 rcall .+328 ; 0x3fea + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda putch(0x00); - 3ea2: 80 e0 ldi r24, 0x00 ; 0 - 3ea4: 7c d0 rcall .+248 ; 0x3f9e - 3ea6: 78 c0 rjmp .+240 ; 0x3f98 + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 3ea8: 84 36 cpi r24, 0x64 ; 100 - 3eaa: 09 f0 breq .+2 ; 0x3eae - 3eac: 4e c0 rjmp .+156 ; 0x3f4a + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 3eae: 87 d0 rcall .+270 ; 0x3fbe + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 3eb0: e0 91 00 02 lds r30, 0x0200 - 3eb4: f0 91 01 02 lds r31, 0x0201 - 3eb8: 88 e3 ldi r24, 0x38 ; 56 - 3eba: e0 30 cpi r30, 0x00 ; 0 - 3ebc: f8 07 cpc r31, r24 - 3ebe: 18 f4 brcc .+6 ; 0x3ec6 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 87 bf out 0x37, r24 ; 55 - 3ec4: e8 95 spm - 3ec6: c0 e0 ldi r28, 0x00 ; 0 - 3ec8: d1 e0 ldi r29, 0x01 ; 1 - + 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 + 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(); - 3eca: 71 d0 rcall .+226 ; 0x3fae - 3ecc: 89 93 st Y+, r24 + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 + 3ee2: 89 93 st Y+, r24 while (--length); - 3ece: 80 91 02 02 lds r24, 0x0202 - 3ed2: 81 50 subi r24, 0x01 ; 1 - 3ed4: 80 93 02 02 sts 0x0202, r24 - 3ed8: 88 23 and r24, r24 - 3eda: b9 f7 brne .-18 ; 0x3eca + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 // 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); - 3edc: e0 91 00 02 lds r30, 0x0200 - 3ee0: f0 91 01 02 lds r31, 0x0201 - 3ee4: 88 e3 ldi r24, 0x38 ; 56 - 3ee6: e0 30 cpi r30, 0x00 ; 0 - 3ee8: f8 07 cpc r31, r24 - 3eea: 18 f0 brcs .+6 ; 0x3ef2 - 3eec: 83 e0 ldi r24, 0x03 ; 3 - 3eee: 87 bf out 0x37, r24 ; 55 - 3ef0: e8 95 spm + 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 + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 3ef2: 75 d0 rcall .+234 ; 0x3fde - + 3ef8: 68 d0 rcall .+208 ; 0x3fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 3ef4: 07 b6 in r0, 0x37 ; 55 - 3ef6: 00 fc sbrc r0, 0 - 3ef8: fd cf rjmp .-6 ; 0x3ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3efa: 40 91 00 02 lds r20, 0x0200 - 3efe: 50 91 01 02 lds r21, 0x0201 + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa + 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; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 3f1c: fa 01 movw r30, r20 3f1e: 0c 01 movw r0, r24 - 3f20: d7 be out 0x37, r13 ; 55 + 3f20: 87 be out 0x37, r8 ; 55 3f22: e8 95 spm 3f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 3f2c: a0 38 cpi r26, 0x80 ; 128 3f2e: bf 07 cpc r27, r31 3f30: 51 f7 brne .-44 ; 0x3f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 3f32: e0 91 00 02 lds r30, 0x0200 - 3f36: f0 91 01 02 lds r31, 0x0201 - 3f3a: e7 be out 0x37, r14 ; 55 - 3f3c: e8 95 spm + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm boot_spm_busy_wait(); - 3f3e: 07 b6 in r0, 0x37 ; 55 - 3f40: 00 fc sbrc r0, 0 - 3f42: fd cf rjmp .-6 ; 0x3f3e + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 3f44: f7 be out 0x37, r15 ; 55 - 3f46: e8 95 spm - 3f48: 27 c0 rjmp .+78 ; 0x3f98 + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 3f4a: 84 37 cpi r24, 0x74 ; 116 - 3f4c: b9 f4 brne .+46 ; 0x3f7c + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 // READ PAGE - we only read flash - getLen(); - 3f4e: 37 d0 rcall .+110 ; 0x3fbe + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 + verifySpace(); - 3f50: 46 d0 rcall .+140 ; 0x3fde + 3f50: 3c d0 rcall .+120 ; 0x3fca + 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++)); - 3f52: e0 91 00 02 lds r30, 0x0200 - 3f56: f0 91 01 02 lds r31, 0x0201 - 3f5a: 31 96 adiw r30, 0x01 ; 1 - 3f5c: f0 93 01 02 sts 0x0201, r31 - 3f60: e0 93 00 02 sts 0x0200, r30 - 3f64: 31 97 sbiw r30, 0x01 ; 1 - 3f66: e4 91 lpm r30, Z+ - 3f68: 8e 2f mov r24, r30 - 3f6a: 19 d0 rcall .+50 ; 0x3f9e + 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 while (--length); - 3f6c: 80 91 02 02 lds r24, 0x0202 - 3f70: 81 50 subi r24, 0x01 ; 1 - 3f72: 80 93 02 02 sts 0x0202, r24 - 3f76: 88 23 and r24, r24 - 3f78: 61 f7 brne .-40 ; 0x3f52 - 3f7a: 0e c0 rjmp .+28 ; 0x3f98 + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 +#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 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 3f7c: 85 37 cpi r24, 0x75 ; 117 - 3f7e: 39 f4 brne .+14 ; 0x3f8e + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 3f80: 2e d0 rcall .+92 ; 0x3fde + 3f78: 28 d0 rcall .+80 ; 0x3fca putch(SIGNATURE_0); - 3f82: 8e e1 ldi r24, 0x1E ; 30 - 3f84: 0c d0 rcall .+24 ; 0x3f9e + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 putch(SIGNATURE_1); - 3f86: 84 e9 ldi r24, 0x94 ; 148 - 3f88: 0a d0 rcall .+20 ; 0x3f9e + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 putch(SIGNATURE_2); - 3f8a: 86 e0 ldi r24, 0x06 ; 6 - 3f8c: 8b cf rjmp .-234 ; 0x3ea4 + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a } else if (ch == 'Q') { - 3f8e: 81 35 cpi r24, 0x51 ; 81 - 3f90: 11 f4 brne .+4 ; 0x3f96 + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 3f92: 88 e0 ldi r24, 0x08 ; 8 - 3f94: 19 d0 rcall .+50 ; 0x3fc8 + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 3f96: 23 d0 rcall .+70 ; 0x3fde + 3f8e: 1d d0 rcall .+58 ; 0x3fca } putch(STK_OK); - 3f98: 80 e1 ldi r24, 0x10 ; 16 - 3f9a: 01 d0 rcall .+2 ; 0x3f9e - 3f9c: 5c cf rjmp .-328 ; 0x3e56 + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 + 3f94: 65 cf rjmp .-310 ; 0x3e60 -00003f9e : +00003f96 : } } void putch(char ch) { - 3f9e: 98 2f mov r25, r24 + 3f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 3fa0: 80 91 c0 00 lds r24, 0x00C0 - 3fa4: 85 ff sbrs r24, 5 - 3fa6: fc cf rjmp .-8 ; 0x3fa0 + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 UDR0 = ch; - 3fa8: 90 93 c6 00 sts 0x00C6, r25 + 3fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 3fac: 08 95 ret + 3fa4: 08 95 ret -00003fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fae: a8 95 wdr +00003fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 3fb0: 80 91 c0 00 lds r24, 0x00C0 - 3fb4: 87 ff sbrs r24, 7 - 3fb6: fc cf rjmp .-8 ; 0x3fb0 + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 +} +#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); @@ -474,79 +526,73 @@ void watchdogReset() { } 3fbc: 08 95 ret -00003fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fbe: f7 df rcall .-18 ; 0x3fae - length = getch(); - 3fc0: f6 df rcall .-20 ; 0x3fae - 3fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc6: f3 cf rjmp .-26 ; 0x3fae - -00003fc8 : +00003fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 3fc8: e0 e6 ldi r30, 0x60 ; 96 - 3fca: f0 e0 ldi r31, 0x00 ; 0 - 3fcc: 98 e1 ldi r25, 0x18 ; 24 - 3fce: 90 83 st Z, r25 + 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; - 3fd0: 80 83 st Z, r24 + 3fc6: 80 83 st Z, r24 } - 3fd2: 08 95 ret + 3fc8: 08 95 ret -00003fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd4: 80 e0 ldi r24, 0x00 ; 0 - 3fd6: f8 df rcall .-16 ; 0x3fc8 - __asm__ __volatile__ ( - 3fd8: ee 27 eor r30, r30 - 3fda: ff 27 eor r31, r31 - 3fdc: 09 94 ijmp - -00003fde : +00003fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fde: e7 df rcall .-50 ; 0x3fae - 3fe0: 80 32 cpi r24, 0x20 ; 32 - 3fe2: 09 f0 breq .+2 ; 0x3fe6 - 3fe4: f7 df rcall .-18 ; 0x3fd4 + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe + 3fd4: ff cf rjmp .-2 ; 0x3fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 3fe6: 84 e1 ldi r24, 0x14 ; 20 + 3fd6: 84 e1 ldi r24, 0x14 ; 20 } - 3fe8: da cf rjmp .-76 ; 0x3f9e + 3fd8: de cf rjmp .-68 ; 0x3f96 -00003fea : +00003fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 3fea: 1f 93 push r17 - 3fec: 18 2f mov r17, r24 + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 do getch(); while (--count); - 3fee: df df rcall .-66 ; 0x3fae - 3ff0: 11 50 subi r17, 0x01 ; 1 - 3ff2: e9 f7 brne .-6 ; 0x3fee + 3fde: e3 df rcall .-58 ; 0x3fa6 + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde verifySpace(); - 3ff4: f4 df rcall .-24 ; 0x3fde + 3fe4: f2 df rcall .-28 ; 0x3fca } - 3ff6: 1f 91 pop r17 - 3ff8: 08 95 ret + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea : + 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 + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_luminet.hex b/optiboot/bootloaders/optiboot/optiboot_luminet.hex index f62315a..ce9cb97 100644 --- a/optiboot/bootloaders/optiboot/optiboot_luminet.hex +++ b/optiboot/bootloaders/optiboot/optiboot_luminet.hex @@ -1,42 +1,41 @@ -:101D000084B714BE81FF22D185E08EBD8EE01AD14A -:101D1000D49AD29A86E023EC3FEF91E03DBD2CBDF2 -:101D20009BB9589BFECFCC9AA8958150B9F7DD247A -:101D3000D39485E0C82E0FE7F02E1EECE12EE9D0FB -:101D4000813421F481E00DD183E020C0823411F48C -:101D500084E103C0853419F485E003D1C8C085351A -:101D600081F4D7D0082F10E0D4D090E0982F8827A6 -:101D7000802B912B880F991F909381018093800174 -:101D8000B5C0863529F484E0ECD080E0B3D0AFC094 -:101D9000843609F06BC0D1D0C0E0D1E0BAD08993CD -:101DA000809182018150809382018823B9F7E0916C -:101DB0008001F091810183E087BFE895CCD007B620 -:101DC00000FCFDCF8091800190918101892B41F52C -:101DD000809100012091010130E0322F222790E014 -:101DE000282B392B309385012093840140910801E1 -:101DF0008091090190E0982F882750E0842B952B43 -:101E000090938701809386012450304020930801ED -:101E1000232F332720930901F0920001E092010162 -:101E20004091800150918101A0E0B1E02C9130E01F -:101E300011968C91119790E0982F8827822B932BE5 -:101E40001296FA010C01D7BEE89511244E5F5F4F40 -:101E5000F1E0A034BF0751F7E0918001F0918101DA -:101E6000C7BEE89507B600FCFDCF41C0843789F5B1 -:101E700064D071D0E0918001F0918101309719F424 -:101E80002091840113C0E130F10519F420918501FE -:101E90000DC0E830F10519F42091860107C0E93042 -:101EA000F10519F42091870101C0249180918001EE -:101EB0009091810101969093810180938001822FFE -:101EC00019D080918201815080938201882391F6FC -:101ED0000EC0853739F43FD08EE10CD083E90AD0AB -:101EE0008CE054CF813511F488E02CD034D080E1DF -:101EF00001D025CF2AE030E08095089410F4DA98DC -:101F000002C0DA9A000015D014D086952A95B1F750 -:101F10000895A89529E030E0CB99FECF0AD009D0EA -:101F200008D08894CB9908942A9511F08795F7CF1B -:101F300008959EE09A95F1F70895EBDFEADF80932C -:101F40008201E7CF98E191BD81BD089580E0FADF7D -:101F5000E4E0FF270994DDDF803209F0F7DF84E158 -:101F6000C9CF1F93182FD5DF1150E9F7F4DF1F9168 -:021F70000895D2 +:101D0000112484B714BE81FF24D185E08EBD8EE0FE +:101D10000CD1D49AD29A86E023EC3FEF91E03DBDFE +:101D20002CBD9BB9589BFECFCC9AA8958150B9F792 +:101D3000EE24FF2493E0992EBB24B39485E0A82ED3 +:101D40000FE7D02E1EECC12EDDD0813461F4DAD045 +:101D5000082FEFD0023811F0013811F484E001C0EF +:101D600083E0C1D0BDC0823411F484E103C0853466 +:101D700019F485E0E6D0B4C0853579F4C3D0E82EF7 +:101D8000FF24C0D0082F10E0102F00270E291F2994 +:101D9000000F111FCED07801A3C0863521F484E056 +:101DA000D0D080E0DECF843609F05FC0ABD0AAD0BF +:101DB000182FA8D0C0E0D1E0A5D089931C17E1F777 +:101DC000F70197BEE895B5D007B600FCFDCFE1144A +:101DD000F10411F0A7012AC08091000120910101B6 +:101DE00030E0322F222790E0282B392B30938501C9 +:101DF00020938401409108018091090190E0982F7F +:101E0000882750E0842B952B90938701809386013F +:101E10002450304020930801232F332720930901B9 +:101E2000D0920001C092010140E050E0A0E0B1E09A +:101E30002C9130E011968C91119790E0982F882783 +:101E4000822B932B1296FA010C01B7BEE895112450 +:101E50004E5F5F4FF1E0A034BF0751F7F701A7BE17 +:101E6000E89507B600FCFDCF3BC0843759F54AD052 +:101E700049D0182F47D05DD0E701012F209719F4E2 +:101E80008091840114C0C130D10519F4809185017D +:101E90000EC0C830D10519F48091860108C0C93040 +:101EA000D10519F48091870102C0FE018491219629 +:101EB0001AD0015019F70894E11CF11C1150E10EE1 +:101EC000F11C0EC0853739F434D08EE10CD083E993 +:101ED0000AD08CE046CF813511F488E026D029D095 +:101EE00080E101D031CF2AE030E08095089410F4F1 +:101EF000DA9802C0DA9A000014D013D086952A9599 +:101F0000B1F7089529E030E0CB99FECF0AD009D08F +:101F100008D08894CB9908942A9511F08795F7CF2B +:101F200008959EE09A95F1F7089598E191BD81BDDD +:101F30000895E8DF803219F088E0F7DFFFCF84E111 +:101F4000D2CF1F93182FDEDF1150E9F7F2DF1F9178 +:0C1F5000089580E0EADFE4E0FF27099438 +:021EFE000404DA :0400000300001D00DC :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_luminet.lst b/optiboot/bootloaders/optiboot/optiboot_luminet.lst index 2ec0951..76efe15 100644 --- a/optiboot/bootloaders/optiboot/optiboot_luminet.lst +++ b/optiboot/bootloaders/optiboot/optiboot_luminet.lst @@ -3,25 +3,27 @@ optiboot_luminet.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 00000272 00001d00 00001d00 00000054 2**1 + 0 .text 0000025c 00001d00 00001d00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 000002c6 2**0 + 1 .version 00000002 00001efe 00001efe 000002b0 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 000002b2 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 00000078 00000000 00000000 000002ee 2**0 + 3 .debug_pubnames 0000006d 00000000 00000000 000002da 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 000002a4 00000000 00000000 00000366 2**0 + 4 .debug_info 000002bc 00000000 00000000 00000347 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ac 00000000 00000000 0000060a 2**0 + 5 .debug_abbrev 00000176 00000000 00000000 00000603 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 0000043d 00000000 00000000 000007b6 2**0 + 6 .debug_line 000004b0 00000000 00000000 00000779 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 000000a0 00000000 00000000 00000bf4 2**2 + 7 .debug_frame 00000090 00000000 00000000 00000c2c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000150 00000000 00000000 00000c94 2**0 + 8 .debug_str 00000152 00000000 00000000 00000cbc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 00000194 00000000 00000000 00000de4 2**0 + 9 .debug_loc 000002a1 00000000 00000000 00000e0e 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000088 00000000 00000000 00000f78 2**0 + 10 .debug_ranges 00000098 00000000 00000000 000010af 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,588 +35,614 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 1d00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 1d00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif // Adaboot no-wait mod ch = MCUSR; + 1d02: 84 b7 in r24, 0x34 ; 52 MCUSR = 0; - 1d02: 14 be out 0x34, r1 ; 52 + 1d04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 1d04: 81 ff sbrs r24, 1 - 1d06: 22 d1 rcall .+580 ; 0x1f4c + 1d06: 81 ff sbrs r24, 1 + 1d08: 24 d1 rcall .+584 ; 0x1f52 #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 1d08: 85 e0 ldi r24, 0x05 ; 5 - 1d0a: 8e bd out 0x2e, r24 ; 46 + 1d0a: 85 e0 ldi r24, 0x05 ; 5 + 1d0c: 8e bd out 0x2e, r24 ; 46 UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 1d0c: 8e e0 ldi r24, 0x0E ; 14 - 1d0e: 1a d1 rcall .+564 ; 0x1f44 + 1d0e: 8e e0 ldi r24, 0x0E ; 14 + 1d10: 0c d1 rcall .+536 ; 0x1f2a /* Set LED pin as output */ LED_DDR |= _BV(LED); - 1d10: d4 9a sbi 0x1a, 4 ; 26 + 1d12: d4 9a sbi 0x1a, 4 ; 26 #ifdef SOFT_UART /* Set TX pin as output */ UART_DDR |= _BV(UART_TX_BIT); - 1d12: d2 9a sbi 0x1a, 2 ; 26 - 1d14: 86 e0 ldi r24, 0x06 ; 6 + 1d14: d2 9a sbi 0x1a, 2 ; 26 + 1d16: 86 e0 ldi r24, 0x06 ; 6 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 1d16: 23 ec ldi r18, 0xC3 ; 195 - 1d18: 3f ef ldi r19, 0xFF ; 255 + 1d18: 23 ec ldi r18, 0xC3 ; 195 + 1d1a: 3f ef ldi r19, 0xFF ; 255 TIFR1 = _BV(TOV1); - 1d1a: 91 e0 ldi r25, 0x01 ; 1 + 1d1c: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 1d1c: 3d bd out 0x2d, r19 ; 45 - 1d1e: 2c bd out 0x2c, r18 ; 44 + 1d1e: 3d bd out 0x2d, r19 ; 45 + 1d20: 2c bd out 0x2c, r18 ; 44 TIFR1 = _BV(TOV1); - 1d20: 9b b9 out 0x0b, r25 ; 11 + 1d22: 9b b9 out 0x0b, r25 ; 11 while(!(TIFR1 & _BV(TOV1))); - 1d22: 58 9b sbis 0x0b, 0 ; 11 - 1d24: fe cf rjmp .-4 ; 0x1d22 + 1d24: 58 9b sbis 0x0b, 0 ; 11 + 1d26: fe cf rjmp .-4 ; 0x1d24 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 1d26: cc 9a sbi 0x19, 4 ; 25 - return getch(); + 1d28: cc 9a sbi 0x19, 4 ; 25 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 1d28: a8 95 wdr + 1d2a: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 1d2a: 81 50 subi r24, 0x01 ; 1 - 1d2c: b9 f7 brne .-18 ; 0x1d1c - /* get character from UART */ - ch = getch(); + 1d2c: 81 50 subi r24, 0x01 ; 1 + 1d2e: b9 f7 brne .-18 ; 0x1d1e + 1d30: ee 24 eor r14, r14 + 1d32: ff 24 eor r15, r15 + do *bufPtr++ = getch(); + while (--length); - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1d2e: dd 24 eor r13, r13 - 1d30: d3 94 inc r13 + // 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); + 1d34: 93 e0 ldi r25, 0x03 ; 3 + 1d36: 99 2e mov r9, r25 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 1d38: bb 24 eor r11, r11 + 1d3a: b3 94 inc r11 addrPtr += 2; } while (--ch); - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 1d32: 85 e0 ldi r24, 0x05 ; 5 - 1d34: c8 2e mov r12, r24 + 1d3c: 85 e0 ldi r24, 0x05 ; 5 + 1d3e: a8 2e mov r10, r24 vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. buff[8] = vect & 0xff; buff[9] = vect >> 8; // Add jump to bootloader at RESET vector buff[0] = 0x7f; - 1d36: 0f e7 ldi r16, 0x7F ; 127 - 1d38: f0 2e mov r15, r16 + 1d40: 0f e7 ldi r16, 0x7F ; 127 + 1d42: d0 2e mov r13, r16 buff[1] = 0xce; // rjmp 0x1d00 instruction - 1d3a: 1e ec ldi r17, 0xCE ; 206 - 1d3c: e1 2e mov r14, r17 + 1d44: 1e ec ldi r17, 0xCE ; 206 + 1d46: c1 2e mov r12, r17 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - 1d3e: e9 d0 rcall .+466 ; 0x1f12 + 1d48: dd d0 rcall .+442 ; 0x1f04 if(ch == STK_GET_PARAMETER) { - 1d40: 81 34 cpi r24, 0x41 ; 65 - 1d42: 21 f4 brne .+8 ; 0x1d4c - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1d44: 81 e0 ldi r24, 0x01 ; 1 - 1d46: 0d d1 rcall .+538 ; 0x1f62 - putch(0x03); - 1d48: 83 e0 ldi r24, 0x03 ; 3 - 1d4a: 20 c0 rjmp .+64 ; 0x1d8c + 1d4a: 81 34 cpi r24, 0x41 ; 65 + 1d4c: 61 f4 brne .+24 ; 0x1d66 + unsigned char which = getch(); + 1d4e: da d0 rcall .+436 ; 0x1f04 + 1d50: 08 2f mov r16, r24 + verifySpace(); + 1d52: ef d0 rcall .+478 ; 0x1f32 + if (which == 0x82) { + 1d54: 02 38 cpi r16, 0x82 ; 130 + 1d56: 11 f0 breq .+4 ; 0x1d5c + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 1d58: 01 38 cpi r16, 0x81 ; 129 + 1d5a: 11 f4 brne .+4 ; 0x1d60 + putch(OPTIBOOT_MAJVER); + 1d5c: 84 e0 ldi r24, 0x04 ; 4 + 1d5e: 01 c0 rjmp .+2 ; 0x1d62 + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 1d60: 83 e0 ldi r24, 0x03 ; 3 + 1d62: c1 d0 rcall .+386 ; 0x1ee6 + 1d64: bd c0 rjmp .+378 ; 0x1ee0 + } } else if(ch == STK_SET_DEVICE) { - 1d4c: 82 34 cpi r24, 0x42 ; 66 - 1d4e: 11 f4 brne .+4 ; 0x1d54 + 1d66: 82 34 cpi r24, 0x42 ; 66 + 1d68: 11 f4 brne .+4 ; 0x1d6e // SET DEVICE is ignored getNch(20); - 1d50: 84 e1 ldi r24, 0x14 ; 20 - 1d52: 03 c0 rjmp .+6 ; 0x1d5a + 1d6a: 84 e1 ldi r24, 0x14 ; 20 + 1d6c: 03 c0 rjmp .+6 ; 0x1d74 } else if(ch == STK_SET_DEVICE_EXT) { - 1d54: 85 34 cpi r24, 0x45 ; 69 - 1d56: 19 f4 brne .+6 ; 0x1d5e + 1d6e: 85 34 cpi r24, 0x45 ; 69 + 1d70: 19 f4 brne .+6 ; 0x1d78 // SET DEVICE EXT is ignored getNch(5); - 1d58: 85 e0 ldi r24, 0x05 ; 5 - 1d5a: 03 d1 rcall .+518 ; 0x1f62 - 1d5c: c8 c0 rjmp .+400 ; 0x1eee + 1d72: 85 e0 ldi r24, 0x05 ; 5 + 1d74: e6 d0 rcall .+460 ; 0x1f42 + 1d76: b4 c0 rjmp .+360 ; 0x1ee0 } else if(ch == STK_LOAD_ADDRESS) { - 1d5e: 85 35 cpi r24, 0x55 ; 85 - 1d60: 81 f4 brne .+32 ; 0x1d82 + 1d78: 85 35 cpi r24, 0x55 ; 85 + 1d7a: 79 f4 brne .+30 ; 0x1d9a // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 1d62: d7 d0 rcall .+430 ; 0x1f12 + 1d7c: c3 d0 rcall .+390 ; 0x1f04 newAddress = (newAddress & 0xff) | (getch() << 8); - 1d64: 08 2f mov r16, r24 - 1d66: 10 e0 ldi r17, 0x00 ; 0 - 1d68: d4 d0 rcall .+424 ; 0x1f12 - 1d6a: 90 e0 ldi r25, 0x00 ; 0 - 1d6c: 98 2f mov r25, r24 - 1d6e: 88 27 eor r24, r24 - 1d70: 80 2b or r24, r16 - 1d72: 91 2b or r25, r17 + 1d7e: e8 2e mov r14, r24 + 1d80: ff 24 eor r15, r15 + 1d82: c0 d0 rcall .+384 ; 0x1f04 + 1d84: 08 2f mov r16, r24 + 1d86: 10 e0 ldi r17, 0x00 ; 0 + 1d88: 10 2f mov r17, r16 + 1d8a: 00 27 eor r16, r16 + 1d8c: 0e 29 or r16, r14 + 1d8e: 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 - 1d74: 88 0f add r24, r24 - 1d76: 99 1f adc r25, r25 + 1d90: 00 0f add r16, r16 + 1d92: 11 1f adc r17, r17 address = newAddress; - 1d78: 90 93 81 01 sts 0x0181, r25 - 1d7c: 80 93 80 01 sts 0x0180, r24 - 1d80: b5 c0 rjmp .+362 ; 0x1eec verifySpace(); + 1d94: ce d0 rcall .+412 ; 0x1f32 + 1d96: 78 01 movw r14, r16 + 1d98: a3 c0 rjmp .+326 ; 0x1ee0 } else if(ch == STK_UNIVERSAL) { - 1d82: 86 35 cpi r24, 0x56 ; 86 - 1d84: 29 f4 brne .+10 ; 0x1d90 + 1d9a: 86 35 cpi r24, 0x56 ; 86 + 1d9c: 21 f4 brne .+8 ; 0x1da6 // UNIVERSAL command is ignored getNch(4); - 1d86: 84 e0 ldi r24, 0x04 ; 4 - 1d88: ec d0 rcall .+472 ; 0x1f62 + 1d9e: 84 e0 ldi r24, 0x04 ; 4 + 1da0: d0 d0 rcall .+416 ; 0x1f42 putch(0x00); - 1d8a: 80 e0 ldi r24, 0x00 ; 0 - 1d8c: b3 d0 rcall .+358 ; 0x1ef4 - 1d8e: af c0 rjmp .+350 ; 0x1eee + 1da2: 80 e0 ldi r24, 0x00 ; 0 + 1da4: de cf rjmp .-68 ; 0x1d62 } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 1d90: 84 36 cpi r24, 0x64 ; 100 - 1d92: 09 f0 breq .+2 ; 0x1d96 - 1d94: 6b c0 rjmp .+214 ; 0x1e6c + 1da6: 84 36 cpi r24, 0x64 ; 100 + 1da8: 09 f0 breq .+2 ; 0x1dac + 1daa: 5f c0 rjmp .+190 ; 0x1e6a // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 1d96: d1 d0 rcall .+418 ; 0x1f3a - 1d98: c0 e0 ldi r28, 0x00 ; 0 - 1d9a: d1 e0 ldi r29, 0x01 ; 1 + getch(); /* getlen() */ + 1dac: ab d0 rcall .+342 ; 0x1f04 + length = getch(); + 1dae: aa d0 rcall .+340 ; 0x1f04 + 1db0: 18 2f mov r17, r24 + getch(); + 1db2: a8 d0 rcall .+336 ; 0x1f04 + 1db4: c0 e0 ldi r28, 0x00 ; 0 + 1db6: d1 e0 ldi r29, 0x01 ; 1 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - + // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - 1d9c: ba d0 rcall .+372 ; 0x1f12 - 1d9e: 89 93 st Y+, r24 + 1db8: a5 d0 rcall .+330 ; 0x1f04 + 1dba: 89 93 st Y+, r24 while (--length); - 1da0: 80 91 82 01 lds r24, 0x0182 - 1da4: 81 50 subi r24, 0x01 ; 1 - 1da6: 80 93 82 01 sts 0x0182, r24 - 1daa: 88 23 and r24, r24 - 1dac: b9 f7 brne .-18 ; 0x1d9c + 1dbc: 1c 17 cp r17, r28 + 1dbe: e1 f7 brne .-8 ; 0x1db8 // 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); - 1dae: e0 91 80 01 lds r30, 0x0180 - 1db2: f0 91 81 01 lds r31, 0x0181 - 1db6: 83 e0 ldi r24, 0x03 ; 3 - 1db8: 87 bf out 0x37, r24 ; 55 - 1dba: e8 95 spm + 1dc0: f7 01 movw r30, r14 + 1dc2: 97 be out 0x37, r9 ; 55 + 1dc4: e8 95 spm // Read command terminator, start reply verifySpace(); - 1dbc: cc d0 rcall .+408 ; 0x1f56 - + 1dc6: b5 d0 rcall .+362 ; 0x1f32 + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 1dbe: 07 b6 in r0, 0x37 ; 55 - 1dc0: 00 fc sbrc r0, 0 - 1dc2: fd cf rjmp .-6 ; 0x1dbe + 1dc8: 07 b6 in r0, 0x37 ; 55 + 1dca: 00 fc sbrc r0, 0 + 1dcc: fd cf rjmp .-6 ; 0x1dc8 #ifdef VIRTUAL_BOOT_PARTITION if ((uint16_t)(void*)address == 0) { - 1dc4: 80 91 80 01 lds r24, 0x0180 - 1dc8: 90 91 81 01 lds r25, 0x0181 - 1dcc: 89 2b or r24, r25 - 1dce: 41 f5 brne .+80 ; 0x1e20 + 1dce: e1 14 cp r14, r1 + 1dd0: f1 04 cpc r15, r1 + 1dd2: 11 f0 breq .+4 ; 0x1dd8 + 1dd4: a7 01 movw r20, r14 + 1dd6: 2a c0 rjmp .+84 ; 0x1e2c // This is the reset vector page. We need to live-patch the code so the // bootloader runs. // // Move RESET vector to WDT vector uint16_t vect = buff[0] | (buff[1]<<8); - 1dd0: 80 91 00 01 lds r24, 0x0100 - 1dd4: 20 91 01 01 lds r18, 0x0101 - 1dd8: 30 e0 ldi r19, 0x00 ; 0 - 1dda: 32 2f mov r19, r18 - 1ddc: 22 27 eor r18, r18 - 1dde: 90 e0 ldi r25, 0x00 ; 0 - 1de0: 28 2b or r18, r24 - 1de2: 39 2b or r19, r25 + 1dd8: 80 91 00 01 lds r24, 0x0100 + 1ddc: 20 91 01 01 lds r18, 0x0101 + 1de0: 30 e0 ldi r19, 0x00 ; 0 + 1de2: 32 2f mov r19, r18 + 1de4: 22 27 eor r18, r18 + 1de6: 90 e0 ldi r25, 0x00 ; 0 + 1de8: 28 2b or r18, r24 + 1dea: 39 2b or r19, r25 rstVect = vect; - 1de4: 30 93 85 01 sts 0x0185, r19 - 1de8: 20 93 84 01 sts 0x0184, r18 + 1dec: 30 93 85 01 sts 0x0185, r19 + 1df0: 20 93 84 01 sts 0x0184, r18 wdtVect = buff[8] | (buff[9]<<8); - 1dec: 40 91 08 01 lds r20, 0x0108 - 1df0: 80 91 09 01 lds r24, 0x0109 - 1df4: 90 e0 ldi r25, 0x00 ; 0 - 1df6: 98 2f mov r25, r24 - 1df8: 88 27 eor r24, r24 - 1dfa: 50 e0 ldi r21, 0x00 ; 0 - 1dfc: 84 2b or r24, r20 - 1dfe: 95 2b or r25, r21 - 1e00: 90 93 87 01 sts 0x0187, r25 - 1e04: 80 93 86 01 sts 0x0186, r24 + 1df4: 40 91 08 01 lds r20, 0x0108 + 1df8: 80 91 09 01 lds r24, 0x0109 + 1dfc: 90 e0 ldi r25, 0x00 ; 0 + 1dfe: 98 2f mov r25, r24 + 1e00: 88 27 eor r24, r24 + 1e02: 50 e0 ldi r21, 0x00 ; 0 + 1e04: 84 2b or r24, r20 + 1e06: 95 2b or r25, r21 + 1e08: 90 93 87 01 sts 0x0187, r25 + 1e0c: 80 93 86 01 sts 0x0186, r24 vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. - 1e08: 24 50 subi r18, 0x04 ; 4 - 1e0a: 30 40 sbci r19, 0x00 ; 0 + 1e10: 24 50 subi r18, 0x04 ; 4 + 1e12: 30 40 sbci r19, 0x00 ; 0 buff[8] = vect & 0xff; - 1e0c: 20 93 08 01 sts 0x0108, r18 + 1e14: 20 93 08 01 sts 0x0108, r18 buff[9] = vect >> 8; - 1e10: 23 2f mov r18, r19 - 1e12: 33 27 eor r19, r19 - 1e14: 20 93 09 01 sts 0x0109, r18 + 1e18: 23 2f mov r18, r19 + 1e1a: 33 27 eor r19, r19 + 1e1c: 20 93 09 01 sts 0x0109, r18 // Add jump to bootloader at RESET vector buff[0] = 0x7f; - 1e18: f0 92 00 01 sts 0x0100, r15 + 1e20: d0 92 00 01 sts 0x0100, r13 buff[1] = 0xce; // rjmp 0x1d00 instruction - 1e1c: e0 92 01 01 sts 0x0101, r14 - } -#endif - - // Copy buffer into programming buffer + 1e24: c0 92 01 01 sts 0x0101, r12 + 1e28: 40 e0 ldi r20, 0x00 ; 0 + 1e2a: 50 e0 ldi r21, 0x00 ; 0 + 1e2c: a0 e0 ldi r26, 0x00 ; 0 + 1e2e: b1 e0 ldi r27, 0x01 ; 1 bufPtr = buff; addrPtr = (uint16_t)(void*)address; - 1e20: 40 91 80 01 lds r20, 0x0180 - 1e24: 50 91 81 01 lds r21, 0x0181 - 1e28: a0 e0 ldi r26, 0x00 ; 0 - 1e2a: b1 e0 ldi r27, 0x01 ; 1 ch = SPM_PAGESIZE / 2; do { uint16_t a; a = *bufPtr++; - 1e2c: 2c 91 ld r18, X - 1e2e: 30 e0 ldi r19, 0x00 ; 0 + 1e30: 2c 91 ld r18, X + 1e32: 30 e0 ldi r19, 0x00 ; 0 a |= (*bufPtr++) << 8; - 1e30: 11 96 adiw r26, 0x01 ; 1 - 1e32: 8c 91 ld r24, X - 1e34: 11 97 sbiw r26, 0x01 ; 1 - 1e36: 90 e0 ldi r25, 0x00 ; 0 - 1e38: 98 2f mov r25, r24 - 1e3a: 88 27 eor r24, r24 - 1e3c: 82 2b or r24, r18 - 1e3e: 93 2b or r25, r19 + 1e34: 11 96 adiw r26, 0x01 ; 1 + 1e36: 8c 91 ld r24, X + 1e38: 11 97 sbiw r26, 0x01 ; 1 + 1e3a: 90 e0 ldi r25, 0x00 ; 0 + 1e3c: 98 2f mov r25, r24 + 1e3e: 88 27 eor r24, r24 + 1e40: 82 2b or r24, r18 + 1e42: 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) { - 1e40: 12 96 adiw r26, 0x02 ; 2 + 1e44: 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); - 1e42: fa 01 movw r30, r20 - 1e44: 0c 01 movw r0, r24 - 1e46: d7 be out 0x37, r13 ; 55 - 1e48: e8 95 spm - 1e4a: 11 24 eor r1, r1 + 1e46: fa 01 movw r30, r20 + 1e48: 0c 01 movw r0, r24 + 1e4a: b7 be out 0x37, r11 ; 55 + 1e4c: e8 95 spm + 1e4e: 11 24 eor r1, r1 addrPtr += 2; - 1e4c: 4e 5f subi r20, 0xFE ; 254 - 1e4e: 5f 4f sbci r21, 0xFF ; 255 + 1e50: 4e 5f subi r20, 0xFE ; 254 + 1e52: 5f 4f sbci r21, 0xFF ; 255 } while (--ch); - 1e50: f1 e0 ldi r31, 0x01 ; 1 - 1e52: a0 34 cpi r26, 0x40 ; 64 - 1e54: bf 07 cpc r27, r31 - 1e56: 51 f7 brne .-44 ; 0x1e2c - + 1e54: f1 e0 ldi r31, 0x01 ; 1 + 1e56: a0 34 cpi r26, 0x40 ; 64 + 1e58: bf 07 cpc r27, r31 + 1e5a: 51 f7 brne .-44 ; 0x1e30 + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 1e58: e0 91 80 01 lds r30, 0x0180 - 1e5c: f0 91 81 01 lds r31, 0x0181 - 1e60: c7 be out 0x37, r12 ; 55 - 1e62: e8 95 spm + 1e5c: f7 01 movw r30, r14 + 1e5e: a7 be out 0x37, r10 ; 55 + 1e60: e8 95 spm boot_spm_busy_wait(); - 1e64: 07 b6 in r0, 0x37 ; 55 - 1e66: 00 fc sbrc r0, 0 - 1e68: fd cf rjmp .-6 ; 0x1e64 - 1e6a: 41 c0 rjmp .+130 ; 0x1eee + 1e62: 07 b6 in r0, 0x37 ; 55 + 1e64: 00 fc sbrc r0, 0 + 1e66: fd cf rjmp .-6 ; 0x1e62 + 1e68: 3b c0 rjmp .+118 ; 0x1ee0 boot_rww_enable(); #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 1e6c: 84 37 cpi r24, 0x74 ; 116 - 1e6e: 89 f5 brne .+98 ; 0x1ed2 + 1e6a: 84 37 cpi r24, 0x74 ; 116 + 1e6c: 59 f5 brne .+86 ; 0x1ec4 // READ PAGE - we only read flash - getLen(); - 1e70: 64 d0 rcall .+200 ; 0x1f3a + getch(); /* getlen() */ + 1e6e: 4a d0 rcall .+148 ; 0x1f04 + length = getch(); + 1e70: 49 d0 rcall .+146 ; 0x1f04 + 1e72: 18 2f mov r17, r24 + getch(); + 1e74: 47 d0 rcall .+142 ; 0x1f04 + verifySpace(); - 1e72: 71 d0 rcall .+226 ; 0x1f56 + 1e76: 5d d0 rcall .+186 ; 0x1f32 + 1e78: e7 01 movw r28, r14 + 1e7a: 01 2f mov r16, r17 #ifdef VIRTUAL_BOOT_PARTITION do { // Undo vector patch in bottom page so verify passes if (address == 0) ch=rstVect & 0xff; - 1e74: e0 91 80 01 lds r30, 0x0180 - 1e78: f0 91 81 01 lds r31, 0x0181 - 1e7c: 30 97 sbiw r30, 0x00 ; 0 + 1e7c: 20 97 sbiw r28, 0x00 ; 0 1e7e: 19 f4 brne .+6 ; 0x1e86 - 1e80: 20 91 84 01 lds r18, 0x0184 - 1e84: 13 c0 rjmp .+38 ; 0x1eac + 1e80: 80 91 84 01 lds r24, 0x0184 + 1e84: 14 c0 rjmp .+40 ; 0x1eae else if (address == 1) ch=rstVect >> 8; - 1e86: e1 30 cpi r30, 0x01 ; 1 - 1e88: f1 05 cpc r31, r1 + 1e86: c1 30 cpi r28, 0x01 ; 1 + 1e88: d1 05 cpc r29, r1 1e8a: 19 f4 brne .+6 ; 0x1e92 - 1e8c: 20 91 85 01 lds r18, 0x0185 - 1e90: 0d c0 rjmp .+26 ; 0x1eac + 1e8c: 80 91 85 01 lds r24, 0x0185 + 1e90: 0e c0 rjmp .+28 ; 0x1eae else if (address == 8) ch=wdtVect & 0xff; - 1e92: e8 30 cpi r30, 0x08 ; 8 - 1e94: f1 05 cpc r31, r1 + 1e92: c8 30 cpi r28, 0x08 ; 8 + 1e94: d1 05 cpc r29, r1 1e96: 19 f4 brne .+6 ; 0x1e9e - 1e98: 20 91 86 01 lds r18, 0x0186 - 1e9c: 07 c0 rjmp .+14 ; 0x1eac + 1e98: 80 91 86 01 lds r24, 0x0186 + 1e9c: 08 c0 rjmp .+16 ; 0x1eae else if (address == 9) ch=wdtVect >> 8; - 1e9e: e9 30 cpi r30, 0x09 ; 9 - 1ea0: f1 05 cpc r31, r1 + 1e9e: c9 30 cpi r28, 0x09 ; 9 + 1ea0: d1 05 cpc r29, r1 1ea2: 19 f4 brne .+6 ; 0x1eaa - 1ea4: 20 91 87 01 lds r18, 0x0187 - 1ea8: 01 c0 rjmp .+2 ; 0x1eac + 1ea4: 80 91 87 01 lds r24, 0x0187 + 1ea8: 02 c0 rjmp .+4 ; 0x1eae else ch = pgm_read_byte_near(address); - 1eaa: 24 91 lpm r18, Z+ + 1eaa: fe 01 movw r30, r28 + 1eac: 84 91 lpm r24, Z+ address++; - 1eac: 80 91 80 01 lds r24, 0x0180 - 1eb0: 90 91 81 01 lds r25, 0x0181 - 1eb4: 01 96 adiw r24, 0x01 ; 1 - 1eb6: 90 93 81 01 sts 0x0181, r25 - 1eba: 80 93 80 01 sts 0x0180, r24 + 1eae: 21 96 adiw r28, 0x01 ; 1 putch(ch); - 1ebe: 82 2f mov r24, r18 - 1ec0: 19 d0 rcall .+50 ; 0x1ef4 + 1eb0: 1a d0 rcall .+52 ; 0x1ee6 } while (--length); - 1ec2: 80 91 82 01 lds r24, 0x0182 - 1ec6: 81 50 subi r24, 0x01 ; 1 - 1ec8: 80 93 82 01 sts 0x0182, r24 - 1ecc: 88 23 and r24, r24 - 1ece: 91 f6 brne .-92 ; 0x1e74 - 1ed0: 0e c0 rjmp .+28 ; 0x1eee + 1eb2: 01 50 subi r16, 0x01 ; 1 + 1eb4: 19 f7 brne .-58 ; 0x1e7c +#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) { + 1eb6: 08 94 sec + 1eb8: e1 1c adc r14, r1 + 1eba: f1 1c adc r15, r1 + 1ebc: 11 50 subi r17, 0x01 ; 1 + 1ebe: e1 0e add r14, r17 + 1ec0: f1 1c adc r15, r1 + 1ec2: 0e c0 rjmp .+28 ; 0x1ee0 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 1ed2: 85 37 cpi r24, 0x75 ; 117 - 1ed4: 39 f4 brne .+14 ; 0x1ee4 + 1ec4: 85 37 cpi r24, 0x75 ; 117 + 1ec6: 39 f4 brne .+14 ; 0x1ed6 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 1ed6: 3f d0 rcall .+126 ; 0x1f56 + 1ec8: 34 d0 rcall .+104 ; 0x1f32 putch(SIGNATURE_0); - 1ed8: 8e e1 ldi r24, 0x1E ; 30 - 1eda: 0c d0 rcall .+24 ; 0x1ef4 + 1eca: 8e e1 ldi r24, 0x1E ; 30 + 1ecc: 0c d0 rcall .+24 ; 0x1ee6 putch(SIGNATURE_1); - 1edc: 83 e9 ldi r24, 0x93 ; 147 - 1ede: 0a d0 rcall .+20 ; 0x1ef4 + 1ece: 83 e9 ldi r24, 0x93 ; 147 + 1ed0: 0a d0 rcall .+20 ; 0x1ee6 putch(SIGNATURE_2); - 1ee0: 8c e0 ldi r24, 0x0C ; 12 - 1ee2: 54 cf rjmp .-344 ; 0x1d8c + 1ed2: 8c e0 ldi r24, 0x0C ; 12 + 1ed4: 46 cf rjmp .-372 ; 0x1d62 } else if (ch == 'Q') { - 1ee4: 81 35 cpi r24, 0x51 ; 81 - 1ee6: 11 f4 brne .+4 ; 0x1eec + 1ed6: 81 35 cpi r24, 0x51 ; 81 + 1ed8: 11 f4 brne .+4 ; 0x1ede // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 1ee8: 88 e0 ldi r24, 0x08 ; 8 - 1eea: 2c d0 rcall .+88 ; 0x1f44 + 1eda: 88 e0 ldi r24, 0x08 ; 8 + 1edc: 26 d0 rcall .+76 ; 0x1f2a verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 1eec: 34 d0 rcall .+104 ; 0x1f56 + 1ede: 29 d0 rcall .+82 ; 0x1f32 } putch(STK_OK); - 1eee: 80 e1 ldi r24, 0x10 ; 16 - 1ef0: 01 d0 rcall .+2 ; 0x1ef4 - 1ef2: 25 cf rjmp .-438 ; 0x1d3e + 1ee0: 80 e1 ldi r24, 0x10 ; 16 + 1ee2: 01 d0 rcall .+2 ; 0x1ee6 + 1ee4: 31 cf rjmp .-414 ; 0x1d48 -00001ef4 : +00001ee6 : void putch(char ch) { #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); UDR0 = ch; #else __asm__ __volatile__ ( - 1ef4: 2a e0 ldi r18, 0x0A ; 10 - 1ef6: 30 e0 ldi r19, 0x00 ; 0 - 1ef8: 80 95 com r24 - 1efa: 08 94 sec - 1efc: 10 f4 brcc .+4 ; 0x1f02 - 1efe: da 98 cbi 0x1b, 2 ; 27 - 1f00: 02 c0 rjmp .+4 ; 0x1f06 - 1f02: da 9a sbi 0x1b, 2 ; 27 - 1f04: 00 00 nop - 1f06: 15 d0 rcall .+42 ; 0x1f32 - 1f08: 14 d0 rcall .+40 ; 0x1f32 - 1f0a: 86 95 lsr r24 - 1f0c: 2a 95 dec r18 - 1f0e: b1 f7 brne .-20 ; 0x1efc + 1ee6: 2a e0 ldi r18, 0x0A ; 10 + 1ee8: 30 e0 ldi r19, 0x00 ; 0 + 1eea: 80 95 com r24 + 1eec: 08 94 sec + 1eee: 10 f4 brcc .+4 ; 0x1ef4 + 1ef0: da 98 cbi 0x1b, 2 ; 27 + 1ef2: 02 c0 rjmp .+4 ; 0x1ef8 + 1ef4: da 9a sbi 0x1b, 2 ; 27 + 1ef6: 00 00 nop + 1ef8: 14 d0 rcall .+40 ; 0x1f22 + 1efa: 13 d0 rcall .+38 ; 0x1f22 + 1efc: 86 95 lsr r24 + 1efe: 2a 95 dec r18 + 1f00: b1 f7 brne .-20 ; 0x1eee [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 1f10: 08 95 ret + 1f02: 08 95 ret -00001f12 : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 1f12: a8 95 wdr +00001f04 : LED_PIN |= _BV(LED); #endif #endif return ch; } - 1f14: 29 e0 ldi r18, 0x09 ; 9 - 1f16: 30 e0 ldi r19, 0x00 ; 0 - 1f18: cb 99 sbic 0x19, 3 ; 25 - 1f1a: fe cf rjmp .-4 ; 0x1f18 - 1f1c: 0a d0 rcall .+20 ; 0x1f32 - 1f1e: 09 d0 rcall .+18 ; 0x1f32 - 1f20: 08 d0 rcall .+16 ; 0x1f32 - 1f22: 88 94 clc - 1f24: cb 99 sbic 0x19, 3 ; 25 - 1f26: 08 94 sec - 1f28: 2a 95 dec r18 - 1f2a: 11 f0 breq .+4 ; 0x1f30 - 1f2c: 87 95 ror r24 - 1f2e: f7 cf rjmp .-18 ; 0x1f1e - 1f30: 08 95 ret + 1f04: 29 e0 ldi r18, 0x09 ; 9 + 1f06: 30 e0 ldi r19, 0x00 ; 0 + 1f08: cb 99 sbic 0x19, 3 ; 25 + 1f0a: fe cf rjmp .-4 ; 0x1f08 + 1f0c: 0a d0 rcall .+20 ; 0x1f22 + 1f0e: 09 d0 rcall .+18 ; 0x1f22 + 1f10: 08 d0 rcall .+16 ; 0x1f22 + 1f12: 88 94 clc + 1f14: cb 99 sbic 0x19, 3 ; 25 + 1f16: 08 94 sec + 1f18: 2a 95 dec r18 + 1f1a: 11 f0 breq .+4 ; 0x1f20 + 1f1c: 87 95 ror r24 + 1f1e: f7 cf rjmp .-18 ; 0x1f0e + 1f20: 08 95 ret -00001f32 : +00001f22 : #if UART_B_VALUE > 255 #error Baud rate too slow for soft UART #endif void uartDelay() { __asm__ __volatile__ ( - 1f32: 9e e0 ldi r25, 0x0E ; 14 - 1f34: 9a 95 dec r25 - 1f36: f1 f7 brne .-4 ; 0x1f34 - 1f38: 08 95 ret + 1f22: 9e e0 ldi r25, 0x0E ; 14 + 1f24: 9a 95 dec r25 + 1f26: f1 f7 brne .-4 ; 0x1f24 + 1f28: 08 95 ret -00001f3a : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 1f3a: eb df rcall .-42 ; 0x1f12 - length = getch(); - 1f3c: ea df rcall .-44 ; 0x1f12 - 1f3e: 80 93 82 01 sts 0x0182, r24 - return getch(); -} - 1f42: e7 cf rjmp .-50 ; 0x1f12 - -00001f44 : +00001f2a : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 1f44: 98 e1 ldi r25, 0x18 ; 24 - 1f46: 91 bd out 0x21, r25 ; 33 + 1f2a: 98 e1 ldi r25, 0x18 ; 24 + 1f2c: 91 bd out 0x21, r25 ; 33 WDTCSR = x; - 1f48: 81 bd out 0x21, r24 ; 33 + 1f2e: 81 bd out 0x21, r24 ; 33 } - 1f4a: 08 95 ret + 1f30: 08 95 ret -00001f4c : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 1f4c: 80 e0 ldi r24, 0x00 ; 0 - 1f4e: fa df rcall .-12 ; 0x1f44 - __asm__ __volatile__ ( - 1f50: e4 e0 ldi r30, 0x04 ; 4 - 1f52: ff 27 eor r31, r31 - 1f54: 09 94 ijmp - -00001f56 : +00001f32 : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 1f56: dd df rcall .-70 ; 0x1f12 - 1f58: 80 32 cpi r24, 0x20 ; 32 - 1f5a: 09 f0 breq .+2 ; 0x1f5e - 1f5c: f7 df rcall .-18 ; 0x1f4c + if (getch() != CRC_EOP) { + 1f32: e8 df rcall .-48 ; 0x1f04 + 1f34: 80 32 cpi r24, 0x20 ; 32 + 1f36: 19 f0 breq .+6 ; 0x1f3e + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 1f38: 88 e0 ldi r24, 0x08 ; 8 + 1f3a: f7 df rcall .-18 ; 0x1f2a + 1f3c: ff cf rjmp .-2 ; 0x1f3c + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 1f5e: 84 e1 ldi r24, 0x14 ; 20 + 1f3e: 84 e1 ldi r24, 0x14 ; 20 } - 1f60: c9 cf rjmp .-110 ; 0x1ef4 + 1f40: d2 cf rjmp .-92 ; 0x1ee6 -00001f62 : +00001f42 : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 1f62: 1f 93 push r17 - 1f64: 18 2f mov r17, r24 + 1f42: 1f 93 push r17 + 1f44: 18 2f mov r17, r24 do getch(); while (--count); - 1f66: d5 df rcall .-86 ; 0x1f12 - 1f68: 11 50 subi r17, 0x01 ; 1 - 1f6a: e9 f7 brne .-6 ; 0x1f66 + 1f46: de df rcall .-68 ; 0x1f04 + 1f48: 11 50 subi r17, 0x01 ; 1 + 1f4a: e9 f7 brne .-6 ; 0x1f46 verifySpace(); - 1f6c: f4 df rcall .-24 ; 0x1f56 + 1f4c: f2 df rcall .-28 ; 0x1f32 } - 1f6e: 1f 91 pop r17 - 1f70: 08 95 ret + 1f4e: 1f 91 pop r17 + 1f50: 08 95 ret + +00001f52 : + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 1f52: 80 e0 ldi r24, 0x00 ; 0 + 1f54: ea df rcall .-44 ; 0x1f2a + __asm__ __volatile__ ( + 1f56: e4 e0 ldi r30, 0x04 ; 4 + 1f58: ff 27 eor r31, r31 + 1f5a: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex b/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex index 41fbd79..c2f2b5b 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex +++ b/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex @@ -1,34 +1,35 @@ -:103E000084B714BE81FFE6D085E08093810082E014 -:103E10008093C00088E18093C10086E08093C20057 -:103E200080E18093C4008EE0CFD0259A86E020E325 -:103E30003CEF91E0309385002093840096BBB09BCB -:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 -:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 -:103E600083E020C0823411F484E103C0853419F466 -:103E700085E0BBD091C0853581F499D0082F10E042 -:103E800096D090E0982F8827802B912B880F991F30 -:103E900090930102809300027EC0863529F484E06D -:103EA000A4D080E07CD078C0843609F04EC087D0A2 -:103EB000E0910002F091010288E3E030F80718F485 -:103EC00083E087BFE895C0E0D1E071D0899380910D -:103ED00002028150809302028823B9F7E091000228 -:103EE000F091010288E3E030F80718F083E087BF23 -:103EF000E89575D007B600FCFDCF409100025091C7 -:103F00000102A0E0B1E02C9130E011968C91119764 +:103E0000112484B714BE81FFF0D085E08093810037 +:103E100082E08093C00088E18093C10086E08093B7 +:103E2000C20080E18093C4008EE0C9D0259A86E06C +:103E300020E33CEF91E0309385002093840096BB13 +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27 +:103E6000A2D0813461F49FD0082FAFD0023811F076 +:103E7000013811F484E001C083E08DD089C0823420 +:103E800011F484E103C0853419F485E0A6D080C024 +:103E9000853579F488D0E82EFF2485D0082F10E0EE +:103EA000102F00270E291F29000F111F8ED0680127 +:103EB0006FC0863521F484E090D080E0DECF843678 +:103EC00009F040C070D06FD0082F6DD080E0C816C8 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14 +:103F0000A601A0E0B1E02C9130E011968C911197C0 :103F100090E0982F8827822B932B1296FA010C01A0 -:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 -:103F300051F7E0910002F0910102E7BEE89507B663 -:103F400000FCFDCFF7BEE89527C08437B9F437D021 -:103F500046D0E0910002F09101023196F093010207 -:103F6000E09300023197E4918E2F19D080910202E4 -:103F7000815080930202882361F70EC0853739F49F -:103F80002ED08EE10CD084E90AD086E08BCF81352B -:103F900011F488E019D023D080E101D05CCF982FB4 -:103FA0008091C00085FFFCCF9093C6000895A8952E -:103FB0008091C00087FFFCCF8091C6000895F7DF95 -:103FC000F6DF80930202F3CFE0E6F0E098E1908321 -:103FD0008083089580E0F8DFEE27FF270994E7DF6C -:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B -:0A3FF0001150E9F7F4DF1F91089566 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED +:103F80000AD086E07ACF813511F488E018D01DD0B0 +:103F900080E101D065CF982F8091C00085FFFCCFD4 +:103FA0009093C60008958091C00087FFFCCF809158 +:103FB000C00084FD01C0A8958091C6000895E0E688 +:103FC000F0E098E1908380830895EDDF803219F06E +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736 +:043FF000FF2709940A +:023FFE000404B9 :0400000300003E00BB :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst b/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst index e10a3d5..2e8e5ca 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst +++ b/optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst @@ -3,25 +3,27 @@ optiboot_pro_16MHz.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00003e00 00003e00 00000054 2**1 + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 3e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 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; - 3e02: 14 be out 0x34, r1 ; 52 + 3e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 3e04: 81 ff sbrs r24, 1 - 3e06: e6 d0 rcall .+460 ; 0x3fd4 + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 3e08: 85 e0 ldi r24, 0x05 ; 5 - 3e0a: 80 93 81 00 sts 0x0081, r24 + 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 - 3e0e: 82 e0 ldi r24, 0x02 ; 2 - 3e10: 80 93 c0 00 sts 0x00C0, r24 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e14: 88 e1 ldi r24, 0x18 ; 24 - 3e16: 80 93 c1 00 sts 0x00C1, r24 + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e1a: 86 e0 ldi r24, 0x06 ; 6 - 3e1c: 80 93 c2 00 sts 0x00C2, r24 + 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 ); - 3e20: 80 e1 ldi r24, 0x10 ; 16 - 3e22: 80 93 c4 00 sts 0x00C4, r24 + 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); - 3e26: 8e e0 ldi r24, 0x0E ; 14 - 3e28: cf d0 rcall .+414 ; 0x3fc8 + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 + 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)); - 3e2e: 20 e3 ldi r18, 0x30 ; 48 - 3e30: 3c ef ldi r19, 0xFC ; 252 + 3e30: 20 e3 ldi r18, 0x30 ; 48 + 3e32: 3c ef ldi r19, 0xFC ; 252 TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 + 3e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 + 3e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 3e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 3e44: a8 95 wdr + 3e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 + 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); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 + 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(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 + 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(); - 3e56: ab d0 rcall .+342 ; 0x3fae + 3e60: a2 d0 rcall .+324 ; 0x3fa6 if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: c5 d0 rcall .+394 ; 0x3fea - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 20 c0 rjmp .+64 ; 0x3ea4 + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 + /* + * 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 + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a + } 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 + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 + } } else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 // SET DEVICE is ignored getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c } else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 // SET DEVICE EXT is ignored getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: bb d0 rcall .+374 ; 0x3fea - 3e74: 91 c0 rjmp .+290 ; 0x3f98 + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 } else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: 81 f4 brne .+32 ; 0x3e9a + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 3e7a: 99 d0 rcall .+306 ; 0x3fae + 3e94: 88 d0 rcall .+272 ; 0x3fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 96 d0 rcall .+300 ; 0x3fae - 3e82: 90 e0 ldi r25, 0x00 ; 0 - 3e84: 98 2f mov r25, r24 - 3e86: 88 27 eor r24, r24 - 3e88: 80 2b or r24, r16 - 3e8a: 91 2b or r25, r17 + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 + 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 - 3e8c: 88 0f add r24, r24 - 3e8e: 99 1f adc r25, r25 + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 address = newAddress; - 3e90: 90 93 01 02 sts 0x0201, r25 - 3e94: 80 93 00 02 sts 0x0200, r24 - 3e98: 7e c0 rjmp .+252 ; 0x3f96 verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 } else if(ch == STK_UNIVERSAL) { - 3e9a: 86 35 cpi r24, 0x56 ; 86 - 3e9c: 29 f4 brne .+10 ; 0x3ea8 + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe // UNIVERSAL command is ignored getNch(4); - 3e9e: 84 e0 ldi r24, 0x04 ; 4 - 3ea0: a4 d0 rcall .+328 ; 0x3fea + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda putch(0x00); - 3ea2: 80 e0 ldi r24, 0x00 ; 0 - 3ea4: 7c d0 rcall .+248 ; 0x3f9e - 3ea6: 78 c0 rjmp .+240 ; 0x3f98 + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 3ea8: 84 36 cpi r24, 0x64 ; 100 - 3eaa: 09 f0 breq .+2 ; 0x3eae - 3eac: 4e c0 rjmp .+156 ; 0x3f4a + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 3eae: 87 d0 rcall .+270 ; 0x3fbe + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 3eb0: e0 91 00 02 lds r30, 0x0200 - 3eb4: f0 91 01 02 lds r31, 0x0201 - 3eb8: 88 e3 ldi r24, 0x38 ; 56 - 3eba: e0 30 cpi r30, 0x00 ; 0 - 3ebc: f8 07 cpc r31, r24 - 3ebe: 18 f4 brcc .+6 ; 0x3ec6 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 87 bf out 0x37, r24 ; 55 - 3ec4: e8 95 spm - 3ec6: c0 e0 ldi r28, 0x00 ; 0 - 3ec8: d1 e0 ldi r29, 0x01 ; 1 - + 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 + 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(); - 3eca: 71 d0 rcall .+226 ; 0x3fae - 3ecc: 89 93 st Y+, r24 + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 + 3ee2: 89 93 st Y+, r24 while (--length); - 3ece: 80 91 02 02 lds r24, 0x0202 - 3ed2: 81 50 subi r24, 0x01 ; 1 - 3ed4: 80 93 02 02 sts 0x0202, r24 - 3ed8: 88 23 and r24, r24 - 3eda: b9 f7 brne .-18 ; 0x3eca + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 // 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); - 3edc: e0 91 00 02 lds r30, 0x0200 - 3ee0: f0 91 01 02 lds r31, 0x0201 - 3ee4: 88 e3 ldi r24, 0x38 ; 56 - 3ee6: e0 30 cpi r30, 0x00 ; 0 - 3ee8: f8 07 cpc r31, r24 - 3eea: 18 f0 brcs .+6 ; 0x3ef2 - 3eec: 83 e0 ldi r24, 0x03 ; 3 - 3eee: 87 bf out 0x37, r24 ; 55 - 3ef0: e8 95 spm + 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 + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 3ef2: 75 d0 rcall .+234 ; 0x3fde - + 3ef8: 68 d0 rcall .+208 ; 0x3fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 3ef4: 07 b6 in r0, 0x37 ; 55 - 3ef6: 00 fc sbrc r0, 0 - 3ef8: fd cf rjmp .-6 ; 0x3ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3efa: 40 91 00 02 lds r20, 0x0200 - 3efe: 50 91 01 02 lds r21, 0x0201 + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa + 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; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 3f1c: fa 01 movw r30, r20 3f1e: 0c 01 movw r0, r24 - 3f20: d7 be out 0x37, r13 ; 55 + 3f20: 87 be out 0x37, r8 ; 55 3f22: e8 95 spm 3f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 3f2c: a0 38 cpi r26, 0x80 ; 128 3f2e: bf 07 cpc r27, r31 3f30: 51 f7 brne .-44 ; 0x3f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 3f32: e0 91 00 02 lds r30, 0x0200 - 3f36: f0 91 01 02 lds r31, 0x0201 - 3f3a: e7 be out 0x37, r14 ; 55 - 3f3c: e8 95 spm + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm boot_spm_busy_wait(); - 3f3e: 07 b6 in r0, 0x37 ; 55 - 3f40: 00 fc sbrc r0, 0 - 3f42: fd cf rjmp .-6 ; 0x3f3e + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 3f44: f7 be out 0x37, r15 ; 55 - 3f46: e8 95 spm - 3f48: 27 c0 rjmp .+78 ; 0x3f98 + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 3f4a: 84 37 cpi r24, 0x74 ; 116 - 3f4c: b9 f4 brne .+46 ; 0x3f7c + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 // READ PAGE - we only read flash - getLen(); - 3f4e: 37 d0 rcall .+110 ; 0x3fbe + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 + verifySpace(); - 3f50: 46 d0 rcall .+140 ; 0x3fde + 3f50: 3c d0 rcall .+120 ; 0x3fca + 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++)); - 3f52: e0 91 00 02 lds r30, 0x0200 - 3f56: f0 91 01 02 lds r31, 0x0201 - 3f5a: 31 96 adiw r30, 0x01 ; 1 - 3f5c: f0 93 01 02 sts 0x0201, r31 - 3f60: e0 93 00 02 sts 0x0200, r30 - 3f64: 31 97 sbiw r30, 0x01 ; 1 - 3f66: e4 91 lpm r30, Z+ - 3f68: 8e 2f mov r24, r30 - 3f6a: 19 d0 rcall .+50 ; 0x3f9e + 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 while (--length); - 3f6c: 80 91 02 02 lds r24, 0x0202 - 3f70: 81 50 subi r24, 0x01 ; 1 - 3f72: 80 93 02 02 sts 0x0202, r24 - 3f76: 88 23 and r24, r24 - 3f78: 61 f7 brne .-40 ; 0x3f52 - 3f7a: 0e c0 rjmp .+28 ; 0x3f98 + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 +#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 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 3f7c: 85 37 cpi r24, 0x75 ; 117 - 3f7e: 39 f4 brne .+14 ; 0x3f8e + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 3f80: 2e d0 rcall .+92 ; 0x3fde + 3f78: 28 d0 rcall .+80 ; 0x3fca putch(SIGNATURE_0); - 3f82: 8e e1 ldi r24, 0x1E ; 30 - 3f84: 0c d0 rcall .+24 ; 0x3f9e + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 putch(SIGNATURE_1); - 3f86: 84 e9 ldi r24, 0x94 ; 148 - 3f88: 0a d0 rcall .+20 ; 0x3f9e + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 putch(SIGNATURE_2); - 3f8a: 86 e0 ldi r24, 0x06 ; 6 - 3f8c: 8b cf rjmp .-234 ; 0x3ea4 + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a } else if (ch == 'Q') { - 3f8e: 81 35 cpi r24, 0x51 ; 81 - 3f90: 11 f4 brne .+4 ; 0x3f96 + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 3f92: 88 e0 ldi r24, 0x08 ; 8 - 3f94: 19 d0 rcall .+50 ; 0x3fc8 + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 3f96: 23 d0 rcall .+70 ; 0x3fde + 3f8e: 1d d0 rcall .+58 ; 0x3fca } putch(STK_OK); - 3f98: 80 e1 ldi r24, 0x10 ; 16 - 3f9a: 01 d0 rcall .+2 ; 0x3f9e - 3f9c: 5c cf rjmp .-328 ; 0x3e56 + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 + 3f94: 65 cf rjmp .-310 ; 0x3e60 -00003f9e : +00003f96 : } } void putch(char ch) { - 3f9e: 98 2f mov r25, r24 + 3f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 3fa0: 80 91 c0 00 lds r24, 0x00C0 - 3fa4: 85 ff sbrs r24, 5 - 3fa6: fc cf rjmp .-8 ; 0x3fa0 + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 UDR0 = ch; - 3fa8: 90 93 c6 00 sts 0x00C6, r25 + 3fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 3fac: 08 95 ret + 3fa4: 08 95 ret -00003fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fae: a8 95 wdr +00003fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 3fb0: 80 91 c0 00 lds r24, 0x00C0 - 3fb4: 87 ff sbrs r24, 7 - 3fb6: fc cf rjmp .-8 ; 0x3fb0 + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 +} +#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); @@ -474,79 +526,73 @@ void watchdogReset() { } 3fbc: 08 95 ret -00003fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fbe: f7 df rcall .-18 ; 0x3fae - length = getch(); - 3fc0: f6 df rcall .-20 ; 0x3fae - 3fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc6: f3 cf rjmp .-26 ; 0x3fae - -00003fc8 : +00003fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 3fc8: e0 e6 ldi r30, 0x60 ; 96 - 3fca: f0 e0 ldi r31, 0x00 ; 0 - 3fcc: 98 e1 ldi r25, 0x18 ; 24 - 3fce: 90 83 st Z, r25 + 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; - 3fd0: 80 83 st Z, r24 + 3fc6: 80 83 st Z, r24 } - 3fd2: 08 95 ret + 3fc8: 08 95 ret -00003fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd4: 80 e0 ldi r24, 0x00 ; 0 - 3fd6: f8 df rcall .-16 ; 0x3fc8 - __asm__ __volatile__ ( - 3fd8: ee 27 eor r30, r30 - 3fda: ff 27 eor r31, r31 - 3fdc: 09 94 ijmp - -00003fde : +00003fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fde: e7 df rcall .-50 ; 0x3fae - 3fe0: 80 32 cpi r24, 0x20 ; 32 - 3fe2: 09 f0 breq .+2 ; 0x3fe6 - 3fe4: f7 df rcall .-18 ; 0x3fd4 + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe + 3fd4: ff cf rjmp .-2 ; 0x3fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 3fe6: 84 e1 ldi r24, 0x14 ; 20 + 3fd6: 84 e1 ldi r24, 0x14 ; 20 } - 3fe8: da cf rjmp .-76 ; 0x3f9e + 3fd8: de cf rjmp .-68 ; 0x3f96 -00003fea : +00003fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 3fea: 1f 93 push r17 - 3fec: 18 2f mov r17, r24 + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 do getch(); while (--count); - 3fee: df df rcall .-66 ; 0x3fae - 3ff0: 11 50 subi r17, 0x01 ; 1 - 3ff2: e9 f7 brne .-6 ; 0x3fee + 3fde: e3 df rcall .-58 ; 0x3fa6 + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde verifySpace(); - 3ff4: f4 df rcall .-24 ; 0x3fde + 3fe4: f2 df rcall .-28 ; 0x3fca } - 3ff6: 1f 91 pop r17 - 3ff8: 08 95 ret + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea : + 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 + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex b/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex index 18d8d9f..6d41124 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex +++ b/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex @@ -1,34 +1,35 @@ -:103E000084B714BE81FFE6D085E08093810082E014 -:103E10008093C00088E18093C10086E08093C20057 -:103E200085E18093C4008EE0CFD0259A86E02CE314 -:103E30003BEF91E0309385002093840096BBB09BCC -:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 -:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 -:103E600083E020C0823411F484E103C0853419F466 -:103E700085E0BBD091C0853581F499D0082F10E042 -:103E800096D090E0982F8827802B912B880F991F30 -:103E900090930102809300027EC0863529F484E06D -:103EA000A4D080E07CD078C0843609F04EC087D0A2 -:103EB000E0910002F091010288E3E030F80718F485 -:103EC00083E087BFE895C0E0D1E071D0899380910D -:103ED00002028150809302028823B9F7E091000228 -:103EE000F091010288E3E030F80718F083E087BF23 -:103EF000E89575D007B600FCFDCF409100025091C7 -:103F00000102A0E0B1E02C9130E011968C91119764 +:103E0000112484B714BE81FFF0D085E08093810037 +:103E100082E08093C00088E18093C10086E08093B7 +:103E2000C20085E18093C4008EE0C9D0259A86E067 +:103E30002CE33BEF91E0309385002093840096BB08 +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27 +:103E6000A2D0813461F49FD0082FAFD0023811F076 +:103E7000013811F484E001C083E08DD089C0823420 +:103E800011F484E103C0853419F485E0A6D080C024 +:103E9000853579F488D0E82EFF2485D0082F10E0EE +:103EA000102F00270E291F29000F111F8ED0680127 +:103EB0006FC0863521F484E090D080E0DECF843678 +:103EC00009F040C070D06FD0082F6DD080E0C816C8 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14 +:103F0000A601A0E0B1E02C9130E011968C911197C0 :103F100090E0982F8827822B932B1296FA010C01A0 -:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 -:103F300051F7E0910002F0910102E7BEE89507B663 -:103F400000FCFDCFF7BEE89527C08437B9F437D021 -:103F500046D0E0910002F09101023196F093010207 -:103F6000E09300023197E4918E2F19D080910202E4 -:103F7000815080930202882361F70EC0853739F49F -:103F80002ED08EE10CD084E90AD086E08BCF81352B -:103F900011F488E019D023D080E101D05CCF982FB4 -:103FA0008091C00085FFFCCF9093C6000895A8952E -:103FB0008091C00087FFFCCF8091C6000895F7DF95 -:103FC000F6DF80930202F3CFE0E6F0E098E1908321 -:103FD0008083089580E0F8DFEE27FF270994E7DF6C -:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B -:0A3FF0001150E9F7F4DF1F91089566 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED +:103F80000AD086E07ACF813511F488E018D01DD0B0 +:103F900080E101D065CF982F8091C00085FFFCCFD4 +:103FA0009093C60008958091C00087FFFCCF809158 +:103FB000C00084FD01C0A8958091C6000895E0E688 +:103FC000F0E098E1908380830895EDDF803219F06E +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736 +:043FF000FF2709940A +:023FFE000404B9 :0400000300003E00BB :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst b/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst index 4cf0332..9d19fb5 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst +++ b/optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst @@ -3,25 +3,27 @@ optiboot_pro_20mhz.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00003e00 00003e00 00000054 2**1 + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 3e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 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; - 3e02: 14 be out 0x34, r1 ; 52 + 3e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 3e04: 81 ff sbrs r24, 1 - 3e06: e6 d0 rcall .+460 ; 0x3fd4 + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 3e08: 85 e0 ldi r24, 0x05 ; 5 - 3e0a: 80 93 81 00 sts 0x0081, r24 + 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 - 3e0e: 82 e0 ldi r24, 0x02 ; 2 - 3e10: 80 93 c0 00 sts 0x00C0, r24 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e14: 88 e1 ldi r24, 0x18 ; 24 - 3e16: 80 93 c1 00 sts 0x00C1, r24 + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e1a: 86 e0 ldi r24, 0x06 ; 6 - 3e1c: 80 93 c2 00 sts 0x00C2, r24 + 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 ); - 3e20: 85 e1 ldi r24, 0x15 ; 21 - 3e22: 80 93 c4 00 sts 0x00C4, r24 + 3e22: 85 e1 ldi r24, 0x15 ; 21 + 3e24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 3e26: 8e e0 ldi r24, 0x0E ; 14 - 3e28: cf d0 rcall .+414 ; 0x3fc8 + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 + 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)); - 3e2e: 2c e3 ldi r18, 0x3C ; 60 - 3e30: 3b ef ldi r19, 0xFB ; 251 + 3e30: 2c e3 ldi r18, 0x3C ; 60 + 3e32: 3b ef ldi r19, 0xFB ; 251 TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 + 3e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 + 3e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 3e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 3e44: a8 95 wdr + 3e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 + 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); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 + 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(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 + 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(); - 3e56: ab d0 rcall .+342 ; 0x3fae + 3e60: a2 d0 rcall .+324 ; 0x3fa6 if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: c5 d0 rcall .+394 ; 0x3fea - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 20 c0 rjmp .+64 ; 0x3ea4 + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 + /* + * 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 + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a + } 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 + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 + } } else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 // SET DEVICE is ignored getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c } else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 // SET DEVICE EXT is ignored getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: bb d0 rcall .+374 ; 0x3fea - 3e74: 91 c0 rjmp .+290 ; 0x3f98 + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 } else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: 81 f4 brne .+32 ; 0x3e9a + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 3e7a: 99 d0 rcall .+306 ; 0x3fae + 3e94: 88 d0 rcall .+272 ; 0x3fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 96 d0 rcall .+300 ; 0x3fae - 3e82: 90 e0 ldi r25, 0x00 ; 0 - 3e84: 98 2f mov r25, r24 - 3e86: 88 27 eor r24, r24 - 3e88: 80 2b or r24, r16 - 3e8a: 91 2b or r25, r17 + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 + 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 - 3e8c: 88 0f add r24, r24 - 3e8e: 99 1f adc r25, r25 + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 address = newAddress; - 3e90: 90 93 01 02 sts 0x0201, r25 - 3e94: 80 93 00 02 sts 0x0200, r24 - 3e98: 7e c0 rjmp .+252 ; 0x3f96 verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 } else if(ch == STK_UNIVERSAL) { - 3e9a: 86 35 cpi r24, 0x56 ; 86 - 3e9c: 29 f4 brne .+10 ; 0x3ea8 + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe // UNIVERSAL command is ignored getNch(4); - 3e9e: 84 e0 ldi r24, 0x04 ; 4 - 3ea0: a4 d0 rcall .+328 ; 0x3fea + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda putch(0x00); - 3ea2: 80 e0 ldi r24, 0x00 ; 0 - 3ea4: 7c d0 rcall .+248 ; 0x3f9e - 3ea6: 78 c0 rjmp .+240 ; 0x3f98 + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 3ea8: 84 36 cpi r24, 0x64 ; 100 - 3eaa: 09 f0 breq .+2 ; 0x3eae - 3eac: 4e c0 rjmp .+156 ; 0x3f4a + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 3eae: 87 d0 rcall .+270 ; 0x3fbe + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 3eb0: e0 91 00 02 lds r30, 0x0200 - 3eb4: f0 91 01 02 lds r31, 0x0201 - 3eb8: 88 e3 ldi r24, 0x38 ; 56 - 3eba: e0 30 cpi r30, 0x00 ; 0 - 3ebc: f8 07 cpc r31, r24 - 3ebe: 18 f4 brcc .+6 ; 0x3ec6 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 87 bf out 0x37, r24 ; 55 - 3ec4: e8 95 spm - 3ec6: c0 e0 ldi r28, 0x00 ; 0 - 3ec8: d1 e0 ldi r29, 0x01 ; 1 - + 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 + 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(); - 3eca: 71 d0 rcall .+226 ; 0x3fae - 3ecc: 89 93 st Y+, r24 + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 + 3ee2: 89 93 st Y+, r24 while (--length); - 3ece: 80 91 02 02 lds r24, 0x0202 - 3ed2: 81 50 subi r24, 0x01 ; 1 - 3ed4: 80 93 02 02 sts 0x0202, r24 - 3ed8: 88 23 and r24, r24 - 3eda: b9 f7 brne .-18 ; 0x3eca + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 // 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); - 3edc: e0 91 00 02 lds r30, 0x0200 - 3ee0: f0 91 01 02 lds r31, 0x0201 - 3ee4: 88 e3 ldi r24, 0x38 ; 56 - 3ee6: e0 30 cpi r30, 0x00 ; 0 - 3ee8: f8 07 cpc r31, r24 - 3eea: 18 f0 brcs .+6 ; 0x3ef2 - 3eec: 83 e0 ldi r24, 0x03 ; 3 - 3eee: 87 bf out 0x37, r24 ; 55 - 3ef0: e8 95 spm + 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 + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 3ef2: 75 d0 rcall .+234 ; 0x3fde - + 3ef8: 68 d0 rcall .+208 ; 0x3fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 3ef4: 07 b6 in r0, 0x37 ; 55 - 3ef6: 00 fc sbrc r0, 0 - 3ef8: fd cf rjmp .-6 ; 0x3ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3efa: 40 91 00 02 lds r20, 0x0200 - 3efe: 50 91 01 02 lds r21, 0x0201 + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa + 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; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 3f1c: fa 01 movw r30, r20 3f1e: 0c 01 movw r0, r24 - 3f20: d7 be out 0x37, r13 ; 55 + 3f20: 87 be out 0x37, r8 ; 55 3f22: e8 95 spm 3f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 3f2c: a0 38 cpi r26, 0x80 ; 128 3f2e: bf 07 cpc r27, r31 3f30: 51 f7 brne .-44 ; 0x3f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 3f32: e0 91 00 02 lds r30, 0x0200 - 3f36: f0 91 01 02 lds r31, 0x0201 - 3f3a: e7 be out 0x37, r14 ; 55 - 3f3c: e8 95 spm + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm boot_spm_busy_wait(); - 3f3e: 07 b6 in r0, 0x37 ; 55 - 3f40: 00 fc sbrc r0, 0 - 3f42: fd cf rjmp .-6 ; 0x3f3e + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 3f44: f7 be out 0x37, r15 ; 55 - 3f46: e8 95 spm - 3f48: 27 c0 rjmp .+78 ; 0x3f98 + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 3f4a: 84 37 cpi r24, 0x74 ; 116 - 3f4c: b9 f4 brne .+46 ; 0x3f7c + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 // READ PAGE - we only read flash - getLen(); - 3f4e: 37 d0 rcall .+110 ; 0x3fbe + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 + verifySpace(); - 3f50: 46 d0 rcall .+140 ; 0x3fde + 3f50: 3c d0 rcall .+120 ; 0x3fca + 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++)); - 3f52: e0 91 00 02 lds r30, 0x0200 - 3f56: f0 91 01 02 lds r31, 0x0201 - 3f5a: 31 96 adiw r30, 0x01 ; 1 - 3f5c: f0 93 01 02 sts 0x0201, r31 - 3f60: e0 93 00 02 sts 0x0200, r30 - 3f64: 31 97 sbiw r30, 0x01 ; 1 - 3f66: e4 91 lpm r30, Z+ - 3f68: 8e 2f mov r24, r30 - 3f6a: 19 d0 rcall .+50 ; 0x3f9e + 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 while (--length); - 3f6c: 80 91 02 02 lds r24, 0x0202 - 3f70: 81 50 subi r24, 0x01 ; 1 - 3f72: 80 93 02 02 sts 0x0202, r24 - 3f76: 88 23 and r24, r24 - 3f78: 61 f7 brne .-40 ; 0x3f52 - 3f7a: 0e c0 rjmp .+28 ; 0x3f98 + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 +#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 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 3f7c: 85 37 cpi r24, 0x75 ; 117 - 3f7e: 39 f4 brne .+14 ; 0x3f8e + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 3f80: 2e d0 rcall .+92 ; 0x3fde + 3f78: 28 d0 rcall .+80 ; 0x3fca putch(SIGNATURE_0); - 3f82: 8e e1 ldi r24, 0x1E ; 30 - 3f84: 0c d0 rcall .+24 ; 0x3f9e + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 putch(SIGNATURE_1); - 3f86: 84 e9 ldi r24, 0x94 ; 148 - 3f88: 0a d0 rcall .+20 ; 0x3f9e + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 putch(SIGNATURE_2); - 3f8a: 86 e0 ldi r24, 0x06 ; 6 - 3f8c: 8b cf rjmp .-234 ; 0x3ea4 + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a } else if (ch == 'Q') { - 3f8e: 81 35 cpi r24, 0x51 ; 81 - 3f90: 11 f4 brne .+4 ; 0x3f96 + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 3f92: 88 e0 ldi r24, 0x08 ; 8 - 3f94: 19 d0 rcall .+50 ; 0x3fc8 + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 3f96: 23 d0 rcall .+70 ; 0x3fde + 3f8e: 1d d0 rcall .+58 ; 0x3fca } putch(STK_OK); - 3f98: 80 e1 ldi r24, 0x10 ; 16 - 3f9a: 01 d0 rcall .+2 ; 0x3f9e - 3f9c: 5c cf rjmp .-328 ; 0x3e56 + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 + 3f94: 65 cf rjmp .-310 ; 0x3e60 -00003f9e : +00003f96 : } } void putch(char ch) { - 3f9e: 98 2f mov r25, r24 + 3f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 3fa0: 80 91 c0 00 lds r24, 0x00C0 - 3fa4: 85 ff sbrs r24, 5 - 3fa6: fc cf rjmp .-8 ; 0x3fa0 + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 UDR0 = ch; - 3fa8: 90 93 c6 00 sts 0x00C6, r25 + 3fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 3fac: 08 95 ret + 3fa4: 08 95 ret -00003fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fae: a8 95 wdr +00003fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 3fb0: 80 91 c0 00 lds r24, 0x00C0 - 3fb4: 87 ff sbrs r24, 7 - 3fb6: fc cf rjmp .-8 ; 0x3fb0 + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 +} +#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); @@ -474,79 +526,73 @@ void watchdogReset() { } 3fbc: 08 95 ret -00003fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fbe: f7 df rcall .-18 ; 0x3fae - length = getch(); - 3fc0: f6 df rcall .-20 ; 0x3fae - 3fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc6: f3 cf rjmp .-26 ; 0x3fae - -00003fc8 : +00003fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 3fc8: e0 e6 ldi r30, 0x60 ; 96 - 3fca: f0 e0 ldi r31, 0x00 ; 0 - 3fcc: 98 e1 ldi r25, 0x18 ; 24 - 3fce: 90 83 st Z, r25 + 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; - 3fd0: 80 83 st Z, r24 + 3fc6: 80 83 st Z, r24 } - 3fd2: 08 95 ret + 3fc8: 08 95 ret -00003fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd4: 80 e0 ldi r24, 0x00 ; 0 - 3fd6: f8 df rcall .-16 ; 0x3fc8 - __asm__ __volatile__ ( - 3fd8: ee 27 eor r30, r30 - 3fda: ff 27 eor r31, r31 - 3fdc: 09 94 ijmp - -00003fde : +00003fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fde: e7 df rcall .-50 ; 0x3fae - 3fe0: 80 32 cpi r24, 0x20 ; 32 - 3fe2: 09 f0 breq .+2 ; 0x3fe6 - 3fe4: f7 df rcall .-18 ; 0x3fd4 + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe + 3fd4: ff cf rjmp .-2 ; 0x3fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 3fe6: 84 e1 ldi r24, 0x14 ; 20 + 3fd6: 84 e1 ldi r24, 0x14 ; 20 } - 3fe8: da cf rjmp .-76 ; 0x3f9e + 3fd8: de cf rjmp .-68 ; 0x3f96 -00003fea : +00003fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 3fea: 1f 93 push r17 - 3fec: 18 2f mov r17, r24 + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 do getch(); while (--count); - 3fee: df df rcall .-66 ; 0x3fae - 3ff0: 11 50 subi r17, 0x01 ; 1 - 3ff2: e9 f7 brne .-6 ; 0x3fee + 3fde: e3 df rcall .-58 ; 0x3fa6 + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde verifySpace(); - 3ff4: f4 df rcall .-24 ; 0x3fde + 3fe4: f2 df rcall .-28 ; 0x3fca } - 3ff6: 1f 91 pop r17 - 3ff8: 08 95 ret + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea : + 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 + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex b/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex index 0d773dd..3cb2549 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex +++ b/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex @@ -1,34 +1,35 @@ -:103E000084B714BE81FFE6D085E08093810082E014 -:103E10008093C00088E18093C10086E08093C20057 -:103E200088E08093C4008EE0CFD0259A86E028E118 -:103E30003EEF91E0309385002093840096BBB09BC9 -:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 -:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 -:103E600083E020C0823411F484E103C0853419F466 -:103E700085E0BBD091C0853581F499D0082F10E042 -:103E800096D090E0982F8827802B912B880F991F30 -:103E900090930102809300027EC0863529F484E06D -:103EA000A4D080E07CD078C0843609F04EC087D0A2 -:103EB000E0910002F091010288E3E030F80718F485 -:103EC00083E087BFE895C0E0D1E071D0899380910D -:103ED00002028150809302028823B9F7E091000228 -:103EE000F091010288E3E030F80718F083E087BF23 -:103EF000E89575D007B600FCFDCF409100025091C7 -:103F00000102A0E0B1E02C9130E011968C91119764 +:103E0000112484B714BE81FFF0D085E08093810037 +:103E100082E08093C00088E18093C10086E08093B7 +:103E2000C20088E08093C4008EE0C9D0259A86E065 +:103E300028E13EEF91E0309385002093840096BB0B +:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404 +:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27 +:103E6000A2D0813461F49FD0082FAFD0023811F076 +:103E7000013811F484E001C083E08DD089C0823420 +:103E800011F484E103C0853419F485E0A6D080C024 +:103E9000853579F488D0E82EFF2485D0082F10E0EE +:103EA000102F00270E291F29000F111F8ED0680127 +:103EB0006FC0863521F484E090D080E0DECF843678 +:103EC00009F040C070D06FD0082F6DD080E0C816C8 +:103ED00088E3D80618F4F601B7BEE895C0E0D1E053 +:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614 +:103EF00018F0F601B7BEE89568D007B600FCFDCF14 +:103F0000A601A0E0B1E02C9130E011968C911197C0 :103F100090E0982F8827822B932B1296FA010C01A0 -:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 -:103F300051F7E0910002F0910102E7BEE89507B663 -:103F400000FCFDCFF7BEE89527C08437B9F437D021 -:103F500046D0E0910002F09101023196F093010207 -:103F6000E09300023197E4918E2F19D080910202E4 -:103F7000815080930202882361F70EC0853739F49F -:103F80002ED08EE10CD084E90AD086E08BCF81352B -:103F900011F488E019D023D080E101D05CCF982FB4 -:103FA0008091C00085FFFCCF9093C6000895A8952E -:103FB0008091C00087FFFCCF8091C6000895F7DF95 -:103FC000F6DF80930202F3CFE0E6F0E098E1908321 -:103FD0008083089580E0F8DFEE27FF270994E7DF6C -:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B -:0A3FF0001150E9F7F4DF1F91089566 +:103F200087BEE89511244E5F5F4FF1E0A038BF07D0 +:103F300051F7F601A7BEE89507B600FCFDCF97BE86 +:103F4000E89526C08437B1F42ED02DD0F82E2BD092 +:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7 +:103F6000EA94F801C1F70894C11CD11CFA94CF0C53 +:103F7000D11C0EC0853739F428D08EE10CD084E9ED +:103F80000AD086E07ACF813511F488E018D01DD0B0 +:103F900080E101D065CF982F8091C00085FFFCCFD4 +:103FA0009093C60008958091C00087FFFCCF809158 +:103FB000C00084FD01C0A8958091C6000895E0E688 +:103FC000F0E098E1908380830895EDDF803219F06E +:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A +:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736 +:043FF000FF2709940A +:023FFE000404B9 :0400000300003E00BB :00000001FF diff --git a/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst b/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst index 86256bf..e6b1726 100644 --- a/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst +++ b/optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst @@ -3,25 +3,27 @@ optiboot_pro_8MHz.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001fa 00003e00 00003e00 00000054 2**1 + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 0000024e 2**0 + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000284 00000000 00000000 000002e0 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003e4 00000000 00000000 00000712 2**0 + 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000141 00000000 00000000 00000b88 2**0 + 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: @@ -33,266 +35,293 @@ Disassembly of section .text: /* main program starts here */ int main(void) { - 3e00: 84 b7 in r24, 0x34 ; 52 - - uint8_t ch; + 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; - 3e02: 14 be out 0x34, r1 ; 52 + 3e04: 14 be out 0x34, r1 ; 52 if (!(ch & _BV(EXTRF))) appStart(); - 3e04: 81 ff sbrs r24, 1 - 3e06: e6 d0 rcall .+460 ; 0x3fd4 + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 3e08: 85 e0 ldi r24, 0x05 ; 5 - 3e0a: 80 93 81 00 sts 0x0081, r24 + 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 - 3e0e: 82 e0 ldi r24, 0x02 ; 2 - 3e10: 80 93 c0 00 sts 0x00C0, r24 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e14: 88 e1 ldi r24, 0x18 ; 24 - 3e16: 80 93 c1 00 sts 0x00C1, r24 + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e1a: 86 e0 ldi r24, 0x06 ; 6 - 3e1c: 80 93 c2 00 sts 0x00C2, r24 + 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 ); - 3e20: 88 e0 ldi r24, 0x08 ; 8 - 3e22: 80 93 c4 00 sts 0x00C4, r24 + 3e22: 88 e0 ldi r24, 0x08 ; 8 + 3e24: 80 93 c4 00 sts 0x00C4, r24 #endif #endif // Set up watchdog to trigger after 500ms watchdogConfig(WATCHDOG_1S); - 3e26: 8e e0 ldi r24, 0x0E ; 14 - 3e28: cf d0 rcall .+414 ; 0x3fc8 + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe /* Set LED pin as output */ LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 + 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)); - 3e2e: 28 e1 ldi r18, 0x18 ; 24 - 3e30: 3e ef ldi r19, 0xFE ; 254 + 3e30: 28 e1 ldi r18, 0x18 ; 24 + 3e32: 3e ef ldi r19, 0xFE ; 254 TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 + 3e34: 91 e0 ldi r25, 0x01 ; 1 } #if LED_START_FLASHES > 0 void flash_led(uint8_t count) { do { TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 + 3e3e: 96 bb out 0x16, r25 ; 22 while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 #ifdef __AVR_ATmega8__ LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); + 3e44: 1d 9a sbi 0x03, 5 ; 3 } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( - 3e44: a8 95 wdr + 3e46: a8 95 wdr LED_PORT ^= _BV(LED); #else LED_PIN |= _BV(LED); #endif watchdogReset(); } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 + 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); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 + 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(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 + 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(); - 3e56: ab d0 rcall .+342 ; 0x3fae + 3e60: a2 d0 rcall .+324 ; 0x3fa6 if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: c5 d0 rcall .+394 ; 0x3fea - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 20 c0 rjmp .+64 ; 0x3ea4 + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 + /* + * 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 + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a + } 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 + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 + } } else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 // SET DEVICE is ignored getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c } else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 // SET DEVICE EXT is ignored getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: bb d0 rcall .+374 ; 0x3fea - 3e74: 91 c0 rjmp .+290 ; 0x3f98 + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 } else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: 81 f4 brne .+32 ; 0x3e9a + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 // LOAD ADDRESS uint16_t newAddress; newAddress = getch(); - 3e7a: 99 d0 rcall .+306 ; 0x3fae + 3e94: 88 d0 rcall .+272 ; 0x3fa6 newAddress = (newAddress & 0xff) | (getch() << 8); - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 96 d0 rcall .+300 ; 0x3fae - 3e82: 90 e0 ldi r25, 0x00 ; 0 - 3e84: 98 2f mov r25, r24 - 3e86: 88 27 eor r24, r24 - 3e88: 80 2b or r24, r16 - 3e8a: 91 2b or r25, r17 + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 + 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 - 3e8c: 88 0f add r24, r24 - 3e8e: 99 1f adc r25, r25 + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 address = newAddress; - 3e90: 90 93 01 02 sts 0x0201, r25 - 3e94: 80 93 00 02 sts 0x0200, r24 - 3e98: 7e c0 rjmp .+252 ; 0x3f96 verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 } else if(ch == STK_UNIVERSAL) { - 3e9a: 86 35 cpi r24, 0x56 ; 86 - 3e9c: 29 f4 brne .+10 ; 0x3ea8 + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe // UNIVERSAL command is ignored getNch(4); - 3e9e: 84 e0 ldi r24, 0x04 ; 4 - 3ea0: a4 d0 rcall .+328 ; 0x3fea + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda putch(0x00); - 3ea2: 80 e0 ldi r24, 0x00 ; 0 - 3ea4: 7c d0 rcall .+248 ; 0x3f9e - 3ea6: 78 c0 rjmp .+240 ; 0x3f98 + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a } /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 3ea8: 84 36 cpi r24, 0x64 ; 100 - 3eaa: 09 f0 breq .+2 ; 0x3eae - 3eac: 4e c0 rjmp .+156 ; 0x3f4a + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 3eae: 87 d0 rcall .+270 ; 0x3fbe + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 // If we are in RWW section, immediately start page erase if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); - 3eb0: e0 91 00 02 lds r30, 0x0200 - 3eb4: f0 91 01 02 lds r31, 0x0201 - 3eb8: 88 e3 ldi r24, 0x38 ; 56 - 3eba: e0 30 cpi r30, 0x00 ; 0 - 3ebc: f8 07 cpc r31, r24 - 3ebe: 18 f4 brcc .+6 ; 0x3ec6 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 87 bf out 0x37, r24 ; 55 - 3ec4: e8 95 spm - 3ec6: c0 e0 ldi r28, 0x00 ; 0 - 3ec8: d1 e0 ldi r29, 0x01 ; 1 - + 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 + 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(); - 3eca: 71 d0 rcall .+226 ; 0x3fae - 3ecc: 89 93 st Y+, r24 + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 + 3ee2: 89 93 st Y+, r24 while (--length); - 3ece: 80 91 02 02 lds r24, 0x0202 - 3ed2: 81 50 subi r24, 0x01 ; 1 - 3ed4: 80 93 02 02 sts 0x0202, r24 - 3ed8: 88 23 and r24, r24 - 3eda: b9 f7 brne .-18 ; 0x3eca + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 // 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); - 3edc: e0 91 00 02 lds r30, 0x0200 - 3ee0: f0 91 01 02 lds r31, 0x0201 - 3ee4: 88 e3 ldi r24, 0x38 ; 56 - 3ee6: e0 30 cpi r30, 0x00 ; 0 - 3ee8: f8 07 cpc r31, r24 - 3eea: 18 f0 brcs .+6 ; 0x3ef2 - 3eec: 83 e0 ldi r24, 0x03 ; 3 - 3eee: 87 bf out 0x37, r24 ; 55 - 3ef0: e8 95 spm + 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 + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 3ef2: 75 d0 rcall .+234 ; 0x3fde - + 3ef8: 68 d0 rcall .+208 ; 0x3fca + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 3ef4: 07 b6 in r0, 0x37 ; 55 - 3ef6: 00 fc sbrc r0, 0 - 3ef8: fd cf rjmp .-6 ; 0x3ef4 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3efa: 40 91 00 02 lds r20, 0x0200 - 3efe: 50 91 01 02 lds r21, 0x0201 + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa + 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; @@ -323,7 +352,7 @@ int main(void) { __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 3f1c: fa 01 movw r30, r20 3f1e: 0c 01 movw r0, r24 - 3f20: d7 be out 0x37, r13 ; 55 + 3f20: 87 be out 0x37, r8 ; 55 3f22: e8 95 spm 3f24: 11 24 eor r1, r1 addrPtr += 2; @@ -334,136 +363,159 @@ int main(void) { 3f2c: a0 38 cpi r26, 0x80 ; 128 3f2e: bf 07 cpc r27, r31 3f30: 51 f7 brne .-44 ; 0x3f06 - + // Write from programming buffer __boot_page_write_short((uint16_t)(void*)address); - 3f32: e0 91 00 02 lds r30, 0x0200 - 3f36: f0 91 01 02 lds r31, 0x0201 - 3f3a: e7 be out 0x37, r14 ; 55 - 3f3c: e8 95 spm + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm boot_spm_busy_wait(); - 3f3e: 07 b6 in r0, 0x37 ; 55 - 3f40: 00 fc sbrc r0, 0 - 3f42: fd cf rjmp .-6 ; 0x3f3e + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 3f44: f7 be out 0x37, r15 ; 55 - 3f46: e8 95 spm - 3f48: 27 c0 rjmp .+78 ; 0x3f98 + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 3f4a: 84 37 cpi r24, 0x74 ; 116 - 3f4c: b9 f4 brne .+46 ; 0x3f7c + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 // READ PAGE - we only read flash - getLen(); - 3f4e: 37 d0 rcall .+110 ; 0x3fbe + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 + verifySpace(); - 3f50: 46 d0 rcall .+140 ; 0x3fde + 3f50: 3c d0 rcall .+120 ; 0x3fca + 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++)); - 3f52: e0 91 00 02 lds r30, 0x0200 - 3f56: f0 91 01 02 lds r31, 0x0201 - 3f5a: 31 96 adiw r30, 0x01 ; 1 - 3f5c: f0 93 01 02 sts 0x0201, r31 - 3f60: e0 93 00 02 sts 0x0200, r30 - 3f64: 31 97 sbiw r30, 0x01 ; 1 - 3f66: e4 91 lpm r30, Z+ - 3f68: 8e 2f mov r24, r30 - 3f6a: 19 d0 rcall .+50 ; 0x3f9e + 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 while (--length); - 3f6c: 80 91 02 02 lds r24, 0x0202 - 3f70: 81 50 subi r24, 0x01 ; 1 - 3f72: 80 93 02 02 sts 0x0202, r24 - 3f76: 88 23 and r24, r24 - 3f78: 61 f7 brne .-40 ; 0x3f52 - 3f7a: 0e c0 rjmp .+28 ; 0x3f98 + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 +#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 #endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 3f7c: 85 37 cpi r24, 0x75 ; 117 - 3f7e: 39 f4 brne .+14 ; 0x3f8e + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 // READ SIGN - return what Avrdude wants to hear verifySpace(); - 3f80: 2e d0 rcall .+92 ; 0x3fde + 3f78: 28 d0 rcall .+80 ; 0x3fca putch(SIGNATURE_0); - 3f82: 8e e1 ldi r24, 0x1E ; 30 - 3f84: 0c d0 rcall .+24 ; 0x3f9e + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 putch(SIGNATURE_1); - 3f86: 84 e9 ldi r24, 0x94 ; 148 - 3f88: 0a d0 rcall .+20 ; 0x3f9e + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 putch(SIGNATURE_2); - 3f8a: 86 e0 ldi r24, 0x06 ; 6 - 3f8c: 8b cf rjmp .-234 ; 0x3ea4 + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a } else if (ch == 'Q') { - 3f8e: 81 35 cpi r24, 0x51 ; 81 - 3f90: 11 f4 brne .+4 ; 0x3f96 + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 3f92: 88 e0 ldi r24, 0x08 ; 8 - 3f94: 19 d0 rcall .+50 ; 0x3fc8 + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 3f96: 23 d0 rcall .+70 ; 0x3fde + 3f8e: 1d d0 rcall .+58 ; 0x3fca } putch(STK_OK); - 3f98: 80 e1 ldi r24, 0x10 ; 16 - 3f9a: 01 d0 rcall .+2 ; 0x3f9e - 3f9c: 5c cf rjmp .-328 ; 0x3e56 + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 + 3f94: 65 cf rjmp .-310 ; 0x3e60 -00003f9e : +00003f96 : } } void putch(char ch) { - 3f9e: 98 2f mov r25, r24 + 3f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 3fa0: 80 91 c0 00 lds r24, 0x00C0 - 3fa4: 85 ff sbrs r24, 5 - 3fa6: fc cf rjmp .-8 ; 0x3fa0 + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 UDR0 = ch; - 3fa8: 90 93 c6 00 sts 0x00C6, r25 + 3fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 3fac: 08 95 ret + 3fa4: 08 95 ret -00003fae : - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fae: a8 95 wdr +00003fa6 : [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 3fb0: 80 91 c0 00 lds r24, 0x00C0 - 3fb4: 87 ff sbrs r24, 7 - 3fb6: fc cf rjmp .-8 ; 0x3fb0 + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 +} +#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); @@ -474,79 +526,73 @@ void watchdogReset() { } 3fbc: 08 95 ret -00003fbe : - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fbe: f7 df rcall .-18 ; 0x3fae - length = getch(); - 3fc0: f6 df rcall .-20 ; 0x3fae - 3fc2: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc6: f3 cf rjmp .-26 ; 0x3fae - -00003fc8 : +00003fbe : "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 3fc8: e0 e6 ldi r30, 0x60 ; 96 - 3fca: f0 e0 ldi r31, 0x00 ; 0 - 3fcc: 98 e1 ldi r25, 0x18 ; 24 - 3fce: 90 83 st Z, r25 + 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; - 3fd0: 80 83 st Z, r24 + 3fc6: 80 83 st Z, r24 } - 3fd2: 08 95 ret + 3fc8: 08 95 ret -00003fd4 : - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd4: 80 e0 ldi r24, 0x00 ; 0 - 3fd6: f8 df rcall .-16 ; 0x3fc8 - __asm__ __volatile__ ( - 3fd8: ee 27 eor r30, r30 - 3fda: ff 27 eor r31, r31 - 3fdc: 09 94 ijmp - -00003fde : +00003fca : do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fde: e7 df rcall .-50 ; 0x3fae - 3fe0: 80 32 cpi r24, 0x20 ; 32 - 3fe2: 09 f0 breq .+2 ; 0x3fe6 - 3fe4: f7 df rcall .-18 ; 0x3fd4 + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe + 3fd4: ff cf rjmp .-2 ; 0x3fd4 + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 3fe6: 84 e1 ldi r24, 0x14 ; 20 + 3fd6: 84 e1 ldi r24, 0x14 ; 20 } - 3fe8: da cf rjmp .-76 ; 0x3f9e + 3fd8: de cf rjmp .-68 ; 0x3f96 -00003fea : +00003fda : ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 3fea: 1f 93 push r17 - 3fec: 18 2f mov r17, r24 + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 do getch(); while (--count); - 3fee: df df rcall .-66 ; 0x3fae - 3ff0: 11 50 subi r17, 0x01 ; 1 - 3ff2: e9 f7 brne .-6 ; 0x3fee + 3fde: e3 df rcall .-58 ; 0x3fa6 + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde verifySpace(); - 3ff4: f4 df rcall .-24 ; 0x3fde + 3fe4: f2 df rcall .-28 ; 0x3fca } - 3ff6: 1f 91 pop r17 - 3ff8: 08 95 ret + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea : + 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 + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/optiboot/bootloaders/optiboot/pin_defs.h b/optiboot/bootloaders/optiboot/pin_defs.h index 313e453..27d7772 100644 --- a/optiboot/bootloaders/optiboot/pin_defs.h +++ b/optiboot/bootloaders/optiboot/pin_defs.h @@ -21,6 +21,7 @@ #define UDR0 UDR #define UDRE0 UDRE #define RXC0 RXC + #define FE0 FE #define TIFR1 TIFR #define WDTCSR WDTCR #endif