From 762613bd7f0ca91752e3d59b0dc72ff23e0609fc Mon Sep 17 00:00:00 2001 From: midelic Date: Fri, 1 Dec 2017 04:29:00 +0200 Subject: [PATCH] Add files via upload --- .../OrangeMultiBoot/OrangeMultiBoot.hex | 47 + BootLoaders/OrangeMultiBoot/Source/Makefile | 503 +++++++++ BootLoaders/OrangeMultiBoot/Source/optiboot.c | 980 ++++++++++++++++++ BootLoaders/OrangeMultiBoot/Source/pin_defs.h | 80 ++ BootLoaders/OrangeMultiBoot/Source/stk500.h | 39 + BootLoaders/StmMultiBoot/README.md | 1 + BootLoaders/StmMultiBoot/StmMultiBoot.bin | Bin 0 -> 7788 bytes BootLoaders/StmMultiUSB/README.md | 2 + BootLoaders/StmMultiUSB/StmMultiUSB.bin | Bin 0 -> 7184 bytes 9 files changed, 1652 insertions(+) create mode 100644 BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex create mode 100644 BootLoaders/OrangeMultiBoot/Source/Makefile create mode 100644 BootLoaders/OrangeMultiBoot/Source/optiboot.c create mode 100644 BootLoaders/OrangeMultiBoot/Source/pin_defs.h create mode 100644 BootLoaders/OrangeMultiBoot/Source/stk500.h create mode 100644 BootLoaders/StmMultiBoot/README.md create mode 100644 BootLoaders/StmMultiBoot/StmMultiBoot.bin create mode 100644 BootLoaders/StmMultiUSB/README.md create mode 100644 BootLoaders/StmMultiUSB/StmMultiUSB.bin diff --git a/BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex b/BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex new file mode 100644 index 0000000..1d7eb24 --- /dev/null +++ b/BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex @@ -0,0 +1,47 @@ +:108000001F92CDB7DEB7CFD01124809178009FEFBB +:1080100090937800837099F088EA91E680936808DD +:108020009093690880E180934C0880914C0884FF0C +:10803000FCCF109240088091680682FD8FD082E0CC +:1080400080936106C12CD12C97D0813479F494D0DF +:10805000898399D08981823811F485E005C08138FF +:1080600011F484E001C083E080D075C0823411F443 +:1080700084E103C0853419F485E08CD06CC085356B +:1080800059F47AD0C82E78D0D12CD82A8D2D881FBB +:108090008827881F8BBF5EC0863521F484E07AD0A4 +:1080A00080E0E2CF843641F567D066D0F82E64D008 +:1080B000C601DCD000E010E25FD0F80181938F01AF +:1080C000FE12FACF60D0D7FC46C0CBD0C601DAD0C2 +:1080D000760100E010E2F801619171918F01C70112 +:1080E000DBD0F2E0EF0EF11C011581E2180799F7E1 +:1080F000C601E0D0B6D02FC08437C1F43DD03CD00B +:10810000F82E3AD040D0F601EC2CEF0C8F010F5F27 +:108110001F4F84912AD0E01207C0EFEFCE1ADE0A7B +:10812000FA94CF0CD11C17C0F801F0CF853739F481 +:108130002AD08EE11AD085E918D082E495CF813516 +:1081400049F421D080E111D08091A10886FFFCCFB5 +:1081500005D001C018D080E108D076CFE0E0F0E093 +:1081600084918F3F09F0099408959091A10895FF9B +:10817000FCCF8093A00808958091A10887FFFCCFD1 +:108180008091A0080895F8DF803211F085E1EDDFDD +:1081900084E1EBCFCF93C82FEFDFC150E9F7CF9148 +:1081A000F2CFA895089583EC8093520080915000FF +:1081B0008860809350008091510083FFFCCF82EC57 +:1081C0008093550080915000806180935000809191 +:1081D000510084FFFCCF88ED84BF1092400084BF23 +:1081E00024E02093400087E08093A20087E88093FA +:1081F0008301109241081092420810924308109295 +:10820000440810924608109247088FEF9FEF809322 +:1082100066089093670810926008109261088BE0DE +:1082200080934008209365062093620688E180933E +:10823000720698E0909345069093410692E29093DF +:10824000A6081092A7088093A4088091A3088F7CA9 +:1082500080618093A30883E08093A5088091A008A3 +:1082600008958091CF0187FDFCCF08958F939F9350 +:1082700082E2E0ECF1E08287FF91EF918DE984BF2B +:10828000E8950895FC0186E28093CA0188ED84BFD9 +:1082900081E08093CB0108950F921F92FC01062E7E +:1082A000172E83E28093CA018DE984BFE8951F9061 +:1082B0000F900895FC018EE28093CA018DE984BF7E +:0482C000E8950895A0 +:040000030000800079 +:00000001FF diff --git a/BootLoaders/OrangeMultiBoot/Source/Makefile b/BootLoaders/OrangeMultiBoot/Source/Makefile new file mode 100644 index 0000000..0797343 --- /dev/null +++ b/BootLoaders/OrangeMultiBoot/Source/Makefile @@ -0,0 +1,503 @@ +# Makefile for ATmegaBOOT +# E.Lins, 18.7.2005 +# $Id$ +# +# Instructions +# +# To make bootloader .hex file: +# make diecimila +# make lilypad +# make ng +# etc... +# +# To burn bootloader .hex file: +# make diecimila_isp +# make lilypad_isp +# make ng_isp +# etc... + +# 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 -b19200 +# +# These are the parameters for a usb-based STK500v2 programmer. +# Exact type unknown. (historical Makefile values.) +ISPTOOL = stk500v2 +ISPPORT = usb +ISPSPEED = -b 57600 +# +# +# These are parameters for using an Arduino with the ArduinoISP sketch +# as the programmer. On a mac, for a particular Uno as programmer. +#ISPTOOL = stk500v1 -C /Applications/arduino/arduino-0022/hardware/tools/avr/etc/avrdude.conf +#ISPPORT = /dev/tty.usbmodemfd3141 +#ISPSPEED = -b19200 + +MCU_TARGET = atmega168 +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 +# confused if you specify 1's for the higher bits, see: +# 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 0x2f (to +# lock it), but since the high two bits of the lock byte are +# unused, avrdude would get confused. + +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 \ +-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt +STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt + +OBJ = $(PROGRAM).o +OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types +# -mshort-calls + +DEFS = +LIBS = + +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 = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib + +OBJCOPY = $(GCCROOT)avr-objcopy +OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump) + +SIZE = $(GCCROOT)avr-size + + + +#Voice board test +# ATmega328 +# +#atmega328: TARGET = atmega328p +#atmega328: MCU_TARGET = atmega328p +#atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400' +#atmega328: AVR_FREQ = 12000000L +#atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe +#atmega328: $(PROGRAM)_atmega328.hex +#atmega328: $(PROGRAM)_atmega328.lst + +xmega32D4: TARGET = atxmega32d4 +xmega32D4: MCU_TARGET = atxmega32d4 +xmega32D4: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600' +xmega32D4: AVR_FREQ = 32000000L +xmega32D4: LDSECTIONS = -Wl,--section-start=.text=0x8000 +xmega32D4: $(PROGRAM)_xmega32d4.hex +xmega32D4: $(PROGRAM)_xmega32d4.lst + +atmega328: TARGET = atmega328 +atmega328: MCU_TARGET = atmega328p +atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600' +atmega328: AVR_FREQ = 16000000L +atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe +atmega328: $(PROGRAM)_atmega328_16.hex +atmega328: $(PROGRAM)_atmega328_16.lst + + +# Test platforms +# Virtual boot block test +virboot328: TARGET = atmega328 +virboot328: MCU_TARGET = atmega328p +virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DVIRTUAL_BOOT' +virboot328: AVR_FREQ = 16000000L +virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe +virboot328: $(PROGRAM)_atmega328.hex +virboot328: $(PROGRAM)_atmega328.lst + +# 20MHz clocked platforms +# +# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue) +# + +pro20: TARGET = pro_20mhz +pro20: MCU_TARGET = atmega168 +pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +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 +pro20_isp: HFUSE = DD +# Full swing xtal (20MHz) 258CK/14CK+4.1ms +pro20_isp: LFUSE = C6 +# 512 byte boot +pro20_isp: EFUSE = 04 +pro20_isp: isp + +# 16MHz clocked platforms +# +# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue) +# + +pro16: TARGET = pro_16MHz +pro16: MCU_TARGET = atmega168 +pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +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 +pro16_isp: HFUSE = DD +# Full swing xtal (20MHz) 258CK/14CK+4.1ms +pro16_isp: LFUSE = C6 +# 512 byte boot +pro16_isp: EFUSE = 04 +pro16_isp: isp + +# 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=0' '-DBAUD_RATE=38400' +atmega168: AVR_FREQ = 12000000L +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=38400' +diecimila: AVR_FREQ = 16000000L +diecimila: $(PROGRAM)_diecimila.hex +diecimila: $(PROGRAM)_diecimila.lst + +diecimila_isp: diecimila +diecimila_isp: TARGET = diecimila +# 2.7V brownout +diecimila_isp: HFUSE = DD +# Low power xtal (16MHz) 16KCK/14CK+65ms +diecimila_isp: LFUSE = FF +# 512 byte boot +diecimila_isp: EFUSE = 04 +diecimila_isp: isp + +atmega328_isp: atmega328 +atmega328_isp: TARGET = atmega328 +atmega328_isp: MCU_TARGET = atmega328p +# 512 byte boot, SPIEN +atmega328_isp: HFUSE = DE +# Low power xtal (16MHz) 16KCK/14CK+65ms +atmega328_isp: LFUSE = FF +# 2.7V brownout +atmega328_isp: EFUSE = FD +atmega328_isp: isp + +atmega1284: TARGET = atmega1284p +atmega1284: MCU_TARGET = atmega1284p +atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT' +atmega1284: AVR_FREQ = 16000000L +atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe +atmega1284: $(PROGRAM)_atmega1284p.hex +atmega1284: $(PROGRAM)_atmega1284p.lst + +atmega1284_isp: atmega1284 +atmega1284_isp: TARGET = atmega1284p +atmega1284_isp: MCU_TARGET = atmega1284p +# 1024 byte boot +atmega1284_isp: HFUSE = DE +# Low power xtal (16MHz) 16KCK/14CK+65ms +atmega1284_isp: LFUSE = FF +# 2.7V brownout +atmega1284_isp: EFUSE = FD +atmega1284_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=38400' '-DBIGBOOT' +sanguino: AVR_FREQ = 16000000L +sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe +sanguino: $(PROGRAM)_atmega644p.hex +sanguino: $(PROGRAM)_atmega644p.lst + +sanguino_isp: sanguino +sanguino_isp: TARGET = atmega644p +sanguino_isp: MCU_TARGET = atmega644p +# 1024 byte boot +sanguino_isp: HFUSE = DE +# Low power xtal (16MHz) 16KCK/14CK+65ms +sanguino_isp: LFUSE = FF +# 2.7V brownout +sanguino_isp: EFUSE = FD +sanguino_isp: isp + +# Mega has a minimum boot size of 1024 bytes, so enable extra functions +#mega: TARGET = atmega1280 +mega1280: MCU_TARGET = atmega1280 +mega1280: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT' +mega1280: AVR_FREQ = 16000000L +mega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe +mega1280: $(PROGRAM)_atmega1280.hex +mega1280: $(PROGRAM)_atmega1280.lst + +mega1280_isp: mega +mega1280_isp: TARGET = atmega1280 +mega1280_isp: MCU_TARGET = atmega1280 +# 1024 byte boot +mega1280_isp: HFUSE = DE +# Low power xtal (16MHz) 16KCK/14CK+65ms +mega1280_isp: LFUSE = FF +# 2.7V brownout +mega1280_isp: EFUSE = FD +mega1280_isp: isp + +# ATmega8 +# +atmega8: TARGET = atmega8 +atmega8: MCU_TARGET = atmega8 +atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +atmega8: AVR_FREQ = 16000000L +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 +# 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=0' '-DBAUD_RATE=38400' +atmega88: AVR_FREQ = 12000000L +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 +# 2.7V brownout +atmega88_isp: HFUSE = DD +# Low power xtal (16MHz) 16KCK/14CK+65ms +atemga88_isp: LFUSE = FF +# 512 byte boot +atmega88_isp: EFUSE = 04 +atmega88_isp: isp + + +# 8MHz clocked platforms +# +# These are capable of 38400 baud +# + +lilypad: TARGET = lilypad +lilypad: MCU_TARGET = atmega168 +lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +lilypad: AVR_FREQ = 8000000L +lilypad: $(PROGRAM)_lilypad.hex +lilypad: $(PROGRAM)_lilypad.lst + +lilypad_isp: lilypad +lilypad_isp: TARGET = lilypad +# 2.7V brownout +lilypad_isp: HFUSE = DD +# Internal 8MHz osc (8MHz) Slow rising power +lilypad_isp: LFUSE = E2 +# 512 byte boot +lilypad_isp: EFUSE = 04 +lilypad_isp: isp + +lilypad_resonator: TARGET = lilypad_resonator +lilypad_resonator: MCU_TARGET = atmega168 +lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +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 +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 = 04 +lilypad_resonator_isp: isp + +pro8: TARGET = pro_8MHz +pro8: MCU_TARGET = atmega168 +pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' +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 +pro8_isp: HFUSE = DD +# Full swing xtal (20MHz) 258CK/14CK+4.1ms +pro8_isp: LFUSE = C6 +# 512 byte boot +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=38400' +atmega328_pro8: AVR_FREQ = 8000000L +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, SPIEN +atmega328_pro8_isp: HFUSE = DE +# Low power xtal (16MHz) 16KCK/14CK+65ms +atmega328_pro8_isp: LFUSE = FF +# 2.7V brownout +atmega328_pro8_isp: EFUSE = DE +atmega328_pro8_isp: isp + +# 1MHz clocked platforms +# +# These are capable of 9600 baud +# + +luminet: TARGET = luminet +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: 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 +# Brownout disabled +luminet_isp: HFUSE = DF +# 1MHz internal oscillator, slowly rising power +luminet_isp: LFUSE = 62 +# Self-programming enable +luminet_isp: EFUSE = FE +luminet_isp: isp + +# +# Generic build instructions +# +# + +isp: $(TARGET) + $(ISPFUSES) + $(ISPFLASH) + +isp-stk500: $(PROGRAM)_$(TARGET).hex + $(STK500-1) + $(STK500-2) + +%.elf: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + $(SIZE) $@ + +clean: + rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex + +%.lst: %.elf + $(OBJDUMP) -h -S $< > $@ + +%.hex: %.elf + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@ + +%.srec: %.elf + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@ + +%.bin: %.elf + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@ diff --git a/BootLoaders/OrangeMultiBoot/Source/optiboot.c b/BootLoaders/OrangeMultiBoot/Source/optiboot.c new file mode 100644 index 0000000..5a7985f --- /dev/null +++ b/BootLoaders/OrangeMultiBoot/Source/optiboot.c @@ -0,0 +1,980 @@ +/**********************************************************/ +/* Optiboot bootloader for Xmega */ +/* */ +/* http://optiboot.googlecode.com */ +/* */ +/* Arduino-maintained version : See README.TXT */ +/* http://code.google.com/p/arduino/ */ +/* It is the intent that changes not relevant to the */ +/* Arduino production envionment get moved from the */ +/* optiboot project to the arduino project in "lumps." */ +/* */ +/* Heavily optimised bootloader that is faster and */ +/* smaller than the Arduino standard bootloader */ +/* */ +/* Enhancements: */ +/* Fits in 512 bytes, saving 1.5K of code space */ +/* Background page erasing speeds up programming */ +/* Higher baud rate speeds up programming */ +/* Written almost entirely in C */ +/* Customisable timeout with accurate timeconstant */ +/* Optional virtual UART. No hardware UART required. */ +/* Optional virtual boot partition for devices without. */ +/* */ +/* What you lose: */ +/* Implements a skeleton STK500 protocol which is */ +/* missing several features including EEPROM */ +/* programming and non-page-aligned writes */ +/* High baud rate breaks compatibility with standard */ +/* Arduino flash settings */ +/* */ +/* Fully supported: */ +/* ATmega168 based devices (Diecimila etc) */ +/* ATmega328P based devices (Duemilanove etc) */ +/* */ +/* Beta test (believed working.) */ +/* ATmega8 based devices (Arduino legacy) */ +/* ATmega328 non-picopower devices */ +/* ATmega644P based devices (Sanguino) */ +/* ATmega1284P based devices */ +/* */ +/* Alpha test */ +/* ATmega1280 based devices (Arduino Mega) */ +/* */ +/* Work in progress: */ +/* ATtiny84 based devices (Luminet) */ +/* */ +/* Does not support: */ +/* USB based devices (eg. Teensy) */ +/* */ +/* Assumptions: */ +/* The code makes several assumptions that reduce the */ +/* code size. They are all true after a hardware reset, */ +/* but may not be true if the bootloader is called by */ +/* other means or on other hardware. */ +/* No interrupts can occur */ +/* UART and Timer 1 are set to their reset state */ +/* SP points to RAMEND */ +/* */ +/* Code builds on code, libraries and optimisations from: */ +/* stk500boot.c by Jason P. Kyle */ +/* Arduino bootloader http://arduino.cc */ +/* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */ +/* avr-libc project http://nongnu.org/avr-libc */ +/* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */ +/* AVR305 Atmel Application Note */ +/* */ +/* This program is free software; you can redistribute it */ +/* and/or modify it under the terms of the GNU General */ +/* Public License as published by the Free Software */ +/* Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will */ +/* be useful, but WITHOUT ANY WARRANTY; without even the */ +/* implied warranty of MERCHANTABILITY or FITNESS FOR A */ +/* PARTICULAR PURPOSE. See the GNU General Public */ +/* License for more details. */ +/* */ +/* You should have received a copy of the GNU General */ +/* Public License along with this program; if not, write */ +/* to the Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/* Licence can be viewed at */ +/* http://www.fsf.org/licenses/gpl.txt */ +/* */ +/**********************************************************/ + + +/**********************************************************/ +/* */ +/* Optional defines: */ +/* */ +/**********************************************************/ +/* */ +/* BIG_BOOT: */ +/* Build a 1k bootloader, not 512 bytes. This turns on */ +/* extra functionality. */ +/* */ +/* BAUD_RATE: */ +/* Set bootloader baud rate. */ +/* */ +/* LUDICROUS_SPEED: */ +/* 230400 baud :-) */ +/* */ +/* SOFT_UART: */ +/* Use AVR305 soft-UART instead of hardware UART. */ +/* */ +/* LED_START_FLASHES: */ +/* Number of LED flashes on bootup. */ +/* */ +/* LED_DATA_FLASH: */ +/* Flash LED when transferring data. For boards without */ +/* TX or RX LEDs, or for people who like blinky lights. */ +/* */ +/* SUPPORT_EEPROM: */ +/* Support reading and writing from EEPROM. This is not */ +/* used by Arduino, so off by default. */ +/* */ +/* TIMEOUT_MS: */ +/* Bootloader timeout period, in milliseconds. */ +/* 500,1000,2000,4000,8000 supported. */ +/* */ +/* UART: */ +/* UART number (0..n) for devices with more than */ +/* one hardware uart (644P, 1284P, etc) */ +/* */ +/**********************************************************/ + +/**********************************************************/ +/* 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: */ +/* */ +/* Nov 2012 */ +/* Specific version for 9x voice module */ +/* by Mike Blandford */ +/* Mar 2012 */ +/* 4.5 WestfW: add infrastructure for non-zero UARTS. */ +/* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */ +/* Jan 2012: */ +/* 4.5 WestfW: fix NRWW value for m1284. */ +/* 4.4 WestfW: use attribute OS_main instead of naked for */ +/* main(). This allows optimizations that we */ +/* count on, which are prohibited in naked */ +/* functions due to PR42240. (keeps us less */ +/* than 512 bytes when compiler is gcc4.5 */ +/* (code from 4.3.2 remains the same.) */ +/* 4.4 WestfW and Maniacbug: Add m1284 support. This */ +/* does not change the 328 binary, so the */ +/* version number didn't change either. (?) */ +/* June 2011: */ +/* 4.4 WestfW: remove automatic soft_uart detect (didn't */ +/* know what it was doing or why.) Added a */ +/* check of the calculated BRG value instead. */ +/* Version stays 4.4; existing binaries are */ +/* not changed. */ +/* 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 5 + +#define MULTI_CALLED 1 + +#define MAKESTR(a) #a +#define MAKEVER(a, b) MAKESTR(a*256+b) + +// Page Size is 128 words (256 bytes) + +//asm(" .section .version\n" +// "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n" +// " .section .text\n"); + +#include +#include +#include + +// uses sts instructions, but this version uses out instructions +// This saves cycles and program memory. +//#include "boot.h" + + +// We don't use as those routines have interrupt overhead we don't need. + +#include "pin_defs.h" +#include "stk500.h" + +#define BIND_pin 2 //PD2 +#define BIND_port PORTD +#define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 ) + +#ifndef LED_START_FLASHES +#define LED_START_FLASHES 0 +#endif + +#ifdef LUDICROUS_SPEED +#define BAUD_RATE 230400L +#endif + +/* set the UART baud rate defaults */ +#ifndef BAUD_RATE +#if F_CPU >= 8000000L +#define BAUD_RATE 38400L // Highest rate Avrdude win32 will support +#elsif F_CPU >= 1000000L +#define BAUD_RATE 9600L // 19200 also supported, but with significant error +#elsif F_CPU >= 128000L +#define BAUD_RATE 4800L // Good for 128kHz internal RC +#else +#define BAUD_RATE 1200L // Good even at 32768Hz +#endif +#endif + +#ifndef UART +#define UART 0 +#endif + +#if 0 +/* Switch in soft UART for hard baud rates */ +/* + * I don't understand what this was supposed to accomplish, where the + * constant "280" came from, or why automatically (and perhaps unexpectedly) + * switching to a soft uart is a good thing, so I'm undoing this in favor + * of a range check using the same calc used to config the BRG... + */ +#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz +#ifndef SOFT_UART +#define SOFT_UART +#endif +#endif +#else // 0 +#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250 +#error Unachievable baud rate (too slow) BAUD_RATE +#endif // baud rate slow check +#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3 +#error Unachievable baud rate (too fast) BAUD_RATE +#endif // baud rate fastn check +#endif + +/* Watchdog settings */ +#define WATCHDOG_OFF (0) +#define WATCHDOG_16MS (_BV(WDE)) +#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE)) +#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE)) +#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE)) +#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE)) +#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE)) +#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(WDP3) | _BV(WDE)) +#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE)) +#endif + +/* Function Prototypes */ +/* The main function is in init9, which removes the interrupt vector table */ +/* we don't need. It is also 'naked', which means the compiler does not */ +/* generate any entry or exit code itself. */ +int main(void) __attribute__ ((OS_main)) __attribute__ ((noreturn)) __attribute__ ((section (".init9"))); +void putch(char); +uint8_t getch(void); +static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */ +void verifySpace(); +#if LED_START_FLASHES > 0 +static inline void flash_led(uint8_t); +#endif +uint8_t getLen(); +//static inline void watchdogReset(); +void watchdogConfig(uint8_t x); +#ifdef SOFT_UART +void uartDelay() __attribute__ ((naked)); +#endif +static void appStart() ; // __attribute__ ((naked)); +void boot_spm_busy_wait() ; +void __boot_page_erase_short( uint16_t address ) ; +void __boot_page_fill_short( uint16_t address, uint16_t data) ; +void __boot_page_write_short( uint16_t address) ; +void __boot_erase_flash_buffer( uint16_t address ) ; +void init() ; + +/* + * NRWW memory + * Addresses below NRWW (Non-Read-While-Write) can be programmed while + * continuing to run code from flash, slightly speeding up programming + * time. Beware that Atmel data sheets specify this as a WORD address, + * while optiboot will be comparing against a 16-bit byte address. This + * means that on a part with 128kB of memory, the upper part of the lower + * 64k will get NRWW processing as well, even though it doesn't need it. + * That's OK. In fact, you can disable the overlapping processing for + * a part entirely by setting NRWWSTART to zero. This reduces code + * space a bit, at the expense of being slightly slower, overall. + * + * RAMSTART should be self-explanatory. It's bigger on parts with a + * lot of peripheral registers. + */ +#if defined(__AVR_ATmega168__) +#define RAMSTART (0x100) +#define NRWWSTART (0x3800) +#elif defined(__AVR_ATmega328P__) +#define RAMSTART (0x100) +#define NRWWSTART (0x7000) +#elif defined(__AVR_ATmega328__) +#define RAMSTART (0x100) +#define NRWWSTART (0x7000) +#elif defined (__AVR_ATmega644P__) +#define RAMSTART (0x100) +#define NRWWSTART (0xE000) +// correct for a bug in avr-libc +#undef SIGNATURE_2 +#define SIGNATURE_2 0x0A +#elif defined (__AVR_ATmega1284P__) +#define RAMSTART (0x100) +#define NRWWSTART (0xE000) +#elif defined(__AVR_ATtiny84__) +#define RAMSTART (0x100) +#define NRWWSTART (0x0000) +#elif defined(__AVR_ATmega1280__) +#define RAMSTART (0x200) +#define NRWWSTART (0xE000) +#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) +#define RAMSTART (0x100) +#define NRWWSTART (0x1800) +#endif + +/* C zero initialises all global variables. However, that requires */ +/* 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)) +#ifdef VIRTUAL_BOOT_PARTITION +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* + * Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly. + * Note that mega8 still needs special handling, because ubrr is handled + * differently. + */ +#if UART == 0 +# define UART_SRA UCSR0A +# define UART_SRB UCSR0B +# define UART_SRC UCSR0C +# define UART_SRL UBRR0L +# define UART_UDR UDR0 +#elif UART == 1 +# define UART_SRA UCSR1A +# define UART_SRB UCSR1B +# define UART_SRC UCSR1C +# define UART_SRL UBRR1L +# define UART_UDR UDR1 +#elif UART == 2 +# define UART_SRA UCSR2A +# define UART_SRB UCSR2B +# define UART_SRC UCSR2C +# define UART_SRL UBRR2L +# define UART_UDR UDR2 +#elif UART == 3 +# define UART_SRA UCSR3A +# define UART_SRB UCSR3B +# define UART_SRC UCSR3C +# define UART_SRL UBRR3L +# define UART_UDR UDR3 +#endif + + +/* main program starts here */ +int main(void) +{ + uint8_t ch; + uint8_t byte ; + + /* + * 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; + init() ; + + // After the zero init loop, this is the first code to run. + // + // This code makes the following assumptions: + // No interrupts will execute + // SP points to RAMEND + // r1 contains zero + // + // If not, uncomment the following instructions: + // cli(); + asm volatile ("clr __zero_reg__"); + + ch = RST.STATUS ; + RST.STATUS = 0xFF ; // Clear all flags + + // Here, if power on, wait 0.1 secs, then check for + // serial Rx signal low, if so, stay in bootloader + // else go to application + + if (ch & (RST_EXTRF_bm | RST_PORF_bm ) ) + { + TCC1.CCA = 25000 ; + TCC1.INTFLAGS = TC1_CCAIF_bm ; + + while(!(TCC1.INTFLAGS & TC1_CCAIF_bm)) + ; + TCC1.CTRLA = 0 ; // Stop timer + + uint8_t x ; + x = PORTD.IN & 0x04 ; + if ( x != 0 ) + { + appStart() ; // Power on, go to app if loaded + } + } + + +//#ifndef SOFT_UART +// UART_SRA = _BV(U2X0); //Double speed mode USART0 +// UART_SRB = _BV(RXEN0) | _BV(TXEN0); +// UART_SRC = _BV(UCSZ00) | _BV(UCSZ01); +//// UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +//// Baudrate of 57600 +//#if F_CPU == 12000000L +// UART_SRL = 25 ; +//#else +//#if F_CPU == 16000000L +// UART_SRL = 33 ; +//#else +//#ERROR Baud rate not available +//#endif +//#endif + +//#endif + + // Set up watchdog to trigger after 500ms + + +// watchdogConfig(WATCHDOG_1S); + + /* Set LED pin as output */ +#define LED_pin 1 //PD1 +#define LED_port PORTD + LED_port.DIRSET = _BV(LED_pin) ; + +//#ifdef SOFT_UART +// /* Set TX pin as output */ +// UART_DDR |= _BV(UART_TX_BIT); +//#endif + +//#if LED_START_FLASHES > 0 +// /* Flash onboard LED to signal entering of bootloader */ +// flash_led(LED_START_FLASHES * 2); +//#endif + + /* Forever loop */ + for (;;) + { + /* get character from UART */ + ch = getch(); + + if(ch == STK_GET_PARAMETER) + { + byte = getch(); + verifySpace(); + if ( byte == 0x82) + { + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } + else if ( byte == 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 + getNch(20); + } + else if(ch == STK_SET_DEVICE_EXT) + { + // SET DEVICE EXT is ignored + getNch(5); + } + else if(ch == STK_LOAD_ADDRESS) + { + // LOAD ADDRESS + uint16_t newAddress; + newAddress = getch() ; + newAddress = (newAddress & 0xff) | (getch() << 8); +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; +#endif +// newAddress += newAddress; // Convert from word address to byte address + address = newAddress; + verifySpace(); + } + else if(ch == STK_UNIVERSAL) + { + // UNIVERSAL command is ignored + getNch(4); + putch(0x00); + } + /* Write memory, length is big endian and is in bytes */ + else if(ch == STK_PROG_PAGE) + { + // PROGRAM PAGE - we support flash programming only, not EEPROM + uint8_t *bufPtr; + uint16_t addrPtr; + register uint8_t length; + + 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); + __boot_page_erase_short((uint16_t)(void*)address); + + // While that is going on, read in page contents + bufPtr = buff; + do *bufPtr++ = getch(); + while (--length); + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account +//#ifdef MULTI_CALLED +// if (address < 0x7E00) +//#endif +// { +// if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); +// } + // 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 +#ifdef MULTI_CALLED + if (address < 0x8000) +#endif + { + boot_spm_busy_wait(); + +#ifdef VIRTUAL_BOOT_PARTITION + if ((uint16_t)(void*)address == 0) { + // 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); + rstVect = vect; + wdtVect = buff[8] | (buff[9]<<8); + 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; + buff[1] = 0xce; // rjmp 0x1d00 instruction + } +#endif + + // Copy buffer into programming buffer + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; + ch = SPM_PAGESIZE / 2; + __boot_erase_flash_buffer((uint16_t)(void*)addrPtr ) ; + do { + uint16_t a; + // a = *bufPtr++; + // a |= (*bufPtr++) << 8; + + a = *((uint16_t *)bufPtr) ; + bufPtr += 2 ; + + __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(); + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); +#endif + } + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) + { + register uint8_t length; + // READ PAGE - we only read flash + getch(); /* getlen() */ + length = getch(); + getch(); + + verifySpace(); +//#ifdef VIRTUAL_BOOT_PARTITION +// do { +// // Undo vector patch in bottom page so verify passes +// if (address == 0) ch=rstVect & 0xff; +// else if (address == 1) ch=rstVect >> 8; +// else if (address == 8) ch=wdtVect & 0xff; +// else if (address == 9) ch=wdtVect >> 8; +// else ch = pgm_read_byte_near(address); +// address++; +// putch(ch); +// } while (--length); +//#else +//#ifdef RAMPZ +//// Since RAMPZ should already be set, we need to use EPLM directly. +//// do putch(pgm_read_byte_near(address++)); +//// while (--length); +// do { +// uint8_t result; +// __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address)); +// putch(result); +// address++; +// } +// while (--length); +//#else + do putch(pgm_read_byte_near(address++)); + while (--length); +//#endif +//#endif + } + + /* Get device signature bytes */ + else if(ch == STK_READ_SIGN) + { + // READ SIGN - return what Avrdude wants to hear + verifySpace(); + putch(SIGNATURE_0); + putch(SIGNATURE_1); + putch(SIGNATURE_2); + } + else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ + // Adaboot no-wait mod + +// watchdogConfig(WATCHDOG_16MS); + + verifySpace(); +#ifdef MULTI_CALLED + putch(STK_OK); + while(!(USARTC0.STATUS & USART_TXCIF_bm)) + ; + appStart() ; +#endif + } + else + { + // This covers the response to commands like STK_ENTER_PROGMODE + verifySpace(); + } + putch(STK_OK); + } +} + +void putch(char ch) +{ +//#ifndef SOFT_UART + while(!(USARTC0.STATUS & USART_DREIF_bm)) + ; + USARTC0.DATA = ch ; +//#else +// __asm__ __volatile__ ( +// " com %[ch]\n" // ones complement, carry set +// " sec\n" +// "1: brcc 2f\n" +// " cbi %[uartPort],%[uartBit]\n" +// " rjmp 3f\n" +// "2: sbi %[uartPort],%[uartBit]\n" +// " nop\n" +// "3: rcall uartDelay\n" +// " rcall uartDelay\n" +// " lsr %[ch]\n" +// " dec %[bitcnt]\n" +// " brne 1b\n" +// : +// : +// [bitcnt] "d" (10), +// [ch] "r" (ch), +// [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)), +// [uartBit] "I" (UART_TX_BIT) +// : +// "r25" +// ); +//#endif +} + +uint8_t getch(void) +{ + uint8_t ch; + +//#ifdef LED_DATA_FLASH +//#ifdef __AVR_ATmega8__ +// LED_PORT ^= _BV(LED); +//#else +// LED_PIN |= _BV(LED); +//#endif +//#endif + +//#ifdef SOFT_UART +// __asm__ __volatile__ ( +// "1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge +// " rjmp 1b\n" +// " rcall uartDelay\n" // Get to middle of start bit +// "2: rcall uartDelay\n" // Wait 1 bit period +// " rcall uartDelay\n" // Wait 1 bit period +// " clc\n" +// " sbic %[uartPin],%[uartBit]\n" +// " sec\n" +// " dec %[bitCnt]\n" +// " breq 3f\n" +// " ror %[ch]\n" +// " rjmp 2b\n" +// "3:\n" +// : +// [ch] "=r" (ch) +// : +// [bitCnt] "d" (9), +// [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)), +// [uartBit] "I" (UART_RX_BIT) +// : +// "r25" +//); +//#else + while(!(USARTC0.STATUS & USART_RXCIF_bm)) + +// watchdogReset() + + ; +// if (!(UART_SRA & _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 = USARTC0.DATA ; +//#endif + +//#ifdef LED_DATA_FLASH +//#ifdef __AVR_ATmega8__ +// LED_PORT ^= _BV(LED); +//#else +// LED_PIN |= _BV(LED); +//#endif +//#endif + + return ch; +} + +#ifdef SOFT_UART +// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6) +// Adding 3 to numerator simulates nearest rounding for more accurate baud rates +#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6) +#if UART_B_VALUE > 255 +#error Baud rate too slow for soft UART +#endif + +void uartDelay() { + __asm__ __volatile__ ( + "ldi r25,%[count]\n" + "1:dec r25\n" + "brne 1b\n" + "ret\n" + ::[count] "M" (UART_B_VALUE) + ); +} +#endif + +void getNch(uint8_t count) { + do getch(); while (--count); + verifySpace(); +} + +void verifySpace() +{ + if ( getch() != CRC_EOP) { + + putch(STK_NOSYNC); +// watchdogConfig(WATCHDOG_16MS); // shorten WD timeout +// +// while (1) // and busy-loop so that WD causes +// ; // a reset and app start. + } + putch(STK_INSYNC); +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + TIFR1 = _BV(TOV1); + while(!(TIFR1 & _BV(TOV1))); +//#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +//#else +// LED_PIN |= _BV(LED); +//#endif + watchdogReset(); + } while (--count); +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + "wdr\n" + ); +} + +//void watchdogConfig(uint8_t x) { +// WDTCSR = _BV(WDCE) | _BV(WDE); +// WDTCSR = x; +//} + +void init() +{ + // Enable external oscillator (16MHz) + OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_256CLK_gc ; + OSC.CTRL |= OSC_XOSCEN_bm ; + while( ( OSC.STATUS & OSC_XOSCRDY_bm ) == 0 ) + /* wait */ ; + // Enable PLL (*2 = 32MHz) + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 2 ; + OSC.CTRL |= OSC_PLLEN_bm ; + while( ( OSC.STATUS & OSC_PLLRDY_bm ) == 0 ) + /* wait */ ; + // Switch to PLL clock + CPU_CCP = 0xD8 ; + CLK.CTRL = CLK_SCLKSEL_RC2M_gc ; + CPU_CCP = 0xD8 ; + CLK.CTRL = CLK_SCLKSEL_PLL_gc ; + + PMIC.CTRL = 7 ; // Enable all interrupt levels + + + // Timer1 config + // TCC1 16-bit timer, clocked at 0.5uS + EVSYS.CH3MUX = 0x80 + 0x07 ; // Prescaler of 128 + TCC1.CTRLB = 0; TCC1.CTRLC = 0; TCC1.CTRLD = 0; TCC1.CTRLE = 0; + TCC1.INTCTRLA = 0 ; + TCC1.INTCTRLB = 0 ; + TCC1.PER = 0xFFFF ; + TCC1.CNT = 0 ; + TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16) + + PORTD.OUTSET = 0x04 ; + PORTD.DIRCLR = 0x04 ; + PORTD.PIN2CTRL = 0x18 ; // Pullup + + PORTC.OUTSET = 0x08 ; + PORTC.DIRSET = 0x08 ; + + USARTC0.BAUDCTRLA = 34 ; // 57600 + USARTC0.BAUDCTRLB = 0 ; + + USARTC0.CTRLB = 0x18 ; // Enable Tx and Rx + USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) ; + USARTC0.CTRLC = 0x03 ; // 8 bit, no parity, 1 stop + USARTC0.DATA ; +} + +void boot_spm_busy_wait() +{ + while(NVM.STATUS & NVM_NVMBUSY_bm) + ; +} + +#define A_NVM_CMD 0x1CA + +void __boot_page_erase_short( uint16_t address ) +{ + asm( "push r24" ) ; + asm( "push r25" ) ; + NVM.CMD = NVM_CMD_ERASE_APP_PAGE_gc ; + asm( "pop r31" ) ; + asm( "pop r30" ) ; + CCP = CCP_SPM_gc ; + asm( "spm" ) ; +} + +void __boot_erase_flash_buffer( uint16_t address ) +{ + asm( "movw r30,r24" ) ; + asm( "ldi r24,0x26" ) ; + asm("sts 0x1CA,r24"); + CCP = CCP_IOREG_gc ; + asm( "ldi r24,1" ) ; + asm("sts 0x1CB,r24"); +} + +void __boot_page_fill_short( uint16_t address, uint16_t data) +{ + asm( "push r0" ) ; + asm( "push r1" ) ; + asm( "movw r30,r24" ) ; + asm( "mov r0,r22" ) ; + asm( "mov r1,r23" ) ; + asm( "ldi r24,0x23" ) ; + asm("sts 0x1CA,r24"); + CCP = CCP_SPM_gc ; + asm( "spm" ) ; + asm( "pop r1" ) ; + asm( "pop r0" ) ; +} + +void __boot_page_write_short( uint16_t address) +{ + asm( "movw r30,r24" ) ; + asm( "ldi r24,0x2E" ) ; + asm("sts 0x1CA,r24"); + CCP = CCP_SPM_gc ; + asm( "spm" ) ; +} + +void appStart() +{ +// watchdogConfig(WATCHDOG_OFF); +// __asm__ __volatile__ ( +//#ifdef VIRTUAL_BOOT_PARTITION +// // Jump to WDT vector +// "ldi r30,4\n" +// "clr r31\n" +//#else +// // Jump to RST vector +// "clr r30\n" +// "clr r31\n" +//#endif +// "ijmp\n" +// ); + + register void (*p)() ; + p = 0 ; + + if ( pgm_read_byte( (uint16_t)p ) != 0xFF ) + { + (*p)() ; + } +} + diff --git a/BootLoaders/OrangeMultiBoot/Source/pin_defs.h b/BootLoaders/OrangeMultiBoot/Source/pin_defs.h new file mode 100644 index 0000000..9623969 --- /dev/null +++ b/BootLoaders/OrangeMultiBoot/Source/pin_defs.h @@ -0,0 +1,80 @@ +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) +/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB5 + +/* Ports for soft UART */ +#ifdef SOFT_UART +#define UART_PORT PORTD +#define UART_PIN PIND +#define UART_DDR DDRD +#define UART_TX_BIT 1 +#define UART_RX_BIT 0 +#endif +#endif + +#if defined(__AVR_ATmega8__) + //Name conversion R.Wiersma + #define UCSR0A UCSRA + #define UDR0 UDR + #define UDRE0 UDRE + #define RXC0 RXC + #define FE0 FE + #define TIFR1 TIFR + #define WDTCSR WDTCR +#endif + +/* Luminet support */ +#if defined(__AVR_ATtiny84__) +/* Red LED is connected to pin PA4 */ +#define LED_DDR DDRA +#define LED_PORT PORTA +#define LED_PIN PINA +#define LED PINA4 +/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */ +#ifdef SOFT_UART +#define UART_PORT PORTA +#define UART_PIN PINA +#define UART_DDR DDRA +#define UART_TX_BIT 2 +#define UART_RX_BIT 3 +#endif +#endif + +/* Sanguino support */ +#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) +/* Onboard LED is connected to pin PB0 on Sanguino */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB0 + +/* Ports for soft UART */ +#ifdef SOFT_UART +#define UART_PORT PORTD +#define UART_PIN PIND +#define UART_DDR DDRD +#define UART_TX_BIT 1 +#define UART_RX_BIT 0 +#endif +#endif + +/* Mega support */ +#if defined(__AVR_ATmega1280__) +/* Onboard LED is connected to pin PB7 on Arduino Mega */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB7 + +/* Ports for soft UART */ +#ifdef SOFT_UART +#define UART_PORT PORTE +#define UART_PIN PINE +#define UART_DDR DDRE +#define UART_TX_BIT 1 +#define UART_RX_BIT 0 +#endif +#endif diff --git a/BootLoaders/OrangeMultiBoot/Source/stk500.h b/BootLoaders/OrangeMultiBoot/Source/stk500.h new file mode 100644 index 0000000..ca0dd91 --- /dev/null +++ b/BootLoaders/OrangeMultiBoot/Source/stk500.h @@ -0,0 +1,39 @@ +/* STK500 constants list, from AVRDUDE */ +#define STK_OK 0x10 +#define STK_FAILED 0x11 // Not used +#define STK_UNKNOWN 0x12 // Not used +#define STK_NODEVICE 0x13 // Not used +#define STK_INSYNC 0x14 // ' ' +#define STK_NOSYNC 0x15 // Not used +#define ADC_CHANNEL_ERROR 0x16 // Not used +#define ADC_MEASURE_OK 0x17 // Not used +#define PWM_CHANNEL_ERROR 0x18 // Not used +#define PWM_ADJUST_OK 0x19 // Not used +#define CRC_EOP 0x20 // 'SPACE' +#define STK_GET_SYNC 0x30 // '0' +#define STK_GET_SIGN_ON 0x31 // '1' +#define STK_SET_PARAMETER 0x40 // '@' +#define STK_GET_PARAMETER 0x41 // 'A' +#define STK_SET_DEVICE 0x42 // 'B' +#define STK_SET_DEVICE_EXT 0x45 // 'E' +#define STK_ENTER_PROGMODE 0x50 // 'P' +#define STK_LEAVE_PROGMODE 0x51 // 'Q' +#define STK_CHIP_ERASE 0x52 // 'R' +#define STK_CHECK_AUTOINC 0x53 // 'S' +#define STK_LOAD_ADDRESS 0x55 // 'U' +#define STK_UNIVERSAL 0x56 // 'V' +#define STK_PROG_FLASH 0x60 // '`' +#define STK_PROG_DATA 0x61 // 'a' +#define STK_PROG_FUSE 0x62 // 'b' +#define STK_PROG_LOCK 0x63 // 'c' +#define STK_PROG_PAGE 0x64 // 'd' +#define STK_PROG_FUSE_EXT 0x65 // 'e' +#define STK_READ_FLASH 0x70 // 'p' +#define STK_READ_DATA 0x71 // 'q' +#define STK_READ_FUSE 0x72 // 'r' +#define STK_READ_LOCK 0x73 // 's' +#define STK_READ_PAGE 0x74 // 't' +#define STK_READ_SIGN 0x75 // 'u' +#define STK_READ_OSCCAL 0x76 // 'v' +#define STK_READ_FUSE_EXT 0x77 // 'w' +#define STK_READ_OSCCAL_EXT 0x78 // 'x' diff --git a/BootLoaders/StmMultiBoot/README.md b/BootLoaders/StmMultiBoot/README.md new file mode 100644 index 0000000..5765b71 --- /dev/null +++ b/BootLoaders/StmMultiBoot/README.md @@ -0,0 +1 @@ +[Source for the StmMultiBooloader](https://github.com/MikeBland/StmMultiBoot) diff --git a/BootLoaders/StmMultiBoot/StmMultiBoot.bin b/BootLoaders/StmMultiBoot/StmMultiBoot.bin new file mode 100644 index 0000000000000000000000000000000000000000..022e373261960c60cb096ce13a7f77a35eee15d5 GIT binary patch literal 7788 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 literal 0 HcmV?d00001