Browse Source

/* 6.0 WestfW: Modularize memory read/write functions */
/* Remove serial/flash overlap */
/* (and all references to NRWWSTART/etc) */
/* Correctly handle pagesize > 255bytes */
/* Add EEPROM support in BIGBOOT (1284) */
/* EEPROM write on small chips now causes err */
/* Split Makefile into smaller pieces */
/* Add Wicked devices Wildfire */
/* Move UART=n conditionals into pin_defs.h */
/* Remove LUDICOUS_SPEED option */
/* Replace inline assembler for .version */
/* and add OPTIBOOT_CUSTOMVER for user code */
/* Fix LED value for Bobuino (Makefile) */
/* Make all functions explicitly inline or */
/* noinline, so we fit when using gcc4.8 */
/* Change optimization options for gcc4.8 */
/* Make ENV=arduino work in 1.5.x trees. */

westfw 10 years ago
parent
commit
6c06686902

+ 31 - 154
optiboot/bootloaders/optiboot/Makefile

@@ -17,6 +17,11 @@
 # etc...
 #
 # Edit History
+# 201406xx: WestfW: More Makefile restructuring.
+#                   Split off Makefile.1284, Makefile.extras, Makefile.custom
+#                   So that in theory, the main Makefile contains only the
+#                   official platforms, and does not need to be modified to
+#                   add "less supported" chips and boards.
 # 201303xx: WestfW: Major Makefile restructuring.
 #                   Allows options on Make command line "make xx LED=B3"
 #                   (see also pin_defs.h)
@@ -59,12 +64,21 @@ LDSECTIONS  = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3f
 
 # default
 fixpath = $(1)
+SH := bash
 
 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
