Added the optiboot bootloader, uses only 512kB of FLASH Includes .hex file is for 20MHz µC Clock and serial speed of 57k6master
							parent
							
								
									5bfba7720e
								
							
						
					
					
						commit
						f991bf23b2
					
				| @ -0,0 +1,470 @@ | |||||||
|  | # 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
 | ||||||
|  | ISPTOOL    = stk500v2 | ||||||
|  | ISPPORT    = usb | ||||||
|  | ISPSPEED   = -b 115200 | ||||||
|  | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | # 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: 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 115200 baud on PC (Arduino Avrdude issue)
 | ||||||
|  | #
 | ||||||
|  | 
 | ||||||
|  | pro20: TARGET = pro_20mhz | ||||||
|  | pro20: MCU_TARGET = atmega168 | ||||||
|  | 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
 | ||||||
|  | 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 115200 baud on PC (Arduino Avrdude issue)
 | ||||||
|  | #
 | ||||||
|  | 
 | ||||||
|  | pro16: TARGET = pro_16MHz | ||||||
|  | pro16: MCU_TARGET = atmega168 | ||||||
|  | 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
 | ||||||
|  | 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=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
 | ||||||
|  | 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: TARGET = atmega328 | ||||||
|  | atmega328: MCU_TARGET = atmega328p | ||||||
|  | atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' | ||||||
|  | atmega328: AVR_FREQ = 16000000L | ||||||
|  | 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, SPIEN
 | ||||||
|  | atmega328_isp: HFUSE = DE | ||||||
|  | # Low power xtal (16MHz) 16KCK/14CK+65ms
 | ||||||
|  | atmega328_isp: LFUSE = FF | ||||||
|  | # 2.7V brownout
 | ||||||
|  | atmega328_isp: EFUSE = 05 | ||||||
|  | atmega328_isp: isp | ||||||
|  | 
 | ||||||
|  | atmega1284: TARGET = atmega1284p | ||||||
|  | atmega1284: MCU_TARGET = atmega1284p | ||||||
|  | atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' | ||||||
|  | atmega1284: AVR_FREQ = 16000000L | ||||||
|  | atmega1284: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00 | ||||||
|  | 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=115200' '-DBIGBOOT' | ||||||
|  | sanguino: AVR_FREQ = 16000000L | ||||||
|  | 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 | ||||||
|  | # 1024 byte boot
 | ||||||
|  | sanguino_isp: HFUSE = DE | ||||||
|  | # Low power xtal (16MHz) 16KCK/14CK+65ms
 | ||||||
|  | sanguino_isp: LFUSE = FF | ||||||
|  | # 2.7V brownout
 | ||||||
|  | sanguino_isp: EFUSE = 05 | ||||||
|  | sanguino_isp: isp | ||||||
|  | 
 | ||||||
|  | # Mega has a minimum boot size of 1024 bytes, so enable extra functions
 | ||||||
|  | #mega: TARGET = atmega1280
 | ||||||
|  | mega: MCU_TARGET = atmega1280 | ||||||
|  | mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' | ||||||
|  | mega: AVR_FREQ = 16000000L | ||||||
|  | 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 | ||||||
|  | # 1024 byte boot
 | ||||||
|  | mega_isp: HFUSE = DE | ||||||
|  | # Low power xtal (16MHz) 16KCK/14CK+65ms
 | ||||||
|  | mega_isp: LFUSE = FF | ||||||
|  | # 2.7V brownout
 | ||||||
|  | mega_isp: EFUSE = 05 | ||||||
|  | mega_isp: isp | ||||||
|  | 
 | ||||||
|  | # ATmega8
 | ||||||
|  | #
 | ||||||
|  | atmega8: TARGET = atmega8 | ||||||
|  | atmega8: MCU_TARGET = atmega8 | ||||||
|  | atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' | ||||||
|  | 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=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 | ||||||
|  | # 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 115200 baud
 | ||||||
|  | #
 | ||||||
|  | 
 | ||||||
|  | lilypad: TARGET = lilypad | ||||||
|  | lilypad: MCU_TARGET = atmega168 | ||||||
|  | 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
 | ||||||
|  | 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=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
 | ||||||
|  | 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=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
 | ||||||
