1
0
mirror of https://github.com/Optiboot/optiboot.git synced 2025-09-05 23:03:58 +03:00

added optiboot/bootloaders/optiboot/README.TXT

added optiboot/bootloaders/optiboot/omake
added optiboot/bootloaders/optiboot/omake.bat
changed optiboot/bootloaders/optiboot/Makefile
changed optiboot/bootloaders/optiboot/makeall
changed optiboot/bootloaders/optiboot/optiboot.c
changed optiboot/bootloaders/optiboot/pin_defs.h

(assorted .hex and .lst files also changed)

This commit syncs up the optiboot mercurial repository with the the
Arduino git repository (as far as optiboot is concerned.)

This should fix (optiboot) issues:
http://code.google.com/p/optiboot/issues/detail?id=1
http://code.google.com/p/optiboot/issues/detail?id=7
http://code.google.com/p/optiboot/issues/detail?id=20
http://code.google.com/p/optiboot/issues/detail?id=23
http://code.google.com/p/optiboot/issues/detail?id=26
http://code.google.com/p/optiboot/issues/detail?id=29
http://code.google.com/p/optiboot/issues/detail?id=30
http://code.google.com/p/optiboot/issues/detail?id=32
http://code.google.com/p/optiboot/issues/detail?id=33
http://code.google.com/p/optiboot/issues/detail?id=34
http://code.google.com/p/optiboot/issues/detail?id=35
http://code.google.com/p/optiboot/issues/detail?id=36
http://code.google.com/p/optiboot/issues/detail?id=37
http://code.google.com/p/optiboot/issues/detail?id=38

See the Arduino commit history for details of which code
changes for which features/bugfix.
This commit is contained in:
Bill Westfield
2011-10-30 01:13:01 -07:00
parent 834898dad0
commit c0bbc7d8a3
27 changed files with 3831 additions and 3116 deletions

View File

@@ -19,13 +19,70 @@
# program name should not be changed... # program name should not be changed...
PROGRAM = optiboot 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 # enter the parameters for the avrdude isp tool
ISPTOOL = stk500v2 ISPTOOL = stk500v2
ISPPORT = usb ISPPORT = usb
ISPSPEED = -b 115200 ISPSPEED = -b 115200
MCU_TARGET = atmega168 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 # the efuse should really be 0xf8; since, however, only the lower
# three bits of that byte are used on the atmega168, avrdude gets # 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/ # 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 # 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 # lock it), but since the high two bits of the lock byte are
# unused, avrdude would get confused. # unused, avrdude would get confused.
ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-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 -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ -e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f: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 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \ 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 = DEFS =
LIBS = LIBS =
CC = avr-gcc CC = $(GCCROOT)avr-gcc
# Override is only needed by avr-lib build system. # Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS) 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 OBJCOPY = $(GCCROOT)avr-objcopy
OBJDUMP = avr-objdump OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
SIZE = $(GCCROOT)avr-size
# Test platforms # Test platforms
# Virtual boot block test # Virtual boot block test
virboot328: TARGET = atmega328 virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p 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: 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.hex
virboot328: $(PROGRAM)_atmega328.lst virboot328: $(PROGRAM)_atmega328.lst
@@ -84,6 +146,7 @@ pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro20: AVR_FREQ = 20000000L pro20: AVR_FREQ = 20000000L
pro20: $(PROGRAM)_pro_20mhz.hex pro20: $(PROGRAM)_pro_20mhz.hex
pro20: $(PROGRAM)_pro_20mhz.lst pro20: $(PROGRAM)_pro_20mhz.lst
pro20_isp: pro20 pro20_isp: pro20
pro20_isp: TARGET = pro_20mhz pro20_isp: TARGET = pro_20mhz
# 2.7V brownout # 2.7V brownout
@@ -105,6 +168,7 @@ pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro16: AVR_FREQ = 16000000L pro16: AVR_FREQ = 16000000L
pro16: $(PROGRAM)_pro_16MHz.hex pro16: $(PROGRAM)_pro_16MHz.hex
pro16: $(PROGRAM)_pro_16MHz.lst pro16: $(PROGRAM)_pro_16MHz.lst
pro16_isp: pro16 pro16_isp: pro16
pro16_isp: TARGET = pro_16MHz pro16_isp: TARGET = pro_16MHz
# 2.7V brownout # 2.7V brownout
@@ -115,13 +179,34 @@ pro16_isp: LFUSE = C6
pro16_isp: EFUSE = 04 pro16_isp: EFUSE = 04
pro16_isp: isp 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: TARGET = diecimila
diecimila: MCU_TARGET = atmega168 diecimila: MCU_TARGET = atmega168
diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
diecimila: AVR_FREQ = 16000000L diecimila: AVR_FREQ = 16000000L
diecimila: $(PROGRAM)_diecimila.hex diecimila: $(PROGRAM)_diecimila.hex
diecimila: $(PROGRAM)_diecimila.lst diecimila: $(PROGRAM)_diecimila.lst
diecimila_isp: diecimila diecimila_isp: diecimila
diecimila_isp: TARGET = diecimila diecimila_isp: TARGET = diecimila
# 2.7V brownout # 2.7V brownout
@@ -136,13 +221,14 @@ atmega328: TARGET = atmega328
atmega328: MCU_TARGET = atmega328p atmega328: MCU_TARGET = atmega328p
atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328: AVR_FREQ = 16000000L 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.hex
atmega328: $(PROGRAM)_atmega328.lst atmega328: $(PROGRAM)_atmega328.lst
atmega328_isp: atmega328 atmega328_isp: atmega328
atmega328_isp: TARGET = atmega328 atmega328_isp: TARGET = atmega328
atmega328_isp: MCU_TARGET = atmega328p atmega328_isp: MCU_TARGET = atmega328p
# 512 byte boot # 512 byte boot, SPIEN
atmega328_isp: HFUSE = DE atmega328_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms # Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_isp: LFUSE = FF atmega328_isp: LFUSE = FF
@@ -151,13 +237,15 @@ atmega328_isp: EFUSE = 05
atmega328_isp: isp atmega328_isp: isp
# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions # Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
#
sanguino: TARGET = atmega644p sanguino: TARGET = atmega644p
sanguino: MCU_TARGET = atmega644p sanguino: MCU_TARGET = atmega644p
sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
sanguino: AVR_FREQ = 16000000L sanguino: AVR_FREQ = 16000000L
sanguino: LDSECTION = --section-start=.text=0xfc00 sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00
sanguino: $(PROGRAM)_atmega644p.hex sanguino: $(PROGRAM)_atmega644p.hex
sanguino: $(PROGRAM)_atmega644p.lst sanguino: $(PROGRAM)_atmega644p.lst
sanguino_isp: sanguino sanguino_isp: sanguino
sanguino_isp: TARGET = atmega644p sanguino_isp: TARGET = atmega644p
sanguino_isp: MCU_TARGET = atmega644p sanguino_isp: MCU_TARGET = atmega644p
@@ -170,13 +258,14 @@ sanguino_isp: EFUSE = 05
sanguino_isp: isp sanguino_isp: isp
# Mega has a minimum boot size of 1024 bytes, so enable extra functions # Mega has a minimum boot size of 1024 bytes, so enable extra functions
mega: TARGET = atmega1280 #mega: TARGET = atmega1280
mega: MCU_TARGET = atmega1280 mega: MCU_TARGET = atmega1280
mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
mega: AVR_FREQ = 16000000L mega: AVR_FREQ = 16000000L
mega: LDSECTION = --section-start=.text=0x1fc00 mega: LDSECTIONS = -Wl,--section-start=.text=0x1fc00
mega: $(PROGRAM)_atmega1280.hex mega: $(PROGRAM)_atmega1280.hex
mega: $(PROGRAM)_atmega1280.lst mega: $(PROGRAM)_atmega1280.lst
mega_isp: mega mega_isp: mega
mega_isp: TARGET = atmega1280 mega_isp: TARGET = atmega1280
mega_isp: MCU_TARGET = atmega1280 mega_isp: MCU_TARGET = atmega1280
@@ -194,25 +283,29 @@ atmega8: TARGET = atmega8
atmega8: MCU_TARGET = atmega8 atmega8: MCU_TARGET = atmega8
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega8: AVR_FREQ = 16000000L 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.hex
atmega8: $(PROGRAM)_atmega8.lst atmega8: $(PROGRAM)_atmega8.lst
atmega8_isp: atmega8 atmega8_isp: atmega8
atmega8_isp: TARGET = atmega8 atmega8_isp: TARGET = atmega8
atmega8_isp: MCU_TARGET = atmega8 atmega8_isp: MCU_TARGET = atmega8
# 2.7V brownout # SPIEN, CKOPT, Bootsize=512B
atmega8_isp: HFUSE = DC atmega8_isp: HFUSE = CC
# Low power xtal (16MHz) 16KCK/14CK+65ms # 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
atmega8_isp: LFUSE = BF atmega8_isp: LFUSE = BF
atmega8_isp: isp atmega8_isp: isp
# ATmega88 # ATmega88
#
atmega88: TARGET = atmega88 atmega88: TARGET = atmega88
atmega88: MCU_TARGET = atmega88 atmega88: MCU_TARGET = atmega88
atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega88: AVR_FREQ = 16000000L atmega88: AVR_FREQ = 16000000L
atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
atmega88: $(PROGRAM)_atmega88.hex atmega88: $(PROGRAM)_atmega88.hex
atmega88: $(PROGRAM)_atmega88.lst atmega88: $(PROGRAM)_atmega88.lst
atmega88_isp: atmega88 atmega88_isp: atmega88
atmega88_isp: TARGET = atmega88 atmega88_isp: TARGET = atmega88
atmega88_isp: MCU_TARGET = atmega88 atmega88_isp: MCU_TARGET = atmega88
@@ -224,6 +317,7 @@ atemga88_isp: LFUSE = FF
atmega88_isp: EFUSE = 04 atmega88_isp: EFUSE = 04
atmega88_isp: isp atmega88_isp: isp
# 8MHz clocked platforms # 8MHz clocked platforms
# #
# These are capable of 115200 baud # These are capable of 115200 baud
@@ -235,6 +329,7 @@ lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
lilypad: AVR_FREQ = 8000000L lilypad: AVR_FREQ = 8000000L
lilypad: $(PROGRAM)_lilypad.hex lilypad: $(PROGRAM)_lilypad.hex
lilypad: $(PROGRAM)_lilypad.lst lilypad: $(PROGRAM)_lilypad.lst
lilypad_isp: lilypad lilypad_isp: lilypad
lilypad_isp: TARGET = lilypad lilypad_isp: TARGET = lilypad
# 2.7V brownout # 2.7V brownout
@@ -242,7 +337,7 @@ lilypad_isp: HFUSE = DD
# Internal 8MHz osc (8MHz) Slow rising power # Internal 8MHz osc (8MHz) Slow rising power
lilypad_isp: LFUSE = E2 lilypad_isp: LFUSE = E2
# 512 byte boot # 512 byte boot
lilypad_isp: EFUSE = 02 lilypad_isp: EFUSE = 04
lilypad_isp: isp lilypad_isp: isp
lilypad_resonator: TARGET = lilypad_resonator 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: AVR_FREQ = 8000000L
lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
lilypad_resonator_isp: lilypad_resonator lilypad_resonator_isp: lilypad_resonator
lilypad_resonator_isp: TARGET = lilypad_resonator lilypad_resonator_isp: TARGET = lilypad_resonator
# 2.7V brownout # 2.7V brownout
@@ -258,7 +354,7 @@ lilypad_resonator_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms # Full swing xtal (20MHz) 258CK/14CK+4.1ms
lilypad_resonator_isp: LFUSE = C6 lilypad_resonator_isp: LFUSE = C6
# 512 byte boot # 512 byte boot
lilypad_resonator_isp: EFUSE = 02 lilypad_resonator_isp: EFUSE = 04
lilypad_resonator_isp: isp lilypad_resonator_isp: isp
pro8: TARGET = pro_8MHz pro8: TARGET = pro_8MHz
@@ -267,6 +363,7 @@ pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro8: AVR_FREQ = 8000000L pro8: AVR_FREQ = 8000000L
pro8: $(PROGRAM)_pro_8MHz.hex pro8: $(PROGRAM)_pro_8MHz.hex
pro8: $(PROGRAM)_pro_8MHz.lst pro8: $(PROGRAM)_pro_8MHz.lst
pro8_isp: pro8 pro8_isp: pro8
pro8_isp: TARGET = pro_8MHz pro8_isp: TARGET = pro_8MHz
# 2.7V brownout # 2.7V brownout
@@ -274,20 +371,21 @@ pro8_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms # Full swing xtal (20MHz) 258CK/14CK+4.1ms
pro8_isp: LFUSE = C6 pro8_isp: LFUSE = C6
# 512 byte boot # 512 byte boot
pro8_isp: EFUSE = 02 pro8_isp: EFUSE = 04
pro8_isp: isp pro8_isp: isp
atmega328_pro8: TARGET = atmega328_pro_8MHz atmega328_pro8: TARGET = atmega328_pro_8MHz
atmega328_pro8: MCU_TARGET = atmega328p atmega328_pro8: MCU_TARGET = atmega328p
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328_pro8: AVR_FREQ = 8000000L 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.hex
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
atmega328_pro8_isp: atmega328_pro8 atmega328_pro8_isp: atmega328_pro8
atmega328_pro8_isp: TARGET = atmega328_pro_8MHz atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
atmega328_pro8_isp: MCU_TARGET = atmega328p atmega328_pro8_isp: MCU_TARGET = atmega328p
# 512 byte boot # 512 byte boot, SPIEN
atmega328_pro8_isp: HFUSE = DE atmega328_pro8_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms # Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_pro8_isp: LFUSE = FF 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 += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION' luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
luminet: AVR_FREQ = 1000000L 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.hex
luminet: $(PROGRAM)_luminet.lst luminet: $(PROGRAM)_luminet.lst
luminet_isp: luminet luminet_isp: luminet
luminet_isp: TARGET = luminet luminet_isp: TARGET = luminet
luminet_isp: MCU_TARGET = attiny84 luminet_isp: MCU_TARGET = attiny84
@@ -334,6 +433,7 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex
%.elf: $(OBJ) %.elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
$(SIZE) $@
clean: clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
@@ -342,10 +442,10 @@ clean:
$(OBJDUMP) -h -S $< > $@ $(OBJDUMP) -h -S $< > $@
%.hex: %.elf %.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 %.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 %.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@ $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@

View File

@@ -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 <targets>" command, which just generates a command that uses
the arduino-included "make" utility with a command like:
make OS=windows ENV=arduino <targets>
or make OS=macosx ENV=arduino <targets>
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 <targets>
or make OS=macosx ENV=arduinodev <targets>
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.

View File

@@ -1,14 +1,20 @@
#!/bin/bash #!/bin/bash
make clean 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
make lilypad_resonator make lilypad_resonator
make pro8 make pro8
make pro16 make pro16
make pro20 make pro20
make diecimila make atmega328_pro8
make atmega328
make sanguino make sanguino
make mega make mega
make atmega8
make atmega88 make atmega88
make luminet make luminet

View File

@@ -0,0 +1,2 @@
echo ../../../tools/avr/bin/make OS=macosx ENV=arduino $*
../../../tools/avr/bin/make OS=macosx ENV=arduino $*

View File

@@ -0,0 +1 @@
..\..\..\tools\avr\utils\bin\make OS=windows ENV=arduino %*

View File

