1
0
mirror of https://github.com/Optiboot/optiboot.git synced 2025-09-04 12:02:07 +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 = optiboot
# The default behavior is to build using tools that are in the users
# current path variables, but we can also build using an installed
# Arduino user IDE setup, or the Arduino source tree.
# Uncomment this next lines to build within the arduino environment,
# using the arduino-included avrgcc toolset (mac and pc)
# ENV ?= arduino
# ENV ?= arduinodev
# OS ?= macosx
# OS ?= windows
# enter the parameters for the avrdude isp tool
ISPTOOL = stk500v2
ISPPORT = usb
ISPSPEED = -b 115200
MCU_TARGET = atmega168
LDSECTION = --section-start=.text=0x3e00
LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
# Build environments
# Start of some ugly makefile-isms to allow optiboot to be built
# in several different environments. See the README.TXT file for
# details.
# default
fixpath = $(1)
ifeq ($(ENV), arduino)
# For Arduino, we assume that we're connected to the optiboot directory
# included with the arduino distribution, which means that the full set
# of avr-tools are "right up there" in standard places.
TOOLROOT = ../../../tools
GCCROOT = $(TOOLROOT)/avr/bin/
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
ifeq ($(OS), windows)
# On windows, SOME of the tool paths will need to have backslashes instead
# of forward slashes (because they use windows cmd.exe for execution instead
# of a unix/mingw shell?) We also have to ensure that a consistent shell
# is used even if a unix shell is installed (ie as part of WINAVR)
fixpath = $(subst /,\,$1)
SHELL = cmd.exe
endif
else ifeq ($(ENV), arduinodev)
# Arduino IDE source code environment. Use the unpacked compilers created
# by the build (you'll need to do "ant build" first.)
ifeq ($(OS), macosx)
TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
endif
ifeq ($(OS), windows)
TOOLROOT = ../../../../build/windows/work/hardware/tools
endif
GCCROOT = $(TOOLROOT)/avr/bin/
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
else
GCCROOT =
AVRDUDE_CONF =
endif
#
# End of build environment code.
# the efuse should really be 0xf8; since, however, only the lower
# three bits of that byte are used on the atmega168, avrdude gets
@@ -33,14 +90,17 @@ LDSECTION = --section-start=.text=0x3e00
# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
#
# similarly, the lock bits should be 0xff instead of 0x3f (to
# unlock the bootloader section) and 0xcf instead of 0x0f (to
# unlock the bootloader section) and 0xcf instead of 0x2f (to
# lock it), but since the high two bits of the lock byte are
# unused, avrdude would get confused.
ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m
ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
@@ -53,23 +113,25 @@ OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls
DEFS =
LIBS =
CC = avr-gcc
CC = $(GCCROOT)avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles -Wl,--gc-sections
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
OBJCOPY = $(GCCROOT)avr-objcopy
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
SIZE = $(GCCROOT)avr-size
# Test platforms
# Virtual boot block test
virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT'
virboot328: AVR_FREQ = 16000000L
virboot328: LDSECTION = --section-start=.text=0x7e00
virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
virboot328: $(PROGRAM)_atmega328.hex
virboot328: $(PROGRAM)_atmega328.lst
@@ -84,6 +146,7 @@ pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro20: AVR_FREQ = 20000000L
pro20: $(PROGRAM)_pro_20mhz.hex
pro20: $(PROGRAM)_pro_20mhz.lst
pro20_isp: pro20
pro20_isp: TARGET = pro_20mhz
# 2.7V brownout
@@ -105,6 +168,7 @@ pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro16: AVR_FREQ = 16000000L
pro16: $(PROGRAM)_pro_16MHz.hex
pro16: $(PROGRAM)_pro_16MHz.lst
pro16_isp: pro16
pro16_isp: TARGET = pro_16MHz
# 2.7V brownout
@@ -115,13 +179,34 @@ pro16_isp: LFUSE = C6
pro16_isp: EFUSE = 04
pro16_isp: isp
# Diecimila and NG use identical bootloaders
# Diecimila, Duemilanove with m168, and NG use identical bootloaders
# Call it "atmega168" for generality and clarity, keep "diecimila" for
# backward compatibility of makefile
#
atmega168: TARGET = atmega168
atmega168: MCU_TARGET = atmega168
atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega168: AVR_FREQ = 16000000L
atmega168: $(PROGRAM)_atmega168.hex
atmega168: $(PROGRAM)_atmega168.lst
atmega168_isp: atmega168
atmega168_isp: TARGET = atmega168
# 2.7V brownout
atmega168_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega168_isp: LFUSE = FF
# 512 byte boot
atmega168_isp: EFUSE = 04
atmega168_isp: isp
diecimila: TARGET = diecimila
diecimila: MCU_TARGET = atmega168
diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
diecimila: AVR_FREQ = 16000000L
diecimila: $(PROGRAM)_diecimila.hex
diecimila: $(PROGRAM)_diecimila.lst
diecimila_isp: diecimila
diecimila_isp: TARGET = diecimila
# 2.7V brownout
@@ -136,13 +221,14 @@ atmega328: TARGET = atmega328
atmega328: MCU_TARGET = atmega328p
atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328: AVR_FREQ = 16000000L
atmega328: LDSECTION = --section-start=.text=0x7e00
atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
atmega328: $(PROGRAM)_atmega328.hex
atmega328: $(PROGRAM)_atmega328.lst
atmega328_isp: atmega328
atmega328_isp: TARGET = atmega328
atmega328_isp: MCU_TARGET = atmega328p
# 512 byte boot
# 512 byte boot, SPIEN
atmega328_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_isp: LFUSE = FF
@@ -151,13 +237,15 @@ atmega328_isp: EFUSE = 05
atmega328_isp: isp
# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
#
sanguino: TARGET = atmega644p
sanguino: MCU_TARGET = atmega644p
sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
sanguino: AVR_FREQ = 16000000L
sanguino: LDSECTION = --section-start=.text=0xfc00
sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00
sanguino: $(PROGRAM)_atmega644p.hex
sanguino: $(PROGRAM)_atmega644p.lst
sanguino_isp: sanguino
sanguino_isp: TARGET = atmega644p
sanguino_isp: MCU_TARGET = atmega644p
@@ -170,13 +258,14 @@ sanguino_isp: EFUSE = 05
sanguino_isp: isp
# Mega has a minimum boot size of 1024 bytes, so enable extra functions
mega: TARGET = atmega1280
#mega: TARGET = atmega1280
mega: MCU_TARGET = atmega1280
mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
mega: AVR_FREQ = 16000000L
mega: LDSECTION = --section-start=.text=0x1fc00
mega: LDSECTIONS = -Wl,--section-start=.text=0x1fc00
mega: $(PROGRAM)_atmega1280.hex
mega: $(PROGRAM)_atmega1280.lst
mega_isp: mega
mega_isp: TARGET = atmega1280
mega_isp: MCU_TARGET = atmega1280
@@ -194,25 +283,29 @@ atmega8: TARGET = atmega8
atmega8: MCU_TARGET = atmega8
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega8: AVR_FREQ = 16000000L
atmega8: LDSECTION = --section-start=.text=0x1e00
atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
atmega8: $(PROGRAM)_atmega8.hex
atmega8: $(PROGRAM)_atmega8.lst
atmega8_isp: atmega8
atmega8_isp: TARGET = atmega8
atmega8_isp: MCU_TARGET = atmega8
# 2.7V brownout
atmega8_isp: HFUSE = DC
# Low power xtal (16MHz) 16KCK/14CK+65ms
# SPIEN, CKOPT, Bootsize=512B
atmega8_isp: HFUSE = CC
# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
atmega8_isp: LFUSE = BF
atmega8_isp: isp
# ATmega88
#
atmega88: TARGET = atmega88
atmega88: MCU_TARGET = atmega88
atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega88: AVR_FREQ = 16000000L
atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
atmega88: $(PROGRAM)_atmega88.hex
atmega88: $(PROGRAM)_atmega88.lst
atmega88_isp: atmega88
atmega88_isp: TARGET = atmega88
atmega88_isp: MCU_TARGET = atmega88
@@ -224,6 +317,7 @@ atemga88_isp: LFUSE = FF
atmega88_isp: EFUSE = 04
atmega88_isp: isp
# 8MHz clocked platforms
#
# These are capable of 115200 baud
@@ -235,6 +329,7 @@ lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
lilypad: AVR_FREQ = 8000000L
lilypad: $(PROGRAM)_lilypad.hex
lilypad: $(PROGRAM)_lilypad.lst
lilypad_isp: lilypad
lilypad_isp: TARGET = lilypad
# 2.7V brownout
@@ -242,7 +337,7 @@ lilypad_isp: HFUSE = DD
# Internal 8MHz osc (8MHz) Slow rising power
lilypad_isp: LFUSE = E2
# 512 byte boot
lilypad_isp: EFUSE = 02
lilypad_isp: EFUSE = 04
lilypad_isp: isp
lilypad_resonator: TARGET = lilypad_resonator
@@ -251,6 +346,7 @@ lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
lilypad_resonator: AVR_FREQ = 8000000L
lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
lilypad_resonator_isp: lilypad_resonator
lilypad_resonator_isp: TARGET = lilypad_resonator
# 2.7V brownout
@@ -258,7 +354,7 @@ lilypad_resonator_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
lilypad_resonator_isp: LFUSE = C6
# 512 byte boot
lilypad_resonator_isp: EFUSE = 02
lilypad_resonator_isp: EFUSE = 04
lilypad_resonator_isp: isp
pro8: TARGET = pro_8MHz
@@ -267,6 +363,7 @@ pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
pro8: AVR_FREQ = 8000000L
pro8: $(PROGRAM)_pro_8MHz.hex
pro8: $(PROGRAM)_pro_8MHz.lst
pro8_isp: pro8
pro8_isp: TARGET = pro_8MHz
# 2.7V brownout
@@ -274,20 +371,21 @@ pro8_isp: HFUSE = DD
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
pro8_isp: LFUSE = C6
# 512 byte boot
pro8_isp: EFUSE = 02
pro8_isp: EFUSE = 04
pro8_isp: isp
atmega328_pro8: TARGET = atmega328_pro_8MHz
atmega328_pro8: MCU_TARGET = atmega328p
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328_pro8: AVR_FREQ = 8000000L
atmega328_pro8: LDSECTION = --section-start=.text=0x7e00
atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
atmega328_pro8_isp: atmega328_pro8
atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
atmega328_pro8_isp: MCU_TARGET = atmega328p
# 512 byte boot
# 512 byte boot, SPIEN
atmega328_pro8_isp: HFUSE = DE
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega328_pro8_isp: LFUSE = FF
@@ -305,9 +403,10 @@ luminet: MCU_TARGET = attiny84
luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
luminet: AVR_FREQ = 1000000L
luminet: LDSECTION = --section-start=.text=0x1d00
luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
luminet: $(PROGRAM)_luminet.hex
luminet: $(PROGRAM)_luminet.lst
luminet_isp: luminet
luminet_isp: TARGET = luminet
luminet_isp: MCU_TARGET = attiny84
@@ -334,6 +433,7 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex
%.elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
$(SIZE) $@
clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
@@ -342,10 +442,10 @@ clean:
$(OBJDUMP) -h -S $< > $@
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@

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
make clean
#
# The "big three" standard bootloaders.
make atmega8
make atmega168
make atmega328
#
# additional buildable platforms of
# somewhat questionable support level
make lilypad
make lilypad_resonator
make pro8
make pro16
make pro20
make diecimila
make atmega328
make atmega328_pro8
make sanguino
make mega
make atmega8
make atmega88
make luminet

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 */
/* */
/* Arduino-maintained version : See README.TXT */
/* http://code.google.com/p/arduino/ */
/* */
/* Heavily optimised bootloader that is faster and */
/* smaller than the Arduino standard bootloader */
/* */
@@ -111,7 +114,45 @@
/* 500,1000,2000,4000,8000 supported. */
/* */
/**********************************************************/
/**********************************************************/
/* Version Numbers! */
/* */
/* Arduino Optiboot now includes this Version number in */
/* the source and object code. */
/* */
/* Version 3 was released as zip from the optiboot */
/* repository and was distributed with Arduino 0022. */
/* Version 4 starts with the arduino repository commit */
/* that brought the arduino repository up-to-date with */
/* the optiboot source tree changes since v3. */
/* */
/**********************************************************/
/**********************************************************/
/* Edit History: */
/* */
/* 4.4 WestfW: add initialization of address to keep */
/* the compiler happy. Change SC'ed targets. */
/* Return the SW version via READ PARAM */
/* 4.3 WestfW: catch framing errors in getch(), so that */
/* AVRISP works without HW kludges. */
/* http://code.google.com/p/arduino/issues/detail?id=368n*/
/* 4.2 WestfW: reduce code size, fix timeouts, change */
/* verifySpace to use WDT instead of appstart */
/* 4.1 WestfW: put version number in binary. */
/**********************************************************/
#define OPTIBOOT_MAJVER 4
#define OPTIBOOT_MINVER 4
#define MAKESTR(a) #a
#define MAKEVER(a, b) MAKESTR(a*256+b)
asm(" .section .version\n"
"optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
" .section .text\n");
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
@@ -120,6 +161,7 @@
// This saves cycles and program memory.
#include "boot.h"
// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
#include "pin_defs.h"
@@ -164,8 +206,8 @@
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
#ifndef __AVR_ATmega8__
#define WATCHDOG_4S (_BV(WDE3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDE3) | _BV(WDE0) | _BV(WDE))
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
#endif
/* Function Prototypes */
@@ -210,8 +252,6 @@ void appStart() __attribute__ ((naked));
/* These definitions are NOT zero initialised, but that doesn't matter */
/* This allows us to drop the zero init code, saving us memory */
#define buff ((uint8_t*)(RAMSTART))
#define address (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2))
#define length (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+2))
#ifdef VIRTUAL_BOOT_PARTITION
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
@@ -219,6 +259,17 @@ void appStart() __attribute__ ((naked));
/* main program starts here */
int main(void) {
uint8_t ch;
/*
* Making these local and in registers prevents the need for initializing
* them, and also saves space because code no longer stores to memory.
* (initializing address keeps the compiler happy, but isn't really
* necessary, and uses 4 bytes of flash.)
*/
register uint16_t address = 0;
register uint8_t length;
// After the zero init loop, this is the first code to run.
//
// This code makes the following assumptions:
@@ -228,15 +279,11 @@ int main(void) {
//
// If not, uncomment the following instructions:
// cli();
asm volatile ("clr __zero_reg__");
#ifdef __AVR_ATmega8__
SP=RAMEND; // This is done by hardware reset
#endif
// asm volatile ("clr __zero_reg__");
uint8_t ch;
// Adaboot no-wait mod
ch = MCUSR;
MCUSR = 0;
@@ -282,9 +329,22 @@ int main(void) {
ch = getch();
if(ch == STK_GET_PARAMETER) {
// GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
getNch(1);
putch(0x03);
unsigned char which = getch();
verifySpace();
if (which == 0x82) {
/*
* Send optiboot version as "minor SW version"
*/
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
putch(OPTIBOOT_MAJVER);
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
}
}
else if(ch == STK_SET_DEVICE) {
// SET DEVICE is ignored
@@ -318,11 +378,13 @@ int main(void) {
uint8_t *bufPtr;
uint16_t addrPtr;
getLen();
getch(); /* getlen() */
length = getch();
getch();
// If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
// While that is going on, read in page contents
bufPtr = buff;
do *bufPtr++ = getch();
@@ -334,7 +396,7 @@ int main(void) {
// Read command terminator, start reply
verifySpace();
// If only a partial page is to be programmed, the erase might not be complete.
// So check that here
boot_spm_busy_wait();
@@ -369,7 +431,7 @@ int main(void) {
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
addrPtr += 2;
} while (--ch);
// Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address);
boot_spm_busy_wait();
@@ -383,7 +445,10 @@ int main(void) {
/* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) {
// READ PAGE - we only read flash
getLen();
getch(); /* getlen() */
length = getch();
getch();
verifySpace();
#ifdef VIRTUAL_BOOT_PARTITION
do {
@@ -468,8 +533,6 @@ void putch(char ch) {
uint8_t getch(void) {
uint8_t ch;
watchdogReset();
#ifdef LED_DATA_FLASH
#ifdef __AVR_ATmega8__
LED_PORT ^= _BV(LED);
@@ -487,7 +550,7 @@ uint8_t getch(void) {
" rcall uartDelay\n" // Wait 1 bit period
" clc\n"
" sbic %[uartPin],%[uartBit]\n"
" sec\n"
" sec\n"
" dec %[bitCnt]\n"
" breq 3f\n"
" ror %[ch]\n"
@@ -503,7 +566,20 @@ uint8_t getch(void) {
"r25"
);
#else
while(!(UCSR0A & _BV(RXC0)));
while(!(UCSR0A & _BV(RXC0)))
;
if (!(UCSR0A & _BV(FE0))) {
/*
* A Framing Error indicates (probably) that something is talking
* to us at the wrong bit rate. Assume that this is because it
* expects to be talking to the application, and DON'T reset the
* watchdog. This should cause the bootloader to abort and run
* the application "soon", if it keeps happening. (Note that we
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UDR0;
#endif
@@ -543,7 +619,11 @@ void getNch(uint8_t count) {
}
void verifySpace() {
if (getch() != CRC_EOP) appStart();
if (getch() != CRC_EOP) {
watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC);
}
@@ -563,12 +643,6 @@ void flash_led(uint8_t count) {
}
#endif
uint8_t getLen() {
getch();
length = getch();
return getch();
}
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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