|  | 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=115200' | ||||||
|  | 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 = 05 | ||||||
|  | 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 $< $@ | ||||||
| @ -0,0 +1,848 @@ | |||||||
|  | /* Modified to use out for SPM access
 | ||||||
|  | ** Peter Knight, Optiboot project http://optiboot.googlecode.com
 | ||||||
|  | ** | ||||||
|  | ** Todo: Tidy up | ||||||
|  | ** | ||||||
|  | ** "_short" routines execute 1 cycle faster and use 1 less word of flash | ||||||
|  | ** by using "out" instruction instead of "sts". | ||||||
|  | ** | ||||||
|  | ** Additional elpm variants that trust the value of RAMPZ | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007  Eric B. Weddington
 | ||||||
|  |    All rights reserved. | ||||||
|  | 
 | ||||||
|  |    Redistribution and use in source and binary forms, with or without | ||||||
|  |    modification, are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  |    * Redistributions of source code must retain the above copyright | ||||||
|  |      notice, this list of conditions and the following disclaimer. | ||||||
|  |    * Redistributions in binary form must reproduce the above copyright | ||||||
|  |      notice, this list of conditions and the following disclaimer in | ||||||
|  |      the documentation and/or other materials provided with the | ||||||
|  |      distribution. | ||||||
|  |    * Neither the name of the copyright holders nor the names of | ||||||
|  |      contributors may be used to endorse or promote products derived | ||||||
|  |      from this software without specific prior written permission. | ||||||
|  | 
 | ||||||
|  |   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||||
|  |   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||||
|  |   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||||
|  |   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||||||
|  |   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  |   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  |   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  |   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  |   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  |   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
|  |   POSSIBILITY OF SUCH DAMAGE. */ | ||||||
|  | 
 | ||||||
|  | /* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */ | ||||||
|  | 
 | ||||||
|  | #ifndef _AVR_BOOT_H_ | ||||||
|  | #define _AVR_BOOT_H_    1 | ||||||
|  | 
 | ||||||
|  | /** \file */ | ||||||
|  | /** \defgroup avr_boot <avr/boot.h>: Bootloader Support Utilities
 | ||||||
|  |     \code | ||||||
|  |     #include <avr/io.h> | ||||||
|  |     #include <avr/boot.h> | ||||||
|  |     \endcode | ||||||
|  | 
 | ||||||
|  |     The macros in this module provide a C language interface to the | ||||||
|  |     bootloader support functionality of certain AVR processors. These | ||||||
|  |     macros are designed to work with all sizes of flash memory. | ||||||
|  | 
 | ||||||
|  |     Global interrupts are not automatically disabled for these macros. It | ||||||
|  |     is left up to the programmer to do this. See the code example below.  | ||||||
|  |     Also see the processor datasheet for caveats on having global interrupts  | ||||||
|  |     enabled during writing of the Flash. | ||||||
|  | 
 | ||||||
|  |     \note Not all AVR processors provide bootloader support. See your | ||||||
|  |     processor datasheet to see if it provides bootloader support. | ||||||
|  | 
 | ||||||
|  |     \todo From email with Marek: On smaller devices (all except ATmega64/128), | ||||||
|  |     __SPM_REG is in the I/O space, accessible with the shorter "in" and "out" | ||||||
|  |     instructions - since the boot loader has a limited size, this could be an | ||||||
|  |     important optimization. | ||||||
|  | 
 | ||||||
|  |     \par API Usage Example | ||||||
|  |     The following code shows typical usage of the boot API. | ||||||
|  | 
 | ||||||
|  |     \code | ||||||
|  |     #include <inttypes.h> | ||||||
|  |     #include <avr/interrupt.h> | ||||||
|  |     #include <avr/pgmspace.h> | ||||||
|  |      | ||||||
|  |     void boot_program_page (uint32_t page, uint8_t *buf) | ||||||
|  |     { | ||||||
|  |         uint16_t i; | ||||||
|  |         uint8_t sreg; | ||||||
|  | 
 | ||||||
|  |         // Disable interrupts.
 | ||||||
|  | 
 | ||||||
|  |         sreg = SREG; | ||||||
|  |         cli(); | ||||||
|  |      | ||||||
|  |         eeprom_busy_wait (); | ||||||
|  | 
 | ||||||
|  |         boot_page_erase (page); | ||||||
|  |         boot_spm_busy_wait ();      // Wait until the memory is erased.
 | ||||||
|  | 
 | ||||||
|  |         for (i=0; i<SPM_PAGESIZE; i+=2) | ||||||
|  |         { | ||||||
|  |             // Set up little-endian word.
 | ||||||
|  | 
 | ||||||
|  |             uint16_t w = *buf++; | ||||||
|  |             w += (*buf++) << 8; | ||||||
|  |          | ||||||
|  |             boot_page_fill (page + i, w); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         boot_page_write (page);     // Store buffer in flash page.
 | ||||||
|  |         boot_spm_busy_wait();       // Wait until the memory is written.
 | ||||||
|  | 
 | ||||||
|  |         // Reenable RWW-section again. We need this if we want to jump back
 | ||||||
|  |         // to the application after bootloading.
 | ||||||
|  | 
 | ||||||
|  |         boot_rww_enable (); | ||||||
|  | 
 | ||||||
|  |         // Re-enable interrupts (if they were ever enabled).
 | ||||||
|  | 
 | ||||||
|  |         SREG = sreg; | ||||||
|  |     }\endcode */ | ||||||
|  | 
 | ||||||