+# (except that in 1.5.x, there's an additional level of "up")
+TESTDIR := $(firstword $(wildcard ../../../tools/*))
+ifeq (,$(TESTDIR))
+# Arduino 1.5.x tool location compared to optiboot dir
+  TOOLROOT = ../../../../tools
+else
+# Arduino 1.0 (and earlier) tool location
+  TOOLROOT = ../../../tools
+endif
 GCCROOT = $(TOOLROOT)/avr/bin/
 
 ifeq ($(OS), windows)
@@ -74,6 +88,7 @@ ifeq ($(OS), windows)
 # is used even if a unix shell is installed (ie as part of WINAVR)
 fixpath = $(subst /,\,$1)
 SHELL = cmd.exe
+SH = sh
 endif
 
 else ifeq ($(ENV), arduinodev)
@@ -103,10 +118,15 @@ 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
+OPTIMIZE = -Os -fno-split-wide-types -mrelax
 
 DEFS       = 
-LIBS       =
+
+#
+# platforms support EEPROM and large bootloaders need the eeprom functions that
+# are defined in libc, even though we explicity remove it with -nostdlib because
+# of the space-savings.
+LIBS       =  -lc
 
 CC         = $(GCCROOT)avr-gcc
 
@@ -187,6 +207,8 @@ endif
 # endif
 #
 
+#.PRECIOUS: %.elf
+
 #---------------------------------------------------------------------------
 # "Chip-level Platform" targets.
 # A "Chip-level Platform" compiles for a particular chip, but probably does
@@ -258,37 +280,6 @@ atmega328_isp: LFUSE ?= FF
 atmega328_isp: EFUSE ?= FD
 atmega328_isp: isp
 
-atmega644p: TARGET = atmega644p
-atmega644p: MCU_TARGET = atmega644p
-atmega644p: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT $(LED_CMD)
-atmega644p: AVR_FREQ ?= 16000000L
-atmega644p: LDSECTIONS  = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
-atmega644p: CFLAGS += $(UARTCMD)
-atmega644p: $(PROGRAM)_atmega644p.hex
-atmega644p: $(PROGRAM)_atmega644p.lst
-
-atmega1284: TARGET = atmega1284p
-atmega1284: MCU_TARGET = atmega1284p
-atmega1284: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT $(LED_CMD)
-atmega1284: AVR_FREQ ?= 16000000L
-atmega1284: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
-atmega1284: CFLAGS += $(UARTCMD)
-atmega1284: $(PROGRAM)_atmega1284p.hex
-atmega1284: $(PROGRAM)_atmega1284p.lst
-
-atmega1284p: atmega1284
-
-atmega1284_isp: atmega1284
-atmega1284_isp: TARGET = atmega1284p
-atmega1284_isp: MCU_TARGET = atmega1284p
-# 1024 byte boot
-atmega1284_isp: HFUSE ?= DE
-# Full Swing xtal (16MHz) 16KCK/14CK+65ms
-atmega1284_isp: LFUSE ?= F7
-# 2.7V brownout
-atmega1284_isp: EFUSE ?= FD
-atmega1284_isp: isp
-
 #Atmega1280
 atmega1280: MCU_TARGET = atmega1280
 atmega1280: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT $(UART_CMD)
@@ -317,45 +308,6 @@ atmega8_isp: HFUSE ?= CC
 atmega8_isp: LFUSE ?= BF
 atmega8_isp: isp
 
-# ATmega88
-#
-atmega88: TARGET = atmega88
-atmega88: MCU_TARGET = atmega88
-atmega88: CFLAGS += $(COMMON_OPTIONS)
-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
-# 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
-
-atmega32: TARGET = atmega32
-atmega32: MCU_TARGET = atmega32
-atmega32: CFLAGS += $(COMMON_OPTIONS)
-atmega32: AVR_FREQ ?= 11059200L
-atmega32: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
-atmega32: $(PROGRAM)_atmega32.hex
-atmega32: $(PROGRAM)_atmega32.lst
-
-atmega32_isp: atmega32
-atmega32_isp: TARGET = atmega32
-atmega32_isp: MCU_TARGET = atmega32
-# No OCD or JTAG, SPIEN, CKOPT (for full swing xtal), Bootsize=512B
-atmega32_isp: HFUSE ?= CE
-# 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
-atemga32_isp: LFUSE ?= BF
-atmega32_isp: isp
-
-
 
 #---------------------------------------------------------------------------
 # "Board-level Platform" targets.
@@ -426,69 +378,12 @@ diecimila_isp: LFUSE ?= FF
 diecimila_isp: EFUSE ?= 04
 diecimila_isp: isp
 
-# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
-#
-sanguino: TARGET = $@
-sanguino: CHIP = atmega644p
-sanguino:
-	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B0
-	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
-	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
-
-sanguino_isp: sanguino
-sanguino_isp: TARGET = sanguino
-sanguino_isp: MCU_TARGET = atmega644p
-# 1024 byte boot
-sanguino_isp: HFUSE ?= DE
-# Full swing xtal (16MHz) 16KCK/14CK+65ms
-sanguino_isp: LFUSE ?= F7
-# 2.7V brownout
-sanguino_isp: EFUSE ?= FD
-sanguino_isp: isp
-
-mighty1284: TARGET = $@
-mighty1284: CHIP = atmega1284p
-mighty1284:
-	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7
-	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
-	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
-
-mighty1284_isp: mighty1284
-mighty1284_isp: TARGET = mighty1284
-mighty1284_isp: MCU_TARGET = atmega1284p
-# 1024 byte boot
-mighty1284_isp: HFUSE ?= DE
-# Full swing xtal (16MHz) 16KCK/14CK+65ms
-mighty1284_isp: LFUSE ?= F7
-# 2.7V brownout
-mighty1284_isp: EFUSE ?= FD
-mighty1284_isp: isp
-
-bobuino: TARGET = $@
-bobuino: CHIP = atmega1284p
-bobuino:
-	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B5
-	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
-	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
-
-bobuino_isp: bobuino
-bobuino_isp: TARGET = bobuino
-bobuino_isp: MCU_TARGET = atmega1284p
-# 1024 byte boot
-bobuino_isp: HFUSE ?= DE
-# Full swing xtal (16MHz) 16KCK/14CK+65ms
-bobuino_isp: LFUSE ?= F7
-# 2.7V brownout
-bobuino_isp: EFUSE ?= FD
-bobuino_isp: isp
-
 # MEGA1280 Board (this is different from the atmega1280 chip platform)
 # Mega has a minimum boot size of 1024 bytes, so enable extra functions
 # Note that optiboot does not (can not) work on the MEGA2560
 #mega: TARGET = atmega1280
 mega1280: atmega1280
 
-
 mega1280_isp: mega1280
 mega1280_isp: TARGET = atmega1280
 mega1280_isp: MCU_TARGET = atmega1280
@@ -573,30 +468,11 @@ atmega328_pro8_isp: LFUSE ?= FF
 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 += $(COMMON_OPTIONS) '-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
+# Include additional platforms
+include Makefile.extras
+include Makefile.1284
+include Makefile.custom
 
 
 #---------------------------------------------------------------------------
@@ -607,8 +483,9 @@ luminet_isp: isp
 FORCE:
 
 baudcheck: FORCE
+	- @$(CC) --version
 	- @$(CC) $(CFLAGS) -E baudcheck.c -o baudcheck.tmp.sh
-	- @sh baudcheck.tmp.sh
+	- @$(SH) baudcheck.tmp.sh
 
 isp: $(TARGET)
 	$(MAKE) -f Makefile.isp isp TARGET=$(TARGET)

+ 136 - 0
optiboot/bootloaders/optiboot/Makefile.1284

@@ -0,0 +1,136 @@
+#
+# Makefile for 40-pin AVR chips, including ATmega644 and ATmega1284
+#
+
+# Chip level targets
+#
+atmega644p: TARGET = atmega644p
+atmega644p: MCU_TARGET = atmega644p
+atmega644p: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
+atmega644p: AVR_FREQ ?= 16000000L
+atmega644p: LDSECTIONS  = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
+atmega644p: CFLAGS += $(UARTCMD)
+atmega644p: $(PROGRAM)_atmega644p.hex
+atmega644p: $(PROGRAM)_atmega644p.lst
+
+atmega1284: TARGET = atmega1284p
+atmega1284: MCU_TARGET = atmega1284p
+atmega1284: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
+atmega1284: AVR_FREQ ?= 16000000L
+atmega1284: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
+atmega1284: CFLAGS += $(UARTCMD)
+atmega1284: $(PROGRAM)_atmega1284p.hex
+atmega1284: $(PROGRAM)_atmega1284p.lst
+
+atmega1284p: atmega1284
+
+atmega1284_isp: atmega1284
+atmega1284_isp: TARGET = atmega1284p
+atmega1284_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+atmega1284_isp: HFUSE ?= DE
+# Full Swing xtal (16MHz) 16KCK/14CK+65ms
+atmega1284_isp: LFUSE ?= F7
+# 2.7V brownout
+atmega1284_isp: EFUSE ?= FD
+atmega1284_isp: isp
+
+#
+# Board-level targets
+#
+
+# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
+#
+sanguino: TARGET = $@
+sanguino: CHIP = atmega644p
+sanguino:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B0
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+sanguino_isp: sanguino
+sanguino_isp: TARGET = sanguino
+sanguino_isp: MCU_TARGET = atmega644p
+# 1024 byte boot
+sanguino_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+sanguino_isp: LFUSE ?= F7
+# 2.7V brownout
+sanguino_isp: EFUSE ?= FD
+sanguino_isp: isp
+
+mighty1284: TARGET = $@
+mighty1284: CHIP = atmega1284p
+mighty1284:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+mighty1284_isp: mighty1284
+mighty1284_isp: TARGET = mighty1284
+mighty1284_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+mighty1284_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+mighty1284_isp: LFUSE ?= F7
+# 2.7V brownout
+mighty1284_isp: EFUSE ?= FD
+mighty1284_isp: isp
+
+bobuino: TARGET = $@
+bobuino: CHIP = atmega1284p
+bobuino:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+bobuino_isp: bobuino
+bobuino_isp: TARGET = bobuino
+bobuino_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+bobuino_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+bobuino_isp: LFUSE ?= F7
+# 2.7V brownout
+bobuino_isp: EFUSE ?= FD
+bobuino_isp: isp
+
+#
+# Wicked Devices "Wildfire" boards (1284 with wireless!)
+#
+
+wildfirev2: TARGET = $@
+wildfirev2: CHIP = atmega1284p
+wildfirev2:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7 BAUD_RATE=1000000
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+wildfirev2_isp: wildfirev2
+wildfirev2_isp: TARGET = wildfirev2
+wildfirev2_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+wildfirev2_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+wildfirev2_isp: LFUSE ?= F7
+# 2.7V brownout
+wildfirev2_isp: EFUSE ?= FD
+wildfirev2_isp: isp
+
+wildfirev3: TARGET = $@
+wildfirev3: CHIP = atmega1284p
+wildfirev3:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B5
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+wildfirev3_isp: wildfirev3
+wildfirev3_isp: TARGET = wildfirev3
+wildfirev3_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+wildfirev3_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+wildfirev3_isp: LFUSE ?= F7
+# 2.7V brownout
+wildfirev3_isp: EFUSE ?= FD
+wildfirev3_isp: isp

+ 12 - 0
optiboot/bootloaders/optiboot/Makefile.custom

@@ -0,0 +1,12 @@
+#
+# Makefile for "custom" platforms.   Add your board here.
+#
+
+
+wildfire: TARGET = $@
+wildfire: CHIP = atmega1284p
+wildfire:
+	$(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B5
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+

+ 82 - 0
optiboot/bootloaders/optiboot/Makefile.extras

@@ -0,0 +1,82 @@
+#
+# Makefile for "other" implemented platforms.
+#
+
+#
+# Extra chips (maybe) supported by optiboot
+# Note that these are usually only minimally tested.
+#
+
+#
+# ATmega88
+#
+atmega88: TARGET = atmega88
+atmega88: MCU_TARGET = atmega88
+atmega88: CFLAGS += $(COMMON_OPTIONS)
+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
+# 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
+
+
+atmega32: TARGET = atmega32
+atmega32: MCU_TARGET = atmega32
+atmega32: CFLAGS += $(COMMON_OPTIONS)
+atmega32: AVR_FREQ ?= 11059200L
+atmega32: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+atmega32: $(PROGRAM)_atmega32.hex
+atmega32: $(PROGRAM)_atmega32.lst
+
+atmega32_isp: atmega32
+atmega32_isp: TARGET = atmega32
+atmega32_isp: MCU_TARGET = atmega32
+# No OCD or JTAG, SPIEN, CKOPT (for full swing xtal), Bootsize=512B
+atmega32_isp: HFUSE ?= CE
+# 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
+atemga32_isp: LFUSE ?= BF
+atmega32_isp: isp
+
+attiny84: TARGET = attiny84
+attiny84: MCU_TARGET = attiny84
+attiny84: CFLAGS += $(COMMON_OPTIONS) -DSOFT_UART -DVIRTUAL_BOOT_PARTITION
+attiny84: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1ffe
+attiny84: $(PROGRAM)_attiny84p.hex
+attiny84: $(PROGRAM)_attiny84p.lst
+
+
+
+# 1MHz clocked platforms/boards
+#
+# These are capable of 9600 baud
+#
+
+luminet: TARGET = $@
+luminet: CHIP = attiny84
+luminet:
+	$(MAKE) $(CHIP) AVR_FREQ=1000000L LED_START_FLASHES=0 BAUD_RATE=9600
+	mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+	mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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
+
+

+ 17 - 12
optiboot/bootloaders/optiboot/Makefile.isp

@@ -38,7 +38,7 @@ AVRDUDE_CONF ?= -C$(TOOLROOT)/avr/etc/avrdude.conf
 # 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
-ISPPORT	?= /dev/tty.usbmodemfd3141 
+ISPPORT	?= /dev/tty.usbserial-FTD61T6Q
 ISPSPEED ?= -b19200
 
 
@@ -49,6 +49,19 @@ ifdef EFUSE
 EFUSE_CMD= -U efuse:w:0x$(EFUSE):m
 endif
 
+#
+# avrdude commands to erase chip, unlock memory, and program fuses.
+#
+ISPFUSES =	-e -u -U lock:w:0x3f:m $(EFUSE_CMD) \
+	 	-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
+
+
+#
+# avrdude commands to program the new bootloader, and protect the bootloader
+# space from accidental SPM writes.  Note: "2f" allows boot section to be read
+# by the application, which is different than the arduino default.
+#
+ISPFLASH =	-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
 
 # There are certain complicated caused by the fact that the default state
 # of a fuse is a "1" rather than a "0", especially with respect to fuse bits
@@ -65,16 +78,8 @@ endif
 # lock it), but since the high two bits of the lock byte are
 # unused, avrdude would get confused.
 
-#  Set fuses and unlock memory
-ISPFUSES    = $(AVRDUDE_ROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-              -e -u -U lock:w:0x3f:m $(EFUSE_CMD) \
-              -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
-# program flash and lock memory.
-ISPFLASH    = $(AVRDUDE_ROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-              -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
-
 isp: $(PROGRAM)_$(TARGET).hex
-	$(ISPFUSES)
+	$(AVRDUDE_ROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
+              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+	$(ISPFUSES) \
 	$(ISPFLASH)

+ 8 - 3
optiboot/bootloaders/optiboot/makeall

@@ -8,13 +8,18 @@ make pro16
 make pro20
 make atmega328_pro8
 make sanguino
-make mega
-make atmega88
+make mega1280
 make luminet
 make diecimila
+make bobuino
+make wildfirev2
+make atmega1284
+make atmega32
+make atmega88
+
 #
 # The "big three" standard bootloaders.
-# These need to be built AFTER the platforms, or they'll get removed
+# These need to be built AFTER the platforms, or they'll get renamed
 make atmega8
 make atmega168
 make atmega328

+ 9 - 2
optiboot/bootloaders/optiboot/omake

@@ -1,2 +1,9 @@
-echo ../../../tools/avr/bin/make OS=macosx ENV=arduino $*
-../../../tools/avr/bin/make OS=macosx ENV=arduino $*
+#%/bin/bash
+if [ -d ../../../tools ]; then
+  mypath=../../../tools/avr/bin
+else
+ mypath=../../../../tools/avr/bin
+fi
+
+echo $mypath/make OS=macosx ENV=arduino $*
+$mypath/make OS=macosx ENV=arduino $*

+ 203 - 156
optiboot/bootloaders/optiboot/optiboot.c

@@ -1,3 +1,5 @@
+#define FUNC_READ 1
+#define FUNC_WRITE 1
 /**********************************************************/
 /* Optiboot bootloader for Arduino                        */
 /*                                                        */
@@ -94,16 +96,13 @@
 /*                                                        */
 /**********************************************************/
 /*                                                        */
-/* BIG_BOOT:                                              */
+/* BIGBOOT:                                              */
 /* 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.         */
 /*                                                        */
@@ -151,6 +150,24 @@
 /**********************************************************/
 /* Edit History:					  */
 /*							  */
+/* Jun 2014						  */
+/* 6.0 WestfW: Modularize memory read/write functions	  */
+/*             Remove serial/flash overlap		  */
+/*              (and all references to NRWWSTART/etc)	  */
+/*             Correctly handle pagesize > 255bytes       */
+/*             Add EEPROM support in BIGBOOT (1284)       */
+/*             EEPROM write on small chips now causes err */
+/*             Split Makefile into smaller pieces         */
+/*             Add Wicked devices Wildfire		  */
+/*	       Move UART=n conditionals into pin_defs.h   */
+/*	       Remove LUDICOUS_SPEED option		  */
+/*	       Replace inline assembler for .version      */
+/*              and add OPTIBOOT_CUSTOMVER for user code  */
+/*             Fix LED value for Bobuino (Makefile)       */
+/*             Make all functions explicitly inline or    */
+/*              noinline, so we fit when using gcc4.8     */
+/*             Change optimization options for gcc4.8	  */
+/*             Make ENV=arduino work in 1.5.x trees.	  */
 /* May 2014                                               */
 /* 5.0 WestfW: Add support for 1Mbps UART                 */
 /* Mar 2013                                               */
@@ -195,38 +212,63 @@
 /* 4.1 WestfW: put version number in binary.		  */
 /**********************************************************/
 
-#define OPTIBOOT_MAJVER 5
+#define OPTIBOOT_MAJVER 6
 #define OPTIBOOT_MINVER 0
 
+/*
+ * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
+ * of optiboot.  That way you don't wind up with very different code that
+ * matches the version number of a "released" optiboot.
+ */
+
+#if !defined(OPTIBOOT_CUSTOMVER)
+#define OPTIBOOT_CUSTOMVER 0
+#endif
+
+#if 0
 #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");
+#else
+unsigned int __attribute__((section(".version"))) 
+optiboot_version = 256*OPTIBOOT_MAJVER + OPTIBOOT_MINVER + OPTIBOOT_CUSTOMVER;
+#endif
+
 
 #include <inttypes.h>
 #include <avr/io.h>
 #include <avr/pgmspace.h>
+#include <avr/eeprom.h>
 
-// <avr/boot.h> uses sts instructions, but this version uses out instructions
-// This saves cycles and program memory.
+/*
+ * Note that we use our own version of "boot.h"
+ * <avr/boot.h> uses sts instructions, but this version uses out instructions
+ * This saves cycles and program memory.  Sorry for the name overlap.
+ */
 #include "boot.h"
 
 
 // We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
 
+/*
+ * pin_defs.h
+ * This contains most of the rather ugly defines that implement our
+ * ability to use UART=n and LED=D3, and some avr family bit name differences.
+ */
 #include "pin_defs.h"
+
+/*
+ * stk500.h contains the constant definitions for the stk500v1 comm protocol
+ */
 #include "stk500.h"
 
 #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
@@ -297,63 +339,48 @@ asm("  .section .version\n"
 #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. */
+/* Function Prototypes
+ * The main() function is in init9, which removes the interrupt vector table
+ * we don't need. It is also 'OS_main', which means the compiler does not
+ * generate any entry or exit code itself (but unlike 'naked', it doesn't
+ * supress some compile-time options we want.)
+ */
+
 int main(void) __attribute__ ((OS_main)) __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();
+
+void __attribute__((noinline)) putch(char);
+uint8_t __attribute__((noinline)) getch(void);
+void __attribute__((noinline)) verifySpace();
+void __attribute__((noinline)) watchdogConfig(uint8_t x);
+
+static inline void getNch(uint8_t);
 static inline void flash_led(uint8_t);
-uint8_t getLen();
 static inline void watchdogReset();
-void watchdogConfig(uint8_t x);
+static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
+			       uint16_t address, uint16_t len);
+static inline void read_mem(uint8_t memtype,
+			    uint16_t address, uint16_t len);
+
 #ifdef SOFT_UART
 void uartDelay() __attribute__ ((naked));
 #endif
 void appStart(uint8_t rstFlags) __attribute__ ((naked));
 
 /*
- * 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.
+ * lot of peripheral registers.  Let 0x100 be the default
+ * Note that RAMSTART need not be exactly at the start of RAM.
  */
-#if defined(__AVR_ATmega168__)
-#define RAMSTART (0x100)
-#define NRWWSTART (0x3800)
-#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32__)
-#define RAMSTART (0x100)
-#define NRWWSTART (0x7000)
-#elif defined (__AVR_ATmega644P__)
-#define RAMSTART (0x100)
-#define NRWWSTART (0xE000)
+#if !defined(RAMSTART)  // newer versions of gcc avr-libc define RAMSTART
+#define RAMSTART 0x100
+#if defined (__AVR_ATmega644P__)
 // 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__)
+#undef RAMSTART
 #define RAMSTART (0x200)
-#define NRWWSTART (0xE000)
-#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
-#define RAMSTART (0x100)
-#define NRWWSTART (0x1800)
+#endif
 #endif
 
 /* C zero initialises all global variables. However, that requires */
@@ -365,45 +392,6 @@ void appStart(uint8_t rstFlags) __attribute__ ((naked));
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
-/*
- * Handle devices with up to 4 uarts (eg m1280.)  Rather inelegantly.
- * Note that mega8/m32 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
-#if !defined(UDR1)
-#error UART == 1, but no UART1 on device
-#endif
-# define UART_SRA UCSR1A
-# define UART_SRB UCSR1B
-# define UART_SRC UCSR1C
-# define UART_SRL UBRR1L
-# define UART_UDR UDR1
-#elif UART == 2
-#if !defined(UDR2)
-#error UART == 2, but no UART2 on device
-#endif
-# define UART_SRA UCSR2A
-# define UART_SRB UCSR2B
-# define UART_SRC UCSR2C
-# define UART_SRL UBRR2L
-# define UART_UDR UDR2
-#elif UART == 3
-#if !defined(UDR1)
-#error UART == 3, but no UART3 on device
-#endif
-# 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) {
@@ -416,7 +404,7 @@ int main(void) {
    *  necessary, and uses 4 bytes of flash.)
    */
   register uint16_t address = 0;
-  register uint8_t  length;
+  register uint16_t  length;
 
   // After the zero init loop, this is the first code to run.
   //
@@ -441,6 +429,7 @@ int main(void) {
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
 #endif
+
 #ifndef SOFT_UART
 #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
   UCSRA = _BV(U2X); //Double speed mode USART
@@ -473,7 +462,7 @@ int main(void) {
   flash_led(LED_START_FLASHES * 2);
 #endif
 
-  /* Forever loop */
+  /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
@@ -525,34 +514,23 @@ int main(void) {
     /* 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 desttype;
       uint8_t *bufPtr;
-      uint16_t addrPtr;
-
-      getch();			/* getlen() */
-      length = getch();
-      getch();
+      uint16_t savelength;
 
-      // If we are in RWW section, immediately start page erase
-      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
+      length = getch()<<8;			/* getlen() */
+      length |= getch();
+      savelength = length;
+      desttype = getch();
 
-      // While that is going on, read in page contents
+      // read a page worth of 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 (not doing so just means that we will
-      //  treat the top of both "pages" of flash as NRWW, for a slight speed
-      //  decrease, so fixing this is not urgent.)
-      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
-      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
@@ -572,58 +550,20 @@ int main(void) {
       }
 #endif
 
-      // Copy buffer into programming buffer
-      bufPtr = buff;
-      addrPtr = (uint16_t)(void*)address;
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-        a |= (*bufPtr++) << 8;
-        __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();
+      writebuffer(desttype, buff, address, savelength);
 
-#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) {
-      // READ PAGE - we only read flash
-      getch();			/* getlen() */
-      length = getch();
-      getch();
+      uint8_t desttype;
+      length = getch()<<8;			/* getlen() */
+      length |= getch();
+      desttype = getch();
 
       verifySpace();
-      do {
-#ifdef VIRTUAL_BOOT_PARTITION
-        // 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++;
-#elif defined(RAMPZ)
-        // Since RAMPZ should already be set, we need to use EPLM directly.
-        // Also, we can use the autoincrement version of lpm to update "address"
-        //      do putch(pgm_read_byte_near(address++));
-        //      while (--length);
-        // read a Flash and increment the address (may increment RAMPZ)
-        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#else
-        // read a Flash byte and increment the address
-        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#endif
-        putch(ch);
-      } while (--length);
+	  
+      read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
@@ -822,3 +762,110 @@ void appStart(uint8_t rstFlags) {
     "ijmp\n"
   );
 }
+
+/*
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
+			       uint16_t address, uint16_t len)
+{
+    switch (memtype) {
+    case 'E': // EEPROM
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+        while(len--) {
+	    eeprom_write_byte((uint8_t *)(address++), *mybuff++);
+        }
+#else
+	/*
+	 * On systems where EEPROM write is not supported, just busy-loop
+	 * until the WDT expires, which will eventually cause an error on
+	 * host system (which is what it should do.)
+	 */
+	while (1)
+	    ; // Error: wait for WDT
+#endif
+	break;
+    default:  // FLASH
+	/*
+	 * Default to writing to Flash program memory.  By making this
+	 * the default rather than checking for the correct code, we save
+	 * space on chips that don't support any other memory types.
+	 */
+	{
+	    // Copy buffer into programming buffer
+	    uint8_t *bufPtr = mybuff;
+	    uint16_t addrPtr = (uint16_t)(void*)address;
+
+	    /*
+	     * Start the page erase and wait for it to finish.  There
+	     * used to be code to do this while receiving the data over
+	     * the serial link, but the performance improvement was slight,
+	     * and we needed the space back.
+	     */
+	    __boot_page_erase_short((uint16_t)(void*)address);
+	    boot_spm_busy_wait();
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
+	     */
+	    do {
+		uint16_t a;
+		a = *bufPtr++;
+		a |= (*bufPtr++) << 8;
+		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
+		addrPtr += 2;
+	    } while (len -= 2);
+
+	    /*
+	     * Actually Write the buffer to flash (and wait for it to finish.)
+	     */
+	    __boot_page_write_short((uint16_t)(void*)address);
+	    boot_spm_busy_wait();
+#if defined(RWWSRE)
+	    // Reenable read access to flash
+	    boot_rww_enable();
+#endif
+	} // default block
+	break;
+    } // switch
+}
+
+static inline void read_mem(uint8_t memtype, uint16_t address, uint16_t length)
+{
+    uint8_t ch;
+
+    switch (memtype) {
+
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+    case 'E': // EEPROM
+	do {
+	    putch(eeprom_read_byte((uint8_t *)(address++)));
+	} while (--length);
+	break;
+#endif
+    default:
+	do {
+#ifdef VIRTUAL_BOOT_PARTITION
+        // 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++;
+#elif defined(RAMPZ)
+	    // Since RAMPZ should already be set, we need to use EPLM directly.
+	    // Also, we can use the autoincrement version of lpm to update "address"
+	    //      do putch(pgm_read_byte_near(address++));
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+#else
+	    // read a Flash byte and increment the address
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+#endif
+	    putch(ch);
+	} while (--length);
+	break;
+    } // switch
+}

+ 40 - 0
optiboot/bootloaders/optiboot/pin_defs.h

@@ -18,6 +18,46 @@
 #endif
 #endif
 
+/*
+ * Handle devices with up to 4 uarts (eg m1280.)  Rather inelegantly.
+ * Note that mega8/m32 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
+#if !defined(UDR1)
+#error UART == 1, but no UART1 on device
+#endif
+# define UART_SRA UCSR1A
+# define UART_SRB UCSR1B
+# define UART_SRC UCSR1C
+# define UART_SRL UBRR1L
+# define UART_UDR UDR1
+#elif UART == 2
+#if !defined(UDR2)
+#error UART == 2, but no UART2 on device
+#endif
+# define UART_SRA UCSR2A
+# define UART_SRB UCSR2B
+# define UART_SRC UCSR2C
+# define UART_SRL UBRR2L
+# define UART_UDR UDR2
+#elif UART == 3
+#if !defined(UDR1)
+#error UART == 3, but no UART3 on device
+#endif
+# define UART_SRA UCSR3A
+# define UART_SRB UCSR3B
+# define UART_SRC UCSR3C
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
+#endif
+
 #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega32__)
   //Name conversion R.Wiersma
   #define UCSR0A	UCSRA