@@ -3,6 +3,9 @@
/* */ /* */
/* http://optiboot.googlecode.com */ /* http://optiboot.googlecode.com */
/* */ /* */
/* Arduino-maintained version : See README.TXT */
/* http://code.google.com/p/arduino/ */
/* */
/* Heavily optimised bootloader that is faster and */ /* Heavily optimised bootloader that is faster and */
/* smaller than the Arduino standard bootloader */ /* smaller than the Arduino standard bootloader */
/* */ /* */
@@ -111,7 +114,45 @@
/* 500,1000,2000,4000,8000 supported. */ /* 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 <inttypes.h> #include <inttypes.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
@@ -120,6 +161,7 @@
// This saves cycles and program memory. // This saves cycles and program memory.
#include "boot.h" #include "boot.h"
// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need. // We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
#include "pin_defs.h" #include "pin_defs.h"
@@ -164,8 +206,8 @@
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE)) #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE)) #define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
#ifndef __AVR_ATmega8__ #ifndef __AVR_ATmega8__
#define WATCHDOG_4S (_BV(WDE3) | _BV(WDE)) #define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDE3) | _BV(WDE0) | _BV(WDE)) #define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
#endif #endif
/* Function Prototypes */ /* Function Prototypes */
@@ -210,8 +252,6 @@ void appStart() __attribute__ ((naked));
/* These definitions are NOT zero initialised, but that doesn't matter */ /* These definitions are NOT zero initialised, but that doesn't matter */
/* This allows us to drop the zero init code, saving us memory */ /* This allows us to drop the zero init code, saving us memory */
#define buff ((uint8_t*)(RAMSTART)) #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 #ifdef VIRTUAL_BOOT_PARTITION
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
@@ -219,6 +259,17 @@ void appStart() __attribute__ ((naked));
/* main program starts here */ /* main program starts here */
int main(void) { 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. // After the zero init loop, this is the first code to run.
// //
// This code makes the following assumptions: // This code makes the following assumptions:
@@ -228,15 +279,11 @@ int main(void) {
// //
// If not, uncomment the following instructions: // If not, uncomment the following instructions:
// cli(); // cli();
asm volatile ("clr __zero_reg__");
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
SP=RAMEND; // This is done by hardware reset SP=RAMEND; // This is done by hardware reset
#endif #endif
// asm volatile ("clr __zero_reg__");
uint8_t ch;
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
MCUSR = 0; MCUSR = 0;
@@ -282,9 +329,22 @@ int main(void) {
ch = getch(); ch = getch();
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); verifySpace();
putch(0x03); 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) { else if(ch == STK_SET_DEVICE) {
// SET DEVICE is ignored // SET DEVICE is ignored
@@ -318,11 +378,13 @@ int main(void) {
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
length = getch();
getch();
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
@@ -334,7 +396,7 @@ int main(void) {
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
@@ -369,7 +431,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
boot_spm_busy_wait(); boot_spm_busy_wait();
@@ -383,7 +445,10 @@ int main(void) {
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
length = getch();
getch();
verifySpace(); verifySpace();
#ifdef VIRTUAL_BOOT_PARTITION #ifdef VIRTUAL_BOOT_PARTITION
do { do {
@@ -468,8 +533,6 @@ void putch(char ch) {
uint8_t getch(void) { uint8_t getch(void) {
uint8_t ch; uint8_t ch;
watchdogReset();
#ifdef LED_DATA_FLASH #ifdef LED_DATA_FLASH
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
@@ -487,7 +550,7 @@ uint8_t getch(void) {
" rcall uartDelay\n" // Wait 1 bit period " rcall uartDelay\n" // Wait 1 bit period
" clc\n" " clc\n"
" sbic %[uartPin],%[uartBit]\n" " sbic %[uartPin],%[uartBit]\n"
" sec\n" " sec\n"
" dec %[bitCnt]\n" " dec %[bitCnt]\n"
" breq 3f\n" " breq 3f\n"
" ror %[ch]\n" " ror %[ch]\n"
@@ -503,7 +566,20 @@ uint8_t getch(void) {
"r25" "r25"
); );
#else #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; ch = UDR0;
#endif #endif
@@ -543,7 +619,11 @@ void getNch(uint8_t count) {
} }
void verifySpace() { 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); putch(STK_INSYNC);
} }
@@ -563,12 +643,6 @@ void flash_led(uint8_t count) {
} }
#endif #endif
uint8_t getLen() {
getch();
length = getch();
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (

View File

@@ -1,36 +1,36 @@
:020000000404F6
:020000021000EC :020000021000EC
:10FC000084B714BE81FFEDD085E08093810082E04F :10FC0000112484B714BE81FFF2D085E08093810077
:10FC10008093C00088E18093C10086E08093C20099 :10FC100082E08093C00088E18093C10086E08093F9
:10FC200080E18093C4008EE0D6D0279A86E020E35E :10FC2000C20080E18093C4008EE0CBD0279A86E0AA
:10FC30003CEF91E0309385002093840096BBB09B0D :10FC300020E33CEF91E0309385002093840096BB55
:10FC4000FECF1F9AA8958150A9F7EE24E394A5E072 :10FC4000B09BFECF1F9AA8958150A9F7CC24DD2444
:10FC5000DA2EF1E1FF2EB2D0813419F481E0CCD05C :10FC500099249394A5E0BA2EF1E1AF2EA6D0813479
:10FC60009BC0823411F484E103C0853419F485E02B :10FC600061F4A3D0082FB3D0023811F0013811F499
:10FC7000C3D099C08535A9F4A1D0082F10E09ED03B :10FC700084E001C083E091D08DC0823411F484E12E
:10FC800090E0982F8827802B912B292F221F222745 :10FC800003C0853419F485E0AAD084C08535A1F479
:10FC9000221F2BBF880F991F9093010480930004AB :10FC90008CD0082F10E089D0E82EFF24FE2CEE2413
:10FCA00081C0863529F484E0A7D080E07FD07BC076 :10FCA000E02AF12A8F2D881F8827881F8BBFEE0C32
:10FCB000843609F04EC08AD0E0910004F09101042E :10FCB000FF1C8DD067016EC0863521F484E08FD0A3
:10FCC00080EEE030F80718F483E087BFE895C0E0E5 :10FCC00080E0D9CF843609F042C06FD06ED0082FC3
:10FCD000D2E074D089938091020481508093020411 :10FCD0006CD080E0C81680EED80620F483E0F601F0
:10FCE0008823B9F7E0910004F091010480EEE03040 :10FCE00087BFE895C0E0D2E060D089930C17E1F7B8
:10FCF000F80718F083E087BFE89578D007B600FCD6 :10FCF000F0E0CF16F0EEDF0620F083E0F60187BFDC
:10FD0000FDCF4091000450910104A0E0B2E02C919D :10FD0000E89565D007B600FCFDCFA601A0E0B2E003
:10FD100030E011968C91119790E0982F8827822BD4 :10FD10002C9130E011968C91119790E0982F8827C4
:10FD2000932B1296FA010C01E7BEE89511244E5F61 :10FD2000822B932B1296FA010C0197BEE8951124B1
:10FD30005F4FF3E0A030BF0751F7E0910004F0916E :10FD30004E5F5F4FF3E0A030BF0751F7F601B7BE4B
:10FD40000104D7BEE89507B600FCFDCFF7BEE895E5 :10FD4000E89507B600FCFDCFA7BEE89523C0843731
:10FD50002AC08437D1F43AD049D0E0910004F09120 :10FD5000A1F42BD02AD0E82E28D039D0E6010E2DE0
:10FD60000104E6918E2F22D080910004909101042D :10FD6000FE0186911AD021960150D1F70894C11C4A
:10FD700001969093010480930004809102048150C5 :10FD7000D11CEA94CE0CD11C0DC0853731F427D0AC
:10FD800080930204882349F70EC0853739F42ED0BA :10FD80008EE10BD087E909D075CF813511F488E079
:10FD90008EE10CD087E90AD083E088CF813511F459 :10FD900018D01DD080E101D061CF982F8091C00094
:10FDA00088E019D023D080E101D055CF982F8091E1 :10FDA00085FFFCCF9093C60008958091C00087FF27
:10FDB000C00085FFFCCF9093C6000895A895809160 :10FDB000FCCF8091C00084FD01C0A8958091C60051
:10FDC000C00087FFFCCF8091C6000895F7DFF6DF03 :10FDC0000895E0E6F0E098E1908380830895EDDF08
:10FDD00080930204F3CFE0E6F0E098E19083808323 :10FDD000803219F088E0F5DFFFCF84E1DECF1F939A
:10FDE000089580E0F8DFEE27FF270994E7DF8032EF :10FDE000182FE3DF1150E9F7F2DF1F91089580E04B
:10FDF00009F0F7DF84E1DACF1F93182FDFDF11500E :08FDF000E8DFEE27FF2709946C
:08FE0000E9F7F4DF1F910895FA
:040000031000FC00ED :040000031000FC00ED
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_atmega1280.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000284 2**0 2 .debug_pubnames 0000005f 00000000 00000000 00000274 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000278 00000000 00000000 000002ee 2**0 3 .debug_info 0000029c 00000000 00000000 000002d3 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001a1 00000000 00000000 00000566 2**0 4 .debug_abbrev 0000016b 00000000 00000000 0000056f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003f4 00000000 00000000 00000707 2**0 5 .debug_line 00000471 00000000 00000000 000006da 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000afc 2**2 6 .debug_frame 00000080 00000000 00000000 00000b4c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000136 00000000 00000000 00000b8c 2**0 7 .debug_str 00000138 00000000 00000000 00000bcc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001b1 00000000 00000000 00000cc2 2**0 8 .debug_loc 000002b3 00000000 00000000 00000d04 2**0
CONTENTS, READONLY, DEBUGGING 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 CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,528 +35,563 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
1fc00: 84 b7 in r24, 0x34 ; 52 1fc00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
1fc02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
1fc02: 14 be out 0x34, r1 ; 52 1fc04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
1fc04: 81 ff sbrs r24, 1 1fc06: 81 ff sbrs r24, 1
1fc06: ed d0 rcall .+474 ; 0x1fde2 <appStart> 1fc08: f2 d0 rcall .+484 ; 0x1fdee <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
1fc08: 85 e0 ldi r24, 0x05 ; 5 1fc0a: 85 e0 ldi r24, 0x05 ; 5
1fc0a: 80 93 81 00 sts 0x0081, r24 1fc0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
1fc0e: 82 e0 ldi r24, 0x02 ; 2 1fc10: 82 e0 ldi r24, 0x02 ; 2
1fc10: 80 93 c0 00 sts 0x00C0, r24 1fc12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
1fc14: 88 e1 ldi r24, 0x18 ; 24 1fc16: 88 e1 ldi r24, 0x18 ; 24
1fc16: 80 93 c1 00 sts 0x00C1, r24 1fc18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
1fc1a: 86 e0 ldi r24, 0x06 ; 6 1fc1c: 86 e0 ldi r24, 0x06 ; 6
1fc1c: 80 93 c2 00 sts 0x00C2, r24 1fc1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
1fc20: 80 e1 ldi r24, 0x10 ; 16 1fc22: 80 e1 ldi r24, 0x10 ; 16
1fc22: 80 93 c4 00 sts 0x00C4, r24 1fc24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
1fc26: 8e e0 ldi r24, 0x0E ; 14 1fc28: 8e e0 ldi r24, 0x0E ; 14
1fc28: d6 d0 rcall .+428 ; 0x1fdd6 <watchdogConfig> 1fc2a: cb d0 rcall .+406 ; 0x1fdc2 <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
1fc2a: 27 9a sbi 0x04, 7 ; 4 1fc2c: 27 9a sbi 0x04, 7 ; 4
1fc2c: 86 e0 ldi r24, 0x06 ; 6 1fc2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
1fc2e: 20 e3 ldi r18, 0x30 ; 48 1fc30: 20 e3 ldi r18, 0x30 ; 48
1fc30: 3c ef ldi r19, 0xFC ; 252 1fc32: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
1fc32: 91 e0 ldi r25, 0x01 ; 1 1fc34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
1fc34: 30 93 85 00 sts 0x0085, r19 1fc36: 30 93 85 00 sts 0x0085, r19
1fc38: 20 93 84 00 sts 0x0084, r18 1fc3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
1fc3c: 96 bb out 0x16, r25 ; 22 1fc3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
1fc3e: b0 9b sbis 0x16, 0 ; 22 1fc40: b0 9b sbis 0x16, 0 ; 22
1fc40: fe cf rjmp .-4 ; 0x1fc3e <main+0x3e> 1fc42: fe cf rjmp .-4 ; 0x1fc40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
1fc42: 1f 9a sbi 0x03, 7 ; 3 1fc44: 1f 9a sbi 0x03, 7 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
1fc44: a8 95 wdr 1fc46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
1fc46: 81 50 subi r24, 0x01 ; 1 1fc48: 81 50 subi r24, 0x01 ; 1
1fc48: a9 f7 brne .-22 ; 0x1fc34 <main+0x34> 1fc4a: a9 f7 brne .-22 ; 0x1fc36 <main+0x36>
/* get character from UART */ 1fc4c: cc 24 eor r12, r12
ch = getch(); 1fc4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
1fc4a: ee 24 eor r14, r14 a |= (*bufPtr++) << 8;
1fc4c: e3 94 inc r14
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
1fc50: 99 24 eor r9, r9
1fc52: 93 94 inc r9
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
1fc4e: a5 e0 ldi r26, 0x05 ; 5 1fc54: a5 e0 ldi r26, 0x05 ; 5
1fc50: da 2e mov r13, r26 1fc56: ba 2e mov r11, r26
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
1fc52: f1 e1 ldi r31, 0x11 ; 17 1fc58: f1 e1 ldi r31, 0x11 ; 17
1fc54: ff 2e mov r15, r31 1fc5a: af 2e mov r10, r31
#endif #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
1fc56: b2 d0 rcall .+356 ; 0x1fdbc <getch> 1fc5c: a6 d0 rcall .+332 ; 0x1fdaa <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
1fc58: 81 34 cpi r24, 0x41 ; 65 1fc5e: 81 34 cpi r24, 0x41 ; 65
1fc5a: 19 f4 brne .+6 ; 0x1fc62 <main+0x62> 1fc60: 61 f4 brne .+24 ; 0x1fc7a <main+0x7a>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 1fc62: a3 d0 rcall .+326 ; 0x1fdaa <getch>
1fc5c: 81 e0 ldi r24, 0x01 ; 1 1fc64: 08 2f mov r16, r24
1fc5e: cc d0 rcall .+408 ; 0x1fdf8 <getNch> verifySpace();
1fc60: 9b c0 rjmp .+310 ; 0x1fd98 <main+0x198> 1fc66: b3 d0 rcall .+358 ; 0x1fdce <verifySpace>
putch(0x03); if (which == 0x82) {
1fc68: 02 38 cpi r16, 0x82 ; 130
1fc6a: 11 f0 breq .+4 ; 0x1fc70 <main+0x70>
/*
* 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 <main+0x74>
putch(OPTIBOOT_MAJVER);
1fc70: 84 e0 ldi r24, 0x04 ; 4
1fc72: 01 c0 rjmp .+2 ; 0x1fc76 <main+0x76>
} 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 <putch>
1fc78: 8d c0 rjmp .+282 ; 0x1fd94 <main+0x194>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
1fc62: 82 34 cpi r24, 0x42 ; 66 1fc7a: 82 34 cpi r24, 0x42 ; 66
1fc64: 11 f4 brne .+4 ; 0x1fc6a <main+0x6a> 1fc7c: 11 f4 brne .+4 ; 0x1fc82 <main+0x82>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
1fc66: 84 e1 ldi r24, 0x14 ; 20 1fc7e: 84 e1 ldi r24, 0x14 ; 20
1fc68: 03 c0 rjmp .+6 ; 0x1fc70 <main+0x70> 1fc80: 03 c0 rjmp .+6 ; 0x1fc88 <main+0x88>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
1fc6a: 85 34 cpi r24, 0x45 ; 69 1fc82: 85 34 cpi r24, 0x45 ; 69
1fc6c: 19 f4 brne .+6 ; 0x1fc74 <main+0x74> 1fc84: 19 f4 brne .+6 ; 0x1fc8c <main+0x8c>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
1fc6e: 85 e0 ldi r24, 0x05 ; 5 1fc86: 85 e0 ldi r24, 0x05 ; 5
1fc70: c3 d0 rcall .+390 ; 0x1fdf8 <getNch> 1fc88: aa d0 rcall .+340 ; 0x1fdde <getNch>
1fc72: 99 c0 rjmp .+306 ; 0x1fda6 <main+0x1a6> 1fc8a: 84 c0 rjmp .+264 ; 0x1fd94 <main+0x194>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
1fc74: 85 35 cpi r24, 0x55 ; 85 1fc8c: 85 35 cpi r24, 0x55 ; 85
1fc76: a9 f4 brne .+42 ; 0x1fca2 <main+0xa2> 1fc8e: a1 f4 brne .+40 ; 0x1fcb8 <main+0xb8>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
1fc78: a1 d0 rcall .+322 ; 0x1fdbc <getch> 1fc90: 8c d0 rcall .+280 ; 0x1fdaa <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
1fc7a: 08 2f mov r16, r24 1fc92: 08 2f mov r16, r24
1fc7c: 10 e0 ldi r17, 0x00 ; 0 1fc94: 10 e0 ldi r17, 0x00 ; 0
1fc7e: 9e d0 rcall .+316 ; 0x1fdbc <getch> 1fc96: 89 d0 rcall .+274 ; 0x1fdaa <getch>
1fc80: 90 e0 ldi r25, 0x00 ; 0 1fc98: e8 2e mov r14, r24
1fc82: 98 2f mov r25, r24 1fc9a: ff 24 eor r15, r15
1fc84: 88 27 eor r24, r24 1fc9c: fe 2c mov r15, r14
1fc86: 80 2b or r24, r16 1fc9e: ee 24 eor r14, r14
1fc88: 91 2b or r25, r17 1fca0: e0 2a or r14, r16
1fca2: f1 2a or r15, r17
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
1fc8a: 29 2f mov r18, r25 1fca4: 8f 2d mov r24, r15
1fc8c: 22 1f adc r18, r18 1fca6: 88 1f adc r24, r24
1fc8e: 22 27 eor r18, r18 1fca8: 88 27 eor r24, r24
1fc90: 22 1f adc r18, r18 1fcaa: 88 1f adc r24, r24
1fc92: 2b bf out 0x3b, r18 ; 59 1fcac: 8b bf out 0x3b, r24 ; 59
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
1fc94: 88 0f add r24, r24 1fcae: ee 0c add r14, r14
1fc96: 99 1f adc r25, r25 1fcb0: ff 1c adc r15, r15
address = newAddress; address = newAddress;
1fc98: 90 93 01 04 sts 0x0401, r25
1fc9c: 80 93 00 04 sts 0x0400, r24
1fca0: 81 c0 rjmp .+258 ; 0x1fda4 <main+0x1a4>
verifySpace(); verifySpace();
1fcb2: 8d d0 rcall .+282 ; 0x1fdce <verifySpace>
1fcb4: 67 01 movw r12, r14
1fcb6: 6e c0 rjmp .+220 ; 0x1fd94 <main+0x194>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
1fca2: 86 35 cpi r24, 0x56 ; 86 1fcb8: 86 35 cpi r24, 0x56 ; 86
1fca4: 29 f4 brne .+10 ; 0x1fcb0 <main+0xb0> 1fcba: 21 f4 brne .+8 ; 0x1fcc4 <main+0xc4>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
1fca6: 84 e0 ldi r24, 0x04 ; 4 1fcbc: 84 e0 ldi r24, 0x04 ; 4
1fca8: a7 d0 rcall .+334 ; 0x1fdf8 <getNch> 1fcbe: 8f d0 rcall .+286 ; 0x1fdde <getNch>
putch(0x00); putch(0x00);
1fcaa: 80 e0 ldi r24, 0x00 ; 0 1fcc0: 80 e0 ldi r24, 0x00 ; 0
1fcac: 7f d0 rcall .+254 ; 0x1fdac <putch> 1fcc2: d9 cf rjmp .-78 ; 0x1fc76 <main+0x76>
1fcae: 7b c0 rjmp .+246 ; 0x1fda6 <main+0x1a6>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
1fcb0: 84 36 cpi r24, 0x64 ; 100 1fcc4: 84 36 cpi r24, 0x64 ; 100
1fcb2: 09 f0 breq .+2 ; 0x1fcb6 <main+0xb6> 1fcc6: 09 f0 breq .+2 ; 0x1fcca <main+0xca>
1fcb4: 4e c0 rjmp .+156 ; 0x1fd52 <main+0x152> 1fcc8: 42 c0 rjmp .+132 ; 0x1fd4e <main+0x14e>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
1fcb6: 8a d0 rcall .+276 ; 0x1fdcc <getLen> 1fcca: 6f d0 rcall .+222 ; 0x1fdaa <getch>
length = getch();
1fccc: 6e d0 rcall .+220 ; 0x1fdaa <getch>
1fcce: 08 2f mov r16, r24
getch();
1fcd0: 6c d0 rcall .+216 ; 0x1fdaa <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
1fcb8: e0 91 00 04 lds r30, 0x0400 1fcd2: 80 e0 ldi r24, 0x00 ; 0
1fcbc: f0 91 01 04 lds r31, 0x0401 1fcd4: c8 16 cp r12, r24
1fcc0: 80 ee ldi r24, 0xE0 ; 224 1fcd6: 80 ee ldi r24, 0xE0 ; 224
1fcc2: e0 30 cpi r30, 0x00 ; 0 1fcd8: d8 06 cpc r13, r24
1fcc4: f8 07 cpc r31, r24 1fcda: 20 f4 brcc .+8 ; 0x1fce4 <main+0xe4>
1fcc6: 18 f4 brcc .+6 ; 0x1fcce <main+0xce> 1fcdc: 83 e0 ldi r24, 0x03 ; 3
1fcc8: 83 e0 ldi r24, 0x03 ; 3 1fcde: f6 01 movw r30, r12
1fcca: 87 bf out 0x37, r24 ; 55 1fce0: 87 bf out 0x37, r24 ; 55
1fccc: e8 95 spm 1fce2: e8 95 spm
1fcce: c0 e0 ldi r28, 0x00 ; 0 1fce4: c0 e0 ldi r28, 0x00 ; 0
1fcd0: d2 e0 ldi r29, 0x02 ; 2 1fce6: d2 e0 ldi r29, 0x02 ; 2
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
1fcd2: 74 d0 rcall .+232 ; 0x1fdbc <getch> 1fce8: 60 d0 rcall .+192 ; 0x1fdaa <getch>
1fcd4: 89 93 st Y+, r24 1fcea: 89 93 st Y+, r24
while (--length); while (--length);
1fcd6: 80 91 02 04 lds r24, 0x0402 1fcec: 0c 17 cp r16, r28
1fcda: 81 50 subi r24, 0x01 ; 1 1fcee: e1 f7 brne .-8 ; 0x1fce8 <main+0xe8>
1fcdc: 80 93 02 04 sts 0x0402, r24
1fce0: 88 23 and r24, r24
1fce2: b9 f7 brne .-18 ; 0x1fcd2 <main+0xd2>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
1fce4: e0 91 00 04 lds r30, 0x0400 1fcf0: f0 e0 ldi r31, 0x00 ; 0
1fce8: f0 91 01 04 lds r31, 0x0401 1fcf2: cf 16 cp r12, r31
1fcec: 80 ee ldi r24, 0xE0 ; 224 1fcf4: f0 ee ldi r31, 0xE0 ; 224
1fcee: e0 30 cpi r30, 0x00 ; 0 1fcf6: df 06 cpc r13, r31
1fcf0: f8 07 cpc r31, r24 1fcf8: 20 f0 brcs .+8 ; 0x1fd02 <main+0x102>
1fcf2: 18 f0 brcs .+6 ; 0x1fcfa <main+0xfa> 1fcfa: 83 e0 ldi r24, 0x03 ; 3
1fcf4: 83 e0 ldi r24, 0x03 ; 3 1fcfc: f6 01 movw r30, r12
1fcf6: 87 bf out 0x37, r24 ; 55 1fcfe: 87 bf out 0x37, r24 ; 55
1fcf8: e8 95 spm 1fd00: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
1fcfa: 78 d0 rcall .+240 ; 0x1fdec <verifySpace> 1fd02: 65 d0 rcall .+202 ; 0x1fdce <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
1fcfc: 07 b6 in r0, 0x37 ; 55 1fd04: 07 b6 in r0, 0x37 ; 55
1fcfe: 00 fc sbrc r0, 0 1fd06: 00 fc sbrc r0, 0
1fd00: fd cf rjmp .-6 ; 0x1fcfc <main+0xfc> 1fd08: fd cf rjmp .-6 ; 0x1fd04 <main+0x104>
} 1fd0a: a6 01 movw r20, r12
#endif 1fd0c: a0 e0 ldi r26, 0x00 ; 0
1fd0e: b2 e0 ldi r27, 0x02 ; 2
// Copy buffer into programming buffer
bufPtr = buff; bufPtr = buff;
addrPtr = (uint16_t)(void*)address; 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; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
1fd0e: 2c 91 ld r18, X 1fd10: 2c 91 ld r18, X
1fd10: 30 e0 ldi r19, 0x00 ; 0 1fd12: 30 e0 ldi r19, 0x00 ; 0
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
1fd12: 11 96 adiw r26, 0x01 ; 1 1fd14: 11 96 adiw r26, 0x01 ; 1
1fd14: 8c 91 ld r24, X 1fd16: 8c 91 ld r24, X
1fd16: 11 97 sbiw r26, 0x01 ; 1 1fd18: 11 97 sbiw r26, 0x01 ; 1
1fd18: 90 e0 ldi r25, 0x00 ; 0 1fd1a: 90 e0 ldi r25, 0x00 ; 0
1fd1a: 98 2f mov r25, r24 1fd1c: 98 2f mov r25, r24
1fd1c: 88 27 eor r24, r24 1fd1e: 88 27 eor r24, r24
1fd1e: 82 2b or r24, r18 1fd20: 82 2b or r24, r18
1fd20: 93 2b or r25, r19 1fd22: 93 2b or r25, r19
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
#endif #endif
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
1fd22: 12 96 adiw r26, 0x02 ; 2 1fd24: 12 96 adiw r26, 0x02 ; 2
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
1fd24: fa 01 movw r30, r20 1fd26: fa 01 movw r30, r20
1fd26: 0c 01 movw r0, r24 1fd28: 0c 01 movw r0, r24
1fd28: e7 be out 0x37, r14 ; 55 1fd2a: 97 be out 0x37, r9 ; 55
1fd2a: e8 95 spm 1fd2c: e8 95 spm
1fd2c: 11 24 eor r1, r1 1fd2e: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
1fd2e: 4e 5f subi r20, 0xFE ; 254 1fd30: 4e 5f subi r20, 0xFE ; 254
1fd30: 5f 4f sbci r21, 0xFF ; 255 1fd32: 5f 4f sbci r21, 0xFF ; 255
} while (--ch); } while (--ch);
1fd32: f3 e0 ldi r31, 0x03 ; 3 1fd34: f3 e0 ldi r31, 0x03 ; 3
1fd34: a0 30 cpi r26, 0x00 ; 0 1fd36: a0 30 cpi r26, 0x00 ; 0
1fd36: bf 07 cpc r27, r31 1fd38: bf 07 cpc r27, r31
1fd38: 51 f7 brne .-44 ; 0x1fd0e <main+0x10e> 1fd3a: 51 f7 brne .-44 ; 0x1fd10 <main+0x110>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
1fd3a: e0 91 00 04 lds r30, 0x0400 1fd3c: f6 01 movw r30, r12
1fd3e: f0 91 01 04 lds r31, 0x0401 1fd3e: b7 be out 0x37, r11 ; 55
1fd42: d7 be out 0x37, r13 ; 55 1fd40: e8 95 spm
1fd44: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
1fd46: 07 b6 in r0, 0x37 ; 55 1fd42: 07 b6 in r0, 0x37 ; 55
1fd48: 00 fc sbrc r0, 0 1fd44: 00 fc sbrc r0, 0
1fd4a: fd cf rjmp .-6 ; 0x1fd46 <main+0x146> 1fd46: fd cf rjmp .-6 ; 0x1fd42 <main+0x142>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
1fd4c: f7 be out 0x37, r15 ; 55 1fd48: a7 be out 0x37, r10 ; 55
1fd4e: e8 95 spm 1fd4a: e8 95 spm
1fd50: 2a c0 rjmp .+84 ; 0x1fda6 <main+0x1a6> 1fd4c: 23 c0 rjmp .+70 ; 0x1fd94 <main+0x194>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
1fd52: 84 37 cpi r24, 0x74 ; 116 1fd4e: 84 37 cpi r24, 0x74 ; 116
1fd54: d1 f4 brne .+52 ; 0x1fd8a <main+0x18a> 1fd50: a1 f4 brne .+40 ; 0x1fd7a <main+0x17a>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
1fd56: 3a d0 rcall .+116 ; 0x1fdcc <getLen> 1fd52: 2b d0 rcall .+86 ; 0x1fdaa <getch>
length = getch();
1fd54: 2a d0 rcall .+84 ; 0x1fdaa <getch>
1fd56: e8 2e mov r14, r24
getch();
1fd58: 28 d0 rcall .+80 ; 0x1fdaa <getch>
verifySpace(); verifySpace();
1fd58: 49 d0 rcall .+146 ; 0x1fdec <verifySpace> 1fd5a: 39 d0 rcall .+114 ; 0x1fdce <verifySpace>
1fd5c: e6 01 movw r28, r12
1fd5e: 0e 2d mov r16, r14
#ifdef __AVR_ATmega1280__ #ifdef __AVR_ATmega1280__
// do putch(pgm_read_byte_near(address++)); // do putch(pgm_read_byte_near(address++));
// while (--length); // while (--length);
do { do {
uint8_t result; uint8_t result;
__asm__ ("elpm %0,Z\n":"=r"(result):"z"(address)); __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
1fd5a: e0 91 00 04 lds r30, 0x0400 1fd60: fe 01 movw r30, r28
1fd5e: f0 91 01 04 lds r31, 0x0401 1fd62: 86 91 elpm r24, Z+
1fd62: e6 91 elpm r30, Z+
putch(result); putch(result);
1fd64: 8e 2f mov r24, r30 1fd64: 1a d0 rcall .+52 ; 0x1fd9a <putch>
1fd66: 22 d0 rcall .+68 ; 0x1fdac <putch>
address++; address++;
1fd68: 80 91 00 04 lds r24, 0x0400 1fd66: 21 96 adiw r28, 0x01 ; 1
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
} }
while (--length); while (--length);
1fd7a: 80 91 02 04 lds r24, 0x0402 1fd68: 01 50 subi r16, 0x01 ; 1
1fd7e: 81 50 subi r24, 0x01 ; 1 1fd6a: d1 f7 brne .-12 ; 0x1fd60 <main+0x160>
1fd80: 80 93 02 04 sts 0x0402, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
1fd84: 88 23 and r24, r24 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
1fd86: 49 f7 brne .-46 ; 0x1fd5a <main+0x15a> #endif
1fd88: 0e c0 rjmp .+28 ; 0x1fda6 <main+0x1a6>
/* 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 <main+0x194>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
1fd8a: 85 37 cpi r24, 0x75 ; 117 1fd7a: 85 37 cpi r24, 0x75 ; 117
1fd8c: 39 f4 brne .+14 ; 0x1fd9c <main+0x19c> 1fd7c: 31 f4 brne .+12 ; 0x1fd8a <main+0x18a>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
1fd8e: 2e d0 rcall .+92 ; 0x1fdec <verifySpace> 1fd7e: 27 d0 rcall .+78 ; 0x1fdce <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
1fd90: 8e e1 ldi r24, 0x1E ; 30 1fd80: 8e e1 ldi r24, 0x1E ; 30
1fd92: 0c d0 rcall .+24 ; 0x1fdac <putch> 1fd82: 0b d0 rcall .+22 ; 0x1fd9a <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
1fd94: 87 e9 ldi r24, 0x97 ; 151 1fd84: 87 e9 ldi r24, 0x97 ; 151
1fd96: 0a d0 rcall .+20 ; 0x1fdac <putch> 1fd86: 09 d0 rcall .+18 ; 0x1fd9a <putch>
1fd88: 75 cf rjmp .-278 ; 0x1fc74 <main+0x74>
putch(SIGNATURE_2); putch(SIGNATURE_2);
1fd98: 83 e0 ldi r24, 0x03 ; 3
1fd9a: 88 cf rjmp .-240 ; 0x1fcac <main+0xac>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
1fd9c: 81 35 cpi r24, 0x51 ; 81 1fd8a: 81 35 cpi r24, 0x51 ; 81
1fd9e: 11 f4 brne .+4 ; 0x1fda4 <main+0x1a4> 1fd8c: 11 f4 brne .+4 ; 0x1fd92 <main+0x192>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
1fda0: 88 e0 ldi r24, 0x08 ; 8 1fd8e: 88 e0 ldi r24, 0x08 ; 8
1fda2: 19 d0 rcall .+50 ; 0x1fdd6 <watchdogConfig> 1fd90: 18 d0 rcall .+48 ; 0x1fdc2 <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
1fda4: 23 d0 rcall .+70 ; 0x1fdec <verifySpace> 1fd92: 1d d0 rcall .+58 ; 0x1fdce <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
1fda6: 80 e1 ldi r24, 0x10 ; 16 1fd94: 80 e1 ldi r24, 0x10 ; 16
1fda8: 01 d0 rcall .+2 ; 0x1fdac <putch> 1fd96: 01 d0 rcall .+2 ; 0x1fd9a <putch>
1fdaa: 55 cf rjmp .-342 ; 0x1fc56 <main+0x56> 1fd98: 61 cf rjmp .-318 ; 0x1fc5c <main+0x5c>
0001fdac <putch>: 0001fd9a <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
1fdac: 98 2f mov r25, r24 1fd9a: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
1fdae: 80 91 c0 00 lds r24, 0x00C0 1fd9c: 80 91 c0 00 lds r24, 0x00C0
1fdb2: 85 ff sbrs r24, 5 1fda0: 85 ff sbrs r24, 5
1fdb4: fc cf rjmp .-8 ; 0x1fdae <putch+0x2> 1fda2: fc cf rjmp .-8 ; 0x1fd9c <putch+0x2>
UDR0 = ch; UDR0 = ch;
1fdb6: 90 93 c6 00 sts 0x00C6, r25 1fda4: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
1fdba: 08 95 ret 1fda8: 08 95 ret
0001fdbc <getch>: 0001fdaa <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
1fdbc: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
1fdbe: 80 91 c0 00 lds r24, 0x00C0 1fdaa: 80 91 c0 00 lds r24, 0x00C0
1fdc2: 87 ff sbrs r24, 7 1fdae: 87 ff sbrs r24, 7
1fdc4: fc cf rjmp .-8 ; 0x1fdbe <getch+0x2> 1fdb0: fc cf rjmp .-8 ; 0x1fdaa <getch>
;
if (!(UCSR0A & _BV(FE0))) {
1fdb2: 80 91 c0 00 lds r24, 0x00C0
1fdb6: 84 fd sbrc r24, 4
1fdb8: 01 c0 rjmp .+2 ; 0x1fdbc <getch+0x12>
}
#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; ch = UDR0;
1fdc6: 80 91 c6 00 lds r24, 0x00C6 1fdbc: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
#endif #endif
return ch; return ch;
} }
1fdca: 08 95 ret 1fdc0: 08 95 ret
0001fdcc <getLen>: 0001fdc2 <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
1fdcc: f7 df rcall .-18 ; 0x1fdbc <getch>
length = getch();
1fdce: f6 df rcall .-20 ; 0x1fdbc <getch>
1fdd0: 80 93 02 04 sts 0x0402, r24
return getch();
}
1fdd4: f3 cf rjmp .-26 ; 0x1fdbc <getch>
0001fdd6 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
1fdd6: e0 e6 ldi r30, 0x60 ; 96 1fdc2: e0 e6 ldi r30, 0x60 ; 96
1fdd8: f0 e0 ldi r31, 0x00 ; 0 1fdc4: f0 e0 ldi r31, 0x00 ; 0
1fdda: 98 e1 ldi r25, 0x18 ; 24 1fdc6: 98 e1 ldi r25, 0x18 ; 24
1fddc: 90 83 st Z, r25 1fdc8: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
1fdde: 80 83 st Z, r24 1fdca: 80 83 st Z, r24
} }
1fde0: 08 95 ret 1fdcc: 08 95 ret
0001fde2 <appStart>: 0001fdce <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
1fde2: 80 e0 ldi r24, 0x00 ; 0
1fde4: f8 df rcall .-16 ; 0x1fdd6 <watchdogConfig>
__asm__ __volatile__ (
1fde6: ee 27 eor r30, r30
1fde8: ff 27 eor r31, r31
1fdea: 09 94 ijmp
0001fdec <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
1fdec: e7 df rcall .-50 ; 0x1fdbc <getch> 1fdce: ed df rcall .-38 ; 0x1fdaa <getch>
1fdee: 80 32 cpi r24, 0x20 ; 32 1fdd0: 80 32 cpi r24, 0x20 ; 32
1fdf0: 09 f0 breq .+2 ; 0x1fdf4 <verifySpace+0x8> 1fdd2: 19 f0 breq .+6 ; 0x1fdda <verifySpace+0xc>
1fdf2: f7 df rcall .-18 ; 0x1fde2 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
1fdd4: 88 e0 ldi r24, 0x08 ; 8
1fdd6: f5 df rcall .-22 ; 0x1fdc2 <watchdogConfig>
1fdd8: ff cf rjmp .-2 ; 0x1fdd8 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
1fdf4: 84 e1 ldi r24, 0x14 ; 20 1fdda: 84 e1 ldi r24, 0x14 ; 20
} }
1fdf6: da cf rjmp .-76 ; 0x1fdac <putch> 1fddc: de cf rjmp .-68 ; 0x1fd9a <putch>
0001fdf8 <getNch>: 0001fdde <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
1fdf8: 1f 93 push r17 1fdde: 1f 93 push r17
1fdfa: 18 2f mov r17, r24 1fde0: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
1fdfc: df df rcall .-66 ; 0x1fdbc <getch> 1fde2: e3 df rcall .-58 ; 0x1fdaa <getch>
1fdfe: 11 50 subi r17, 0x01 ; 1 1fde4: 11 50 subi r17, 0x01 ; 1
1fe00: e9 f7 brne .-6 ; 0x1fdfc <getNch+0x4> 1fde6: e9 f7 brne .-6 ; 0x1fde2 <getNch+0x4>
verifySpace(); verifySpace();
1fe02: f4 df rcall .-24 ; 0x1fdec <verifySpace> 1fde8: f2 df rcall .-28 ; 0x1fdce <verifySpace>
} }
1fe04: 1f 91 pop r17 1fdea: 1f 91 pop r17
1fe06: 08 95 ret 1fdec: 08 95 ret
0001fdee <appStart>:
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 <watchdogConfig>
__asm__ __volatile__ (
1fdf2: ee 27 eor r30, r30
1fdf4: ff 27 eor r31, r31
1fdf6: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:107E000084B714BE81FFE6D085E08093810082E0D4 :107E0000112484B714BE81FFF0D085E080938100F7
:107E10008093C00088E18093C10086E08093C20017 :107E100082E08093C00088E18093C10086E0809377
:107E200080E18093C4008EE0CFD0259A86E020E3E5 :107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E30003CEF91E0309385002093840096BBB09B8B :107E300020E33CEF91E0309385002093840096BBD3
:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 :107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0 :107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E600083E020C0823411F484E103C0853419F426 :107E6000A2D0813461F49FD0082FAFD0023811F036
:107E700085E0BBD091C0853581F499D0082F10E002 :107E7000013811F484E001C083E08DD089C08234E0
:107E800096D090E0982F8827802B912B880F991FF0 :107E800011F484E103C0853419F485E0A6D080C0E4
:107E900090930102809300027EC0863529F484E02D :107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000A4D080E07CD078C0843609F04EC087D062 :107EA000102F00270E291F29000F111F8ED06801E7
:107EB000E0910002F091010280E7E030F80718F449 :107EB0006FC0863521F484E090D080E0DECF843638
:107EC00083E087BFE895C0E0D1E071D089938091CD :107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00002028150809302028823B9F7E0910002E8 :107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE000F091010280E7E030F80718F083E087BFE7 :107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF000E89575D007B600FCFDCF40910002509187 :107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F00000102A0E0B1E02C9130E011968C91119724 :107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160 :107F100090E0982F8827822B932B1296FA010C0160
:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740 :107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7E0910002F0910102E7BEE89507B623 :107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F400000FCFDCFF7BEE89527C08437B9F437D0E1 :107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F500046D0E0910002F09101023196F0930102C7 :107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000E09300023197E4918E2F19D080910202A4 :107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000815080930202882361F70EC0853739F45F :107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80002ED08EE10CD085E90AD08FE08BCF8135E1 :107F80000AD08FE07ACF813511F488E018D01DD067
:107F900011F488E019D023D080E101D05CCF982F74 :107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0008091C00085FFFCCF9093C6000895A895EE :107FA0009093C60008958091C00087FFFCCF809118
:107FB0008091C00087FFFCCF8091C6000895F7DF55 :107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F6DF80930202F3CFE0E6F0E098E19083E1 :107FC000F0E098E1908380830895EDDF803219F02E
:107FD0008083089580E0F8DFEE27FF270994E7DF2C :107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B :107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:0A7FF0001150E9F7F4DF1F91089526 :047FF000FF270994CA
:027FFE00040479
:0400000300007E007B :0400000300007E007B
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_atmega328.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
7e00: 84 b7 in r24, 0x34 ; 52 7e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
7e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
7e02: 14 be out 0x34, r1 ; 52 7e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
7e04: 81 ff sbrs r24, 1 7e06: 81 ff sbrs r24, 1
7e06: e6 d0 rcall .+460 ; 0x7fd4 <appStart> 7e08: f0 d0 rcall .+480 ; 0x7fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
7e08: 85 e0 ldi r24, 0x05 ; 5 7e0a: 85 e0 ldi r24, 0x05 ; 5
7e0a: 80 93 81 00 sts 0x0081, r24 7e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
7e0e: 82 e0 ldi r24, 0x02 ; 2 7e10: 82 e0 ldi r24, 0x02 ; 2
7e10: 80 93 c0 00 sts 0x00C0, r24 7e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
7e14: 88 e1 ldi r24, 0x18 ; 24 7e16: 88 e1 ldi r24, 0x18 ; 24
7e16: 80 93 c1 00 sts 0x00C1, r24 7e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
7e1a: 86 e0 ldi r24, 0x06 ; 6 7e1c: 86 e0 ldi r24, 0x06 ; 6
7e1c: 80 93 c2 00 sts 0x00C2, r24 7e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
7e20: 80 e1 ldi r24, 0x10 ; 16 7e22: 80 e1 ldi r24, 0x10 ; 16
7e22: 80 93 c4 00 sts 0x00C4, r24 7e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
7e26: 8e e0 ldi r24, 0x0E ; 14 7e28: 8e e0 ldi r24, 0x0E ; 14
7e28: cf d0 rcall .+414 ; 0x7fc8 <watchdogConfig> 7e2a: c9 d0 rcall .+402 ; 0x7fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
7e2a: 25 9a sbi 0x04, 5 ; 4 7e2c: 25 9a sbi 0x04, 5 ; 4
7e2c: 86 e0 ldi r24, 0x06 ; 6 7e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e2e: 20 e3 ldi r18, 0x30 ; 48 7e30: 20 e3 ldi r18, 0x30 ; 48
7e30: 3c ef ldi r19, 0xFC ; 252 7e32: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e32: 91 e0 ldi r25, 0x01 ; 1 7e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e34: 30 93 85 00 sts 0x0085, r19 7e36: 30 93 85 00 sts 0x0085, r19
7e38: 20 93 84 00 sts 0x0084, r18 7e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e3c: 96 bb out 0x16, r25 ; 22 7e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
7e3e: b0 9b sbis 0x16, 0 ; 22 7e40: b0 9b sbis 0x16, 0 ; 22
7e40: fe cf rjmp .-4 ; 0x7e3e <main+0x3e> 7e42: fe cf rjmp .-4 ; 0x7e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
7e42: 1d 9a sbi 0x03, 5 ; 3 7e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
7e44: a8 95 wdr 7e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
7e46: 81 50 subi r24, 0x01 ; 1 7e48: 81 50 subi r24, 0x01 ; 1
7e48: a9 f7 brne .-22 ; 0x7e34 <main+0x34> 7e4a: a9 f7 brne .-22 ; 0x7e36 <main+0x36>
/* get character from UART */ 7e4c: cc 24 eor r12, r12
ch = getch(); 7e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
7e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
7e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7e50: 88 24 eor r8, r8
7e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
7e4e: a5 e0 ldi r26, 0x05 ; 5 7e54: b5 e0 ldi r27, 0x05 ; 5
7e50: ea 2e mov r14, r26 7e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7e52: f1 e1 ldi r31, 0x11 ; 17 7e58: a1 e1 ldi r26, 0x11 ; 17
7e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
7e56: ab d0 rcall .+342 ; 0x7fae <getch> 7e60: a2 d0 rcall .+324 ; 0x7fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
7e58: 81 34 cpi r24, 0x41 ; 65 7e62: 81 34 cpi r24, 0x41 ; 65
7e5a: 21 f4 brne .+8 ; 0x7e64 <main+0x64> 7e64: 61 f4 brne .+24 ; 0x7e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 7e66: 9f d0 rcall .+318 ; 0x7fa6 <getch>
7e5c: 81 e0 ldi r24, 0x01 ; 1 7e68: 08 2f mov r16, r24
7e5e: c5 d0 rcall .+394 ; 0x7fea <getNch> verifySpace();
putch(0x03); 7e6a: af d0 rcall .+350 ; 0x7fca <verifySpace>
7e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
7e62: 20 c0 rjmp .+64 ; 0x7ea4 <main+0xa4> 7e6c: 02 38 cpi r16, 0x82 ; 130
7e6e: 11 f0 breq .+4 ; 0x7e74 <main+0x74>
/*
* 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 <main+0x78>
putch(OPTIBOOT_MAJVER);
7e74: 84 e0 ldi r24, 0x04 ; 4
7e76: 01 c0 rjmp .+2 ; 0x7e7a <main+0x7a>
} 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 <putch>
7e7c: 89 c0 rjmp .+274 ; 0x7f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
7e64: 82 34 cpi r24, 0x42 ; 66 7e7e: 82 34 cpi r24, 0x42 ; 66
7e66: 11 f4 brne .+4 ; 0x7e6c <main+0x6c> 7e80: 11 f4 brne .+4 ; 0x7e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
7e68: 84 e1 ldi r24, 0x14 ; 20 7e82: 84 e1 ldi r24, 0x14 ; 20
7e6a: 03 c0 rjmp .+6 ; 0x7e72 <main+0x72> 7e84: 03 c0 rjmp .+6 ; 0x7e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
7e6c: 85 34 cpi r24, 0x45 ; 69 7e86: 85 34 cpi r24, 0x45 ; 69
7e6e: 19 f4 brne .+6 ; 0x7e76 <main+0x76> 7e88: 19 f4 brne .+6 ; 0x7e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
7e70: 85 e0 ldi r24, 0x05 ; 5 7e8a: 85 e0 ldi r24, 0x05 ; 5
7e72: bb d0 rcall .+374 ; 0x7fea <getNch> 7e8c: a6 d0 rcall .+332 ; 0x7fda <getNch>
7e74: 91 c0 rjmp .+290 ; 0x7f98 <main+0x198> 7e8e: 80 c0 rjmp .+256 ; 0x7f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
7e76: 85 35 cpi r24, 0x55 ; 85 7e90: 85 35 cpi r24, 0x55 ; 85
7e78: 81 f4 brne .+32 ; 0x7e9a <main+0x9a> 7e92: 79 f4 brne .+30 ; 0x7eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
7e7a: 99 d0 rcall .+306 ; 0x7fae <getch> 7e94: 88 d0 rcall .+272 ; 0x7fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
7e7c: 08 2f mov r16, r24 7e96: e8 2e mov r14, r24
7e7e: 10 e0 ldi r17, 0x00 ; 0 7e98: ff 24 eor r15, r15
7e80: 96 d0 rcall .+300 ; 0x7fae <getch> 7e9a: 85 d0 rcall .+266 ; 0x7fa6 <getch>
7e82: 90 e0 ldi r25, 0x00 ; 0 7e9c: 08 2f mov r16, r24
7e84: 98 2f mov r25, r24 7e9e: 10 e0 ldi r17, 0x00 ; 0
7e86: 88 27 eor r24, r24 7ea0: 10 2f mov r17, r16
7e88: 80 2b or r24, r16 7ea2: 00 27 eor r16, r16
7e8a: 91 2b or r25, r17 7ea4: 0e 29 or r16, r14
7ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
7e8c: 88 0f add r24, r24 7ea8: 00 0f add r16, r16
7e8e: 99 1f adc r25, r25 7eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
7e90: 90 93 01 02 sts 0x0201, r25
7e94: 80 93 00 02 sts 0x0200, r24
7e98: 7e c0 rjmp .+252 ; 0x7f96 <main+0x196>
verifySpace(); verifySpace();
7eac: 8e d0 rcall .+284 ; 0x7fca <verifySpace>
7eae: 68 01 movw r12, r16
7eb0: 6f c0 rjmp .+222 ; 0x7f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
7e9a: 86 35 cpi r24, 0x56 ; 86 7eb2: 86 35 cpi r24, 0x56 ; 86
7e9c: 29 f4 brne .+10 ; 0x7ea8 <main+0xa8> 7eb4: 21 f4 brne .+8 ; 0x7ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
7e9e: 84 e0 ldi r24, 0x04 ; 4 7eb6: 84 e0 ldi r24, 0x04 ; 4
7ea0: a4 d0 rcall .+328 ; 0x7fea <getNch> 7eb8: 90 d0 rcall .+288 ; 0x7fda <getNch>
putch(0x00); putch(0x00);
7ea2: 80 e0 ldi r24, 0x00 ; 0 7eba: 80 e0 ldi r24, 0x00 ; 0
7ea4: 7c d0 rcall .+248 ; 0x7f9e <putch> 7ebc: de cf rjmp .-68 ; 0x7e7a <main+0x7a>
7ea6: 78 c0 rjmp .+240 ; 0x7f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
7ea8: 84 36 cpi r24, 0x64 ; 100 7ebe: 84 36 cpi r24, 0x64 ; 100
7eaa: 09 f0 breq .+2 ; 0x7eae <main+0xae> 7ec0: 09 f0 breq .+2 ; 0x7ec4 <main+0xc4>
7eac: 4e c0 rjmp .+156 ; 0x7f4a <main+0x14a> 7ec2: 40 c0 rjmp .+128 ; 0x7f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
7eae: 87 d0 rcall .+270 ; 0x7fbe <getLen> 7ec4: 70 d0 rcall .+224 ; 0x7fa6 <getch>
length = getch();
7ec6: 6f d0 rcall .+222 ; 0x7fa6 <getch>
7ec8: 08 2f mov r16, r24
getch();
7eca: 6d d0 rcall .+218 ; 0x7fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
7eb0: e0 91 00 02 lds r30, 0x0200 7ecc: 80 e0 ldi r24, 0x00 ; 0
7eb4: f0 91 01 02 lds r31, 0x0201 7ece: c8 16 cp r12, r24
7eb8: 80 e7 ldi r24, 0x70 ; 112 7ed0: 80 e7 ldi r24, 0x70 ; 112
7eba: e0 30 cpi r30, 0x00 ; 0 7ed2: d8 06 cpc r13, r24
7ebc: f8 07 cpc r31, r24 7ed4: 18 f4 brcc .+6 ; 0x7edc <main+0xdc>
7ebe: 18 f4 brcc .+6 ; 0x7ec6 <main+0xc6> 7ed6: f6 01 movw r30, r12
7ec0: 83 e0 ldi r24, 0x03 ; 3 7ed8: b7 be out 0x37, r11 ; 55
7ec2: 87 bf out 0x37, r24 ; 55 7eda: e8 95 spm
7ec4: e8 95 spm 7edc: c0 e0 ldi r28, 0x00 ; 0
7ec6: c0 e0 ldi r28, 0x00 ; 0 7ede: d1 e0 ldi r29, 0x01 ; 1
7ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
7eca: 71 d0 rcall .+226 ; 0x7fae <getch> 7ee0: 62 d0 rcall .+196 ; 0x7fa6 <getch>
7ecc: 89 93 st Y+, r24 7ee2: 89 93 st Y+, r24
while (--length); while (--length);
7ece: 80 91 02 02 lds r24, 0x0202 7ee4: 0c 17 cp r16, r28
7ed2: 81 50 subi r24, 0x01 ; 1 7ee6: e1 f7 brne .-8 ; 0x7ee0 <main+0xe0>
7ed4: 80 93 02 02 sts 0x0202, r24
7ed8: 88 23 and r24, r24
7eda: b9 f7 brne .-18 ; 0x7eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
7edc: e0 91 00 02 lds r30, 0x0200 7ee8: f0 e0 ldi r31, 0x00 ; 0
7ee0: f0 91 01 02 lds r31, 0x0201 7eea: cf 16 cp r12, r31
7ee4: 80 e7 ldi r24, 0x70 ; 112 7eec: f0 e7 ldi r31, 0x70 ; 112
7ee6: e0 30 cpi r30, 0x00 ; 0 7eee: df 06 cpc r13, r31
7ee8: f8 07 cpc r31, r24 7ef0: 18 f0 brcs .+6 ; 0x7ef8 <main+0xf8>
7eea: 18 f0 brcs .+6 ; 0x7ef2 <main+0xf2> 7ef2: f6 01 movw r30, r12
7eec: 83 e0 ldi r24, 0x03 ; 3 7ef4: b7 be out 0x37, r11 ; 55
7eee: 87 bf out 0x37, r24 ; 55 7ef6: e8 95 spm
7ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
7ef2: 75 d0 rcall .+234 ; 0x7fde <verifySpace> 7ef8: 68 d0 rcall .+208 ; 0x7fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
7ef4: 07 b6 in r0, 0x37 ; 55 7efa: 07 b6 in r0, 0x37 ; 55
7ef6: 00 fc sbrc r0, 0 7efc: 00 fc sbrc r0, 0
7ef8: fd cf rjmp .-6 ; 0x7ef4 <main+0xf4> 7efe: fd cf rjmp .-6 ; 0x7efa <main+0xfa>
} 7f00: a6 01 movw r20, r12
#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
7f02: a0 e0 ldi r26, 0x00 ; 0 7f02: a0 e0 ldi r26, 0x00 ; 0
7f04: b1 e0 ldi r27, 0x01 ; 1 7f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7f1c: fa 01 movw r30, r20 7f1c: fa 01 movw r30, r20
7f1e: 0c 01 movw r0, r24 7f1e: 0c 01 movw r0, r24
7f20: d7 be out 0x37, r13 ; 55 7f20: 87 be out 0x37, r8 ; 55
7f22: e8 95 spm 7f22: e8 95 spm
7f24: 11 24 eor r1, r1 7f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
7f2c: a0 38 cpi r26, 0x80 ; 128 7f2c: a0 38 cpi r26, 0x80 ; 128
7f2e: bf 07 cpc r27, r31 7f2e: bf 07 cpc r27, r31
7f30: 51 f7 brne .-44 ; 0x7f06 <main+0x106> 7f30: 51 f7 brne .-44 ; 0x7f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
7f32: e0 91 00 02 lds r30, 0x0200 7f32: f6 01 movw r30, r12
7f36: f0 91 01 02 lds r31, 0x0201 7f34: a7 be out 0x37, r10 ; 55
7f3a: e7 be out 0x37, r14 ; 55 7f36: e8 95 spm
7f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
7f3e: 07 b6 in r0, 0x37 ; 55 7f38: 07 b6 in r0, 0x37 ; 55
7f40: 00 fc sbrc r0, 0 7f3a: 00 fc sbrc r0, 0
7f42: fd cf rjmp .-6 ; 0x7f3e <main+0x13e> 7f3c: fd cf rjmp .-6 ; 0x7f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7f44: f7 be out 0x37, r15 ; 55 7f3e: 97 be out 0x37, r9 ; 55
7f46: e8 95 spm 7f40: e8 95 spm
7f48: 27 c0 rjmp .+78 ; 0x7f98 <main+0x198> 7f42: 26 c0 rjmp .+76 ; 0x7f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
7f4a: 84 37 cpi r24, 0x74 ; 116 7f44: 84 37 cpi r24, 0x74 ; 116
7f4c: b9 f4 brne .+46 ; 0x7f7c <main+0x17c> 7f46: b1 f4 brne .+44 ; 0x7f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
7f4e: 37 d0 rcall .+110 ; 0x7fbe <getLen> 7f48: 2e d0 rcall .+92 ; 0x7fa6 <getch>
length = getch();
7f4a: 2d d0 rcall .+90 ; 0x7fa6 <getch>
7f4c: f8 2e mov r15, r24
getch();
7f4e: 2b d0 rcall .+86 ; 0x7fa6 <getch>
verifySpace(); verifySpace();
7f50: 46 d0 rcall .+140 ; 0x7fde <verifySpace> 7f50: 3c d0 rcall .+120 ; 0x7fca <verifySpace>
7f52: f6 01 movw r30, r12
7f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
7f52: e0 91 00 02 lds r30, 0x0200 7f56: 8f 01 movw r16, r30
7f56: f0 91 01 02 lds r31, 0x0201 7f58: 0f 5f subi r16, 0xFF ; 255
7f5a: 31 96 adiw r30, 0x01 ; 1 7f5a: 1f 4f sbci r17, 0xFF ; 255
7f5c: f0 93 01 02 sts 0x0201, r31 7f5c: 84 91 lpm r24, Z+
7f60: e0 93 00 02 sts 0x0200, r30 7f5e: 1b d0 rcall .+54 ; 0x7f96 <putch>
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 <putch>
while (--length); while (--length);
7f6c: 80 91 02 02 lds r24, 0x0202 7f60: ea 94 dec r14
7f70: 81 50 subi r24, 0x01 ; 1 7f62: f8 01 movw r30, r16
7f72: 80 93 02 02 sts 0x0202, r24 7f64: c1 f7 brne .-16 ; 0x7f56 <main+0x156>
7f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
7f78: 61 f7 brne .-40 ; 0x7f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
7f7a: 0e c0 rjmp .+28 ; 0x7f98 <main+0x198> #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 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
7f7c: 85 37 cpi r24, 0x75 ; 117 7f74: 85 37 cpi r24, 0x75 ; 117
7f7e: 39 f4 brne .+14 ; 0x7f8e <main+0x18e> 7f76: 39 f4 brne .+14 ; 0x7f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
7f80: 2e d0 rcall .+92 ; 0x7fde <verifySpace> 7f78: 28 d0 rcall .+80 ; 0x7fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
7f82: 8e e1 ldi r24, 0x1E ; 30 7f7a: 8e e1 ldi r24, 0x1E ; 30
7f84: 0c d0 rcall .+24 ; 0x7f9e <putch> 7f7c: 0c d0 rcall .+24 ; 0x7f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
7f86: 85 e9 ldi r24, 0x95 ; 149 7f7e: 85 e9 ldi r24, 0x95 ; 149
7f88: 0a d0 rcall .+20 ; 0x7f9e <putch> 7f80: 0a d0 rcall .+20 ; 0x7f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
7f8a: 8f e0 ldi r24, 0x0F ; 15 7f82: 8f e0 ldi r24, 0x0F ; 15
7f8c: 8b cf rjmp .-234 ; 0x7ea4 <main+0xa4> 7f84: 7a cf rjmp .-268 ; 0x7e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
7f8e: 81 35 cpi r24, 0x51 ; 81 7f86: 81 35 cpi r24, 0x51 ; 81
7f90: 11 f4 brne .+4 ; 0x7f96 <main+0x196> 7f88: 11 f4 brne .+4 ; 0x7f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
7f92: 88 e0 ldi r24, 0x08 ; 8 7f8a: 88 e0 ldi r24, 0x08 ; 8
7f94: 19 d0 rcall .+50 ; 0x7fc8 <watchdogConfig> 7f8c: 18 d0 rcall .+48 ; 0x7fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
7f96: 23 d0 rcall .+70 ; 0x7fde <verifySpace> 7f8e: 1d d0 rcall .+58 ; 0x7fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
7f98: 80 e1 ldi r24, 0x10 ; 16 7f90: 80 e1 ldi r24, 0x10 ; 16
7f9a: 01 d0 rcall .+2 ; 0x7f9e <putch> 7f92: 01 d0 rcall .+2 ; 0x7f96 <putch>
7f9c: 5c cf rjmp .-328 ; 0x7e56 <main+0x56> 7f94: 65 cf rjmp .-310 ; 0x7e60 <main+0x60>
00007f9e <putch>: 00007f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
7f9e: 98 2f mov r25, r24 7f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
7fa0: 80 91 c0 00 lds r24, 0x00C0 7f98: 80 91 c0 00 lds r24, 0x00C0
7fa4: 85 ff sbrs r24, 5 7f9c: 85 ff sbrs r24, 5
7fa6: fc cf rjmp .-8 ; 0x7fa0 <putch+0x2> 7f9e: fc cf rjmp .-8 ; 0x7f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
7fa8: 90 93 c6 00 sts 0x00C6, r25 7fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
7fac: 08 95 ret 7fa4: 08 95 ret
00007fae <getch>: 00007fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
7fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
7fb0: 80 91 c0 00 lds r24, 0x00C0 7fa6: 80 91 c0 00 lds r24, 0x00C0
7fb4: 87 ff sbrs r24, 7 7faa: 87 ff sbrs r24, 7
7fb6: fc cf rjmp .-8 ; 0x7fb0 <getch+0x2> 7fac: fc cf rjmp .-8 ; 0x7fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
7fae: 80 91 c0 00 lds r24, 0x00C0
7fb2: 84 fd sbrc r24, 4
7fb4: 01 c0 rjmp .+2 ; 0x7fb8 <getch+0x12>
}
#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; ch = UDR0;
7fb8: 80 91 c6 00 lds r24, 0x00C6 7fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
7fbc: 08 95 ret 7fbc: 08 95 ret
00007fbe <getLen>: 00007fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
7fbe: f7 df rcall .-18 ; 0x7fae <getch>
length = getch();
7fc0: f6 df rcall .-20 ; 0x7fae <getch>
7fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
7fc6: f3 cf rjmp .-26 ; 0x7fae <getch>
00007fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
7fc8: e0 e6 ldi r30, 0x60 ; 96 7fbe: e0 e6 ldi r30, 0x60 ; 96
7fca: f0 e0 ldi r31, 0x00 ; 0 7fc0: f0 e0 ldi r31, 0x00 ; 0
7fcc: 98 e1 ldi r25, 0x18 ; 24 7fc2: 98 e1 ldi r25, 0x18 ; 24
7fce: 90 83 st Z, r25 7fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
7fd0: 80 83 st Z, r24 7fc6: 80 83 st Z, r24
} }
7fd2: 08 95 ret 7fc8: 08 95 ret
00007fd4 <appStart>: 00007fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
7fd4: 80 e0 ldi r24, 0x00 ; 0
7fd6: f8 df rcall .-16 ; 0x7fc8 <watchdogConfig>
__asm__ __volatile__ (
7fd8: ee 27 eor r30, r30
7fda: ff 27 eor r31, r31
7fdc: 09 94 ijmp
00007fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
7fde: e7 df rcall .-50 ; 0x7fae <getch> 7fca: ed df rcall .-38 ; 0x7fa6 <getch>
7fe0: 80 32 cpi r24, 0x20 ; 32 7fcc: 80 32 cpi r24, 0x20 ; 32
7fe2: 09 f0 breq .+2 ; 0x7fe6 <verifySpace+0x8> 7fce: 19 f0 breq .+6 ; 0x7fd6 <verifySpace+0xc>
7fe4: f7 df rcall .-18 ; 0x7fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
7fd0: 88 e0 ldi r24, 0x08 ; 8
7fd2: f5 df rcall .-22 ; 0x7fbe <watchdogConfig>
7fd4: ff cf rjmp .-2 ; 0x7fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
7fe6: 84 e1 ldi r24, 0x14 ; 20 7fd6: 84 e1 ldi r24, 0x14 ; 20
} }
7fe8: da cf rjmp .-76 ; 0x7f9e <putch> 7fd8: de cf rjmp .-68 ; 0x7f96 <putch>
00007fea <getNch>: 00007fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
7fea: 1f 93 push r17 7fda: 1f 93 push r17
7fec: 18 2f mov r17, r24 7fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
7fee: df df rcall .-66 ; 0x7fae <getch> 7fde: e3 df rcall .-58 ; 0x7fa6 <getch>
7ff0: 11 50 subi r17, 0x01 ; 1 7fe0: 11 50 subi r17, 0x01 ; 1
7ff2: e9 f7 brne .-6 ; 0x7fee <getNch+0x4> 7fe2: e9 f7 brne .-6 ; 0x7fde <getNch+0x4>
verifySpace(); verifySpace();
7ff4: f4 df rcall .-24 ; 0x7fde <verifySpace> 7fe4: f2 df rcall .-28 ; 0x7fca <verifySpace>
} }
7ff6: 1f 91 pop r17 7fe6: 1f 91 pop r17
7ff8: 08 95 ret 7fe8: 08 95 ret
00007fea <appStart>:
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 <watchdogConfig>
__asm__ __volatile__ (
7fee: ee 27 eor r30, r30
7ff0: ff 27 eor r31, r31
7ff2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:107E000085E08093810082E08093C00088E18093C8 :107E0000112484B714BE81FFF0D085E080938100F7
:107E1000C10086E08093C20088E08093C40084B7EC :107E100082E08093C00088E18093C10086E0809377
:107E200014BE81FFD7D08DE0CFD0259A86E028E11F :107E2000C20088E08093C4008EE0C9D0259A86E025
:107E30003EEF91E0309385002093840096BBB09B89 :107E300028E13EEF91E0309385002093840096BBCB
:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 :107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0 :107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E600083E020C0823411F484E103C0853419F426 :107E6000A2D0813461F49FD0082FAFD0023811F036
:107E700085E0BBD091C0853581F499D0082F10E002 :107E7000013811F484E001C083E08DD089C08234E0
:107E800096D090E0982F8827802B912B880F991FF0 :107E800011F484E103C0853419F485E0A6D080C0E4
:107E900090930102809300027EC0863529F484E02D :107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000A4D080E07CD078C0843609F04EC087D062 :107EA000102F00270E291F29000F111F8ED06801E7
:107EB000E0910002F091010280E7E030F80718F449 :107EB0006FC0863521F484E090D080E0DECF843638
:107EC00083E087BFE895C0E0D1E071D089938091CD :107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00002028150809302028823B9F7E0910002E8 :107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE000F091010280E7E030F80718F083E087BFE7 :107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF000E89575D007B600FCFDCF40910002509187 :107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F00000102A0E0B1E02C9130E011968C91119724 :107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160 :107F100090E0982F8827822B932B1296FA010C0160
:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740 :107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7E0910002F0910102E7BEE89507B623 :107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F400000FCFDCFF7BEE89527C08437B9F437D0E1 :107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F500046D0E0910002F09101023196F0930102C7 :107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000E09300023197E4918E2F19D080910202A4 :107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000815080930202882361F70EC0853739F45F :107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80002ED08EE10CD085E90AD08FE08BCF8135E1 :107F80000AD08FE07ACF813511F488E018D01DD067
:107F900011F488E019D023D080E101D05CCF982F74 :107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0008091C00085FFFCCF9093C6000895A895EE :107FA0009093C60008958091C00087FFFCCF809118
:107FB0008091C00087FFFCCF8091C6000895F7DF55 :107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F6DF80930202F3CFE0E6F0E098E19083E1 :107FC000F0E098E1908380830895EDDF803219F02E
:107FD0008083089580E0F8DFEE27FF270994E7DF2C :107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B :107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:0A7FF0001150E9F7F4DF1F91089526 :047FF000FF270994CA
:027FFE00040479
:0400000300007E007B :0400000300007E007B
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_atmega328_pro_8MHz.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e3 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000140 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc8 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000ea9 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,256 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
7e00: 85 e0 ldi r24, 0x05 ; 5 7e00: 11 24 eor r1, r1
7e02: 80 93 81 00 sts 0x0081, r24 #ifdef __AVR_ATmega8__
#if LED_START_FLASHES > 0 SP=RAMEND; // This is done by hardware reset
// 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
#endif #endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
7e1e: 84 b7 in r24, 0x34 ; 52 7e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
7e20: 14 be out 0x34, r1 ; 52 7e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
7e22: 81 ff sbrs r24, 1 7e06: 81 ff sbrs r24, 1
7e24: d7 d0 rcall .+430 ; 0x7fd4 <appStart> 7e08: f0 d0 rcall .+480 ; 0x7fea <appStart>
#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 // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_500MS); watchdogConfig(WATCHDOG_1S);
7e26: 8d e0 ldi r24, 0x0D ; 13 7e28: 8e e0 ldi r24, 0x0E ; 14
7e28: cf d0 rcall .+414 ; 0x7fc8 <watchdogConfig> 7e2a: c9 d0 rcall .+402 ; 0x7fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
7e2a: 25 9a sbi 0x04, 5 ; 4 7e2c: 25 9a sbi 0x04, 5 ; 4
7e2c: 86 e0 ldi r24, 0x06 ; 6 7e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e2e: 28 e1 ldi r18, 0x18 ; 24 7e30: 28 e1 ldi r18, 0x18 ; 24
7e30: 3e ef ldi r19, 0xFE ; 254 7e32: 3e ef ldi r19, 0xFE ; 254
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e32: 91 e0 ldi r25, 0x01 ; 1 7e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
7e34: 30 93 85 00 sts 0x0085, r19 7e36: 30 93 85 00 sts 0x0085, r19
7e38: 20 93 84 00 sts 0x0084, r18 7e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
7e3c: 96 bb out 0x16, r25 ; 22 7e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
7e3e: b0 9b sbis 0x16, 0 ; 22 7e40: b0 9b sbis 0x16, 0 ; 22
7e40: fe cf rjmp .-4 ; 0x7e3e <main+0x3e> 7e42: fe cf rjmp .-4 ; 0x7e40 <main+0x40>
#ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED);
#else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
7e42: 1d 9a sbi 0x03, 5 ; 3 7e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
7e44: a8 95 wdr 7e46: a8 95 wdr
TCNT1 = -(F_CPU/(1024*16)); LED_PORT ^= _BV(LED);
TIFR1 = _BV(TOV1); #else
while(!(TIFR1 & _BV(TOV1)));
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
7e46: 81 50 subi r24, 0x01 ; 1 7e48: 81 50 subi r24, 0x01 ; 1
7e48: a9 f7 brne .-22 ; 0x7e34 <main+0x34> 7e4a: a9 f7 brne .-22 ; 0x7e36 <main+0x36>
/* get character from UART */ 7e4c: cc 24 eor r12, r12
ch = getch(); 7e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
7e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
7e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7e50: 88 24 eor r8, r8
7e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
7e4e: a5 e0 ldi r26, 0x05 ; 5 7e54: b5 e0 ldi r27, 0x05 ; 5
7e50: ea 2e mov r14, r26 7e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7e52: f1 e1 ldi r31, 0x11 ; 17 7e58: a1 e1 ldi r26, 0x11 ; 17
7e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
7e56: ab d0 rcall .+342 ; 0x7fae <getch> 7e60: a2 d0 rcall .+324 ; 0x7fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
7e58: 81 34 cpi r24, 0x41 ; 65 7e62: 81 34 cpi r24, 0x41 ; 65
7e5a: 21 f4 brne .+8 ; 0x7e64 <main+0x64> 7e64: 61 f4 brne .+24 ; 0x7e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 7e66: 9f d0 rcall .+318 ; 0x7fa6 <getch>
7e5c: 81 e0 ldi r24, 0x01 ; 1 7e68: 08 2f mov r16, r24
7e5e: c5 d0 rcall .+394 ; 0x7fea <verifySpace+0xc> verifySpace();
putch(0x03); 7e6a: af d0 rcall .+350 ; 0x7fca <verifySpace>
7e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
7e62: 20 c0 rjmp .+64 ; 0x7ea4 <main+0xa4> 7e6c: 02 38 cpi r16, 0x82 ; 130
7e6e: 11 f0 breq .+4 ; 0x7e74 <main+0x74>
/*
* 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 <main+0x78>
putch(OPTIBOOT_MAJVER);
7e74: 84 e0 ldi r24, 0x04 ; 4
7e76: 01 c0 rjmp .+2 ; 0x7e7a <main+0x7a>
} 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 <putch>
7e7c: 89 c0 rjmp .+274 ; 0x7f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
7e64: 82 34 cpi r24, 0x42 ; 66 7e7e: 82 34 cpi r24, 0x42 ; 66
7e66: 11 f4 brne .+4 ; 0x7e6c <main+0x6c> 7e80: 11 f4 brne .+4 ; 0x7e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
7e68: 84 e1 ldi r24, 0x14 ; 20 7e82: 84 e1 ldi r24, 0x14 ; 20
7e6a: 03 c0 rjmp .+6 ; 0x7e72 <main+0x72> 7e84: 03 c0 rjmp .+6 ; 0x7e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
7e6c: 85 34 cpi r24, 0x45 ; 69 7e86: 85 34 cpi r24, 0x45 ; 69
7e6e: 19 f4 brne .+6 ; 0x7e76 <main+0x76> 7e88: 19 f4 brne .+6 ; 0x7e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
7e70: 85 e0 ldi r24, 0x05 ; 5 7e8a: 85 e0 ldi r24, 0x05 ; 5
7e72: bb d0 rcall .+374 ; 0x7fea <verifySpace+0xc> 7e8c: a6 d0 rcall .+332 ; 0x7fda <getNch>
7e74: 91 c0 rjmp .+290 ; 0x7f98 <main+0x198> 7e8e: 80 c0 rjmp .+256 ; 0x7f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
7e76: 85 35 cpi r24, 0x55 ; 85 7e90: 85 35 cpi r24, 0x55 ; 85
7e78: 81 f4 brne .+32 ; 0x7e9a <main+0x9a> 7e92: 79 f4 brne .+30 ; 0x7eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
7e7a: 99 d0 rcall .+306 ; 0x7fae <getch> 7e94: 88 d0 rcall .+272 ; 0x7fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
7e7c: 08 2f mov r16, r24 7e96: e8 2e mov r14, r24
7e7e: 10 e0 ldi r17, 0x00 ; 0 7e98: ff 24 eor r15, r15
7e80: 96 d0 rcall .+300 ; 0x7fae <getch> 7e9a: 85 d0 rcall .+266 ; 0x7fa6 <getch>
7e82: 90 e0 ldi r25, 0x00 ; 0 7e9c: 08 2f mov r16, r24
7e84: 98 2f mov r25, r24 7e9e: 10 e0 ldi r17, 0x00 ; 0
7e86: 88 27 eor r24, r24 7ea0: 10 2f mov r17, r16
7e88: 80 2b or r24, r16 7ea2: 00 27 eor r16, r16
7e8a: 91 2b or r25, r17 7ea4: 0e 29 or r16, r14
7ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
7e8c: 88 0f add r24, r24 7ea8: 00 0f add r16, r16
7e8e: 99 1f adc r25, r25 7eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
7e90: 90 93 01 02 sts 0x0201, r25
7e94: 80 93 00 02 sts 0x0200, r24
7e98: 7e c0 rjmp .+252 ; 0x7f96 <main+0x196>
verifySpace(); verifySpace();
7eac: 8e d0 rcall .+284 ; 0x7fca <verifySpace>
7eae: 68 01 movw r12, r16
7eb0: 6f c0 rjmp .+222 ; 0x7f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
7e9a: 86 35 cpi r24, 0x56 ; 86 7eb2: 86 35 cpi r24, 0x56 ; 86
7e9c: 29 f4 brne .+10 ; 0x7ea8 <main+0xa8> 7eb4: 21 f4 brne .+8 ; 0x7ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
7e9e: 84 e0 ldi r24, 0x04 ; 4 7eb6: 84 e0 ldi r24, 0x04 ; 4
7ea0: a4 d0 rcall .+328 ; 0x7fea <verifySpace+0xc> 7eb8: 90 d0 rcall .+288 ; 0x7fda <getNch>
putch(0x00); putch(0x00);
7ea2: 80 e0 ldi r24, 0x00 ; 0 7eba: 80 e0 ldi r24, 0x00 ; 0
7ea4: 7c d0 rcall .+248 ; 0x7f9e <putch> 7ebc: de cf rjmp .-68 ; 0x7e7a <main+0x7a>
7ea6: 78 c0 rjmp .+240 ; 0x7f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
7ea8: 84 36 cpi r24, 0x64 ; 100 7ebe: 84 36 cpi r24, 0x64 ; 100
7eaa: 09 f0 breq .+2 ; 0x7eae <main+0xae> 7ec0: 09 f0 breq .+2 ; 0x7ec4 <main+0xc4>
7eac: 4e c0 rjmp .+156 ; 0x7f4a <main+0x14a> 7ec2: 40 c0 rjmp .+128 ; 0x7f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
7eae: 87 d0 rcall .+270 ; 0x7fbe <getLen> 7ec4: 70 d0 rcall .+224 ; 0x7fa6 <getch>
length = getch();
7ec6: 6f d0 rcall .+222 ; 0x7fa6 <getch>
7ec8: 08 2f mov r16, r24
getch();
7eca: 6d d0 rcall .+218 ; 0x7fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
7eb0: e0 91 00 02 lds r30, 0x0200 7ecc: 80 e0 ldi r24, 0x00 ; 0
7eb4: f0 91 01 02 lds r31, 0x0201 7ece: c8 16 cp r12, r24
7eb8: 80 e7 ldi r24, 0x70 ; 112 7ed0: 80 e7 ldi r24, 0x70 ; 112
7eba: e0 30 cpi r30, 0x00 ; 0 7ed2: d8 06 cpc r13, r24
7ebc: f8 07 cpc r31, r24 7ed4: 18 f4 brcc .+6 ; 0x7edc <main+0xdc>
7ebe: 18 f4 brcc .+6 ; 0x7ec6 <main+0xc6> 7ed6: f6 01 movw r30, r12
7ec0: 83 e0 ldi r24, 0x03 ; 3 7ed8: b7 be out 0x37, r11 ; 55
7ec2: 87 bf out 0x37, r24 ; 55 7eda: e8 95 spm
7ec4: e8 95 spm 7edc: c0 e0 ldi r28, 0x00 ; 0
7ec6: c0 e0 ldi r28, 0x00 ; 0 7ede: d1 e0 ldi r29, 0x01 ; 1
7ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
7eca: 71 d0 rcall .+226 ; 0x7fae <getch> 7ee0: 62 d0 rcall .+196 ; 0x7fa6 <getch>
7ecc: 89 93 st Y+, r24 7ee2: 89 93 st Y+, r24
while (--length); while (--length);
7ece: 80 91 02 02 lds r24, 0x0202 7ee4: 0c 17 cp r16, r28
7ed2: 81 50 subi r24, 0x01 ; 1 7ee6: e1 f7 brne .-8 ; 0x7ee0 <main+0xe0>
7ed4: 80 93 02 02 sts 0x0202, r24
7ed8: 88 23 and r24, r24
7eda: b9 f7 brne .-18 ; 0x7eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
7edc: e0 91 00 02 lds r30, 0x0200 7ee8: f0 e0 ldi r31, 0x00 ; 0
7ee0: f0 91 01 02 lds r31, 0x0201 7eea: cf 16 cp r12, r31
7ee4: 80 e7 ldi r24, 0x70 ; 112 7eec: f0 e7 ldi r31, 0x70 ; 112
7ee6: e0 30 cpi r30, 0x00 ; 0 7eee: df 06 cpc r13, r31
7ee8: f8 07 cpc r31, r24 7ef0: 18 f0 brcs .+6 ; 0x7ef8 <main+0xf8>
7eea: 18 f0 brcs .+6 ; 0x7ef2 <main+0xf2> 7ef2: f6 01 movw r30, r12
7eec: 83 e0 ldi r24, 0x03 ; 3 7ef4: b7 be out 0x37, r11 ; 55
7eee: 87 bf out 0x37, r24 ; 55 7ef6: e8 95 spm
7ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
7ef2: 75 d0 rcall .+234 ; 0x7fde <verifySpace> 7ef8: 68 d0 rcall .+208 ; 0x7fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
7ef4: 07 b6 in r0, 0x37 ; 55 7efa: 07 b6 in r0, 0x37 ; 55
7ef6: 00 fc sbrc r0, 0 7efc: 00 fc sbrc r0, 0
7ef8: fd cf rjmp .-6 ; 0x7ef4 <main+0xf4> 7efe: fd cf rjmp .-6 ; 0x7efa <main+0xfa>
} 7f00: a6 01 movw r20, r12
#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
7f02: a0 e0 ldi r26, 0x00 ; 0 7f02: a0 e0 ldi r26, 0x00 ; 0
7f04: b1 e0 ldi r27, 0x01 ; 1 7f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -313,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7f1c: fa 01 movw r30, r20 7f1c: fa 01 movw r30, r20
7f1e: 0c 01 movw r0, r24 7f1e: 0c 01 movw r0, r24
7f20: d7 be out 0x37, r13 ; 55 7f20: 87 be out 0x37, r8 ; 55
7f22: e8 95 spm 7f22: e8 95 spm
7f24: 11 24 eor r1, r1 7f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -324,219 +363,236 @@ int main(void) {
7f2c: a0 38 cpi r26, 0x80 ; 128 7f2c: a0 38 cpi r26, 0x80 ; 128
7f2e: bf 07 cpc r27, r31 7f2e: bf 07 cpc r27, r31
7f30: 51 f7 brne .-44 ; 0x7f06 <main+0x106> 7f30: 51 f7 brne .-44 ; 0x7f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
7f32: e0 91 00 02 lds r30, 0x0200 7f32: f6 01 movw r30, r12
7f36: f0 91 01 02 lds r31, 0x0201 7f34: a7 be out 0x37, r10 ; 55
7f3a: e7 be out 0x37, r14 ; 55 7f36: e8 95 spm
7f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
7f3e: 07 b6 in r0, 0x37 ; 55 7f38: 07 b6 in r0, 0x37 ; 55
7f40: 00 fc sbrc r0, 0 7f3a: 00 fc sbrc r0, 0
7f42: fd cf rjmp .-6 ; 0x7f3e <main+0x13e> 7f3c: fd cf rjmp .-6 ; 0x7f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
7f44: f7 be out 0x37, r15 ; 55 7f3e: 97 be out 0x37, r9 ; 55
7f46: e8 95 spm 7f40: e8 95 spm
7f48: 27 c0 rjmp .+78 ; 0x7f98 <main+0x198> 7f42: 26 c0 rjmp .+76 ; 0x7f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
7f4a: 84 37 cpi r24, 0x74 ; 116 7f44: 84 37 cpi r24, 0x74 ; 116
7f4c: b9 f4 brne .+46 ; 0x7f7c <main+0x17c> 7f46: b1 f4 brne .+44 ; 0x7f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
7f4e: 37 d0 rcall .+110 ; 0x7fbe <getLen> 7f48: 2e d0 rcall .+92 ; 0x7fa6 <getch>
length = getch();
7f4a: 2d d0 rcall .+90 ; 0x7fa6 <getch>
7f4c: f8 2e mov r15, r24
getch();
7f4e: 2b d0 rcall .+86 ; 0x7fa6 <getch>
verifySpace(); verifySpace();
7f50: 46 d0 rcall .+140 ; 0x7fde <verifySpace> 7f50: 3c d0 rcall .+120 ; 0x7fca <verifySpace>
7f52: f6 01 movw r30, r12
7f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
7f52: e0 91 00 02 lds r30, 0x0200 7f56: 8f 01 movw r16, r30
7f56: f0 91 01 02 lds r31, 0x0201 7f58: 0f 5f subi r16, 0xFF ; 255
7f5a: 31 96 adiw r30, 0x01 ; 1 7f5a: 1f 4f sbci r17, 0xFF ; 255
7f5c: f0 93 01 02 sts 0x0201, r31 7f5c: 84 91 lpm r24, Z+
7f60: e0 93 00 02 sts 0x0200, r30 7f5e: 1b d0 rcall .+54 ; 0x7f96 <putch>
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 <putch>
while (--length); while (--length);
7f6c: 80 91 02 02 lds r24, 0x0202 7f60: ea 94 dec r14
7f70: 81 50 subi r24, 0x01 ; 1 7f62: f8 01 movw r30, r16
7f72: 80 93 02 02 sts 0x0202, r24 7f64: c1 f7 brne .-16 ; 0x7f56 <main+0x156>
7f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
7f78: 61 f7 brne .-40 ; 0x7f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
7f7a: 0e c0 rjmp .+28 ; 0x7f98 <main+0x198> #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 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
7f7c: 85 37 cpi r24, 0x75 ; 117 7f74: 85 37 cpi r24, 0x75 ; 117
7f7e: 39 f4 brne .+14 ; 0x7f8e <main+0x18e> 7f76: 39 f4 brne .+14 ; 0x7f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
7f80: 2e d0 rcall .+92 ; 0x7fde <verifySpace> 7f78: 28 d0 rcall .+80 ; 0x7fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
7f82: 8e e1 ldi r24, 0x1E ; 30 7f7a: 8e e1 ldi r24, 0x1E ; 30
7f84: 0c d0 rcall .+24 ; 0x7f9e <putch> 7f7c: 0c d0 rcall .+24 ; 0x7f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
7f86: 85 e9 ldi r24, 0x95 ; 149 7f7e: 85 e9 ldi r24, 0x95 ; 149
7f88: 0a d0 rcall .+20 ; 0x7f9e <putch> 7f80: 0a d0 rcall .+20 ; 0x7f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
7f8a: 8f e0 ldi r24, 0x0F ; 15 7f82: 8f e0 ldi r24, 0x0F ; 15
7f8c: 8b cf rjmp .-234 ; 0x7ea4 <main+0xa4> 7f84: 7a cf rjmp .-268 ; 0x7e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
7f8e: 81 35 cpi r24, 0x51 ; 81 7f86: 81 35 cpi r24, 0x51 ; 81
7f90: 11 f4 brne .+4 ; 0x7f96 <main+0x196> 7f88: 11 f4 brne .+4 ; 0x7f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
7f92: 88 e0 ldi r24, 0x08 ; 8 7f8a: 88 e0 ldi r24, 0x08 ; 8
7f94: 19 d0 rcall .+50 ; 0x7fc8 <watchdogConfig> 7f8c: 18 d0 rcall .+48 ; 0x7fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
7f96: 23 d0 rcall .+70 ; 0x7fde <verifySpace> 7f8e: 1d d0 rcall .+58 ; 0x7fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
7f98: 80 e1 ldi r24, 0x10 ; 16 7f90: 80 e1 ldi r24, 0x10 ; 16
7f9a: 01 d0 rcall .+2 ; 0x7f9e <putch> 7f92: 01 d0 rcall .+2 ; 0x7f96 <putch>
7f9c: 5c cf rjmp .-328 ; 0x7e56 <main+0x56> 7f94: 65 cf rjmp .-310 ; 0x7e60 <main+0x60>
00007f9e <putch>: 00007f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
7f9e: 98 2f mov r25, r24 7f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
7fa0: 80 91 c0 00 lds r24, 0x00C0 7f98: 80 91 c0 00 lds r24, 0x00C0
7fa4: 85 ff sbrs r24, 5 7f9c: 85 ff sbrs r24, 5
7fa6: fc cf rjmp .-8 ; 0x7fa0 <putch+0x2> 7f9e: fc cf rjmp .-8 ; 0x7f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
7fa8: 90 93 c6 00 sts 0x00C6, r25 7fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
7fac: 08 95 ret 7fa4: 08 95 ret
00007fae <getch>: 00007fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
7fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
7fb0: 80 91 c0 00 lds r24, 0x00C0 7fa6: 80 91 c0 00 lds r24, 0x00C0
7fb4: 87 ff sbrs r24, 7 7faa: 87 ff sbrs r24, 7
7fb6: fc cf rjmp .-8 ; 0x7fb0 <getch+0x2> 7fac: fc cf rjmp .-8 ; 0x7fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
7fae: 80 91 c0 00 lds r24, 0x00C0
7fb2: 84 fd sbrc r24, 4
7fb4: 01 c0 rjmp .+2 ; 0x7fb8 <getch+0x12>
}
#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; ch = UDR0;
7fb8: 80 91 c6 00 lds r24, 0x00C6 7fb8: 80 91 c6 00 lds r24, 0x00C6
#ifdef LED_DATA_FLASH
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif
#endif #endif
return ch; return ch;
} }
7fbc: 08 95 ret 7fbc: 08 95 ret
00007fbe <getLen>: 00007fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
7fbe: f7 df rcall .-18 ; 0x7fae <getch>
length = getch();
7fc0: f6 df rcall .-20 ; 0x7fae <getch>
7fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
7fc6: f3 cf rjmp .-26 ; 0x7fae <getch>
00007fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
7fc8: e0 e6 ldi r30, 0x60 ; 96 7fbe: e0 e6 ldi r30, 0x60 ; 96
7fca: f0 e0 ldi r31, 0x00 ; 0 7fc0: f0 e0 ldi r31, 0x00 ; 0
7fcc: 98 e1 ldi r25, 0x18 ; 24 7fc2: 98 e1 ldi r25, 0x18 ; 24
7fce: 90 83 st Z, r25 7fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
7fd0: 80 83 st Z, r24 7fc6: 80 83 st Z, r24
} }
7fd2: 08 95 ret 7fc8: 08 95 ret
00007fd4 <appStart>: 00007fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
7fd4: 80 e0 ldi r24, 0x00 ; 0
7fd6: f8 df rcall .-16 ; 0x7fc8 <watchdogConfig>
__asm__ __volatile__ (
7fd8: ee 27 eor r30, r30
7fda: ff 27 eor r31, r31
7fdc: 09 94 ijmp
00007fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
7fde: e7 df rcall .-50 ; 0x7fae <getch> 7fca: ed df rcall .-38 ; 0x7fa6 <getch>
7fe0: 80 32 cpi r24, 0x20 ; 32 7fcc: 80 32 cpi r24, 0x20 ; 32
7fe2: 09 f0 breq .+2 ; 0x7fe6 <verifySpace+0x8> 7fce: 19 f0 breq .+6 ; 0x7fd6 <verifySpace+0xc>
7fe4: f7 df rcall .-18 ; 0x7fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
7fd0: 88 e0 ldi r24, 0x08 ; 8
7fd2: f5 df rcall .-22 ; 0x7fbe <watchdogConfig>
7fd4: ff cf rjmp .-2 ; 0x7fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
7fe6: 84 e1 ldi r24, 0x14 ; 20 7fd6: 84 e1 ldi r24, 0x14 ; 20
} }
7fe8: da cf rjmp .-76 ; 0x7f9e <putch> 7fd8: de cf rjmp .-68 ; 0x7f96 <putch>
00007fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
7fea: 1f 93 push r17 7fda: 1f 93 push r17
7fec: 18 2f mov r17, r24 7fdc: 18 2f mov r17, r24
00007fee <getNch>:
do getch(); while (--count); do getch(); while (--count);
7fee: df df rcall .-66 ; 0x7fae <getch> 7fde: e3 df rcall .-58 ; 0x7fa6 <getch>
7ff0: 11 50 subi r17, 0x01 ; 1 7fe0: 11 50 subi r17, 0x01 ; 1
7ff2: e9 f7 brne .-6 ; 0x7fee <getNch> 7fe2: e9 f7 brne .-6 ; 0x7fde <getNch+0x4>
verifySpace(); verifySpace();
7ff4: f4 df rcall .-24 ; 0x7fde <verifySpace> 7fe4: f2 df rcall .-28 ; 0x7fca <verifySpace>
} }
7ff6: 1f 91 pop r17 7fe6: 1f 91 pop r17
7ff8: 08 95 ret 7fe8: 08 95 ret
00007fea <appStart>:
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 <watchdogConfig>
__asm__ __volatile__ (
7fee: ee 27 eor r30, r30
7ff0: ff 27 eor r31, r31
7ff2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:10FC000084B714BE81FFE6D085E08093810082E056 :020000000404F6
:10FC10008093C00088E18093C10086E08093C20099 :10FC0000112484B714BE81FFF0D085E08093810079
:10FC200080E18093C4008EE0CFD0209A86E020E36C :10FC100082E08093C00088E18093C10086E08093F9
:10FC30003CEF91E0309385002093840096BBB09B0D :10FC2000C20080E18093C4008EE0C9D0209A86E0B3
:10FC4000FECF189AA8958150A9F7DD24D394A5E09A :10FC300020E33CEF91E0309385002093840096BB55
:10FC5000EA2EF1E1FF2EABD0813421F481E0C5D052 :10FC4000B09BFECF189AA8958150A9F7CC24DD244B
:10FC600083E020C0823411F484E103C0853419F4A8 :10FC500088248394B5E0AB2EA1E19A2EF3E0BF2E69
:10FC700085E0BBD091C0853581F499D0082F10E084 :10FC6000A2D0813461F49FD0082FAFD0023811F0B8
:10FC800096D090E0982F8827802B912B880F991F72 :10FC7000013811F484E001C083E08DD089C0823462
:10FC900090930103809300037EC0863529F484E0AD :10FC800011F484E103C0853419F485E0A6D080C066
:10FCA000A4D080E07CD078C0843609F04EC087D0E4 :10FC9000853579F488D0E82EFF2485D0082F10E030
:10FCB000E0910003F091010380EEE030F80718F4C2 :10FCA000102F00270E291F29000F111F8ED0680169
:10FCC00083E087BFE895C0E0D1E071D0899380914F :10FCB0006FC0863521F484E090D080E0DECF8436BA
:10FCD00002038150809302038823B9F7E091000367 :10FCC00009F040C070D06FD0082F6DD080E0C8160A
:10FCE000F091010380EEE030F80718F083E087BF61 :10FCD00080EED80618F4F601B7BEE895C0E0D1E092
:10FCF000E89575D007B600FCFDCF40910003509108 :10FCE00062D089930C17E1F7F0E0CF16F0EEDF0653
:10FD00000103A0E0B1E02C9130E011968C911197A5 :10FCF00018F0F601B7BEE89568D007B600FCFDCF56
:10FD0000A601A0E0B1E02C9130E011968C91119702
:10FD100090E0982F8827822B932B1296FA010C01E2 :10FD100090E0982F8827822B932B1296FA010C01E2
:10FD2000D7BEE89511244E5F5F4FF2E0A030BF07C9 :10FD200087BEE89511244E5F5F4FF2E0A030BF0719
:10FD300051F7E0910003F0910103E7BEE89507B6A3 :10FD300051F7F601A7BEE89507B600FCFDCF97BEC8
:10FD400000FCFDCFF7BEE89527C08437B9F437D063 :10FD4000E89526C08437B1F42ED02DD0F82E2BD0D4
:10FD500046D0E0910003F09101033196F093010346 :10FD50003CD0F601EF2C8F010F5F1F4F84911BD019
:10FD6000E09300033197E4918E2F19D08091020324 :10FD6000EA94F801C1F70894C11CD11CFA94CF0C95
:10FD7000815080930203882361F70EC0853739F4E0 :10FD7000D11C0EC0853739F428D08EE10CD086E92D
:10FD80002ED08EE10CD086E90AD08AE08BCF813567 :10FD80000AD089E07ACF813511F488E018D01DD0EF
:10FD900011F488E019D023D080E101D05CCF982FF6 :10FD900080E101D065CF982F8091C00085FFFCCF16
:10FDA0008091C00085FFFCCF9093C6000895A89570 :10FDA0009093C60008958091C00087FFFCCF80919A
:10FDB0008091C00087FFFCCF8091C6000895F7DFD7 :10FDB000C00084FD01C0A8958091C6000895E0E6CA
:10FDC000F6DF80930203F3CFE0E6F0E098E1908362 :10FDC000F0E098E1908380830895EDDF803219F0B0
:10FDD0008083089580E0F8DFEE27FF270994E7DFAE :10FDD00088E0F5DFFFCF84E1DECF1F93182FE3DF4C
:10FDE000803209F0F7DF84E1DACF1F93182FDFDFCD :10FDE0001150E9F7F2DF1F91089580E0E8DFEE2778
:0AFDF0001150E9F7F4DF1F910895A8 :04FDF000FF2709944C
:040000030000FC00FD :040000030000FC00FD
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_atmega644p.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 2 .debug_pubnames 0000005f 00000000 00000000 00000270 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 3 .debug_info 000002a8 00000000 00000000 000002cf 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 4 .debug_abbrev 00000178 00000000 00000000 00000577 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 5 .debug_line 0000046b 00000000 00000000 000006ef 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 6 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 7 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 8 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING 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 CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
fc00: 84 b7 in r24, 0x34 ; 52 fc00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
fc02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
fc02: 14 be out 0x34, r1 ; 52 fc04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
fc04: 81 ff sbrs r24, 1 fc06: 81 ff sbrs r24, 1
fc06: e6 d0 rcall .+460 ; 0xfdd4 <appStart> fc08: f0 d0 rcall .+480 ; 0xfdea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
fc08: 85 e0 ldi r24, 0x05 ; 5 fc0a: 85 e0 ldi r24, 0x05 ; 5
fc0a: 80 93 81 00 sts 0x0081, r24 fc0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
fc0e: 82 e0 ldi r24, 0x02 ; 2 fc10: 82 e0 ldi r24, 0x02 ; 2
fc10: 80 93 c0 00 sts 0x00C0, r24 fc12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
fc14: 88 e1 ldi r24, 0x18 ; 24 fc16: 88 e1 ldi r24, 0x18 ; 24
fc16: 80 93 c1 00 sts 0x00C1, r24 fc18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
fc1a: 86 e0 ldi r24, 0x06 ; 6 fc1c: 86 e0 ldi r24, 0x06 ; 6
fc1c: 80 93 c2 00 sts 0x00C2, r24 fc1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
fc20: 80 e1 ldi r24, 0x10 ; 16 fc22: 80 e1 ldi r24, 0x10 ; 16
fc22: 80 93 c4 00 sts 0x00C4, r24 fc24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
fc26: 8e e0 ldi r24, 0x0E ; 14 fc28: 8e e0 ldi r24, 0x0E ; 14
fc28: cf d0 rcall .+414 ; 0xfdc8 <watchdogConfig> fc2a: c9 d0 rcall .+402 ; 0xfdbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
fc2a: 20 9a sbi 0x04, 0 ; 4 fc2c: 20 9a sbi 0x04, 0 ; 4
fc2c: 86 e0 ldi r24, 0x06 ; 6 fc2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
fc2e: 20 e3 ldi r18, 0x30 ; 48 fc30: 20 e3 ldi r18, 0x30 ; 48
fc30: 3c ef ldi r19, 0xFC ; 252 fc32: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
fc32: 91 e0 ldi r25, 0x01 ; 1 fc34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
fc34: 30 93 85 00 sts 0x0085, r19 fc36: 30 93 85 00 sts 0x0085, r19
fc38: 20 93 84 00 sts 0x0084, r18 fc3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
fc3c: 96 bb out 0x16, r25 ; 22 fc3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
fc3e: b0 9b sbis 0x16, 0 ; 22 fc40: b0 9b sbis 0x16, 0 ; 22
fc40: fe cf rjmp .-4 ; 0xfc3e <main+0x3e> fc42: fe cf rjmp .-4 ; 0xfc40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
fc42: 18 9a sbi 0x03, 0 ; 3 fc44: 18 9a sbi 0x03, 0 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
fc44: a8 95 wdr fc46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
fc46: 81 50 subi r24, 0x01 ; 1 fc48: 81 50 subi r24, 0x01 ; 1
fc48: a9 f7 brne .-22 ; 0xfc34 <main+0x34> fc4a: a9 f7 brne .-22 ; 0xfc36 <main+0x36>
/* get character from UART */ fc4c: cc 24 eor r12, r12
ch = getch(); fc4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
fc4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
fc4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
fc50: 88 24 eor r8, r8
fc52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
fc4e: a5 e0 ldi r26, 0x05 ; 5 fc54: b5 e0 ldi r27, 0x05 ; 5
fc50: ea 2e mov r14, r26 fc56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
fc52: f1 e1 ldi r31, 0x11 ; 17 fc58: a1 e1 ldi r26, 0x11 ; 17
fc54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
fc56: ab d0 rcall .+342 ; 0xfdae <getch> fc60: a2 d0 rcall .+324 ; 0xfda6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
fc58: 81 34 cpi r24, 0x41 ; 65 fc62: 81 34 cpi r24, 0x41 ; 65
fc5a: 21 f4 brne .+8 ; 0xfc64 <main+0x64> fc64: 61 f4 brne .+24 ; 0xfc7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); fc66: 9f d0 rcall .+318 ; 0xfda6 <getch>
fc5c: 81 e0 ldi r24, 0x01 ; 1 fc68: 08 2f mov r16, r24
fc5e: c5 d0 rcall .+394 ; 0xfdea <getNch> verifySpace();
putch(0x03); fc6a: af d0 rcall .+350 ; 0xfdca <verifySpace>
fc60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
fc62: 20 c0 rjmp .+64 ; 0xfca4 <main+0xa4> fc6c: 02 38 cpi r16, 0x82 ; 130
fc6e: 11 f0 breq .+4 ; 0xfc74 <main+0x74>
/*
* 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 <main+0x78>
putch(OPTIBOOT_MAJVER);
fc74: 84 e0 ldi r24, 0x04 ; 4
fc76: 01 c0 rjmp .+2 ; 0xfc7a <main+0x7a>
} 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 <putch>
fc7c: 89 c0 rjmp .+274 ; 0xfd90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
fc64: 82 34 cpi r24, 0x42 ; 66 fc7e: 82 34 cpi r24, 0x42 ; 66
fc66: 11 f4 brne .+4 ; 0xfc6c <main+0x6c> fc80: 11 f4 brne .+4 ; 0xfc86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
fc68: 84 e1 ldi r24, 0x14 ; 20 fc82: 84 e1 ldi r24, 0x14 ; 20
fc6a: 03 c0 rjmp .+6 ; 0xfc72 <main+0x72> fc84: 03 c0 rjmp .+6 ; 0xfc8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
fc6c: 85 34 cpi r24, 0x45 ; 69 fc86: 85 34 cpi r24, 0x45 ; 69
fc6e: 19 f4 brne .+6 ; 0xfc76 <main+0x76> fc88: 19 f4 brne .+6 ; 0xfc90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
fc70: 85 e0 ldi r24, 0x05 ; 5 fc8a: 85 e0 ldi r24, 0x05 ; 5
fc72: bb d0 rcall .+374 ; 0xfdea <getNch> fc8c: a6 d0 rcall .+332 ; 0xfdda <getNch>
fc74: 91 c0 rjmp .+290 ; 0xfd98 <main+0x198> fc8e: 80 c0 rjmp .+256 ; 0xfd90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
fc76: 85 35 cpi r24, 0x55 ; 85 fc90: 85 35 cpi r24, 0x55 ; 85
fc78: 81 f4 brne .+32 ; 0xfc9a <main+0x9a> fc92: 79 f4 brne .+30 ; 0xfcb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
fc7a: 99 d0 rcall .+306 ; 0xfdae <getch> fc94: 88 d0 rcall .+272 ; 0xfda6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
fc7c: 08 2f mov r16, r24 fc96: e8 2e mov r14, r24
fc7e: 10 e0 ldi r17, 0x00 ; 0 fc98: ff 24 eor r15, r15
fc80: 96 d0 rcall .+300 ; 0xfdae <getch> fc9a: 85 d0 rcall .+266 ; 0xfda6 <getch>
fc82: 90 e0 ldi r25, 0x00 ; 0 fc9c: 08 2f mov r16, r24
fc84: 98 2f mov r25, r24 fc9e: 10 e0 ldi r17, 0x00 ; 0
fc86: 88 27 eor r24, r24 fca0: 10 2f mov r17, r16
fc88: 80 2b or r24, r16 fca2: 00 27 eor r16, r16
fc8a: 91 2b or r25, r17 fca4: 0e 29 or r16, r14
fca6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
fc8c: 88 0f add r24, r24 fca8: 00 0f add r16, r16
fc8e: 99 1f adc r25, r25 fcaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
fc90: 90 93 01 03 sts 0x0301, r25
fc94: 80 93 00 03 sts 0x0300, r24
fc98: 7e c0 rjmp .+252 ; 0xfd96 <main+0x196>
verifySpace(); verifySpace();
fcac: 8e d0 rcall .+284 ; 0xfdca <verifySpace>
fcae: 68 01 movw r12, r16
fcb0: 6f c0 rjmp .+222 ; 0xfd90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
fc9a: 86 35 cpi r24, 0x56 ; 86 fcb2: 86 35 cpi r24, 0x56 ; 86
fc9c: 29 f4 brne .+10 ; 0xfca8 <main+0xa8> fcb4: 21 f4 brne .+8 ; 0xfcbe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
fc9e: 84 e0 ldi r24, 0x04 ; 4 fcb6: 84 e0 ldi r24, 0x04 ; 4
fca0: a4 d0 rcall .+328 ; 0xfdea <getNch> fcb8: 90 d0 rcall .+288 ; 0xfdda <getNch>
putch(0x00); putch(0x00);
fca2: 80 e0 ldi r24, 0x00 ; 0 fcba: 80 e0 ldi r24, 0x00 ; 0
fca4: 7c d0 rcall .+248 ; 0xfd9e <putch> fcbc: de cf rjmp .-68 ; 0xfc7a <main+0x7a>
fca6: 78 c0 rjmp .+240 ; 0xfd98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
fca8: 84 36 cpi r24, 0x64 ; 100 fcbe: 84 36 cpi r24, 0x64 ; 100
fcaa: 09 f0 breq .+2 ; 0xfcae <main+0xae> fcc0: 09 f0 breq .+2 ; 0xfcc4 <main+0xc4>
fcac: 4e c0 rjmp .+156 ; 0xfd4a <main+0x14a> fcc2: 40 c0 rjmp .+128 ; 0xfd44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
fcae: 87 d0 rcall .+270 ; 0xfdbe <getLen> fcc4: 70 d0 rcall .+224 ; 0xfda6 <getch>
length = getch();
fcc6: 6f d0 rcall .+222 ; 0xfda6 <getch>
fcc8: 08 2f mov r16, r24
getch();
fcca: 6d d0 rcall .+218 ; 0xfda6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
fcb0: e0 91 00 03 lds r30, 0x0300 fccc: 80 e0 ldi r24, 0x00 ; 0
fcb4: f0 91 01 03 lds r31, 0x0301 fcce: c8 16 cp r12, r24
fcb8: 80 ee ldi r24, 0xE0 ; 224 fcd0: 80 ee ldi r24, 0xE0 ; 224
fcba: e0 30 cpi r30, 0x00 ; 0 fcd2: d8 06 cpc r13, r24
fcbc: f8 07 cpc r31, r24 fcd4: 18 f4 brcc .+6 ; 0xfcdc <main+0xdc>
fcbe: 18 f4 brcc .+6 ; 0xfcc6 <main+0xc6> fcd6: f6 01 movw r30, r12
fcc0: 83 e0 ldi r24, 0x03 ; 3 fcd8: b7 be out 0x37, r11 ; 55
fcc2: 87 bf out 0x37, r24 ; 55 fcda: e8 95 spm
fcc4: e8 95 spm fcdc: c0 e0 ldi r28, 0x00 ; 0
fcc6: c0 e0 ldi r28, 0x00 ; 0 fcde: d1 e0 ldi r29, 0x01 ; 1
fcc8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
fcca: 71 d0 rcall .+226 ; 0xfdae <getch> fce0: 62 d0 rcall .+196 ; 0xfda6 <getch>
fccc: 89 93 st Y+, r24 fce2: 89 93 st Y+, r24
while (--length); while (--length);
fcce: 80 91 02 03 lds r24, 0x0302 fce4: 0c 17 cp r16, r28
fcd2: 81 50 subi r24, 0x01 ; 1 fce6: e1 f7 brne .-8 ; 0xfce0 <main+0xe0>
fcd4: 80 93 02 03 sts 0x0302, r24
fcd8: 88 23 and r24, r24
fcda: b9 f7 brne .-18 ; 0xfcca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
fcdc: e0 91 00 03 lds r30, 0x0300 fce8: f0 e0 ldi r31, 0x00 ; 0
fce0: f0 91 01 03 lds r31, 0x0301 fcea: cf 16 cp r12, r31
fce4: 80 ee ldi r24, 0xE0 ; 224 fcec: f0 ee ldi r31, 0xE0 ; 224
fce6: e0 30 cpi r30, 0x00 ; 0 fcee: df 06 cpc r13, r31
fce8: f8 07 cpc r31, r24 fcf0: 18 f0 brcs .+6 ; 0xfcf8 <main+0xf8>
fcea: 18 f0 brcs .+6 ; 0xfcf2 <main+0xf2> fcf2: f6 01 movw r30, r12
fcec: 83 e0 ldi r24, 0x03 ; 3 fcf4: b7 be out 0x37, r11 ; 55
fcee: 87 bf out 0x37, r24 ; 55 fcf6: e8 95 spm
fcf0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
fcf2: 75 d0 rcall .+234 ; 0xfdde <verifySpace> fcf8: 68 d0 rcall .+208 ; 0xfdca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
fcf4: 07 b6 in r0, 0x37 ; 55 fcfa: 07 b6 in r0, 0x37 ; 55
fcf6: 00 fc sbrc r0, 0 fcfc: 00 fc sbrc r0, 0
fcf8: fd cf rjmp .-6 ; 0xfcf4 <main+0xf4> fcfe: fd cf rjmp .-6 ; 0xfcfa <main+0xfa>
} fd00: a6 01 movw r20, r12
#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
fd02: a0 e0 ldi r26, 0x00 ; 0 fd02: a0 e0 ldi r26, 0x00 ; 0
fd04: b1 e0 ldi r27, 0x01 ; 1 fd04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
fd1c: fa 01 movw r30, r20 fd1c: fa 01 movw r30, r20
fd1e: 0c 01 movw r0, r24 fd1e: 0c 01 movw r0, r24
fd20: d7 be out 0x37, r13 ; 55 fd20: 87 be out 0x37, r8 ; 55
fd22: e8 95 spm fd22: e8 95 spm
fd24: 11 24 eor r1, r1 fd24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
fd2c: a0 30 cpi r26, 0x00 ; 0 fd2c: a0 30 cpi r26, 0x00 ; 0
fd2e: bf 07 cpc r27, r31 fd2e: bf 07 cpc r27, r31
fd30: 51 f7 brne .-44 ; 0xfd06 <main+0x106> fd30: 51 f7 brne .-44 ; 0xfd06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
fd32: e0 91 00 03 lds r30, 0x0300 fd32: f6 01 movw r30, r12
fd36: f0 91 01 03 lds r31, 0x0301 fd34: a7 be out 0x37, r10 ; 55
fd3a: e7 be out 0x37, r14 ; 55 fd36: e8 95 spm
fd3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
fd3e: 07 b6 in r0, 0x37 ; 55 fd38: 07 b6 in r0, 0x37 ; 55
fd40: 00 fc sbrc r0, 0 fd3a: 00 fc sbrc r0, 0
fd42: fd cf rjmp .-6 ; 0xfd3e <main+0x13e> fd3c: fd cf rjmp .-6 ; 0xfd38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
fd44: f7 be out 0x37, r15 ; 55 fd3e: 97 be out 0x37, r9 ; 55
fd46: e8 95 spm fd40: e8 95 spm
fd48: 27 c0 rjmp .+78 ; 0xfd98 <main+0x198> fd42: 26 c0 rjmp .+76 ; 0xfd90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
fd4a: 84 37 cpi r24, 0x74 ; 116 fd44: 84 37 cpi r24, 0x74 ; 116
fd4c: b9 f4 brne .+46 ; 0xfd7c <main+0x17c> fd46: b1 f4 brne .+44 ; 0xfd74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
fd4e: 37 d0 rcall .+110 ; 0xfdbe <getLen> fd48: 2e d0 rcall .+92 ; 0xfda6 <getch>
length = getch();
fd4a: 2d d0 rcall .+90 ; 0xfda6 <getch>
fd4c: f8 2e mov r15, r24
getch();
fd4e: 2b d0 rcall .+86 ; 0xfda6 <getch>
verifySpace(); verifySpace();
fd50: 46 d0 rcall .+140 ; 0xfdde <verifySpace> fd50: 3c d0 rcall .+120 ; 0xfdca <verifySpace>
fd52: f6 01 movw r30, r12
fd54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
fd52: e0 91 00 03 lds r30, 0x0300 fd56: 8f 01 movw r16, r30
fd56: f0 91 01 03 lds r31, 0x0301 fd58: 0f 5f subi r16, 0xFF ; 255
fd5a: 31 96 adiw r30, 0x01 ; 1 fd5a: 1f 4f sbci r17, 0xFF ; 255
fd5c: f0 93 01 03 sts 0x0301, r31 fd5c: 84 91 lpm r24, Z+
fd60: e0 93 00 03 sts 0x0300, r30 fd5e: 1b d0 rcall .+54 ; 0xfd96 <putch>
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 <putch>
while (--length); while (--length);
fd6c: 80 91 02 03 lds r24, 0x0302 fd60: ea 94 dec r14
fd70: 81 50 subi r24, 0x01 ; 1 fd62: f8 01 movw r30, r16
fd72: 80 93 02 03 sts 0x0302, r24 fd64: c1 f7 brne .-16 ; 0xfd56 <main+0x156>
fd76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
fd78: 61 f7 brne .-40 ; 0xfd52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
fd7a: 0e c0 rjmp .+28 ; 0xfd98 <main+0x198> #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 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
fd7c: 85 37 cpi r24, 0x75 ; 117 fd74: 85 37 cpi r24, 0x75 ; 117
fd7e: 39 f4 brne .+14 ; 0xfd8e <main+0x18e> fd76: 39 f4 brne .+14 ; 0xfd86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
fd80: 2e d0 rcall .+92 ; 0xfdde <verifySpace> fd78: 28 d0 rcall .+80 ; 0xfdca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
fd82: 8e e1 ldi r24, 0x1E ; 30 fd7a: 8e e1 ldi r24, 0x1E ; 30
fd84: 0c d0 rcall .+24 ; 0xfd9e <putch> fd7c: 0c d0 rcall .+24 ; 0xfd96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
fd86: 86 e9 ldi r24, 0x96 ; 150 fd7e: 86 e9 ldi r24, 0x96 ; 150
fd88: 0a d0 rcall .+20 ; 0xfd9e <putch> fd80: 0a d0 rcall .+20 ; 0xfd96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
fd8a: 8a e0 ldi r24, 0x0A ; 10 fd82: 89 e0 ldi r24, 0x09 ; 9
fd8c: 8b cf rjmp .-234 ; 0xfca4 <main+0xa4> fd84: 7a cf rjmp .-268 ; 0xfc7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
fd8e: 81 35 cpi r24, 0x51 ; 81 fd86: 81 35 cpi r24, 0x51 ; 81
fd90: 11 f4 brne .+4 ; 0xfd96 <main+0x196> fd88: 11 f4 brne .+4 ; 0xfd8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
fd92: 88 e0 ldi r24, 0x08 ; 8 fd8a: 88 e0 ldi r24, 0x08 ; 8
fd94: 19 d0 rcall .+50 ; 0xfdc8 <watchdogConfig> fd8c: 18 d0 rcall .+48 ; 0xfdbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
fd96: 23 d0 rcall .+70 ; 0xfdde <verifySpace> fd8e: 1d d0 rcall .+58 ; 0xfdca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
fd98: 80 e1 ldi r24, 0x10 ; 16 fd90: 80 e1 ldi r24, 0x10 ; 16
fd9a: 01 d0 rcall .+2 ; 0xfd9e <putch> fd92: 01 d0 rcall .+2 ; 0xfd96 <putch>
fd9c: 5c cf rjmp .-328 ; 0xfc56 <main+0x56> fd94: 65 cf rjmp .-310 ; 0xfc60 <main+0x60>
0000fd9e <putch>: 0000fd96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
fd9e: 98 2f mov r25, r24 fd96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
fda0: 80 91 c0 00 lds r24, 0x00C0 fd98: 80 91 c0 00 lds r24, 0x00C0
fda4: 85 ff sbrs r24, 5 fd9c: 85 ff sbrs r24, 5
fda6: fc cf rjmp .-8 ; 0xfda0 <putch+0x2> fd9e: fc cf rjmp .-8 ; 0xfd98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
fda8: 90 93 c6 00 sts 0x00C6, r25 fda0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
fdac: 08 95 ret fda4: 08 95 ret
0000fdae <getch>: 0000fda6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
fdae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
fdb0: 80 91 c0 00 lds r24, 0x00C0 fda6: 80 91 c0 00 lds r24, 0x00C0
fdb4: 87 ff sbrs r24, 7 fdaa: 87 ff sbrs r24, 7
fdb6: fc cf rjmp .-8 ; 0xfdb0 <getch+0x2> fdac: fc cf rjmp .-8 ; 0xfda6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
fdae: 80 91 c0 00 lds r24, 0x00C0
fdb2: 84 fd sbrc r24, 4
fdb4: 01 c0 rjmp .+2 ; 0xfdb8 <getch+0x12>
}
#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; ch = UDR0;
fdb8: 80 91 c6 00 lds r24, 0x00C6 fdb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
fdbc: 08 95 ret fdbc: 08 95 ret
0000fdbe <getLen>: 0000fdbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
fdbe: f7 df rcall .-18 ; 0xfdae <getch>
length = getch();
fdc0: f6 df rcall .-20 ; 0xfdae <getch>
fdc2: 80 93 02 03 sts 0x0302, r24
return getch();
}
fdc6: f3 cf rjmp .-26 ; 0xfdae <getch>
0000fdc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
fdc8: e0 e6 ldi r30, 0x60 ; 96 fdbe: e0 e6 ldi r30, 0x60 ; 96
fdca: f0 e0 ldi r31, 0x00 ; 0 fdc0: f0 e0 ldi r31, 0x00 ; 0
fdcc: 98 e1 ldi r25, 0x18 ; 24 fdc2: 98 e1 ldi r25, 0x18 ; 24
fdce: 90 83 st Z, r25 fdc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
fdd0: 80 83 st Z, r24 fdc6: 80 83 st Z, r24
} }
fdd2: 08 95 ret fdc8: 08 95 ret
0000fdd4 <appStart>: 0000fdca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
fdd4: 80 e0 ldi r24, 0x00 ; 0
fdd6: f8 df rcall .-16 ; 0xfdc8 <watchdogConfig>
__asm__ __volatile__ (
fdd8: ee 27 eor r30, r30
fdda: ff 27 eor r31, r31
fddc: 09 94 ijmp
0000fdde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
fdde: e7 df rcall .-50 ; 0xfdae <getch> fdca: ed df rcall .-38 ; 0xfda6 <getch>
fde0: 80 32 cpi r24, 0x20 ; 32 fdcc: 80 32 cpi r24, 0x20 ; 32
fde2: 09 f0 breq .+2 ; 0xfde6 <verifySpace+0x8> fdce: 19 f0 breq .+6 ; 0xfdd6 <verifySpace+0xc>
fde4: f7 df rcall .-18 ; 0xfdd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
fdd0: 88 e0 ldi r24, 0x08 ; 8
fdd2: f5 df rcall .-22 ; 0xfdbe <watchdogConfig>
fdd4: ff cf rjmp .-2 ; 0xfdd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
fde6: 84 e1 ldi r24, 0x14 ; 20 fdd6: 84 e1 ldi r24, 0x14 ; 20
} }
fde8: da cf rjmp .-76 ; 0xfd9e <putch> fdd8: de cf rjmp .-68 ; 0xfd96 <putch>
0000fdea <getNch>: 0000fdda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
fdea: 1f 93 push r17 fdda: 1f 93 push r17
fdec: 18 2f mov r17, r24 fddc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
fdee: df df rcall .-66 ; 0xfdae <getch> fdde: e3 df rcall .-58 ; 0xfda6 <getch>
fdf0: 11 50 subi r17, 0x01 ; 1 fde0: 11 50 subi r17, 0x01 ; 1
fdf2: e9 f7 brne .-6 ; 0xfdee <getNch+0x4> fde2: e9 f7 brne .-6 ; 0xfdde <getNch+0x4>
verifySpace(); verifySpace();
fdf4: f4 df rcall .-24 ; 0xfdde <verifySpace> fde4: f2 df rcall .-28 ; 0xfdca <verifySpace>
} }
fdf6: 1f 91 pop r17 fde6: 1f 91 pop r17
fdf8: 08 95 ret fde8: 08 95 ret
0000fdea <appStart>:
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 <watchdogConfig>
__asm__ __volatile__ (
fdee: ee 27 eor r30, r30
fdf0: ff 27 eor r31, r31
fdf2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:103E000084B714BE81FFE6D085E08093810082E014 :103E0000112484B714BE81FFF0D085E08093810037
:103E10008093C00088E18093C10086E08093C20057 :103E100082E08093C00088E18093C10086E08093B7
:103E200088E08093C4008EE0CFD0259A86E028E118 :103E2000C20088E08093C4008EE0C9D0259A86E065
:103E30003EEF91E0309385002093840096BBB09BC9 :103E300028E13EEF91E0309385002093840096BB0B
:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 :103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 :103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
:103E600083E020C0823411F484E103C0853419F466 :103E6000A2D0813461F49FD0082FAFD0023811F076
:103E700085E0BBD091C0853581F499D0082F10E042 :103E7000013811F484E001C083E08DD089C0823420
:103E800096D090E0982F8827802B912B880F991F30 :103E800011F484E103C0853419F485E0A6D080C024
:103E900090930102809300027EC0863529F484E06D :103E9000853579F488D0E82EFF2485D0082F10E0EE
:103EA000A4D080E07CD078C0843609F04EC087D0A2 :103EA000102F00270E291F29000F111F8ED0680127
:103EB000E0910002F091010288E3E030F80718F485 :103EB0006FC0863521F484E090D080E0DECF843678
:103EC00083E087BFE895C0E0D1E071D0899380910D :103EC00009F040C070D06FD0082F6DD080E0C816C8
:103ED00002028150809302028823B9F7E091000228 :103ED00088E3D80618F4F601B7BEE895C0E0D1E053
:103EE000F091010288E3E030F80718F083E087BF23 :103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
:103EF000E89575D007B600FCFDCF409100025091C7 :103EF00018F0F601B7BEE89568D007B600FCFDCF14
:103F00000102A0E0B1E02C9130E011968C91119764 :103F0000A601A0E0B1E02C9130E011968C911197C0
:103F100090E0982F8827822B932B1296FA010C01A0 :103F100090E0982F8827822B932B1296FA010C01A0
:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 :103F200087BEE89511244E5F5F4FF1E0A038BF07D0
:103F300051F7E0910002F0910102E7BEE89507B663 :103F300051F7F601A7BEE89507B600FCFDCF97BE86
:103F400000FCFDCFF7BEE89527C08437B9F437D021 :103F4000E89526C08437B1F42ED02DD0F82E2BD092
:103F500046D0E0910002F09101023196F093010207 :103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
:103F6000E09300023197E4918E2F19D080910202E4 :103F6000EA94F801C1F70894C11CD11CFA94CF0C53
:103F7000815080930202882361F70EC0853739F49F :103F7000D11C0EC0853739F428D08EE10CD084E9ED
:103F80002ED08EE10CD084E90AD086E08BCF81352B :103F80000AD086E07ACF813511F488E018D01DD0B0
:103F900011F488E019D023D080E101D05CCF982FB4 :103F900080E101D065CF982F8091C00085FFFCCFD4
:103FA0008091C00085FFFCCF9093C6000895A8952E :103FA0009093C60008958091C00087FFFCCF809158
:103FB0008091C00087FFFCCF8091C6000895F7DF95 :103FB000C00084FD01C0A8958091C6000895E0E688
:103FC000F6DF80930202F3CFE0E6F0E098E1908321 :103FC000F0E098E1908380830895EDDF803219F06E
:103FD0008083089580E0F8DFEE27FF270994E7DF6C :103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B :103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
:0A3FF0001150E9F7F4DF1F91089566 :043FF000FF2709940A
:023FFE000404B9
:0400000300003E00BB :0400000300003E00BB
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_lilypad.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
3e00: 84 b7 in r24, 0x34 ; 52 3e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
3e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
3e02: 14 be out 0x34, r1 ; 52 3e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
3e04: 81 ff sbrs r24, 1 3e06: 81 ff sbrs r24, 1
3e06: e6 d0 rcall .+460 ; 0x3fd4 <appStart> 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
3e08: 85 e0 ldi r24, 0x05 ; 5 3e0a: 85 e0 ldi r24, 0x05 ; 5
3e0a: 80 93 81 00 sts 0x0081, r24 3e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
3e0e: 82 e0 ldi r24, 0x02 ; 2 3e10: 82 e0 ldi r24, 0x02 ; 2
3e10: 80 93 c0 00 sts 0x00C0, r24 3e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
3e14: 88 e1 ldi r24, 0x18 ; 24 3e16: 88 e1 ldi r24, 0x18 ; 24
3e16: 80 93 c1 00 sts 0x00C1, r24 3e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
3e1a: 86 e0 ldi r24, 0x06 ; 6 3e1c: 86 e0 ldi r24, 0x06 ; 6
3e1c: 80 93 c2 00 sts 0x00C2, r24 3e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
3e20: 88 e0 ldi r24, 0x08 ; 8 3e22: 88 e0 ldi r24, 0x08 ; 8
3e22: 80 93 c4 00 sts 0x00C4, r24 3e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
3e26: 8e e0 ldi r24, 0x0E ; 14 3e28: 8e e0 ldi r24, 0x0E ; 14
3e28: cf d0 rcall .+414 ; 0x3fc8 <watchdogConfig> 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
3e2a: 25 9a sbi 0x04, 5 ; 4 3e2c: 25 9a sbi 0x04, 5 ; 4
3e2c: 86 e0 ldi r24, 0x06 ; 6 3e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e2e: 28 e1 ldi r18, 0x18 ; 24 3e30: 28 e1 ldi r18, 0x18 ; 24
3e30: 3e ef ldi r19, 0xFE ; 254 3e32: 3e ef ldi r19, 0xFE ; 254
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e32: 91 e0 ldi r25, 0x01 ; 1 3e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e34: 30 93 85 00 sts 0x0085, r19 3e36: 30 93 85 00 sts 0x0085, r19
3e38: 20 93 84 00 sts 0x0084, r18 3e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e3c: 96 bb out 0x16, r25 ; 22 3e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
3e3e: b0 9b sbis 0x16, 0 ; 22 3e40: b0 9b sbis 0x16, 0 ; 22
3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
3e42: 1d 9a sbi 0x03, 5 ; 3 3e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
3e44: a8 95 wdr 3e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
3e46: 81 50 subi r24, 0x01 ; 1 3e48: 81 50 subi r24, 0x01 ; 1
3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36>
/* get character from UART */ 3e4c: cc 24 eor r12, r12
ch = getch(); 3e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
3e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
3e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3e50: 88 24 eor r8, r8
3e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3e4e: a5 e0 ldi r26, 0x05 ; 5 3e54: b5 e0 ldi r27, 0x05 ; 5
3e50: ea 2e mov r14, r26 3e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3e52: f1 e1 ldi r31, 0x11 ; 17 3e58: a1 e1 ldi r26, 0x11 ; 17
3e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
3e56: ab d0 rcall .+342 ; 0x3fae <getch> 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
3e58: 81 34 cpi r24, 0x41 ; 65 3e62: 81 34 cpi r24, 0x41 ; 65
3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch>
3e5c: 81 e0 ldi r24, 0x01 ; 1 3e68: 08 2f mov r16, r24
3e5e: c5 d0 rcall .+394 ; 0x3fea <getNch> verifySpace();
putch(0x03); 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace>
3e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
3e62: 20 c0 rjmp .+64 ; 0x3ea4 <main+0xa4> 3e6c: 02 38 cpi r16, 0x82 ; 130
3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74>
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
3e70: 01 38 cpi r16, 0x81 ; 129
3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78>
putch(OPTIBOOT_MAJVER);
3e74: 84 e0 ldi r24, 0x04 ; 4
3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
3e78: 83 e0 ldi r24, 0x03 ; 3
3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch>
3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
3e64: 82 34 cpi r24, 0x42 ; 66 3e7e: 82 34 cpi r24, 0x42 ; 66
3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
3e68: 84 e1 ldi r24, 0x14 ; 20 3e82: 84 e1 ldi r24, 0x14 ; 20
3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
3e6c: 85 34 cpi r24, 0x45 ; 69 3e86: 85 34 cpi r24, 0x45 ; 69
3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
3e70: 85 e0 ldi r24, 0x05 ; 5 3e8a: 85 e0 ldi r24, 0x05 ; 5
3e72: bb d0 rcall .+374 ; 0x3fea <getNch> 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch>
3e74: 91 c0 rjmp .+290 ; 0x3f98 <main+0x198> 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
3e76: 85 35 cpi r24, 0x55 ; 85 3e90: 85 35 cpi r24, 0x55 ; 85
3e78: 81 f4 brne .+32 ; 0x3e9a <main+0x9a> 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
3e7a: 99 d0 rcall .+306 ; 0x3fae <getch> 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
3e7c: 08 2f mov r16, r24 3e96: e8 2e mov r14, r24
3e7e: 10 e0 ldi r17, 0x00 ; 0 3e98: ff 24 eor r15, r15
3e80: 96 d0 rcall .+300 ; 0x3fae <getch> 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch>
3e82: 90 e0 ldi r25, 0x00 ; 0 3e9c: 08 2f mov r16, r24
3e84: 98 2f mov r25, r24 3e9e: 10 e0 ldi r17, 0x00 ; 0
3e86: 88 27 eor r24, r24 3ea0: 10 2f mov r17, r16
3e88: 80 2b or r24, r16 3ea2: 00 27 eor r16, r16
3e8a: 91 2b or r25, r17 3ea4: 0e 29 or r16, r14
3ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
3e8c: 88 0f add r24, r24 3ea8: 00 0f add r16, r16
3e8e: 99 1f adc r25, r25 3eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
3e90: 90 93 01 02 sts 0x0201, r25
3e94: 80 93 00 02 sts 0x0200, r24
3e98: 7e c0 rjmp .+252 ; 0x3f96 <main+0x196>
verifySpace(); verifySpace();
3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace>
3eae: 68 01 movw r12, r16
3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
3e9a: 86 35 cpi r24, 0x56 ; 86 3eb2: 86 35 cpi r24, 0x56 ; 86
3e9c: 29 f4 brne .+10 ; 0x3ea8 <main+0xa8> 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
3e9e: 84 e0 ldi r24, 0x04 ; 4 3eb6: 84 e0 ldi r24, 0x04 ; 4
3ea0: a4 d0 rcall .+328 ; 0x3fea <getNch> 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch>
putch(0x00); putch(0x00);
3ea2: 80 e0 ldi r24, 0x00 ; 0 3eba: 80 e0 ldi r24, 0x00 ; 0
3ea4: 7c d0 rcall .+248 ; 0x3f9e <putch> 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a>
3ea6: 78 c0 rjmp .+240 ; 0x3f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
3ea8: 84 36 cpi r24, 0x64 ; 100 3ebe: 84 36 cpi r24, 0x64 ; 100
3eaa: 09 f0 breq .+2 ; 0x3eae <main+0xae> 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4>
3eac: 4e c0 rjmp .+156 ; 0x3f4a <main+0x14a> 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
3eae: 87 d0 rcall .+270 ; 0x3fbe <getLen> 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch>
length = getch();
3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch>
3ec8: 08 2f mov r16, r24
getch();
3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3eb0: e0 91 00 02 lds r30, 0x0200 3ecc: 80 e0 ldi r24, 0x00 ; 0
3eb4: f0 91 01 02 lds r31, 0x0201 3ece: c8 16 cp r12, r24
3eb8: 88 e3 ldi r24, 0x38 ; 56 3ed0: 88 e3 ldi r24, 0x38 ; 56
3eba: e0 30 cpi r30, 0x00 ; 0 3ed2: d8 06 cpc r13, r24
3ebc: f8 07 cpc r31, r24 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc>
3ebe: 18 f4 brcc .+6 ; 0x3ec6 <main+0xc6> 3ed6: f6 01 movw r30, r12
3ec0: 83 e0 ldi r24, 0x03 ; 3 3ed8: b7 be out 0x37, r11 ; 55
3ec2: 87 bf out 0x37, r24 ; 55 3eda: e8 95 spm
3ec4: e8 95 spm 3edc: c0 e0 ldi r28, 0x00 ; 0
3ec6: c0 e0 ldi r28, 0x00 ; 0 3ede: d1 e0 ldi r29, 0x01 ; 1
3ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
3eca: 71 d0 rcall .+226 ; 0x3fae <getch> 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch>
3ecc: 89 93 st Y+, r24 3ee2: 89 93 st Y+, r24
while (--length); while (--length);
3ece: 80 91 02 02 lds r24, 0x0202 3ee4: 0c 17 cp r16, r28
3ed2: 81 50 subi r24, 0x01 ; 1 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0>
3ed4: 80 93 02 02 sts 0x0202, r24
3ed8: 88 23 and r24, r24
3eda: b9 f7 brne .-18 ; 0x3eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3edc: e0 91 00 02 lds r30, 0x0200 3ee8: f0 e0 ldi r31, 0x00 ; 0
3ee0: f0 91 01 02 lds r31, 0x0201 3eea: cf 16 cp r12, r31
3ee4: 88 e3 ldi r24, 0x38 ; 56 3eec: f8 e3 ldi r31, 0x38 ; 56
3ee6: e0 30 cpi r30, 0x00 ; 0 3eee: df 06 cpc r13, r31
3ee8: f8 07 cpc r31, r24 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8>
3eea: 18 f0 brcs .+6 ; 0x3ef2 <main+0xf2> 3ef2: f6 01 movw r30, r12
3eec: 83 e0 ldi r24, 0x03 ; 3 3ef4: b7 be out 0x37, r11 ; 55
3eee: 87 bf out 0x37, r24 ; 55 3ef6: e8 95 spm
3ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
3ef2: 75 d0 rcall .+234 ; 0x3fde <verifySpace> 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
3ef4: 07 b6 in r0, 0x37 ; 55 3efa: 07 b6 in r0, 0x37 ; 55
3ef6: 00 fc sbrc r0, 0 3efc: 00 fc sbrc r0, 0
3ef8: fd cf rjmp .-6 ; 0x3ef4 <main+0xf4> 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa>
} 3f00: a6 01 movw r20, r12
#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
3f02: a0 e0 ldi r26, 0x00 ; 0 3f02: a0 e0 ldi r26, 0x00 ; 0
3f04: b1 e0 ldi r27, 0x01 ; 1 3f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3f1c: fa 01 movw r30, r20 3f1c: fa 01 movw r30, r20
3f1e: 0c 01 movw r0, r24 3f1e: 0c 01 movw r0, r24
3f20: d7 be out 0x37, r13 ; 55 3f20: 87 be out 0x37, r8 ; 55
3f22: e8 95 spm 3f22: e8 95 spm
3f24: 11 24 eor r1, r1 3f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
3f2c: a0 38 cpi r26, 0x80 ; 128 3f2c: a0 38 cpi r26, 0x80 ; 128
3f2e: bf 07 cpc r27, r31 3f2e: bf 07 cpc r27, r31
3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3f32: e0 91 00 02 lds r30, 0x0200 3f32: f6 01 movw r30, r12
3f36: f0 91 01 02 lds r31, 0x0201 3f34: a7 be out 0x37, r10 ; 55
3f3a: e7 be out 0x37, r14 ; 55 3f36: e8 95 spm
3f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
3f3e: 07 b6 in r0, 0x37 ; 55 3f38: 07 b6 in r0, 0x37 ; 55
3f40: 00 fc sbrc r0, 0 3f3a: 00 fc sbrc r0, 0
3f42: fd cf rjmp .-6 ; 0x3f3e <main+0x13e> 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3f44: f7 be out 0x37, r15 ; 55 3f3e: 97 be out 0x37, r9 ; 55
3f46: e8 95 spm 3f40: e8 95 spm
3f48: 27 c0 rjmp .+78 ; 0x3f98 <main+0x198> 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
3f4a: 84 37 cpi r24, 0x74 ; 116 3f44: 84 37 cpi r24, 0x74 ; 116
3f4c: b9 f4 brne .+46 ; 0x3f7c <main+0x17c> 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
3f4e: 37 d0 rcall .+110 ; 0x3fbe <getLen> 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch>
length = getch();
3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch>
3f4c: f8 2e mov r15, r24
getch();
3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch>
verifySpace(); verifySpace();
3f50: 46 d0 rcall .+140 ; 0x3fde <verifySpace> 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace>
3f52: f6 01 movw r30, r12
3f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
3f52: e0 91 00 02 lds r30, 0x0200 3f56: 8f 01 movw r16, r30
3f56: f0 91 01 02 lds r31, 0x0201 3f58: 0f 5f subi r16, 0xFF ; 255
3f5a: 31 96 adiw r30, 0x01 ; 1 3f5a: 1f 4f sbci r17, 0xFF ; 255
3f5c: f0 93 01 02 sts 0x0201, r31 3f5c: 84 91 lpm r24, Z+
3f60: e0 93 00 02 sts 0x0200, r30 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch>
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 <putch>
while (--length); while (--length);
3f6c: 80 91 02 02 lds r24, 0x0202 3f60: ea 94 dec r14
3f70: 81 50 subi r24, 0x01 ; 1 3f62: f8 01 movw r30, r16
3f72: 80 93 02 02 sts 0x0202, r24 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156>
3f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
3f78: 61 f7 brne .-40 ; 0x3f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
3f7a: 0e c0 rjmp .+28 ; 0x3f98 <main+0x198> #endif
/* main program starts here */
int main(void) {
3f66: 08 94 sec
3f68: c1 1c adc r12, r1
3f6a: d1 1c adc r13, r1
3f6c: fa 94 dec r15
3f6e: cf 0c add r12, r15
3f70: d1 1c adc r13, r1
3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
3f7c: 85 37 cpi r24, 0x75 ; 117 3f74: 85 37 cpi r24, 0x75 ; 117
3f7e: 39 f4 brne .+14 ; 0x3f8e <main+0x18e> 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
3f80: 2e d0 rcall .+92 ; 0x3fde <verifySpace> 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
3f82: 8e e1 ldi r24, 0x1E ; 30 3f7a: 8e e1 ldi r24, 0x1E ; 30
3f84: 0c d0 rcall .+24 ; 0x3f9e <putch> 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
3f86: 84 e9 ldi r24, 0x94 ; 148 3f7e: 84 e9 ldi r24, 0x94 ; 148
3f88: 0a d0 rcall .+20 ; 0x3f9e <putch> 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
3f8a: 86 e0 ldi r24, 0x06 ; 6 3f82: 86 e0 ldi r24, 0x06 ; 6
3f8c: 8b cf rjmp .-234 ; 0x3ea4 <main+0xa4> 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
3f8e: 81 35 cpi r24, 0x51 ; 81 3f86: 81 35 cpi r24, 0x51 ; 81
3f90: 11 f4 brne .+4 ; 0x3f96 <main+0x196> 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
3f92: 88 e0 ldi r24, 0x08 ; 8 3f8a: 88 e0 ldi r24, 0x08 ; 8
3f94: 19 d0 rcall .+50 ; 0x3fc8 <watchdogConfig> 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
3f96: 23 d0 rcall .+70 ; 0x3fde <verifySpace> 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
3f98: 80 e1 ldi r24, 0x10 ; 16 3f90: 80 e1 ldi r24, 0x10 ; 16
3f9a: 01 d0 rcall .+2 ; 0x3f9e <putch> 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch>
3f9c: 5c cf rjmp .-328 ; 0x3e56 <main+0x56> 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60>
00003f9e <putch>: 00003f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
3f9e: 98 2f mov r25, r24 3f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
3fa0: 80 91 c0 00 lds r24, 0x00C0 3f98: 80 91 c0 00 lds r24, 0x00C0
3fa4: 85 ff sbrs r24, 5 3f9c: 85 ff sbrs r24, 5
3fa6: fc cf rjmp .-8 ; 0x3fa0 <putch+0x2> 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
3fa8: 90 93 c6 00 sts 0x00C6, r25 3fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
3fac: 08 95 ret 3fa4: 08 95 ret
00003fae <getch>: 00003fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
3fb0: 80 91 c0 00 lds r24, 0x00C0 3fa6: 80 91 c0 00 lds r24, 0x00C0
3fb4: 87 ff sbrs r24, 7 3faa: 87 ff sbrs r24, 7
3fb6: fc cf rjmp .-8 ; 0x3fb0 <getch+0x2> 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
3fae: 80 91 c0 00 lds r24, 0x00C0
3fb2: 84 fd sbrc r24, 4
3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fb6: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0; ch = UDR0;
3fb8: 80 91 c6 00 lds r24, 0x00C6 3fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
3fbc: 08 95 ret 3fbc: 08 95 ret
00003fbe <getLen>: 00003fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
3fbe: f7 df rcall .-18 ; 0x3fae <getch>
length = getch();
3fc0: f6 df rcall .-20 ; 0x3fae <getch>
3fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
3fc6: f3 cf rjmp .-26 ; 0x3fae <getch>
00003fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
3fc8: e0 e6 ldi r30, 0x60 ; 96 3fbe: e0 e6 ldi r30, 0x60 ; 96
3fca: f0 e0 ldi r31, 0x00 ; 0 3fc0: f0 e0 ldi r31, 0x00 ; 0
3fcc: 98 e1 ldi r25, 0x18 ; 24 3fc2: 98 e1 ldi r25, 0x18 ; 24
3fce: 90 83 st Z, r25 3fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
3fd0: 80 83 st Z, r24 3fc6: 80 83 st Z, r24
} }
3fd2: 08 95 ret 3fc8: 08 95 ret
00003fd4 <appStart>: 00003fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fd4: 80 e0 ldi r24, 0x00 ; 0
3fd6: f8 df rcall .-16 ; 0x3fc8 <watchdogConfig>
__asm__ __volatile__ (
3fd8: ee 27 eor r30, r30
3fda: ff 27 eor r31, r31
3fdc: 09 94 ijmp
00003fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
3fde: e7 df rcall .-50 ; 0x3fae <getch> 3fca: ed df rcall .-38 ; 0x3fa6 <getch>
3fe0: 80 32 cpi r24, 0x20 ; 32 3fcc: 80 32 cpi r24, 0x20 ; 32
3fe2: 09 f0 breq .+2 ; 0x3fe6 <verifySpace+0x8> 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc>
3fe4: f7 df rcall .-18 ; 0x3fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
3fd0: 88 e0 ldi r24, 0x08 ; 8
3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig>
3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
3fe6: 84 e1 ldi r24, 0x14 ; 20 3fd6: 84 e1 ldi r24, 0x14 ; 20
} }
3fe8: da cf rjmp .-76 ; 0x3f9e <putch> 3fd8: de cf rjmp .-68 ; 0x3f96 <putch>
00003fea <getNch>: 00003fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
3fea: 1f 93 push r17 3fda: 1f 93 push r17
3fec: 18 2f mov r17, r24 3fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
3fee: df df rcall .-66 ; 0x3fae <getch> 3fde: e3 df rcall .-58 ; 0x3fa6 <getch>
3ff0: 11 50 subi r17, 0x01 ; 1 3fe0: 11 50 subi r17, 0x01 ; 1
3ff2: e9 f7 brne .-6 ; 0x3fee <getNch+0x4> 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4>
verifySpace(); verifySpace();
3ff4: f4 df rcall .-24 ; 0x3fde <verifySpace> 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace>
} }
3ff6: 1f 91 pop r17 3fe6: 1f 91 pop r17
3ff8: 08 95 ret 3fe8: 08 95 ret
00003fea <appStart>:
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fea: 80 e0 ldi r24, 0x00 ; 0
3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig>
__asm__ __volatile__ (
3fee: ee 27 eor r30, r30
3ff0: ff 27 eor r31, r31
3ff2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:103E000084B714BE81FFE6D085E08093810082E014 :103E0000112484B714BE81FFF0D085E08093810037
:103E10008093C00088E18093C10086E08093C20057 :103E100082E08093C00088E18093C10086E08093B7
:103E200088E08093C4008EE0CFD0259A86E028E118 :103E2000C20088E08093C4008EE0C9D0259A86E065
:103E30003EEF91E0309385002093840096BBB09BC9 :103E300028E13EEF91E0309385002093840096BB0B
:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 :103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 :103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
:103E600083E020C0823411F484E103C0853419F466 :103E6000A2D0813461F49FD0082FAFD0023811F076
:103E700085E0BBD091C0853581F499D0082F10E042 :103E7000013811F484E001C083E08DD089C0823420
:103E800096D090E0982F8827802B912B880F991F30 :103E800011F484E103C0853419F485E0A6D080C024
:103E900090930102809300027EC0863529F484E06D :103E9000853579F488D0E82EFF2485D0082F10E0EE
:103EA000A4D080E07CD078C0843609F04EC087D0A2 :103EA000102F00270E291F29000F111F8ED0680127
:103EB000E0910002F091010288E3E030F80718F485 :103EB0006FC0863521F484E090D080E0DECF843678
:103EC00083E087BFE895C0E0D1E071D0899380910D :103EC00009F040C070D06FD0082F6DD080E0C816C8
:103ED00002028150809302028823B9F7E091000228 :103ED00088E3D80618F4F601B7BEE895C0E0D1E053
:103EE000F091010288E3E030F80718F083E087BF23 :103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
:103EF000E89575D007B600FCFDCF409100025091C7 :103EF00018F0F601B7BEE89568D007B600FCFDCF14
:103F00000102A0E0B1E02C9130E011968C91119764 :103F0000A601A0E0B1E02C9130E011968C911197C0
:103F100090E0982F8827822B932B1296FA010C01A0 :103F100090E0982F8827822B932B1296FA010C01A0
:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 :103F200087BEE89511244E5F5F4FF1E0A038BF07D0
:103F300051F7E0910002F0910102E7BEE89507B663 :103F300051F7F601A7BEE89507B600FCFDCF97BE86
:103F400000FCFDCFF7BEE89527C08437B9F437D021 :103F4000E89526C08437B1F42ED02DD0F82E2BD092
:103F500046D0E0910002F09101023196F093010207 :103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
:103F6000E09300023197E4918E2F19D080910202E4 :103F6000EA94F801C1F70894C11CD11CFA94CF0C53
:103F7000815080930202882361F70EC0853739F49F :103F7000D11C0EC0853739F428D08EE10CD084E9ED
:103F80002ED08EE10CD084E90AD086E08BCF81352B :103F80000AD086E07ACF813511F488E018D01DD0B0
:103F900011F488E019D023D080E101D05CCF982FB4 :103F900080E101D065CF982F8091C00085FFFCCFD4
:103FA0008091C00085FFFCCF9093C6000895A8952E :103FA0009093C60008958091C00087FFFCCF809158
:103FB0008091C00087FFFCCF8091C6000895F7DF95 :103FB000C00084FD01C0A8958091C6000895E0E688
:103FC000F6DF80930202F3CFE0E6F0E098E1908321 :103FC000F0E098E1908380830895EDDF803219F06E
:103FD0008083089580E0F8DFEE27FF270994E7DF6C :103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B :103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
:0A3FF0001150E9F7F4DF1F91089566 :043FF000FF2709940A
:023FFE000404B9
:0400000300003E00BB :0400000300003E00BB
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_lilypad_resonator.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
3e00: 84 b7 in r24, 0x34 ; 52 3e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
3e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
3e02: 14 be out 0x34, r1 ; 52 3e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
3e04: 81 ff sbrs r24, 1 3e06: 81 ff sbrs r24, 1
3e06: e6 d0 rcall .+460 ; 0x3fd4 <appStart> 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
3e08: 85 e0 ldi r24, 0x05 ; 5 3e0a: 85 e0 ldi r24, 0x05 ; 5
3e0a: 80 93 81 00 sts 0x0081, r24 3e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
3e0e: 82 e0 ldi r24, 0x02 ; 2 3e10: 82 e0 ldi r24, 0x02 ; 2
3e10: 80 93 c0 00 sts 0x00C0, r24 3e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
3e14: 88 e1 ldi r24, 0x18 ; 24 3e16: 88 e1 ldi r24, 0x18 ; 24
3e16: 80 93 c1 00 sts 0x00C1, r24 3e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
3e1a: 86 e0 ldi r24, 0x06 ; 6 3e1c: 86 e0 ldi r24, 0x06 ; 6
3e1c: 80 93 c2 00 sts 0x00C2, r24 3e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
3e20: 88 e0 ldi r24, 0x08 ; 8 3e22: 88 e0 ldi r24, 0x08 ; 8
3e22: 80 93 c4 00 sts 0x00C4, r24 3e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
3e26: 8e e0 ldi r24, 0x0E ; 14 3e28: 8e e0 ldi r24, 0x0E ; 14
3e28: cf d0 rcall .+414 ; 0x3fc8 <watchdogConfig> 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
3e2a: 25 9a sbi 0x04, 5 ; 4 3e2c: 25 9a sbi 0x04, 5 ; 4
3e2c: 86 e0 ldi r24, 0x06 ; 6 3e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e2e: 28 e1 ldi r18, 0x18 ; 24 3e30: 28 e1 ldi r18, 0x18 ; 24
3e30: 3e ef ldi r19, 0xFE ; 254 3e32: 3e ef ldi r19, 0xFE ; 254
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e32: 91 e0 ldi r25, 0x01 ; 1 3e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e34: 30 93 85 00 sts 0x0085, r19 3e36: 30 93 85 00 sts 0x0085, r19
3e38: 20 93 84 00 sts 0x0084, r18 3e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e3c: 96 bb out 0x16, r25 ; 22 3e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
3e3e: b0 9b sbis 0x16, 0 ; 22 3e40: b0 9b sbis 0x16, 0 ; 22
3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
3e42: 1d 9a sbi 0x03, 5 ; 3 3e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
3e44: a8 95 wdr 3e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
3e46: 81 50 subi r24, 0x01 ; 1 3e48: 81 50 subi r24, 0x01 ; 1
3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36>
/* get character from UART */ 3e4c: cc 24 eor r12, r12
ch = getch(); 3e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
3e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
3e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3e50: 88 24 eor r8, r8
3e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3e4e: a5 e0 ldi r26, 0x05 ; 5 3e54: b5 e0 ldi r27, 0x05 ; 5
3e50: ea 2e mov r14, r26 3e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3e52: f1 e1 ldi r31, 0x11 ; 17 3e58: a1 e1 ldi r26, 0x11 ; 17
3e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
3e56: ab d0 rcall .+342 ; 0x3fae <getch> 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
3e58: 81 34 cpi r24, 0x41 ; 65 3e62: 81 34 cpi r24, 0x41 ; 65
3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch>
3e5c: 81 e0 ldi r24, 0x01 ; 1 3e68: 08 2f mov r16, r24
3e5e: c5 d0 rcall .+394 ; 0x3fea <getNch> verifySpace();
putch(0x03); 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace>
3e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
3e62: 20 c0 rjmp .+64 ; 0x3ea4 <main+0xa4> 3e6c: 02 38 cpi r16, 0x82 ; 130
3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74>
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
3e70: 01 38 cpi r16, 0x81 ; 129
3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78>
putch(OPTIBOOT_MAJVER);
3e74: 84 e0 ldi r24, 0x04 ; 4
3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
3e78: 83 e0 ldi r24, 0x03 ; 3
3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch>
3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
3e64: 82 34 cpi r24, 0x42 ; 66 3e7e: 82 34 cpi r24, 0x42 ; 66
3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
3e68: 84 e1 ldi r24, 0x14 ; 20 3e82: 84 e1 ldi r24, 0x14 ; 20
3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
3e6c: 85 34 cpi r24, 0x45 ; 69 3e86: 85 34 cpi r24, 0x45 ; 69
3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
3e70: 85 e0 ldi r24, 0x05 ; 5 3e8a: 85 e0 ldi r24, 0x05 ; 5
3e72: bb d0 rcall .+374 ; 0x3fea <getNch> 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch>
3e74: 91 c0 rjmp .+290 ; 0x3f98 <main+0x198> 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
3e76: 85 35 cpi r24, 0x55 ; 85 3e90: 85 35 cpi r24, 0x55 ; 85
3e78: 81 f4 brne .+32 ; 0x3e9a <main+0x9a> 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
3e7a: 99 d0 rcall .+306 ; 0x3fae <getch> 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
3e7c: 08 2f mov r16, r24 3e96: e8 2e mov r14, r24
3e7e: 10 e0 ldi r17, 0x00 ; 0 3e98: ff 24 eor r15, r15
3e80: 96 d0 rcall .+300 ; 0x3fae <getch> 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch>
3e82: 90 e0 ldi r25, 0x00 ; 0 3e9c: 08 2f mov r16, r24
3e84: 98 2f mov r25, r24 3e9e: 10 e0 ldi r17, 0x00 ; 0
3e86: 88 27 eor r24, r24 3ea0: 10 2f mov r17, r16
3e88: 80 2b or r24, r16 3ea2: 00 27 eor r16, r16
3e8a: 91 2b or r25, r17 3ea4: 0e 29 or r16, r14
3ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
3e8c: 88 0f add r24, r24 3ea8: 00 0f add r16, r16
3e8e: 99 1f adc r25, r25 3eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
3e90: 90 93 01 02 sts 0x0201, r25
3e94: 80 93 00 02 sts 0x0200, r24
3e98: 7e c0 rjmp .+252 ; 0x3f96 <main+0x196>
verifySpace(); verifySpace();
3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace>
3eae: 68 01 movw r12, r16
3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
3e9a: 86 35 cpi r24, 0x56 ; 86 3eb2: 86 35 cpi r24, 0x56 ; 86
3e9c: 29 f4 brne .+10 ; 0x3ea8 <main+0xa8> 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
3e9e: 84 e0 ldi r24, 0x04 ; 4 3eb6: 84 e0 ldi r24, 0x04 ; 4
3ea0: a4 d0 rcall .+328 ; 0x3fea <getNch> 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch>
putch(0x00); putch(0x00);
3ea2: 80 e0 ldi r24, 0x00 ; 0 3eba: 80 e0 ldi r24, 0x00 ; 0
3ea4: 7c d0 rcall .+248 ; 0x3f9e <putch> 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a>
3ea6: 78 c0 rjmp .+240 ; 0x3f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
3ea8: 84 36 cpi r24, 0x64 ; 100 3ebe: 84 36 cpi r24, 0x64 ; 100
3eaa: 09 f0 breq .+2 ; 0x3eae <main+0xae> 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4>
3eac: 4e c0 rjmp .+156 ; 0x3f4a <main+0x14a> 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
3eae: 87 d0 rcall .+270 ; 0x3fbe <getLen> 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch>
length = getch();
3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch>
3ec8: 08 2f mov r16, r24
getch();
3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3eb0: e0 91 00 02 lds r30, 0x0200 3ecc: 80 e0 ldi r24, 0x00 ; 0
3eb4: f0 91 01 02 lds r31, 0x0201 3ece: c8 16 cp r12, r24
3eb8: 88 e3 ldi r24, 0x38 ; 56 3ed0: 88 e3 ldi r24, 0x38 ; 56
3eba: e0 30 cpi r30, 0x00 ; 0 3ed2: d8 06 cpc r13, r24
3ebc: f8 07 cpc r31, r24 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc>
3ebe: 18 f4 brcc .+6 ; 0x3ec6 <main+0xc6> 3ed6: f6 01 movw r30, r12
3ec0: 83 e0 ldi r24, 0x03 ; 3 3ed8: b7 be out 0x37, r11 ; 55
3ec2: 87 bf out 0x37, r24 ; 55 3eda: e8 95 spm
3ec4: e8 95 spm 3edc: c0 e0 ldi r28, 0x00 ; 0
3ec6: c0 e0 ldi r28, 0x00 ; 0 3ede: d1 e0 ldi r29, 0x01 ; 1
3ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
3eca: 71 d0 rcall .+226 ; 0x3fae <getch> 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch>
3ecc: 89 93 st Y+, r24 3ee2: 89 93 st Y+, r24
while (--length); while (--length);
3ece: 80 91 02 02 lds r24, 0x0202 3ee4: 0c 17 cp r16, r28
3ed2: 81 50 subi r24, 0x01 ; 1 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0>
3ed4: 80 93 02 02 sts 0x0202, r24
3ed8: 88 23 and r24, r24
3eda: b9 f7 brne .-18 ; 0x3eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3edc: e0 91 00 02 lds r30, 0x0200 3ee8: f0 e0 ldi r31, 0x00 ; 0
3ee0: f0 91 01 02 lds r31, 0x0201 3eea: cf 16 cp r12, r31
3ee4: 88 e3 ldi r24, 0x38 ; 56 3eec: f8 e3 ldi r31, 0x38 ; 56
3ee6: e0 30 cpi r30, 0x00 ; 0 3eee: df 06 cpc r13, r31
3ee8: f8 07 cpc r31, r24 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8>
3eea: 18 f0 brcs .+6 ; 0x3ef2 <main+0xf2> 3ef2: f6 01 movw r30, r12
3eec: 83 e0 ldi r24, 0x03 ; 3 3ef4: b7 be out 0x37, r11 ; 55
3eee: 87 bf out 0x37, r24 ; 55 3ef6: e8 95 spm
3ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
3ef2: 75 d0 rcall .+234 ; 0x3fde <verifySpace> 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
3ef4: 07 b6 in r0, 0x37 ; 55 3efa: 07 b6 in r0, 0x37 ; 55
3ef6: 00 fc sbrc r0, 0 3efc: 00 fc sbrc r0, 0
3ef8: fd cf rjmp .-6 ; 0x3ef4 <main+0xf4> 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa>
} 3f00: a6 01 movw r20, r12
#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
3f02: a0 e0 ldi r26, 0x00 ; 0 3f02: a0 e0 ldi r26, 0x00 ; 0
3f04: b1 e0 ldi r27, 0x01 ; 1 3f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3f1c: fa 01 movw r30, r20 3f1c: fa 01 movw r30, r20
3f1e: 0c 01 movw r0, r24 3f1e: 0c 01 movw r0, r24
3f20: d7 be out 0x37, r13 ; 55 3f20: 87 be out 0x37, r8 ; 55
3f22: e8 95 spm 3f22: e8 95 spm
3f24: 11 24 eor r1, r1 3f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
3f2c: a0 38 cpi r26, 0x80 ; 128 3f2c: a0 38 cpi r26, 0x80 ; 128
3f2e: bf 07 cpc r27, r31 3f2e: bf 07 cpc r27, r31
3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3f32: e0 91 00 02 lds r30, 0x0200 3f32: f6 01 movw r30, r12
3f36: f0 91 01 02 lds r31, 0x0201 3f34: a7 be out 0x37, r10 ; 55
3f3a: e7 be out 0x37, r14 ; 55 3f36: e8 95 spm
3f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
3f3e: 07 b6 in r0, 0x37 ; 55 3f38: 07 b6 in r0, 0x37 ; 55
3f40: 00 fc sbrc r0, 0 3f3a: 00 fc sbrc r0, 0
3f42: fd cf rjmp .-6 ; 0x3f3e <main+0x13e> 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3f44: f7 be out 0x37, r15 ; 55 3f3e: 97 be out 0x37, r9 ; 55
3f46: e8 95 spm 3f40: e8 95 spm
3f48: 27 c0 rjmp .+78 ; 0x3f98 <main+0x198> 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
3f4a: 84 37 cpi r24, 0x74 ; 116 3f44: 84 37 cpi r24, 0x74 ; 116
3f4c: b9 f4 brne .+46 ; 0x3f7c <main+0x17c> 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
3f4e: 37 d0 rcall .+110 ; 0x3fbe <getLen> 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch>
length = getch();
3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch>
3f4c: f8 2e mov r15, r24
getch();
3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch>
verifySpace(); verifySpace();
3f50: 46 d0 rcall .+140 ; 0x3fde <verifySpace> 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace>
3f52: f6 01 movw r30, r12
3f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
3f52: e0 91 00 02 lds r30, 0x0200 3f56: 8f 01 movw r16, r30
3f56: f0 91 01 02 lds r31, 0x0201 3f58: 0f 5f subi r16, 0xFF ; 255
3f5a: 31 96 adiw r30, 0x01 ; 1 3f5a: 1f 4f sbci r17, 0xFF ; 255
3f5c: f0 93 01 02 sts 0x0201, r31 3f5c: 84 91 lpm r24, Z+
3f60: e0 93 00 02 sts 0x0200, r30 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch>
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 <putch>
while (--length); while (--length);
3f6c: 80 91 02 02 lds r24, 0x0202 3f60: ea 94 dec r14
3f70: 81 50 subi r24, 0x01 ; 1 3f62: f8 01 movw r30, r16
3f72: 80 93 02 02 sts 0x0202, r24 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156>
3f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
3f78: 61 f7 brne .-40 ; 0x3f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
3f7a: 0e c0 rjmp .+28 ; 0x3f98 <main+0x198> #endif
/* main program starts here */
int main(void) {
3f66: 08 94 sec
3f68: c1 1c adc r12, r1
3f6a: d1 1c adc r13, r1
3f6c: fa 94 dec r15
3f6e: cf 0c add r12, r15
3f70: d1 1c adc r13, r1
3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
3f7c: 85 37 cpi r24, 0x75 ; 117 3f74: 85 37 cpi r24, 0x75 ; 117
3f7e: 39 f4 brne .+14 ; 0x3f8e <main+0x18e> 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
3f80: 2e d0 rcall .+92 ; 0x3fde <verifySpace> 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
3f82: 8e e1 ldi r24, 0x1E ; 30 3f7a: 8e e1 ldi r24, 0x1E ; 30
3f84: 0c d0 rcall .+24 ; 0x3f9e <putch> 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
3f86: 84 e9 ldi r24, 0x94 ; 148 3f7e: 84 e9 ldi r24, 0x94 ; 148
3f88: 0a d0 rcall .+20 ; 0x3f9e <putch> 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
3f8a: 86 e0 ldi r24, 0x06 ; 6 3f82: 86 e0 ldi r24, 0x06 ; 6
3f8c: 8b cf rjmp .-234 ; 0x3ea4 <main+0xa4> 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
3f8e: 81 35 cpi r24, 0x51 ; 81 3f86: 81 35 cpi r24, 0x51 ; 81
3f90: 11 f4 brne .+4 ; 0x3f96 <main+0x196> 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
3f92: 88 e0 ldi r24, 0x08 ; 8 3f8a: 88 e0 ldi r24, 0x08 ; 8
3f94: 19 d0 rcall .+50 ; 0x3fc8 <watchdogConfig> 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
3f96: 23 d0 rcall .+70 ; 0x3fde <verifySpace> 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
3f98: 80 e1 ldi r24, 0x10 ; 16 3f90: 80 e1 ldi r24, 0x10 ; 16
3f9a: 01 d0 rcall .+2 ; 0x3f9e <putch> 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch>
3f9c: 5c cf rjmp .-328 ; 0x3e56 <main+0x56> 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60>
00003f9e <putch>: 00003f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
3f9e: 98 2f mov r25, r24 3f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
3fa0: 80 91 c0 00 lds r24, 0x00C0 3f98: 80 91 c0 00 lds r24, 0x00C0
3fa4: 85 ff sbrs r24, 5 3f9c: 85 ff sbrs r24, 5
3fa6: fc cf rjmp .-8 ; 0x3fa0 <putch+0x2> 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
3fa8: 90 93 c6 00 sts 0x00C6, r25 3fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
3fac: 08 95 ret 3fa4: 08 95 ret
00003fae <getch>: 00003fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
3fb0: 80 91 c0 00 lds r24, 0x00C0 3fa6: 80 91 c0 00 lds r24, 0x00C0
3fb4: 87 ff sbrs r24, 7 3faa: 87 ff sbrs r24, 7
3fb6: fc cf rjmp .-8 ; 0x3fb0 <getch+0x2> 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
3fae: 80 91 c0 00 lds r24, 0x00C0
3fb2: 84 fd sbrc r24, 4
3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fb6: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0; ch = UDR0;
3fb8: 80 91 c6 00 lds r24, 0x00C6 3fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
3fbc: 08 95 ret 3fbc: 08 95 ret
00003fbe <getLen>: 00003fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
3fbe: f7 df rcall .-18 ; 0x3fae <getch>
length = getch();
3fc0: f6 df rcall .-20 ; 0x3fae <getch>
3fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
3fc6: f3 cf rjmp .-26 ; 0x3fae <getch>
00003fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
3fc8: e0 e6 ldi r30, 0x60 ; 96 3fbe: e0 e6 ldi r30, 0x60 ; 96
3fca: f0 e0 ldi r31, 0x00 ; 0 3fc0: f0 e0 ldi r31, 0x00 ; 0
3fcc: 98 e1 ldi r25, 0x18 ; 24 3fc2: 98 e1 ldi r25, 0x18 ; 24
3fce: 90 83 st Z, r25 3fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
3fd0: 80 83 st Z, r24 3fc6: 80 83 st Z, r24
} }
3fd2: 08 95 ret 3fc8: 08 95 ret
00003fd4 <appStart>: 00003fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fd4: 80 e0 ldi r24, 0x00 ; 0
3fd6: f8 df rcall .-16 ; 0x3fc8 <watchdogConfig>
__asm__ __volatile__ (
3fd8: ee 27 eor r30, r30
3fda: ff 27 eor r31, r31
3fdc: 09 94 ijmp
00003fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
3fde: e7 df rcall .-50 ; 0x3fae <getch> 3fca: ed df rcall .-38 ; 0x3fa6 <getch>
3fe0: 80 32 cpi r24, 0x20 ; 32 3fcc: 80 32 cpi r24, 0x20 ; 32
3fe2: 09 f0 breq .+2 ; 0x3fe6 <verifySpace+0x8> 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc>
3fe4: f7 df rcall .-18 ; 0x3fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
3fd0: 88 e0 ldi r24, 0x08 ; 8
3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig>
3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
3fe6: 84 e1 ldi r24, 0x14 ; 20 3fd6: 84 e1 ldi r24, 0x14 ; 20
} }
3fe8: da cf rjmp .-76 ; 0x3f9e <putch> 3fd8: de cf rjmp .-68 ; 0x3f96 <putch>
00003fea <getNch>: 00003fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
3fea: 1f 93 push r17 3fda: 1f 93 push r17
3fec: 18 2f mov r17, r24 3fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
3fee: df df rcall .-66 ; 0x3fae <getch> 3fde: e3 df rcall .-58 ; 0x3fa6 <getch>
3ff0: 11 50 subi r17, 0x01 ; 1 3fe0: 11 50 subi r17, 0x01 ; 1
3ff2: e9 f7 brne .-6 ; 0x3fee <getNch+0x4> 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4>
verifySpace(); verifySpace();
3ff4: f4 df rcall .-24 ; 0x3fde <verifySpace> 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace>
} }
3ff6: 1f 91 pop r17 3fe6: 1f 91 pop r17
3ff8: 08 95 ret 3fe8: 08 95 ret
00003fea <appStart>:
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fea: 80 e0 ldi r24, 0x00 ; 0
3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig>
__asm__ __volatile__ (
3fee: ee 27 eor r30, r30
3ff0: ff 27 eor r31, r31
3ff2: 09 94 ijmp

View File

@@ -1,42 +1,41 @@
:101D000084B714BE81FF22D185E08EBD8EE01AD14A :101D0000112484B714BE81FF24D185E08EBD8EE0FE
:101D1000D49AD29A86E023EC3FEF91E03DBD2CBDF2 :101D10000CD1D49AD29A86E023EC3FEF91E03DBDFE
:101D20009BB9589BFECFCC9AA8958150B9F7DD247A :101D20002CBD9BB9589BFECFCC9AA8958150B9F792
:101D3000D39485E0C82E0FE7F02E1EECE12EE9D0FB :101D3000EE24FF2493E0992EBB24B39485E0A82ED3
:101D4000813421F481E00DD183E020C0823411F48C :101D40000FE7D02E1EECC12EDDD0813461F4DAD045
:101D500084E103C0853419F485E003D1C8C085351A :101D5000082FEFD0023811F0013811F484E001C0EF
:101D600081F4D7D0082F10E0D4D090E0982F8827A6 :101D600083E0C1D0BDC0823411F484E103C0853466
:101D7000802B912B880F991F909381018093800174 :101D700019F485E0E6D0B4C0853579F4C3D0E82EF7
:101D8000B5C0863529F484E0ECD080E0B3D0AFC094 :101D8000FF24C0D0082F10E0102F00270E291F2994
:101D9000843609F06BC0D1D0C0E0D1E0BAD08993CD :101D9000000F111FCED07801A3C0863521F484E056
:101DA000809182018150809382018823B9F7E0916C :101DA000D0D080E0DECF843609F05FC0ABD0AAD0BF
:101DB0008001F091810183E087BFE895CCD007B620 :101DB000182FA8D0C0E0D1E0A5D089931C17E1F777
:101DC00000FCFDCF8091800190918101892B41F52C :101DC000F70197BEE895B5D007B600FCFDCFE1144A
:101DD000809100012091010130E0322F222790E014 :101DD000F10411F0A7012AC08091000120910101B6
:101DE000282B392B309385012093840140910801E1 :101DE00030E0322F222790E0282B392B30938501C9
:101DF0008091090190E0982F882750E0842B952B43 :101DF00020938401409108018091090190E0982F7F
:101E000090938701809386012450304020930801ED :101E0000882750E0842B952B90938701809386013F
:101E1000232F332720930901F0920001E092010162 :101E10002450304020930801232F332720930901B9
:101E20004091800150918101A0E0B1E02C9130E01F :101E2000D0920001C092010140E050E0A0E0B1E09A
:101E300011968C91119790E0982F8827822B932BE5 :101E30002C9130E011968C91119790E0982F882783
:101E40001296FA010C01D7BEE89511244E5F5F4F40 :101E4000822B932B1296FA010C01B7BEE895112450
:101E5000F1E0A034BF0751F7E0918001F0918101DA :101E50004E5F5F4FF1E0A034BF0751F7F701A7BE17
:101E6000C7BEE89507B600FCFDCF41C0843789F5B1 :101E6000E89507B600FCFDCF3BC0843759F54AD052
:101E700064D071D0E0918001F0918101309719F424 :101E700049D0182F47D05DD0E701012F209719F4E2
:101E80002091840113C0E130F10519F420918501FE :101E80008091840114C0C130D10519F4809185017D
:101E90000DC0E830F10519F42091860107C0E93042 :101E90000EC0C830D10519F48091860108C0C93040
:101EA000F10519F42091870101C0249180918001EE :101EA000D10519F48091870102C0FE018491219629
:101EB0009091810101969093810180938001822FFE :101EB0001AD0015019F70894E11CF11C1150E10EE1
:101EC00019D080918201815080938201882391F6FC :101EC000F11C0EC0853739F434D08EE10CD083E993
:101ED0000EC0853739F43FD08EE10CD083E90AD0AB :101ED0000AD08CE046CF813511F488E026D029D095
:101EE0008CE054CF813511F488E02CD034D080E1DF :101EE00080E101D031CF2AE030E08095089410F4F1
:101EF00001D025CF2AE030E08095089410F4DA98DC :101EF000DA9802C0DA9A000014D013D086952A9599
:101F000002C0DA9A000015D014D086952A95B1F750 :101F0000B1F7089529E030E0CB99FECF0AD009D08F
:101F10000895A89529E030E0CB99FECF0AD009D0EA :101F100008D08894CB9908942A9511F08795F7CF2B
:101F200008D08894CB9908942A9511F08795F7CF1B :101F200008959EE09A95F1F7089598E191BD81BDDD
:101F300008959EE09A95F1F70895EBDFEADF80932C :101F30000895E8DF803219F088E0F7DFFFCF84E111
:101F40008201E7CF98E191BD81BD089580E0FADF7D :101F4000D2CF1F93182FDEDF1150E9F7F2DF1F9178
:101F5000E4E0FF270994DDDF803209F0F7DF84E158 :0C1F5000089580E0EADFE4E0FF27099438
:101F6000C9CF1F93182FD5DF1150E9F7F4DF1F9168 :021EFE000404DA
:021F70000895D2
:0400000300001D00DC :0400000300001D00DC
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_luminet.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 00000078 00000000 00000000 000002ee 2**0 3 .debug_pubnames 0000006d 00000000 00000000 000002da 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 000002a4 00000000 00000000 00000366 2**0 4 .debug_info 000002bc 00000000 00000000 00000347 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ac 00000000 00000000 0000060a 2**0 5 .debug_abbrev 00000176 00000000 00000000 00000603 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 0000043d 00000000 00000000 000007b6 2**0 6 .debug_line 000004b0 00000000 00000000 00000779 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 000000a0 00000000 00000000 00000bf4 2**2 7 .debug_frame 00000090 00000000 00000000 00000c2c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000150 00000000 00000000 00000c94 2**0 8 .debug_str 00000152 00000000 00000000 00000cbc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 00000194 00000000 00000000 00000de4 2**0 9 .debug_loc 000002a1 00000000 00000000 00000e0e 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000088 00000000 00000000 00000f78 2**0 10 .debug_ranges 00000098 00000000 00000000 000010af 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,588 +35,614 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
1d00: 84 b7 in r24, 0x34 ; 52 1d00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
1d02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
1d02: 14 be out 0x34, r1 ; 52 1d04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
1d04: 81 ff sbrs r24, 1 1d06: 81 ff sbrs r24, 1
1d06: 22 d1 rcall .+580 ; 0x1f4c <appStart> 1d08: 24 d1 rcall .+584 ; 0x1f52 <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
1d08: 85 e0 ldi r24, 0x05 ; 5 1d0a: 85 e0 ldi r24, 0x05 ; 5
1d0a: 8e bd out 0x2e, r24 ; 46 1d0c: 8e bd out 0x2e, r24 ; 46
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
1d0c: 8e e0 ldi r24, 0x0E ; 14 1d0e: 8e e0 ldi r24, 0x0E ; 14
1d0e: 1a d1 rcall .+564 ; 0x1f44 <watchdogConfig> 1d10: 0c d1 rcall .+536 ; 0x1f2a <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
1d10: d4 9a sbi 0x1a, 4 ; 26 1d12: d4 9a sbi 0x1a, 4 ; 26
#ifdef SOFT_UART #ifdef SOFT_UART
/* Set TX pin as output */ /* Set TX pin as output */
UART_DDR |= _BV(UART_TX_BIT); UART_DDR |= _BV(UART_TX_BIT);
1d12: d2 9a sbi 0x1a, 2 ; 26 1d14: d2 9a sbi 0x1a, 2 ; 26
1d14: 86 e0 ldi r24, 0x06 ; 6 1d16: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
1d16: 23 ec ldi r18, 0xC3 ; 195 1d18: 23 ec ldi r18, 0xC3 ; 195
1d18: 3f ef ldi r19, 0xFF ; 255 1d1a: 3f ef ldi r19, 0xFF ; 255
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
1d1a: 91 e0 ldi r25, 0x01 ; 1 1d1c: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
1d1c: 3d bd out 0x2d, r19 ; 45 1d1e: 3d bd out 0x2d, r19 ; 45
1d1e: 2c bd out 0x2c, r18 ; 44 1d20: 2c bd out 0x2c, r18 ; 44
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
1d20: 9b b9 out 0x0b, r25 ; 11 1d22: 9b b9 out 0x0b, r25 ; 11
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
1d22: 58 9b sbis 0x0b, 0 ; 11 1d24: 58 9b sbis 0x0b, 0 ; 11
1d24: fe cf rjmp .-4 ; 0x1d22 <main+0x22> 1d26: fe cf rjmp .-4 ; 0x1d24 <main+0x24>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
1d26: cc 9a sbi 0x19, 4 ; 25 1d28: cc 9a sbi 0x19, 4 ; 25
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
1d28: a8 95 wdr 1d2a: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
1d2a: 81 50 subi r24, 0x01 ; 1 1d2c: 81 50 subi r24, 0x01 ; 1
1d2c: b9 f7 brne .-18 ; 0x1d1c <main+0x1c> 1d2e: b9 f7 brne .-18 ; 0x1d1e <main+0x1e>
/* get character from UART */ 1d30: ee 24 eor r14, r14
ch = getch(); 1d32: ff 24 eor r15, r15
do *bufPtr++ = getch();
while (--length);
if(ch == STK_GET_PARAMETER) { // If we are in NRWW section, page erase has to be delayed until now.
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy // Todo: Take RAMPZ into account
getNch(1); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
1d2e: dd 24 eor r13, r13 1d34: 93 e0 ldi r25, 0x03 ; 3
1d30: d3 94 inc r13 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); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
1d38: bb 24 eor r11, r11
1d3a: b3 94 inc r11
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
1d32: 85 e0 ldi r24, 0x05 ; 5 1d3c: 85 e0 ldi r24, 0x05 ; 5
1d34: c8 2e mov r12, r24 1d3e: a8 2e mov r10, r24
vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
buff[8] = vect & 0xff; buff[8] = vect & 0xff;
buff[9] = vect >> 8; buff[9] = vect >> 8;
// Add jump to bootloader at RESET vector // Add jump to bootloader at RESET vector
buff[0] = 0x7f; buff[0] = 0x7f;
1d36: 0f e7 ldi r16, 0x7F ; 127 1d40: 0f e7 ldi r16, 0x7F ; 127
1d38: f0 2e mov r15, r16 1d42: d0 2e mov r13, r16
buff[1] = 0xce; // rjmp 0x1d00 instruction buff[1] = 0xce; // rjmp 0x1d00 instruction
1d3a: 1e ec ldi r17, 0xCE ; 206 1d44: 1e ec ldi r17, 0xCE ; 206
1d3c: e1 2e mov r14, r17 1d46: c1 2e mov r12, r17
#endif #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
1d3e: e9 d0 rcall .+466 ; 0x1f12 <getch> 1d48: dd d0 rcall .+442 ; 0x1f04 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
1d40: 81 34 cpi r24, 0x41 ; 65 1d4a: 81 34 cpi r24, 0x41 ; 65
1d42: 21 f4 brne .+8 ; 0x1d4c <main+0x4c> 1d4c: 61 f4 brne .+24 ; 0x1d66 <main+0x66>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 1d4e: da d0 rcall .+436 ; 0x1f04 <getch>
1d44: 81 e0 ldi r24, 0x01 ; 1 1d50: 08 2f mov r16, r24
1d46: 0d d1 rcall .+538 ; 0x1f62 <getNch> verifySpace();
putch(0x03); 1d52: ef d0 rcall .+478 ; 0x1f32 <verifySpace>
1d48: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
1d4a: 20 c0 rjmp .+64 ; 0x1d8c <main+0x8c> 1d54: 02 38 cpi r16, 0x82 ; 130
1d56: 11 f0 breq .+4 ; 0x1d5c <main+0x5c>
/*
* 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 <main+0x60>
putch(OPTIBOOT_MAJVER);
1d5c: 84 e0 ldi r24, 0x04 ; 4
1d5e: 01 c0 rjmp .+2 ; 0x1d62 <main+0x62>
} 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 <putch>
1d64: bd c0 rjmp .+378 ; 0x1ee0 <main+0x1e0>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
1d4c: 82 34 cpi r24, 0x42 ; 66 1d66: 82 34 cpi r24, 0x42 ; 66
1d4e: 11 f4 brne .+4 ; 0x1d54 <main+0x54> 1d68: 11 f4 brne .+4 ; 0x1d6e <main+0x6e>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
1d50: 84 e1 ldi r24, 0x14 ; 20 1d6a: 84 e1 ldi r24, 0x14 ; 20
1d52: 03 c0 rjmp .+6 ; 0x1d5a <main+0x5a> 1d6c: 03 c0 rjmp .+6 ; 0x1d74 <main+0x74>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
1d54: 85 34 cpi r24, 0x45 ; 69 1d6e: 85 34 cpi r24, 0x45 ; 69
1d56: 19 f4 brne .+6 ; 0x1d5e <main+0x5e> 1d70: 19 f4 brne .+6 ; 0x1d78 <main+0x78>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
1d58: 85 e0 ldi r24, 0x05 ; 5 1d72: 85 e0 ldi r24, 0x05 ; 5
1d5a: 03 d1 rcall .+518 ; 0x1f62 <getNch> 1d74: e6 d0 rcall .+460 ; 0x1f42 <getNch>
1d5c: c8 c0 rjmp .+400 ; 0x1eee <main+0x1ee> 1d76: b4 c0 rjmp .+360 ; 0x1ee0 <main+0x1e0>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
1d5e: 85 35 cpi r24, 0x55 ; 85 1d78: 85 35 cpi r24, 0x55 ; 85
1d60: 81 f4 brne .+32 ; 0x1d82 <main+0x82> 1d7a: 79 f4 brne .+30 ; 0x1d9a <main+0x9a>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
1d62: d7 d0 rcall .+430 ; 0x1f12 <getch> 1d7c: c3 d0 rcall .+390 ; 0x1f04 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
1d64: 08 2f mov r16, r24 1d7e: e8 2e mov r14, r24
1d66: 10 e0 ldi r17, 0x00 ; 0 1d80: ff 24 eor r15, r15
1d68: d4 d0 rcall .+424 ; 0x1f12 <getch> 1d82: c0 d0 rcall .+384 ; 0x1f04 <getch>
1d6a: 90 e0 ldi r25, 0x00 ; 0 1d84: 08 2f mov r16, r24
1d6c: 98 2f mov r25, r24 1d86: 10 e0 ldi r17, 0x00 ; 0
1d6e: 88 27 eor r24, r24 1d88: 10 2f mov r17, r16
1d70: 80 2b or r24, r16 1d8a: 00 27 eor r16, r16
1d72: 91 2b or r25, r17 1d8c: 0e 29 or r16, r14
1d8e: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
1d74: 88 0f add r24, r24 1d90: 00 0f add r16, r16
1d76: 99 1f adc r25, r25 1d92: 11 1f adc r17, r17
address = newAddress; address = newAddress;
1d78: 90 93 81 01 sts 0x0181, r25
1d7c: 80 93 80 01 sts 0x0180, r24
1d80: b5 c0 rjmp .+362 ; 0x1eec <main+0x1ec>
verifySpace(); verifySpace();
1d94: ce d0 rcall .+412 ; 0x1f32 <verifySpace>
1d96: 78 01 movw r14, r16
1d98: a3 c0 rjmp .+326 ; 0x1ee0 <main+0x1e0>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
1d82: 86 35 cpi r24, 0x56 ; 86 1d9a: 86 35 cpi r24, 0x56 ; 86
1d84: 29 f4 brne .+10 ; 0x1d90 <main+0x90> 1d9c: 21 f4 brne .+8 ; 0x1da6 <main+0xa6>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
1d86: 84 e0 ldi r24, 0x04 ; 4 1d9e: 84 e0 ldi r24, 0x04 ; 4
1d88: ec d0 rcall .+472 ; 0x1f62 <getNch> 1da0: d0 d0 rcall .+416 ; 0x1f42 <getNch>
putch(0x00); putch(0x00);
1d8a: 80 e0 ldi r24, 0x00 ; 0 1da2: 80 e0 ldi r24, 0x00 ; 0
1d8c: b3 d0 rcall .+358 ; 0x1ef4 <putch> 1da4: de cf rjmp .-68 ; 0x1d62 <main+0x62>
1d8e: af c0 rjmp .+350 ; 0x1eee <main+0x1ee>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
1d90: 84 36 cpi r24, 0x64 ; 100 1da6: 84 36 cpi r24, 0x64 ; 100
1d92: 09 f0 breq .+2 ; 0x1d96 <main+0x96> 1da8: 09 f0 breq .+2 ; 0x1dac <main+0xac>
1d94: 6b c0 rjmp .+214 ; 0x1e6c <main+0x16c> 1daa: 5f c0 rjmp .+190 ; 0x1e6a <main+0x16a>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
1d96: d1 d0 rcall .+418 ; 0x1f3a <getLen> 1dac: ab d0 rcall .+342 ; 0x1f04 <getch>
1d98: c0 e0 ldi r28, 0x00 ; 0 length = getch();
1d9a: d1 e0 ldi r29, 0x01 ; 1 1dae: aa d0 rcall .+340 ; 0x1f04 <getch>
1db0: 18 2f mov r17, r24
getch();
1db2: a8 d0 rcall .+336 ; 0x1f04 <getch>
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 we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
1d9c: ba d0 rcall .+372 ; 0x1f12 <getch> 1db8: a5 d0 rcall .+330 ; 0x1f04 <getch>
1d9e: 89 93 st Y+, r24 1dba: 89 93 st Y+, r24
while (--length); while (--length);
1da0: 80 91 82 01 lds r24, 0x0182 1dbc: 1c 17 cp r17, r28
1da4: 81 50 subi r24, 0x01 ; 1 1dbe: e1 f7 brne .-8 ; 0x1db8 <main+0xb8>
1da6: 80 93 82 01 sts 0x0182, r24
1daa: 88 23 and r24, r24
1dac: b9 f7 brne .-18 ; 0x1d9c <main+0x9c>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
1dae: e0 91 80 01 lds r30, 0x0180 1dc0: f7 01 movw r30, r14
1db2: f0 91 81 01 lds r31, 0x0181 1dc2: 97 be out 0x37, r9 ; 55
1db6: 83 e0 ldi r24, 0x03 ; 3 1dc4: e8 95 spm
1db8: 87 bf out 0x37, r24 ; 55
1dba: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
1dbc: cc d0 rcall .+408 ; 0x1f56 <verifySpace> 1dc6: b5 d0 rcall .+362 ; 0x1f32 <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
1dbe: 07 b6 in r0, 0x37 ; 55 1dc8: 07 b6 in r0, 0x37 ; 55
1dc0: 00 fc sbrc r0, 0 1dca: 00 fc sbrc r0, 0
1dc2: fd cf rjmp .-6 ; 0x1dbe <main+0xbe> 1dcc: fd cf rjmp .-6 ; 0x1dc8 <main+0xc8>
#ifdef VIRTUAL_BOOT_PARTITION #ifdef VIRTUAL_BOOT_PARTITION
if ((uint16_t)(void*)address == 0) { if ((uint16_t)(void*)address == 0) {
1dc4: 80 91 80 01 lds r24, 0x0180 1dce: e1 14 cp r14, r1
1dc8: 90 91 81 01 lds r25, 0x0181 1dd0: f1 04 cpc r15, r1
1dcc: 89 2b or r24, r25 1dd2: 11 f0 breq .+4 ; 0x1dd8 <main+0xd8>
1dce: 41 f5 brne .+80 ; 0x1e20 <main+0x120> 1dd4: a7 01 movw r20, r14
1dd6: 2a c0 rjmp .+84 ; 0x1e2c <main+0x12c>
// This is the reset vector page. We need to live-patch the code so the // This is the reset vector page. We need to live-patch the code so the
// bootloader runs. // bootloader runs.
// //
// Move RESET vector to WDT vector // Move RESET vector to WDT vector
uint16_t vect = buff[0] | (buff[1]<<8); uint16_t vect = buff[0] | (buff[1]<<8);
1dd0: 80 91 00 01 lds r24, 0x0100 1dd8: 80 91 00 01 lds r24, 0x0100
1dd4: 20 91 01 01 lds r18, 0x0101 1ddc: 20 91 01 01 lds r18, 0x0101
1dd8: 30 e0 ldi r19, 0x00 ; 0 1de0: 30 e0 ldi r19, 0x00 ; 0
1dda: 32 2f mov r19, r18 1de2: 32 2f mov r19, r18
1ddc: 22 27 eor r18, r18 1de4: 22 27 eor r18, r18
1dde: 90 e0 ldi r25, 0x00 ; 0 1de6: 90 e0 ldi r25, 0x00 ; 0
1de0: 28 2b or r18, r24 1de8: 28 2b or r18, r24
1de2: 39 2b or r19, r25 1dea: 39 2b or r19, r25
rstVect = vect; rstVect = vect;
1de4: 30 93 85 01 sts 0x0185, r19 1dec: 30 93 85 01 sts 0x0185, r19
1de8: 20 93 84 01 sts 0x0184, r18 1df0: 20 93 84 01 sts 0x0184, r18
wdtVect = buff[8] | (buff[9]<<8); wdtVect = buff[8] | (buff[9]<<8);
1dec: 40 91 08 01 lds r20, 0x0108 1df4: 40 91 08 01 lds r20, 0x0108
1df0: 80 91 09 01 lds r24, 0x0109 1df8: 80 91 09 01 lds r24, 0x0109
1df4: 90 e0 ldi r25, 0x00 ; 0 1dfc: 90 e0 ldi r25, 0x00 ; 0
1df6: 98 2f mov r25, r24 1dfe: 98 2f mov r25, r24
1df8: 88 27 eor r24, r24 1e00: 88 27 eor r24, r24
1dfa: 50 e0 ldi r21, 0x00 ; 0 1e02: 50 e0 ldi r21, 0x00 ; 0
1dfc: 84 2b or r24, r20 1e04: 84 2b or r24, r20
1dfe: 95 2b or r25, r21 1e06: 95 2b or r25, r21
1e00: 90 93 87 01 sts 0x0187, r25 1e08: 90 93 87 01 sts 0x0187, r25
1e04: 80 93 86 01 sts 0x0186, r24 1e0c: 80 93 86 01 sts 0x0186, r24
vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
1e08: 24 50 subi r18, 0x04 ; 4 1e10: 24 50 subi r18, 0x04 ; 4
1e0a: 30 40 sbci r19, 0x00 ; 0 1e12: 30 40 sbci r19, 0x00 ; 0
buff[8] = vect & 0xff; buff[8] = vect & 0xff;
1e0c: 20 93 08 01 sts 0x0108, r18 1e14: 20 93 08 01 sts 0x0108, r18
buff[9] = vect >> 8; buff[9] = vect >> 8;
1e10: 23 2f mov r18, r19 1e18: 23 2f mov r18, r19
1e12: 33 27 eor r19, r19 1e1a: 33 27 eor r19, r19
1e14: 20 93 09 01 sts 0x0109, r18 1e1c: 20 93 09 01 sts 0x0109, r18
// Add jump to bootloader at RESET vector // Add jump to bootloader at RESET vector
buff[0] = 0x7f; 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 buff[1] = 0xce; // rjmp 0x1d00 instruction
1e1c: e0 92 01 01 sts 0x0101, r14 1e24: c0 92 01 01 sts 0x0101, r12
} 1e28: 40 e0 ldi r20, 0x00 ; 0
#endif 1e2a: 50 e0 ldi r21, 0x00 ; 0
1e2c: a0 e0 ldi r26, 0x00 ; 0
// Copy buffer into programming buffer 1e2e: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff; bufPtr = buff;
addrPtr = (uint16_t)(void*)address; 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; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
1e2c: 2c 91 ld r18, X 1e30: 2c 91 ld r18, X
1e2e: 30 e0 ldi r19, 0x00 ; 0 1e32: 30 e0 ldi r19, 0x00 ; 0
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
1e30: 11 96 adiw r26, 0x01 ; 1 1e34: 11 96 adiw r26, 0x01 ; 1
1e32: 8c 91 ld r24, X 1e36: 8c 91 ld r24, X
1e34: 11 97 sbiw r26, 0x01 ; 1 1e38: 11 97 sbiw r26, 0x01 ; 1
1e36: 90 e0 ldi r25, 0x00 ; 0 1e3a: 90 e0 ldi r25, 0x00 ; 0
1e38: 98 2f mov r25, r24 1e3c: 98 2f mov r25, r24
1e3a: 88 27 eor r24, r24 1e3e: 88 27 eor r24, r24
1e3c: 82 2b or r24, r18 1e40: 82 2b or r24, r18
1e3e: 93 2b or r25, r19 1e42: 93 2b or r25, r19
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
#endif #endif
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
1e40: 12 96 adiw r26, 0x02 ; 2 1e44: 12 96 adiw r26, 0x02 ; 2
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
a = *bufPtr++; a = *bufPtr++;
a |= (*bufPtr++) << 8; a |= (*bufPtr++) << 8;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
1e42: fa 01 movw r30, r20 1e46: fa 01 movw r30, r20
1e44: 0c 01 movw r0, r24 1e48: 0c 01 movw r0, r24
1e46: d7 be out 0x37, r13 ; 55 1e4a: b7 be out 0x37, r11 ; 55
1e48: e8 95 spm 1e4c: e8 95 spm
1e4a: 11 24 eor r1, r1 1e4e: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
1e4c: 4e 5f subi r20, 0xFE ; 254 1e50: 4e 5f subi r20, 0xFE ; 254
1e4e: 5f 4f sbci r21, 0xFF ; 255 1e52: 5f 4f sbci r21, 0xFF ; 255
} while (--ch); } while (--ch);
1e50: f1 e0 ldi r31, 0x01 ; 1 1e54: f1 e0 ldi r31, 0x01 ; 1
1e52: a0 34 cpi r26, 0x40 ; 64 1e56: a0 34 cpi r26, 0x40 ; 64
1e54: bf 07 cpc r27, r31 1e58: bf 07 cpc r27, r31
1e56: 51 f7 brne .-44 ; 0x1e2c <main+0x12c> 1e5a: 51 f7 brne .-44 ; 0x1e30 <main+0x130>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
1e58: e0 91 80 01 lds r30, 0x0180 1e5c: f7 01 movw r30, r14
1e5c: f0 91 81 01 lds r31, 0x0181 1e5e: a7 be out 0x37, r10 ; 55
1e60: c7 be out 0x37, r12 ; 55 1e60: e8 95 spm
1e62: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
1e64: 07 b6 in r0, 0x37 ; 55 1e62: 07 b6 in r0, 0x37 ; 55
1e66: 00 fc sbrc r0, 0 1e64: 00 fc sbrc r0, 0
1e68: fd cf rjmp .-6 ; 0x1e64 <main+0x164> 1e66: fd cf rjmp .-6 ; 0x1e62 <main+0x162>
1e6a: 41 c0 rjmp .+130 ; 0x1eee <main+0x1ee> 1e68: 3b c0 rjmp .+118 ; 0x1ee0 <main+0x1e0>
boot_rww_enable(); boot_rww_enable();
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
1e6c: 84 37 cpi r24, 0x74 ; 116 1e6a: 84 37 cpi r24, 0x74 ; 116
1e6e: 89 f5 brne .+98 ; 0x1ed2 <main+0x1d2> 1e6c: 59 f5 brne .+86 ; 0x1ec4 <main+0x1c4>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
1e70: 64 d0 rcall .+200 ; 0x1f3a <getLen> 1e6e: 4a d0 rcall .+148 ; 0x1f04 <getch>
length = getch();
1e70: 49 d0 rcall .+146 ; 0x1f04 <getch>
1e72: 18 2f mov r17, r24
getch();
1e74: 47 d0 rcall .+142 ; 0x1f04 <getch>
verifySpace(); verifySpace();
1e72: 71 d0 rcall .+226 ; 0x1f56 <verifySpace> 1e76: 5d d0 rcall .+186 ; 0x1f32 <verifySpace>
1e78: e7 01 movw r28, r14
1e7a: 01 2f mov r16, r17
#ifdef VIRTUAL_BOOT_PARTITION #ifdef VIRTUAL_BOOT_PARTITION
do { do {
// Undo vector patch in bottom page so verify passes // Undo vector patch in bottom page so verify passes
if (address == 0) ch=rstVect & 0xff; if (address == 0) ch=rstVect & 0xff;
1e74: e0 91 80 01 lds r30, 0x0180 1e7c: 20 97 sbiw r28, 0x00 ; 0
1e78: f0 91 81 01 lds r31, 0x0181
1e7c: 30 97 sbiw r30, 0x00 ; 0
1e7e: 19 f4 brne .+6 ; 0x1e86 <main+0x186> 1e7e: 19 f4 brne .+6 ; 0x1e86 <main+0x186>
1e80: 20 91 84 01 lds r18, 0x0184 1e80: 80 91 84 01 lds r24, 0x0184
1e84: 13 c0 rjmp .+38 ; 0x1eac <main+0x1ac> 1e84: 14 c0 rjmp .+40 ; 0x1eae <main+0x1ae>
else if (address == 1) ch=rstVect >> 8; else if (address == 1) ch=rstVect >> 8;
1e86: e1 30 cpi r30, 0x01 ; 1 1e86: c1 30 cpi r28, 0x01 ; 1
1e88: f1 05 cpc r31, r1 1e88: d1 05 cpc r29, r1
1e8a: 19 f4 brne .+6 ; 0x1e92 <main+0x192> 1e8a: 19 f4 brne .+6 ; 0x1e92 <main+0x192>
1e8c: 20 91 85 01 lds r18, 0x0185 1e8c: 80 91 85 01 lds r24, 0x0185
1e90: 0d c0 rjmp .+26 ; 0x1eac <main+0x1ac> 1e90: 0e c0 rjmp .+28 ; 0x1eae <main+0x1ae>
else if (address == 8) ch=wdtVect & 0xff; else if (address == 8) ch=wdtVect & 0xff;
1e92: e8 30 cpi r30, 0x08 ; 8 1e92: c8 30 cpi r28, 0x08 ; 8
1e94: f1 05 cpc r31, r1 1e94: d1 05 cpc r29, r1
1e96: 19 f4 brne .+6 ; 0x1e9e <main+0x19e> 1e96: 19 f4 brne .+6 ; 0x1e9e <main+0x19e>
1e98: 20 91 86 01 lds r18, 0x0186 1e98: 80 91 86 01 lds r24, 0x0186
1e9c: 07 c0 rjmp .+14 ; 0x1eac <main+0x1ac> 1e9c: 08 c0 rjmp .+16 ; 0x1eae <main+0x1ae>
else if (address == 9) ch=wdtVect >> 8; else if (address == 9) ch=wdtVect >> 8;
1e9e: e9 30 cpi r30, 0x09 ; 9 1e9e: c9 30 cpi r28, 0x09 ; 9
1ea0: f1 05 cpc r31, r1 1ea0: d1 05 cpc r29, r1
1ea2: 19 f4 brne .+6 ; 0x1eaa <main+0x1aa> 1ea2: 19 f4 brne .+6 ; 0x1eaa <main+0x1aa>
1ea4: 20 91 87 01 lds r18, 0x0187 1ea4: 80 91 87 01 lds r24, 0x0187
1ea8: 01 c0 rjmp .+2 ; 0x1eac <main+0x1ac> 1ea8: 02 c0 rjmp .+4 ; 0x1eae <main+0x1ae>
else ch = pgm_read_byte_near(address); 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++; address++;
1eac: 80 91 80 01 lds r24, 0x0180 1eae: 21 96 adiw r28, 0x01 ; 1
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
putch(ch); putch(ch);
1ebe: 82 2f mov r24, r18 1eb0: 1a d0 rcall .+52 ; 0x1ee6 <putch>
1ec0: 19 d0 rcall .+50 ; 0x1ef4 <putch>
} while (--length); } while (--length);
1ec2: 80 91 82 01 lds r24, 0x0182 1eb2: 01 50 subi r16, 0x01 ; 1
1ec6: 81 50 subi r24, 0x01 ; 1 1eb4: 19 f7 brne .-58 ; 0x1e7c <main+0x17c>
1ec8: 80 93 82 01 sts 0x0182, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
1ecc: 88 23 and r24, r24 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
1ece: 91 f6 brne .-92 ; 0x1e74 <main+0x174> #endif
1ed0: 0e c0 rjmp .+28 ; 0x1eee <main+0x1ee>
/* 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 <main+0x1e0>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
1ed2: 85 37 cpi r24, 0x75 ; 117 1ec4: 85 37 cpi r24, 0x75 ; 117
1ed4: 39 f4 brne .+14 ; 0x1ee4 <main+0x1e4> 1ec6: 39 f4 brne .+14 ; 0x1ed6 <main+0x1d6>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
1ed6: 3f d0 rcall .+126 ; 0x1f56 <verifySpace> 1ec8: 34 d0 rcall .+104 ; 0x1f32 <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
1ed8: 8e e1 ldi r24, 0x1E ; 30 1eca: 8e e1 ldi r24, 0x1E ; 30
1eda: 0c d0 rcall .+24 ; 0x1ef4 <putch> 1ecc: 0c d0 rcall .+24 ; 0x1ee6 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
1edc: 83 e9 ldi r24, 0x93 ; 147 1ece: 83 e9 ldi r24, 0x93 ; 147
1ede: 0a d0 rcall .+20 ; 0x1ef4 <putch> 1ed0: 0a d0 rcall .+20 ; 0x1ee6 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
1ee0: 8c e0 ldi r24, 0x0C ; 12 1ed2: 8c e0 ldi r24, 0x0C ; 12
1ee2: 54 cf rjmp .-344 ; 0x1d8c <main+0x8c> 1ed4: 46 cf rjmp .-372 ; 0x1d62 <main+0x62>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
1ee4: 81 35 cpi r24, 0x51 ; 81 1ed6: 81 35 cpi r24, 0x51 ; 81
1ee6: 11 f4 brne .+4 ; 0x1eec <main+0x1ec> 1ed8: 11 f4 brne .+4 ; 0x1ede <main+0x1de>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
1ee8: 88 e0 ldi r24, 0x08 ; 8 1eda: 88 e0 ldi r24, 0x08 ; 8
1eea: 2c d0 rcall .+88 ; 0x1f44 <watchdogConfig> 1edc: 26 d0 rcall .+76 ; 0x1f2a <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
1eec: 34 d0 rcall .+104 ; 0x1f56 <verifySpace> 1ede: 29 d0 rcall .+82 ; 0x1f32 <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
1eee: 80 e1 ldi r24, 0x10 ; 16 1ee0: 80 e1 ldi r24, 0x10 ; 16
1ef0: 01 d0 rcall .+2 ; 0x1ef4 <putch> 1ee2: 01 d0 rcall .+2 ; 0x1ee6 <putch>
1ef2: 25 cf rjmp .-438 ; 0x1d3e <main+0x3e> 1ee4: 31 cf rjmp .-414 ; 0x1d48 <main+0x48>
00001ef4 <putch>: 00001ee6 <putch>:
void putch(char ch) { void putch(char ch) {
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
UDR0 = ch; UDR0 = ch;
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
1ef4: 2a e0 ldi r18, 0x0A ; 10 1ee6: 2a e0 ldi r18, 0x0A ; 10
1ef6: 30 e0 ldi r19, 0x00 ; 0 1ee8: 30 e0 ldi r19, 0x00 ; 0
1ef8: 80 95 com r24 1eea: 80 95 com r24
1efa: 08 94 sec 1eec: 08 94 sec
1efc: 10 f4 brcc .+4 ; 0x1f02 <putch+0xe> 1eee: 10 f4 brcc .+4 ; 0x1ef4 <putch+0xe>
1efe: da 98 cbi 0x1b, 2 ; 27 1ef0: da 98 cbi 0x1b, 2 ; 27
1f00: 02 c0 rjmp .+4 ; 0x1f06 <putch+0x12> 1ef2: 02 c0 rjmp .+4 ; 0x1ef8 <putch+0x12>
1f02: da 9a sbi 0x1b, 2 ; 27 1ef4: da 9a sbi 0x1b, 2 ; 27
1f04: 00 00 nop 1ef6: 00 00 nop
1f06: 15 d0 rcall .+42 ; 0x1f32 <uartDelay> 1ef8: 14 d0 rcall .+40 ; 0x1f22 <uartDelay>
1f08: 14 d0 rcall .+40 ; 0x1f32 <uartDelay> 1efa: 13 d0 rcall .+38 ; 0x1f22 <uartDelay>
1f0a: 86 95 lsr r24 1efc: 86 95 lsr r24
1f0c: 2a 95 dec r18 1efe: 2a 95 dec r18
1f0e: b1 f7 brne .-20 ; 0x1efc <putch+0x8> 1f00: b1 f7 brne .-20 ; 0x1eee <putch+0x8>
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
1f10: 08 95 ret 1f02: 08 95 ret
00001f12 <getch>: 00001f04 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
1f12: a8 95 wdr
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
#endif #endif
return ch; return ch;
} }
1f14: 29 e0 ldi r18, 0x09 ; 9 1f04: 29 e0 ldi r18, 0x09 ; 9
1f16: 30 e0 ldi r19, 0x00 ; 0 1f06: 30 e0 ldi r19, 0x00 ; 0
1f18: cb 99 sbic 0x19, 3 ; 25 1f08: cb 99 sbic 0x19, 3 ; 25
1f1a: fe cf rjmp .-4 ; 0x1f18 <getch+0x6> 1f0a: fe cf rjmp .-4 ; 0x1f08 <getch+0x4>
1f1c: 0a d0 rcall .+20 ; 0x1f32 <uartDelay> 1f0c: 0a d0 rcall .+20 ; 0x1f22 <uartDelay>
1f1e: 09 d0 rcall .+18 ; 0x1f32 <uartDelay> 1f0e: 09 d0 rcall .+18 ; 0x1f22 <uartDelay>
1f20: 08 d0 rcall .+16 ; 0x1f32 <uartDelay> 1f10: 08 d0 rcall .+16 ; 0x1f22 <uartDelay>
1f22: 88 94 clc 1f12: 88 94 clc
1f24: cb 99 sbic 0x19, 3 ; 25 1f14: cb 99 sbic 0x19, 3 ; 25
1f26: 08 94 sec 1f16: 08 94 sec
1f28: 2a 95 dec r18 1f18: 2a 95 dec r18
1f2a: 11 f0 breq .+4 ; 0x1f30 <getch+0x1e> 1f1a: 11 f0 breq .+4 ; 0x1f20 <getch+0x1c>
1f2c: 87 95 ror r24 1f1c: 87 95 ror r24
1f2e: f7 cf rjmp .-18 ; 0x1f1e <getch+0xc> 1f1e: f7 cf rjmp .-18 ; 0x1f0e <getch+0xa>
1f30: 08 95 ret 1f20: 08 95 ret
00001f32 <uartDelay>: 00001f22 <uartDelay>:
#if UART_B_VALUE > 255 #if UART_B_VALUE > 255
#error Baud rate too slow for soft UART #error Baud rate too slow for soft UART
#endif #endif
void uartDelay() { void uartDelay() {
__asm__ __volatile__ ( __asm__ __volatile__ (
1f32: 9e e0 ldi r25, 0x0E ; 14 1f22: 9e e0 ldi r25, 0x0E ; 14
1f34: 9a 95 dec r25 1f24: 9a 95 dec r25
1f36: f1 f7 brne .-4 ; 0x1f34 <uartDelay+0x2> 1f26: f1 f7 brne .-4 ; 0x1f24 <uartDelay+0x2>
1f38: 08 95 ret 1f28: 08 95 ret
00001f3a <getLen>: 00001f2a <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
1f3a: eb df rcall .-42 ; 0x1f12 <getch>
length = getch();
1f3c: ea df rcall .-44 ; 0x1f12 <getch>
1f3e: 80 93 82 01 sts 0x0182, r24
return getch();
}
1f42: e7 cf rjmp .-50 ; 0x1f12 <getch>
00001f44 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
1f44: 98 e1 ldi r25, 0x18 ; 24 1f2a: 98 e1 ldi r25, 0x18 ; 24
1f46: 91 bd out 0x21, r25 ; 33 1f2c: 91 bd out 0x21, r25 ; 33
WDTCSR = x; 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 <appStart>: 00001f32 <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
1f4c: 80 e0 ldi r24, 0x00 ; 0
1f4e: fa df rcall .-12 ; 0x1f44 <watchdogConfig>
__asm__ __volatile__ (
1f50: e4 e0 ldi r30, 0x04 ; 4
1f52: ff 27 eor r31, r31
1f54: 09 94 ijmp
00001f56 <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
1f56: dd df rcall .-70 ; 0x1f12 <getch> 1f32: e8 df rcall .-48 ; 0x1f04 <getch>
1f58: 80 32 cpi r24, 0x20 ; 32 1f34: 80 32 cpi r24, 0x20 ; 32
1f5a: 09 f0 breq .+2 ; 0x1f5e <verifySpace+0x8> 1f36: 19 f0 breq .+6 ; 0x1f3e <verifySpace+0xc>
1f5c: f7 df rcall .-18 ; 0x1f4c <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
1f38: 88 e0 ldi r24, 0x08 ; 8
1f3a: f7 df rcall .-18 ; 0x1f2a <watchdogConfig>
1f3c: ff cf rjmp .-2 ; 0x1f3c <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
1f5e: 84 e1 ldi r24, 0x14 ; 20 1f3e: 84 e1 ldi r24, 0x14 ; 20
} }
1f60: c9 cf rjmp .-110 ; 0x1ef4 <putch> 1f40: d2 cf rjmp .-92 ; 0x1ee6 <putch>
00001f62 <getNch>: 00001f42 <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
1f62: 1f 93 push r17 1f42: 1f 93 push r17
1f64: 18 2f mov r17, r24 1f44: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
1f66: d5 df rcall .-86 ; 0x1f12 <getch> 1f46: de df rcall .-68 ; 0x1f04 <getch>
1f68: 11 50 subi r17, 0x01 ; 1 1f48: 11 50 subi r17, 0x01 ; 1
1f6a: e9 f7 brne .-6 ; 0x1f66 <getNch+0x4> 1f4a: e9 f7 brne .-6 ; 0x1f46 <getNch+0x4>
verifySpace(); verifySpace();
1f6c: f4 df rcall .-24 ; 0x1f56 <verifySpace> 1f4c: f2 df rcall .-28 ; 0x1f32 <verifySpace>
} }
1f6e: 1f 91 pop r17 1f4e: 1f 91 pop r17
1f70: 08 95 ret 1f50: 08 95 ret
00001f52 <appStart>:
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 <watchdogConfig>
__asm__ __volatile__ (
1f56: e4 e0 ldi r30, 0x04 ; 4
1f58: ff 27 eor r31, r31
1f5a: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:103E000084B714BE81FFE6D085E08093810082E014 :103E0000112484B714BE81FFF0D085E08093810037
:103E10008093C00088E18093C10086E08093C20057 :103E100082E08093C00088E18093C10086E08093B7
:103E200080E18093C4008EE0CFD0259A86E020E325 :103E2000C20080E18093C4008EE0C9D0259A86E06C
:103E30003CEF91E0309385002093840096BBB09BCB :103E300020E33CEF91E0309385002093840096BB13
:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 :103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 :103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
:103E600083E020C0823411F484E103C0853419F466 :103E6000A2D0813461F49FD0082FAFD0023811F076
:103E700085E0BBD091C0853581F499D0082F10E042 :103E7000013811F484E001C083E08DD089C0823420
:103E800096D090E0982F8827802B912B880F991F30 :103E800011F484E103C0853419F485E0A6D080C024
:103E900090930102809300027EC0863529F484E06D :103E9000853579F488D0E82EFF2485D0082F10E0EE
:103EA000A4D080E07CD078C0843609F04EC087D0A2 :103EA000102F00270E291F29000F111F8ED0680127
:103EB000E0910002F091010288E3E030F80718F485 :103EB0006FC0863521F484E090D080E0DECF843678
:103EC00083E087BFE895C0E0D1E071D0899380910D :103EC00009F040C070D06FD0082F6DD080E0C816C8
:103ED00002028150809302028823B9F7E091000228 :103ED00088E3D80618F4F601B7BEE895C0E0D1E053
:103EE000F091010288E3E030F80718F083E087BF23 :103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
:103EF000E89575D007B600FCFDCF409100025091C7 :103EF00018F0F601B7BEE89568D007B600FCFDCF14
:103F00000102A0E0B1E02C9130E011968C91119764 :103F0000A601A0E0B1E02C9130E011968C911197C0
:103F100090E0982F8827822B932B1296FA010C01A0 :103F100090E0982F8827822B932B1296FA010C01A0
:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 :103F200087BEE89511244E5F5F4FF1E0A038BF07D0
:103F300051F7E0910002F0910102E7BEE89507B663 :103F300051F7F601A7BEE89507B600FCFDCF97BE86
:103F400000FCFDCFF7BEE89527C08437B9F437D021 :103F4000E89526C08437B1F42ED02DD0F82E2BD092
:103F500046D0E0910002F09101023196F093010207 :103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
:103F6000E09300023197E4918E2F19D080910202E4 :103F6000EA94F801C1F70894C11CD11CFA94CF0C53
:103F7000815080930202882361F70EC0853739F49F :103F7000D11C0EC0853739F428D08EE10CD084E9ED
:103F80002ED08EE10CD084E90AD086E08BCF81352B :103F80000AD086E07ACF813511F488E018D01DD0B0
:103F900011F488E019D023D080E101D05CCF982FB4 :103F900080E101D065CF982F8091C00085FFFCCFD4
:103FA0008091C00085FFFCCF9093C6000895A8952E :103FA0009093C60008958091C00087FFFCCF809158
:103FB0008091C00087FFFCCF8091C6000895F7DF95 :103FB000C00084FD01C0A8958091C6000895E0E688
:103FC000F6DF80930202F3CFE0E6F0E098E1908321 :103FC000F0E098E1908380830895EDDF803219F06E
:103FD0008083089580E0F8DFEE27FF270994E7DF6C :103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B :103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
:0A3FF0001150E9F7F4DF1F91089566 :043FF000FF2709940A
:023FFE000404B9
:0400000300003E00BB :0400000300003E00BB
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_pro_16MHz.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
3e00: 84 b7 in r24, 0x34 ; 52 3e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
3e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
3e02: 14 be out 0x34, r1 ; 52 3e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
3e04: 81 ff sbrs r24, 1 3e06: 81 ff sbrs r24, 1
3e06: e6 d0 rcall .+460 ; 0x3fd4 <appStart> 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
3e08: 85 e0 ldi r24, 0x05 ; 5 3e0a: 85 e0 ldi r24, 0x05 ; 5
3e0a: 80 93 81 00 sts 0x0081, r24 3e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
3e0e: 82 e0 ldi r24, 0x02 ; 2 3e10: 82 e0 ldi r24, 0x02 ; 2
3e10: 80 93 c0 00 sts 0x00C0, r24 3e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
3e14: 88 e1 ldi r24, 0x18 ; 24 3e16: 88 e1 ldi r24, 0x18 ; 24
3e16: 80 93 c1 00 sts 0x00C1, r24 3e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
3e1a: 86 e0 ldi r24, 0x06 ; 6 3e1c: 86 e0 ldi r24, 0x06 ; 6
3e1c: 80 93 c2 00 sts 0x00C2, r24 3e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
3e20: 80 e1 ldi r24, 0x10 ; 16 3e22: 80 e1 ldi r24, 0x10 ; 16
3e22: 80 93 c4 00 sts 0x00C4, r24 3e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
3e26: 8e e0 ldi r24, 0x0E ; 14 3e28: 8e e0 ldi r24, 0x0E ; 14
3e28: cf d0 rcall .+414 ; 0x3fc8 <watchdogConfig> 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
3e2a: 25 9a sbi 0x04, 5 ; 4 3e2c: 25 9a sbi 0x04, 5 ; 4
3e2c: 86 e0 ldi r24, 0x06 ; 6 3e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e2e: 20 e3 ldi r18, 0x30 ; 48 3e30: 20 e3 ldi r18, 0x30 ; 48
3e30: 3c ef ldi r19, 0xFC ; 252 3e32: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e32: 91 e0 ldi r25, 0x01 ; 1 3e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e34: 30 93 85 00 sts 0x0085, r19 3e36: 30 93 85 00 sts 0x0085, r19
3e38: 20 93 84 00 sts 0x0084, r18 3e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e3c: 96 bb out 0x16, r25 ; 22 3e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
3e3e: b0 9b sbis 0x16, 0 ; 22 3e40: b0 9b sbis 0x16, 0 ; 22
3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
3e42: 1d 9a sbi 0x03, 5 ; 3 3e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
3e44: a8 95 wdr 3e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
3e46: 81 50 subi r24, 0x01 ; 1 3e48: 81 50 subi r24, 0x01 ; 1
3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36>
/* get character from UART */ 3e4c: cc 24 eor r12, r12
ch = getch(); 3e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
3e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
3e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3e50: 88 24 eor r8, r8
3e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3e4e: a5 e0 ldi r26, 0x05 ; 5 3e54: b5 e0 ldi r27, 0x05 ; 5
3e50: ea 2e mov r14, r26 3e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3e52: f1 e1 ldi r31, 0x11 ; 17 3e58: a1 e1 ldi r26, 0x11 ; 17
3e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
3e56: ab d0 rcall .+342 ; 0x3fae <getch> 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
3e58: 81 34 cpi r24, 0x41 ; 65 3e62: 81 34 cpi r24, 0x41 ; 65
3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch>
3e5c: 81 e0 ldi r24, 0x01 ; 1 3e68: 08 2f mov r16, r24
3e5e: c5 d0 rcall .+394 ; 0x3fea <getNch> verifySpace();
putch(0x03); 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace>
3e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
3e62: 20 c0 rjmp .+64 ; 0x3ea4 <main+0xa4> 3e6c: 02 38 cpi r16, 0x82 ; 130
3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74>
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
3e70: 01 38 cpi r16, 0x81 ; 129
3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78>
putch(OPTIBOOT_MAJVER);
3e74: 84 e0 ldi r24, 0x04 ; 4
3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
3e78: 83 e0 ldi r24, 0x03 ; 3
3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch>
3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
3e64: 82 34 cpi r24, 0x42 ; 66 3e7e: 82 34 cpi r24, 0x42 ; 66
3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
3e68: 84 e1 ldi r24, 0x14 ; 20 3e82: 84 e1 ldi r24, 0x14 ; 20
3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
3e6c: 85 34 cpi r24, 0x45 ; 69 3e86: 85 34 cpi r24, 0x45 ; 69
3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
3e70: 85 e0 ldi r24, 0x05 ; 5 3e8a: 85 e0 ldi r24, 0x05 ; 5
3e72: bb d0 rcall .+374 ; 0x3fea <getNch> 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch>
3e74: 91 c0 rjmp .+290 ; 0x3f98 <main+0x198> 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
3e76: 85 35 cpi r24, 0x55 ; 85 3e90: 85 35 cpi r24, 0x55 ; 85
3e78: 81 f4 brne .+32 ; 0x3e9a <main+0x9a> 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
3e7a: 99 d0 rcall .+306 ; 0x3fae <getch> 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
3e7c: 08 2f mov r16, r24 3e96: e8 2e mov r14, r24
3e7e: 10 e0 ldi r17, 0x00 ; 0 3e98: ff 24 eor r15, r15
3e80: 96 d0 rcall .+300 ; 0x3fae <getch> 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch>
3e82: 90 e0 ldi r25, 0x00 ; 0 3e9c: 08 2f mov r16, r24
3e84: 98 2f mov r25, r24 3e9e: 10 e0 ldi r17, 0x00 ; 0
3e86: 88 27 eor r24, r24 3ea0: 10 2f mov r17, r16
3e88: 80 2b or r24, r16 3ea2: 00 27 eor r16, r16
3e8a: 91 2b or r25, r17 3ea4: 0e 29 or r16, r14
3ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
3e8c: 88 0f add r24, r24 3ea8: 00 0f add r16, r16
3e8e: 99 1f adc r25, r25 3eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
3e90: 90 93 01 02 sts 0x0201, r25
3e94: 80 93 00 02 sts 0x0200, r24
3e98: 7e c0 rjmp .+252 ; 0x3f96 <main+0x196>
verifySpace(); verifySpace();
3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace>
3eae: 68 01 movw r12, r16
3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
3e9a: 86 35 cpi r24, 0x56 ; 86 3eb2: 86 35 cpi r24, 0x56 ; 86
3e9c: 29 f4 brne .+10 ; 0x3ea8 <main+0xa8> 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
3e9e: 84 e0 ldi r24, 0x04 ; 4 3eb6: 84 e0 ldi r24, 0x04 ; 4
3ea0: a4 d0 rcall .+328 ; 0x3fea <getNch> 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch>
putch(0x00); putch(0x00);
3ea2: 80 e0 ldi r24, 0x00 ; 0 3eba: 80 e0 ldi r24, 0x00 ; 0
3ea4: 7c d0 rcall .+248 ; 0x3f9e <putch> 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a>
3ea6: 78 c0 rjmp .+240 ; 0x3f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
3ea8: 84 36 cpi r24, 0x64 ; 100 3ebe: 84 36 cpi r24, 0x64 ; 100
3eaa: 09 f0 breq .+2 ; 0x3eae <main+0xae> 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4>
3eac: 4e c0 rjmp .+156 ; 0x3f4a <main+0x14a> 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
3eae: 87 d0 rcall .+270 ; 0x3fbe <getLen> 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch>
length = getch();
3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch>
3ec8: 08 2f mov r16, r24
getch();
3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3eb0: e0 91 00 02 lds r30, 0x0200 3ecc: 80 e0 ldi r24, 0x00 ; 0
3eb4: f0 91 01 02 lds r31, 0x0201 3ece: c8 16 cp r12, r24
3eb8: 88 e3 ldi r24, 0x38 ; 56 3ed0: 88 e3 ldi r24, 0x38 ; 56
3eba: e0 30 cpi r30, 0x00 ; 0 3ed2: d8 06 cpc r13, r24
3ebc: f8 07 cpc r31, r24 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc>
3ebe: 18 f4 brcc .+6 ; 0x3ec6 <main+0xc6> 3ed6: f6 01 movw r30, r12
3ec0: 83 e0 ldi r24, 0x03 ; 3 3ed8: b7 be out 0x37, r11 ; 55
3ec2: 87 bf out 0x37, r24 ; 55 3eda: e8 95 spm
3ec4: e8 95 spm 3edc: c0 e0 ldi r28, 0x00 ; 0
3ec6: c0 e0 ldi r28, 0x00 ; 0 3ede: d1 e0 ldi r29, 0x01 ; 1
3ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
3eca: 71 d0 rcall .+226 ; 0x3fae <getch> 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch>
3ecc: 89 93 st Y+, r24 3ee2: 89 93 st Y+, r24
while (--length); while (--length);
3ece: 80 91 02 02 lds r24, 0x0202 3ee4: 0c 17 cp r16, r28
3ed2: 81 50 subi r24, 0x01 ; 1 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0>
3ed4: 80 93 02 02 sts 0x0202, r24
3ed8: 88 23 and r24, r24
3eda: b9 f7 brne .-18 ; 0x3eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3edc: e0 91 00 02 lds r30, 0x0200 3ee8: f0 e0 ldi r31, 0x00 ; 0
3ee0: f0 91 01 02 lds r31, 0x0201 3eea: cf 16 cp r12, r31
3ee4: 88 e3 ldi r24, 0x38 ; 56 3eec: f8 e3 ldi r31, 0x38 ; 56
3ee6: e0 30 cpi r30, 0x00 ; 0 3eee: df 06 cpc r13, r31
3ee8: f8 07 cpc r31, r24 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8>
3eea: 18 f0 brcs .+6 ; 0x3ef2 <main+0xf2> 3ef2: f6 01 movw r30, r12
3eec: 83 e0 ldi r24, 0x03 ; 3 3ef4: b7 be out 0x37, r11 ; 55
3eee: 87 bf out 0x37, r24 ; 55 3ef6: e8 95 spm
3ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
3ef2: 75 d0 rcall .+234 ; 0x3fde <verifySpace> 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
3ef4: 07 b6 in r0, 0x37 ; 55 3efa: 07 b6 in r0, 0x37 ; 55
3ef6: 00 fc sbrc r0, 0 3efc: 00 fc sbrc r0, 0
3ef8: fd cf rjmp .-6 ; 0x3ef4 <main+0xf4> 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa>
} 3f00: a6 01 movw r20, r12
#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
3f02: a0 e0 ldi r26, 0x00 ; 0 3f02: a0 e0 ldi r26, 0x00 ; 0
3f04: b1 e0 ldi r27, 0x01 ; 1 3f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3f1c: fa 01 movw r30, r20 3f1c: fa 01 movw r30, r20
3f1e: 0c 01 movw r0, r24 3f1e: 0c 01 movw r0, r24
3f20: d7 be out 0x37, r13 ; 55 3f20: 87 be out 0x37, r8 ; 55
3f22: e8 95 spm 3f22: e8 95 spm
3f24: 11 24 eor r1, r1 3f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
3f2c: a0 38 cpi r26, 0x80 ; 128 3f2c: a0 38 cpi r26, 0x80 ; 128
3f2e: bf 07 cpc r27, r31 3f2e: bf 07 cpc r27, r31
3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3f32: e0 91 00 02 lds r30, 0x0200 3f32: f6 01 movw r30, r12
3f36: f0 91 01 02 lds r31, 0x0201 3f34: a7 be out 0x37, r10 ; 55
3f3a: e7 be out 0x37, r14 ; 55 3f36: e8 95 spm
3f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
3f3e: 07 b6 in r0, 0x37 ; 55 3f38: 07 b6 in r0, 0x37 ; 55
3f40: 00 fc sbrc r0, 0 3f3a: 00 fc sbrc r0, 0
3f42: fd cf rjmp .-6 ; 0x3f3e <main+0x13e> 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3f44: f7 be out 0x37, r15 ; 55 3f3e: 97 be out 0x37, r9 ; 55
3f46: e8 95 spm 3f40: e8 95 spm
3f48: 27 c0 rjmp .+78 ; 0x3f98 <main+0x198> 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
3f4a: 84 37 cpi r24, 0x74 ; 116 3f44: 84 37 cpi r24, 0x74 ; 116
3f4c: b9 f4 brne .+46 ; 0x3f7c <main+0x17c> 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
3f4e: 37 d0 rcall .+110 ; 0x3fbe <getLen> 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch>
length = getch();
3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch>
3f4c: f8 2e mov r15, r24
getch();
3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch>
verifySpace(); verifySpace();
3f50: 46 d0 rcall .+140 ; 0x3fde <verifySpace> 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace>
3f52: f6 01 movw r30, r12
3f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
3f52: e0 91 00 02 lds r30, 0x0200 3f56: 8f 01 movw r16, r30
3f56: f0 91 01 02 lds r31, 0x0201 3f58: 0f 5f subi r16, 0xFF ; 255
3f5a: 31 96 adiw r30, 0x01 ; 1 3f5a: 1f 4f sbci r17, 0xFF ; 255
3f5c: f0 93 01 02 sts 0x0201, r31 3f5c: 84 91 lpm r24, Z+
3f60: e0 93 00 02 sts 0x0200, r30 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch>
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 <putch>
while (--length); while (--length);
3f6c: 80 91 02 02 lds r24, 0x0202 3f60: ea 94 dec r14
3f70: 81 50 subi r24, 0x01 ; 1 3f62: f8 01 movw r30, r16
3f72: 80 93 02 02 sts 0x0202, r24 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156>
3f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
3f78: 61 f7 brne .-40 ; 0x3f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
3f7a: 0e c0 rjmp .+28 ; 0x3f98 <main+0x198> #endif
/* main program starts here */
int main(void) {
3f66: 08 94 sec
3f68: c1 1c adc r12, r1
3f6a: d1 1c adc r13, r1
3f6c: fa 94 dec r15
3f6e: cf 0c add r12, r15
3f70: d1 1c adc r13, r1
3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
3f7c: 85 37 cpi r24, 0x75 ; 117 3f74: 85 37 cpi r24, 0x75 ; 117
3f7e: 39 f4 brne .+14 ; 0x3f8e <main+0x18e> 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
3f80: 2e d0 rcall .+92 ; 0x3fde <verifySpace> 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
3f82: 8e e1 ldi r24, 0x1E ; 30 3f7a: 8e e1 ldi r24, 0x1E ; 30
3f84: 0c d0 rcall .+24 ; 0x3f9e <putch> 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
3f86: 84 e9 ldi r24, 0x94 ; 148 3f7e: 84 e9 ldi r24, 0x94 ; 148
3f88: 0a d0 rcall .+20 ; 0x3f9e <putch> 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
3f8a: 86 e0 ldi r24, 0x06 ; 6 3f82: 86 e0 ldi r24, 0x06 ; 6
3f8c: 8b cf rjmp .-234 ; 0x3ea4 <main+0xa4> 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
3f8e: 81 35 cpi r24, 0x51 ; 81 3f86: 81 35 cpi r24, 0x51 ; 81
3f90: 11 f4 brne .+4 ; 0x3f96 <main+0x196> 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
3f92: 88 e0 ldi r24, 0x08 ; 8 3f8a: 88 e0 ldi r24, 0x08 ; 8
3f94: 19 d0 rcall .+50 ; 0x3fc8 <watchdogConfig> 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
3f96: 23 d0 rcall .+70 ; 0x3fde <verifySpace> 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
3f98: 80 e1 ldi r24, 0x10 ; 16 3f90: 80 e1 ldi r24, 0x10 ; 16
3f9a: 01 d0 rcall .+2 ; 0x3f9e <putch> 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch>
3f9c: 5c cf rjmp .-328 ; 0x3e56 <main+0x56> 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60>
00003f9e <putch>: 00003f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
3f9e: 98 2f mov r25, r24 3f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
3fa0: 80 91 c0 00 lds r24, 0x00C0 3f98: 80 91 c0 00 lds r24, 0x00C0
3fa4: 85 ff sbrs r24, 5 3f9c: 85 ff sbrs r24, 5
3fa6: fc cf rjmp .-8 ; 0x3fa0 <putch+0x2> 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
3fa8: 90 93 c6 00 sts 0x00C6, r25 3fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
3fac: 08 95 ret 3fa4: 08 95 ret
00003fae <getch>: 00003fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
3fb0: 80 91 c0 00 lds r24, 0x00C0 3fa6: 80 91 c0 00 lds r24, 0x00C0
3fb4: 87 ff sbrs r24, 7 3faa: 87 ff sbrs r24, 7
3fb6: fc cf rjmp .-8 ; 0x3fb0 <getch+0x2> 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
3fae: 80 91 c0 00 lds r24, 0x00C0
3fb2: 84 fd sbrc r24, 4
3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fb6: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0; ch = UDR0;
3fb8: 80 91 c6 00 lds r24, 0x00C6 3fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
3fbc: 08 95 ret 3fbc: 08 95 ret
00003fbe <getLen>: 00003fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
3fbe: f7 df rcall .-18 ; 0x3fae <getch>
length = getch();
3fc0: f6 df rcall .-20 ; 0x3fae <getch>
3fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
3fc6: f3 cf rjmp .-26 ; 0x3fae <getch>
00003fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
3fc8: e0 e6 ldi r30, 0x60 ; 96 3fbe: e0 e6 ldi r30, 0x60 ; 96
3fca: f0 e0 ldi r31, 0x00 ; 0 3fc0: f0 e0 ldi r31, 0x00 ; 0
3fcc: 98 e1 ldi r25, 0x18 ; 24 3fc2: 98 e1 ldi r25, 0x18 ; 24
3fce: 90 83 st Z, r25 3fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
3fd0: 80 83 st Z, r24 3fc6: 80 83 st Z, r24
} }
3fd2: 08 95 ret 3fc8: 08 95 ret
00003fd4 <appStart>: 00003fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fd4: 80 e0 ldi r24, 0x00 ; 0
3fd6: f8 df rcall .-16 ; 0x3fc8 <watchdogConfig>
__asm__ __volatile__ (
3fd8: ee 27 eor r30, r30
3fda: ff 27 eor r31, r31
3fdc: 09 94 ijmp
00003fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
3fde: e7 df rcall .-50 ; 0x3fae <getch> 3fca: ed df rcall .-38 ; 0x3fa6 <getch>
3fe0: 80 32 cpi r24, 0x20 ; 32 3fcc: 80 32 cpi r24, 0x20 ; 32
3fe2: 09 f0 breq .+2 ; 0x3fe6 <verifySpace+0x8> 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc>
3fe4: f7 df rcall .-18 ; 0x3fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
3fd0: 88 e0 ldi r24, 0x08 ; 8
3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig>
3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
3fe6: 84 e1 ldi r24, 0x14 ; 20 3fd6: 84 e1 ldi r24, 0x14 ; 20
} }
3fe8: da cf rjmp .-76 ; 0x3f9e <putch> 3fd8: de cf rjmp .-68 ; 0x3f96 <putch>
00003fea <getNch>: 00003fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
3fea: 1f 93 push r17 3fda: 1f 93 push r17
3fec: 18 2f mov r17, r24 3fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
3fee: df df rcall .-66 ; 0x3fae <getch> 3fde: e3 df rcall .-58 ; 0x3fa6 <getch>
3ff0: 11 50 subi r17, 0x01 ; 1 3fe0: 11 50 subi r17, 0x01 ; 1
3ff2: e9 f7 brne .-6 ; 0x3fee <getNch+0x4> 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4>
verifySpace(); verifySpace();
3ff4: f4 df rcall .-24 ; 0x3fde <verifySpace> 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace>
} }
3ff6: 1f 91 pop r17 3fe6: 1f 91 pop r17
3ff8: 08 95 ret 3fe8: 08 95 ret
00003fea <appStart>:
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fea: 80 e0 ldi r24, 0x00 ; 0
3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig>
__asm__ __volatile__ (
3fee: ee 27 eor r30, r30
3ff0: ff 27 eor r31, r31
3ff2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:103E000084B714BE81FFE6D085E08093810082E014 :103E0000112484B714BE81FFF0D085E08093810037
:103E10008093C00088E18093C10086E08093C20057 :103E100082E08093C00088E18093C10086E08093B7
:103E200085E18093C4008EE0CFD0259A86E02CE314 :103E2000C20085E18093C4008EE0C9D0259A86E067
:103E30003BEF91E0309385002093840096BBB09BCC :103E30002CE33BEF91E0309385002093840096BB08
:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 :103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 :103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
:103E600083E020C0823411F484E103C0853419F466 :103E6000A2D0813461F49FD0082FAFD0023811F076
:103E700085E0BBD091C0853581F499D0082F10E042 :103E7000013811F484E001C083E08DD089C0823420
:103E800096D090E0982F8827802B912B880F991F30 :103E800011F484E103C0853419F485E0A6D080C024
:103E900090930102809300027EC0863529F484E06D :103E9000853579F488D0E82EFF2485D0082F10E0EE
:103EA000A4D080E07CD078C0843609F04EC087D0A2 :103EA000102F00270E291F29000F111F8ED0680127
:103EB000E0910002F091010288E3E030F80718F485 :103EB0006FC0863521F484E090D080E0DECF843678
:103EC00083E087BFE895C0E0D1E071D0899380910D :103EC00009F040C070D06FD0082F6DD080E0C816C8
:103ED00002028150809302028823B9F7E091000228 :103ED00088E3D80618F4F601B7BEE895C0E0D1E053
:103EE000F091010288E3E030F80718F083E087BF23 :103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
:103EF000E89575D007B600FCFDCF409100025091C7 :103EF00018F0F601B7BEE89568D007B600FCFDCF14
:103F00000102A0E0B1E02C9130E011968C91119764 :103F0000A601A0E0B1E02C9130E011968C911197C0
:103F100090E0982F8827822B932B1296FA010C01A0 :103F100090E0982F8827822B932B1296FA010C01A0
:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 :103F200087BEE89511244E5F5F4FF1E0A038BF07D0
:103F300051F7E0910002F0910102E7BEE89507B663 :103F300051F7F601A7BEE89507B600FCFDCF97BE86
:103F400000FCFDCFF7BEE89527C08437B9F437D021 :103F4000E89526C08437B1F42ED02DD0F82E2BD092
:103F500046D0E0910002F09101023196F093010207 :103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
:103F6000E09300023197E4918E2F19D080910202E4 :103F6000EA94F801C1F70894C11CD11CFA94CF0C53
:103F7000815080930202882361F70EC0853739F49F :103F7000D11C0EC0853739F428D08EE10CD084E9ED
:103F80002ED08EE10CD084E90AD086E08BCF81352B :103F80000AD086E07ACF813511F488E018D01DD0B0
:103F900011F488E019D023D080E101D05CCF982FB4 :103F900080E101D065CF982F8091C00085FFFCCFD4
:103FA0008091C00085FFFCCF9093C6000895A8952E :103FA0009093C60008958091C00087FFFCCF809158
:103FB0008091C00087FFFCCF8091C6000895F7DF95 :103FB000C00084FD01C0A8958091C6000895E0E688
:103FC000F6DF80930202F3CFE0E6F0E098E1908321 :103FC000F0E098E1908380830895EDDF803219F06E
:103FD0008083089580E0F8DFEE27FF270994E7DF6C :103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B :103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
:0A3FF0001150E9F7F4DF1F91089566 :043FF000FF2709940A
:023FFE000404B9
:0400000300003E00BB :0400000300003E00BB
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_pro_20mhz.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
3e00: 84 b7 in r24, 0x34 ; 52 3e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
3e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
3e02: 14 be out 0x34, r1 ; 52 3e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
3e04: 81 ff sbrs r24, 1 3e06: 81 ff sbrs r24, 1
3e06: e6 d0 rcall .+460 ; 0x3fd4 <appStart> 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
3e08: 85 e0 ldi r24, 0x05 ; 5 3e0a: 85 e0 ldi r24, 0x05 ; 5
3e0a: 80 93 81 00 sts 0x0081, r24 3e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
3e0e: 82 e0 ldi r24, 0x02 ; 2 3e10: 82 e0 ldi r24, 0x02 ; 2
3e10: 80 93 c0 00 sts 0x00C0, r24 3e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
3e14: 88 e1 ldi r24, 0x18 ; 24 3e16: 88 e1 ldi r24, 0x18 ; 24
3e16: 80 93 c1 00 sts 0x00C1, r24 3e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
3e1a: 86 e0 ldi r24, 0x06 ; 6 3e1c: 86 e0 ldi r24, 0x06 ; 6
3e1c: 80 93 c2 00 sts 0x00C2, r24 3e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
3e20: 85 e1 ldi r24, 0x15 ; 21 3e22: 85 e1 ldi r24, 0x15 ; 21
3e22: 80 93 c4 00 sts 0x00C4, r24 3e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
3e26: 8e e0 ldi r24, 0x0E ; 14 3e28: 8e e0 ldi r24, 0x0E ; 14
3e28: cf d0 rcall .+414 ; 0x3fc8 <watchdogConfig> 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
3e2a: 25 9a sbi 0x04, 5 ; 4 3e2c: 25 9a sbi 0x04, 5 ; 4
3e2c: 86 e0 ldi r24, 0x06 ; 6 3e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e2e: 2c e3 ldi r18, 0x3C ; 60 3e30: 2c e3 ldi r18, 0x3C ; 60
3e30: 3b ef ldi r19, 0xFB ; 251 3e32: 3b ef ldi r19, 0xFB ; 251
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e32: 91 e0 ldi r25, 0x01 ; 1 3e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e34: 30 93 85 00 sts 0x0085, r19 3e36: 30 93 85 00 sts 0x0085, r19
3e38: 20 93 84 00 sts 0x0084, r18 3e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e3c: 96 bb out 0x16, r25 ; 22 3e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
3e3e: b0 9b sbis 0x16, 0 ; 22 3e40: b0 9b sbis 0x16, 0 ; 22
3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
3e42: 1d 9a sbi 0x03, 5 ; 3 3e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
3e44: a8 95 wdr 3e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
3e46: 81 50 subi r24, 0x01 ; 1 3e48: 81 50 subi r24, 0x01 ; 1
3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36>
/* get character from UART */ 3e4c: cc 24 eor r12, r12
ch = getch(); 3e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
3e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
3e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3e50: 88 24 eor r8, r8
3e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3e4e: a5 e0 ldi r26, 0x05 ; 5 3e54: b5 e0 ldi r27, 0x05 ; 5
3e50: ea 2e mov r14, r26 3e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3e52: f1 e1 ldi r31, 0x11 ; 17 3e58: a1 e1 ldi r26, 0x11 ; 17
3e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
3e56: ab d0 rcall .+342 ; 0x3fae <getch> 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
3e58: 81 34 cpi r24, 0x41 ; 65 3e62: 81 34 cpi r24, 0x41 ; 65
3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch>
3e5c: 81 e0 ldi r24, 0x01 ; 1 3e68: 08 2f mov r16, r24
3e5e: c5 d0 rcall .+394 ; 0x3fea <getNch> verifySpace();
putch(0x03); 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace>
3e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
3e62: 20 c0 rjmp .+64 ; 0x3ea4 <main+0xa4> 3e6c: 02 38 cpi r16, 0x82 ; 130
3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74>
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
3e70: 01 38 cpi r16, 0x81 ; 129
3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78>
putch(OPTIBOOT_MAJVER);
3e74: 84 e0 ldi r24, 0x04 ; 4
3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
3e78: 83 e0 ldi r24, 0x03 ; 3
3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch>
3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
3e64: 82 34 cpi r24, 0x42 ; 66 3e7e: 82 34 cpi r24, 0x42 ; 66
3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
3e68: 84 e1 ldi r24, 0x14 ; 20 3e82: 84 e1 ldi r24, 0x14 ; 20
3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
3e6c: 85 34 cpi r24, 0x45 ; 69 3e86: 85 34 cpi r24, 0x45 ; 69
3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
3e70: 85 e0 ldi r24, 0x05 ; 5 3e8a: 85 e0 ldi r24, 0x05 ; 5
3e72: bb d0 rcall .+374 ; 0x3fea <getNch> 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch>
3e74: 91 c0 rjmp .+290 ; 0x3f98 <main+0x198> 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
3e76: 85 35 cpi r24, 0x55 ; 85 3e90: 85 35 cpi r24, 0x55 ; 85
3e78: 81 f4 brne .+32 ; 0x3e9a <main+0x9a> 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
3e7a: 99 d0 rcall .+306 ; 0x3fae <getch> 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
3e7c: 08 2f mov r16, r24 3e96: e8 2e mov r14, r24
3e7e: 10 e0 ldi r17, 0x00 ; 0 3e98: ff 24 eor r15, r15
3e80: 96 d0 rcall .+300 ; 0x3fae <getch> 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch>
3e82: 90 e0 ldi r25, 0x00 ; 0 3e9c: 08 2f mov r16, r24
3e84: 98 2f mov r25, r24 3e9e: 10 e0 ldi r17, 0x00 ; 0
3e86: 88 27 eor r24, r24 3ea0: 10 2f mov r17, r16
3e88: 80 2b or r24, r16 3ea2: 00 27 eor r16, r16
3e8a: 91 2b or r25, r17 3ea4: 0e 29 or r16, r14
3ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
3e8c: 88 0f add r24, r24 3ea8: 00 0f add r16, r16
3e8e: 99 1f adc r25, r25 3eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
3e90: 90 93 01 02 sts 0x0201, r25
3e94: 80 93 00 02 sts 0x0200, r24
3e98: 7e c0 rjmp .+252 ; 0x3f96 <main+0x196>
verifySpace(); verifySpace();
3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace>
3eae: 68 01 movw r12, r16
3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
3e9a: 86 35 cpi r24, 0x56 ; 86 3eb2: 86 35 cpi r24, 0x56 ; 86
3e9c: 29 f4 brne .+10 ; 0x3ea8 <main+0xa8> 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
3e9e: 84 e0 ldi r24, 0x04 ; 4 3eb6: 84 e0 ldi r24, 0x04 ; 4
3ea0: a4 d0 rcall .+328 ; 0x3fea <getNch> 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch>
putch(0x00); putch(0x00);
3ea2: 80 e0 ldi r24, 0x00 ; 0 3eba: 80 e0 ldi r24, 0x00 ; 0
3ea4: 7c d0 rcall .+248 ; 0x3f9e <putch> 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a>
3ea6: 78 c0 rjmp .+240 ; 0x3f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
3ea8: 84 36 cpi r24, 0x64 ; 100 3ebe: 84 36 cpi r24, 0x64 ; 100
3eaa: 09 f0 breq .+2 ; 0x3eae <main+0xae> 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4>
3eac: 4e c0 rjmp .+156 ; 0x3f4a <main+0x14a> 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
3eae: 87 d0 rcall .+270 ; 0x3fbe <getLen> 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch>
length = getch();
3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch>
3ec8: 08 2f mov r16, r24
getch();
3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3eb0: e0 91 00 02 lds r30, 0x0200 3ecc: 80 e0 ldi r24, 0x00 ; 0
3eb4: f0 91 01 02 lds r31, 0x0201 3ece: c8 16 cp r12, r24
3eb8: 88 e3 ldi r24, 0x38 ; 56 3ed0: 88 e3 ldi r24, 0x38 ; 56
3eba: e0 30 cpi r30, 0x00 ; 0 3ed2: d8 06 cpc r13, r24
3ebc: f8 07 cpc r31, r24 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc>
3ebe: 18 f4 brcc .+6 ; 0x3ec6 <main+0xc6> 3ed6: f6 01 movw r30, r12
3ec0: 83 e0 ldi r24, 0x03 ; 3 3ed8: b7 be out 0x37, r11 ; 55
3ec2: 87 bf out 0x37, r24 ; 55 3eda: e8 95 spm
3ec4: e8 95 spm 3edc: c0 e0 ldi r28, 0x00 ; 0
3ec6: c0 e0 ldi r28, 0x00 ; 0 3ede: d1 e0 ldi r29, 0x01 ; 1
3ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
3eca: 71 d0 rcall .+226 ; 0x3fae <getch> 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch>
3ecc: 89 93 st Y+, r24 3ee2: 89 93 st Y+, r24
while (--length); while (--length);
3ece: 80 91 02 02 lds r24, 0x0202 3ee4: 0c 17 cp r16, r28
3ed2: 81 50 subi r24, 0x01 ; 1 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0>
3ed4: 80 93 02 02 sts 0x0202, r24
3ed8: 88 23 and r24, r24
3eda: b9 f7 brne .-18 ; 0x3eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3edc: e0 91 00 02 lds r30, 0x0200 3ee8: f0 e0 ldi r31, 0x00 ; 0
3ee0: f0 91 01 02 lds r31, 0x0201 3eea: cf 16 cp r12, r31
3ee4: 88 e3 ldi r24, 0x38 ; 56 3eec: f8 e3 ldi r31, 0x38 ; 56
3ee6: e0 30 cpi r30, 0x00 ; 0 3eee: df 06 cpc r13, r31
3ee8: f8 07 cpc r31, r24 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8>
3eea: 18 f0 brcs .+6 ; 0x3ef2 <main+0xf2> 3ef2: f6 01 movw r30, r12
3eec: 83 e0 ldi r24, 0x03 ; 3 3ef4: b7 be out 0x37, r11 ; 55
3eee: 87 bf out 0x37, r24 ; 55 3ef6: e8 95 spm
3ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
3ef2: 75 d0 rcall .+234 ; 0x3fde <verifySpace> 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
3ef4: 07 b6 in r0, 0x37 ; 55 3efa: 07 b6 in r0, 0x37 ; 55
3ef6: 00 fc sbrc r0, 0 3efc: 00 fc sbrc r0, 0
3ef8: fd cf rjmp .-6 ; 0x3ef4 <main+0xf4> 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa>
} 3f00: a6 01 movw r20, r12
#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
3f02: a0 e0 ldi r26, 0x00 ; 0 3f02: a0 e0 ldi r26, 0x00 ; 0
3f04: b1 e0 ldi r27, 0x01 ; 1 3f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3f1c: fa 01 movw r30, r20 3f1c: fa 01 movw r30, r20
3f1e: 0c 01 movw r0, r24 3f1e: 0c 01 movw r0, r24
3f20: d7 be out 0x37, r13 ; 55 3f20: 87 be out 0x37, r8 ; 55
3f22: e8 95 spm 3f22: e8 95 spm
3f24: 11 24 eor r1, r1 3f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
3f2c: a0 38 cpi r26, 0x80 ; 128 3f2c: a0 38 cpi r26, 0x80 ; 128
3f2e: bf 07 cpc r27, r31 3f2e: bf 07 cpc r27, r31
3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3f32: e0 91 00 02 lds r30, 0x0200 3f32: f6 01 movw r30, r12
3f36: f0 91 01 02 lds r31, 0x0201 3f34: a7 be out 0x37, r10 ; 55
3f3a: e7 be out 0x37, r14 ; 55 3f36: e8 95 spm
3f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
3f3e: 07 b6 in r0, 0x37 ; 55 3f38: 07 b6 in r0, 0x37 ; 55
3f40: 00 fc sbrc r0, 0 3f3a: 00 fc sbrc r0, 0
3f42: fd cf rjmp .-6 ; 0x3f3e <main+0x13e> 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3f44: f7 be out 0x37, r15 ; 55 3f3e: 97 be out 0x37, r9 ; 55
3f46: e8 95 spm 3f40: e8 95 spm
3f48: 27 c0 rjmp .+78 ; 0x3f98 <main+0x198> 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
3f4a: 84 37 cpi r24, 0x74 ; 116 3f44: 84 37 cpi r24, 0x74 ; 116
3f4c: b9 f4 brne .+46 ; 0x3f7c <main+0x17c> 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
3f4e: 37 d0 rcall .+110 ; 0x3fbe <getLen> 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch>
length = getch();
3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch>
3f4c: f8 2e mov r15, r24
getch();
3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch>
verifySpace(); verifySpace();
3f50: 46 d0 rcall .+140 ; 0x3fde <verifySpace> 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace>
3f52: f6 01 movw r30, r12
3f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
3f52: e0 91 00 02 lds r30, 0x0200 3f56: 8f 01 movw r16, r30
3f56: f0 91 01 02 lds r31, 0x0201 3f58: 0f 5f subi r16, 0xFF ; 255
3f5a: 31 96 adiw r30, 0x01 ; 1 3f5a: 1f 4f sbci r17, 0xFF ; 255
3f5c: f0 93 01 02 sts 0x0201, r31 3f5c: 84 91 lpm r24, Z+
3f60: e0 93 00 02 sts 0x0200, r30 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch>
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 <putch>
while (--length); while (--length);
3f6c: 80 91 02 02 lds r24, 0x0202 3f60: ea 94 dec r14
3f70: 81 50 subi r24, 0x01 ; 1 3f62: f8 01 movw r30, r16
3f72: 80 93 02 02 sts 0x0202, r24 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156>
3f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
3f78: 61 f7 brne .-40 ; 0x3f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
3f7a: 0e c0 rjmp .+28 ; 0x3f98 <main+0x198> #endif
/* main program starts here */
int main(void) {
3f66: 08 94 sec
3f68: c1 1c adc r12, r1
3f6a: d1 1c adc r13, r1
3f6c: fa 94 dec r15
3f6e: cf 0c add r12, r15
3f70: d1 1c adc r13, r1
3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
3f7c: 85 37 cpi r24, 0x75 ; 117 3f74: 85 37 cpi r24, 0x75 ; 117
3f7e: 39 f4 brne .+14 ; 0x3f8e <main+0x18e> 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
3f80: 2e d0 rcall .+92 ; 0x3fde <verifySpace> 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
3f82: 8e e1 ldi r24, 0x1E ; 30 3f7a: 8e e1 ldi r24, 0x1E ; 30
3f84: 0c d0 rcall .+24 ; 0x3f9e <putch> 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
3f86: 84 e9 ldi r24, 0x94 ; 148 3f7e: 84 e9 ldi r24, 0x94 ; 148
3f88: 0a d0 rcall .+20 ; 0x3f9e <putch> 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
3f8a: 86 e0 ldi r24, 0x06 ; 6 3f82: 86 e0 ldi r24, 0x06 ; 6
3f8c: 8b cf rjmp .-234 ; 0x3ea4 <main+0xa4> 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
3f8e: 81 35 cpi r24, 0x51 ; 81 3f86: 81 35 cpi r24, 0x51 ; 81
3f90: 11 f4 brne .+4 ; 0x3f96 <main+0x196> 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
3f92: 88 e0 ldi r24, 0x08 ; 8 3f8a: 88 e0 ldi r24, 0x08 ; 8
3f94: 19 d0 rcall .+50 ; 0x3fc8 <watchdogConfig> 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
3f96: 23 d0 rcall .+70 ; 0x3fde <verifySpace> 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
3f98: 80 e1 ldi r24, 0x10 ; 16 3f90: 80 e1 ldi r24, 0x10 ; 16
3f9a: 01 d0 rcall .+2 ; 0x3f9e <putch> 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch>
3f9c: 5c cf rjmp .-328 ; 0x3e56 <main+0x56> 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60>
00003f9e <putch>: 00003f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
3f9e: 98 2f mov r25, r24 3f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
3fa0: 80 91 c0 00 lds r24, 0x00C0 3f98: 80 91 c0 00 lds r24, 0x00C0
3fa4: 85 ff sbrs r24, 5 3f9c: 85 ff sbrs r24, 5
3fa6: fc cf rjmp .-8 ; 0x3fa0 <putch+0x2> 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
3fa8: 90 93 c6 00 sts 0x00C6, r25 3fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
3fac: 08 95 ret 3fa4: 08 95 ret
00003fae <getch>: 00003fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
3fb0: 80 91 c0 00 lds r24, 0x00C0 3fa6: 80 91 c0 00 lds r24, 0x00C0
3fb4: 87 ff sbrs r24, 7 3faa: 87 ff sbrs r24, 7
3fb6: fc cf rjmp .-8 ; 0x3fb0 <getch+0x2> 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
3fae: 80 91 c0 00 lds r24, 0x00C0
3fb2: 84 fd sbrc r24, 4
3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fb6: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0; ch = UDR0;
3fb8: 80 91 c6 00 lds r24, 0x00C6 3fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
3fbc: 08 95 ret 3fbc: 08 95 ret
00003fbe <getLen>: 00003fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
3fbe: f7 df rcall .-18 ; 0x3fae <getch>
length = getch();
3fc0: f6 df rcall .-20 ; 0x3fae <getch>
3fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
3fc6: f3 cf rjmp .-26 ; 0x3fae <getch>
00003fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
3fc8: e0 e6 ldi r30, 0x60 ; 96 3fbe: e0 e6 ldi r30, 0x60 ; 96
3fca: f0 e0 ldi r31, 0x00 ; 0 3fc0: f0 e0 ldi r31, 0x00 ; 0
3fcc: 98 e1 ldi r25, 0x18 ; 24 3fc2: 98 e1 ldi r25, 0x18 ; 24
3fce: 90 83 st Z, r25 3fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
3fd0: 80 83 st Z, r24 3fc6: 80 83 st Z, r24
} }
3fd2: 08 95 ret 3fc8: 08 95 ret
00003fd4 <appStart>: 00003fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fd4: 80 e0 ldi r24, 0x00 ; 0
3fd6: f8 df rcall .-16 ; 0x3fc8 <watchdogConfig>
__asm__ __volatile__ (
3fd8: ee 27 eor r30, r30
3fda: ff 27 eor r31, r31
3fdc: 09 94 ijmp
00003fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
3fde: e7 df rcall .-50 ; 0x3fae <getch> 3fca: ed df rcall .-38 ; 0x3fa6 <getch>
3fe0: 80 32 cpi r24, 0x20 ; 32 3fcc: 80 32 cpi r24, 0x20 ; 32
3fe2: 09 f0 breq .+2 ; 0x3fe6 <verifySpace+0x8> 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc>
3fe4: f7 df rcall .-18 ; 0x3fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
3fd0: 88 e0 ldi r24, 0x08 ; 8
3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig>
3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
3fe6: 84 e1 ldi r24, 0x14 ; 20 3fd6: 84 e1 ldi r24, 0x14 ; 20
} }
3fe8: da cf rjmp .-76 ; 0x3f9e <putch> 3fd8: de cf rjmp .-68 ; 0x3f96 <putch>
00003fea <getNch>: 00003fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
3fea: 1f 93 push r17 3fda: 1f 93 push r17
3fec: 18 2f mov r17, r24 3fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
3fee: df df rcall .-66 ; 0x3fae <getch> 3fde: e3 df rcall .-58 ; 0x3fa6 <getch>
3ff0: 11 50 subi r17, 0x01 ; 1 3fe0: 11 50 subi r17, 0x01 ; 1
3ff2: e9 f7 brne .-6 ; 0x3fee <getNch+0x4> 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4>
verifySpace(); verifySpace();
3ff4: f4 df rcall .-24 ; 0x3fde <verifySpace> 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace>
} }
3ff6: 1f 91 pop r17 3fe6: 1f 91 pop r17
3ff8: 08 95 ret 3fe8: 08 95 ret
00003fea <appStart>:
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fea: 80 e0 ldi r24, 0x00 ; 0
3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig>
__asm__ __volatile__ (
3fee: ee 27 eor r30, r30
3ff0: ff 27 eor r31, r31
3ff2: 09 94 ijmp

View File

@@ -1,34 +1,35 @@
:103E000084B714BE81FFE6D085E08093810082E014 :103E0000112484B714BE81FFF0D085E08093810037
:103E10008093C00088E18093C10086E08093C20057 :103E100082E08093C00088E18093C10086E08093B7
:103E200088E08093C4008EE0CFD0259A86E028E118 :103E2000C20088E08093C4008EE0C9D0259A86E065
:103E30003EEF91E0309385002093840096BBB09BC9 :103E300028E13EEF91E0309385002093840096BB0B
:103E4000FECF1D9AA8958150A9F7DD24D394A5E053 :103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010 :103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
:103E600083E020C0823411F484E103C0853419F466 :103E6000A2D0813461F49FD0082FAFD0023811F076
:103E700085E0BBD091C0853581F499D0082F10E042 :103E7000013811F484E001C083E08DD089C0823420
:103E800096D090E0982F8827802B912B880F991F30 :103E800011F484E103C0853419F485E0A6D080C024
:103E900090930102809300027EC0863529F484E06D :103E9000853579F488D0E82EFF2485D0082F10E0EE
:103EA000A4D080E07CD078C0843609F04EC087D0A2 :103EA000102F00270E291F29000F111F8ED0680127
:103EB000E0910002F091010288E3E030F80718F485 :103EB0006FC0863521F484E090D080E0DECF843678
:103EC00083E087BFE895C0E0D1E071D0899380910D :103EC00009F040C070D06FD0082F6DD080E0C816C8
:103ED00002028150809302028823B9F7E091000228 :103ED00088E3D80618F4F601B7BEE895C0E0D1E053
:103EE000F091010288E3E030F80718F083E087BF23 :103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
:103EF000E89575D007B600FCFDCF409100025091C7 :103EF00018F0F601B7BEE89568D007B600FCFDCF14
:103F00000102A0E0B1E02C9130E011968C91119764 :103F0000A601A0E0B1E02C9130E011968C911197C0
:103F100090E0982F8827822B932B1296FA010C01A0 :103F100090E0982F8827822B932B1296FA010C01A0
:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780 :103F200087BEE89511244E5F5F4FF1E0A038BF07D0
:103F300051F7E0910002F0910102E7BEE89507B663 :103F300051F7F601A7BEE89507B600FCFDCF97BE86
:103F400000FCFDCFF7BEE89527C08437B9F437D021 :103F4000E89526C08437B1F42ED02DD0F82E2BD092
:103F500046D0E0910002F09101023196F093010207 :103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
:103F6000E09300023197E4918E2F19D080910202E4 :103F6000EA94F801C1F70894C11CD11CFA94CF0C53
:103F7000815080930202882361F70EC0853739F49F :103F7000D11C0EC0853739F428D08EE10CD084E9ED
:103F80002ED08EE10CD084E90AD086E08BCF81352B :103F80000AD086E07ACF813511F488E018D01DD0B0
:103F900011F488E019D023D080E101D05CCF982FB4 :103F900080E101D065CF982F8091C00085FFFCCFD4
:103FA0008091C00085FFFCCF9093C6000895A8952E :103FA0009093C60008958091C00087FFFCCF809158
:103FB0008091C00087FFFCCF8091C6000895F7DF95 :103FB000C00084FD01C0A8958091C6000895E0E688
:103FC000F6DF80930202F3CFE0E6F0E098E1908321 :103FC000F0E098E1908380830895EDDF803219F06E
:103FD0008083089580E0F8DFEE27FF270994E7DF6C :103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B :103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
:0A3FF0001150E9F7F4DF1F91089566 :043FF000FF2709940A
:023FFE000404B9
:0400000300003E00BB :0400000300003E00BB
:00000001FF :00000001FF

View File

@@ -3,25 +3,27 @@ optiboot_pro_8MHz.elf: file format elf32-avr
Sections: Sections:
Idx Name Size VMA LMA File off Algn 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 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 CONTENTS, READONLY, DEBUGGING
2 .debug_pubnames 0000006a 00000000 00000000 00000276 2**0 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
3 .debug_info 00000284 00000000 00000000 000002e0 2**0 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
4 .debug_abbrev 000001ae 00000000 00000000 00000564 2**0 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
5 .debug_line 000003e4 00000000 00000000 00000712 2**0 6 .debug_line 0000046b 00000000 00000000 000006f1 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
6 .debug_frame 00000090 00000000 00000000 00000af8 2**2 7 .debug_frame 00000080 00000000 00000000 00000b5c 2**2
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
7 .debug_str 00000141 00000000 00000000 00000b88 2**0 8 .debug_str 00000143 00000000 00000000 00000bdc 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000001e1 00000000 00000000 00000cc9 2**0 9 .debug_loc 000002d8 00000000 00000000 00000d1f 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000068 00000000 00000000 00000eaa 2**0 10 .debug_ranges 00000078 00000000 00000000 00000ff7 2**0
CONTENTS, READONLY, DEBUGGING CONTENTS, READONLY, DEBUGGING
Disassembly of section .text: Disassembly of section .text:
@@ -33,266 +35,293 @@ Disassembly of section .text:
/* main program starts here */ /* main program starts here */
int main(void) { int main(void) {
3e00: 84 b7 in r24, 0x34 ; 52 3e00: 11 24 eor r1, r1
#ifdef __AVR_ATmega8__
uint8_t ch; SP=RAMEND; // This is done by hardware reset
#endif
// Adaboot no-wait mod // Adaboot no-wait mod
ch = MCUSR; ch = MCUSR;
3e02: 84 b7 in r24, 0x34 ; 52
MCUSR = 0; MCUSR = 0;
3e02: 14 be out 0x34, r1 ; 52 3e04: 14 be out 0x34, r1 ; 52
if (!(ch & _BV(EXTRF))) appStart(); if (!(ch & _BV(EXTRF))) appStart();
3e04: 81 ff sbrs r24, 1 3e06: 81 ff sbrs r24, 1
3e06: e6 d0 rcall .+460 ; 0x3fd4 <appStart> 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart>
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter // Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
3e08: 85 e0 ldi r24, 0x05 ; 5 3e0a: 85 e0 ldi r24, 0x05 ; 5
3e0a: 80 93 81 00 sts 0x0081, r24 3e0c: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else #else
UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0A = _BV(U2X0); //Double speed mode USART0
3e0e: 82 e0 ldi r24, 0x02 ; 2 3e10: 82 e0 ldi r24, 0x02 ; 2
3e10: 80 93 c0 00 sts 0x00C0, r24 3e12: 80 93 c0 00 sts 0x00C0, r24
UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0B = _BV(RXEN0) | _BV(TXEN0);
3e14: 88 e1 ldi r24, 0x18 ; 24 3e16: 88 e1 ldi r24, 0x18 ; 24
3e16: 80 93 c1 00 sts 0x00C1, r24 3e18: 80 93 c1 00 sts 0x00C1, r24
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
3e1a: 86 e0 ldi r24, 0x06 ; 6 3e1c: 86 e0 ldi r24, 0x06 ; 6
3e1c: 80 93 c2 00 sts 0x00C2, r24 3e1e: 80 93 c2 00 sts 0x00C2, r24
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
3e20: 88 e0 ldi r24, 0x08 ; 8 3e22: 88 e0 ldi r24, 0x08 ; 8
3e22: 80 93 c4 00 sts 0x00C4, r24 3e24: 80 93 c4 00 sts 0x00C4, r24
#endif #endif
#endif #endif
// Set up watchdog to trigger after 500ms // Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S); watchdogConfig(WATCHDOG_1S);
3e26: 8e e0 ldi r24, 0x0E ; 14 3e28: 8e e0 ldi r24, 0x0E ; 14
3e28: cf d0 rcall .+414 ; 0x3fc8 <watchdogConfig> 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig>
/* Set LED pin as output */ /* Set LED pin as output */
LED_DDR |= _BV(LED); LED_DDR |= _BV(LED);
3e2a: 25 9a sbi 0x04, 5 ; 4 3e2c: 25 9a sbi 0x04, 5 ; 4
3e2c: 86 e0 ldi r24, 0x06 ; 6 3e2e: 86 e0 ldi r24, 0x06 ; 6
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e2e: 28 e1 ldi r18, 0x18 ; 24 3e30: 28 e1 ldi r18, 0x18 ; 24
3e30: 3e ef ldi r19, 0xFE ; 254 3e32: 3e ef ldi r19, 0xFE ; 254
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e32: 91 e0 ldi r25, 0x01 ; 1 3e34: 91 e0 ldi r25, 0x01 ; 1
} }
#if LED_START_FLASHES > 0 #if LED_START_FLASHES > 0
void flash_led(uint8_t count) { void flash_led(uint8_t count) {
do { do {
TCNT1 = -(F_CPU/(1024*16)); TCNT1 = -(F_CPU/(1024*16));
3e34: 30 93 85 00 sts 0x0085, r19 3e36: 30 93 85 00 sts 0x0085, r19
3e38: 20 93 84 00 sts 0x0084, r18 3e3a: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1); TIFR1 = _BV(TOV1);
3e3c: 96 bb out 0x16, r25 ; 22 3e3e: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1))); while(!(TIFR1 & _BV(TOV1)));
3e3e: b0 9b sbis 0x16, 0 ; 22 3e40: b0 9b sbis 0x16, 0 ; 22
3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40>
#ifdef __AVR_ATmega8__ #ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
3e42: 1d 9a sbi 0x03, 5 ; 3 3e44: 1d 9a sbi 0x03, 5 ; 3
return getch();
} }
#endif
// Watchdog functions. These are only safe with interrupts turned off. // Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() { void watchdogReset() {
__asm__ __volatile__ ( __asm__ __volatile__ (
3e44: a8 95 wdr 3e46: a8 95 wdr
LED_PORT ^= _BV(LED); LED_PORT ^= _BV(LED);
#else #else
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
#endif #endif
watchdogReset(); watchdogReset();
} while (--count); } while (--count);
3e46: 81 50 subi r24, 0x01 ; 1 3e48: 81 50 subi r24, 0x01 ; 1
3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36>
/* get character from UART */ 3e4c: cc 24 eor r12, r12
ch = getch(); 3e4e: dd 24 eor r13, r13
ch = SPM_PAGESIZE / 2;
if(ch == STK_GET_PARAMETER) { do {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy uint16_t a;
getNch(1); a = *bufPtr++;
3e4a: dd 24 eor r13, r13 a |= (*bufPtr++) << 8;
3e4c: d3 94 inc r13
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3e50: 88 24 eor r8, r8
3e52: 83 94 inc r8
addrPtr += 2; addrPtr += 2;
} while (--ch); } while (--ch);
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3e4e: a5 e0 ldi r26, 0x05 ; 5 3e54: b5 e0 ldi r27, 0x05 ; 5
3e50: ea 2e mov r14, r26 3e56: ab 2e mov r10, r27
boot_spm_busy_wait(); boot_spm_busy_wait();
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3e52: f1 e1 ldi r31, 0x11 ; 17 3e58: a1 e1 ldi r26, 0x11 ; 17
3e54: ff 2e mov r15, r31 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 #endif
/* Forever loop */ /* Forever loop */
for (;;) { for (;;) {
/* get character from UART */ /* get character from UART */
ch = getch(); ch = getch();
3e56: ab d0 rcall .+342 ; 0x3fae <getch> 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch>
if(ch == STK_GET_PARAMETER) { if(ch == STK_GET_PARAMETER) {
3e58: 81 34 cpi r24, 0x41 ; 65 3e62: 81 34 cpi r24, 0x41 ; 65
3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e>
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy unsigned char which = getch();
getNch(1); 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch>
3e5c: 81 e0 ldi r24, 0x01 ; 1 3e68: 08 2f mov r16, r24
3e5e: c5 d0 rcall .+394 ; 0x3fea <getNch> verifySpace();
putch(0x03); 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace>
3e60: 83 e0 ldi r24, 0x03 ; 3 if (which == 0x82) {
3e62: 20 c0 rjmp .+64 ; 0x3ea4 <main+0xa4> 3e6c: 02 38 cpi r16, 0x82 ; 130
3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74>
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
3e70: 01 38 cpi r16, 0x81 ; 129
3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78>
putch(OPTIBOOT_MAJVER);
3e74: 84 e0 ldi r24, 0x04 ; 4
3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
3e78: 83 e0 ldi r24, 0x03 ; 3
3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch>
3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190>
}
} }
else if(ch == STK_SET_DEVICE) { else if(ch == STK_SET_DEVICE) {
3e64: 82 34 cpi r24, 0x42 ; 66 3e7e: 82 34 cpi r24, 0x42 ; 66
3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86>
// SET DEVICE is ignored // SET DEVICE is ignored
getNch(20); getNch(20);
3e68: 84 e1 ldi r24, 0x14 ; 20 3e82: 84 e1 ldi r24, 0x14 ; 20
3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c>
} }
else if(ch == STK_SET_DEVICE_EXT) { else if(ch == STK_SET_DEVICE_EXT) {
3e6c: 85 34 cpi r24, 0x45 ; 69 3e86: 85 34 cpi r24, 0x45 ; 69
3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90>
// SET DEVICE EXT is ignored // SET DEVICE EXT is ignored
getNch(5); getNch(5);
3e70: 85 e0 ldi r24, 0x05 ; 5 3e8a: 85 e0 ldi r24, 0x05 ; 5
3e72: bb d0 rcall .+374 ; 0x3fea <getNch> 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch>
3e74: 91 c0 rjmp .+290 ; 0x3f98 <main+0x198> 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_LOAD_ADDRESS) { else if(ch == STK_LOAD_ADDRESS) {
3e76: 85 35 cpi r24, 0x55 ; 85 3e90: 85 35 cpi r24, 0x55 ; 85
3e78: 81 f4 brne .+32 ; 0x3e9a <main+0x9a> 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2>
// LOAD ADDRESS // LOAD ADDRESS
uint16_t newAddress; uint16_t newAddress;
newAddress = getch(); newAddress = getch();
3e7a: 99 d0 rcall .+306 ; 0x3fae <getch> 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch>
newAddress = (newAddress & 0xff) | (getch() << 8); newAddress = (newAddress & 0xff) | (getch() << 8);
3e7c: 08 2f mov r16, r24 3e96: e8 2e mov r14, r24
3e7e: 10 e0 ldi r17, 0x00 ; 0 3e98: ff 24 eor r15, r15
3e80: 96 d0 rcall .+300 ; 0x3fae <getch> 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch>
3e82: 90 e0 ldi r25, 0x00 ; 0 3e9c: 08 2f mov r16, r24
3e84: 98 2f mov r25, r24 3e9e: 10 e0 ldi r17, 0x00 ; 0
3e86: 88 27 eor r24, r24 3ea0: 10 2f mov r17, r16
3e88: 80 2b or r24, r16 3ea2: 00 27 eor r16, r16
3e8a: 91 2b or r25, r17 3ea4: 0e 29 or r16, r14
3ea6: 1f 29 or r17, r15
#ifdef RAMPZ #ifdef RAMPZ
// Transfer top bit to RAMPZ // Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0; RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif #endif
newAddress += newAddress; // Convert from word address to byte address newAddress += newAddress; // Convert from word address to byte address
3e8c: 88 0f add r24, r24 3ea8: 00 0f add r16, r16
3e8e: 99 1f adc r25, r25 3eaa: 11 1f adc r17, r17
address = newAddress; address = newAddress;
3e90: 90 93 01 02 sts 0x0201, r25
3e94: 80 93 00 02 sts 0x0200, r24
3e98: 7e c0 rjmp .+252 ; 0x3f96 <main+0x196>
verifySpace(); verifySpace();
3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace>
3eae: 68 01 movw r12, r16
3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190>
} }
else if(ch == STK_UNIVERSAL) { else if(ch == STK_UNIVERSAL) {
3e9a: 86 35 cpi r24, 0x56 ; 86 3eb2: 86 35 cpi r24, 0x56 ; 86
3e9c: 29 f4 brne .+10 ; 0x3ea8 <main+0xa8> 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe>
// UNIVERSAL command is ignored // UNIVERSAL command is ignored
getNch(4); getNch(4);
3e9e: 84 e0 ldi r24, 0x04 ; 4 3eb6: 84 e0 ldi r24, 0x04 ; 4
3ea0: a4 d0 rcall .+328 ; 0x3fea <getNch> 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch>
putch(0x00); putch(0x00);
3ea2: 80 e0 ldi r24, 0x00 ; 0 3eba: 80 e0 ldi r24, 0x00 ; 0
3ea4: 7c d0 rcall .+248 ; 0x3f9e <putch> 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a>
3ea6: 78 c0 rjmp .+240 ; 0x3f98 <main+0x198>
} }
/* 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) { else if(ch == STK_PROG_PAGE) {
3ea8: 84 36 cpi r24, 0x64 ; 100 3ebe: 84 36 cpi r24, 0x64 ; 100
3eaa: 09 f0 breq .+2 ; 0x3eae <main+0xae> 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4>
3eac: 4e c0 rjmp .+156 ; 0x3f4a <main+0x14a> 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144>
// PROGRAM PAGE - we support flash programming only, not EEPROM // PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr; uint8_t *bufPtr;
uint16_t addrPtr; uint16_t addrPtr;
getLen(); getch(); /* getlen() */
3eae: 87 d0 rcall .+270 ; 0x3fbe <getLen> 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch>
length = getch();
3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch>
3ec8: 08 2f mov r16, r24
getch();
3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch>
// If we are in RWW section, immediately start page erase // If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3eb0: e0 91 00 02 lds r30, 0x0200 3ecc: 80 e0 ldi r24, 0x00 ; 0
3eb4: f0 91 01 02 lds r31, 0x0201 3ece: c8 16 cp r12, r24
3eb8: 88 e3 ldi r24, 0x38 ; 56 3ed0: 88 e3 ldi r24, 0x38 ; 56
3eba: e0 30 cpi r30, 0x00 ; 0 3ed2: d8 06 cpc r13, r24
3ebc: f8 07 cpc r31, r24 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc>
3ebe: 18 f4 brcc .+6 ; 0x3ec6 <main+0xc6> 3ed6: f6 01 movw r30, r12
3ec0: 83 e0 ldi r24, 0x03 ; 3 3ed8: b7 be out 0x37, r11 ; 55
3ec2: 87 bf out 0x37, r24 ; 55 3eda: e8 95 spm
3ec4: e8 95 spm 3edc: c0 e0 ldi r28, 0x00 ; 0
3ec6: c0 e0 ldi r28, 0x00 ; 0 3ede: d1 e0 ldi r29, 0x01 ; 1
3ec8: d1 e0 ldi r29, 0x01 ; 1
// While that is going on, read in page contents // While that is going on, read in page contents
bufPtr = buff; bufPtr = buff;
do *bufPtr++ = getch(); do *bufPtr++ = getch();
3eca: 71 d0 rcall .+226 ; 0x3fae <getch> 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch>
3ecc: 89 93 st Y+, r24 3ee2: 89 93 st Y+, r24
while (--length); while (--length);
3ece: 80 91 02 02 lds r24, 0x0202 3ee4: 0c 17 cp r16, r28
3ed2: 81 50 subi r24, 0x01 ; 1 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0>
3ed4: 80 93 02 02 sts 0x0202, r24
3ed8: 88 23 and r24, r24
3eda: b9 f7 brne .-18 ; 0x3eca <main+0xca>
// If we are in NRWW section, page erase has to be delayed until now. // If we are in NRWW section, page erase has to be delayed until now.
// Todo: Take RAMPZ into account // Todo: Take RAMPZ into account
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
3edc: e0 91 00 02 lds r30, 0x0200 3ee8: f0 e0 ldi r31, 0x00 ; 0
3ee0: f0 91 01 02 lds r31, 0x0201 3eea: cf 16 cp r12, r31
3ee4: 88 e3 ldi r24, 0x38 ; 56 3eec: f8 e3 ldi r31, 0x38 ; 56
3ee6: e0 30 cpi r30, 0x00 ; 0 3eee: df 06 cpc r13, r31
3ee8: f8 07 cpc r31, r24 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8>
3eea: 18 f0 brcs .+6 ; 0x3ef2 <main+0xf2> 3ef2: f6 01 movw r30, r12
3eec: 83 e0 ldi r24, 0x03 ; 3 3ef4: b7 be out 0x37, r11 ; 55
3eee: 87 bf out 0x37, r24 ; 55 3ef6: e8 95 spm
3ef0: e8 95 spm
// Read command terminator, start reply // Read command terminator, start reply
verifySpace(); verifySpace();
3ef2: 75 d0 rcall .+234 ; 0x3fde <verifySpace> 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace>
// If only a partial page is to be programmed, the erase might not be complete. // If only a partial page is to be programmed, the erase might not be complete.
// So check that here // So check that here
boot_spm_busy_wait(); boot_spm_busy_wait();
3ef4: 07 b6 in r0, 0x37 ; 55 3efa: 07 b6 in r0, 0x37 ; 55
3ef6: 00 fc sbrc r0, 0 3efc: 00 fc sbrc r0, 0
3ef8: fd cf rjmp .-6 ; 0x3ef4 <main+0xf4> 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa>
} 3f00: a6 01 movw r20, r12
#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
3f02: a0 e0 ldi r26, 0x00 ; 0 3f02: a0 e0 ldi r26, 0x00 ; 0
3f04: b1 e0 ldi r27, 0x01 ; 1 3f04: b1 e0 ldi r27, 0x01 ; 1
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2; ch = SPM_PAGESIZE / 2;
do { do {
uint16_t a; uint16_t a;
@@ -323,7 +352,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a); __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
3f1c: fa 01 movw r30, r20 3f1c: fa 01 movw r30, r20
3f1e: 0c 01 movw r0, r24 3f1e: 0c 01 movw r0, r24
3f20: d7 be out 0x37, r13 ; 55 3f20: 87 be out 0x37, r8 ; 55
3f22: e8 95 spm 3f22: e8 95 spm
3f24: 11 24 eor r1, r1 3f24: 11 24 eor r1, r1
addrPtr += 2; addrPtr += 2;
@@ -334,136 +363,159 @@ int main(void) {
3f2c: a0 38 cpi r26, 0x80 ; 128 3f2c: a0 38 cpi r26, 0x80 ; 128
3f2e: bf 07 cpc r27, r31 3f2e: bf 07 cpc r27, r31
3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106>
// Write from programming buffer // Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address); __boot_page_write_short((uint16_t)(void*)address);
3f32: e0 91 00 02 lds r30, 0x0200 3f32: f6 01 movw r30, r12
3f36: f0 91 01 02 lds r31, 0x0201 3f34: a7 be out 0x37, r10 ; 55
3f3a: e7 be out 0x37, r14 ; 55 3f36: e8 95 spm
3f3c: e8 95 spm
boot_spm_busy_wait(); boot_spm_busy_wait();
3f3e: 07 b6 in r0, 0x37 ; 55 3f38: 07 b6 in r0, 0x37 ; 55
3f40: 00 fc sbrc r0, 0 3f3a: 00 fc sbrc r0, 0
3f42: fd cf rjmp .-6 ; 0x3f3e <main+0x13e> 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138>
#if defined(RWWSRE) #if defined(RWWSRE)
// Reenable read access to flash // Reenable read access to flash
boot_rww_enable(); boot_rww_enable();
3f44: f7 be out 0x37, r15 ; 55 3f3e: 97 be out 0x37, r9 ; 55
3f46: e8 95 spm 3f40: e8 95 spm
3f48: 27 c0 rjmp .+78 ; 0x3f98 <main+0x198> 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190>
#endif #endif
} }
/* Read memory block mode, length is big endian. */ /* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) { else if(ch == STK_READ_PAGE) {
3f4a: 84 37 cpi r24, 0x74 ; 116 3f44: 84 37 cpi r24, 0x74 ; 116
3f4c: b9 f4 brne .+46 ; 0x3f7c <main+0x17c> 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174>
// READ PAGE - we only read flash // READ PAGE - we only read flash
getLen(); getch(); /* getlen() */
3f4e: 37 d0 rcall .+110 ; 0x3fbe <getLen> 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch>
length = getch();
3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch>
3f4c: f8 2e mov r15, r24
getch();
3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch>
verifySpace(); verifySpace();
3f50: 46 d0 rcall .+140 ; 0x3fde <verifySpace> 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace>
3f52: f6 01 movw r30, r12
3f54: ef 2c mov r14, r15
putch(result); putch(result);
address++; address++;
} }
while (--length); while (--length);
#else #else
do putch(pgm_read_byte_near(address++)); do putch(pgm_read_byte_near(address++));
3f52: e0 91 00 02 lds r30, 0x0200 3f56: 8f 01 movw r16, r30
3f56: f0 91 01 02 lds r31, 0x0201 3f58: 0f 5f subi r16, 0xFF ; 255
3f5a: 31 96 adiw r30, 0x01 ; 1 3f5a: 1f 4f sbci r17, 0xFF ; 255
3f5c: f0 93 01 02 sts 0x0201, r31 3f5c: 84 91 lpm r24, Z+
3f60: e0 93 00 02 sts 0x0200, r30 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch>
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 <putch>
while (--length); while (--length);
3f6c: 80 91 02 02 lds r24, 0x0202 3f60: ea 94 dec r14
3f70: 81 50 subi r24, 0x01 ; 1 3f62: f8 01 movw r30, r16
3f72: 80 93 02 02 sts 0x0202, r24 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156>
3f76: 88 23 and r24, r24 #define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
3f78: 61 f7 brne .-40 ; 0x3f52 <main+0x152> #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
3f7a: 0e c0 rjmp .+28 ; 0x3f98 <main+0x198> #endif
/* main program starts here */
int main(void) {
3f66: 08 94 sec
3f68: c1 1c adc r12, r1
3f6a: d1 1c adc r13, r1
3f6c: fa 94 dec r15
3f6e: cf 0c add r12, r15
3f70: d1 1c adc r13, r1
3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190>
#endif #endif
#endif #endif
} }
/* Get device signature bytes */ /* Get device signature bytes */
else if(ch == STK_READ_SIGN) { else if(ch == STK_READ_SIGN) {
3f7c: 85 37 cpi r24, 0x75 ; 117 3f74: 85 37 cpi r24, 0x75 ; 117
3f7e: 39 f4 brne .+14 ; 0x3f8e <main+0x18e> 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186>
// READ SIGN - return what Avrdude wants to hear // READ SIGN - return what Avrdude wants to hear
verifySpace(); verifySpace();
3f80: 2e d0 rcall .+92 ; 0x3fde <verifySpace> 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace>
putch(SIGNATURE_0); putch(SIGNATURE_0);
3f82: 8e e1 ldi r24, 0x1E ; 30 3f7a: 8e e1 ldi r24, 0x1E ; 30
3f84: 0c d0 rcall .+24 ; 0x3f9e <putch> 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch>
putch(SIGNATURE_1); putch(SIGNATURE_1);
3f86: 84 e9 ldi r24, 0x94 ; 148 3f7e: 84 e9 ldi r24, 0x94 ; 148
3f88: 0a d0 rcall .+20 ; 0x3f9e <putch> 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch>
putch(SIGNATURE_2); putch(SIGNATURE_2);
3f8a: 86 e0 ldi r24, 0x06 ; 6 3f82: 86 e0 ldi r24, 0x06 ; 6
3f8c: 8b cf rjmp .-234 ; 0x3ea4 <main+0xa4> 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a>
} }
else if (ch == 'Q') { else if (ch == 'Q') {
3f8e: 81 35 cpi r24, 0x51 ; 81 3f86: 81 35 cpi r24, 0x51 ; 81
3f90: 11 f4 brne .+4 ; 0x3f96 <main+0x196> 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e>
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); watchdogConfig(WATCHDOG_16MS);
3f92: 88 e0 ldi r24, 0x08 ; 8 3f8a: 88 e0 ldi r24, 0x08 ; 8
3f94: 19 d0 rcall .+50 ; 0x3fc8 <watchdogConfig> 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig>
verifySpace(); verifySpace();
} }
else { else {
// This covers the response to commands like STK_ENTER_PROGMODE // This covers the response to commands like STK_ENTER_PROGMODE
verifySpace(); verifySpace();
3f96: 23 d0 rcall .+70 ; 0x3fde <verifySpace> 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace>
} }
putch(STK_OK); putch(STK_OK);
3f98: 80 e1 ldi r24, 0x10 ; 16 3f90: 80 e1 ldi r24, 0x10 ; 16
3f9a: 01 d0 rcall .+2 ; 0x3f9e <putch> 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch>
3f9c: 5c cf rjmp .-328 ; 0x3e56 <main+0x56> 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60>
00003f9e <putch>: 00003f96 <putch>:
} }
} }
void putch(char ch) { void putch(char ch) {
3f9e: 98 2f mov r25, r24 3f96: 98 2f mov r25, r24
#ifndef SOFT_UART #ifndef SOFT_UART
while (!(UCSR0A & _BV(UDRE0))); while (!(UCSR0A & _BV(UDRE0)));
3fa0: 80 91 c0 00 lds r24, 0x00C0 3f98: 80 91 c0 00 lds r24, 0x00C0
3fa4: 85 ff sbrs r24, 5 3f9c: 85 ff sbrs r24, 5
3fa6: fc cf rjmp .-8 ; 0x3fa0 <putch+0x2> 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2>
UDR0 = ch; UDR0 = ch;
3fa8: 90 93 c6 00 sts 0x00C6, r25 3fa0: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT) [uartBit] "I" (UART_TX_BIT)
: :
"r25" "r25"
); );
#endif #endif
} }
3fac: 08 95 ret 3fa4: 08 95 ret
00003fae <getch>: 00003fa6 <getch>:
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fae: a8 95 wdr
[uartBit] "I" (UART_RX_BIT) [uartBit] "I" (UART_RX_BIT)
: :
"r25" "r25"
); );
#else #else
while(!(UCSR0A & _BV(RXC0))); while(!(UCSR0A & _BV(RXC0)))
3fb0: 80 91 c0 00 lds r24, 0x00C0 3fa6: 80 91 c0 00 lds r24, 0x00C0
3fb4: 87 ff sbrs r24, 7 3faa: 87 ff sbrs r24, 7
3fb6: fc cf rjmp .-8 ; 0x3fb0 <getch+0x2> 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch>
;
if (!(UCSR0A & _BV(FE0))) {
3fae: 80 91 c0 00 lds r24, 0x00C0
3fb2: 84 fd sbrc r24, 4
3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
3fb6: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0; ch = UDR0;
3fb8: 80 91 c6 00 lds r24, 0x00C6 3fb8: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED); LED_PIN |= _BV(LED);
@@ -474,79 +526,73 @@ void watchdogReset() {
} }
3fbc: 08 95 ret 3fbc: 08 95 ret
00003fbe <getLen>: 00003fbe <watchdogConfig>:
} while (--count);
}
#endif
uint8_t getLen() {
getch();
3fbe: f7 df rcall .-18 ; 0x3fae <getch>
length = getch();
3fc0: f6 df rcall .-20 ; 0x3fae <getch>
3fc2: 80 93 02 02 sts 0x0202, r24
return getch();
}
3fc6: f3 cf rjmp .-26 ; 0x3fae <getch>
00003fc8 <watchdogConfig>:
"wdr\n" "wdr\n"
); );
} }
void watchdogConfig(uint8_t x) { void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDCE) | _BV(WDE);
3fc8: e0 e6 ldi r30, 0x60 ; 96 3fbe: e0 e6 ldi r30, 0x60 ; 96
3fca: f0 e0 ldi r31, 0x00 ; 0 3fc0: f0 e0 ldi r31, 0x00 ; 0
3fcc: 98 e1 ldi r25, 0x18 ; 24 3fc2: 98 e1 ldi r25, 0x18 ; 24
3fce: 90 83 st Z, r25 3fc4: 90 83 st Z, r25
WDTCSR = x; WDTCSR = x;
3fd0: 80 83 st Z, r24 3fc6: 80 83 st Z, r24
} }
3fd2: 08 95 ret 3fc8: 08 95 ret
00003fd4 <appStart>: 00003fca <verifySpace>:
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fd4: 80 e0 ldi r24, 0x00 ; 0
3fd6: f8 df rcall .-16 ; 0x3fc8 <watchdogConfig>
__asm__ __volatile__ (
3fd8: ee 27 eor r30, r30
3fda: ff 27 eor r31, r31
3fdc: 09 94 ijmp
00003fde <verifySpace>:
do getch(); while (--count); do getch(); while (--count);
verifySpace(); verifySpace();
} }
void verifySpace() { void verifySpace() {
if (getch() != CRC_EOP) appStart(); if (getch() != CRC_EOP) {
3fde: e7 df rcall .-50 ; 0x3fae <getch> 3fca: ed df rcall .-38 ; 0x3fa6 <getch>
3fe0: 80 32 cpi r24, 0x20 ; 32 3fcc: 80 32 cpi r24, 0x20 ; 32
3fe2: 09 f0 breq .+2 ; 0x3fe6 <verifySpace+0x8> 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc>
3fe4: f7 df rcall .-18 ; 0x3fd4 <appStart> watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
3fd0: 88 e0 ldi r24, 0x08 ; 8
3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig>
3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC); putch(STK_INSYNC);
3fe6: 84 e1 ldi r24, 0x14 ; 20 3fd6: 84 e1 ldi r24, 0x14 ; 20
} }
3fe8: da cf rjmp .-76 ; 0x3f9e <putch> 3fd8: de cf rjmp .-68 ; 0x3f96 <putch>
00003fea <getNch>: 00003fda <getNch>:
::[count] "M" (UART_B_VALUE) ::[count] "M" (UART_B_VALUE)
); );
} }
#endif #endif
void getNch(uint8_t count) { void getNch(uint8_t count) {
3fea: 1f 93 push r17 3fda: 1f 93 push r17
3fec: 18 2f mov r17, r24 3fdc: 18 2f mov r17, r24
do getch(); while (--count); do getch(); while (--count);
3fee: df df rcall .-66 ; 0x3fae <getch> 3fde: e3 df rcall .-58 ; 0x3fa6 <getch>
3ff0: 11 50 subi r17, 0x01 ; 1 3fe0: 11 50 subi r17, 0x01 ; 1
3ff2: e9 f7 brne .-6 ; 0x3fee <getNch+0x4> 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4>
verifySpace(); verifySpace();
3ff4: f4 df rcall .-24 ; 0x3fde <verifySpace> 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace>
} }
3ff6: 1f 91 pop r17 3fe6: 1f 91 pop r17
3ff8: 08 95 ret 3fe8: 08 95 ret
00003fea <appStart>:
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
}
void appStart() {
watchdogConfig(WATCHDOG_OFF);
3fea: 80 e0 ldi r24, 0x00 ; 0
3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig>
__asm__ __volatile__ (
3fee: ee 27 eor r30, r30
3ff0: ff 27 eor r31, r31
3ff2: 09 94 ijmp

View File

@@ -21,6 +21,7 @@
#define UDR0 UDR #define UDR0 UDR
#define UDRE0 UDRE #define UDRE0 UDRE
#define RXC0 RXC #define RXC0 RXC
#define FE0 FE
#define TIFR1 TIFR #define TIFR1 TIFR
#define WDTCSR WDTCR #define WDTCSR WDTCR
#endif #endif