|  | #include <avr/eeprom.h> | ||||||
|  | #include <avr/io.h> | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <limits.h> | ||||||
|  | 
 | ||||||
|  | /* Check for SPM Control Register in processor. */ | ||||||
|  | #if defined (SPMCSR) | ||||||
|  | #  define __SPM_REG    SPMCSR | ||||||
|  | #elif defined (SPMCR) | ||||||
|  | #  define __SPM_REG    SPMCR | ||||||
|  | #else | ||||||
|  | #  error AVR processor does not provide bootloader support! | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Check for SPM Enable bit. */ | ||||||
|  | #if defined(SPMEN) | ||||||
|  | #  define __SPM_ENABLE  SPMEN | ||||||
|  | #elif defined(SELFPRGEN) | ||||||
|  | #  define __SPM_ENABLE  SELFPRGEN | ||||||
|  | #else | ||||||
|  | #  error Cannot find SPM Enable bit definition! | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def BOOTLOADER_SECTION | ||||||
|  | 
 | ||||||
|  |     Used to declare a function or variable to be placed into a | ||||||
|  |     new section called .bootloader. This section and its contents | ||||||
|  |     can then be relocated to any address (such as the bootloader | ||||||
|  |     NRWW area) at link-time. */ | ||||||
|  | 
 | ||||||
|  | #define BOOTLOADER_SECTION    __attribute__ ((section (".bootloader"))) | ||||||
|  | 
 | ||||||
|  | /* Create common bit definitions. */ | ||||||
|  | #ifdef ASB | ||||||
|  | #define __COMMON_ASB    ASB | ||||||
|  | #else | ||||||
|  | #define __COMMON_ASB    RWWSB | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef ASRE | ||||||
|  | #define __COMMON_ASRE   ASRE | ||||||
|  | #else | ||||||
|  | #define __COMMON_ASRE   RWWSRE | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Define the bit positions of the Boot Lock Bits. */ | ||||||
|  | 
 | ||||||
|  | #define BLB12           5 | ||||||
|  | #define BLB11           4 | ||||||
|  | #define BLB02           3 | ||||||
|  | #define BLB01           2 | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_spm_interrupt_enable() | ||||||
|  |     Enable the SPM interrupt. */ | ||||||
|  | 
 | ||||||
|  | #define boot_spm_interrupt_enable()   (__SPM_REG |= (uint8_t)_BV(SPMIE)) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_spm_interrupt_disable() | ||||||
|  |     Disable the SPM interrupt. */ | ||||||
|  | 
 | ||||||
|  | #define boot_spm_interrupt_disable()  (__SPM_REG &= (uint8_t)~_BV(SPMIE)) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_is_spm_interrupt() | ||||||
|  |     Check if the SPM interrupt is enabled. */ | ||||||
|  | 
 | ||||||
|  | #define boot_is_spm_interrupt()       (__SPM_REG & (uint8_t)_BV(SPMIE)) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_rww_busy() | ||||||
|  |     Check if the RWW section is busy. */ | ||||||
|  | 
 | ||||||
|  | #define boot_rww_busy()          (__SPM_REG & (uint8_t)_BV(__COMMON_ASB)) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_spm_busy() | ||||||
|  |     Check if the SPM instruction is busy. */ | ||||||
|  | 
 | ||||||
|  | #define boot_spm_busy()               (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE)) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_spm_busy_wait() | ||||||
|  |     Wait while the SPM instruction is busy. */ | ||||||
|  | 
 | ||||||
|  | #define boot_spm_busy_wait()          do{}while(boot_spm_busy()) | ||||||
|  | 
 | ||||||
|  | #define __BOOT_PAGE_ERASE         (_BV(__SPM_ENABLE) | _BV(PGERS)) | ||||||
|  | #define __BOOT_PAGE_WRITE         (_BV(__SPM_ENABLE) | _BV(PGWRT)) | ||||||
|  | #define __BOOT_PAGE_FILL          _BV(__SPM_ENABLE) | ||||||
|  | #define __BOOT_RWW_ENABLE         (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE)) | ||||||
|  | #define __BOOT_LOCK_BITS_SET      (_BV(__SPM_ENABLE) | _BV(BLBSET)) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_fill_short(address, data)   \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw  r0, %3\n\t"                       \ | ||||||
|  |         "out %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         "clr  r1\n\t"                            \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_FILL),       \ | ||||||
|  |           "z" ((uint16_t)address),               \ | ||||||
|  |           "r" ((uint16_t)data)                   \ | ||||||
|  |         : "r0"                                   \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_fill_normal(address, data)   \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw  r0, %3\n\t"                       \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         "clr  r1\n\t"                            \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_FILL),       \ | ||||||
|  |           "z" ((uint16_t)address),               \ | ||||||
|  |           "r" ((uint16_t)data)                   \ | ||||||
|  |         : "r0"                                   \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_fill_alternate(address, data)\ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw  r0, %3\n\t"                       \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         ".word 0xffff\n\t"                       \ | ||||||
|  |         "nop\n\t"                                \ | ||||||
|  |         "clr  r1\n\t"                            \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_FILL),       \ | ||||||
|  |           "z" ((uint16_t)address),               \ | ||||||
|  |           "r" ((uint16_t)data)                   \ | ||||||
|  |         : "r0"                                   \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_fill_extended(address, data) \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw  r0, %4\n\t"                       \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "sts %1, %C3\n\t"                        \ | ||||||
|  |         "sts %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         "clr  r1\n\t"                            \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_MEM_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_FILL),       \ | ||||||
|  |           "r" ((uint32_t)address),               \ | ||||||
|  |           "r" ((uint16_t)data)                   \ | ||||||
|  |         : "r0", "r30", "r31"                     \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_fill_extended_short(address, data) \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw  r0, %4\n\t"                       \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "out %1, %C3\n\t"                        \ | ||||||
|  |         "out %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         "clr  r1\n\t"                            \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_IO_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_FILL),       \ | ||||||
|  |           "r" ((uint32_t)address),               \ | ||||||
|  |           "r" ((uint16_t)data)                   \ | ||||||
|  |         : "r0", "r30", "r31"                     \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_erase_short(address)        \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "out %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_ERASE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define __boot_page_erase_normal(address)        \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_ERASE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_erase_alternate(address)     \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         ".word 0xffff\n\t"                       \ | ||||||
|  |         "nop\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_ERASE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_erase_extended(address)      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "sts  %1, %C3\n\t"                       \ | ||||||
|  |         "sts %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_MEM_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_ERASE),      \ | ||||||
|  |           "r" ((uint32_t)address)                \ | ||||||
|  |         : "r30", "r31"                           \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | #define __boot_page_erase_extended_short(address)      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "out  %1, %C3\n\t"                       \ | ||||||
|  |         "out %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_IO_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_ERASE),      \ | ||||||
|  |           "r" ((uint32_t)address)                \ | ||||||
|  |         : "r30", "r31"                           \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_write_short(address)        \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "out %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_WRITE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_write_normal(address)        \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_WRITE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_write_alternate(address)     \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         ".word 0xffff\n\t"                       \ | ||||||
|  |         "nop\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_WRITE),      \ | ||||||
|  |           "z" ((uint16_t)address)                \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_page_write_extended(address)      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "sts %1, %C3\n\t"                        \ | ||||||
|  |         "sts %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_MEM_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_WRITE),      \ | ||||||
|  |           "r" ((uint32_t)address)                \ | ||||||
|  |         : "r30", "r31"                           \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | #define __boot_page_write_extended_short(address)      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "movw r30, %A3\n\t"                      \ | ||||||
|  |         "out %1, %C3\n\t"                        \ | ||||||
|  |         "out %0, %2\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "i" (_SFR_IO_ADDR(RAMPZ)),            \ | ||||||
|  |           "r" ((uint8_t)__BOOT_PAGE_WRITE),      \ | ||||||
|  |           "r" ((uint32_t)address)                \ | ||||||
|  |         : "r30", "r31"                           \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_rww_enable_short()                      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "out %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_RWW_ENABLE)       \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_rww_enable()                      \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_RWW_ENABLE)       \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_rww_enable_alternate()            \ | ||||||
|  | (__extension__({                                 \ | ||||||
|  |     __asm__ __volatile__                         \ | ||||||
|  |     (                                            \ | ||||||
|  |         "sts %0, %1\n\t"                         \ | ||||||
|  |         "spm\n\t"                                \ | ||||||
|  |         ".word 0xffff\n\t"                       \ | ||||||
|  |         "nop\n\t"                                \ | ||||||
|  |         :                                        \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t)__BOOT_RWW_ENABLE)       \ | ||||||
|  |     );                                           \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | /* From the mega16/mega128 data sheets (maybe others):
 | ||||||
|  | 
 | ||||||
|  |      Bits by SPM To set the Boot Loader Lock bits, write the desired data to | ||||||
|  |      R0, write "X0001001" to SPMCR and execute SPM within four clock cycles | ||||||
|  |      after writing SPMCR. The only accessible Lock bits are the Boot Lock bits | ||||||
|  |      that may prevent the Application and Boot Loader section from any | ||||||
|  |      software update by the MCU. | ||||||
|  | 
 | ||||||
|  |      If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit | ||||||
|  |      will be programmed if an SPM instruction is executed within four cycles | ||||||
|  |      after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is  | ||||||
|  |      don't care during this operation, but for future compatibility it is  | ||||||
|  |      recommended to load the Z-pointer with $0001 (same as used for reading the  | ||||||
|  |      Lock bits). For future compatibility It is also recommended to set bits 7,  | ||||||
|  |      6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the  | ||||||
|  |      Lock bits the entire Flash can be read during the operation. */ | ||||||
|  | 
 | ||||||
|  | #define __boot_lock_bits_set_short(lock_bits)                    \ | ||||||
|  | (__extension__({                                           \ | ||||||
|  |     uint8_t value = (uint8_t)(~(lock_bits));               \ | ||||||
|  |     __asm__ __volatile__                                   \ | ||||||
|  |     (                                                      \ | ||||||
|  |         "ldi r30, 1\n\t"                                   \ | ||||||
|  |         "ldi r31, 0\n\t"                                   \ | ||||||
|  |         "mov r0, %2\n\t"                                   \ | ||||||
|  |         "out %0, %1\n\t"                                   \ | ||||||
|  |         "spm\n\t"                                          \ | ||||||
|  |         :                                                  \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \ | ||||||
|  |           "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \ | ||||||
|  |           "r" (value)                                      \ | ||||||
|  |         : "r0", "r30", "r31"                               \ | ||||||
|  |     );                                                     \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_lock_bits_set(lock_bits)                    \ | ||||||
|  | (__extension__({                                           \ | ||||||
|  |     uint8_t value = (uint8_t)(~(lock_bits));               \ | ||||||
|  |     __asm__ __volatile__                                   \ | ||||||
|  |     (                                                      \ | ||||||
|  |         "ldi r30, 1\n\t"                                   \ | ||||||
|  |         "ldi r31, 0\n\t"                                   \ | ||||||
|  |         "mov r0, %2\n\t"                                   \ | ||||||
|  |         "sts %0, %1\n\t"                                   \ | ||||||
|  |         "spm\n\t"                                          \ | ||||||
|  |         :                                                  \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \ | ||||||
|  |           "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \ | ||||||
|  |           "r" (value)                                      \ | ||||||
|  |         : "r0", "r30", "r31"                               \ | ||||||
|  |     );                                                     \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define __boot_lock_bits_set_alternate(lock_bits)          \ | ||||||
|  | (__extension__({                                           \ | ||||||
|  |     uint8_t value = (uint8_t)(~(lock_bits));               \ | ||||||
|  |     __asm__ __volatile__                                   \ | ||||||
|  |     (                                                      \ | ||||||
|  |         "ldi r30, 1\n\t"                                   \ | ||||||
|  |         "ldi r31, 0\n\t"                                   \ | ||||||
|  |         "mov r0, %2\n\t"                                   \ | ||||||
|  |         "sts %0, %1\n\t"                                   \ | ||||||
|  |         "spm\n\t"                                          \ | ||||||
|  |         ".word 0xffff\n\t"                                 \ | ||||||
|  |         "nop\n\t"                                          \ | ||||||
|  |         :                                                  \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \ | ||||||
|  |           "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \ | ||||||
|  |           "r" (value)                                      \ | ||||||
|  |         : "r0", "r30", "r31"                               \ | ||||||
|  |     );                                                     \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |    Reading lock and fuse bits: | ||||||
|  | 
 | ||||||
|  |      Similarly to writing the lock bits above, set BLBSET and SPMEN (or  | ||||||
|  |      SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an  | ||||||
|  |      LPM instruction. | ||||||
|  | 
 | ||||||
|  |      Z address:       contents: | ||||||
|  |      0x0000           low fuse bits | ||||||
|  |      0x0001           lock bits | ||||||
|  |      0x0002           extended fuse bits | ||||||
|  |      0x0003           high fuse bits | ||||||
|  | 
 | ||||||
|  |      Sounds confusing, doesn't it? | ||||||
|  | 
 | ||||||
|  |      Unlike the macros in pgmspace.h, no need to care for non-enhanced | ||||||
|  |      cores here as these old cores do not provide SPM support anyway. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def GET_LOW_FUSE_BITS | ||||||
|  |     address to read the low fuse bits, using boot_lock_fuse_bits_get | ||||||
|  |  */ | ||||||
|  | #define GET_LOW_FUSE_BITS           (0x0000) | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def GET_LOCK_BITS | ||||||
|  |     address to read the lock bits, using boot_lock_fuse_bits_get | ||||||
|  |  */ | ||||||
|  | #define GET_LOCK_BITS               (0x0001) | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def GET_EXTENDED_FUSE_BITS | ||||||
|  |     address to read the extended fuse bits, using boot_lock_fuse_bits_get | ||||||
|  |  */ | ||||||
|  | #define GET_EXTENDED_FUSE_BITS      (0x0002) | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def GET_HIGH_FUSE_BITS | ||||||
|  |     address to read the high fuse bits, using boot_lock_fuse_bits_get | ||||||
|  |  */ | ||||||
|  | #define GET_HIGH_FUSE_BITS          (0x0003) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_lock_fuse_bits_get(address) | ||||||
|  | 
 | ||||||
|  |     Read the lock or fuse bits at \c address. | ||||||
|  | 
 | ||||||
|  |     Parameter \c address can be any of GET_LOW_FUSE_BITS, | ||||||
|  |     GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS. | ||||||
|  | 
 | ||||||
|  |     \note The lock and fuse bits returned are the physical values, | ||||||
|  |     i.e. a bit returned as 0 means the corresponding fuse or lock bit | ||||||
|  |     is programmed. | ||||||
|  |  */ | ||||||
|  | #define boot_lock_fuse_bits_get_short(address)                   \ | ||||||
|  | (__extension__({                                           \ | ||||||
|  |     uint8_t __result;                                      \ | ||||||
|  |     __asm__ __volatile__                                   \ | ||||||
|  |     (                                                      \ | ||||||
|  |         "ldi r30, %3\n\t"                                  \ | ||||||
|  |         "ldi r31, 0\n\t"                                   \ | ||||||
|  |         "out %1, %2\n\t"                                   \ | ||||||
|  |         "lpm %0, Z\n\t"                                    \ | ||||||
|  |         : "=r" (__result)                                  \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \ | ||||||
|  |           "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \ | ||||||
|  |           "M" (address)                                    \ | ||||||
|  |         : "r0", "r30", "r31"                               \ | ||||||
|  |     );                                                     \ | ||||||
|  |     __result;                                              \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define boot_lock_fuse_bits_get(address)                   \ | ||||||
|  | (__extension__({                                           \ | ||||||
|  |     uint8_t __result;                                      \ | ||||||
|  |     __asm__ __volatile__                                   \ | ||||||
|  |     (                                                      \ | ||||||
|  |         "ldi r30, %3\n\t"                                  \ | ||||||
|  |         "ldi r31, 0\n\t"                                   \ | ||||||
|  |         "sts %1, %2\n\t"                                   \ | ||||||
|  |         "lpm %0, Z\n\t"                                    \ | ||||||
|  |         : "=r" (__result)                                  \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \ | ||||||
|  |           "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \ | ||||||
|  |           "M" (address)                                    \ | ||||||
|  |         : "r0", "r30", "r31"                               \ | ||||||
|  |     );                                                     \ | ||||||
|  |     __result;                                              \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_signature_byte_get(address) | ||||||
|  | 
 | ||||||
|  |     Read the Signature Row byte at \c address.  For some MCU types, | ||||||
|  |     this function can also retrieve the factory-stored oscillator | ||||||
|  |     calibration bytes. | ||||||
|  | 
 | ||||||
|  |     Parameter \c address can be 0-0x1f as documented by the datasheet. | ||||||
|  |     \note The values are MCU type dependent. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD)) | ||||||
|  | 
 | ||||||
|  | #define boot_signature_byte_get_short(addr) \ | ||||||
|  | (__extension__({                      \ | ||||||
|  |       uint16_t __addr16 = (uint16_t)(addr);     \ | ||||||
|  |       uint8_t __result;                         \ | ||||||
|  |       __asm__ __volatile__                      \ | ||||||
|  |       (                                         \ | ||||||
|  |         "out %1, %2\n\t"                        \ | ||||||
|  |         "lpm %0, Z" "\n\t"                      \ | ||||||
|  |         : "=r" (__result)                       \ | ||||||
|  |         : "i" (_SFR_IO_ADDR(__SPM_REG)),        \ | ||||||
|  |           "r" ((uint8_t) __BOOT_SIGROW_READ),   \ | ||||||
|  |           "z" (__addr16)                        \ | ||||||
|  |       );                                        \ | ||||||
|  |       __result;                                 \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | #define boot_signature_byte_get(addr) \ | ||||||
|  | (__extension__({                      \ | ||||||
|  |       uint16_t __addr16 = (uint16_t)(addr);     \ | ||||||
|  |       uint8_t __result;                         \ | ||||||
|  |       __asm__ __volatile__                      \ | ||||||
|  |       (                                         \ | ||||||
|  |         "sts %1, %2\n\t"                        \ | ||||||
|  |         "lpm %0, Z" "\n\t"                      \ | ||||||
|  |         : "=r" (__result)                       \ | ||||||
|  |         : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \ | ||||||
|  |           "r" ((uint8_t) __BOOT_SIGROW_READ),   \ | ||||||
|  |           "z" (__addr16)                        \ | ||||||
|  |       );                                        \ | ||||||
|  |       __result;                                 \ | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_page_fill(address, data) | ||||||
|  | 
 | ||||||
|  |     Fill the bootloader temporary page buffer for flash  | ||||||
|  |     address with data word.  | ||||||
|  | 
 | ||||||
|  |     \note The address is a byte address. The data is a word. The AVR  | ||||||
|  |     writes data to the buffer a word at a time, but addresses the buffer | ||||||
|  |     per byte! So, increment your address by 2 between calls, and send 2 | ||||||
|  |     data bytes in a word format! The LSB of the data is written to the lower  | ||||||
|  |     address; the MSB of the data is written to the higher address.*/ | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_page_erase(address) | ||||||
|  | 
 | ||||||
|  |     Erase the flash page that contains address. | ||||||
|  | 
 | ||||||
|  |     \note address is a byte address in flash, not a word address. */ | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_page_write(address) | ||||||
|  | 
 | ||||||
|  |     Write the bootloader temporary page buffer  | ||||||
|  |     to flash page that contains address. | ||||||
|  |      | ||||||
|  |     \note address is a byte address in flash, not a word address. */ | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_rww_enable() | ||||||
|  | 
 | ||||||
|  |     Enable the Read-While-Write memory section. */ | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  |     \def boot_lock_bits_set(lock_bits) | ||||||
|  | 
 | ||||||
|  |     Set the bootloader lock bits. | ||||||
|  | 
 | ||||||
|  |     \param lock_bits A mask of which Boot Loader Lock Bits to set. | ||||||
|  | 
 | ||||||
|  |     \note In this context, a 'set bit' will be written to a zero value. | ||||||
|  |     Note also that only BLBxx bits can be programmed by this command. | ||||||
|  | 
 | ||||||
|  |     For example, to disallow the SPM instruction from writing to the Boot | ||||||
|  |     Loader memory section of flash, you would use this macro as such: | ||||||
|  | 
 | ||||||
|  |     \code | ||||||
|  |     boot_lock_bits_set (_BV (BLB11)); | ||||||
|  |     \endcode | ||||||
|  | 
 | ||||||
|  |     \note Like any lock bits, the Boot Loader Lock Bits, once set, | ||||||
|  |     cannot be cleared again except by a chip erase which will in turn | ||||||
|  |     also erase the boot loader itself. */ | ||||||
|  | 
 | ||||||
|  | /* Normal versions of the macros use 16-bit addresses.
 | ||||||
|  |    Extended versions of the macros use 32-bit addresses. | ||||||
|  |    Alternate versions of the macros use 16-bit addresses and require special | ||||||
|  |    instruction sequences after LPM. | ||||||
|  | 
 | ||||||
|  |    FLASHEND is defined in the ioXXXX.h file. | ||||||
|  |    USHRT_MAX is defined in <limits.h>. */  | ||||||
|  | 
 | ||||||
|  | #if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \ | ||||||
|  |     || defined(__AVR_ATmega323__) | ||||||
|  | 
 | ||||||
|  | /* Alternate: ATmega161/163/323 and 16 bit address */ | ||||||
|  | #define boot_page_fill(address, data) __boot_page_fill_alternate(address, data) | ||||||
|  | #define boot_page_erase(address)      __boot_page_erase_alternate(address) | ||||||
|  | #define boot_page_write(address)      __boot_page_write_alternate(address) | ||||||
|  | #define boot_rww_enable()             __boot_rww_enable_alternate() | ||||||
|  | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits) | ||||||
|  | 
 | ||||||
|  | #elif (FLASHEND > USHRT_MAX) | ||||||
|  | 
 | ||||||
|  | /* Extended: >16 bit address */ | ||||||
|  | #define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data) | ||||||
|  | #define boot_page_erase(address)      __boot_page_erase_extended_short(address) | ||||||
|  | #define boot_page_write(address)      __boot_page_write_extended_short(address) | ||||||
|  | #define boot_rww_enable()             __boot_rww_enable_short() | ||||||
|  | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits) | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | 
 | ||||||
|  | /* Normal: 16 bit address */ | ||||||
|  | #define boot_page_fill(address, data) __boot_page_fill_short(address, data) | ||||||
|  | #define boot_page_erase(address)      __boot_page_erase_short(address) | ||||||
|  | #define boot_page_write(address)      __boot_page_write_short(address) | ||||||
|  | #define boot_rww_enable()             __boot_rww_enable_short() | ||||||
|  | #define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits) | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  | 
 | ||||||
|  |     Same as boot_page_fill() except it waits for eeprom and spm operations to | ||||||
|  |     complete before filling the page. */ | ||||||
|  | 
 | ||||||
|  | #define boot_page_fill_safe(address, data) \ | ||||||
|  | do { \ | ||||||
|  |     boot_spm_busy_wait();                       \ | ||||||
|  |     eeprom_busy_wait();                         \ | ||||||
|  |     boot_page_fill(address, data);              \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  | 
 | ||||||
|  |     Same as boot_page_erase() except it waits for eeprom and spm operations to | ||||||
|  |     complete before erasing the page. */ | ||||||
|  | 
 | ||||||
|  | #define boot_page_erase_safe(address) \ | ||||||
|  | do { \ | ||||||
|  |     boot_spm_busy_wait();                       \ | ||||||
|  |     eeprom_busy_wait();                         \ | ||||||
|  |     boot_page_erase (address);                  \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  | 
 | ||||||
|  |     Same as boot_page_write() except it waits for eeprom and spm operations to | ||||||
|  |     complete before writing the page. */ | ||||||
|  | 
 | ||||||
|  | #define boot_page_write_safe(address) \ | ||||||
|  | do { \ | ||||||
|  |     boot_spm_busy_wait();                       \ | ||||||
|  |     eeprom_busy_wait();                         \ | ||||||
|  |     boot_page_write (address);                  \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  | 
 | ||||||
|  |     Same as boot_rww_enable() except waits for eeprom and spm operations to | ||||||
|  |     complete before enabling the RWW mameory. */ | ||||||
|  | 
 | ||||||
|  | #define boot_rww_enable_safe() \ | ||||||
|  | do { \ | ||||||
|  |     boot_spm_busy_wait();                       \ | ||||||
|  |     eeprom_busy_wait();                         \ | ||||||
|  |     boot_rww_enable();                          \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | /** \ingroup avr_boot
 | ||||||
|  | 
 | ||||||
|  |     Same as boot_lock_bits_set() except waits for eeprom and spm operations to | ||||||
|  |     complete before setting the lock bits. */ | ||||||
|  | 
 | ||||||
|  | #define boot_lock_bits_set_safe(lock_bits) \ | ||||||
|  | do { \ | ||||||
|  |     boot_spm_busy_wait();                       \ | ||||||
|  |     eeprom_busy_wait();                         \ | ||||||
|  |     boot_lock_bits_set (lock_bits);             \ | ||||||
|  | } while (0) | ||||||
|  | 
 | ||||||
|  | #endif /* _AVR_BOOT_H_ */ | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | :020000021000EC | ||||||
|  | :10FE00000F92CDB7DEB7112484B714BE81FFDFD0C7 | ||||||
|  | :10FE100082E08093C00088E18093C10086E08093F7 | ||||||
|  | :10FE2000C2008AE28093C4008EE0BBD0209A00E03A | ||||||
|  | :10FE300010E0EE24E394E1E1DE2EF3E0FF2EA5D006 | ||||||
|  | :10FE4000813471F4A2D08983B2D08981823809F4D7 | ||||||
|  | :10FE50008BC0813811F484E001C083E08FD08BC067 | ||||||
|  | :10FE6000823411F484E103C0853419F485E0A7D00D | ||||||
|  | :10FE700082C0853591F489D0A82EBB2486D0082F66 | ||||||
|  | :10FE800010E0102F00270A291B29812F881F88279F | ||||||
|  | :10FE9000881F8BBF000F111F6DC0863521F484E0D1 | ||||||
|  | :10FEA0008ED080E0DBCF843609F040C06ED06DD0BC | ||||||
|  | :10FEB000C82E6BD080EE0030180718F4F801F7BE9A | ||||||
|  | :10FEC000E895A12C51E0B52E60D0F50181935F013A | ||||||
|  | :10FED000CE16D1F7F0EE00301F0718F0F801F7BE8C | ||||||
|  | :10FEE000E89565D007B600FCFDCFF801A0E0B1E0D1 | ||||||
|  | :10FEF0002C9130E011968C91119790E0982F8827E3 | ||||||
|  | :10FF0000822B932B12960C01E7BEE89511243296B2 | ||||||
|  | :10FF100082E0A030B80761F785E0F80187BFE89577 | ||||||
|  | :10FF200007B600FCFDCFD7BEE89525C08437A9F4FD | ||||||
|  | :10FF30002CD02BD0B82E29D03AD0CB2C4801F401AC | ||||||
|  | :10FF400086911CD00894811C911CCA94C1F70F5F44 | ||||||
|  | :10FF50001F4FBA940B0D111D0EC0853739F427D0F1 | ||||||
|  | :10FF60008EE10CD087E90AD085E078CF813511F495 | ||||||
|  | :10FF700088E017D01CD080E101D061CF9091C00003 | ||||||
|  | :10FF800095FFFCCF8093C60008958091C00087FF45 | ||||||
|  | :10FF9000FCCF8091C00084FD01C0A8958091C6006F | ||||||
|  | :10FFA0000895E0E6F0E098E1908380830895EDDF26 | ||||||
|  | :10FFB000803219F088E0F5DFFFCF84E1DFCFCF9307 | ||||||
|  | :10FFC000C82FE3DFC150E9F7F2DFCF91089580E059 | ||||||
|  | :08FFD000E8DFEE27FF2709948A | ||||||
|  | :040000031000FE00EB | ||||||
|  | :00000001FF | ||||||
| @ -0,0 +1,81 @@ | |||||||
|  | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || 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 | ||||||
|  | 
 | ||||||
| @ -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'
 | ||||||
					Loading…
					
					
				
		Reference in new issue
	
	 Dirk Eichel
						Dirk Eichel