diff options
191 files changed, 12904 insertions, 7870 deletions
@@ -1,8 +1,7 @@ ############################################################## uno.name=Arduino Uno -uno.platform=avr -uno.upload.protocol=stk500 +uno.upload.protocol=arduino uno.upload.maximum_size=32256 uno.upload.speed=115200 uno.bootloader.low_fuses=0xff @@ -15,13 +14,12 @@ uno.bootloader.lock_bits=0x0F uno.build.mcu=atmega328p uno.build.f_cpu=16000000L uno.build.core=arduino -uno.build.pins=standard +uno.build.variant=standard ############################################################## -atmega328.name=Arduino Duemilanove or Nano w/ ATmega328 -atmega328.platform=avr -atmega328.upload.protocol=stk500 +atmega328.name=Arduino Duemilanove w/ ATmega328 +atmega328.upload.protocol=arduino atmega328.upload.maximum_size=30720 atmega328.upload.speed=57600 @@ -36,13 +34,12 @@ atmega328.bootloader.lock_bits=0x0F atmega328.build.mcu=atmega328p atmega328.build.f_cpu=16000000L atmega328.build.core=arduino -atmega328.build.pins=standard +atmega328.build.variant=standard ############################################################## -diecimila.name=Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 -diecimila.platform=avr -diecimila.upload.protocol=stk500 +diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168 +diecimila.upload.protocol=arduino diecimila.upload.maximum_size=14336 diecimila.upload.speed=19200 @@ -57,12 +54,51 @@ diecimila.bootloader.lock_bits=0x0F diecimila.build.mcu=atmega168 diecimila.build.f_cpu=16000000L diecimila.build.core=arduino -diecimila.build.pins=standard +diecimila.build.variant=standard ############################################################## -mega2560.name=Arduino Mega 2560 -mega2560.platform=avr +nano328.name=Arduino Nano w/ ATmega328 +nano328.upload.protocol=arduino +nano328.upload.maximum_size=30720 +nano328.upload.speed=57600 + +nano328.bootloader.low_fuses=0xFF +nano328.bootloader.high_fuses=0xDA +nano328.bootloader.extended_fuses=0x05 +nano328.bootloader.path=atmega +nano328.bootloader.file=ATmegaBOOT_168_atmega328.hex +nano328.bootloader.unlock_bits=0x3F +nano328.bootloader.lock_bits=0x0F + +nano328.build.mcu=atmega328p +nano328.build.f_cpu=16000000L +nano328.build.core=arduino +nano328.build.variant=eightanaloginputs + +############################################################## + +nano.name=Arduino Nano w/ ATmega168 +nano.upload.protocol=arduino +nano.upload.maximum_size=14336 +nano.upload.speed=19200 + +nano.bootloader.low_fuses=0xff +nano.bootloader.high_fuses=0xdd +nano.bootloader.extended_fuses=0x00 +nano.bootloader.path=atmega +nano.bootloader.file=ATmegaBOOT_168_diecimila.hex +nano.bootloader.unlock_bits=0x3F +nano.bootloader.lock_bits=0x0F + +nano.build.mcu=atmega168 +nano.build.f_cpu=16000000L +nano.build.core=arduino +nano.build.variant=eightanaloginputs + +############################################################## + +mega2560.name=Arduino Mega 2560 or Mega ADK mega2560.upload.protocol=stk500v2 mega2560.upload.maximum_size=258048 mega2560.upload.speed=115200 @@ -78,13 +114,12 @@ mega2560.bootloader.lock_bits=0x0F mega2560.build.mcu=atmega2560 mega2560.build.f_cpu=16000000L mega2560.build.core=arduino -mega2560.build.pins=mega +mega2560.build.variant=mega ############################################################## mega.name=Arduino Mega (ATmega1280) -mega.platform=avr -mega.upload.protocol=stk500 +mega.upload.protocol=arduino mega.upload.maximum_size=126976 mega.upload.speed=57600 @@ -99,13 +134,68 @@ mega.bootloader.lock_bits=0x0F mega.build.mcu=atmega1280 mega.build.f_cpu=16000000L mega.build.core=arduino -mega.build.pins=mega +mega.build.variant=mega + +############################################################## + +#leonardo.name=Arduino Leonardo +#leonardo.upload.protocol=arduino +#leonardo.upload.maximum_size=28672 +#leonardo.upload.speed=1200 +#leonardo.bootloader.low_fuses=0xde +#leonardo.bootloader.high_fuses=0xd8 +#leonardo.bootloader.extended_fuses=0xcb +#leonardo.bootloader.path=diskloader +#leonardo.bootloader.file=DiskLoader-Leonardo.hex +#leonardo.bootloader.unlock_bits=0x3F +#leonardo.bootloader.lock_bits=0x2F +#leonardo.build.mcu=atmega32u4 +#leonardo.build.f_cpu=16000000L +#leonardo.build.core=arduino +#leonardo.build.variant=leonardo ############################################################## -mini.name=Arduino Mini -mini.platform=avr -mini.upload.protocol=stk500 +#micro.name=Arduino Micro +#micro.upload.protocol=arduino +#micro.upload.maximum_size=30720 +#micro.upload.speed=1200 +#micro.bootloader.low_fuses=0xde +#micro.bootloader.high_fuses=0xda +#micro.bootloader.extended_fuses=0xcb +#micro.bootloader.path=diskloader +#micro.bootloader.file=DiskLoader-Micro.hex +#micro.bootloader.unlock_bits=0x3F +#micro.bootloader.lock_bits=0x2F +#micro.build.mcu=atmega32u4 +#micro.build.f_cpu=16000000L +#micro.build.core=arduino +#micro.build.variant=micro + +############################################################## + +mini328.name=Arduino Mini w/ ATmega328 +mini328.upload.protocol=stk500 +mini328.upload.maximum_size=28672 +mini328.upload.speed=115200 + +mini328.bootloader.low_fuses=0xff +mini328.bootloader.high_fuses=0xd8 +mini328.bootloader.extended_fuses=0x05 +mini328.bootloader.path=optiboot +mini328.bootloader.file=optiboot_atmega328-Mini.hex +mini328.bootloader.unlock_bits=0x3F +mini328.bootloader.lock_bits=0x0F + +mini328.build.mcu=atmega328p +mini328.build.f_cpu=16000000L +mini328.build.core=arduino +mini328.build.variant=eightanaloginputs + +############################################################## + +mini.name=Arduino Mini w/ ATmega168 +mini.upload.protocol=arduino mini.upload.maximum_size=14336 mini.upload.speed=19200 @@ -120,13 +210,32 @@ mini.bootloader.lock_bits=0x0F mini.build.mcu=atmega168 mini.build.f_cpu=16000000L mini.build.core=arduino -mini.build.pins=standard +mini.build.variant=eightanaloginputs + +############################################################## + +ethernet.name=Arduino Ethernet +ethernet.upload.protocol=arduino +ethernet.upload.maximum_size=32256 +ethernet.upload.speed=115200 + +ethernet.bootloader.low_fuses=0xff +ethernet.bootloader.high_fuses=0xde +ethernet.bootloader.extended_fuses=0x05 +ethernet.bootloader.path=optiboot +ethernet.bootloader.file=optiboot_atmega328.hex +ethernet.bootloader.unlock_bits=0x3F +ethernet.bootloader.lock_bits=0x0F + +ethernet.build.variant=standard +ethernet.build.mcu=atmega328p +ethernet.build.f_cpu=16000000L +ethernet.build.core=arduino ############################################################## fio.name=Arduino Fio -fio.platform=avr -fio.upload.protocol=stk500 +fio.upload.protocol=arduino fio.upload.maximum_size=30720 fio.upload.speed=57600 @@ -141,13 +250,12 @@ fio.bootloader.lock_bits=0x0F fio.build.mcu=atmega328p fio.build.f_cpu=8000000L fio.build.core=arduino -fio.build.pins=standard +fio.build.variant=eightanaloginputs ############################################################## bt328.name=Arduino BT w/ ATmega328 -bt328.platform=avr -bt328.upload.protocol=stk500 +bt328.upload.protocol=arduino bt328.upload.maximum_size=28672 bt328.upload.speed=19200 bt328.upload.disable_flushing=true @@ -163,13 +271,12 @@ bt328.bootloader.lock_bits=0x0F bt328.build.mcu=atmega328p bt328.build.f_cpu=16000000L bt328.build.core=arduino -bt328.build.pins=standard +bt328.build.variant=eightanaloginputs ############################################################## bt.name=Arduino BT w/ ATmega168 -bt.platform=avr -bt.upload.protocol=stk500 +bt.upload.protocol=arduino bt.upload.maximum_size=14336 bt.upload.speed=19200 bt.upload.disable_flushing=true @@ -185,13 +292,12 @@ bt.bootloader.lock_bits=0x0F bt.build.mcu=atmega168 bt.build.f_cpu=16000000L bt.build.core=arduino -bt.build.pins=standard +bt.build.variant=eightanaloginputs ############################################################## lilypad328.name=LilyPad Arduino w/ ATmega328 -lilypad328.platform=avr -lilypad328.upload.protocol=stk500 +lilypad328.upload.protocol=arduino lilypad328.upload.maximum_size=30720 lilypad328.upload.speed=57600 @@ -206,13 +312,12 @@ lilypad328.bootloader.lock_bits=0x0F lilypad328.build.mcu=atmega328p lilypad328.build.f_cpu=8000000L lilypad328.build.core=arduino -lilypad328.build.pins=standard +lilypad328.build.variant=standard ############################################################## lilypad.name=LilyPad Arduino w/ ATmega168 -lilypad.platform=avr -lilypad.upload.protocol=stk500 +lilypad.upload.protocol=arduino lilypad.upload.maximum_size=14336 lilypad.upload.speed=19200 @@ -227,13 +332,12 @@ lilypad.bootloader.lock_bits=0x0F lilypad.build.mcu=atmega168 lilypad.build.f_cpu=8000000L lilypad.build.core=arduino -lilypad.build.pins=standard +lilypad.build.variant=standard ############################################################## pro5v328.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 -pro5v328.platform=avr -pro5v328.upload.protocol=stk500 +pro5v328.upload.protocol=arduino pro5v328.upload.maximum_size=30720 pro5v328.upload.speed=57600 @@ -248,13 +352,12 @@ pro5v328.bootloader.lock_bits=0x0F pro5v328.build.mcu=atmega328p pro5v328.build.f_cpu=16000000L pro5v328.build.core=arduino -pro5v328.build.pins=standard +pro5v328.build.variant=standard ############################################################## pro5v.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 -pro5v.platform=avr -pro5v.upload.protocol=stk500 +pro5v.upload.protocol=arduino pro5v.upload.maximum_size=14336 pro5v.upload.speed=19200 @@ -269,13 +372,12 @@ pro5v.bootloader.lock_bits=0x0F pro5v.build.mcu=atmega168 pro5v.build.f_cpu=16000000L pro5v.build.core=arduino -pro5v.build.pins=standard +pro5v.build.variant=standard ############################################################## pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 -pro328.platform=avr -pro328.upload.protocol=stk500 +pro328.upload.protocol=arduino pro328.upload.maximum_size=30720 pro328.upload.speed=57600 @@ -290,13 +392,12 @@ pro328.bootloader.lock_bits=0x0F pro328.build.mcu=atmega328p pro328.build.f_cpu=8000000L pro328.build.core=arduino -pro328.build.pins=standard +pro328.build.variant=standard ############################################################## pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 -pro.platform=avr -pro.upload.protocol=stk500 +pro.upload.protocol=arduino pro.upload.maximum_size=14336 pro.upload.speed=19200 @@ -311,13 +412,12 @@ pro.bootloader.lock_bits=0x0F pro.build.mcu=atmega168 pro.build.f_cpu=8000000L pro.build.core=arduino -pro.build.pins=standard +pro.build.variant=standard ############################################################## atmega168.name=Arduino NG or older w/ ATmega168 -atmega168.platform=avr -atmega168.upload.protocol=stk500 +atmega168.upload.protocol=arduino atmega168.upload.maximum_size=14336 atmega168.upload.speed=19200 @@ -332,13 +432,12 @@ atmega168.bootloader.lock_bits=0x0F atmega168.build.mcu=atmega168 atmega168.build.f_cpu=16000000L atmega168.build.core=arduino -atmega168.build.pins=standard +atmega168.build.variant=standard ############################################################## atmega8.name=Arduino NG or older w/ ATmega8 -atmega8.platform=avr -atmega8.upload.protocol=stk500 +atmega8.upload.protocol=arduino atmega8.upload.maximum_size=7168 atmega8.upload.speed=19200 @@ -352,4 +451,4 @@ atmega8.bootloader.lock_bits=0x0F atmega8.build.mcu=atmega8 atmega8.build.f_cpu=16000000L atmega8.build.core=arduino -atmega8.build.pins=standard +atmega8.build.variant=standard diff --git a/bootloaders/diskloader/DiskLoader-Leonardo.hex b/bootloaders/diskloader/DiskLoader-Leonardo.hex new file mode 100644 index 0000000..0d0c167 --- /dev/null +++ b/bootloaders/diskloader/DiskLoader-Leonardo.hex @@ -0,0 +1,115 @@ +:1078000011241FBECFEFDAE0DEBFCDBFFFC04101C4
+:1078100042144505560455026403740300001E9586
+:1078200087020110030000C18081C106C0FF0A0069
+:107830000CA10185037508150026FF00954009017C
+:107840008102954009029102C0040309041A033021
+:1078500000300030003000300030003000300031A7
+:1078600000370030003100380341007200640075B9
+:107870000069006E006F0020004C0065006F006E14
+:10788000006100720064006F00200062006F006FF2
+:107890000074006C006F00610064006500720018E5
+:1078A00003410072006400750069006E006F0020E3
+:1078B000004C004C00430012010002020000404155
+:1078C0002334000001000203011201000200000045
+:1078D0004041233400000100020301090264000357
+:1078E00001008032080B00020202010009040000BE
+:1078F0000102020000052400100105240101010419
+:107900002402020524060001070581031000400936
+:10791000040100020A0000000705020240000007FF
+:107920000583024000000904020001030000000971
+:107930002101010001221E000705840340004000D0
+:1079400020918A0130918B012C5F3F4F30938B0146
+:1079500020938A01C901892F99278695982F803411
+:1079600018F08FE7891B982F990F921710F44798FA
+:107970000895479A08955D9A289A81E08093E000DF
+:107980001092E200EE27FF27099408950F931F93AA
+:10799000CF93DF93982FEB01042F10E088E760303E
+:1079A000780730F411E083E0FB0180935700E895FD
+:1079B000892F68E071E0402FF8D0112311F107B64C
+:1079C00000FCFDCF402F4695FE01A8E0B1E020E08D
+:1079D00031E009C08D919D910C0130935700E895DD
+:1079E000112432962F5F2417A8F385E0FE018093BF
+:1079F0005700E89507B600FCFDCF81E18093570062
+:107A0000E895DF91CF911F910F91089588E10FB60E
+:107A1000F89480936000109260000FBE5D9A289ADF
+:107A200047983F9A209A559A90E890936100109257
+:107A3000610081E885BF95BF9FD084E18093880174
+:107A400080E180938901E0E0F0E0859194918F5F7F
+:107A50009F4F19F081E080938F01EE24FF24BB2417
+:107A6000B39454EFC52E51E0D52E13D2082F8EE0DB
+:107A700098E7FC012491319602964491201711F069
+:107A80002223B9F7109291011092900182E068E0F0
+:107A900071E08BD0013479F4609108016058633053
+:107AA00028F0683111F064E001C063E0C62FD0E037
+:107AB000CF5DD7480EC0063571F480910801803340
+:107AC00011F011E022C080910A01C82FD0E0C25EFF
+:107AD000D74811E022C0053721F413E0CEE1D8E702
+:107AE0001CC0053539F4E0900801F0900901EE0C56
+:107AF000FF1C0AC0043631F482E0B701409109014D
+:107B000045DF02C0043721F010E0C5E2D8E705C028
+:107B100010910901E701E10EF11CBBD18097B1F48E
+:107B200083E068E871E041E050E059D0112329F08A
+:107B3000412F50E083E8BE0152D083E469E871E050
+:107B400041E050E04CD0013509F08FCFD092910147
+:107B5000C0929001B0928F01EE24FF2486CFFC01E9
+:107B6000289884E680938D0104C08091F100819370
+:107B700061506623D1F708951092910110929001FF
+:107B800010928E0110928F0181E08093D70080EADD
+:107B90008093D80082E189BD09B400FEFDCF80E961
+:107BA0008093D8001092E0000895FB018093E900D3
+:107BB00024E69BE611C08091E80085FFFCCF289861
+:107BC00020938D018091F10081938091E80085FDE3
+:107BD00002C09093E8004150442369F70895982F1C
+:107BE000FB01282F207287708093E90064E63AE356
+:107BF00017C08091E80085FFFCCF97FF02C08491F9
+:107C000001C080813196211180E05D9860938C01E4
+:107C10008093F1008091E80085FD02C03093E80078
+:107C2000415050408FEF4F3F580719F796FF03C060
+:107C30008AE38093E800089580919301813299F45A
+:107C40005D9884E680938C0120E030E003C0808161
+:107C50008093F100F901E050FF4F2F5F3F4F283034
+:107C60003105A9F714C0803261F48091E80082FFE9
+:107C7000FCCF80E091E067E072DF8BEF8093E8005B
+:107C800006C0823221F4809194018093070181E043
+:107C9000089520919501223289F1213081F480915B
+:107CA000980190919901089711F420939A0180917D
+:107CB0009A01882309F04FC0E9ECF8E74EC0223062
+:107CC00021F484E6EBEDF8E71CC0233009F041C055
+:107CD00080919401882319F4E9E4F8E73EC08230EA
+:107CE00019F4E7E6F8E739C0833019F4EDE4F8E772
+:107CF00034C0813071F5EFE9F8E72FC081E0EBE2A5
+:107D0000F8E790919801382F981708F4392F90913F
+:107D10008C0120E04EEF8091E8008570E1F38091C6
+:107D2000E80082FD12C02F5F84915D988093F1007E
+:107D3000822F8F7311F44093E800319694E6231755
+:107D400050F390938C0181E0089590938C0180E032
+:107D5000089580E00895E7EBF8E78491D2CF109280
+:107D6000E9008091E80083FF61C082E991E068E06A
+:107D7000F6DE82EF8093E8008091920187FF05C0D4
+:107D80008091E80080FFFCCF03C08EEF8093E80075
+:107D900080919301853051F48091E80080FFFCCF01
+:107DA0008091940180688093E30039C08930E1F4C8
+:107DB0008091940180938E01E7E2F8E791E031E051
+:107DC00026E39093E9003093EB0084918093EC00DC
+:107DD0002093ED009F5F3196953099F78EE7809361
+:107DE000EA001092EA001BC0883049F490918E019D
+:107DF0005D9884E680938C019093F10010C08823F5
+:107E000039F45D9884E680938C011092F10007C0EC
+:107E1000863011F43EDF01C00FDF882321F08EEFA2
+:107E20008093E800089581E28093EB0008958091AB
+:107E3000E1001092E100282F83FF0CC01092E900AE
+:107E400081E08093EB001092EC0082E38093ED00E0
+:107E500010928E0122FF1CC080918C01882331F08A
+:107E6000815080938C01882309F45D9A80918D0163
+:107E7000882331F0815080938D01882309F4289A5A
+:107E800080918F01882321F410929101109290012A
+:107E900008951F93CF93DF9312E0C0E9D1E05FDF35
+:107EA000C6DF1093E9008091E80085FF13C0289891
+:107EB00084E680938D019091F1008091E80085FD2A
+:107EC00003C08BE68093E800892F90E0DF91CF918B
+:107ED0001F91089580919001909191010197909345
+:107EE0009101809390018091900190919101892B53
+:0E7EF00009F441DDCE010197F1F722DDD0CF7C
+:087EFE0000E10000000000009B
+:040000030000780081
+:00000001FF
diff --git a/bootloaders/diskloader/Makefile b/bootloaders/diskloader/Makefile new file mode 100644 index 0000000..6ac3db3 --- /dev/null +++ b/bootloaders/diskloader/Makefile @@ -0,0 +1,105 @@ +############################################################################### +# Makefile for DiskLoader +############################################################################### + +## General Flags +PROJECT = DiskLoader +TARGET = DiskLoader.elf +CC = avr-gcc + +# BOARD2 +MCU = atmega32u4 +AVR_FREQ = 16000000L + +# Specify the Arduino model using the assigned PID. This is used by Descriptors.c
+# to set PID and product descriptor string
+# Arduino Leonardo PID
+ARDUINO_MODEL_PID = 0x0034
+# Arduino Micro PID
+#ARDUINO_MODEL_PID = 0x0035 + +# Change if your programmer is different +AVRDUDE_PROGRAMMER = avrispmkII +AVRDUDE_PORT = usb + +# program name should not be changed... +PROGRAM = DiskLoader + +AVRDUDE = avrdude +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -p $(MCU) + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +override CFLAGS = -g -Wall -Os -mmcu=$(MCU) -DF_CPU=$(AVR_FREQ) -DARDUINO_MODEL_PID=$(ARDUINO_MODEL_PID) $(DEFS) -ffunction-sections -gdwarf-2 -fdata-sections -fno-split-wide-types + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-gc-sections,-Map=DiskLoader.map,--section-start=.text=0x7800,--relax +LDFLAGS += -nodefaultlibs -nostartfiles + + +## Intel Hex file production flags +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +MODULES := . +SRC_DIR := $(addprefix src/,$(MODULES)) +BUILD_DIR := $(addprefix build/,$(MODULES)) + +SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp)) +OBJ := $(patsubst src/%.cpp,build/%.o,$(SRC)) +DEP := $(OBJ:%.o=%.d) +INCLUDES := $(addprefix -I,$(SRC_DIR)) + +vpath %.cpp $(SRC_DIR) + +.PHONY: all checkdirs clean + +all: checkdirs $(TARGET) DiskLoader.hex DiskLoader.lss size + +-include $(DEP) + +checkdirs: $(BUILD_DIR) + +$(BUILD_DIR): + @mkdir -p $@ + +clean: + @rm -rf build/ + @rm -f *.hex + @rm -f *.elf + @rm -f *.lss + @rm -f *.map + +define make-goal +$1/%.o: %.cpp + $(CC) $(INCLUDES) $(CFLAGS) -c $$< -MD -o $$@ +endef + +$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir)))) + +$(TARGET): $(OBJ) + $(CC) $(LDFLAGS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) $^ -o $@ + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: $(TARGET) + @echo +# @avr-size -C --mcu=${MCU} ${TARGET}.elf + +program: $(TARGET).hex + $(AVRDUDE) $(AVRDUDE_FLAGS) -B 5 -u -U flash:w:$(TARGET).hex
\ No newline at end of file diff --git a/bootloaders/diskloader/src/DiskLoader.cpp b/bootloaders/diskloader/src/DiskLoader.cpp new file mode 100644 index 0000000..6580618 --- /dev/null +++ b/bootloaders/diskloader/src/DiskLoader.cpp @@ -0,0 +1,239 @@ + + +#include "Platform.h" + +// This bootloader creates a composite Serial device +// +// The serial interface supports a STK500v1 protocol that is very similar to optiboot +// +// The bootloader will timeout and start the firmware after a few hundred milliseconds +// if a usb connection is not detected. +// +// The tweakier code is to keep the bootloader below 2k (no interrupt table, for example) + +extern "C" +void entrypoint(void) __attribute__ ((naked)) __attribute__ ((section (".vectors"))); +void entrypoint(void) +{ + asm volatile ( + "eor r1, r1\n" // Zero register + "out 0x3F, r1\n" // SREG + "ldi r28, 0xFF\n" + "ldi r29, 0x0A\n" + "out 0x3E, r29\n" // SPH + "out 0x3D, r28\n" // SPL + "rjmp main" // Stack is all set up, start the main code + ::); +} + +u8 _flashbuf[128]; +u8 _inSync; +u8 _ok; +extern volatile u8 _ejected; +extern volatile u16 _timeout; + +void Program(u8 ep, u16 page, u8 count) +{ + u8 write = page < 30*1024; // Don't write over firmware please + if (write) + boot_page_erase(page); + + Recv(ep,_flashbuf,count); // Read while page is erasing + + if (!write) + return; + + boot_spm_busy_wait(); // Wait until the memory is erased. + + count >>= 1; + u16* p = (u16*)page; + u16* b = (u16*)_flashbuf; + for (u8 i = 0; i < count; i++) + boot_page_fill(p++, b[i]); + + boot_page_write(page); + boot_spm_busy_wait(); + boot_rww_enable (); +} + + +int USBGetChar(); +#define getch USBGetChar + +#define HW_VER 0x02 +#define SW_MAJOR 0x01 +#define SW_MINOR 0x10 + +#define STK_OK 0x10 +#define STK_INSYNC 0x14 // ' ' +#define CRC_EOP 0x20 // 'SPACE' +#define STK_GET_SYNC 0x30 // '0' + +#define STK_GET_PARAMETER 0x41 // 'A' +#define STK_SET_DEVICE 0x42 // 'B' +#define STK_SET_DEVICE_EXT 0x45 // 'E' +#define STK_LOAD_ADDRESS 0x55 // 'U' +#define STK_UNIVERSAL 0x56 // 'V' +#define STK_PROG_PAGE 0x64 // 'd' +#define STK_READ_PAGE 0x74 // 't' +#define STK_READ_SIGN 0x75 // 'u' + +extern const u8 _readSize[] PROGMEM; +const u8 _readSize[] = +{ + STK_GET_PARAMETER, 1, + STK_SET_DEVICE, 20, + STK_SET_DEVICE_EXT, 5, + STK_UNIVERSAL, 4, + STK_LOAD_ADDRESS, 2, + STK_PROG_PAGE, 3, + STK_READ_PAGE, 3, + 0,0 +}; + +extern const u8 _consts[] PROGMEM; +const u8 _consts[] = +{ + SIGNATURE_0, + SIGNATURE_1, + SIGNATURE_2, + HW_VER, // Hardware version + SW_MAJOR, // Software major version + SW_MINOR, // Software minor version + 0x03, // Unknown but seems to be required by avr studio 3.56 + 0x00, // +}; + + +void USBInit(void); +int main(void) __attribute__ ((naked)); + +// STK500v1 main loop, very similar to optiboot in protocol and implementation +int main() +{ + wdt_disable(); + TXLED0; + RXLED0; + LED0; + BOARD_INIT(); + USBInit(); + + _inSync = STK_INSYNC; + _ok = STK_OK; + + if (pgm_read_word(0) != -1) + _ejected = 1; + + for(;;) + { + u8* packet = _flashbuf; + u16 address = 0; + for (;;) + { + u8 cmd = getch(); + + // Read packet contents + u8 len; + const u8* rs = _readSize; + for(;;) + { + u8 c = pgm_read_byte(rs++); + len = pgm_read_byte(rs++); + if (c == cmd || c == 0) + break; + } + _timeout = 0; + // Read params + Recv(CDC_RX,packet,len); + + // Send a response + u8 send = 0; + const u8* pgm = _consts+7; // 0 + if (STK_GET_PARAMETER == cmd) + { + u8 i = packet[0] - 0x80; + if (i > 2) + i = (i == 0x18) ? 3 : 4; // 0x80:HW_VER,0x81:SW_MAJOR,0x82:SW_MINOR,0x18:3 or 0 + pgm = _consts + i + 3; + send = 1; + } + + else if (STK_UNIVERSAL == cmd) + { + if (packet[0] == 0x30) + pgm = _consts + packet[2]; // read signature + send = 1; + } + + // Read signature bytes + else if (STK_READ_SIGN == cmd) + { + pgm = _consts; + send = 3; + } + + else if (STK_LOAD_ADDRESS == cmd) + { + address = *((u16*)packet); // word addresses + address += address; + } + + else if (STK_PROG_PAGE == cmd) + { + Program(CDC_RX,address,packet[1]); + } + + else if (STK_READ_PAGE == cmd) + { + send = packet[1]; + pgm = (const u8*)address; + address += send; // not sure of this is required + } + + // Check sync + if (getch() != ' ') + break; + Transfer(CDC_TX,&_inSync,1); + + // Send result + if (send) + Transfer(CDC_TX|TRANSFER_PGM,pgm,send); // All from pgm memory + + // Send ok + Transfer(CDC_TX|TRANSFER_RELEASE,&_ok,1); + + if (cmd == 'Q') + break; + } + _timeout = 500; // wait a moment before exiting the bootloader - may need to finish responding to 'Q' for example + _ejected = 1; + } +} + +// Nice breathing LED indicates we are in the firmware +u16 _pulse; +void LEDPulse() +{ + _pulse += 4; + u8 p = _pulse >> 9; + if (p > 63) + p = 127-p; + p += p; + if (((u8)_pulse) > p) + LED0; + else + LED1; +} + +void Reboot() +{ + TXLED0; // switch off the RX and TX LEDs before starting the user sketch + RXLED0; + UDCON = 1; // Detatch USB + UDIEN = 0; + asm volatile ( // Reset vector to run firmware + "clr r30\n" + "clr r31\n" + "ijmp\n" + ::); +} diff --git a/bootloaders/diskloader/src/Platform.h b/bootloaders/diskloader/src/Platform.h new file mode 100644 index 0000000..04c5b79 --- /dev/null +++ b/bootloaders/diskloader/src/Platform.h @@ -0,0 +1,51 @@ + +#include <inttypes.h> +#include <avr/io.h> +#include <avr/pgmspace.h> +#include <avr/boot.h> +#include <util/delay.h> +#include <avr/interrupt.h> +#include <avr/wdt.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + + +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define DISABLE_JTAG() MCUCR = (1 << JTD) | (1 << IVCE) | (0 << PUD); MCUCR = (1 << JTD) | (0 << IVSEL) | (0 << IVCE) | (0 << PUD); + +#define USB_PID_LEONARDO 0x0034 +#define USB_PID_MICRO 0x0035 +#define USB_VID 0x2341 // arduino LLC vid +#define USB_PID ARDUINO_MODEL_PID // passed in by Makefile - 0x0034 for Leonardo, 0x0035 for MIcro + +#define USB_SERIAL_STRING '0','0','0','0','0','0','0','0','1','7','0','1' + +#define OEM_NAME 'l','e','o','n','a','r','d','o' // 8 chars +#define BOARD_INIT() DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5); CPU_PRESCALE(0); DISABLE_JTAG(); +#define LED0 PORTC &= ~(1<<7) +#define LED1 PORTC |= (1<<7) +#define TXLED0 PORTD |= (1<<5) +#define TXLED1 PORTD &= ~(1<<5) +#define RXLED0 PORTB |= (1<<0) +#define RXLED1 PORTB &= ~(1<<0) + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +void Transfer(u8 ep, const u8* data, int len); +void Recv(u8 ep, u8* dst, u8 len); +void Program(u8 ep, u16 page, u8 count); + +#define CDC_ENABLED + +#include "USBCore.h" +#include "USBDesc.h" + + diff --git a/bootloaders/diskloader/src/USBCore.cpp b/bootloaders/diskloader/src/USBCore.cpp new file mode 100644 index 0000000..208121e --- /dev/null +++ b/bootloaders/diskloader/src/USBCore.cpp @@ -0,0 +1,510 @@ + + +/* Copyright (c) 2010, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" + +#define CDC_TX CDC_ENDPOINT_IN +#define CDC_RX CDC_ENDPOINT_OUT + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ +#define TX_RX_LED_PULSE_MS 100 +u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ +u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ + +void Reboot(); + +//================================================================== +//================================================================== + +typedef struct +{ + u32 dwDTERate; + u8 bCharFormat; + u8 bParityType; + u8 bDataBits; + u8 lineState; +} LineInfo; + +static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; + +//================================================================== +//================================================================== + +// 4 bytes of RAM +volatile u8 _usbConfiguration; +volatile u8 _ejected; +volatile u16 _timeout; + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1<<TXINI))); +} + +static inline void ClearIN(void) +{ + UEINTX = ~(1<<TXINI); +} + +static inline void WaitOUT(void) +{ + while (!(UEINTX & (1<<RXOUTI))) + ; +} + +static inline u8 WaitForINOrOUT() +{ + while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI)))) + ; + return (UEINTX & (1<<RXOUTI)) == 0; +} + +static inline void ClearOUT(void) +{ + UEINTX = ~(1<<RXOUTI); +} + +static +void Send(volatile const u8* data, u8 count) +{ + TXLED1; // light the TX LED + TxLEDPulse = TX_RX_LED_PULSE_MS; + while (count--) + UEDATX = *data++; +} + +void Recv(volatile u8* data, u8 count) +{ + RXLED1; // light the RX LED + RxLEDPulse = TX_RX_LED_PULSE_MS; + while (count--) + *data++ = UEDATX; +} + +static inline u8 Recv8() +{ + RXLED1; // light the RX LED + RxLEDPulse = TX_RX_LED_PULSE_MS; + return UEDATX; +} + +static inline void Send8(u8 d) +{ + TXLED1; // light the TX LED + TxLEDPulse = TX_RX_LED_PULSE_MS; + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; +} + +static inline u8 ReceivedSetupInt() +{ + return UEINTX & (1<<RXSTPI); +} + +static inline void ClearSetupInt() +{ + UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI)); +} + +static inline void Stall() +{ + UECONX = (1<<STALLRQ) | (1<<EPEN); +} + +static inline u8 ReadWriteAllowed() +{ + return UEINTX & (1<<RWAL); +} + +static inline u8 Stalled() +{ + return UEINTX & (1<<STALLEDI); +} + +static inline u8 FifoFree() +{ + return UEINTX & (1<<FIFOCON); +} + +static inline void ReleaseRX() +{ + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 +} + +static inline u8 FrameNumber() +{ + return UDFNUML; +} + +//================================================================== +//================================================================== + +#define EP_SINGLE_64 0x32 // EP0 +#define EP_DOUBLE_64 0x36 // Other endpoints + +static void InitEP(u8 index, u8 type, u8 size) +{ + UENUM = index; + UECONX = 1; + UECFG0X = type; + UECFG1X = size; +} + +// API +void USBInit(void) +{ + _timeout = 0; + _usbConfiguration = 0; + _ejected = 0; + + UHWCON = 0x01; // power internal reg (don't need this?) + USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled + PLLCSR = 0x12; // Need 16 MHz xtal + while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll + ; + USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock + UDCON = 0; // enable attach resistor +} + +u8 USBGetConfiguration(void) +{ + return _usbConfiguration; +} + +u8 HasData(u8 ep) +{ + SetEP(ep); + return ReadWriteAllowed(); // count in fifo +} + +int USBGetChar(); +void Recv(u8 ep, u8* dst, u8 len) +{ + SetEP(ep); + while (len--) + { + while (!ReadWriteAllowed()) + ; + *dst++ = Recv8(); + if (!ReadWriteAllowed()) // release empty buffer + ReleaseRX(); + } +} + +// Transmit a packet to endpoint +void Transfer(u8 ep, const u8* data, int len) +{ + u8 zero = ep & TRANSFER_ZERO; + SetEP(ep & 7); + while (len--) + { + while (!ReadWriteAllowed()) + ; // TODO Check for STALL etc + + u8 d = (ep & TRANSFER_PGM) ? pgm_read_byte(data) : data[0]; + data++; + if (zero) + d = 0; + Send8(d); + + if (!ReadWriteAllowed()) + ReleaseTX(); + } + if (ep & TRANSFER_RELEASE) + ReleaseTX(); +} + +extern const u8 _initEndpoints[] PROGMEM; +const u8 _initEndpoints[] = +{ + 0, + +#ifdef CDC_ENABLED + EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN +#endif + + EP_TYPE_INTERRUPT_IN, // HID_ENDPOINT_INT +}; + +static void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints); i++) + { + UENUM = i; + UECONX = 1; + UECFG0X = pgm_read_byte(_initEndpoints+i); + UECFG1X = EP_DOUBLE_64; + } + UERST = 0x7E; // And reset them + UERST = 0; +} + +typedef struct +{ + u8 bmRequestType; + u8 bRequest; + u8 wValueL; + u8 wValueH; + u16 wIndex; + u16 wLength; +} Setup; +Setup _setup; + +//bool USBHook(Setup& setup) +bool USBHook() +{ + Setup& setup = _setup; + u8 r = setup.bRequest; + + // CDC Requests + if (CDC_GET_LINE_CODING == r) + { + Send((const volatile u8*)&_usbLineInfo,7); + } + + else if (CDC_SET_LINE_CODING == r) + { + WaitOUT(); + Recv((volatile u8*)&_usbLineInfo,7); + ClearOUT(); + } + + else if (CDC_SET_CONTROL_LINE_STATE == r) + { + _usbLineInfo.lineState = setup.wValueL; + } + + return true; +} + +extern const u8 _rawHID[] PROGMEM; +#define LSB(_x) ((_x) & 0xFF) +#define MSB(_x) ((_x) >> 8) + +#define RAWHID_USAGE_PAGE 0xFFC0 +#define RAWHID_USAGE 0x0C00 +#define RAWHID_TX_SIZE 64 +#define RAWHID_RX_SIZE 64 + +const u8 _rawHID[] = +{ + // RAW HID + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + + 0xA1, 0x01, // Collection 0x01 + 0x85, 0x03, // REPORT_ID (3) + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + + 0x95, 64, // report count TX + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + + 0x95, 64, // report count RX + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +}; + +u8 _cdcComposite = 0; + +bool SendDescriptor() +{ + Setup& setup = _setup; + u8 desc_length = 0; + const u8* desc_addr = 0; + + u8 t = setup.wValueH; + if (0x22 == t) + { + desc_addr = _rawHID; + desc_length = sizeof(desc_length); + } else if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + if (setup.wLength == 8) + _cdcComposite = 1; + desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; + } + else if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + { + desc_addr = (const u8*)&USB_ConfigDescriptor; + desc_length = sizeof(USB_ConfigDescriptor); + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + if (setup.wValueL == 0) + desc_addr = (const u8*)&STRING_LANGUAGE; + else if (setup.wValueL == IPRODUCT) + desc_addr = (const u8*)&STRING_IPRODUCT; + else if (setup.wValueL == ISERIAL) + desc_addr = (const u8*)&STRING_SERIAL; + else if (setup.wValueL == IMANUFACTURER) + desc_addr = (const u8*)&STRING_IMANUFACTURER; + else + return false; + } else + return false; + + if (desc_length == 0) + desc_length = pgm_read_byte(desc_addr); + if ((u8)setup.wLength < desc_length) // bit of a cheat limiting to 255 bytes TODO (saved 8 bytes) + desc_length = (u8)setup.wLength; + + // Send descriptor + // EP0 is 64 bytes long + // RWAL and FIFOCON don't work on EP0 + u8 n = 0; + do + { + if (!WaitForINOrOUT()) + return false; + Send8(pgm_read_byte(&desc_addr[n++])); + u8 clr = n & 0x3F; + if (!clr) + ClearIN(); // Fifo is full, release this packet + } while (n < desc_length); + return true; +} + +void USBSetupInterrupt() +{ + SetEP(0); + if (!ReceivedSetupInt()) + return; + + Setup& setup = _setup; // global saves ~30 bytes + Recv((u8*)&setup,8); + ClearSetupInt(); + + if (setup.bmRequestType & DEVICETOHOST) + WaitIN(); + else + ClearIN(); + + bool ok = true; + u8 r = setup.bRequest; + if (SET_ADDRESS == r) + { + WaitIN(); + UDADDR = setup.wValueL | (1<<ADDEN); + } + else if (SET_CONFIGURATION == r) + { + _usbConfiguration = setup.wValueL; + InitEndpoints(); + } + else if (GET_CONFIGURATION == r) + { + Send8(_usbConfiguration); + } + else if (GET_STATUS == r) + { + Send8(0); // All good as far as I know + } + else if (GET_DESCRIPTOR == r) + { + ok = SendDescriptor(); + } + else + { + ok = USBHook(); + } + + if (ok) + ClearIN(); + else + Stall(); +} + +void USBGeneralInterrupt() +{ + u8 udint = UDINT; + UDINT = 0; + + // End of Reset + if (udint & (1<<EORSTI)) + { + InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64); // init ep0 + _usbConfiguration = 0; // not configured yet + } + + // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too + if (udint & (1<<SOFI)) + { + // check whether the one-shot period has elapsed. if so, turn off the LED + if (TxLEDPulse && !(--TxLEDPulse)) + TXLED0; + if (RxLEDPulse && !(--RxLEDPulse)) + RXLED0; + + if (!_ejected) + _timeout = 0; + } +} + +void LEDPulse(); +int USBGetChar() +{ + for(;;) + { + USBSetupInterrupt(); + USBGeneralInterrupt(); + + // Read a char + if (HasData(CDC_RX)) + { + u8 c = Recv8(); + if (!ReadWriteAllowed()) + ReleaseRX(); + return c; + } + + if (!--_timeout) { + Reboot(); // USB not connected, run firmware + } + + _delay_us(100); // stretch out the bootloader period to about 5 seconds after enumeration + LEDPulse(); + } + return -1; +} diff --git a/bootloaders/diskloader/src/USBCore.h b/bootloaders/diskloader/src/USBCore.h new file mode 100644 index 0000000..537c0ec --- /dev/null +++ b/bootloaders/diskloader/src/USBCore.h @@ -0,0 +1,246 @@ + +// Copyright (c) 2010, Peter Barrett +/* +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 + +// bmRequestType +#define HOSTTODEVICE 0x00 +#define DEVICETOHOST 0x80 +#define STANDARD 0x00 +#define CLASS 0x20 +#define VENDOR 0x40 +#define DEVICE 0x00 +#define INTERFACE 0x01 +#define ENDPOINT 0x02 +#define OTHER 0x03 + +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 + +// Descriptors + +#define USB_DEVICE_DESC_SIZE 18 +#define USB_CONFIGUARTION_DESC_SIZE 9 +#define USB_INTERFACE_DESC_SIZE 9 +#define USB_ENDPOINT_DESC_SIZE 7 + +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 + +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +// bMaxPower in Configuration Descriptor +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +// bEndpointAddress in Endpoint Descriptor +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 + +#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define CDC_V1_10 0x0110 +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_HEADER 0x00 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_UNION 0x06 +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 +#define CDC_DATA_INTERFACE_CLASS 0x0A + + +// Device +typedef struct { + u8 len; // 18 + u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE + u16 usbVersion; // 0x200 + u8 deviceClass; + u8 deviceSubClass; + u8 deviceProtocol; + u8 packetSize0; // Packet 0 + u16 idVendor; + u16 idProduct; + u16 deviceVersion; // 0x100 + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; + +// Config +typedef struct { + u8 len; // 9 + u8 dtype; // 2 + u16 clen; // total length + u8 numInterfaces; + u8 config; + u8 iconfig; + u8 attributes; + u8 maxPower; +} ConfigDescriptor; + +// String + +// Interface +typedef struct +{ + u8 len; // 9 + u8 dtype; // 4 + u8 number; + u8 alternate; + u8 numEndpoints; + u8 interfaceClass; + u8 interfaceSubClass; + u8 protocol; + u8 iInterface; +} InterfaceDescriptor; + +// Endpoint +typedef struct +{ + u8 len; // 7 + u8 dtype; // 5 + u8 addr; + u8 attr; + u16 packetSize; + u8 interval; +} EndpointDescriptor; + +// Interface Association Descriptor +// Used to bind 2 interfaces together in CDC compostite device +typedef struct +{ + u8 len; // 8 + u8 dtype; // 11 + u8 firstInterface; + u8 interfaceCount; + u8 functionClass; + u8 funtionSubClass; + u8 functionProtocol; + u8 iInterface; +} IADDescriptor; + +// CDC CS interface descriptor +typedef struct +{ + u8 len; // 5 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; + u8 d1; +} CDCCSInterfaceDescriptor; + +typedef struct +{ + u8 len; // 4 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; +} CDCCSInterfaceDescriptor4; + +typedef struct +{ + IADDescriptor iad; // Only needed on compound device + + // Control + InterfaceDescriptor cif; // + CDCCSInterfaceDescriptor header; + CDCCSInterfaceDescriptor callManagement; + CDCCSInterfaceDescriptor4 controlManagement; + CDCCSInterfaceDescriptor functionalDescriptor; + EndpointDescriptor cifin; + + // Data + InterfaceDescriptor dif; + EndpointDescriptor in; + EndpointDescriptor out; +} CDCDescriptor; + +typedef struct +{ + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct +{ + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + +#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ + { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } + +#define D_CONFIG(_totalLength,_interfaces) \ + { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(100) } + +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } + +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } + +#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ + { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } +#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } + +#endif
\ No newline at end of file diff --git a/bootloaders/diskloader/src/USBDesc.cpp b/bootloaders/diskloader/src/USBDesc.cpp new file mode 100644 index 0000000..ade072a --- /dev/null +++ b/bootloaders/diskloader/src/USBDesc.cpp @@ -0,0 +1,87 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" + +//==================================================================================================== +//==================================================================================================== +// Actual device descriptors + +const u16 STRING_LANGUAGE[2] = { + (3<<8) | (2+2), + 0x0409 // English +}; + +const u16 STRING_SERIAL[13] = { + (3<<8) | (2+2*12), + USB_SERIAL_STRING +}; + +const u16 STRING_IPRODUCT[28] = { + (3<<8) | (2+2*27), +#if USB_PID == USB_PID_LEONARDO + 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o',' ','b','o','o','t','l','o','a','d','e','r' +#elif USB_PID == USB_PID_MICRO + 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ','b','o','o','t','l','o','a','d','e','r',' ',' ',' ' +#endif +}; + +const u16 STRING_IMANUFACTURER[12] = { + (3<<8) | (2+2*11), + 'A','r','d','u','i','n','o',' ','L','L','C' +}; + + +//#ifdef CDC_ENABLED +DeviceDescriptor USB_DeviceDescriptorA = D_DEVICE(0X02,0X00,0X00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1); +//#else +DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,0,IPRODUCT,ISERIAL,1); +//#endif + + +Config USB_ConfigDescriptor = +{ + D_CONFIG(sizeof(Config),INTERFACE_COUNT), + +#ifdef CDC_ENABLED + // CDC + { + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,2), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) + }, +#endif + // HID + { + D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_HIDREPORT(30), + D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x40) + } +}; + diff --git a/bootloaders/diskloader/src/USBDesc.h b/bootloaders/diskloader/src/USBDesc.h new file mode 100644 index 0000000..a970fa4 --- /dev/null +++ b/bootloaders/diskloader/src/USBDesc.h @@ -0,0 +1,65 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + + +#ifdef CDC_ENABLED + +#define CDC_ACM_INTERFACE 0 // CDC ACM +#define CDC_DATA_INTERFACE 1 // CDC Data +#define CDC_ENDPOINT_ACM 1 +#define CDC_ENDPOINT_OUT 2 +#define CDC_ENDPOINT_IN 3 + +#define HID_INTERFACE 2 // HID Interface +#define HID_ENDPOINT_INT 4 + +#define INTERFACE_COUNT 3 // 2 for cdc + 1 for hid + +#else + +#define HID_INTERFACE 2 // HID Interface +#define HID_ENDPOINT_INT 4 + +#define INTERFACE_COUNT 1 // 1 for hid + +#endif + +typedef struct +{ + ConfigDescriptor config; +#ifdef CDC_ENABLED + CDCDescriptor cdc; +#endif + HIDDescriptor hid; +} Config; + +extern Config USB_ConfigDescriptor PROGMEM; +extern DeviceDescriptor USB_DeviceDescriptor PROGMEM; +extern DeviceDescriptor USB_DeviceDescriptorA PROGMEM; + +extern const u16 STRING_LANGUAGE[2] PROGMEM; +extern const u16 STRING_IPRODUCT[28] PROGMEM; +extern const u16 STRING_IMANUFACTURER[12] PROGMEM; +extern const u16 STRING_SERIAL[13] PROGMEM; + +#define IMANUFACTURER 1 +#define IPRODUCT 2 +#define ISERIAL 3 + +#define CDC_TX CDC_ENDPOINT_IN +#define CDC_RX CDC_ENDPOINT_OUT
\ No newline at end of file diff --git a/bootloaders/optiboot/Makefile b/bootloaders/optiboot/Makefile index 0fd6005..b9f3ed5 100644 --- a/bootloaders/optiboot/Makefile +++ b/bootloaders/optiboot/Makefile @@ -19,13 +19,70 @@ # program name should not be changed... PROGRAM = optiboot +# The default behavior is to build using tools that are in the users +# current path variables, but we can also build using an installed +# Arduino user IDE setup, or the Arduino source tree. +# Uncomment this next lines to build within the arduino environment, +# using the arduino-included avrgcc toolset (mac and pc) +# ENV ?= arduino +# ENV ?= arduinodev +# OS ?= macosx +# OS ?= windows + + # enter the parameters for the avrdude isp tool ISPTOOL = stk500v2 ISPPORT = usb ISPSPEED = -b 115200 MCU_TARGET = atmega168 -LDSECTION = --section-start=.text=0x3e00 +LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe + +# Build environments +# Start of some ugly makefile-isms to allow optiboot to be built +# in several different environments. See the README.TXT file for +# details. + +# default +fixpath = $(1) + +ifeq ($(ENV), arduino) +# For Arduino, we assume that we're connected to the optiboot directory +# included with the arduino distribution, which means that the full set +# of avr-tools are "right up there" in standard places. +TOOLROOT = ../../../tools +GCCROOT = $(TOOLROOT)/avr/bin/ +AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf + +ifeq ($(OS), windows) +# On windows, SOME of the tool paths will need to have backslashes instead +# of forward slashes (because they use windows cmd.exe for execution instead +# of a unix/mingw shell?) We also have to ensure that a consistent shell +# is used even if a unix shell is installed (ie as part of WINAVR) +fixpath = $(subst /,\,$1) +SHELL = cmd.exe +endif + +else ifeq ($(ENV), arduinodev) +# Arduino IDE source code environment. Use the unpacked compilers created +# by the build (you'll need to do "ant build" first.) +ifeq ($(OS), macosx) +TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools +endif +ifeq ($(OS), windows) +TOOLROOT = ../../../../build/windows/work/hardware/tools +endif + +GCCROOT = $(TOOLROOT)/avr/bin/ +AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf + +else +GCCROOT = +AVRDUDE_CONF = +endif +# +# End of build environment code. + # the efuse should really be 0xf8; since, however, only the lower # three bits of that byte are used on the atmega168, avrdude gets @@ -33,14 +90,17 @@ LDSECTION = --section-start=.text=0x3e00 # http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/ # # similarly, the lock bits should be 0xff instead of 0x3f (to -# unlock the bootloader section) and 0xcf instead of 0x0f (to +# unlock the bootloader section) and 0xcf instead of 0x2f (to # lock it), but since the high two bits of the lock byte are # unused, avrdude would get confused. -ISPFUSES = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ --e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m -ISPFLASH = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ --U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m +ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \ + -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ + -e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \ + -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m +ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \ + -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ + -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe" STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \ @@ -53,15 +113,27 @@ OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls DEFS = LIBS = -CC = avr-gcc +CC = $(GCCROOT)avr-gcc # Override is only needed by avr-lib build system. override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS) -override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles +override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump +OBJCOPY = $(GCCROOT)avr-objcopy +OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump) + +SIZE = $(GCCROOT)avr-size + +# Test platforms +# Virtual boot block test +virboot328: TARGET = atmega328 +virboot328: MCU_TARGET = atmega328p +virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT' +virboot328: 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 # @@ -69,6 +141,7 @@ OBJDUMP = avr-objdump # 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 @@ -76,9 +149,12 @@ pro20: $(PROGRAM)_pro_20mhz.lst pro20_isp: pro20 pro20_isp: TARGET = pro_20mhz -pro20_isp: HFUSE = DD # 2.7V brownout -pro20_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms -pro20_isp: EFUSE = 02 # 512 byte boot +# 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 @@ -87,6 +163,7 @@ pro20_isp: isp # 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 @@ -94,14 +171,37 @@ pro16: $(PROGRAM)_pro_16MHz.lst pro16_isp: pro16 pro16_isp: TARGET = pro_16MHz -pro16_isp: HFUSE = DD # 2.7V brownout -pro16_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms -pro16_isp: EFUSE = 02 # 512 byte boot +# 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 and NG use identical bootloaders +# Diecimila, Duemilanove with m168, and NG use identical bootloaders +# Call it "atmega168" for generality and clarity, keep "diecimila" for +# backward compatibility of makefile # +atmega168: TARGET = atmega168 +atmega168: MCU_TARGET = atmega168 +atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' +atmega168: AVR_FREQ = 16000000L +atmega168: $(PROGRAM)_atmega168.hex +atmega168: $(PROGRAM)_atmega168.lst + +atmega168_isp: atmega168 +atmega168_isp: TARGET = atmega168 +# 2.7V brownout +atmega168_isp: HFUSE = DD +# Low power xtal (16MHz) 16KCK/14CK+65ms +atmega168_isp: LFUSE = FF +# 512 byte boot +atmega168_isp: EFUSE = 04 +atmega168_isp: isp + diecimila: TARGET = diecimila +diecimila: MCU_TARGET = atmega168 diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' diecimila: AVR_FREQ = 16000000L diecimila: $(PROGRAM)_diecimila.hex @@ -109,85 +209,188 @@ diecimila: $(PROGRAM)_diecimila.lst diecimila_isp: diecimila diecimila_isp: TARGET = diecimila -diecimila_isp: HFUSE = DD # 2.7V brownout -diecimila_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms -diecimila_isp: EFUSE = 02 # 512 byte boot +# 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: LDSECTION = --section-start=.text=0x7e00 +atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe atmega328: $(PROGRAM)_atmega328.hex atmega328: $(PROGRAM)_atmega328.lst atmega328_isp: atmega328 atmega328_isp: TARGET = atmega328 atmega328_isp: MCU_TARGET = atmega328p -atmega328_isp: HFUSE = DE # 512 byte boot -atmega328_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms -atmega328_isp: EFUSE = 05 # 2.7V brownout +# 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 +# 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: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200' +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 -lilypad_isp: HFUSE = DD # 2.7V brownout -lilypad_isp: LFUSE = E2 # Internal 8MHz osc (8MHz) Slow rising power -lilypad_isp: EFUSE = 02 # 512 byte boot +# 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: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200' +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 -lilypad_resonator_isp: HFUSE = DD # 2.7V brownout -lilypad_resonator_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms -lilypad_resonator_isp: EFUSE = 02 # 512 byte boot +# 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: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200' +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 -pro8_isp: HFUSE = DD # 2.7V brownout -pro8_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms -pro8_isp: EFUSE = 02 # 512 byte boot +# 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: LDSECTION = --section-start=.text=0x7e00 +atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst atmega328_pro8_isp: atmega328_pro8 atmega328_pro8_isp: TARGET = atmega328_pro_8MHz atmega328_pro8_isp: MCU_TARGET = atmega328p -atmega328_pro8_isp: HFUSE = DE # 512 byte boot -atmega328_pro8_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms -atmega328_pro8_isp: EFUSE = 05 # 2.7V brownout +# 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 @@ -200,18 +403,26 @@ luminet: MCU_TARGET = attiny84 luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600' luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION' luminet: AVR_FREQ = 1000000L -luminet: LDSECTION = --section-start=.text=0x1d00 +luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe luminet: $(PROGRAM)_luminet.hex luminet: $(PROGRAM)_luminet.lst luminet_isp: luminet luminet_isp: TARGET = luminet luminet_isp: MCU_TARGET = attiny84 -luminet_isp: HFUSE = DF # Brownout disabled -luminet_isp: LFUSE = 62 # 1MHz internal oscillator, slowly rising power -luminet_isp: EFUSE = FE # Self-programming enable +# 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) @@ -222,6 +433,7 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex %.elf: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + $(SIZE) $@ clean: rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex @@ -230,10 +442,10 @@ clean: $(OBJDUMP) -h -S $< > $@ %.hex: %.elf - $(OBJCOPY) -j .text -j .data -O ihex $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@ %.srec: %.elf - $(OBJCOPY) -j .text -j .data -O srec $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@ %.bin: %.elf - $(OBJCOPY) -j .text -j .data -O binary $< $@ + $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@ diff --git a/bootloaders/optiboot/README.TXT b/bootloaders/optiboot/README.TXT new file mode 100644 index 0000000..cd79cd9 --- /dev/null +++ b/bootloaders/optiboot/README.TXT @@ -0,0 +1,81 @@ +This directory contains the Optiboot small bootloader for AVR +microcontrollers, somewhat modified specifically for the Arduino +environment. + +Optiboot is more fully described here: http://code.google.com/p/optiboot/ +and is the work of Peter Knight (aka Cathedrow), building on work of Jason P +Kyle, Spiff, and Ladyada. Arduino-specific modification are by Bill +Westfield (aka WestfW) + +Arduino-specific issues are tracked as part of the Arduino project +at http://code.google.com/p/arduino + + +------------------------------------------------------------ +Building optiboot for Arduino. + +Production builds of optiboot for Arduino are done on a Mac in "unix mode" +using CrossPack-AVR-20100115. CrossPack tracks WINAVR (for windows), which +is just a package of avr-gcc and related utilities, so similar builds should +work on Windows or Linux systems. + +One of the Arduino-specific changes is modifications to the makefile to +allow building optiboot using only the tools installed as part of the +Arduino environment, or the Arduino source development tree. All three +build procedures should yield identical binaries (.hex files) (although +this may change if compiler versions drift apart between CrossPack and +the Arduino IDE.) + + +Building Optiboot in the Arduino IDE Install. + +Work in the .../hardware/arduino/bootloaders/optiboot/ and use the +"omake <targets>" command, which just generates a command that uses +the arduino-included "make" utility with a command like: + make OS=windows ENV=arduino <targets> +or make OS=macosx ENV=arduino <targets> +On windows, this assumes you're using the windows command shell. If +you're using a cygwin or mingw shell, or have one of those in your +path, the build will probably break due to slash vs backslash issues. +On a Mac, if you have the developer tools installed, you can use the +Apple-supplied version of make. +The makefile uses relative paths ("../../../tools/" and such) to find +the programs it needs, so you need to work in the existing optiboot +directory (or something created at the same "level") for it to work. + + +Building Optiboot in the Arduino Source Development Install. + +In this case, there is no special shell script, and you're assumed to +have "make" installed somewhere in your path. +Build the Arduino source ("ant build") to unpack the tools into the +expected directory. +Work in Arduino/hardware/arduino/bootloaders/optiboot and use + make OS=windows ENV=arduinodev <targets> +or make OS=macosx ENV=arduinodev <targets> + + +Programming Chips Using the _isp Targets + +The CPU targets have corresponding ISP targets that will actuall +program the bootloader into a chip. "atmega328_isp" for the atmega328, +for example. These will set the fuses and lock bits as appropriate as +well as uploading the bootloader code. + +The makefiles default to using a USB programmer, but you can use +a serial programmer like ArduinoISP by changing the appropriate +variables when you invoke make: + + make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN \ + ISPSPEED=-b19200 atmega328_isp + +The "atmega8_isp" target does not currently work, because the mega8 +doesn't have the "extended" fuse that the generic ISP target wants to +pass on to avrdude. You'll need to run avrdude manually. + + +Standard Targets + +I've reduced the pre-built and source-version-controlled targets +(.hex and .lst files included in the git repository) to just the +three basic 16MHz targets: atmega8, atmega16, atmega328. diff --git a/bootloaders/optiboot/boot.h b/bootloaders/optiboot/boot.h new file mode 100644 index 0000000..2639cd8 --- /dev/null +++ b/bootloaders/optiboot/boot.h @@ -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_ */ diff --git a/bootloaders/optiboot/makeall b/bootloaders/optiboot/makeall index 7a0b82d..f076bc7 100755 --- a/bootloaders/optiboot/makeall +++ b/bootloaders/optiboot/makeall @@ -1,13 +1,20 @@ #!/bin/bash make clean +# +# The "big three" standard bootloaders. +make atmega8 +make atmega168 +make atmega328 +# +# additional buildable platforms of +# somewhat questionable support level make lilypad make lilypad_resonator make pro8 make pro16 make pro20 -make diecimila -make ng -make atmega328 make atmega328_pro8 +make sanguino +make mega +make atmega88 make luminet - diff --git a/bootloaders/optiboot/omake b/bootloaders/optiboot/omake new file mode 100644 index 0000000..cc7c6bc --- /dev/null +++ b/bootloaders/optiboot/omake @@ -0,0 +1,2 @@ +echo ../../../tools/avr/bin/make OS=macosx ENV=arduino $* +../../../tools/avr/bin/make OS=macosx ENV=arduino $* diff --git a/bootloaders/optiboot/omake.bat b/bootloaders/optiboot/omake.bat new file mode 100644 index 0000000..f6815da --- /dev/null +++ b/bootloaders/optiboot/omake.bat @@ -0,0 +1 @@ +..\..\..\tools\avr\utils\bin\make OS=windows ENV=arduino %* diff --git a/bootloaders/optiboot/optiboot.c b/bootloaders/optiboot/optiboot.c index c7d817a..d499d85 100644 --- a/bootloaders/optiboot/optiboot.c +++ b/bootloaders/optiboot/optiboot.c @@ -1,6 +1,11 @@ /**********************************************************/ /* Optiboot bootloader for Arduino */ /* */ +/* http://optiboot.googlecode.com */ +/* */ +/* Arduino-maintained version : See README.TXT */ +/* http://code.google.com/p/arduino/ */ +/* */ /* Heavily optimised bootloader that is faster and */ /* smaller than the Arduino standard bootloader */ /* */ @@ -10,6 +15,8 @@ /* Higher baud rate speeds up programming */ /* Written almost entirely in C */ /* Customisable timeout with accurate timeconstant */ +/* Optional virtual UART. No hardware UART required. */ +/* Optional virtual boot partition for devices without. */ /* */ /* What you lose: */ /* Implements a skeleton STK500 protocol which is */ @@ -18,12 +25,19 @@ /* High baud rate breaks compatibility with standard */ /* Arduino flash settings */ /* */ -/* Currently supports: */ -/* ATmega168 based devices (Diecimila etc) */ +/* Fully supported: */ +/* ATmega168 based devices (Diecimila etc) */ /* ATmega328P based devices (Duemilanove etc) */ /* */ +/* Alpha test */ +/* ATmega1280 based devices (Arduino Mega) */ +/* */ +/* Work in progress: */ +/* ATmega644P based devices (Sanguino) */ +/* ATtiny84 based devices (Luminet) */ +/* */ /* Does not support: */ -/* ATmega1280 based devices (eg. Mega) */ +/* USB based devices (eg. Teensy) */ /* */ /* Assumptions: */ /* The code makes several assumptions that reduce the */ @@ -64,102 +78,123 @@ /* */ /**********************************************************/ + +/**********************************************************/ +/* */ +/* Optional defines: */ +/* */ +/**********************************************************/ +/* */ +/* BIG_BOOT: */ +/* Build a 1k bootloader, not 512 bytes. This turns on */ +/* extra functionality. */ +/* */ +/* BAUD_RATE: */ +/* Set bootloader baud rate. */ +/* */ +/* LUDICROUS_SPEED: */ +/* 230400 baud :-) */ +/* */ +/* SOFT_UART: */ +/* Use AVR305 soft-UART instead of hardware UART. */ +/* */ +/* LED_START_FLASHES: */ +/* Number of LED flashes on bootup. */ +/* */ +/* LED_DATA_FLASH: */ +/* Flash LED when transferring data. For boards without */ +/* TX or RX LEDs, or for people who like blinky lights. */ +/* */ +/* SUPPORT_EEPROM: */ +/* Support reading and writing from EEPROM. This is not */ +/* used by Arduino, so off by default. */ +/* */ +/* TIMEOUT_MS: */ +/* Bootloader timeout period, in milliseconds. */ +/* 500,1000,2000,4000,8000 supported. */ +/* */ +/**********************************************************/ + +/**********************************************************/ +/* Version Numbers! */ +/* */ +/* Arduino Optiboot now includes this Version number in */ +/* the source and object code. */ +/* */ +/* Version 3 was released as zip from the optiboot */ +/* repository and was distributed with Arduino 0022. */ +/* Version 4 starts with the arduino repository commit */ +/* that brought the arduino repository up-to-date with */ +/* the optiboot source tree changes since v3. */ +/* */ +/**********************************************************/ + +/**********************************************************/ +/* Edit History: */ +/* */ +/* 4.4 WestfW: add initialization of address to keep */ +/* the compiler happy. Change SC'ed targets. */ +/* Return the SW version via READ PARAM */ +/* 4.3 WestfW: catch framing errors in getch(), so that */ +/* AVRISP works without HW kludges. */ +/* http://code.google.com/p/arduino/issues/detail?id=368n*/ +/* 4.2 WestfW: reduce code size, fix timeouts, change */ +/* verifySpace to use WDT instead of appstart */ +/* 4.1 WestfW: put version number in binary. */ +/**********************************************************/ + +#define OPTIBOOT_MAJVER 4 +#define OPTIBOOT_MINVER 4 + +#define MAKESTR(a) #a +#define MAKEVER(a, b) MAKESTR(a*256+b) + +asm(" .section .version\n" + "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n" + " .section .text\n"); + #include <inttypes.h> #include <avr/io.h> #include <avr/pgmspace.h> -#include <avr/boot.h> -//#define LED_DATA_FLASH +// <avr/boot.h> uses sts instructions, but this version uses out instructions +// This saves cycles and program memory. +#include "boot.h" + + +// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need. + +#include "pin_defs.h" +#include "stk500.h" #ifndef LED_START_FLASHES #define LED_START_FLASHES 0 #endif -/* Build-time variables */ -/* BAUD_RATE Programming baud rate */ -/* LED_NO_FLASHES Number of LED flashes on boot */ -/* FLASH_TIME_MS Duration of each LED flash */ -/* BOOT_TIMEOUT_MS Serial port wait time before exiting bootloader */ +#ifdef LUDICROUS_SPEED +#define BAUD_RATE 230400L +#endif -/* set the UART baud rate */ +/* set the UART baud rate defaults */ #ifndef BAUD_RATE -#define BAUD_RATE 19200 +#if F_CPU >= 8000000L +#define BAUD_RATE 115200L // Highest rate Avrdude win32 will support +#elsif F_CPU >= 1000000L +#define BAUD_RATE 9600L // 19200 also supported, but with significant error +#elsif F_CPU >= 128000L +#define BAUD_RATE 4800L // Good for 128kHz internal RC +#else +#define BAUD_RATE 1200L // Good even at 32768Hz +#endif #endif -#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) -/* 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 +/* Switch in soft UART for hard baud rates */ +#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz +#ifndef SOFT_UART +#define SOFT_UART #endif #endif -#if defined(__AVR_ATtiny84__) -/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ -#define LED_DDR DDRA -#define LED_PORT PORTA -#define LED_PIN PINA -#define LED PINA4 - -/* Ports for soft UART - left port only for now*/ -#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 - -/* 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' - /* Watchdog settings */ #define WATCHDOG_OFF (0) #define WATCHDOG_16MS (_BV(WDE)) @@ -170,8 +205,10 @@ #define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE)) #define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE)) #define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE)) -#define WATCHDOG_4S (_BV(WDE3) | _BV(WDE)) -#define WATCHDOG_8S (_BV(WDE3) | _BV(WDE0) | _BV(WDE)) +#ifndef __AVR_ATmega8__ +#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE)) +#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE)) +#endif /* Function Prototypes */ /* The main function is in init9, which removes the interrupt vector table */ @@ -191,18 +228,48 @@ void uartDelay() __attribute__ ((naked)); #endif void appStart() __attribute__ ((naked)); +#if defined(__AVR_ATmega168__) +#define RAMSTART (0x100) +#define NRWWSTART (0x3800) +#elif defined(__AVR_ATmega328P__) +#define RAMSTART (0x100) +#define NRWWSTART (0x7000) +#elif defined (__AVR_ATmega644P__) +#define RAMSTART (0x100) +#define NRWWSTART (0xE000) +#elif defined(__AVR_ATtiny84__) +#define RAMSTART (0x100) +#define NRWWSTART (0x0000) +#elif defined(__AVR_ATmega1280__) +#define RAMSTART (0x200) +#define NRWWSTART (0xE000) +#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) +#define RAMSTART (0x100) +#define NRWWSTART (0x1800) +#endif + /* C zero initialises all global variables. However, that requires */ /* These definitions are NOT zero initialised, but that doesn't matter */ /* This allows us to drop the zero init code, saving us memory */ -#define buff ((uint8_t*)(0x100)) -#define address (*(uint16_t*)(0x200)) -#define length (*(uint8_t*)(0x202)) +#define buff ((uint8_t*)(RAMSTART)) #ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #endif + /* main program starts here */ int main(void) { + uint8_t ch; + + /* + * Making these local and in registers prevents the need for initializing + * them, and also saves space because code no longer stores to memory. + * (initializing address keeps the compiler happy, but isn't really + * necessary, and uses 4 bytes of flash.) + */ + register uint16_t address = 0; + register uint8_t length; + // After the zero init loop, this is the first code to run. // // This code makes the following assumptions: @@ -212,29 +279,36 @@ int main(void) { // // If not, uncomment the following instructions: // cli(); - // SP=RAMEND; // This is done by hardware reset asm volatile ("clr __zero_reg__"); +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif - uint8_t ch; + // Adaboot no-wait mod + ch = MCUSR; + MCUSR = 0; + if (!(ch & _BV(EXTRF))) appStart(); #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 #endif #ifndef SOFT_UART +#ifdef __AVR_ATmega8__ + UCSRA = _BV(U2X); //Double speed mode USART + UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 + UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#else UCSR0A = _BV(U2X0); //Double speed mode USART0 UCSR0B = _BV(RXEN0) | _BV(TXEN0); UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); #endif - - // Adaboot no-wait mod - ch = MCUSR; - MCUSR = 0; - if (!(ch & _BV(EXTRF))) appStart(); +#endif // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); + watchdogConfig(WATCHDOG_1S); /* Set LED pin as output */ LED_DDR |= _BV(LED); @@ -255,9 +329,22 @@ int main(void) { ch = getch(); if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - putch(0x03); + unsigned char which = getch(); + verifySpace(); + if (which == 0x82) { + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + putch(OPTIBOOT_MAJVER); + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + } } else if(ch == STK_SET_DEVICE) { // SET DEVICE is ignored @@ -269,9 +356,15 @@ int main(void) { } else if(ch == STK_LOAD_ADDRESS) { // LOAD ADDRESS - address = getch(); - address = (address & 0xff) | (getch() << 8); - address += address; // Convert from word address to byte address + uint16_t newAddress; + newAddress = getch(); + newAddress = (newAddress & 0xff) | (getch() << 8); +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; +#endif + newAddress += newAddress; // Convert from word address to byte address + address = newAddress; verifySpace(); } else if(ch == STK_UNIVERSAL) { @@ -279,25 +372,31 @@ int main(void) { getNch(4); putch(0x00); } - /* Write memory, length is big endian and is in bytes */ + /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); + getch(); /* getlen() */ + length = getch(); + getch(); - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); + // If we are in RWW section, immediately start page erase + if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); while (--length); + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + // 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(); @@ -310,10 +409,10 @@ int main(void) { // Move RESET vector to WDT vector uint16_t vect = buff[0] | (buff[1]<<8); rstVect = vect; - wdtVect = buff[10] | (buff[11]<<8); + wdtVect = buff[8] | (buff[9]<<8); vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. - buff[10] = vect & 0xff; - buff[11] = vect >> 8; + buff[8] = vect & 0xff; + buff[9] = vect >> 8; // Add jump to bootloader at RESET vector buff[0] = 0x7f; @@ -329,12 +428,12 @@ int main(void) { uint16_t a; a = *bufPtr++; a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); addrPtr += 2; } while (--ch); - + // Write from programming buffer - boot_page_write((uint16_t)(void*)address); + __boot_page_write_short((uint16_t)(void*)address); boot_spm_busy_wait(); #if defined(RWWSRE) @@ -346,23 +445,38 @@ int main(void) { /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { // READ PAGE - we only read flash - getLen(); + getch(); /* getlen() */ + length = getch(); + getch(); + verifySpace(); #ifdef VIRTUAL_BOOT_PARTITION do { // 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 == 10) ch=wdtVect & 0xff; - else if (address == 11) ch=wdtVect >> 8; + else if (address == 8) ch=wdtVect & 0xff; + else if (address == 9) ch=wdtVect >> 8; else ch = pgm_read_byte_near(address); address++; putch(ch); } while (--length); #else +#ifdef __AVR_ATmega1280__ +// do putch(pgm_read_byte_near(address++)); +// while (--length); + do { + uint8_t result; + __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address)); + putch(result); + address++; + } + while (--length); +#else do putch(pgm_read_byte_near(address++)); while (--length); #endif +#endif } /* Get device signature bytes */ @@ -419,11 +533,13 @@ void putch(char ch) { uint8_t getch(void) { uint8_t ch; - watchdogReset(); - #ifdef LED_DATA_FLASH +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); #endif +#endif #ifdef SOFT_UART __asm__ __volatile__ ( @@ -434,7 +550,7 @@ uint8_t getch(void) { " rcall uartDelay\n" // Wait 1 bit period " clc\n" " sbic %[uartPin],%[uartBit]\n" - " sec\n" + " sec\n" " dec %[bitCnt]\n" " breq 3f\n" " ror %[ch]\n" @@ -450,19 +566,37 @@ uint8_t getch(void) { "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); + while(!(UCSR0A & _BV(RXC0))) + ; + if (!(UCSR0A & _BV(FE0))) { + /* + * A Framing Error indicates (probably) that something is talking + * to us at the wrong bit rate. Assume that this is because it + * expects to be talking to the application, and DON'T reset the + * watchdog. This should cause the bootloader to abort and run + * the application "soon", if it keeps happening. (Note that we + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; #endif #ifdef LED_DATA_FLASH +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); #endif +#endif return ch; } #ifdef SOFT_UART -//#define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6) +// AVR350 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6) +// Adding 3 to numerator simulates nearest rounding for more accurate baud rates #define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6) #if UART_B_VALUE > 255 #error Baud rate too slow for soft UART @@ -485,7 +619,11 @@ void getNch(uint8_t count) { } void verifySpace() { - if (getch() != CRC_EOP) appStart(); + if (getch() != CRC_EOP) { + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); } @@ -495,18 +633,16 @@ void flash_led(uint8_t count) { TCNT1 = -(F_CPU/(1024*16)); TIFR1 = _BV(TOV1); while(!(TIFR1 & _BV(TOV1))); +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); +#endif watchdogReset(); } while (--count); } #endif -uint8_t getLen() { - getch(); - length = getch(); - return getch(); -} - // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( @@ -524,7 +660,7 @@ void appStart() { __asm__ __volatile__ ( #ifdef VIRTUAL_BOOT_PARTITION // Jump to WDT vector - "ldi r30,5\n" + "ldi r30,4\n" "clr r31\n" #else // Jump to RST vector diff --git a/bootloaders/optiboot/optiboot_atmega168.hex b/bootloaders/optiboot/optiboot_atmega168.hex new file mode 100644 index 0000000..c2f2b5b --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega168.hex @@ -0,0 +1,35 @@ +:103E0000112484B714BE81FFF0D085E08093810037
+:103E100082E08093C00088E18093C10086E08093B7
+:103E2000C20080E18093C4008EE0C9D0259A86E06C
+:103E300020E33CEF91E0309385002093840096BB13
+:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
+:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
+:103E6000A2D0813461F49FD0082FAFD0023811F076
+:103E7000013811F484E001C083E08DD089C0823420
+:103E800011F484E103C0853419F485E0A6D080C024
+:103E9000853579F488D0E82EFF2485D0082F10E0EE
+:103EA000102F00270E291F29000F111F8ED0680127
+:103EB0006FC0863521F484E090D080E0DECF843678
+:103EC00009F040C070D06FD0082F6DD080E0C816C8
+:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
+:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
+:103EF00018F0F601B7BEE89568D007B600FCFDCF14
+:103F0000A601A0E0B1E02C9130E011968C911197C0
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
+:103F300051F7F601A7BEE89507B600FCFDCF97BE86
+:103F4000E89526C08437B1F42ED02DD0F82E2BD092
+:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
+:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
+:103F7000D11C0EC0853739F428D08EE10CD084E9ED
+:103F80000AD086E07ACF813511F488E018D01DD0B0
+:103F900080E101D065CF982F8091C00085FFFCCFD4
+:103FA0009093C60008958091C00087FFFCCF809158
+:103FB000C00084FD01C0A8958091C6000895E0E688
+:103FC000F0E098E1908380830895EDDF803219F06E
+:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
+:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
+:043FF000FF2709940A
+:023FFE000404B9
+:0400000300003E00BB
+:00000001FF
diff --git a/bootloaders/optiboot/optiboot_atmega168.lst b/bootloaders/optiboot/optiboot_atmega168.lst new file mode 100644 index 0000000..06316db --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega168.lst @@ -0,0 +1,598 @@ + +optiboot_atmega168.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 000001f4 00003e00 00003e00 00000054 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .version 00000002 00003ffe 00003ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 + CONTENTS, READONLY, DEBUGGING + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 + CONTENTS, READONLY, DEBUGGING + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 00000488 00000000 00000000 000006f1 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_frame 00000080 00000000 00000000 00000b7c 2**2 + CONTENTS, READONLY, DEBUGGING + 8 .debug_str 0000014f 00000000 00000000 00000bfc 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_loc 000002d8 00000000 00000000 00000d4b 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_ranges 00000078 00000000 00000000 00001023 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00003e00 <main>: +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 3e00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif + + // Adaboot no-wait mod + ch = MCUSR; + 3e02: 84 b7 in r24, 0x34 ; 52 + MCUSR = 0; + 3e04: 14 be out 0x34, r1 ; 52 + if (!(ch & _BV(EXTRF))) appStart(); + 3e06: 81 ff sbrs r24, 1 + 3e08: f0 d0 rcall .+480 ; 0x3fea <appStart> + +#if LED_START_FLASHES > 0 + // Set up Timer 1 for timeout counter + TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 + 3e0a: 85 e0 ldi r24, 0x05 ; 5 + 3e0c: 80 93 81 00 sts 0x0081, r24 + UCSRA = _BV(U2X); //Double speed mode USART + UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 + UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#else + UCSR0A = _BV(U2X0); //Double speed mode USART0 + 3e10: 82 e0 ldi r24, 0x02 ; 2 + 3e12: 80 93 c0 00 sts 0x00C0, r24 + UCSR0B = _BV(RXEN0) | _BV(TXEN0); + 3e16: 88 e1 ldi r24, 0x18 ; 24 + 3e18: 80 93 c1 00 sts 0x00C1, r24 + UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); + 3e1c: 86 e0 ldi r24, 0x06 ; 6 + 3e1e: 80 93 c2 00 sts 0x00C2, r24 + UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); + 3e22: 80 e1 ldi r24, 0x10 ; 16 + 3e24: 80 93 c4 00 sts 0x00C4, r24 +#endif +#endif + + // Set up watchdog to trigger after 500ms + watchdogConfig(WATCHDOG_1S); + 3e28: 8e e0 ldi r24, 0x0E ; 14 + 3e2a: c9 d0 rcall .+402 ; 0x3fbe <watchdogConfig> + + /* Set LED pin as output */ + LED_DDR |= _BV(LED); + 3e2c: 25 9a sbi 0x04, 5 ; 4 + 3e2e: 86 e0 ldi r24, 0x06 ; 6 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 3e30: 20 e3 ldi r18, 0x30 ; 48 + 3e32: 3c ef ldi r19, 0xFC ; 252 + TIFR1 = _BV(TOV1); + 3e34: 91 e0 ldi r25, 0x01 ; 1 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 3e36: 30 93 85 00 sts 0x0085, r19 + 3e3a: 20 93 84 00 sts 0x0084, r18 + TIFR1 = _BV(TOV1); + 3e3e: 96 bb out 0x16, r25 ; 22 + while(!(TIFR1 & _BV(TOV1))); + 3e40: b0 9b sbis 0x16, 0 ; 22 + 3e42: fe cf rjmp .-4 ; 0x3e40 <main+0x40> +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else + LED_PIN |= _BV(LED); + 3e44: 1d 9a sbi 0x03, 5 ; 3 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 3e46: a8 95 wdr + LED_PORT ^= _BV(LED); +#else + LED_PIN |= _BV(LED); +#endif + watchdogReset(); + } while (--count); + 3e48: 81 50 subi r24, 0x01 ; 1 + 3e4a: a9 f7 brne .-22 ; 0x3e36 <main+0x36> + 3e4c: cc 24 eor r12, r12 + 3e4e: dd 24 eor r13, r13 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 3e50: 88 24 eor r8, r8 + 3e52: 83 94 inc r8 + addrPtr += 2; + } while (--ch); + + // Write from programming buffer + __boot_page_write_short((uint16_t)(void*)address); + 3e54: b5 e0 ldi r27, 0x05 ; 5 + 3e56: ab 2e mov r10, r27 + boot_spm_busy_wait(); + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 3e58: a1 e1 ldi r26, 0x11 ; 17 + 3e5a: 9a 2e mov r9, r26 + do *bufPtr++ = getch(); + while (--length); + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 3e5c: f3 e0 ldi r31, 0x03 ; 3 + 3e5e: bf 2e mov r11, r31 +#endif + + /* Forever loop */ + for (;;) { + /* get character from UART */ + ch = getch(); + 3e60: a2 d0 rcall .+324 ; 0x3fa6 <getch> + + if(ch == STK_GET_PARAMETER) { + 3e62: 81 34 cpi r24, 0x41 ; 65 + 3e64: 61 f4 brne .+24 ; 0x3e7e <main+0x7e> + unsigned char which = getch(); + 3e66: 9f d0 rcall .+318 ; 0x3fa6 <getch> + 3e68: 08 2f mov r16, r24 + verifySpace(); + 3e6a: af d0 rcall .+350 ; 0x3fca <verifySpace> + if (which == 0x82) { + 3e6c: 02 38 cpi r16, 0x82 ; 130 + 3e6e: 11 f0 breq .+4 ; 0x3e74 <main+0x74> + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 3e70: 01 38 cpi r16, 0x81 ; 129 + 3e72: 11 f4 brne .+4 ; 0x3e78 <main+0x78> + putch(OPTIBOOT_MAJVER); + 3e74: 84 e0 ldi r24, 0x04 ; 4 + 3e76: 01 c0 rjmp .+2 ; 0x3e7a <main+0x7a> + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 3e78: 83 e0 ldi r24, 0x03 ; 3 + 3e7a: 8d d0 rcall .+282 ; 0x3f96 <putch> + 3e7c: 89 c0 rjmp .+274 ; 0x3f90 <main+0x190> + } + } + else if(ch == STK_SET_DEVICE) { + 3e7e: 82 34 cpi r24, 0x42 ; 66 + 3e80: 11 f4 brne .+4 ; 0x3e86 <main+0x86> + // SET DEVICE is ignored + getNch(20); + 3e82: 84 e1 ldi r24, 0x14 ; 20 + 3e84: 03 c0 rjmp .+6 ; 0x3e8c <main+0x8c> + } + else if(ch == STK_SET_DEVICE_EXT) { + 3e86: 85 34 cpi r24, 0x45 ; 69 + 3e88: 19 f4 brne .+6 ; 0x3e90 <main+0x90> + // SET DEVICE EXT is ignored + getNch(5); + 3e8a: 85 e0 ldi r24, 0x05 ; 5 + 3e8c: a6 d0 rcall .+332 ; 0x3fda <getNch> + 3e8e: 80 c0 rjmp .+256 ; 0x3f90 <main+0x190> + } + else if(ch == STK_LOAD_ADDRESS) { + 3e90: 85 35 cpi r24, 0x55 ; 85 + 3e92: 79 f4 brne .+30 ; 0x3eb2 <main+0xb2> + // LOAD ADDRESS + uint16_t newAddress; + newAddress = getch(); + 3e94: 88 d0 rcall .+272 ; 0x3fa6 <getch> + newAddress = (newAddress & 0xff) | (getch() << 8); + 3e96: e8 2e mov r14, r24 + 3e98: ff 24 eor r15, r15 + 3e9a: 85 d0 rcall .+266 ; 0x3fa6 <getch> + 3e9c: 08 2f mov r16, r24 + 3e9e: 10 e0 ldi r17, 0x00 ; 0 + 3ea0: 10 2f mov r17, r16 + 3ea2: 00 27 eor r16, r16 + 3ea4: 0e 29 or r16, r14 + 3ea6: 1f 29 or r17, r15 +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; +#endif + newAddress += newAddress; // Convert from word address to byte address + 3ea8: 00 0f add r16, r16 + 3eaa: 11 1f adc r17, r17 + address = newAddress; + verifySpace(); + 3eac: 8e d0 rcall .+284 ; 0x3fca <verifySpace> + 3eae: 68 01 movw r12, r16 + 3eb0: 6f c0 rjmp .+222 ; 0x3f90 <main+0x190> + } + else if(ch == STK_UNIVERSAL) { + 3eb2: 86 35 cpi r24, 0x56 ; 86 + 3eb4: 21 f4 brne .+8 ; 0x3ebe <main+0xbe> + // UNIVERSAL command is ignored + getNch(4); + 3eb6: 84 e0 ldi r24, 0x04 ; 4 + 3eb8: 90 d0 rcall .+288 ; 0x3fda <getNch> + putch(0x00); + 3eba: 80 e0 ldi r24, 0x00 ; 0 + 3ebc: de cf rjmp .-68 ; 0x3e7a <main+0x7a> + } + /* Write memory, length is big endian and is in bytes */ + else if(ch == STK_PROG_PAGE) { + 3ebe: 84 36 cpi r24, 0x64 ; 100 + 3ec0: 09 f0 breq .+2 ; 0x3ec4 <main+0xc4> + 3ec2: 40 c0 rjmp .+128 ; 0x3f44 <main+0x144> + // PROGRAM PAGE - we support flash programming only, not EEPROM + uint8_t *bufPtr; + uint16_t addrPtr; + + getch(); /* getlen() */ + 3ec4: 70 d0 rcall .+224 ; 0x3fa6 <getch> + length = getch(); + 3ec6: 6f d0 rcall .+222 ; 0x3fa6 <getch> + 3ec8: 08 2f mov r16, r24 + getch(); + 3eca: 6d d0 rcall .+218 ; 0x3fa6 <getch> + + // If we are in RWW section, immediately start page erase + if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 3ecc: 80 e0 ldi r24, 0x00 ; 0 + 3ece: c8 16 cp r12, r24 + 3ed0: 88 e3 ldi r24, 0x38 ; 56 + 3ed2: d8 06 cpc r13, r24 + 3ed4: 18 f4 brcc .+6 ; 0x3edc <main+0xdc> + 3ed6: f6 01 movw r30, r12 + 3ed8: b7 be out 0x37, r11 ; 55 + 3eda: e8 95 spm + 3edc: c0 e0 ldi r28, 0x00 ; 0 + 3ede: d1 e0 ldi r29, 0x01 ; 1 + + // While that is going on, read in page contents + bufPtr = buff; + do *bufPtr++ = getch(); + 3ee0: 62 d0 rcall .+196 ; 0x3fa6 <getch> + 3ee2: 89 93 st Y+, r24 + while (--length); + 3ee4: 0c 17 cp r16, r28 + 3ee6: e1 f7 brne .-8 ; 0x3ee0 <main+0xe0> + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 3ee8: f0 e0 ldi r31, 0x00 ; 0 + 3eea: cf 16 cp r12, r31 + 3eec: f8 e3 ldi r31, 0x38 ; 56 + 3eee: df 06 cpc r13, r31 + 3ef0: 18 f0 brcs .+6 ; 0x3ef8 <main+0xf8> + 3ef2: f6 01 movw r30, r12 + 3ef4: b7 be out 0x37, r11 ; 55 + 3ef6: e8 95 spm + + // Read command terminator, start reply + verifySpace(); + 3ef8: 68 d0 rcall .+208 ; 0x3fca <verifySpace> + + // If only a partial page is to be programmed, the erase might not be complete. + // So check that here + boot_spm_busy_wait(); + 3efa: 07 b6 in r0, 0x37 ; 55 + 3efc: 00 fc sbrc r0, 0 + 3efe: fd cf rjmp .-6 ; 0x3efa <main+0xfa> + 3f00: a6 01 movw r20, r12 + 3f02: a0 e0 ldi r26, 0x00 ; 0 + 3f04: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + 3f06: 2c 91 ld r18, X + 3f08: 30 e0 ldi r19, 0x00 ; 0 + a |= (*bufPtr++) << 8; + 3f0a: 11 96 adiw r26, 0x01 ; 1 + 3f0c: 8c 91 ld r24, X + 3f0e: 11 97 sbiw r26, 0x01 ; 1 + 3f10: 90 e0 ldi r25, 0x00 ; 0 + 3f12: 98 2f mov r25, r24 + 3f14: 88 27 eor r24, r24 + 3f16: 82 2b or r24, r18 + 3f18: 93 2b or r25, r19 +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 3f1a: 12 96 adiw r26, 0x02 ; 2 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 3f1c: fa 01 movw r30, r20 + 3f1e: 0c 01 movw r0, r24 + 3f20: 87 be out 0x37, r8 ; 55 + 3f22: e8 95 spm + 3f24: 11 24 eor r1, r1 + addrPtr += 2; + 3f26: 4e 5f subi r20, 0xFE ; 254 + 3f28: 5f 4f sbci r21, 0xFF ; 255 + } while (--ch); + 3f2a: f1 e0 ldi r31, 0x01 ; 1 + 3f2c: a0 38 cpi r26, 0x80 ; 128 + 3f2e: bf 07 cpc r27, r31 + 3f30: 51 f7 brne .-44 ; 0x3f06 <main+0x106> + + // Write from programming buffer + __boot_page_write_short((uint16_t)(void*)address); + 3f32: f6 01 movw r30, r12 + 3f34: a7 be out 0x37, r10 ; 55 + 3f36: e8 95 spm + boot_spm_busy_wait(); + 3f38: 07 b6 in r0, 0x37 ; 55 + 3f3a: 00 fc sbrc r0, 0 + 3f3c: fd cf rjmp .-6 ; 0x3f38 <main+0x138> + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 3f3e: 97 be out 0x37, r9 ; 55 + 3f40: e8 95 spm + 3f42: 26 c0 rjmp .+76 ; 0x3f90 <main+0x190> +#endif + + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) { + 3f44: 84 37 cpi r24, 0x74 ; 116 + 3f46: b1 f4 brne .+44 ; 0x3f74 <main+0x174> + // READ PAGE - we only read flash + getch(); /* getlen() */ + 3f48: 2e d0 rcall .+92 ; 0x3fa6 <getch> + length = getch(); + 3f4a: 2d d0 rcall .+90 ; 0x3fa6 <getch> + 3f4c: f8 2e mov r15, r24 + getch(); + 3f4e: 2b d0 rcall .+86 ; 0x3fa6 <getch> + + verifySpace(); + 3f50: 3c d0 rcall .+120 ; 0x3fca <verifySpace> + 3f52: f6 01 movw r30, r12 + 3f54: ef 2c mov r14, r15 + putch(result); + address++; + } + while (--length); +#else + do putch(pgm_read_byte_near(address++)); + 3f56: 8f 01 movw r16, r30 + 3f58: 0f 5f subi r16, 0xFF ; 255 + 3f5a: 1f 4f sbci r17, 0xFF ; 255 + 3f5c: 84 91 lpm r24, Z+ + 3f5e: 1b d0 rcall .+54 ; 0x3f96 <putch> + while (--length); + 3f60: ea 94 dec r14 + 3f62: f8 01 movw r30, r16 + 3f64: c1 f7 brne .-16 ; 0x3f56 <main+0x156> +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 3f66: 08 94 sec + 3f68: c1 1c adc r12, r1 + 3f6a: d1 1c adc r13, r1 + 3f6c: fa 94 dec r15 + 3f6e: cf 0c add r12, r15 + 3f70: d1 1c adc r13, r1 + 3f72: 0e c0 rjmp .+28 ; 0x3f90 <main+0x190> +#endif +#endif + } + + /* Get device signature bytes */ + else if(ch == STK_READ_SIGN) { + 3f74: 85 37 cpi r24, 0x75 ; 117 + 3f76: 39 f4 brne .+14 ; 0x3f86 <main+0x186> + // READ SIGN - return what Avrdude wants to hear + verifySpace(); + 3f78: 28 d0 rcall .+80 ; 0x3fca <verifySpace> + putch(SIGNATURE_0); + 3f7a: 8e e1 ldi r24, 0x1E ; 30 + 3f7c: 0c d0 rcall .+24 ; 0x3f96 <putch> + putch(SIGNATURE_1); + 3f7e: 84 e9 ldi r24, 0x94 ; 148 + 3f80: 0a d0 rcall .+20 ; 0x3f96 <putch> + putch(SIGNATURE_2); + 3f82: 86 e0 ldi r24, 0x06 ; 6 + 3f84: 7a cf rjmp .-268 ; 0x3e7a <main+0x7a> + } + else if (ch == 'Q') { + 3f86: 81 35 cpi r24, 0x51 ; 81 + 3f88: 11 f4 brne .+4 ; 0x3f8e <main+0x18e> + // Adaboot no-wait mod + watchdogConfig(WATCHDOG_16MS); + 3f8a: 88 e0 ldi r24, 0x08 ; 8 + 3f8c: 18 d0 rcall .+48 ; 0x3fbe <watchdogConfig> + verifySpace(); + } + else { + // This covers the response to commands like STK_ENTER_PROGMODE + verifySpace(); + 3f8e: 1d d0 rcall .+58 ; 0x3fca <verifySpace> + } + putch(STK_OK); + 3f90: 80 e1 ldi r24, 0x10 ; 16 + 3f92: 01 d0 rcall .+2 ; 0x3f96 <putch> + 3f94: 65 cf rjmp .-310 ; 0x3e60 <main+0x60> + +00003f96 <putch>: + } +} + +void putch(char ch) { + 3f96: 98 2f mov r25, r24 +#ifndef SOFT_UART + while (!(UCSR0A & _BV(UDRE0))); + 3f98: 80 91 c0 00 lds r24, 0x00C0 + 3f9c: 85 ff sbrs r24, 5 + 3f9e: fc cf rjmp .-8 ; 0x3f98 <putch+0x2> + UDR0 = ch; + 3fa0: 90 93 c6 00 sts 0x00C6, r25 + [uartBit] "I" (UART_TX_BIT) + : + "r25" + ); +#endif +} + 3fa4: 08 95 ret + +00003fa6 <getch>: + [uartBit] "I" (UART_RX_BIT) + : + "r25" +); +#else + while(!(UCSR0A & _BV(RXC0))) + 3fa6: 80 91 c0 00 lds r24, 0x00C0 + 3faa: 87 ff sbrs r24, 7 + 3fac: fc cf rjmp .-8 ; 0x3fa6 <getch> + ; + if (!(UCSR0A & _BV(FE0))) { + 3fae: 80 91 c0 00 lds r24, 0x00C0 + 3fb2: 84 fd sbrc r24, 4 + 3fb4: 01 c0 rjmp .+2 ; 0x3fb8 <getch+0x12> +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 3fb6: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + + ch = UDR0; + 3fb8: 80 91 c6 00 lds r24, 0x00C6 + LED_PIN |= _BV(LED); +#endif +#endif + + return ch; +} + 3fbc: 08 95 ret + +00003fbe <watchdogConfig>: + "wdr\n" + ); +} + +void watchdogConfig(uint8_t x) { + WDTCSR = _BV(WDCE) | _BV(WDE); + 3fbe: e0 e6 ldi r30, 0x60 ; 96 + 3fc0: f0 e0 ldi r31, 0x00 ; 0 + 3fc2: 98 e1 ldi r25, 0x18 ; 24 + 3fc4: 90 83 st Z, r25 + WDTCSR = x; + 3fc6: 80 83 st Z, r24 +} + 3fc8: 08 95 ret + +00003fca <verifySpace>: + do getch(); while (--count); + verifySpace(); +} + +void verifySpace() { + if (getch() != CRC_EOP) { + 3fca: ed df rcall .-38 ; 0x3fa6 <getch> + 3fcc: 80 32 cpi r24, 0x20 ; 32 + 3fce: 19 f0 breq .+6 ; 0x3fd6 <verifySpace+0xc> + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 3fd0: 88 e0 ldi r24, 0x08 ; 8 + 3fd2: f5 df rcall .-22 ; 0x3fbe <watchdogConfig> + 3fd4: ff cf rjmp .-2 ; 0x3fd4 <verifySpace+0xa> + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } + putch(STK_INSYNC); + 3fd6: 84 e1 ldi r24, 0x14 ; 20 +} + 3fd8: de cf rjmp .-68 ; 0x3f96 <putch> + +00003fda <getNch>: + ::[count] "M" (UART_B_VALUE) + ); +} +#endif + +void getNch(uint8_t count) { + 3fda: 1f 93 push r17 + 3fdc: 18 2f mov r17, r24 + do getch(); while (--count); + 3fde: e3 df rcall .-58 ; 0x3fa6 <getch> + 3fe0: 11 50 subi r17, 0x01 ; 1 + 3fe2: e9 f7 brne .-6 ; 0x3fde <getNch+0x4> + verifySpace(); + 3fe4: f2 df rcall .-28 ; 0x3fca <verifySpace> +} + 3fe6: 1f 91 pop r17 + 3fe8: 08 95 ret + +00003fea <appStart>: + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 3fea: 80 e0 ldi r24, 0x00 ; 0 + 3fec: e8 df rcall .-48 ; 0x3fbe <watchdogConfig> + __asm__ __volatile__ ( + 3fee: ee 27 eor r30, r30 + 3ff0: ff 27 eor r31, r31 + 3ff2: 09 94 ijmp diff --git a/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex b/bootloaders/optiboot/optiboot_atmega328-Mini.hex index d6ac145..02266ee 100644 --- a/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex +++ b/bootloaders/optiboot/optiboot_atmega328-Mini.hex @@ -1,33 +1,33 @@ -:107E000085E08093810082E08093C00088E18093C8
-:107E1000C10086E08093C20088E08093C40084B7EC
-:107E200014BE81FFD0D08DE0C8D0259A86E028E12D
-:107E30003EEF91E0309385002093840096BBB09B89
-:107E4000FECF1D9AA8958150A9F7DD24D394A5E013
-:107E5000EA2EF1E1FF2EA4D0813421F481E0BED0DE
-:107E600083E024C0823411F484E103C0853419F422
-:107E700085E0B4D08AC08535A1F492D0082F10E0F7
-:107E800010930102009300028BD090E0982F882776
-:107E9000802B912B880F991F9093010280930002F1
-:107EA00073C0863529F484E099D080E071D06DC02C
-:107EB000843609F043C07CD0E0910002F0910102C9
-:107EC00083E080935700E895C0E0D1E069D08993C2
-:107ED000809102028150809302028823B9F778D002
-:107EE00007B600FCFDCF4091000250910102A0E0D6
-:107EF000B1E02C9130E011968C91119790E0982F81
-:107F00008827822B932B1296FA010C01D0925700EE
-:107F1000E89511244E5F5F4FF1E0A038BF0749F7A5
-:107F2000E0910002F0910102E0925700E89507B657
-:107F300000FCFDCFF0925700E89527C08437B9F4D4
-:107F400037D046D0E0910002F09101023196F093D3
-:107F50000102E09300023197E4918E2F19D08091B5
-:107F60000202815080930202882361F70EC0853798
-:107F700039F42ED08EE10CD085E90AD08FE096CF6F
-:107F8000813511F488E019D023D080E101D063CF8E
-:107F9000982F8091C00085FFFCCF9093C600089574
-:107FA000A8958091C00087FFFCCF8091C6000895FE
-:107FB000F7DFF6DF80930202F3CFE0E6F0E098E12E
-:107FC00090838083089580E0F8DFEE27FF270994EF
-:107FD000E7DF803209F0F7DF84E1DACF1F93182F53
-:0C7FE000DFDF1150E9F7F4DF1F91089576
-:0400000300007E007B
-:00000001FF
+:107E000085E08093810082E08093C00088E18093C8 +:107E1000C10086E08093C20080E18093C40084B7F3 +:107E200014BE81FFD0D089E2C8D0259A86E020E335 +:107E30003CEF91E0309385002093840096BBB09B8B +:107E4000FECF1D9AA8958150A9F7DD24D394A5E013 +:107E5000EA2EF1E1FF2EA4D0813421F481E0BED0DE +:107E600083E024C0823411F484E103C0853419F422 +:107E700085E0B4D08AC08535A1F492D0082F10E0F7 +:107E800010930102009300028BD090E0982F882776 +:107E9000802B912B880F991F9093010280930002F1 +:107EA00073C0863529F484E099D080E071D06DC02C +:107EB000843609F043C07CD0E0910002F0910102C9 +:107EC00083E080935700E895C0E0D1E069D08993C2 +:107ED000809102028150809302028823B9F778D002 +:107EE00007B600FCFDCF4091000250910102A0E0D6 +:107EF000B1E02C9130E011968C91119790E0982F81 +:107F00008827822B932B1296FA010C01D0925700EE +:107F1000E89511244E5F5F4FF1E0A038BF0749F7A5 +:107F2000E0910002F0910102E0925700E89507B657 +:107F300000FCFDCFF0925700E89527C08437B9F4D4 +:107F400037D046D0E0910002F09101023196F093D3 +:107F50000102E09300023197E4918E2F19D08091B5 +:107F60000202815080930202882361F70EC0853798 +:107F700039F42ED08EE10CD085E90AD08FE096CF6F +:107F8000813511F488E019D023D080E101D063CF8E +:107F9000982F8091C00085FFFCCF9093C600089574 +:107FA000A8958091C00087FFFCCF8091C6000895FE +:107FB000F7DFF6DF80930202F3CFE0E6F0E098E12E +:107FC00090838083089580E0F8DFEE27FF270994EF +:107FD000E7DF803209F0F7DF84E1DACF1F93182F53 +:0C7FE000DFDF1150E9F7F4DF1F91089576 +:0400000300007E007B +:00000001FF diff --git a/bootloaders/optiboot/optiboot_atmega328.hex b/bootloaders/optiboot/optiboot_atmega328.hex index e8aa31c..a219f08 100644 --- a/bootloaders/optiboot/optiboot_atmega328.hex +++ b/bootloaders/optiboot/optiboot_atmega328.hex @@ -1,33 +1,35 @@ -:107E0000112485E08093810082E08093C00088E1A6
-:107E10008093C10086E08093C20080E18093C4001B
-:107E200084B714BE81FFD0D08DE0C8D0259A86E0FB
+:107E0000112484B714BE81FFF0D085E080938100F7
+:107E100082E08093C00088E18093C10086E0809377
+:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
-:107E4000B09BFECF1D9AA8958150A9F7DD24D3944D
-:107E5000A5E0EA2EF1E1FF2EA4D0813421F481E0E7
-:107E6000BED083E024C0823411F484E103C08534A1
-:107E700019F485E0B4D08AC08535A1F492D0082FDA
-:107E800010E010930102009300028BD090E0982F35
-:107E90008827802B912B880F991F90930102809344
-:107EA000000273C0863529F484E099D080E071D057
-:107EB0006DC0843609F043C07CD0E0910002F0919F
-:107EC000010283E080935700E895C0E0D1E069D0DB
-:107ED0008993809102028150809302028823B9F72E
-:107EE00078D007B600FCFDCF40910002509101020E
-:107EF000A0E0B1E02C9130E011968C91119790E0C8
-:107F0000982F8827822B932B1296FA010C01D0927E
-:107F10005700E89511244E5F5F4FF1E0A038BF078E
-:107F200049F7E0910002F0910102E0925700E895D4
-:107F300007B600FCFDCFF0925700E89527C08437C4
-:107F4000B9F437D046D0E0910002F09101023196A9
-:107F5000F0930102E09300023197E4918E2F19D043
-:107F600080910202815080930202882361F70EC043
-:107F7000853739F42ED08EE10CD085E90AD08FE018
-:107F800096CF813511F488E019D023D080E101D05B
-:107F900063CF982F8091C00085FFFCCF9093C600DF
-:107FA0000895A8958091C00087FFFCCF8091C600FE
-:107FB0000895F7DFF6DF80930202F3CFE0E6F0E00A
-:107FC00098E190838083089580E0F8DFEE27FF2713
-:107FD0000994E7DF803209F0F7DF84E1DACF1F93FD
-:0E7FE000182FDFDF1150E9F7F4DF1F9108952D
+:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
+:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
+:107E6000A2D0813461F49FD0082FAFD0023811F036
+:107E7000013811F484E001C083E08DD089C08234E0
+:107E800011F484E103C0853419F485E0A6D080C0E4
+:107E9000853579F488D0E82EFF2485D0082F10E0AE
+:107EA000102F00270E291F29000F111F8ED06801E7
+:107EB0006FC0863521F484E090D080E0DECF843638
+:107EC00009F040C070D06FD0082F6DD080E0C81688
+:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
+:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
+:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
+:107F0000A601A0E0B1E02C9130E011968C91119780
+:107F100090E0982F8827822B932B1296FA010C0160
+:107F200087BEE89511244E5F5F4FF1E0A038BF0790
+:107F300051F7F601A7BEE89507B600FCFDCF97BE46
+:107F4000E89526C08437B1F42ED02DD0F82E2BD052
+:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
+:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
+:107F7000D11C0EC0853739F428D08EE10CD085E9AC
+:107F80000AD08FE07ACF813511F488E018D01DD067
+:107F900080E101D065CF982F8091C00085FFFCCF94
+:107FA0009093C60008958091C00087FFFCCF809118
+:107FB000C00084FD01C0A8958091C6000895E0E648
+:107FC000F0E098E1908380830895EDDF803219F02E
+:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
+:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
+:047FF000FF270994CA
+:027FFE00040479
:0400000300007E007B
:00000001FF
diff --git a/bootloaders/optiboot/optiboot_atmega328.lst b/bootloaders/optiboot/optiboot_atmega328.lst index dd879dc..d9dd4cc 100644 --- a/bootloaders/optiboot/optiboot_atmega328.lst +++ b/bootloaders/optiboot/optiboot_atmega328.lst @@ -3,74 +3,81 @@ optiboot_atmega328.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn - 0 .text 000001ee 00007e00 00007e00 00000054 2**1 + 0 .text 000001f4 00007e00 00007e00 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000242 2**0 + 1 .version 00000002 00007ffe 00007ffe 00000248 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 0000024a 2**0 CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 0000026a 2**0 + 3 .debug_pubnames 0000005f 00000000 00000000 00000272 2**0 CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000269 00000000 00000000 000002d4 2**0 + 4 .debug_info 000002a8 00000000 00000000 000002d1 2**0 CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000196 00000000 00000000 0000053d 2**0 + 5 .debug_abbrev 00000178 00000000 00000000 00000579 2**0 CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003db 00000000 00000000 000006d3 2**0 + 6 .debug_line 00000488 00000000 00000000 000006f1 2**0 CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000ab0 2**2 + 7 .debug_frame 00000080 00000000 00000000 00000b7c 2**2 CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000124 00000000 00000000 00000b40 2**0 + 8 .debug_str 0000014f 00000000 00000000 00000bfc 2**0 CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001d1 00000000 00000000 00000c64 2**0 + 9 .debug_loc 000002d8 00000000 00000000 00000d4b 2**0 CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e35 2**0 + 10 .debug_ranges 00000078 00000000 00000000 00001023 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: 00007e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #endif + /* main program starts here */ int main(void) { 7e00: 11 24 eor r1, r1 +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset +#endif - uint8_t ch; + // Adaboot no-wait mod + ch = MCUSR; + 7e02: 84 b7 in r24, 0x34 ; 52 + MCUSR = 0; + 7e04: 14 be out 0x34, r1 ; 52 + if (!(ch & _BV(EXTRF))) appStart(); + 7e06: 81 ff sbrs r24, 1 + 7e08: f0 d0 rcall .+480 ; 0x7fea <appStart> #if LED_START_FLASHES > 0 // Set up Timer 1 for timeout counter TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 - 7e02: 85 e0 ldi r24, 0x05 ; 5 - 7e04: 80 93 81 00 sts 0x0081, r24 -#endif -#ifndef SOFT_UART + 7e0a: 85 e0 ldi r24, 0x05 ; 5 + 7e0c: 80 93 81 00 sts 0x0081, r24 + UCSRA = _BV(U2X); //Double speed mode USART + UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 + UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#else UCSR0A = _BV(U2X0); //Double speed mode USART0 - 7e08: 82 e0 ldi r24, 0x02 ; 2 - 7e0a: 80 93 c0 00 sts 0x00C0, r24 + 7e10: 82 e0 ldi r24, 0x02 ; 2 + 7e12: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 7e0e: 88 e1 ldi r24, 0x18 ; 24 - 7e10: 80 93 c1 00 sts 0x00C1, r24 + 7e16: 88 e1 ldi r24, 0x18 ; 24 + 7e18: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 7e14: 86 e0 ldi r24, 0x06 ; 6 - 7e16: 80 93 c2 00 sts 0x00C2, r24 + 7e1c: 86 e0 ldi r24, 0x06 ; 6 + 7e1e: 80 93 c2 00 sts 0x00C2, r24 UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 7e1a: 80 e1 ldi r24, 0x10 ; 16 - 7e1c: 80 93 c4 00 sts 0x00C4, r24 + 7e22: 80 e1 ldi r24, 0x10 ; 16 + 7e24: 80 93 c4 00 sts 0x00C4, r24 +#endif #endif - - // Adaboot no-wait mod - ch = MCUSR; - 7e20: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 7e22: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 7e24: 81 ff sbrs r24, 1 - 7e26: d0 d0 rcall .+416 ; 0x7fc8 <appStart> // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 7e28: 8d e0 ldi r24, 0x0D ; 13 - 7e2a: c8 d0 rcall .+400 ; 0x7fbc <watchdogConfig> + watchdogConfig(WATCHDOG_1S); + 7e28: 8e e0 ldi r24, 0x0E ; 14 + 7e2a: c9 d0 rcall .+402 ; 0x7fbe <watchdogConfig> /* Set LED pin as output */ LED_DDR |= _BV(LED); @@ -99,426 +106,493 @@ void flash_led(uint8_t count) { while(!(TIFR1 & _BV(TOV1))); 7e40: b0 9b sbis 0x16, 0 ; 22 7e42: fe cf rjmp .-4 ; 0x7e40 <main+0x40> +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); 7e44: 1d 9a sbi 0x03, 5 ; 3 - return getch(); } +#endif // Watchdog functions. These are only safe with interrupts turned off. void watchdogReset() { __asm__ __volatile__ ( 7e46: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); + LED_PORT ^= _BV(LED); +#else LED_PIN |= _BV(LED); +#endif watchdogReset(); } while (--count); 7e48: 81 50 subi r24, 0x01 ; 1 7e4a: a9 f7 brne .-22 ; 0x7e36 <main+0x36> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e4c: dd 24 eor r13, r13 - 7e4e: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); + 7e4c: cc 24 eor r12, r12 + 7e4e: dd 24 eor r13, r13 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 7e50: 88 24 eor r8, r8 + 7e52: 83 94 inc r8 addrPtr += 2; } while (--ch); - + // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 7e50: a5 e0 ldi r26, 0x05 ; 5 - 7e52: ea 2e mov r14, r26 + __boot_page_write_short((uint16_t)(void*)address); + 7e54: b5 e0 ldi r27, 0x05 ; 5 + 7e56: ab 2e mov r10, r27 boot_spm_busy_wait(); #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7e54: f1 e1 ldi r31, 0x11 ; 17 - 7e56: ff 2e mov r15, r31 + 7e58: a1 e1 ldi r26, 0x11 ; 17 + 7e5a: 9a 2e mov r9, r26 + do *bufPtr++ = getch(); + while (--length); + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 7e5c: f3 e0 ldi r31, 0x03 ; 3 + 7e5e: bf 2e mov r11, r31 #endif /* Forever loop */ for (;;) { /* get character from UART */ ch = getch(); - 7e58: a4 d0 rcall .+328 ; 0x7fa2 <getch> + 7e60: a2 d0 rcall .+324 ; 0x7fa6 <getch> if(ch == STK_GET_PARAMETER) { - 7e5a: 81 34 cpi r24, 0x41 ; 65 - 7e5c: 21 f4 brne .+8 ; 0x7e66 <main+0x66> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e5e: 81 e0 ldi r24, 0x01 ; 1 - 7e60: be d0 rcall .+380 ; 0x7fde <verifySpace+0xc> - putch(0x03); - 7e62: 83 e0 ldi r24, 0x03 ; 3 - 7e64: 24 c0 rjmp .+72 ; 0x7eae <main+0xae> + 7e62: 81 34 cpi r24, 0x41 ; 65 + 7e64: 61 f4 brne .+24 ; 0x7e7e <main+0x7e> + unsigned char which = getch(); + 7e66: 9f d0 rcall .+318 ; 0x7fa6 <getch> + 7e68: 08 2f mov r16, r24 + verifySpace(); + 7e6a: af d0 rcall .+350 ; 0x7fca <verifySpace> + if (which == 0x82) { + 7e6c: 02 38 cpi r16, 0x82 ; 130 + 7e6e: 11 f0 breq .+4 ; 0x7e74 <main+0x74> + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 7e70: 01 38 cpi r16, 0x81 ; 129 + 7e72: 11 f4 brne .+4 ; 0x7e78 <main+0x78> + putch(OPTIBOOT_MAJVER); + 7e74: 84 e0 ldi r24, 0x04 ; 4 + 7e76: 01 c0 rjmp .+2 ; 0x7e7a <main+0x7a> + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 7e78: 83 e0 ldi r24, 0x03 ; 3 + 7e7a: 8d d0 rcall .+282 ; 0x7f96 <putch> + 7e7c: 89 c0 rjmp .+274 ; 0x7f90 <main+0x190> + } } else if(ch == STK_SET_DEVICE) { - 7e66: 82 34 cpi r24, 0x42 ; 66 - 7e68: 11 f4 brne .+4 ; 0x7e6e <main+0x6e> + 7e7e: 82 34 cpi r24, 0x42 ; 66 + 7e80: 11 f4 brne .+4 ; 0x7e86 <main+0x86> // SET DEVICE is ignored getNch(20); - 7e6a: 84 e1 ldi r24, 0x14 ; 20 - 7e6c: 03 c0 rjmp .+6 ; 0x7e74 <main+0x74> + 7e82: 84 e1 ldi r24, 0x14 ; 20 + 7e84: 03 c0 rjmp .+6 ; 0x7e8c <main+0x8c> } else if(ch == STK_SET_DEVICE_EXT) { - 7e6e: 85 34 cpi r24, 0x45 ; 69 - 7e70: 19 f4 brne .+6 ; 0x7e78 <main+0x78> + 7e86: 85 34 cpi r24, 0x45 ; 69 + 7e88: 19 f4 brne .+6 ; 0x7e90 <main+0x90> // SET DEVICE EXT is ignored getNch(5); - 7e72: 85 e0 ldi r24, 0x05 ; 5 - 7e74: b4 d0 rcall .+360 ; 0x7fde <verifySpace+0xc> - 7e76: 8a c0 rjmp .+276 ; 0x7f8c <main+0x18c> + 7e8a: 85 e0 ldi r24, 0x05 ; 5 + 7e8c: a6 d0 rcall .+332 ; 0x7fda <getNch> + 7e8e: 80 c0 rjmp .+256 ; 0x7f90 <main+0x190> } else if(ch == STK_LOAD_ADDRESS) { - 7e78: 85 35 cpi r24, 0x55 ; 85 - 7e7a: a1 f4 brne .+40 ; 0x7ea4 <main+0xa4> + 7e90: 85 35 cpi r24, 0x55 ; 85 + 7e92: 79 f4 brne .+30 ; 0x7eb2 <main+0xb2> // LOAD ADDRESS - address = getch(); - 7e7c: 92 d0 rcall .+292 ; 0x7fa2 <getch> - 7e7e: 08 2f mov r16, r24 - 7e80: 10 e0 ldi r17, 0x00 ; 0 - 7e82: 10 93 01 02 sts 0x0201, r17 - 7e86: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 7e8a: 8b d0 rcall .+278 ; 0x7fa2 <getch> - 7e8c: 90 e0 ldi r25, 0x00 ; 0 - 7e8e: 98 2f mov r25, r24 - 7e90: 88 27 eor r24, r24 - 7e92: 80 2b or r24, r16 - 7e94: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 7e96: 88 0f add r24, r24 - 7e98: 99 1f adc r25, r25 - 7e9a: 90 93 01 02 sts 0x0201, r25 - 7e9e: 80 93 00 02 sts 0x0200, r24 - 7ea2: 73 c0 rjmp .+230 ; 0x7f8a <main+0x18a> + uint16_t newAddress; + newAddress = getch(); + 7e94: 88 d0 rcall .+272 ; 0x7fa6 <getch> + newAddress = (newAddress & 0xff) | (getch() << 8); + 7e96: e8 2e mov r14, r24 + 7e98: ff 24 eor r15, r15 + 7e9a: 85 d0 rcall .+266 ; 0x7fa6 <getch> + 7e9c: 08 2f mov r16, r24 + 7e9e: 10 e0 ldi r17, 0x00 ; 0 + 7ea0: 10 2f mov r17, r16 + 7ea2: 00 27 eor r16, r16 + 7ea4: 0e 29 or r16, r14 + 7ea6: 1f 29 or r17, r15 +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; +#endif + newAddress += newAddress; // Convert from word address to byte address + 7ea8: 00 0f add r16, r16 + 7eaa: 11 1f adc r17, r17 + address = newAddress; verifySpace(); + 7eac: 8e d0 rcall .+284 ; 0x7fca <verifySpace> + 7eae: 68 01 movw r12, r16 + 7eb0: 6f c0 rjmp .+222 ; 0x7f90 <main+0x190> } else if(ch == STK_UNIVERSAL) { - 7ea4: 86 35 cpi r24, 0x56 ; 86 - 7ea6: 29 f4 brne .+10 ; 0x7eb2 <main+0xb2> + 7eb2: 86 35 cpi r24, 0x56 ; 86 + 7eb4: 21 f4 brne .+8 ; 0x7ebe <main+0xbe> // UNIVERSAL command is ignored getNch(4); - 7ea8: 84 e0 ldi r24, 0x04 ; 4 - 7eaa: 99 d0 rcall .+306 ; 0x7fde <verifySpace+0xc> + 7eb6: 84 e0 ldi r24, 0x04 ; 4 + 7eb8: 90 d0 rcall .+288 ; 0x7fda <getNch> putch(0x00); - 7eac: 80 e0 ldi r24, 0x00 ; 0 - 7eae: 71 d0 rcall .+226 ; 0x7f92 <putch> - 7eb0: 6d c0 rjmp .+218 ; 0x7f8c <main+0x18c> + 7eba: 80 e0 ldi r24, 0x00 ; 0 + 7ebc: de cf rjmp .-68 ; 0x7e7a <main+0x7a> } - /* Write memory, length is big endian and is in bytes */ + /* Write memory, length is big endian and is in bytes */ else if(ch == STK_PROG_PAGE) { - 7eb2: 84 36 cpi r24, 0x64 ; 100 - 7eb4: 09 f0 breq .+2 ; 0x7eb8 <main+0xb8> - 7eb6: 43 c0 rjmp .+134 ; 0x7f3e <main+0x13e> + 7ebe: 84 36 cpi r24, 0x64 ; 100 + 7ec0: 09 f0 breq .+2 ; 0x7ec4 <main+0xc4> + 7ec2: 40 c0 rjmp .+128 ; 0x7f44 <main+0x144> // PROGRAM PAGE - we support flash programming only, not EEPROM uint8_t *bufPtr; uint16_t addrPtr; - getLen(); - 7eb8: 7c d0 rcall .+248 ; 0x7fb2 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 7eba: e0 91 00 02 lds r30, 0x0200 - 7ebe: f0 91 01 02 lds r31, 0x0201 - 7ec2: 83 e0 ldi r24, 0x03 ; 3 - 7ec4: 80 93 57 00 sts 0x0057, r24 - 7ec8: e8 95 spm - 7eca: c0 e0 ldi r28, 0x00 ; 0 - 7ecc: d1 e0 ldi r29, 0x01 ; 1 + getch(); /* getlen() */ + 7ec4: 70 d0 rcall .+224 ; 0x7fa6 <getch> + length = getch(); + 7ec6: 6f d0 rcall .+222 ; 0x7fa6 <getch> + 7ec8: 08 2f mov r16, r24 + getch(); + 7eca: 6d d0 rcall .+218 ; 0x7fa6 <getch> + + // If we are in RWW section, immediately start page erase + if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 7ecc: 80 e0 ldi r24, 0x00 ; 0 + 7ece: c8 16 cp r12, r24 + 7ed0: 80 e7 ldi r24, 0x70 ; 112 + 7ed2: d8 06 cpc r13, r24 + 7ed4: 18 f4 brcc .+6 ; 0x7edc <main+0xdc> + 7ed6: f6 01 movw r30, r12 + 7ed8: b7 be out 0x37, r11 ; 55 + 7eda: e8 95 spm + 7edc: c0 e0 ldi r28, 0x00 ; 0 + 7ede: d1 e0 ldi r29, 0x01 ; 1 // While that is going on, read in page contents bufPtr = buff; do *bufPtr++ = getch(); - 7ece: 69 d0 rcall .+210 ; 0x7fa2 <getch> - 7ed0: 89 93 st Y+, r24 + 7ee0: 62 d0 rcall .+196 ; 0x7fa6 <getch> + 7ee2: 89 93 st Y+, r24 while (--length); - 7ed2: 80 91 02 02 lds r24, 0x0202 - 7ed6: 81 50 subi r24, 0x01 ; 1 - 7ed8: 80 93 02 02 sts 0x0202, r24 - 7edc: 88 23 and r24, r24 - 7ede: b9 f7 brne .-18 ; 0x7ece <main+0xce> + 7ee4: 0c 17 cp r16, r28 + 7ee6: e1 f7 brne .-8 ; 0x7ee0 <main+0xe0> + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 7ee8: f0 e0 ldi r31, 0x00 ; 0 + 7eea: cf 16 cp r12, r31 + 7eec: f0 e7 ldi r31, 0x70 ; 112 + 7eee: df 06 cpc r13, r31 + 7ef0: 18 f0 brcs .+6 ; 0x7ef8 <main+0xf8> + 7ef2: f6 01 movw r30, r12 + 7ef4: b7 be out 0x37, r11 ; 55 + 7ef6: e8 95 spm // Read command terminator, start reply verifySpace(); - 7ee0: 78 d0 rcall .+240 ; 0x7fd2 <verifySpace> - + 7ef8: 68 d0 rcall .+208 ; 0x7fca <verifySpace> + // If only a partial page is to be programmed, the erase might not be complete. // So check that here boot_spm_busy_wait(); - 7ee2: 07 b6 in r0, 0x37 ; 55 - 7ee4: 00 fc sbrc r0, 0 - 7ee6: fd cf rjmp .-6 ; 0x7ee2 <main+0xe2> - } -#endif - - // Copy buffer into programming buffer + 7efa: 07 b6 in r0, 0x37 ; 55 + 7efc: 00 fc sbrc r0, 0 + 7efe: fd cf rjmp .-6 ; 0x7efa <main+0xfa> + 7f00: a6 01 movw r20, r12 + 7f02: a0 e0 ldi r26, 0x00 ; 0 + 7f04: b1 e0 ldi r27, 0x01 ; 1 bufPtr = buff; addrPtr = (uint16_t)(void*)address; - 7ee8: 40 91 00 02 lds r20, 0x0200 - 7eec: 50 91 01 02 lds r21, 0x0201 - 7ef0: a0 e0 ldi r26, 0x00 ; 0 - 7ef2: b1 e0 ldi r27, 0x01 ; 1 ch = SPM_PAGESIZE / 2; do { uint16_t a; a = *bufPtr++; - 7ef4: 2c 91 ld r18, X - 7ef6: 30 e0 ldi r19, 0x00 ; 0 + 7f06: 2c 91 ld r18, X + 7f08: 30 e0 ldi r19, 0x00 ; 0 a |= (*bufPtr++) << 8; - 7ef8: 11 96 adiw r26, 0x01 ; 1 - 7efa: 8c 91 ld r24, X - 7efc: 11 97 sbiw r26, 0x01 ; 1 - 7efe: 90 e0 ldi r25, 0x00 ; 0 - 7f00: 98 2f mov r25, r24 - 7f02: 88 27 eor r24, r24 - 7f04: 82 2b or r24, r18 - 7f06: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) + 7f0a: 11 96 adiw r26, 0x01 ; 1 + 7f0c: 8c 91 ld r24, X + 7f0e: 11 97 sbiw r26, 0x01 ; 1 + 7f10: 90 e0 ldi r25, 0x00 ; 0 + 7f12: 98 2f mov r25, r24 + 7f14: 88 27 eor r24, r24 + 7f16: 82 2b or r24, r18 + 7f18: 93 2b or r25, r19 +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) #endif + /* main program starts here */ int main(void) { - 7f08: 12 96 adiw r26, 0x02 ; 2 + 7f1a: 12 96 adiw r26, 0x02 ; 2 ch = SPM_PAGESIZE / 2; do { uint16_t a; a = *bufPtr++; a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 7f0a: fa 01 movw r30, r20 - 7f0c: 0c 01 movw r0, r24 - 7f0e: d0 92 57 00 sts 0x0057, r13 - 7f12: e8 95 spm - 7f14: 11 24 eor r1, r1 + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 7f1c: fa 01 movw r30, r20 + 7f1e: 0c 01 movw r0, r24 + 7f20: 87 be out 0x37, r8 ; 55 + 7f22: e8 95 spm + 7f24: 11 24 eor r1, r1 addrPtr += 2; - 7f16: 4e 5f subi r20, 0xFE ; 254 - 7f18: 5f 4f sbci r21, 0xFF ; 255 + 7f26: 4e 5f subi r20, 0xFE ; 254 + 7f28: 5f 4f sbci r21, 0xFF ; 255 } while (--ch); - 7f1a: f1 e0 ldi r31, 0x01 ; 1 - 7f1c: a0 38 cpi r26, 0x80 ; 128 - 7f1e: bf 07 cpc r27, r31 - 7f20: 49 f7 brne .-46 ; 0x7ef4 <main+0xf4> - + 7f2a: f1 e0 ldi r31, 0x01 ; 1 + 7f2c: a0 38 cpi r26, 0x80 ; 128 + 7f2e: bf 07 cpc r27, r31 + 7f30: 51 f7 brne .-44 ; 0x7f06 <main+0x106> + // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 7f22: e0 91 00 02 lds r30, 0x0200 - 7f26: f0 91 01 02 lds r31, 0x0201 - 7f2a: e0 92 57 00 sts 0x0057, r14 - 7f2e: e8 95 spm + __boot_page_write_short((uint16_t)(void*)address); + 7f32: f6 01 movw r30, r12 + 7f34: a7 be out 0x37, r10 ; 55 + 7f36: e8 95 spm boot_spm_busy_wait(); - 7f30: 07 b6 in r0, 0x37 ; 55 - 7f32: 00 fc sbrc r0, 0 - 7f34: fd cf rjmp .-6 ; 0x7f30 <main+0x130> + 7f38: 07 b6 in r0, 0x37 ; 55 + 7f3a: 00 fc sbrc r0, 0 + 7f3c: fd cf rjmp .-6 ; 0x7f38 <main+0x138> #if defined(RWWSRE) // Reenable read access to flash boot_rww_enable(); - 7f36: f0 92 57 00 sts 0x0057, r15 - 7f3a: e8 95 spm - 7f3c: 27 c0 rjmp .+78 ; 0x7f8c <main+0x18c> + 7f3e: 97 be out 0x37, r9 ; 55 + 7f40: e8 95 spm + 7f42: 26 c0 rjmp .+76 ; 0x7f90 <main+0x190> #endif } /* Read memory block mode, length is big endian. */ else if(ch == STK_READ_PAGE) { - 7f3e: 84 37 cpi r24, 0x74 ; 116 - 7f40: b9 f4 brne .+46 ; 0x7f70 <main+0x170> + 7f44: 84 37 cpi r24, 0x74 ; 116 + 7f46: b1 f4 brne .+44 ; 0x7f74 <main+0x174> // READ PAGE - we only read flash - getLen(); - 7f42: 37 d0 rcall .+110 ; 0x7fb2 <getLen> + getch(); /* getlen() */ + 7f48: 2e d0 rcall .+92 ; 0x7fa6 <getch> + length = getch(); + 7f4a: 2d d0 rcall .+90 ; 0x7fa6 <getch> + 7f4c: f8 2e mov r15, r24 + getch(); + 7f4e: 2b d0 rcall .+86 ; 0x7fa6 <getch> + verifySpace(); - 7f44: 46 d0 rcall .+140 ; 0x7fd2 <verifySpace> - else ch = pgm_read_byte_near(address); + 7f50: 3c d0 rcall .+120 ; 0x7fca <verifySpace> + 7f52: f6 01 movw r30, r12 + 7f54: ef 2c mov r14, r15 + putch(result); address++; - putch(ch); - } while (--length); + } + while (--length); #else do putch(pgm_read_byte_near(address++)); - 7f46: e0 91 00 02 lds r30, 0x0200 - 7f4a: f0 91 01 02 lds r31, 0x0201 - 7f4e: 31 96 adiw r30, 0x01 ; 1 - 7f50: f0 93 01 02 sts 0x0201, r31 - 7f54: e0 93 00 02 sts 0x0200, r30 - 7f58: 31 97 sbiw r30, 0x01 ; 1 - 7f5a: e4 91 lpm r30, Z+ - 7f5c: 8e 2f mov r24, r30 - 7f5e: 19 d0 rcall .+50 ; 0x7f92 <putch> + 7f56: 8f 01 movw r16, r30 + 7f58: 0f 5f subi r16, 0xFF ; 255 + 7f5a: 1f 4f sbci r17, 0xFF ; 255 + 7f5c: 84 91 lpm r24, Z+ + 7f5e: 1b d0 rcall .+54 ; 0x7f96 <putch> while (--length); - 7f60: 80 91 02 02 lds r24, 0x0202 - 7f64: 81 50 subi r24, 0x01 ; 1 - 7f66: 80 93 02 02 sts 0x0202, r24 - 7f6a: 88 23 and r24, r24 - 7f6c: 61 f7 brne .-40 ; 0x7f46 <main+0x146> - 7f6e: 0e c0 rjmp .+28 ; 0x7f8c <main+0x18c> + 7f60: ea 94 dec r14 + 7f62: f8 01 movw r30, r16 + 7f64: c1 f7 brne .-16 ; 0x7f56 <main+0x156> +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 7f66: 08 94 sec + 7f68: c1 1c adc r12, r1 + 7f6a: d1 1c adc r13, r1 + 7f6c: fa 94 dec r15 + 7f6e: cf 0c add r12, r15 + 7f70: d1 1c adc r13, r1 + 7f72: 0e c0 rjmp .+28 ; 0x7f90 <main+0x190> +#endif #endif } /* Get device signature bytes */ else if(ch == STK_READ_SIGN) { - 7f70: 85 37 cpi r24, 0x75 ; 117 - 7f72: 39 f4 brne .+14 ; 0x7f82 <main+0x182> + 7f74: 85 37 cpi r24, 0x75 ; 117 + 7f76: 39 f4 brne .+14 ; 0x7f86 <main+0x186> // READ SIGN - return what Avrdude wants to hear verifySpace(); - 7f74: 2e d0 rcall .+92 ; 0x7fd2 <verifySpace> + 7f78: 28 d0 rcall .+80 ; 0x7fca <verifySpace> putch(SIGNATURE_0); - 7f76: 8e e1 ldi r24, 0x1E ; 30 - 7f78: 0c d0 rcall .+24 ; 0x7f92 <putch> + 7f7a: 8e e1 ldi r24, 0x1E ; 30 + 7f7c: 0c d0 rcall .+24 ; 0x7f96 <putch> putch(SIGNATURE_1); - 7f7a: 85 e9 ldi r24, 0x95 ; 149 - 7f7c: 0a d0 rcall .+20 ; 0x7f92 <putch> + 7f7e: 85 e9 ldi r24, 0x95 ; 149 + 7f80: 0a d0 rcall .+20 ; 0x7f96 <putch> putch(SIGNATURE_2); - 7f7e: 8f e0 ldi r24, 0x0F ; 15 - 7f80: 96 cf rjmp .-212 ; 0x7eae <main+0xae> + 7f82: 8f e0 ldi r24, 0x0F ; 15 + 7f84: 7a cf rjmp .-268 ; 0x7e7a <main+0x7a> } else if (ch == 'Q') { - 7f82: 81 35 cpi r24, 0x51 ; 81 - 7f84: 11 f4 brne .+4 ; 0x7f8a <main+0x18a> + 7f86: 81 35 cpi r24, 0x51 ; 81 + 7f88: 11 f4 brne .+4 ; 0x7f8e <main+0x18e> // Adaboot no-wait mod watchdogConfig(WATCHDOG_16MS); - 7f86: 88 e0 ldi r24, 0x08 ; 8 - 7f88: 19 d0 rcall .+50 ; 0x7fbc <watchdogConfig> + 7f8a: 88 e0 ldi r24, 0x08 ; 8 + 7f8c: 18 d0 rcall .+48 ; 0x7fbe <watchdogConfig> verifySpace(); } else { // This covers the response to commands like STK_ENTER_PROGMODE verifySpace(); - 7f8a: 23 d0 rcall .+70 ; 0x7fd2 <verifySpace> + 7f8e: 1d d0 rcall .+58 ; 0x7fca <verifySpace> } putch(STK_OK); - 7f8c: 80 e1 ldi r24, 0x10 ; 16 - 7f8e: 01 d0 rcall .+2 ; 0x7f92 <putch> - 7f90: 63 cf rjmp .-314 ; 0x7e58 <main+0x58> + 7f90: 80 e1 ldi r24, 0x10 ; 16 + 7f92: 01 d0 rcall .+2 ; 0x7f96 <putch> + 7f94: 65 cf rjmp .-310 ; 0x7e60 <main+0x60> -00007f92 <putch>: +00007f96 <putch>: } } void putch(char ch) { - 7f92: 98 2f mov r25, r24 + 7f96: 98 2f mov r25, r24 #ifndef SOFT_UART while (!(UCSR0A & _BV(UDRE0))); - 7f94: 80 91 c0 00 lds r24, 0x00C0 - 7f98: 85 ff sbrs r24, 5 - 7f9a: fc cf rjmp .-8 ; 0x7f94 <putch+0x2> + 7f98: 80 91 c0 00 lds r24, 0x00C0 + 7f9c: 85 ff sbrs r24, 5 + 7f9e: fc cf rjmp .-8 ; 0x7f98 <putch+0x2> UDR0 = ch; - 7f9c: 90 93 c6 00 sts 0x00C6, r25 + 7fa0: 90 93 c6 00 sts 0x00C6, r25 [uartBit] "I" (UART_TX_BIT) : "r25" ); #endif } - 7fa0: 08 95 ret + 7fa4: 08 95 ret -00007fa2 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 7fa2: a8 95 wdr +00007fa6 <getch>: [uartBit] "I" (UART_RX_BIT) : "r25" ); #else - while(!(UCSR0A & _BV(RXC0))); - 7fa4: 80 91 c0 00 lds r24, 0x00C0 - 7fa8: 87 ff sbrs r24, 7 - 7faa: fc cf rjmp .-8 ; 0x7fa4 <getch+0x2> + while(!(UCSR0A & _BV(RXC0))) + 7fa6: 80 91 c0 00 lds r24, 0x00C0 + 7faa: 87 ff sbrs r24, 7 + 7fac: fc cf rjmp .-8 ; 0x7fa6 <getch> + ; + if (!(UCSR0A & _BV(FE0))) { + 7fae: 80 91 c0 00 lds r24, 0x00C0 + 7fb2: 84 fd sbrc r24, 4 + 7fb4: 01 c0 rjmp .+2 ; 0x7fb8 <getch+0x12> +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 7fb6: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; - 7fac: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH + 7fb8: 80 91 c6 00 lds r24, 0x00C6 LED_PIN |= _BV(LED); #endif - - return ch; -} - 7fb0: 08 95 ret - -00007fb2 <getLen>: - } while (--count); -} #endif -uint8_t getLen() { - getch(); - 7fb2: f7 df rcall .-18 ; 0x7fa2 <getch> - length = getch(); - 7fb4: f6 df rcall .-20 ; 0x7fa2 <getch> - 7fb6: 80 93 02 02 sts 0x0202, r24 - return getch(); + return ch; } - 7fba: f3 cf rjmp .-26 ; 0x7fa2 <getch> + 7fbc: 08 95 ret -00007fbc <watchdogConfig>: +00007fbe <watchdogConfig>: "wdr\n" ); } void watchdogConfig(uint8_t x) { WDTCSR = _BV(WDCE) | _BV(WDE); - 7fbc: e0 e6 ldi r30, 0x60 ; 96 - 7fbe: f0 e0 ldi r31, 0x00 ; 0 - 7fc0: 98 e1 ldi r25, 0x18 ; 24 - 7fc2: 90 83 st Z, r25 + 7fbe: e0 e6 ldi r30, 0x60 ; 96 + 7fc0: f0 e0 ldi r31, 0x00 ; 0 + 7fc2: 98 e1 ldi r25, 0x18 ; 24 + 7fc4: 90 83 st Z, r25 WDTCSR = x; - 7fc4: 80 83 st Z, r24 + 7fc6: 80 83 st Z, r24 } - 7fc6: 08 95 ret - -00007fc8 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 7fc8: 80 e0 ldi r24, 0x00 ; 0 - 7fca: f8 df rcall .-16 ; 0x7fbc <watchdogConfig> - __asm__ __volatile__ ( - 7fcc: ee 27 eor r30, r30 - 7fce: ff 27 eor r31, r31 - 7fd0: 09 94 ijmp + 7fc8: 08 95 ret -00007fd2 <verifySpace>: +00007fca <verifySpace>: do getch(); while (--count); verifySpace(); } void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 7fd2: e7 df rcall .-50 ; 0x7fa2 <getch> - 7fd4: 80 32 cpi r24, 0x20 ; 32 - 7fd6: 09 f0 breq .+2 ; 0x7fda <verifySpace+0x8> - 7fd8: f7 df rcall .-18 ; 0x7fc8 <appStart> + if (getch() != CRC_EOP) { + 7fca: ed df rcall .-38 ; 0x7fa6 <getch> + 7fcc: 80 32 cpi r24, 0x20 ; 32 + 7fce: 19 f0 breq .+6 ; 0x7fd6 <verifySpace+0xc> + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 7fd0: 88 e0 ldi r24, 0x08 ; 8 + 7fd2: f5 df rcall .-22 ; 0x7fbe <watchdogConfig> + 7fd4: ff cf rjmp .-2 ; 0x7fd4 <verifySpace+0xa> + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } putch(STK_INSYNC); - 7fda: 84 e1 ldi r24, 0x14 ; 20 + 7fd6: 84 e1 ldi r24, 0x14 ; 20 } - 7fdc: da cf rjmp .-76 ; 0x7f92 <putch> + 7fd8: de cf rjmp .-68 ; 0x7f96 <putch> + +00007fda <getNch>: ::[count] "M" (UART_B_VALUE) ); } #endif void getNch(uint8_t count) { - 7fde: 1f 93 push r17 - 7fe0: 18 2f mov r17, r24 - -00007fe2 <getNch>: + 7fda: 1f 93 push r17 + 7fdc: 18 2f mov r17, r24 do getch(); while (--count); - 7fe2: df df rcall .-66 ; 0x7fa2 <getch> - 7fe4: 11 50 subi r17, 0x01 ; 1 - 7fe6: e9 f7 brne .-6 ; 0x7fe2 <getNch> + 7fde: e3 df rcall .-58 ; 0x7fa6 <getch> + 7fe0: 11 50 subi r17, 0x01 ; 1 + 7fe2: e9 f7 brne .-6 ; 0x7fde <getNch+0x4> verifySpace(); - 7fe8: f4 df rcall .-24 ; 0x7fd2 <verifySpace> + 7fe4: f2 df rcall .-28 ; 0x7fca <verifySpace> } - 7fea: 1f 91 pop r17 - 7fec: 08 95 ret + 7fe6: 1f 91 pop r17 + 7fe8: 08 95 ret + +00007fea <appStart>: + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 7fea: 80 e0 ldi r24, 0x00 ; 0 + 7fec: e8 df rcall .-48 ; 0x7fbe <watchdogConfig> + __asm__ __volatile__ ( + 7fee: ee 27 eor r30, r30 + 7ff0: ff 27 eor r31, r31 + 7ff2: 09 94 ijmp diff --git a/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst b/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst deleted file mode 100644 index 46eda68..0000000 --- a/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst +++ /dev/null @@ -1,520 +0,0 @@ - -optiboot_atmega328_pro_8MHz.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001ec 00007e00 00007e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000240 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000268 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000269 00000000 00000000 000002d2 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000196 00000000 00000000 0000053b 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003d3 00000000 00000000 000006d1 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000aa4 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000135 00000000 00000000 00000b34 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001d1 00000000 00000000 00000c69 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e3a 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00007e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 7e00: 85 e0 ldi r24, 0x05 ; 5 - 7e02: 80 93 81 00 sts 0x0081, r24 -#if LED_START_FLASHES > 0 - // Set up Timer 1 for timeout counter - TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 -#endif -#ifndef SOFT_UART - UCSR0A = _BV(U2X0); //Double speed mode USART0 - 7e06: 82 e0 ldi r24, 0x02 ; 2 - 7e08: 80 93 c0 00 sts 0x00C0, r24 - UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 7e0c: 88 e1 ldi r24, 0x18 ; 24 - 7e0e: 80 93 c1 00 sts 0x00C1, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 7e12: 86 e0 ldi r24, 0x06 ; 6 - 7e14: 80 93 c2 00 sts 0x00C2, r24 - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 7e18: 88 e0 ldi r24, 0x08 ; 8 - 7e1a: 80 93 c4 00 sts 0x00C4, r24 -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 7e1e: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 7e20: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 7e22: 81 ff sbrs r24, 1 - 7e24: d0 d0 rcall .+416 ; 0x7fc6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 7e26: 8d e0 ldi r24, 0x0D ; 13 - 7e28: c8 d0 rcall .+400 ; 0x7fba <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 7e2a: 25 9a sbi 0x04, 5 ; 4 - 7e2c: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 7e2e: 28 e1 ldi r18, 0x18 ; 24 - 7e30: 3e ef ldi r19, 0xFE ; 254 - TIFR1 = _BV(TOV1); - 7e32: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 7e34: 30 93 85 00 sts 0x0085, r19 - 7e38: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 7e3c: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 7e3e: b0 9b sbis 0x16, 0 ; 22 - 7e40: fe cf rjmp .-4 ; 0x7e3e <main+0x3e> - LED_PIN |= _BV(LED); - 7e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 7e44: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 7e46: 81 50 subi r24, 0x01 ; 1 - 7e48: a9 f7 brne .-22 ; 0x7e34 <main+0x34> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e4a: dd 24 eor r13, r13 - 7e4c: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 7e4e: a5 e0 ldi r26, 0x05 ; 5 - 7e50: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 7e52: f1 e1 ldi r31, 0x11 ; 17 - 7e54: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 7e56: a4 d0 rcall .+328 ; 0x7fa0 <getch> - - if(ch == STK_GET_PARAMETER) { - 7e58: 81 34 cpi r24, 0x41 ; 65 - 7e5a: 21 f4 brne .+8 ; 0x7e64 <main+0x64> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 7e5c: 81 e0 ldi r24, 0x01 ; 1 - 7e5e: be d0 rcall .+380 ; 0x7fdc <verifySpace+0xc> - putch(0x03); - 7e60: 83 e0 ldi r24, 0x03 ; 3 - 7e62: 24 c0 rjmp .+72 ; 0x7eac <main+0xac> - } - else if(ch == STK_SET_DEVICE) { - 7e64: 82 34 cpi r24, 0x42 ; 66 - 7e66: 11 f4 brne .+4 ; 0x7e6c <main+0x6c> - // SET DEVICE is ignored - getNch(20); - 7e68: 84 e1 ldi r24, 0x14 ; 20 - 7e6a: 03 c0 rjmp .+6 ; 0x7e72 <main+0x72> - } - else if(ch == STK_SET_DEVICE_EXT) { - 7e6c: 85 34 cpi r24, 0x45 ; 69 - 7e6e: 19 f4 brne .+6 ; 0x7e76 <main+0x76> - // SET DEVICE EXT is ignored - getNch(5); - 7e70: 85 e0 ldi r24, 0x05 ; 5 - 7e72: b4 d0 rcall .+360 ; 0x7fdc <verifySpace+0xc> - 7e74: 8a c0 rjmp .+276 ; 0x7f8a <main+0x18a> - } - else if(ch == STK_LOAD_ADDRESS) { - 7e76: 85 35 cpi r24, 0x55 ; 85 - 7e78: a1 f4 brne .+40 ; 0x7ea2 <main+0xa2> - // LOAD ADDRESS - address = getch(); - 7e7a: 92 d0 rcall .+292 ; 0x7fa0 <getch> - 7e7c: 08 2f mov r16, r24 - 7e7e: 10 e0 ldi r17, 0x00 ; 0 - 7e80: 10 93 01 02 sts 0x0201, r17 - 7e84: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 7e88: 8b d0 rcall .+278 ; 0x7fa0 <getch> - 7e8a: 90 e0 ldi r25, 0x00 ; 0 - 7e8c: 98 2f mov r25, r24 - 7e8e: 88 27 eor r24, r24 - 7e90: 80 2b or r24, r16 - 7e92: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 7e94: 88 0f add r24, r24 - 7e96: 99 1f adc r25, r25 - 7e98: 90 93 01 02 sts 0x0201, r25 - 7e9c: 80 93 00 02 sts 0x0200, r24 - 7ea0: 73 c0 rjmp .+230 ; 0x7f88 <main+0x188> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 7ea2: 86 35 cpi r24, 0x56 ; 86 - 7ea4: 29 f4 brne .+10 ; 0x7eb0 <main+0xb0> - // UNIVERSAL command is ignored - getNch(4); - 7ea6: 84 e0 ldi r24, 0x04 ; 4 - 7ea8: 99 d0 rcall .+306 ; 0x7fdc <verifySpace+0xc> - putch(0x00); - 7eaa: 80 e0 ldi r24, 0x00 ; 0 - 7eac: 71 d0 rcall .+226 ; 0x7f90 <putch> - 7eae: 6d c0 rjmp .+218 ; 0x7f8a <main+0x18a> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 7eb0: 84 36 cpi r24, 0x64 ; 100 - 7eb2: 09 f0 breq .+2 ; 0x7eb6 <main+0xb6> - 7eb4: 43 c0 rjmp .+134 ; 0x7f3c <main+0x13c> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 7eb6: 7c d0 rcall .+248 ; 0x7fb0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 7eb8: e0 91 00 02 lds r30, 0x0200 - 7ebc: f0 91 01 02 lds r31, 0x0201 - 7ec0: 83 e0 ldi r24, 0x03 ; 3 - 7ec2: 80 93 57 00 sts 0x0057, r24 - 7ec6: e8 95 spm - 7ec8: c0 e0 ldi r28, 0x00 ; 0 - 7eca: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 7ecc: 69 d0 rcall .+210 ; 0x7fa0 <getch> - 7ece: 89 93 st Y+, r24 - while (--length); - 7ed0: 80 91 02 02 lds r24, 0x0202 - 7ed4: 81 50 subi r24, 0x01 ; 1 - 7ed6: 80 93 02 02 sts 0x0202, r24 - 7eda: 88 23 and r24, r24 - 7edc: b9 f7 brne .-18 ; 0x7ecc <main+0xcc> - - // Read command terminator, start reply - verifySpace(); - 7ede: 78 d0 rcall .+240 ; 0x7fd0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 7ee0: 07 b6 in r0, 0x37 ; 55 - 7ee2: 00 fc sbrc r0, 0 - 7ee4: fd cf rjmp .-6 ; 0x7ee0 <main+0xe0> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 7ee6: 40 91 00 02 lds r20, 0x0200 - 7eea: 50 91 01 02 lds r21, 0x0201 - 7eee: a0 e0 ldi r26, 0x00 ; 0 - 7ef0: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 7ef2: 2c 91 ld r18, X - 7ef4: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 7ef6: 11 96 adiw r26, 0x01 ; 1 - 7ef8: 8c 91 ld r24, X - 7efa: 11 97 sbiw r26, 0x01 ; 1 - 7efc: 90 e0 ldi r25, 0x00 ; 0 - 7efe: 98 2f mov r25, r24 - 7f00: 88 27 eor r24, r24 - 7f02: 82 2b or r24, r18 - 7f04: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 7f06: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 7f08: fa 01 movw r30, r20 - 7f0a: 0c 01 movw r0, r24 - 7f0c: d0 92 57 00 sts 0x0057, r13 - 7f10: e8 95 spm - 7f12: 11 24 eor r1, r1 - addrPtr += 2; - 7f14: 4e 5f subi r20, 0xFE ; 254 - 7f16: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 7f18: f1 e0 ldi r31, 0x01 ; 1 - 7f1a: a0 38 cpi r26, 0x80 ; 128 - 7f1c: bf 07 cpc r27, r31 - 7f1e: 49 f7 brne .-46 ; 0x7ef2 <main+0xf2> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 7f20: e0 91 00 02 lds r30, 0x0200 - 7f24: f0 91 01 02 lds r31, 0x0201 - 7f28: e0 92 57 00 sts 0x0057, r14 - 7f2c: e8 95 spm - boot_spm_busy_wait(); - 7f2e: 07 b6 in r0, 0x37 ; 55 - 7f30: 00 fc sbrc r0, 0 - 7f32: fd cf rjmp .-6 ; 0x7f2e <main+0x12e> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 7f34: f0 92 57 00 sts 0x0057, r15 - 7f38: e8 95 spm - 7f3a: 27 c0 rjmp .+78 ; 0x7f8a <main+0x18a> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 7f3c: 84 37 cpi r24, 0x74 ; 116 - 7f3e: b9 f4 brne .+46 ; 0x7f6e <main+0x16e> - // READ PAGE - we only read flash - getLen(); - 7f40: 37 d0 rcall .+110 ; 0x7fb0 <getLen> - verifySpace(); - 7f42: 46 d0 rcall .+140 ; 0x7fd0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 7f44: e0 91 00 02 lds r30, 0x0200 - 7f48: f0 91 01 02 lds r31, 0x0201 - 7f4c: 31 96 adiw r30, 0x01 ; 1 - 7f4e: f0 93 01 02 sts 0x0201, r31 - 7f52: e0 93 00 02 sts 0x0200, r30 - 7f56: 31 97 sbiw r30, 0x01 ; 1 - 7f58: e4 91 lpm r30, Z+ - 7f5a: 8e 2f mov r24, r30 - 7f5c: 19 d0 rcall .+50 ; 0x7f90 <putch> - while (--length); - 7f5e: 80 91 02 02 lds r24, 0x0202 - 7f62: 81 50 subi r24, 0x01 ; 1 - 7f64: 80 93 02 02 sts 0x0202, r24 - 7f68: 88 23 and r24, r24 - 7f6a: 61 f7 brne .-40 ; 0x7f44 <main+0x144> - 7f6c: 0e c0 rjmp .+28 ; 0x7f8a <main+0x18a> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 7f6e: 85 37 cpi r24, 0x75 ; 117 - 7f70: 39 f4 brne .+14 ; 0x7f80 <main+0x180> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 7f72: 2e d0 rcall .+92 ; 0x7fd0 <verifySpace> - putch(SIGNATURE_0); - 7f74: 8e e1 ldi r24, 0x1E ; 30 - 7f76: 0c d0 rcall .+24 ; 0x7f90 <putch> - putch(SIGNATURE_1); - 7f78: 85 e9 ldi r24, 0x95 ; 149 - 7f7a: 0a d0 rcall .+20 ; 0x7f90 <putch> - putch(SIGNATURE_2); - 7f7c: 8f e0 ldi r24, 0x0F ; 15 - 7f7e: 96 cf rjmp .-212 ; 0x7eac <main+0xac> - } - else if (ch == 'Q') { - 7f80: 81 35 cpi r24, 0x51 ; 81 - 7f82: 11 f4 brne .+4 ; 0x7f88 <main+0x188> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 7f84: 88 e0 ldi r24, 0x08 ; 8 - 7f86: 19 d0 rcall .+50 ; 0x7fba <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 7f88: 23 d0 rcall .+70 ; 0x7fd0 <verifySpace> - } - putch(STK_OK); - 7f8a: 80 e1 ldi r24, 0x10 ; 16 - 7f8c: 01 d0 rcall .+2 ; 0x7f90 <putch> - 7f8e: 63 cf rjmp .-314 ; 0x7e56 <main+0x56> - -00007f90 <putch>: - } -} - -void putch(char ch) { - 7f90: 98 2f mov r25, r24 -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - 7f92: 80 91 c0 00 lds r24, 0x00C0 - 7f96: 85 ff sbrs r24, 5 - 7f98: fc cf rjmp .-8 ; 0x7f92 <putch+0x2> - UDR0 = ch; - 7f9a: 90 93 c6 00 sts 0x00C6, r25 - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 7f9e: 08 95 ret - -00007fa0 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 7fa0: a8 95 wdr - [uartBit] "I" (UART_RX_BIT) - : - "r25" -); -#else - while(!(UCSR0A & _BV(RXC0))); - 7fa2: 80 91 c0 00 lds r24, 0x00C0 - 7fa6: 87 ff sbrs r24, 7 - 7fa8: fc cf rjmp .-8 ; 0x7fa2 <getch+0x2> - ch = UDR0; - 7faa: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 7fae: 08 95 ret - -00007fb0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 7fb0: f7 df rcall .-18 ; 0x7fa0 <getch> - length = getch(); - 7fb2: f6 df rcall .-20 ; 0x7fa0 <getch> - 7fb4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 7fb8: f3 cf rjmp .-26 ; 0x7fa0 <getch> - -00007fba <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 7fba: e0 e6 ldi r30, 0x60 ; 96 - 7fbc: f0 e0 ldi r31, 0x00 ; 0 - 7fbe: 98 e1 ldi r25, 0x18 ; 24 - 7fc0: 90 83 st Z, r25 - WDTCSR = x; - 7fc2: 80 83 st Z, r24 -} - 7fc4: 08 95 ret - -00007fc6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 7fc6: 80 e0 ldi r24, 0x00 ; 0 - 7fc8: f8 df rcall .-16 ; 0x7fba <watchdogConfig> - __asm__ __volatile__ ( - 7fca: ee 27 eor r30, r30 - 7fcc: ff 27 eor r31, r31 - 7fce: 09 94 ijmp - -00007fd0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 7fd0: e7 df rcall .-50 ; 0x7fa0 <getch> - 7fd2: 80 32 cpi r24, 0x20 ; 32 - 7fd4: 09 f0 breq .+2 ; 0x7fd8 <verifySpace+0x8> - 7fd6: f7 df rcall .-18 ; 0x7fc6 <appStart> - putch(STK_INSYNC); - 7fd8: 84 e1 ldi r24, 0x14 ; 20 -} - 7fda: da cf rjmp .-76 ; 0x7f90 <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 7fdc: 1f 93 push r17 - 7fde: 18 2f mov r17, r24 - -00007fe0 <getNch>: - do getch(); while (--count); - 7fe0: df df rcall .-66 ; 0x7fa0 <getch> - 7fe2: 11 50 subi r17, 0x01 ; 1 - 7fe4: e9 f7 brne .-6 ; 0x7fe0 <getNch> - verifySpace(); - 7fe6: f4 df rcall .-24 ; 0x7fd0 <verifySpace> -} - 7fe8: 1f 91 pop r17 - 7fea: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_atmega8.hex b/bootloaders/optiboot/optiboot_atmega8.hex new file mode 100644 index 0000000..b04f276 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega8.hex @@ -0,0 +1,33 @@ +:101E000011248FE594E09EBF8DBF84B714BE81FF7F
+:101E1000E2D085E08EBD82E08BB988E18AB986E8A0
+:101E200080BD80E189B98EE0C2D0BD9A96E020E302
+:101E30003CEF54E040E23DBD2CBD58BF08B602FE69
+:101E4000FDCF88B3842788BBA8959150A1F7CC24F7
+:101E5000DD2488248394B5E0AB2EA1E19A2EF3E033
+:101E6000BF2E9ED0813461F49BD0082FA4D00238BD
+:101E700011F0013811F484E001C083E08DD089C0F5
+:101E8000823411F484E103C0853419F485E09BD0D9
+:101E900080C0853579F484D0E82EFF2481D0082FC6
+:101EA00010E0102F00270E291F29000F111F83D0CB
+:101EB00068016FC0863521F484E085D080E0DECFF4
+:101EC000843609F040C06CD06BD0082F69D080E018
+:101ED000C81688E1D80618F4F601B7BEE895C0E048
+:101EE000D1E05ED089930C17E1F7F0E0CF16F8E16E
+:101EF000DF0618F0F601B7BEE8955DD007B600FC26
+:101F0000FDCFA601A0E0B1E02C9130E011968C91BC
+:101F1000119790E0982F8827822B932B1296FA0125
+:101F20000C0187BEE89511244E5F5F4FF1E0A034AD
+:101F3000BF0751F7F601A7BEE89507B600FCFDCF35
+:101F400097BEE89526C08437B1F42AD029D0F82E60
+:101F500027D031D0F601EF2C8F010F5F1F4F8491F6
+:101F60001BD0EA94F801C1F70894C11CD11CFA9463
+:101F7000CF0CD11C0EC0853739F41DD08EE10CD0AA
+:101F800083E90AD087E07ACF813511F488E00FD059
+:101F900012D080E101D065CF5D9BFECF8CB9089552
+:101FA0005F9BFECF5C9901C0A8958CB1089598E124
+:101FB00091BD81BD0895F4DF803219F088E0F7DF2C
+:101FC000FFCF84E1E9CF1F93182FEADF1150E9F723
+:101FD000F2DF1F91089580E0EADFEE27FF270994E2
+:021FFE000404D9
+:0400000300001E00DB
+:00000001FF
diff --git a/bootloaders/optiboot/optiboot_atmega8.lst b/bootloaders/optiboot/optiboot_atmega8.lst new file mode 100644 index 0000000..d921895 --- /dev/null +++ b/bootloaders/optiboot/optiboot_atmega8.lst @@ -0,0 +1,604 @@ + +optiboot_atmega8.elf: file format elf32-avr + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 000001e0 00001e00 00001e00 00000054 2**1 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .version 00000002 00001ffe 00001ffe 00000234 2**0 + CONTENTS, READONLY + 2 .debug_aranges 00000028 00000000 00000000 00000236 2**0 + CONTENTS, READONLY, DEBUGGING + 3 .debug_pubnames 0000005f 00000000 00000000 0000025e 2**0 + CONTENTS, READONLY, DEBUGGING + 4 .debug_info 000002a6 00000000 00000000 000002bd 2**0 + CONTENTS, READONLY, DEBUGGING + 5 .debug_abbrev 00000169 00000000 00000000 00000563 2**0 + CONTENTS, READONLY, DEBUGGING + 6 .debug_line 00000498 00000000 00000000 000006cc 2**0 + CONTENTS, READONLY, DEBUGGING + 7 .debug_frame 00000080 00000000 00000000 00000b64 2**2 + CONTENTS, READONLY, DEBUGGING + 8 .debug_str 0000014f 00000000 00000000 00000be4 2**0 + CONTENTS, READONLY, DEBUGGING + 9 .debug_loc 000002ba 00000000 00000000 00000d33 2**0 + CONTENTS, READONLY, DEBUGGING + 10 .debug_ranges 00000078 00000000 00000000 00000fed 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +00001e00 <main>: +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 1e00: 11 24 eor r1, r1 + // + // If not, uncomment the following instructions: + // cli(); + asm volatile ("clr __zero_reg__"); +#ifdef __AVR_ATmega8__ + SP=RAMEND; // This is done by hardware reset + 1e02: 8f e5 ldi r24, 0x5F ; 95 + 1e04: 94 e0 ldi r25, 0x04 ; 4 + 1e06: 9e bf out 0x3e, r25 ; 62 + 1e08: 8d bf out 0x3d, r24 ; 61 +#endif + + // Adaboot no-wait mod + ch = MCUSR; + 1e0a: 84 b7 in r24, 0x34 ; 52 + MCUSR = 0; + 1e0c: 14 be out 0x34, r1 ; 52 + if (!(ch & _BV(EXTRF))) appStart(); + 1e0e: 81 ff sbrs r24, 1 + 1e10: e2 d0 rcall .+452 ; 0x1fd6 <appStart> + +#if LED_START_FLASHES > 0 + // Set up Timer 1 for timeout counter + TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 + 1e12: 85 e0 ldi r24, 0x05 ; 5 + 1e14: 8e bd out 0x2e, r24 ; 46 +#endif +#ifndef SOFT_UART +#ifdef __AVR_ATmega8__ + UCSRA = _BV(U2X); //Double speed mode USART + 1e16: 82 e0 ldi r24, 0x02 ; 2 + 1e18: 8b b9 out 0x0b, r24 ; 11 + UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx + 1e1a: 88 e1 ldi r24, 0x18 ; 24 + 1e1c: 8a b9 out 0x0a, r24 ; 10 + UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 + 1e1e: 86 e8 ldi r24, 0x86 ; 134 + 1e20: 80 bd out 0x20, r24 ; 32 + UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); + 1e22: 80 e1 ldi r24, 0x10 ; 16 + 1e24: 89 b9 out 0x09, r24 ; 9 + UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); +#endif +#endif + + // Set up watchdog to trigger after 500ms + watchdogConfig(WATCHDOG_1S); + 1e26: 8e e0 ldi r24, 0x0E ; 14 + 1e28: c2 d0 rcall .+388 ; 0x1fae <watchdogConfig> + + /* Set LED pin as output */ + LED_DDR |= _BV(LED); + 1e2a: bd 9a sbi 0x17, 5 ; 23 + 1e2c: 96 e0 ldi r25, 0x06 ; 6 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 1e2e: 20 e3 ldi r18, 0x30 ; 48 + 1e30: 3c ef ldi r19, 0xFC ; 252 + TIFR1 = _BV(TOV1); + 1e32: 54 e0 ldi r21, 0x04 ; 4 + while(!(TIFR1 & _BV(TOV1))); +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); + 1e34: 40 e2 ldi r20, 0x20 ; 32 +} + +#if LED_START_FLASHES > 0 +void flash_led(uint8_t count) { + do { + TCNT1 = -(F_CPU/(1024*16)); + 1e36: 3d bd out 0x2d, r19 ; 45 + 1e38: 2c bd out 0x2c, r18 ; 44 + TIFR1 = _BV(TOV1); + 1e3a: 58 bf out 0x38, r21 ; 56 + while(!(TIFR1 & _BV(TOV1))); + 1e3c: 08 b6 in r0, 0x38 ; 56 + 1e3e: 02 fe sbrs r0, 2 + 1e40: fd cf rjmp .-6 ; 0x1e3c <main+0x3c> +#ifdef __AVR_ATmega8__ + LED_PORT ^= _BV(LED); + 1e42: 88 b3 in r24, 0x18 ; 24 + 1e44: 84 27 eor r24, r20 + 1e46: 88 bb out 0x18, r24 ; 24 +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 1e48: a8 95 wdr + LED_PORT ^= _BV(LED); +#else + LED_PIN |= _BV(LED); +#endif + watchdogReset(); + } while (--count); + 1e4a: 91 50 subi r25, 0x01 ; 1 + 1e4c: a1 f7 brne .-24 ; 0x1e36 <main+0x36> + 1e4e: cc 24 eor r12, r12 + 1e50: dd 24 eor r13, r13 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 1e52: 88 24 eor r8, r8 + 1e54: 83 94 inc r8 + addrPtr += 2; + } while (--ch); + + // Write from programming buffer + __boot_page_write_short((uint16_t)(void*)address); + 1e56: b5 e0 ldi r27, 0x05 ; 5 + 1e58: ab 2e mov r10, r27 + boot_spm_busy_wait(); + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 1e5a: a1 e1 ldi r26, 0x11 ; 17 + 1e5c: 9a 2e mov r9, r26 + do *bufPtr++ = getch(); + while (--length); + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 1e5e: f3 e0 ldi r31, 0x03 ; 3 + 1e60: bf 2e mov r11, r31 +#endif + + /* Forever loop */ + for (;;) { + /* get character from UART */ + ch = getch(); + 1e62: 9e d0 rcall .+316 ; 0x1fa0 <getch> + + if(ch == STK_GET_PARAMETER) { + 1e64: 81 34 cpi r24, 0x41 ; 65 + 1e66: 61 f4 brne .+24 ; 0x1e80 <main+0x80> + unsigned char which = getch(); + 1e68: 9b d0 rcall .+310 ; 0x1fa0 <getch> + 1e6a: 08 2f mov r16, r24 + verifySpace(); + 1e6c: a4 d0 rcall .+328 ; 0x1fb6 <verifySpace> + if (which == 0x82) { + 1e6e: 02 38 cpi r16, 0x82 ; 130 + 1e70: 11 f0 breq .+4 ; 0x1e76 <main+0x76> + /* + * Send optiboot version as "minor SW version" + */ + putch(OPTIBOOT_MINVER); + } else if (which == 0x81) { + 1e72: 01 38 cpi r16, 0x81 ; 129 + 1e74: 11 f4 brne .+4 ; 0x1e7a <main+0x7a> + putch(OPTIBOOT_MAJVER); + 1e76: 84 e0 ldi r24, 0x04 ; 4 + 1e78: 01 c0 rjmp .+2 ; 0x1e7c <main+0x7c> + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + 1e7a: 83 e0 ldi r24, 0x03 ; 3 + 1e7c: 8d d0 rcall .+282 ; 0x1f98 <putch> + 1e7e: 89 c0 rjmp .+274 ; 0x1f92 <main+0x192> + } + } + else if(ch == STK_SET_DEVICE) { + 1e80: 82 34 cpi r24, 0x42 ; 66 + 1e82: 11 f4 brne .+4 ; 0x1e88 <main+0x88> + // SET DEVICE is ignored + getNch(20); + 1e84: 84 e1 ldi r24, 0x14 ; 20 + 1e86: 03 c0 rjmp .+6 ; 0x1e8e <main+0x8e> + } + else if(ch == STK_SET_DEVICE_EXT) { + 1e88: 85 34 cpi r24, 0x45 ; 69 + 1e8a: 19 f4 brne .+6 ; 0x1e92 <main+0x92> + // SET DEVICE EXT is ignored + getNch(5); + 1e8c: 85 e0 ldi r24, 0x05 ; 5 + 1e8e: 9b d0 rcall .+310 ; 0x1fc6 <getNch> + 1e90: 80 c0 rjmp .+256 ; 0x1f92 <main+0x192> + } + else if(ch == STK_LOAD_ADDRESS) { + 1e92: 85 35 cpi r24, 0x55 ; 85 + 1e94: 79 f4 brne .+30 ; 0x1eb4 <main+0xb4> + // LOAD ADDRESS + uint16_t newAddress; + newAddress = getch(); + 1e96: 84 d0 rcall .+264 ; 0x1fa0 <getch> + newAddress = (newAddress & 0xff) | (getch() << 8); + 1e98: e8 2e mov r14, r24 + 1e9a: ff 24 eor r15, r15 + 1e9c: 81 d0 rcall .+258 ; 0x1fa0 <getch> + 1e9e: 08 2f mov r16, r24 + 1ea0: 10 e0 ldi r17, 0x00 ; 0 + 1ea2: 10 2f mov r17, r16 + 1ea4: 00 27 eor r16, r16 + 1ea6: 0e 29 or r16, r14 + 1ea8: 1f 29 or r17, r15 +#ifdef RAMPZ + // Transfer top bit to RAMPZ + RAMPZ = (newAddress & 0x8000) ? 1 : 0; +#endif + newAddress += newAddress; // Convert from word address to byte address + 1eaa: 00 0f add r16, r16 + 1eac: 11 1f adc r17, r17 + address = newAddress; + verifySpace(); + 1eae: 83 d0 rcall .+262 ; 0x1fb6 <verifySpace> + 1eb0: 68 01 movw r12, r16 + 1eb2: 6f c0 rjmp .+222 ; 0x1f92 <main+0x192> + } + else if(ch == STK_UNIVERSAL) { + 1eb4: 86 35 cpi r24, 0x56 ; 86 + 1eb6: 21 f4 brne .+8 ; 0x1ec0 <main+0xc0> + // UNIVERSAL command is ignored + getNch(4); + 1eb8: 84 e0 ldi r24, 0x04 ; 4 + 1eba: 85 d0 rcall .+266 ; 0x1fc6 <getNch> + putch(0x00); + 1ebc: 80 e0 ldi r24, 0x00 ; 0 + 1ebe: de cf rjmp .-68 ; 0x1e7c <main+0x7c> + } + /* Write memory, length is big endian and is in bytes */ + else if(ch == STK_PROG_PAGE) { + 1ec0: 84 36 cpi r24, 0x64 ; 100 + 1ec2: 09 f0 breq .+2 ; 0x1ec6 <main+0xc6> + 1ec4: 40 c0 rjmp .+128 ; 0x1f46 <main+0x146> + // PROGRAM PAGE - we support flash programming only, not EEPROM + uint8_t *bufPtr; + uint16_t addrPtr; + + getch(); /* getlen() */ + 1ec6: 6c d0 rcall .+216 ; 0x1fa0 <getch> + length = getch(); + 1ec8: 6b d0 rcall .+214 ; 0x1fa0 <getch> + 1eca: 08 2f mov r16, r24 + getch(); + 1ecc: 69 d0 rcall .+210 ; 0x1fa0 <getch> + + // If we are in RWW section, immediately start page erase + if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 1ece: 80 e0 ldi r24, 0x00 ; 0 + 1ed0: c8 16 cp r12, r24 + 1ed2: 88 e1 ldi r24, 0x18 ; 24 + 1ed4: d8 06 cpc r13, r24 + 1ed6: 18 f4 brcc .+6 ; 0x1ede <main+0xde> + 1ed8: f6 01 movw r30, r12 + 1eda: b7 be out 0x37, r11 ; 55 + 1edc: e8 95 spm + 1ede: c0 e0 ldi r28, 0x00 ; 0 + 1ee0: d1 e0 ldi r29, 0x01 ; 1 + + // While that is going on, read in page contents + bufPtr = buff; + do *bufPtr++ = getch(); + 1ee2: 5e d0 rcall .+188 ; 0x1fa0 <getch> + 1ee4: 89 93 st Y+, r24 + while (--length); + 1ee6: 0c 17 cp r16, r28 + 1ee8: e1 f7 brne .-8 ; 0x1ee2 <main+0xe2> + + // If we are in NRWW section, page erase has to be delayed until now. + // Todo: Take RAMPZ into account + if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); + 1eea: f0 e0 ldi r31, 0x00 ; 0 + 1eec: cf 16 cp r12, r31 + 1eee: f8 e1 ldi r31, 0x18 ; 24 + 1ef0: df 06 cpc r13, r31 + 1ef2: 18 f0 brcs .+6 ; 0x1efa <main+0xfa> + 1ef4: f6 01 movw r30, r12 + 1ef6: b7 be out 0x37, r11 ; 55 + 1ef8: e8 95 spm + + // Read command terminator, start reply + verifySpace(); + 1efa: 5d d0 rcall .+186 ; 0x1fb6 <verifySpace> + + // If only a partial page is to be programmed, the erase might not be complete. + // So check that here + boot_spm_busy_wait(); + 1efc: 07 b6 in r0, 0x37 ; 55 + 1efe: 00 fc sbrc r0, 0 + 1f00: fd cf rjmp .-6 ; 0x1efc <main+0xfc> + 1f02: a6 01 movw r20, r12 + 1f04: a0 e0 ldi r26, 0x00 ; 0 + 1f06: b1 e0 ldi r27, 0x01 ; 1 + bufPtr = buff; + addrPtr = (uint16_t)(void*)address; + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + 1f08: 2c 91 ld r18, X + 1f0a: 30 e0 ldi r19, 0x00 ; 0 + a |= (*bufPtr++) << 8; + 1f0c: 11 96 adiw r26, 0x01 ; 1 + 1f0e: 8c 91 ld r24, X + 1f10: 11 97 sbiw r26, 0x01 ; 1 + 1f12: 90 e0 ldi r25, 0x00 ; 0 + 1f14: 98 2f mov r25, r24 + 1f16: 88 27 eor r24, r24 + 1f18: 82 2b or r24, r18 + 1f1a: 93 2b or r25, r19 +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 1f1c: 12 96 adiw r26, 0x02 ; 2 + ch = SPM_PAGESIZE / 2; + do { + uint16_t a; + a = *bufPtr++; + a |= (*bufPtr++) << 8; + __boot_page_fill_short((uint16_t)(void*)addrPtr,a); + 1f1e: fa 01 movw r30, r20 + 1f20: 0c 01 movw r0, r24 + 1f22: 87 be out 0x37, r8 ; 55 + 1f24: e8 95 spm + 1f26: 11 24 eor r1, r1 + addrPtr += 2; + 1f28: 4e 5f subi r20, 0xFE ; 254 + 1f2a: 5f 4f sbci r21, 0xFF ; 255 + } while (--ch); + 1f2c: f1 e0 ldi r31, 0x01 ; 1 + 1f2e: a0 34 cpi r26, 0x40 ; 64 + 1f30: bf 07 cpc r27, r31 + 1f32: 51 f7 brne .-44 ; 0x1f08 <main+0x108> + + // Write from programming buffer + __boot_page_write_short((uint16_t)(void*)address); + 1f34: f6 01 movw r30, r12 + 1f36: a7 be out 0x37, r10 ; 55 + 1f38: e8 95 spm + boot_spm_busy_wait(); + 1f3a: 07 b6 in r0, 0x37 ; 55 + 1f3c: 00 fc sbrc r0, 0 + 1f3e: fd cf rjmp .-6 ; 0x1f3a <main+0x13a> + +#if defined(RWWSRE) + // Reenable read access to flash + boot_rww_enable(); + 1f40: 97 be out 0x37, r9 ; 55 + 1f42: e8 95 spm + 1f44: 26 c0 rjmp .+76 ; 0x1f92 <main+0x192> +#endif + + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) { + 1f46: 84 37 cpi r24, 0x74 ; 116 + 1f48: b1 f4 brne .+44 ; 0x1f76 <main+0x176> + // READ PAGE - we only read flash + getch(); /* getlen() */ + 1f4a: 2a d0 rcall .+84 ; 0x1fa0 <getch> + length = getch(); + 1f4c: 29 d0 rcall .+82 ; 0x1fa0 <getch> + 1f4e: f8 2e mov r15, r24 + getch(); + 1f50: 27 d0 rcall .+78 ; 0x1fa0 <getch> + + verifySpace(); + 1f52: 31 d0 rcall .+98 ; 0x1fb6 <verifySpace> + 1f54: f6 01 movw r30, r12 + 1f56: ef 2c mov r14, r15 + putch(result); + address++; + } + while (--length); +#else + do putch(pgm_read_byte_near(address++)); + 1f58: 8f 01 movw r16, r30 + 1f5a: 0f 5f subi r16, 0xFF ; 255 + 1f5c: 1f 4f sbci r17, 0xFF ; 255 + 1f5e: 84 91 lpm r24, Z+ + 1f60: 1b d0 rcall .+54 ; 0x1f98 <putch> + while (--length); + 1f62: ea 94 dec r14 + 1f64: f8 01 movw r30, r16 + 1f66: c1 f7 brne .-16 ; 0x1f58 <main+0x158> +#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4)) +#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6)) +#endif + +/* main program starts here */ +int main(void) { + 1f68: 08 94 sec + 1f6a: c1 1c adc r12, r1 + 1f6c: d1 1c adc r13, r1 + 1f6e: fa 94 dec r15 + 1f70: cf 0c add r12, r15 + 1f72: d1 1c adc r13, r1 + 1f74: 0e c0 rjmp .+28 ; 0x1f92 <main+0x192> +#endif +#endif + } + + /* Get device signature bytes */ + else if(ch == STK_READ_SIGN) { + 1f76: 85 37 cpi r24, 0x75 ; 117 + 1f78: 39 f4 brne .+14 ; 0x1f88 <main+0x188> + // READ SIGN - return what Avrdude wants to hear + verifySpace(); + 1f7a: 1d d0 rcall .+58 ; 0x1fb6 <verifySpace> + putch(SIGNATURE_0); + 1f7c: 8e e1 ldi r24, 0x1E ; 30 + 1f7e: 0c d0 rcall .+24 ; 0x1f98 <putch> + putch(SIGNATURE_1); + 1f80: 83 e9 ldi r24, 0x93 ; 147 + 1f82: 0a d0 rcall .+20 ; 0x1f98 <putch> + putch(SIGNATURE_2); + 1f84: 87 e0 ldi r24, 0x07 ; 7 + 1f86: 7a cf rjmp .-268 ; 0x1e7c <main+0x7c> + } + else if (ch == 'Q') { + 1f88: 81 35 cpi r24, 0x51 ; 81 + 1f8a: 11 f4 brne .+4 ; 0x1f90 <main+0x190> + // Adaboot no-wait mod + watchdogConfig(WATCHDOG_16MS); + 1f8c: 88 e0 ldi r24, 0x08 ; 8 + 1f8e: 0f d0 rcall .+30 ; 0x1fae <watchdogConfig> + verifySpace(); + } + else { + // This covers the response to commands like STK_ENTER_PROGMODE + verifySpace(); + 1f90: 12 d0 rcall .+36 ; 0x1fb6 <verifySpace> + } + putch(STK_OK); + 1f92: 80 e1 ldi r24, 0x10 ; 16 + 1f94: 01 d0 rcall .+2 ; 0x1f98 <putch> + 1f96: 65 cf rjmp .-310 ; 0x1e62 <main+0x62> + +00001f98 <putch>: + } +} + +void putch(char ch) { +#ifndef SOFT_UART + while (!(UCSR0A & _BV(UDRE0))); + 1f98: 5d 9b sbis 0x0b, 5 ; 11 + 1f9a: fe cf rjmp .-4 ; 0x1f98 <putch> + UDR0 = ch; + 1f9c: 8c b9 out 0x0c, r24 ; 12 + [uartBit] "I" (UART_TX_BIT) + : + "r25" + ); +#endif +} + 1f9e: 08 95 ret + +00001fa0 <getch>: + [uartBit] "I" (UART_RX_BIT) + : + "r25" +); +#else + while(!(UCSR0A & _BV(RXC0))) + 1fa0: 5f 9b sbis 0x0b, 7 ; 11 + 1fa2: fe cf rjmp .-4 ; 0x1fa0 <getch> + ; + if (!(UCSR0A & _BV(FE0))) { + 1fa4: 5c 99 sbic 0x0b, 4 ; 11 + 1fa6: 01 c0 rjmp .+2 ; 0x1faa <getch+0xa> +} +#endif + +// Watchdog functions. These are only safe with interrupts turned off. +void watchdogReset() { + __asm__ __volatile__ ( + 1fa8: a8 95 wdr + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + + ch = UDR0; + 1faa: 8c b1 in r24, 0x0c ; 12 + LED_PIN |= _BV(LED); +#endif +#endif + + return ch; +} + 1fac: 08 95 ret + +00001fae <watchdogConfig>: + "wdr\n" + ); +} + +void watchdogConfig(uint8_t x) { + WDTCSR = _BV(WDCE) | _BV(WDE); + 1fae: 98 e1 ldi r25, 0x18 ; 24 + 1fb0: 91 bd out 0x21, r25 ; 33 + WDTCSR = x; + 1fb2: 81 bd out 0x21, r24 ; 33 +} + 1fb4: 08 95 ret + +00001fb6 <verifySpace>: + do getch(); while (--count); + verifySpace(); +} + +void verifySpace() { + if (getch() != CRC_EOP) { + 1fb6: f4 df rcall .-24 ; 0x1fa0 <getch> + 1fb8: 80 32 cpi r24, 0x20 ; 32 + 1fba: 19 f0 breq .+6 ; 0x1fc2 <verifySpace+0xc> + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + 1fbc: 88 e0 ldi r24, 0x08 ; 8 + 1fbe: f7 df rcall .-18 ; 0x1fae <watchdogConfig> + 1fc0: ff cf rjmp .-2 ; 0x1fc0 <verifySpace+0xa> + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } + putch(STK_INSYNC); + 1fc2: 84 e1 ldi r24, 0x14 ; 20 +} + 1fc4: e9 cf rjmp .-46 ; 0x1f98 <putch> + +00001fc6 <getNch>: + ::[count] "M" (UART_B_VALUE) + ); +} +#endif + +void getNch(uint8_t count) { + 1fc6: 1f 93 push r17 + 1fc8: 18 2f mov r17, r24 + do getch(); while (--count); + 1fca: ea df rcall .-44 ; 0x1fa0 <getch> + 1fcc: 11 50 subi r17, 0x01 ; 1 + 1fce: e9 f7 brne .-6 ; 0x1fca <getNch+0x4> + verifySpace(); + 1fd0: f2 df rcall .-28 ; 0x1fb6 <verifySpace> +} + 1fd2: 1f 91 pop r17 + 1fd4: 08 95 ret + +00001fd6 <appStart>: + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +void appStart() { + watchdogConfig(WATCHDOG_OFF); + 1fd6: 80 e0 ldi r24, 0x00 ; 0 + 1fd8: ea df rcall .-44 ; 0x1fae <watchdogConfig> + __asm__ __volatile__ ( + 1fda: ee 27 eor r30, r30 + 1fdc: ff 27 eor r31, r31 + 1fde: 09 94 ijmp diff --git a/bootloaders/optiboot/optiboot_diecimila.hex b/bootloaders/optiboot/optiboot_diecimila.hex deleted file mode 100644 index 1e93414..0000000 --- a/bootloaders/optiboot/optiboot_diecimila.hex +++ /dev/null @@ -1,33 +0,0 @@ -:103E000085E08093810082E08093C00088E1809308
-:103E1000C10086E08093C20080E18093C40084B733
-:103E200014BE81FFD0D08DE0C8D0259A86E020E373
-:103E30003CEF91E0309385002093840096BBB09BCB
-:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
-:103E600083E024C0823411F484E103C0853419F462
-:103E700085E0B4D08AC08535A1F492D0082F10E037
-:103E800010930102009300028BD090E0982F8827B6
-:103E9000802B912B880F991F909301028093000231
-:103EA00073C0863529F484E099D080E071D06DC06C
-:103EB000843609F043C07CD0E0910002F091010209
-:103EC00083E080935700E895C0E0D1E069D0899302
-:103ED000809102028150809302028823B9F778D042
-:103EE00007B600FCFDCF4091000250910102A0E016
-:103EF000B1E02C9130E011968C91119790E0982FC1
-:103F00008827822B932B1296FA010C01D09257002E
-:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
-:103F2000E0910002F0910102E0925700E89507B697
-:103F300000FCFDCFF0925700E89527C08437B9F414
-:103F400037D046D0E0910002F09101023196F09313
-:103F50000102E09300023197E4918E2F19D08091F5
-:103F60000202815080930202882361F70EC08537D8
-:103F700039F42ED08EE10CD084E90AD086E096CFB9
-:103F8000813511F488E019D023D080E101D063CFCE
-:103F9000982F8091C00085FFFCCF9093C6000895B4
-:103FA000A8958091C00087FFFCCF8091C60008953E
-:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
-:103FC00090838083089580E0F8DFEE27FF2709942F
-:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
-:0C3FE000DFDF1150E9F7F4DF1F910895B6
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_diecimila.lst b/bootloaders/optiboot/optiboot_diecimila.lst deleted file mode 100644 index 1121893..0000000 --- a/bootloaders/optiboot/optiboot_diecimila.lst +++ /dev/null @@ -1,520 +0,0 @@ - -optiboot_diecimila.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001ec 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000240 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000268 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000269 00000000 00000000 000002d2 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000196 00000000 00000000 0000053b 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003d3 00000000 00000000 000006d1 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000aa4 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000135 00000000 00000000 00000b34 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001d1 00000000 00000000 00000c69 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e3a 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 -#if LED_START_FLASHES > 0 - // Set up Timer 1 for timeout counter - TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 -#endif -#ifndef SOFT_UART - UCSR0A = _BV(U2X0); //Double speed mode USART0 - 3e06: 82 e0 ldi r24, 0x02 ; 2 - 3e08: 80 93 c0 00 sts 0x00C0, r24 - UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e0c: 88 e1 ldi r24, 0x18 ; 24 - 3e0e: 80 93 c1 00 sts 0x00C1, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e12: 86 e0 ldi r24, 0x06 ; 6 - 3e14: 80 93 c2 00 sts 0x00C2, r24 - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 3e18: 80 e1 ldi r24, 0x10 ; 16 - 3e1a: 80 93 c4 00 sts 0x00C4, r24 -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e1e: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e20: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e22: 81 ff sbrs r24, 1 - 3e24: d0 d0 rcall .+416 ; 0x3fc6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e26: 8d e0 ldi r24, 0x0D ; 13 - 3e28: c8 d0 rcall .+400 ; 0x3fba <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e2e: 20 e3 ldi r18, 0x30 ; 48 - 3e30: 3c ef ldi r19, 0xFC ; 252 - TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> - LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e44: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e56: a4 d0 rcall .+328 ; 0x3fa0 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: be d0 rcall .+380 ; 0x3fdc <verifySpace+0xc> - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 24 c0 rjmp .+72 ; 0x3eac <main+0xac> - } - else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> - // SET DEVICE is ignored - getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> - // SET DEVICE EXT is ignored - getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: b4 d0 rcall .+360 ; 0x3fdc <verifySpace+0xc> - 3e74: 8a c0 rjmp .+276 ; 0x3f8a <main+0x18a> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: a1 f4 brne .+40 ; 0x3ea2 <main+0xa2> - // LOAD ADDRESS - address = getch(); - 3e7a: 92 d0 rcall .+292 ; 0x3fa0 <getch> - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 10 93 01 02 sts 0x0201, r17 - 3e84: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e88: 8b d0 rcall .+278 ; 0x3fa0 <getch> - 3e8a: 90 e0 ldi r25, 0x00 ; 0 - 3e8c: 98 2f mov r25, r24 - 3e8e: 88 27 eor r24, r24 - 3e90: 80 2b or r24, r16 - 3e92: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e94: 88 0f add r24, r24 - 3e96: 99 1f adc r25, r25 - 3e98: 90 93 01 02 sts 0x0201, r25 - 3e9c: 80 93 00 02 sts 0x0200, r24 - 3ea0: 73 c0 rjmp .+230 ; 0x3f88 <main+0x188> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3ea2: 86 35 cpi r24, 0x56 ; 86 - 3ea4: 29 f4 brne .+10 ; 0x3eb0 <main+0xb0> - // UNIVERSAL command is ignored - getNch(4); - 3ea6: 84 e0 ldi r24, 0x04 ; 4 - 3ea8: 99 d0 rcall .+306 ; 0x3fdc <verifySpace+0xc> - putch(0x00); - 3eaa: 80 e0 ldi r24, 0x00 ; 0 - 3eac: 71 d0 rcall .+226 ; 0x3f90 <putch> - 3eae: 6d c0 rjmp .+218 ; 0x3f8a <main+0x18a> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3eb0: 84 36 cpi r24, 0x64 ; 100 - 3eb2: 09 f0 breq .+2 ; 0x3eb6 <main+0xb6> - 3eb4: 43 c0 rjmp .+134 ; 0x3f3c <main+0x13c> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3eb6: 7c d0 rcall .+248 ; 0x3fb0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3eb8: e0 91 00 02 lds r30, 0x0200 - 3ebc: f0 91 01 02 lds r31, 0x0201 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 80 93 57 00 sts 0x0057, r24 - 3ec6: e8 95 spm - 3ec8: c0 e0 ldi r28, 0x00 ; 0 - 3eca: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3ecc: 69 d0 rcall .+210 ; 0x3fa0 <getch> - 3ece: 89 93 st Y+, r24 - while (--length); - 3ed0: 80 91 02 02 lds r24, 0x0202 - 3ed4: 81 50 subi r24, 0x01 ; 1 - 3ed6: 80 93 02 02 sts 0x0202, r24 - 3eda: 88 23 and r24, r24 - 3edc: b9 f7 brne .-18 ; 0x3ecc <main+0xcc> - - // Read command terminator, start reply - verifySpace(); - 3ede: 78 d0 rcall .+240 ; 0x3fd0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3ee0: 07 b6 in r0, 0x37 ; 55 - 3ee2: 00 fc sbrc r0, 0 - 3ee4: fd cf rjmp .-6 ; 0x3ee0 <main+0xe0> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ee6: 40 91 00 02 lds r20, 0x0200 - 3eea: 50 91 01 02 lds r21, 0x0201 - 3eee: a0 e0 ldi r26, 0x00 ; 0 - 3ef0: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3ef2: 2c 91 ld r18, X - 3ef4: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ef6: 11 96 adiw r26, 0x01 ; 1 - 3ef8: 8c 91 ld r24, X - 3efa: 11 97 sbiw r26, 0x01 ; 1 - 3efc: 90 e0 ldi r25, 0x00 ; 0 - 3efe: 98 2f mov r25, r24 - 3f00: 88 27 eor r24, r24 - 3f02: 82 2b or r24, r18 - 3f04: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3f06: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3f08: fa 01 movw r30, r20 - 3f0a: 0c 01 movw r0, r24 - 3f0c: d0 92 57 00 sts 0x0057, r13 - 3f10: e8 95 spm - 3f12: 11 24 eor r1, r1 - addrPtr += 2; - 3f14: 4e 5f subi r20, 0xFE ; 254 - 3f16: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f18: f1 e0 ldi r31, 0x01 ; 1 - 3f1a: a0 38 cpi r26, 0x80 ; 128 - 3f1c: bf 07 cpc r27, r31 - 3f1e: 49 f7 brne .-46 ; 0x3ef2 <main+0xf2> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f20: e0 91 00 02 lds r30, 0x0200 - 3f24: f0 91 01 02 lds r31, 0x0201 - 3f28: e0 92 57 00 sts 0x0057, r14 - 3f2c: e8 95 spm - boot_spm_busy_wait(); - 3f2e: 07 b6 in r0, 0x37 ; 55 - 3f30: 00 fc sbrc r0, 0 - 3f32: fd cf rjmp .-6 ; 0x3f2e <main+0x12e> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f34: f0 92 57 00 sts 0x0057, r15 - 3f38: e8 95 spm - 3f3a: 27 c0 rjmp .+78 ; 0x3f8a <main+0x18a> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f3c: 84 37 cpi r24, 0x74 ; 116 - 3f3e: b9 f4 brne .+46 ; 0x3f6e <main+0x16e> - // READ PAGE - we only read flash - getLen(); - 3f40: 37 d0 rcall .+110 ; 0x3fb0 <getLen> - verifySpace(); - 3f42: 46 d0 rcall .+140 ; 0x3fd0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f44: e0 91 00 02 lds r30, 0x0200 - 3f48: f0 91 01 02 lds r31, 0x0201 - 3f4c: 31 96 adiw r30, 0x01 ; 1 - 3f4e: f0 93 01 02 sts 0x0201, r31 - 3f52: e0 93 00 02 sts 0x0200, r30 - 3f56: 31 97 sbiw r30, 0x01 ; 1 - 3f58: e4 91 lpm r30, Z+ - 3f5a: 8e 2f mov r24, r30 - 3f5c: 19 d0 rcall .+50 ; 0x3f90 <putch> - while (--length); - 3f5e: 80 91 02 02 lds r24, 0x0202 - 3f62: 81 50 subi r24, 0x01 ; 1 - 3f64: 80 93 02 02 sts 0x0202, r24 - 3f68: 88 23 and r24, r24 - 3f6a: 61 f7 brne .-40 ; 0x3f44 <main+0x144> - 3f6c: 0e c0 rjmp .+28 ; 0x3f8a <main+0x18a> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f6e: 85 37 cpi r24, 0x75 ; 117 - 3f70: 39 f4 brne .+14 ; 0x3f80 <main+0x180> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f72: 2e d0 rcall .+92 ; 0x3fd0 <verifySpace> - putch(SIGNATURE_0); - 3f74: 8e e1 ldi r24, 0x1E ; 30 - 3f76: 0c d0 rcall .+24 ; 0x3f90 <putch> - putch(SIGNATURE_1); - 3f78: 84 e9 ldi r24, 0x94 ; 148 - 3f7a: 0a d0 rcall .+20 ; 0x3f90 <putch> - putch(SIGNATURE_2); - 3f7c: 86 e0 ldi r24, 0x06 ; 6 - 3f7e: 96 cf rjmp .-212 ; 0x3eac <main+0xac> - } - else if (ch == 'Q') { - 3f80: 81 35 cpi r24, 0x51 ; 81 - 3f82: 11 f4 brne .+4 ; 0x3f88 <main+0x188> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f84: 88 e0 ldi r24, 0x08 ; 8 - 3f86: 19 d0 rcall .+50 ; 0x3fba <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f88: 23 d0 rcall .+70 ; 0x3fd0 <verifySpace> - } - putch(STK_OK); - 3f8a: 80 e1 ldi r24, 0x10 ; 16 - 3f8c: 01 d0 rcall .+2 ; 0x3f90 <putch> - 3f8e: 63 cf rjmp .-314 ; 0x3e56 <main+0x56> - -00003f90 <putch>: - } -} - -void putch(char ch) { - 3f90: 98 2f mov r25, r24 -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - 3f92: 80 91 c0 00 lds r24, 0x00C0 - 3f96: 85 ff sbrs r24, 5 - 3f98: fc cf rjmp .-8 ; 0x3f92 <putch+0x2> - UDR0 = ch; - 3f9a: 90 93 c6 00 sts 0x00C6, r25 - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f9e: 08 95 ret - -00003fa0 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fa0: a8 95 wdr - [uartBit] "I" (UART_RX_BIT) - : - "r25" -); -#else - while(!(UCSR0A & _BV(RXC0))); - 3fa2: 80 91 c0 00 lds r24, 0x00C0 - 3fa6: 87 ff sbrs r24, 7 - 3fa8: fc cf rjmp .-8 ; 0x3fa2 <getch+0x2> - ch = UDR0; - 3faa: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3fae: 08 95 ret - -00003fb0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fb0: f7 df rcall .-18 ; 0x3fa0 <getch> - length = getch(); - 3fb2: f6 df rcall .-20 ; 0x3fa0 <getch> - 3fb4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fb8: f3 cf rjmp .-26 ; 0x3fa0 <getch> - -00003fba <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fba: e0 e6 ldi r30, 0x60 ; 96 - 3fbc: f0 e0 ldi r31, 0x00 ; 0 - 3fbe: 98 e1 ldi r25, 0x18 ; 24 - 3fc0: 90 83 st Z, r25 - WDTCSR = x; - 3fc2: 80 83 st Z, r24 -} - 3fc4: 08 95 ret - -00003fc6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fc6: 80 e0 ldi r24, 0x00 ; 0 - 3fc8: f8 df rcall .-16 ; 0x3fba <watchdogConfig> - __asm__ __volatile__ ( - 3fca: ee 27 eor r30, r30 - 3fcc: ff 27 eor r31, r31 - 3fce: 09 94 ijmp - -00003fd0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fd0: e7 df rcall .-50 ; 0x3fa0 <getch> - 3fd2: 80 32 cpi r24, 0x20 ; 32 - 3fd4: 09 f0 breq .+2 ; 0x3fd8 <verifySpace+0x8> - 3fd6: f7 df rcall .-18 ; 0x3fc6 <appStart> - putch(STK_INSYNC); - 3fd8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fda: da cf rjmp .-76 ; 0x3f90 <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fdc: 1f 93 push r17 - 3fde: 18 2f mov r17, r24 - -00003fe0 <getNch>: - do getch(); while (--count); - 3fe0: df df rcall .-66 ; 0x3fa0 <getch> - 3fe2: 11 50 subi r17, 0x01 ; 1 - 3fe4: e9 f7 brne .-6 ; 0x3fe0 <getNch> - verifySpace(); - 3fe6: f4 df rcall .-24 ; 0x3fd0 <verifySpace> -} - 3fe8: 1f 91 pop r17 - 3fea: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_lilypad.hex b/bootloaders/optiboot/optiboot_lilypad.hex deleted file mode 100644 index 9d31a7a..0000000 --- a/bootloaders/optiboot/optiboot_lilypad.hex +++ /dev/null @@ -1,34 +0,0 @@ -:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E028E13EEF91E030937C
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF089598E09A95F1F7089555
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_lilypad.lst b/bootloaders/optiboot/optiboot_lilypad.lst deleted file mode 100644 index 0e46bd1..0000000 --- a/bootloaders/optiboot/optiboot_lilypad.lst +++ /dev/null @@ -1,533 +0,0 @@ - -optiboot_lilypad.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001fc 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000250 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 00000078 00000000 00000000 00000278 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000277 00000000 00000000 000002f0 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000194 00000000 00000000 00000567 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003bb 00000000 00000000 000006fb 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 000000a0 00000000 00000000 00000ab8 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 0000013f 00000000 00000000 00000b58 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001a0 00000000 00000000 00000c97 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000070 00000000 00000000 00000e37 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e06: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e08: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e0a: 81 ff sbrs r24, 1 - 3e0c: e4 d0 rcall .+456 ; 0x3fd6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e0e: 8d e0 ldi r24, 0x0D ; 13 - 3e10: dc d0 rcall .+440 ; 0x3fca <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e12: 25 9a sbi 0x04, 5 ; 4 - -#ifdef SOFT_UART - /* Set TX pin as output */ - UART_DDR |= _BV(UART_TX_BIT); - 3e14: 51 9a sbi 0x0a, 1 ; 10 - 3e16: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e18: 28 e1 ldi r18, 0x18 ; 24 - 3e1a: 3e ef ldi r19, 0xFE ; 254 - TIFR1 = _BV(TOV1); - 3e1c: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e1e: 30 93 85 00 sts 0x0085, r19 - 3e22: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e26: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e28: b0 9b sbis 0x16, 0 ; 22 - 3e2a: fe cf rjmp .-4 ; 0x3e28 <main+0x28> - LED_PIN |= _BV(LED); - 3e2c: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e2e: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e30: 81 50 subi r24, 0x01 ; 1 - 3e32: a9 f7 brne .-22 ; 0x3e1e <main+0x1e> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e34: dd 24 eor r13, r13 - 3e36: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e38: a5 e0 ldi r26, 0x05 ; 5 - 3e3a: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e3c: f1 e1 ldi r31, 0x11 ; 17 - 3e3e: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e40: ab d0 rcall .+342 ; 0x3f98 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e42: 81 34 cpi r24, 0x41 ; 65 - 3e44: 21 f4 brne .+8 ; 0x3e4e <main+0x4e> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e46: 81 e0 ldi r24, 0x01 ; 1 - 3e48: d1 d0 rcall .+418 ; 0x3fec <verifySpace+0xc> - putch(0x03); - 3e4a: 83 e0 ldi r24, 0x03 ; 3 - 3e4c: 24 c0 rjmp .+72 ; 0x3e96 <main+0x96> - } - else if(ch == STK_SET_DEVICE) { - 3e4e: 82 34 cpi r24, 0x42 ; 66 - 3e50: 11 f4 brne .+4 ; 0x3e56 <main+0x56> - // SET DEVICE is ignored - getNch(20); - 3e52: 84 e1 ldi r24, 0x14 ; 20 - 3e54: 03 c0 rjmp .+6 ; 0x3e5c <main+0x5c> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e56: 85 34 cpi r24, 0x45 ; 69 - 3e58: 19 f4 brne .+6 ; 0x3e60 <main+0x60> - // SET DEVICE EXT is ignored - getNch(5); - 3e5a: 85 e0 ldi r24, 0x05 ; 5 - 3e5c: c7 d0 rcall .+398 ; 0x3fec <verifySpace+0xc> - 3e5e: 8a c0 rjmp .+276 ; 0x3f74 <main+0x174> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e60: 85 35 cpi r24, 0x55 ; 85 - 3e62: a1 f4 brne .+40 ; 0x3e8c <main+0x8c> - // LOAD ADDRESS - address = getch(); - 3e64: 99 d0 rcall .+306 ; 0x3f98 <getch> - 3e66: 08 2f mov r16, r24 - 3e68: 10 e0 ldi r17, 0x00 ; 0 - 3e6a: 10 93 01 02 sts 0x0201, r17 - 3e6e: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e72: 92 d0 rcall .+292 ; 0x3f98 <getch> - 3e74: 90 e0 ldi r25, 0x00 ; 0 - 3e76: 98 2f mov r25, r24 - 3e78: 88 27 eor r24, r24 - 3e7a: 80 2b or r24, r16 - 3e7c: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e7e: 88 0f add r24, r24 - 3e80: 99 1f adc r25, r25 - 3e82: 90 93 01 02 sts 0x0201, r25 - 3e86: 80 93 00 02 sts 0x0200, r24 - 3e8a: 73 c0 rjmp .+230 ; 0x3f72 <main+0x172> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3e8c: 86 35 cpi r24, 0x56 ; 86 - 3e8e: 29 f4 brne .+10 ; 0x3e9a <main+0x9a> - // UNIVERSAL command is ignored - getNch(4); - 3e90: 84 e0 ldi r24, 0x04 ; 4 - 3e92: ac d0 rcall .+344 ; 0x3fec <verifySpace+0xc> - putch(0x00); - 3e94: 80 e0 ldi r24, 0x00 ; 0 - 3e96: 71 d0 rcall .+226 ; 0x3f7a <putch> - 3e98: 6d c0 rjmp .+218 ; 0x3f74 <main+0x174> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3e9a: 84 36 cpi r24, 0x64 ; 100 - 3e9c: 09 f0 breq .+2 ; 0x3ea0 <main+0xa0> - 3e9e: 43 c0 rjmp .+134 ; 0x3f26 <main+0x126> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3ea0: 8f d0 rcall .+286 ; 0x3fc0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3ea2: e0 91 00 02 lds r30, 0x0200 - 3ea6: f0 91 01 02 lds r31, 0x0201 - 3eaa: 83 e0 ldi r24, 0x03 ; 3 - 3eac: 80 93 57 00 sts 0x0057, r24 - 3eb0: e8 95 spm - 3eb2: c0 e0 ldi r28, 0x00 ; 0 - 3eb4: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3eb6: 70 d0 rcall .+224 ; 0x3f98 <getch> - 3eb8: 89 93 st Y+, r24 - while (--length); - 3eba: 80 91 02 02 lds r24, 0x0202 - 3ebe: 81 50 subi r24, 0x01 ; 1 - 3ec0: 80 93 02 02 sts 0x0202, r24 - 3ec4: 88 23 and r24, r24 - 3ec6: b9 f7 brne .-18 ; 0x3eb6 <main+0xb6> - - // Read command terminator, start reply - verifySpace(); - 3ec8: 8b d0 rcall .+278 ; 0x3fe0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3eca: 07 b6 in r0, 0x37 ; 55 - 3ecc: 00 fc sbrc r0, 0 - 3ece: fd cf rjmp .-6 ; 0x3eca <main+0xca> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ed0: 40 91 00 02 lds r20, 0x0200 - 3ed4: 50 91 01 02 lds r21, 0x0201 - 3ed8: a0 e0 ldi r26, 0x00 ; 0 - 3eda: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3edc: 2c 91 ld r18, X - 3ede: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ee0: 11 96 adiw r26, 0x01 ; 1 - 3ee2: 8c 91 ld r24, X - 3ee4: 11 97 sbiw r26, 0x01 ; 1 - 3ee6: 90 e0 ldi r25, 0x00 ; 0 - 3ee8: 98 2f mov r25, r24 - 3eea: 88 27 eor r24, r24 - 3eec: 82 2b or r24, r18 - 3eee: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3ef0: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3ef2: fa 01 movw r30, r20 - 3ef4: 0c 01 movw r0, r24 - 3ef6: d0 92 57 00 sts 0x0057, r13 - 3efa: e8 95 spm - 3efc: 11 24 eor r1, r1 - addrPtr += 2; - 3efe: 4e 5f subi r20, 0xFE ; 254 - 3f00: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f02: f1 e0 ldi r31, 0x01 ; 1 - 3f04: a0 38 cpi r26, 0x80 ; 128 - 3f06: bf 07 cpc r27, r31 - 3f08: 49 f7 brne .-46 ; 0x3edc <main+0xdc> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f0a: e0 91 00 02 lds r30, 0x0200 - 3f0e: f0 91 01 02 lds r31, 0x0201 - 3f12: e0 92 57 00 sts 0x0057, r14 - 3f16: e8 95 spm - boot_spm_busy_wait(); - 3f18: 07 b6 in r0, 0x37 ; 55 - 3f1a: 00 fc sbrc r0, 0 - 3f1c: fd cf rjmp .-6 ; 0x3f18 <main+0x118> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f1e: f0 92 57 00 sts 0x0057, r15 - 3f22: e8 95 spm - 3f24: 27 c0 rjmp .+78 ; 0x3f74 <main+0x174> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f26: 84 37 cpi r24, 0x74 ; 116 - 3f28: b9 f4 brne .+46 ; 0x3f58 <main+0x158> - // READ PAGE - we only read flash - getLen(); - 3f2a: 4a d0 rcall .+148 ; 0x3fc0 <getLen> - verifySpace(); - 3f2c: 59 d0 rcall .+178 ; 0x3fe0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f2e: e0 91 00 02 lds r30, 0x0200 - 3f32: f0 91 01 02 lds r31, 0x0201 - 3f36: 31 96 adiw r30, 0x01 ; 1 - 3f38: f0 93 01 02 sts 0x0201, r31 - 3f3c: e0 93 00 02 sts 0x0200, r30 - 3f40: 31 97 sbiw r30, 0x01 ; 1 - 3f42: e4 91 lpm r30, Z+ - 3f44: 8e 2f mov r24, r30 - 3f46: 19 d0 rcall .+50 ; 0x3f7a <putch> - while (--length); - 3f48: 80 91 02 02 lds r24, 0x0202 - 3f4c: 81 50 subi r24, 0x01 ; 1 - 3f4e: 80 93 02 02 sts 0x0202, r24 - 3f52: 88 23 and r24, r24 - 3f54: 61 f7 brne .-40 ; 0x3f2e <main+0x12e> - 3f56: 0e c0 rjmp .+28 ; 0x3f74 <main+0x174> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f58: 85 37 cpi r24, 0x75 ; 117 - 3f5a: 39 f4 brne .+14 ; 0x3f6a <main+0x16a> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f5c: 41 d0 rcall .+130 ; 0x3fe0 <verifySpace> - putch(SIGNATURE_0); - 3f5e: 8e e1 ldi r24, 0x1E ; 30 - 3f60: 0c d0 rcall .+24 ; 0x3f7a <putch> - putch(SIGNATURE_1); - 3f62: 84 e9 ldi r24, 0x94 ; 148 - 3f64: 0a d0 rcall .+20 ; 0x3f7a <putch> - putch(SIGNATURE_2); - 3f66: 86 e0 ldi r24, 0x06 ; 6 - 3f68: 96 cf rjmp .-212 ; 0x3e96 <main+0x96> - } - else if (ch == 'Q') { - 3f6a: 81 35 cpi r24, 0x51 ; 81 - 3f6c: 11 f4 brne .+4 ; 0x3f72 <main+0x172> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f6e: 88 e0 ldi r24, 0x08 ; 8 - 3f70: 2c d0 rcall .+88 ; 0x3fca <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f72: 36 d0 rcall .+108 ; 0x3fe0 <verifySpace> - } - putch(STK_OK); - 3f74: 80 e1 ldi r24, 0x10 ; 16 - 3f76: 01 d0 rcall .+2 ; 0x3f7a <putch> - 3f78: 63 cf rjmp .-314 ; 0x3e40 <main+0x40> - -00003f7a <putch>: -void putch(char ch) { -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - UDR0 = ch; -#else - __asm__ __volatile__ ( - 3f7a: 2a e0 ldi r18, 0x0A ; 10 - 3f7c: 30 e0 ldi r19, 0x00 ; 0 - 3f7e: 80 95 com r24 - 3f80: 08 94 sec - 3f82: 10 f4 brcc .+4 ; 0x3f88 <putch+0xe> - 3f84: 59 98 cbi 0x0b, 1 ; 11 - 3f86: 02 c0 rjmp .+4 ; 0x3f8c <putch+0x12> - 3f88: 59 9a sbi 0x0b, 1 ; 11 - 3f8a: 00 00 nop - 3f8c: 15 d0 rcall .+42 ; 0x3fb8 <uartDelay> - 3f8e: 14 d0 rcall .+40 ; 0x3fb8 <uartDelay> - 3f90: 86 95 lsr r24 - 3f92: 2a 95 dec r18 - 3f94: b1 f7 brne .-20 ; 0x3f82 <putch+0x8> - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f96: 08 95 ret - -00003f98 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3f98: a8 95 wdr -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3f9a: 29 e0 ldi r18, 0x09 ; 9 - 3f9c: 30 e0 ldi r19, 0x00 ; 0 - 3f9e: 48 99 sbic 0x09, 0 ; 9 - 3fa0: fe cf rjmp .-4 ; 0x3f9e <getch+0x6> - 3fa2: 0a d0 rcall .+20 ; 0x3fb8 <uartDelay> - 3fa4: 09 d0 rcall .+18 ; 0x3fb8 <uartDelay> - 3fa6: 08 d0 rcall .+16 ; 0x3fb8 <uartDelay> - 3fa8: 88 94 clc - 3faa: 48 99 sbic 0x09, 0 ; 9 - 3fac: 08 94 sec - 3fae: 2a 95 dec r18 - 3fb0: 11 f0 breq .+4 ; 0x3fb6 <getch+0x1e> - 3fb2: 87 95 ror r24 - 3fb4: f7 cf rjmp .-18 ; 0x3fa4 <getch+0xc> - 3fb6: 08 95 ret - -00003fb8 <uartDelay>: -#if UART_B_VALUE > 255 -#error Baud rate too slow for soft UART -#endif - -void uartDelay() { - __asm__ __volatile__ ( - 3fb8: 98 e0 ldi r25, 0x08 ; 8 - 3fba: 9a 95 dec r25 - 3fbc: f1 f7 brne .-4 ; 0x3fba <uartDelay+0x2> - 3fbe: 08 95 ret - -00003fc0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fc0: eb df rcall .-42 ; 0x3f98 <getch> - length = getch(); - 3fc2: ea df rcall .-44 ; 0x3f98 <getch> - 3fc4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc8: e7 cf rjmp .-50 ; 0x3f98 <getch> - -00003fca <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fca: e0 e6 ldi r30, 0x60 ; 96 - 3fcc: f0 e0 ldi r31, 0x00 ; 0 - 3fce: 98 e1 ldi r25, 0x18 ; 24 - 3fd0: 90 83 st Z, r25 - WDTCSR = x; - 3fd2: 80 83 st Z, r24 -} - 3fd4: 08 95 ret - -00003fd6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd6: 80 e0 ldi r24, 0x00 ; 0 - 3fd8: f8 df rcall .-16 ; 0x3fca <watchdogConfig> - __asm__ __volatile__ ( - 3fda: ee 27 eor r30, r30 - 3fdc: ff 27 eor r31, r31 - 3fde: 09 94 ijmp - -00003fe0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fe0: db df rcall .-74 ; 0x3f98 <getch> - 3fe2: 80 32 cpi r24, 0x20 ; 32 - 3fe4: 09 f0 breq .+2 ; 0x3fe8 <verifySpace+0x8> - 3fe6: f7 df rcall .-18 ; 0x3fd6 <appStart> - putch(STK_INSYNC); - 3fe8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fea: c7 cf rjmp .-114 ; 0x3f7a <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fec: 1f 93 push r17 - 3fee: 18 2f mov r17, r24 - -00003ff0 <getNch>: - do getch(); while (--count); - 3ff0: d3 df rcall .-90 ; 0x3f98 <getch> - 3ff2: 11 50 subi r17, 0x01 ; 1 - 3ff4: e9 f7 brne .-6 ; 0x3ff0 <getNch> - verifySpace(); - 3ff6: f4 df rcall .-24 ; 0x3fe0 <verifySpace> -} - 3ff8: 1f 91 pop r17 - 3ffa: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_lilypad_resonator.hex b/bootloaders/optiboot/optiboot_lilypad_resonator.hex deleted file mode 100644 index 9d31a7a..0000000 --- a/bootloaders/optiboot/optiboot_lilypad_resonator.hex +++ /dev/null @@ -1,34 +0,0 @@ -:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E028E13EEF91E030937C
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF089598E09A95F1F7089555
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_lilypad_resonator.lst b/bootloaders/optiboot/optiboot_lilypad_resonator.lst deleted file mode 100644 index 80ecb83..0000000 --- a/bootloaders/optiboot/optiboot_lilypad_resonator.lst +++ /dev/null @@ -1,533 +0,0 @@ - -optiboot_lilypad_resonator.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001fc 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000250 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 00000078 00000000 00000000 00000278 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000277 00000000 00000000 000002f0 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000194 00000000 00000000 00000567 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003bb 00000000 00000000 000006fb 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 000000a0 00000000 00000000 00000ab8 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 0000013f 00000000 00000000 00000b58 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001a0 00000000 00000000 00000c97 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000070 00000000 00000000 00000e37 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e06: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e08: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e0a: 81 ff sbrs r24, 1 - 3e0c: e4 d0 rcall .+456 ; 0x3fd6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e0e: 8d e0 ldi r24, 0x0D ; 13 - 3e10: dc d0 rcall .+440 ; 0x3fca <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e12: 25 9a sbi 0x04, 5 ; 4 - -#ifdef SOFT_UART - /* Set TX pin as output */ - UART_DDR |= _BV(UART_TX_BIT); - 3e14: 51 9a sbi 0x0a, 1 ; 10 - 3e16: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e18: 28 e1 ldi r18, 0x18 ; 24 - 3e1a: 3e ef ldi r19, 0xFE ; 254 - TIFR1 = _BV(TOV1); - 3e1c: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e1e: 30 93 85 00 sts 0x0085, r19 - 3e22: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e26: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e28: b0 9b sbis 0x16, 0 ; 22 - 3e2a: fe cf rjmp .-4 ; 0x3e28 <main+0x28> - LED_PIN |= _BV(LED); - 3e2c: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e2e: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e30: 81 50 subi r24, 0x01 ; 1 - 3e32: a9 f7 brne .-22 ; 0x3e1e <main+0x1e> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e34: dd 24 eor r13, r13 - 3e36: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e38: a5 e0 ldi r26, 0x05 ; 5 - 3e3a: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e3c: f1 e1 ldi r31, 0x11 ; 17 - 3e3e: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e40: ab d0 rcall .+342 ; 0x3f98 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e42: 81 34 cpi r24, 0x41 ; 65 - 3e44: 21 f4 brne .+8 ; 0x3e4e <main+0x4e> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e46: 81 e0 ldi r24, 0x01 ; 1 - 3e48: d1 d0 rcall .+418 ; 0x3fec <verifySpace+0xc> - putch(0x03); - 3e4a: 83 e0 ldi r24, 0x03 ; 3 - 3e4c: 24 c0 rjmp .+72 ; 0x3e96 <main+0x96> - } - else if(ch == STK_SET_DEVICE) { - 3e4e: 82 34 cpi r24, 0x42 ; 66 - 3e50: 11 f4 brne .+4 ; 0x3e56 <main+0x56> - // SET DEVICE is ignored - getNch(20); - 3e52: 84 e1 ldi r24, 0x14 ; 20 - 3e54: 03 c0 rjmp .+6 ; 0x3e5c <main+0x5c> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e56: 85 34 cpi r24, 0x45 ; 69 - 3e58: 19 f4 brne .+6 ; 0x3e60 <main+0x60> - // SET DEVICE EXT is ignored - getNch(5); - 3e5a: 85 e0 ldi r24, 0x05 ; 5 - 3e5c: c7 d0 rcall .+398 ; 0x3fec <verifySpace+0xc> - 3e5e: 8a c0 rjmp .+276 ; 0x3f74 <main+0x174> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e60: 85 35 cpi r24, 0x55 ; 85 - 3e62: a1 f4 brne .+40 ; 0x3e8c <main+0x8c> - // LOAD ADDRESS - address = getch(); - 3e64: 99 d0 rcall .+306 ; 0x3f98 <getch> - 3e66: 08 2f mov r16, r24 - 3e68: 10 e0 ldi r17, 0x00 ; 0 - 3e6a: 10 93 01 02 sts 0x0201, r17 - 3e6e: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e72: 92 d0 rcall .+292 ; 0x3f98 <getch> - 3e74: 90 e0 ldi r25, 0x00 ; 0 - 3e76: 98 2f mov r25, r24 - 3e78: 88 27 eor r24, r24 - 3e7a: 80 2b or r24, r16 - 3e7c: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e7e: 88 0f add r24, r24 - 3e80: 99 1f adc r25, r25 - 3e82: 90 93 01 02 sts 0x0201, r25 - 3e86: 80 93 00 02 sts 0x0200, r24 - 3e8a: 73 c0 rjmp .+230 ; 0x3f72 <main+0x172> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3e8c: 86 35 cpi r24, 0x56 ; 86 - 3e8e: 29 f4 brne .+10 ; 0x3e9a <main+0x9a> - // UNIVERSAL command is ignored - getNch(4); - 3e90: 84 e0 ldi r24, 0x04 ; 4 - 3e92: ac d0 rcall .+344 ; 0x3fec <verifySpace+0xc> - putch(0x00); - 3e94: 80 e0 ldi r24, 0x00 ; 0 - 3e96: 71 d0 rcall .+226 ; 0x3f7a <putch> - 3e98: 6d c0 rjmp .+218 ; 0x3f74 <main+0x174> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3e9a: 84 36 cpi r24, 0x64 ; 100 - 3e9c: 09 f0 breq .+2 ; 0x3ea0 <main+0xa0> - 3e9e: 43 c0 rjmp .+134 ; 0x3f26 <main+0x126> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3ea0: 8f d0 rcall .+286 ; 0x3fc0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3ea2: e0 91 00 02 lds r30, 0x0200 - 3ea6: f0 91 01 02 lds r31, 0x0201 - 3eaa: 83 e0 ldi r24, 0x03 ; 3 - 3eac: 80 93 57 00 sts 0x0057, r24 - 3eb0: e8 95 spm - 3eb2: c0 e0 ldi r28, 0x00 ; 0 - 3eb4: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3eb6: 70 d0 rcall .+224 ; 0x3f98 <getch> - 3eb8: 89 93 st Y+, r24 - while (--length); - 3eba: 80 91 02 02 lds r24, 0x0202 - 3ebe: 81 50 subi r24, 0x01 ; 1 - 3ec0: 80 93 02 02 sts 0x0202, r24 - 3ec4: 88 23 and r24, r24 - 3ec6: b9 f7 brne .-18 ; 0x3eb6 <main+0xb6> - - // Read command terminator, start reply - verifySpace(); - 3ec8: 8b d0 rcall .+278 ; 0x3fe0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3eca: 07 b6 in r0, 0x37 ; 55 - 3ecc: 00 fc sbrc r0, 0 - 3ece: fd cf rjmp .-6 ; 0x3eca <main+0xca> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ed0: 40 91 00 02 lds r20, 0x0200 - 3ed4: 50 91 01 02 lds r21, 0x0201 - 3ed8: a0 e0 ldi r26, 0x00 ; 0 - 3eda: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3edc: 2c 91 ld r18, X - 3ede: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ee0: 11 96 adiw r26, 0x01 ; 1 - 3ee2: 8c 91 ld r24, X - 3ee4: 11 97 sbiw r26, 0x01 ; 1 - 3ee6: 90 e0 ldi r25, 0x00 ; 0 - 3ee8: 98 2f mov r25, r24 - 3eea: 88 27 eor r24, r24 - 3eec: 82 2b or r24, r18 - 3eee: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3ef0: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3ef2: fa 01 movw r30, r20 - 3ef4: 0c 01 movw r0, r24 - 3ef6: d0 92 57 00 sts 0x0057, r13 - 3efa: e8 95 spm - 3efc: 11 24 eor r1, r1 - addrPtr += 2; - 3efe: 4e 5f subi r20, 0xFE ; 254 - 3f00: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f02: f1 e0 ldi r31, 0x01 ; 1 - 3f04: a0 38 cpi r26, 0x80 ; 128 - 3f06: bf 07 cpc r27, r31 - 3f08: 49 f7 brne .-46 ; 0x3edc <main+0xdc> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f0a: e0 91 00 02 lds r30, 0x0200 - 3f0e: f0 91 01 02 lds r31, 0x0201 - 3f12: e0 92 57 00 sts 0x0057, r14 - 3f16: e8 95 spm - boot_spm_busy_wait(); - 3f18: 07 b6 in r0, 0x37 ; 55 - 3f1a: 00 fc sbrc r0, 0 - 3f1c: fd cf rjmp .-6 ; 0x3f18 <main+0x118> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f1e: f0 92 57 00 sts 0x0057, r15 - 3f22: e8 95 spm - 3f24: 27 c0 rjmp .+78 ; 0x3f74 <main+0x174> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f26: 84 37 cpi r24, 0x74 ; 116 - 3f28: b9 f4 brne .+46 ; 0x3f58 <main+0x158> - // READ PAGE - we only read flash - getLen(); - 3f2a: 4a d0 rcall .+148 ; 0x3fc0 <getLen> - verifySpace(); - 3f2c: 59 d0 rcall .+178 ; 0x3fe0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f2e: e0 91 00 02 lds r30, 0x0200 - 3f32: f0 91 01 02 lds r31, 0x0201 - 3f36: 31 96 adiw r30, 0x01 ; 1 - 3f38: f0 93 01 02 sts 0x0201, r31 - 3f3c: e0 93 00 02 sts 0x0200, r30 - 3f40: 31 97 sbiw r30, 0x01 ; 1 - 3f42: e4 91 lpm r30, Z+ - 3f44: 8e 2f mov r24, r30 - 3f46: 19 d0 rcall .+50 ; 0x3f7a <putch> - while (--length); - 3f48: 80 91 02 02 lds r24, 0x0202 - 3f4c: 81 50 subi r24, 0x01 ; 1 - 3f4e: 80 93 02 02 sts 0x0202, r24 - 3f52: 88 23 and r24, r24 - 3f54: 61 f7 brne .-40 ; 0x3f2e <main+0x12e> - 3f56: 0e c0 rjmp .+28 ; 0x3f74 <main+0x174> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f58: 85 37 cpi r24, 0x75 ; 117 - 3f5a: 39 f4 brne .+14 ; 0x3f6a <main+0x16a> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f5c: 41 d0 rcall .+130 ; 0x3fe0 <verifySpace> - putch(SIGNATURE_0); - 3f5e: 8e e1 ldi r24, 0x1E ; 30 - 3f60: 0c d0 rcall .+24 ; 0x3f7a <putch> - putch(SIGNATURE_1); - 3f62: 84 e9 ldi r24, 0x94 ; 148 - 3f64: 0a d0 rcall .+20 ; 0x3f7a <putch> - putch(SIGNATURE_2); - 3f66: 86 e0 ldi r24, 0x06 ; 6 - 3f68: 96 cf rjmp .-212 ; 0x3e96 <main+0x96> - } - else if (ch == 'Q') { - 3f6a: 81 35 cpi r24, 0x51 ; 81 - 3f6c: 11 f4 brne .+4 ; 0x3f72 <main+0x172> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f6e: 88 e0 ldi r24, 0x08 ; 8 - 3f70: 2c d0 rcall .+88 ; 0x3fca <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f72: 36 d0 rcall .+108 ; 0x3fe0 <verifySpace> - } - putch(STK_OK); - 3f74: 80 e1 ldi r24, 0x10 ; 16 - 3f76: 01 d0 rcall .+2 ; 0x3f7a <putch> - 3f78: 63 cf rjmp .-314 ; 0x3e40 <main+0x40> - -00003f7a <putch>: -void putch(char ch) { -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - UDR0 = ch; -#else - __asm__ __volatile__ ( - 3f7a: 2a e0 ldi r18, 0x0A ; 10 - 3f7c: 30 e0 ldi r19, 0x00 ; 0 - 3f7e: 80 95 com r24 - 3f80: 08 94 sec - 3f82: 10 f4 brcc .+4 ; 0x3f88 <putch+0xe> - 3f84: 59 98 cbi 0x0b, 1 ; 11 - 3f86: 02 c0 rjmp .+4 ; 0x3f8c <putch+0x12> - 3f88: 59 9a sbi 0x0b, 1 ; 11 - 3f8a: 00 00 nop - 3f8c: 15 d0 rcall .+42 ; 0x3fb8 <uartDelay> - 3f8e: 14 d0 rcall .+40 ; 0x3fb8 <uartDelay> - 3f90: 86 95 lsr r24 - 3f92: 2a 95 dec r18 - 3f94: b1 f7 brne .-20 ; 0x3f82 <putch+0x8> - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f96: 08 95 ret - -00003f98 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3f98: a8 95 wdr -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3f9a: 29 e0 ldi r18, 0x09 ; 9 - 3f9c: 30 e0 ldi r19, 0x00 ; 0 - 3f9e: 48 99 sbic 0x09, 0 ; 9 - 3fa0: fe cf rjmp .-4 ; 0x3f9e <getch+0x6> - 3fa2: 0a d0 rcall .+20 ; 0x3fb8 <uartDelay> - 3fa4: 09 d0 rcall .+18 ; 0x3fb8 <uartDelay> - 3fa6: 08 d0 rcall .+16 ; 0x3fb8 <uartDelay> - 3fa8: 88 94 clc - 3faa: 48 99 sbic 0x09, 0 ; 9 - 3fac: 08 94 sec - 3fae: 2a 95 dec r18 - 3fb0: 11 f0 breq .+4 ; 0x3fb6 <getch+0x1e> - 3fb2: 87 95 ror r24 - 3fb4: f7 cf rjmp .-18 ; 0x3fa4 <getch+0xc> - 3fb6: 08 95 ret - -00003fb8 <uartDelay>: -#if UART_B_VALUE > 255 -#error Baud rate too slow for soft UART -#endif - -void uartDelay() { - __asm__ __volatile__ ( - 3fb8: 98 e0 ldi r25, 0x08 ; 8 - 3fba: 9a 95 dec r25 - 3fbc: f1 f7 brne .-4 ; 0x3fba <uartDelay+0x2> - 3fbe: 08 95 ret - -00003fc0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fc0: eb df rcall .-42 ; 0x3f98 <getch> - length = getch(); - 3fc2: ea df rcall .-44 ; 0x3f98 <getch> - 3fc4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc8: e7 cf rjmp .-50 ; 0x3f98 <getch> - -00003fca <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fca: e0 e6 ldi r30, 0x60 ; 96 - 3fcc: f0 e0 ldi r31, 0x00 ; 0 - 3fce: 98 e1 ldi r25, 0x18 ; 24 - 3fd0: 90 83 st Z, r25 - WDTCSR = x; - 3fd2: 80 83 st Z, r24 -} - 3fd4: 08 95 ret - -00003fd6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd6: 80 e0 ldi r24, 0x00 ; 0 - 3fd8: f8 df rcall .-16 ; 0x3fca <watchdogConfig> - __asm__ __volatile__ ( - 3fda: ee 27 eor r30, r30 - 3fdc: ff 27 eor r31, r31 - 3fde: 09 94 ijmp - -00003fe0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fe0: db df rcall .-74 ; 0x3f98 <getch> - 3fe2: 80 32 cpi r24, 0x20 ; 32 - 3fe4: 09 f0 breq .+2 ; 0x3fe8 <verifySpace+0x8> - 3fe6: f7 df rcall .-18 ; 0x3fd6 <appStart> - putch(STK_INSYNC); - 3fe8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fea: c7 cf rjmp .-114 ; 0x3f7a <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fec: 1f 93 push r17 - 3fee: 18 2f mov r17, r24 - -00003ff0 <getNch>: - do getch(); while (--count); - 3ff0: d3 df rcall .-90 ; 0x3f98 <getch> - 3ff2: 11 50 subi r17, 0x01 ; 1 - 3ff4: e9 f7 brne .-6 ; 0x3ff0 <getNch> - verifySpace(); - 3ff6: f4 df rcall .-24 ; 0x3fe0 <verifySpace> -} - 3ff8: 1f 91 pop r17 - 3ffa: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_luminet.hex b/bootloaders/optiboot/optiboot_luminet.hex deleted file mode 100644 index 0e51124..0000000 --- a/bootloaders/optiboot/optiboot_luminet.hex +++ /dev/null @@ -1,42 +0,0 @@ -:101D000085E08EBD84B714BE81FF27D18DE021D13F
-:101D1000D49AD29A86E023EC3FEF91E03DBD2CBDF2
-:101D20009BB9589BFECFCC9AA8958150B9F7CC248B
-:101D3000C39485E0E82E0FE7D02E1EECF12EF0D0F4
-:101D4000813421F481E014D183E024C0823411F481
-:101D500084E103C0853419F485E00AD1CFC085350C
-:101D6000A1F4DED0082F10E01093010200930002CE
-:101D7000D7D090E0982F8827802B912B880F991F20
-:101D80009093010280930002B8C0863529F484E064
-:101D9000EFD080E0B6D0B2C0843609F06EC0D4D0A7
-:101DA000E0910002F091010283E080935700E895F2
-:101DB000C0E0D1E0B5D08993809102028150809338
-:101DC00002028823B9F7CED007B600FCFDCF809180
-:101DD000000290910102892B41F580910001209130
-:101DE000010130E0322F222790E0282B392B30934D
-:101DF00005022093040240910A0180910B0190E0BA
-:101E0000982F882750E0842B952B9093070280937E
-:101E100006022450304020930A01232F33272093B9
-:101E20000B01D0920001F09201014091000250910B
-:101E30000102A0E0B1E02C9130E011968C91119755
-:101E400090E0982F8827822B932B1296FA010C0191
-:101E5000C0925700E89511244E5F5F4FF1E0A03427
-:101E6000BF0749F7E0910002F0910102E0925700AC
-:101E7000E89507B600FCFDCF41C0843789F564D0F2
-:101E800071D0E0910002F0910102309719F4209195
-:101E9000040213C0E130F10519F4209105020DC0D0
-:101EA000EA30F10519F42091060207C0EB30F10584
-:101EB00019F42091070201C02491809100029091B1
-:101EC000010201969093010280930002822F19D0A3
-:101ED00080910202815080930202882391F60EC005
-:101EE000853739F43FD08EE10CD083E90AD08CE0FD
-:101EF00051CF813511F488E02CD034D080E101D06D
-:101F00001ECF2AE030E08095089410F4DA9802C0E1
-:101F1000DA9A000015D014D086952A95B1F7089565
-:101F2000A89529E030E0CB99FECF0AD009D008D09F
-:101F30008894CB9908942A9511F08795F7CF089546
-:101F40009EE09A95F1F70895EBDFEADF80930202B5
-:101F5000E7CF98E191BD81BD089580E0FADFE5E02B
-:101F6000FF270994DDDF803209F0F7DF84E1C9CF74
-:101F70001F93182FD5DF1150E9F7F4DF1F91089553
-:0400000300001D00DC
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_luminet.lst b/bootloaders/optiboot/optiboot_luminet.lst deleted file mode 100644 index 59468cb..0000000 --- a/bootloaders/optiboot/optiboot_luminet.lst +++ /dev/null @@ -1,604 +0,0 @@ - -optiboot_luminet.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 00000280 00001d00 00001d00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 000002d4 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 00000078 00000000 00000000 000002fc 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000289 00000000 00000000 00000374 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 000001a1 00000000 00000000 000005fd 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 00000435 00000000 00000000 0000079e 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 000000a0 00000000 00000000 00000bd4 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000144 00000000 00000000 00000c74 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 00000194 00000000 00000000 00000db8 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000088 00000000 00000000 00000f4c 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00001d00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 1d00: 85 e0 ldi r24, 0x05 ; 5 - 1d02: 8e bd out 0x2e, r24 ; 46 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 1d04: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 1d06: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 1d08: 81 ff sbrs r24, 1 - 1d0a: 27 d1 rcall .+590 ; 0x1f5a <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 1d0c: 8d e0 ldi r24, 0x0D ; 13 - 1d0e: 21 d1 rcall .+578 ; 0x1f52 <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 1d10: d4 9a sbi 0x1a, 4 ; 26 - -#ifdef SOFT_UART - /* Set TX pin as output */ - UART_DDR |= _BV(UART_TX_BIT); - 1d12: d2 9a sbi 0x1a, 2 ; 26 - 1d14: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 1d16: 23 ec ldi r18, 0xC3 ; 195 - 1d18: 3f ef ldi r19, 0xFF ; 255 - TIFR1 = _BV(TOV1); - 1d1a: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 1d1c: 3d bd out 0x2d, r19 ; 45 - 1d1e: 2c bd out 0x2c, r18 ; 44 - TIFR1 = _BV(TOV1); - 1d20: 9b b9 out 0x0b, r25 ; 11 - while(!(TIFR1 & _BV(TOV1))); - 1d22: 58 9b sbis 0x0b, 0 ; 11 - 1d24: fe cf rjmp .-4 ; 0x1d22 <main+0x22> - LED_PIN |= _BV(LED); - 1d26: cc 9a sbi 0x19, 4 ; 25 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 1d28: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 1d2a: 81 50 subi r24, 0x01 ; 1 - 1d2c: b9 f7 brne .-18 ; 0x1d1c <main+0x1c> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1d2e: cc 24 eor r12, r12 - 1d30: c3 94 inc r12 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 1d32: 85 e0 ldi r24, 0x05 ; 5 - 1d34: e8 2e mov r14, r24 - vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. - buff[10] = vect & 0xff; - buff[11] = vect >> 8; - - // Add jump to bootloader at RESET vector - buff[0] = 0x7f; - 1d36: 0f e7 ldi r16, 0x7F ; 127 - 1d38: d0 2e mov r13, r16 - buff[1] = 0xce; // rjmp 0x1d00 instruction - 1d3a: 1e ec ldi r17, 0xCE ; 206 - 1d3c: f1 2e mov r15, r17 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 1d3e: f0 d0 rcall .+480 ; 0x1f20 <getch> - - if(ch == STK_GET_PARAMETER) { - 1d40: 81 34 cpi r24, 0x41 ; 65 - 1d42: 21 f4 brne .+8 ; 0x1d4c <main+0x4c> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 1d44: 81 e0 ldi r24, 0x01 ; 1 - 1d46: 14 d1 rcall .+552 ; 0x1f70 <verifySpace+0xc> - putch(0x03); - 1d48: 83 e0 ldi r24, 0x03 ; 3 - 1d4a: 24 c0 rjmp .+72 ; 0x1d94 <main+0x94> - } - else if(ch == STK_SET_DEVICE) { - 1d4c: 82 34 cpi r24, 0x42 ; 66 - 1d4e: 11 f4 brne .+4 ; 0x1d54 <main+0x54> - // SET DEVICE is ignored - getNch(20); - 1d50: 84 e1 ldi r24, 0x14 ; 20 - 1d52: 03 c0 rjmp .+6 ; 0x1d5a <main+0x5a> - } - else if(ch == STK_SET_DEVICE_EXT) { - 1d54: 85 34 cpi r24, 0x45 ; 69 - 1d56: 19 f4 brne .+6 ; 0x1d5e <main+0x5e> - // SET DEVICE EXT is ignored - getNch(5); - 1d58: 85 e0 ldi r24, 0x05 ; 5 - 1d5a: 0a d1 rcall .+532 ; 0x1f70 <verifySpace+0xc> - 1d5c: cf c0 rjmp .+414 ; 0x1efc <main+0x1fc> - } - else if(ch == STK_LOAD_ADDRESS) { - 1d5e: 85 35 cpi r24, 0x55 ; 85 - 1d60: a1 f4 brne .+40 ; 0x1d8a <main+0x8a> - // LOAD ADDRESS - address = getch(); - 1d62: de d0 rcall .+444 ; 0x1f20 <getch> - 1d64: 08 2f mov r16, r24 - 1d66: 10 e0 ldi r17, 0x00 ; 0 - 1d68: 10 93 01 02 sts 0x0201, r17 - 1d6c: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 1d70: d7 d0 rcall .+430 ; 0x1f20 <getch> - 1d72: 90 e0 ldi r25, 0x00 ; 0 - 1d74: 98 2f mov r25, r24 - 1d76: 88 27 eor r24, r24 - 1d78: 80 2b or r24, r16 - 1d7a: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 1d7c: 88 0f add r24, r24 - 1d7e: 99 1f adc r25, r25 - 1d80: 90 93 01 02 sts 0x0201, r25 - 1d84: 80 93 00 02 sts 0x0200, r24 - 1d88: b8 c0 rjmp .+368 ; 0x1efa <main+0x1fa> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 1d8a: 86 35 cpi r24, 0x56 ; 86 - 1d8c: 29 f4 brne .+10 ; 0x1d98 <main+0x98> - // UNIVERSAL command is ignored - getNch(4); - 1d8e: 84 e0 ldi r24, 0x04 ; 4 - 1d90: ef d0 rcall .+478 ; 0x1f70 <verifySpace+0xc> - putch(0x00); - 1d92: 80 e0 ldi r24, 0x00 ; 0 - 1d94: b6 d0 rcall .+364 ; 0x1f02 <putch> - 1d96: b2 c0 rjmp .+356 ; 0x1efc <main+0x1fc> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 1d98: 84 36 cpi r24, 0x64 ; 100 - 1d9a: 09 f0 breq .+2 ; 0x1d9e <main+0x9e> - 1d9c: 6e c0 rjmp .+220 ; 0x1e7a <main+0x17a> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 1d9e: d4 d0 rcall .+424 ; 0x1f48 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 1da0: e0 91 00 02 lds r30, 0x0200 - 1da4: f0 91 01 02 lds r31, 0x0201 - 1da8: 83 e0 ldi r24, 0x03 ; 3 - 1daa: 80 93 57 00 sts 0x0057, r24 - 1dae: e8 95 spm - 1db0: c0 e0 ldi r28, 0x00 ; 0 - 1db2: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 1db4: b5 d0 rcall .+362 ; 0x1f20 <getch> - 1db6: 89 93 st Y+, r24 - while (--length); - 1db8: 80 91 02 02 lds r24, 0x0202 - 1dbc: 81 50 subi r24, 0x01 ; 1 - 1dbe: 80 93 02 02 sts 0x0202, r24 - 1dc2: 88 23 and r24, r24 - 1dc4: b9 f7 brne .-18 ; 0x1db4 <main+0xb4> - - // Read command terminator, start reply - verifySpace(); - 1dc6: ce d0 rcall .+412 ; 0x1f64 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 1dc8: 07 b6 in r0, 0x37 ; 55 - 1dca: 00 fc sbrc r0, 0 - 1dcc: fd cf rjmp .-6 ; 0x1dc8 <main+0xc8> - -#ifdef VIRTUAL_BOOT_PARTITION - if ((uint16_t)(void*)address == 0) { - 1dce: 80 91 00 02 lds r24, 0x0200 - 1dd2: 90 91 01 02 lds r25, 0x0201 - 1dd6: 89 2b or r24, r25 - 1dd8: 41 f5 brne .+80 ; 0x1e2a <main+0x12a> - // This is the reset vector page. We need to live-patch the code so the - // bootloader runs. - // - // Move RESET vector to WDT vector - uint16_t vect = buff[0] | (buff[1]<<8); - 1dda: 80 91 00 01 lds r24, 0x0100 - 1dde: 20 91 01 01 lds r18, 0x0101 - 1de2: 30 e0 ldi r19, 0x00 ; 0 - 1de4: 32 2f mov r19, r18 - 1de6: 22 27 eor r18, r18 - 1de8: 90 e0 ldi r25, 0x00 ; 0 - 1dea: 28 2b or r18, r24 - 1dec: 39 2b or r19, r25 - rstVect = vect; - 1dee: 30 93 05 02 sts 0x0205, r19 - 1df2: 20 93 04 02 sts 0x0204, r18 - wdtVect = buff[10] | (buff[11]<<8); - 1df6: 40 91 0a 01 lds r20, 0x010A - 1dfa: 80 91 0b 01 lds r24, 0x010B - 1dfe: 90 e0 ldi r25, 0x00 ; 0 - 1e00: 98 2f mov r25, r24 - 1e02: 88 27 eor r24, r24 - 1e04: 50 e0 ldi r21, 0x00 ; 0 - 1e06: 84 2b or r24, r20 - 1e08: 95 2b or r25, r21 - 1e0a: 90 93 07 02 sts 0x0207, r25 - 1e0e: 80 93 06 02 sts 0x0206, r24 - vect -= 4; // Instruction is a relative jump (rjmp), so recalculate. - 1e12: 24 50 subi r18, 0x04 ; 4 - 1e14: 30 40 sbci r19, 0x00 ; 0 - buff[10] = vect & 0xff; - 1e16: 20 93 0a 01 sts 0x010A, r18 - buff[11] = vect >> 8; - 1e1a: 23 2f mov r18, r19 - 1e1c: 33 27 eor r19, r19 - 1e1e: 20 93 0b 01 sts 0x010B, r18 - - // Add jump to bootloader at RESET vector - buff[0] = 0x7f; - 1e22: d0 92 00 01 sts 0x0100, r13 - buff[1] = 0xce; // rjmp 0x1d00 instruction - 1e26: f0 92 01 01 sts 0x0101, r15 - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 1e2a: 40 91 00 02 lds r20, 0x0200 - 1e2e: 50 91 01 02 lds r21, 0x0201 - 1e32: a0 e0 ldi r26, 0x00 ; 0 - 1e34: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 1e36: 2c 91 ld r18, X - 1e38: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 1e3a: 11 96 adiw r26, 0x01 ; 1 - 1e3c: 8c 91 ld r24, X - 1e3e: 11 97 sbiw r26, 0x01 ; 1 - 1e40: 90 e0 ldi r25, 0x00 ; 0 - 1e42: 98 2f mov r25, r24 - 1e44: 88 27 eor r24, r24 - 1e46: 82 2b or r24, r18 - 1e48: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 1e4a: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 1e4c: fa 01 movw r30, r20 - 1e4e: 0c 01 movw r0, r24 - 1e50: c0 92 57 00 sts 0x0057, r12 - 1e54: e8 95 spm - 1e56: 11 24 eor r1, r1 - addrPtr += 2; - 1e58: 4e 5f subi r20, 0xFE ; 254 - 1e5a: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 1e5c: f1 e0 ldi r31, 0x01 ; 1 - 1e5e: a0 34 cpi r26, 0x40 ; 64 - 1e60: bf 07 cpc r27, r31 - 1e62: 49 f7 brne .-46 ; 0x1e36 <main+0x136> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 1e64: e0 91 00 02 lds r30, 0x0200 - 1e68: f0 91 01 02 lds r31, 0x0201 - 1e6c: e0 92 57 00 sts 0x0057, r14 - 1e70: e8 95 spm - boot_spm_busy_wait(); - 1e72: 07 b6 in r0, 0x37 ; 55 - 1e74: 00 fc sbrc r0, 0 - 1e76: fd cf rjmp .-6 ; 0x1e72 <main+0x172> - 1e78: 41 c0 rjmp .+130 ; 0x1efc <main+0x1fc> - boot_rww_enable(); -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 1e7a: 84 37 cpi r24, 0x74 ; 116 - 1e7c: 89 f5 brne .+98 ; 0x1ee0 <main+0x1e0> - // READ PAGE - we only read flash - getLen(); - 1e7e: 64 d0 rcall .+200 ; 0x1f48 <getLen> - verifySpace(); - 1e80: 71 d0 rcall .+226 ; 0x1f64 <verifySpace> -#ifdef VIRTUAL_BOOT_PARTITION - do { - // Undo vector patch in bottom page so verify passes - if (address == 0) ch=rstVect & 0xff; - 1e82: e0 91 00 02 lds r30, 0x0200 - 1e86: f0 91 01 02 lds r31, 0x0201 - 1e8a: 30 97 sbiw r30, 0x00 ; 0 - 1e8c: 19 f4 brne .+6 ; 0x1e94 <main+0x194> - 1e8e: 20 91 04 02 lds r18, 0x0204 - 1e92: 13 c0 rjmp .+38 ; 0x1eba <main+0x1ba> - else if (address == 1) ch=rstVect >> 8; - 1e94: e1 30 cpi r30, 0x01 ; 1 - 1e96: f1 05 cpc r31, r1 - 1e98: 19 f4 brne .+6 ; 0x1ea0 <main+0x1a0> - 1e9a: 20 91 05 02 lds r18, 0x0205 - 1e9e: 0d c0 rjmp .+26 ; 0x1eba <main+0x1ba> - else if (address == 10) ch=wdtVect & 0xff; - 1ea0: ea 30 cpi r30, 0x0A ; 10 - 1ea2: f1 05 cpc r31, r1 - 1ea4: 19 f4 brne .+6 ; 0x1eac <main+0x1ac> - 1ea6: 20 91 06 02 lds r18, 0x0206 - 1eaa: 07 c0 rjmp .+14 ; 0x1eba <main+0x1ba> - else if (address == 11) ch=wdtVect >> 8; - 1eac: eb 30 cpi r30, 0x0B ; 11 - 1eae: f1 05 cpc r31, r1 - 1eb0: 19 f4 brne .+6 ; 0x1eb8 <main+0x1b8> - 1eb2: 20 91 07 02 lds r18, 0x0207 - 1eb6: 01 c0 rjmp .+2 ; 0x1eba <main+0x1ba> - else ch = pgm_read_byte_near(address); - 1eb8: 24 91 lpm r18, Z+ - address++; - 1eba: 80 91 00 02 lds r24, 0x0200 - 1ebe: 90 91 01 02 lds r25, 0x0201 - 1ec2: 01 96 adiw r24, 0x01 ; 1 - 1ec4: 90 93 01 02 sts 0x0201, r25 - 1ec8: 80 93 00 02 sts 0x0200, r24 - putch(ch); - 1ecc: 82 2f mov r24, r18 - 1ece: 19 d0 rcall .+50 ; 0x1f02 <putch> - } while (--length); - 1ed0: 80 91 02 02 lds r24, 0x0202 - 1ed4: 81 50 subi r24, 0x01 ; 1 - 1ed6: 80 93 02 02 sts 0x0202, r24 - 1eda: 88 23 and r24, r24 - 1edc: 91 f6 brne .-92 ; 0x1e82 <main+0x182> - 1ede: 0e c0 rjmp .+28 ; 0x1efc <main+0x1fc> - while (--length); -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 1ee0: 85 37 cpi r24, 0x75 ; 117 - 1ee2: 39 f4 brne .+14 ; 0x1ef2 <main+0x1f2> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 1ee4: 3f d0 rcall .+126 ; 0x1f64 <verifySpace> - putch(SIGNATURE_0); - 1ee6: 8e e1 ldi r24, 0x1E ; 30 - 1ee8: 0c d0 rcall .+24 ; 0x1f02 <putch> - putch(SIGNATURE_1); - 1eea: 83 e9 ldi r24, 0x93 ; 147 - 1eec: 0a d0 rcall .+20 ; 0x1f02 <putch> - putch(SIGNATURE_2); - 1eee: 8c e0 ldi r24, 0x0C ; 12 - 1ef0: 51 cf rjmp .-350 ; 0x1d94 <main+0x94> - } - else if (ch == 'Q') { - 1ef2: 81 35 cpi r24, 0x51 ; 81 - 1ef4: 11 f4 brne .+4 ; 0x1efa <main+0x1fa> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 1ef6: 88 e0 ldi r24, 0x08 ; 8 - 1ef8: 2c d0 rcall .+88 ; 0x1f52 <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 1efa: 34 d0 rcall .+104 ; 0x1f64 <verifySpace> - } - putch(STK_OK); - 1efc: 80 e1 ldi r24, 0x10 ; 16 - 1efe: 01 d0 rcall .+2 ; 0x1f02 <putch> - 1f00: 1e cf rjmp .-452 ; 0x1d3e <main+0x3e> - -00001f02 <putch>: -void putch(char ch) { -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - UDR0 = ch; -#else - __asm__ __volatile__ ( - 1f02: 2a e0 ldi r18, 0x0A ; 10 - 1f04: 30 e0 ldi r19, 0x00 ; 0 - 1f06: 80 95 com r24 - 1f08: 08 94 sec - 1f0a: 10 f4 brcc .+4 ; 0x1f10 <putch+0xe> - 1f0c: da 98 cbi 0x1b, 2 ; 27 - 1f0e: 02 c0 rjmp .+4 ; 0x1f14 <putch+0x12> - 1f10: da 9a sbi 0x1b, 2 ; 27 - 1f12: 00 00 nop - 1f14: 15 d0 rcall .+42 ; 0x1f40 <uartDelay> - 1f16: 14 d0 rcall .+40 ; 0x1f40 <uartDelay> - 1f18: 86 95 lsr r24 - 1f1a: 2a 95 dec r18 - 1f1c: b1 f7 brne .-20 ; 0x1f0a <putch+0x8> - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 1f1e: 08 95 ret - -00001f20 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 1f20: a8 95 wdr -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 1f22: 29 e0 ldi r18, 0x09 ; 9 - 1f24: 30 e0 ldi r19, 0x00 ; 0 - 1f26: cb 99 sbic 0x19, 3 ; 25 - 1f28: fe cf rjmp .-4 ; 0x1f26 <getch+0x6> - 1f2a: 0a d0 rcall .+20 ; 0x1f40 <uartDelay> - 1f2c: 09 d0 rcall .+18 ; 0x1f40 <uartDelay> - 1f2e: 08 d0 rcall .+16 ; 0x1f40 <uartDelay> - 1f30: 88 94 clc - 1f32: cb 99 sbic 0x19, 3 ; 25 - 1f34: 08 94 sec - 1f36: 2a 95 dec r18 - 1f38: 11 f0 breq .+4 ; 0x1f3e <getch+0x1e> - 1f3a: 87 95 ror r24 - 1f3c: f7 cf rjmp .-18 ; 0x1f2c <getch+0xc> - 1f3e: 08 95 ret - -00001f40 <uartDelay>: -#if UART_B_VALUE > 255 -#error Baud rate too slow for soft UART -#endif - -void uartDelay() { - __asm__ __volatile__ ( - 1f40: 9e e0 ldi r25, 0x0E ; 14 - 1f42: 9a 95 dec r25 - 1f44: f1 f7 brne .-4 ; 0x1f42 <uartDelay+0x2> - 1f46: 08 95 ret - -00001f48 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 1f48: eb df rcall .-42 ; 0x1f20 <getch> - length = getch(); - 1f4a: ea df rcall .-44 ; 0x1f20 <getch> - 1f4c: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 1f50: e7 cf rjmp .-50 ; 0x1f20 <getch> - -00001f52 <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 1f52: 98 e1 ldi r25, 0x18 ; 24 - 1f54: 91 bd out 0x21, r25 ; 33 - WDTCSR = x; - 1f56: 81 bd out 0x21, r24 ; 33 -} - 1f58: 08 95 ret - -00001f5a <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 1f5a: 80 e0 ldi r24, 0x00 ; 0 - 1f5c: fa df rcall .-12 ; 0x1f52 <watchdogConfig> - __asm__ __volatile__ ( - 1f5e: e5 e0 ldi r30, 0x05 ; 5 - 1f60: ff 27 eor r31, r31 - 1f62: 09 94 ijmp - -00001f64 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 1f64: dd df rcall .-70 ; 0x1f20 <getch> - 1f66: 80 32 cpi r24, 0x20 ; 32 - 1f68: 09 f0 breq .+2 ; 0x1f6c <verifySpace+0x8> - 1f6a: f7 df rcall .-18 ; 0x1f5a <appStart> - putch(STK_INSYNC); - 1f6c: 84 e1 ldi r24, 0x14 ; 20 -} - 1f6e: c9 cf rjmp .-110 ; 0x1f02 <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 1f70: 1f 93 push r17 - 1f72: 18 2f mov r17, r24 - -00001f74 <getNch>: - do getch(); while (--count); - 1f74: d5 df rcall .-86 ; 0x1f20 <getch> - 1f76: 11 50 subi r17, 0x01 ; 1 - 1f78: e9 f7 brne .-6 ; 0x1f74 <getNch> - verifySpace(); - 1f7a: f4 df rcall .-24 ; 0x1f64 <verifySpace> -} - 1f7c: 1f 91 pop r17 - 1f7e: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_pro_16MHz.hex b/bootloaders/optiboot/optiboot_pro_16MHz.hex deleted file mode 100644 index 1e93414..0000000 --- a/bootloaders/optiboot/optiboot_pro_16MHz.hex +++ /dev/null @@ -1,33 +0,0 @@ -:103E000085E08093810082E08093C00088E1809308
-:103E1000C10086E08093C20080E18093C40084B733
-:103E200014BE81FFD0D08DE0C8D0259A86E020E373
-:103E30003CEF91E0309385002093840096BBB09BCB
-:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
-:103E600083E024C0823411F484E103C0853419F462
-:103E700085E0B4D08AC08535A1F492D0082F10E037
-:103E800010930102009300028BD090E0982F8827B6
-:103E9000802B912B880F991F909301028093000231
-:103EA00073C0863529F484E099D080E071D06DC06C
-:103EB000843609F043C07CD0E0910002F091010209
-:103EC00083E080935700E895C0E0D1E069D0899302
-:103ED000809102028150809302028823B9F778D042
-:103EE00007B600FCFDCF4091000250910102A0E016
-:103EF000B1E02C9130E011968C91119790E0982FC1
-:103F00008827822B932B1296FA010C01D09257002E
-:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
-:103F2000E0910002F0910102E0925700E89507B697
-:103F300000FCFDCFF0925700E89527C08437B9F414
-:103F400037D046D0E0910002F09101023196F09313
-:103F50000102E09300023197E4918E2F19D08091F5
-:103F60000202815080930202882361F70EC08537D8
-:103F700039F42ED08EE10CD084E90AD086E096CFB9
-:103F8000813511F488E019D023D080E101D063CFCE
-:103F9000982F8091C00085FFFCCF9093C6000895B4
-:103FA000A8958091C00087FFFCCF8091C60008953E
-:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
-:103FC00090838083089580E0F8DFEE27FF2709942F
-:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
-:0C3FE000DFDF1150E9F7F4DF1F910895B6
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_pro_16MHz.lst b/bootloaders/optiboot/optiboot_pro_16MHz.lst deleted file mode 100644 index 9920a76..0000000 --- a/bootloaders/optiboot/optiboot_pro_16MHz.lst +++ /dev/null @@ -1,520 +0,0 @@ - -optiboot_pro_16MHz.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001ec 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000240 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000268 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000269 00000000 00000000 000002d2 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000196 00000000 00000000 0000053b 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003d3 00000000 00000000 000006d1 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000aa4 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000135 00000000 00000000 00000b34 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001d1 00000000 00000000 00000c69 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e3a 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 -#if LED_START_FLASHES > 0 - // Set up Timer 1 for timeout counter - TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 -#endif -#ifndef SOFT_UART - UCSR0A = _BV(U2X0); //Double speed mode USART0 - 3e06: 82 e0 ldi r24, 0x02 ; 2 - 3e08: 80 93 c0 00 sts 0x00C0, r24 - UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e0c: 88 e1 ldi r24, 0x18 ; 24 - 3e0e: 80 93 c1 00 sts 0x00C1, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e12: 86 e0 ldi r24, 0x06 ; 6 - 3e14: 80 93 c2 00 sts 0x00C2, r24 - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 3e18: 80 e1 ldi r24, 0x10 ; 16 - 3e1a: 80 93 c4 00 sts 0x00C4, r24 -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e1e: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e20: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e22: 81 ff sbrs r24, 1 - 3e24: d0 d0 rcall .+416 ; 0x3fc6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e26: 8d e0 ldi r24, 0x0D ; 13 - 3e28: c8 d0 rcall .+400 ; 0x3fba <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e2e: 20 e3 ldi r18, 0x30 ; 48 - 3e30: 3c ef ldi r19, 0xFC ; 252 - TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> - LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e44: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e56: a4 d0 rcall .+328 ; 0x3fa0 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: be d0 rcall .+380 ; 0x3fdc <verifySpace+0xc> - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 24 c0 rjmp .+72 ; 0x3eac <main+0xac> - } - else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> - // SET DEVICE is ignored - getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> - // SET DEVICE EXT is ignored - getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: b4 d0 rcall .+360 ; 0x3fdc <verifySpace+0xc> - 3e74: 8a c0 rjmp .+276 ; 0x3f8a <main+0x18a> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: a1 f4 brne .+40 ; 0x3ea2 <main+0xa2> - // LOAD ADDRESS - address = getch(); - 3e7a: 92 d0 rcall .+292 ; 0x3fa0 <getch> - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 10 93 01 02 sts 0x0201, r17 - 3e84: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e88: 8b d0 rcall .+278 ; 0x3fa0 <getch> - 3e8a: 90 e0 ldi r25, 0x00 ; 0 - 3e8c: 98 2f mov r25, r24 - 3e8e: 88 27 eor r24, r24 - 3e90: 80 2b or r24, r16 - 3e92: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e94: 88 0f add r24, r24 - 3e96: 99 1f adc r25, r25 - 3e98: 90 93 01 02 sts 0x0201, r25 - 3e9c: 80 93 00 02 sts 0x0200, r24 - 3ea0: 73 c0 rjmp .+230 ; 0x3f88 <main+0x188> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3ea2: 86 35 cpi r24, 0x56 ; 86 - 3ea4: 29 f4 brne .+10 ; 0x3eb0 <main+0xb0> - // UNIVERSAL command is ignored - getNch(4); - 3ea6: 84 e0 ldi r24, 0x04 ; 4 - 3ea8: 99 d0 rcall .+306 ; 0x3fdc <verifySpace+0xc> - putch(0x00); - 3eaa: 80 e0 ldi r24, 0x00 ; 0 - 3eac: 71 d0 rcall .+226 ; 0x3f90 <putch> - 3eae: 6d c0 rjmp .+218 ; 0x3f8a <main+0x18a> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3eb0: 84 36 cpi r24, 0x64 ; 100 - 3eb2: 09 f0 breq .+2 ; 0x3eb6 <main+0xb6> - 3eb4: 43 c0 rjmp .+134 ; 0x3f3c <main+0x13c> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3eb6: 7c d0 rcall .+248 ; 0x3fb0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3eb8: e0 91 00 02 lds r30, 0x0200 - 3ebc: f0 91 01 02 lds r31, 0x0201 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 80 93 57 00 sts 0x0057, r24 - 3ec6: e8 95 spm - 3ec8: c0 e0 ldi r28, 0x00 ; 0 - 3eca: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3ecc: 69 d0 rcall .+210 ; 0x3fa0 <getch> - 3ece: 89 93 st Y+, r24 - while (--length); - 3ed0: 80 91 02 02 lds r24, 0x0202 - 3ed4: 81 50 subi r24, 0x01 ; 1 - 3ed6: 80 93 02 02 sts 0x0202, r24 - 3eda: 88 23 and r24, r24 - 3edc: b9 f7 brne .-18 ; 0x3ecc <main+0xcc> - - // Read command terminator, start reply - verifySpace(); - 3ede: 78 d0 rcall .+240 ; 0x3fd0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3ee0: 07 b6 in r0, 0x37 ; 55 - 3ee2: 00 fc sbrc r0, 0 - 3ee4: fd cf rjmp .-6 ; 0x3ee0 <main+0xe0> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ee6: 40 91 00 02 lds r20, 0x0200 - 3eea: 50 91 01 02 lds r21, 0x0201 - 3eee: a0 e0 ldi r26, 0x00 ; 0 - 3ef0: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3ef2: 2c 91 ld r18, X - 3ef4: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ef6: 11 96 adiw r26, 0x01 ; 1 - 3ef8: 8c 91 ld r24, X - 3efa: 11 97 sbiw r26, 0x01 ; 1 - 3efc: 90 e0 ldi r25, 0x00 ; 0 - 3efe: 98 2f mov r25, r24 - 3f00: 88 27 eor r24, r24 - 3f02: 82 2b or r24, r18 - 3f04: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3f06: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3f08: fa 01 movw r30, r20 - 3f0a: 0c 01 movw r0, r24 - 3f0c: d0 92 57 00 sts 0x0057, r13 - 3f10: e8 95 spm - 3f12: 11 24 eor r1, r1 - addrPtr += 2; - 3f14: 4e 5f subi r20, 0xFE ; 254 - 3f16: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f18: f1 e0 ldi r31, 0x01 ; 1 - 3f1a: a0 38 cpi r26, 0x80 ; 128 - 3f1c: bf 07 cpc r27, r31 - 3f1e: 49 f7 brne .-46 ; 0x3ef2 <main+0xf2> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f20: e0 91 00 02 lds r30, 0x0200 - 3f24: f0 91 01 02 lds r31, 0x0201 - 3f28: e0 92 57 00 sts 0x0057, r14 - 3f2c: e8 95 spm - boot_spm_busy_wait(); - 3f2e: 07 b6 in r0, 0x37 ; 55 - 3f30: 00 fc sbrc r0, 0 - 3f32: fd cf rjmp .-6 ; 0x3f2e <main+0x12e> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f34: f0 92 57 00 sts 0x0057, r15 - 3f38: e8 95 spm - 3f3a: 27 c0 rjmp .+78 ; 0x3f8a <main+0x18a> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f3c: 84 37 cpi r24, 0x74 ; 116 - 3f3e: b9 f4 brne .+46 ; 0x3f6e <main+0x16e> - // READ PAGE - we only read flash - getLen(); - 3f40: 37 d0 rcall .+110 ; 0x3fb0 <getLen> - verifySpace(); - 3f42: 46 d0 rcall .+140 ; 0x3fd0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f44: e0 91 00 02 lds r30, 0x0200 - 3f48: f0 91 01 02 lds r31, 0x0201 - 3f4c: 31 96 adiw r30, 0x01 ; 1 - 3f4e: f0 93 01 02 sts 0x0201, r31 - 3f52: e0 93 00 02 sts 0x0200, r30 - 3f56: 31 97 sbiw r30, 0x01 ; 1 - 3f58: e4 91 lpm r30, Z+ - 3f5a: 8e 2f mov r24, r30 - 3f5c: 19 d0 rcall .+50 ; 0x3f90 <putch> - while (--length); - 3f5e: 80 91 02 02 lds r24, 0x0202 - 3f62: 81 50 subi r24, 0x01 ; 1 - 3f64: 80 93 02 02 sts 0x0202, r24 - 3f68: 88 23 and r24, r24 - 3f6a: 61 f7 brne .-40 ; 0x3f44 <main+0x144> - 3f6c: 0e c0 rjmp .+28 ; 0x3f8a <main+0x18a> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f6e: 85 37 cpi r24, 0x75 ; 117 - 3f70: 39 f4 brne .+14 ; 0x3f80 <main+0x180> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f72: 2e d0 rcall .+92 ; 0x3fd0 <verifySpace> - putch(SIGNATURE_0); - 3f74: 8e e1 ldi r24, 0x1E ; 30 - 3f76: 0c d0 rcall .+24 ; 0x3f90 <putch> - putch(SIGNATURE_1); - 3f78: 84 e9 ldi r24, 0x94 ; 148 - 3f7a: 0a d0 rcall .+20 ; 0x3f90 <putch> - putch(SIGNATURE_2); - 3f7c: 86 e0 ldi r24, 0x06 ; 6 - 3f7e: 96 cf rjmp .-212 ; 0x3eac <main+0xac> - } - else if (ch == 'Q') { - 3f80: 81 35 cpi r24, 0x51 ; 81 - 3f82: 11 f4 brne .+4 ; 0x3f88 <main+0x188> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f84: 88 e0 ldi r24, 0x08 ; 8 - 3f86: 19 d0 rcall .+50 ; 0x3fba <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f88: 23 d0 rcall .+70 ; 0x3fd0 <verifySpace> - } - putch(STK_OK); - 3f8a: 80 e1 ldi r24, 0x10 ; 16 - 3f8c: 01 d0 rcall .+2 ; 0x3f90 <putch> - 3f8e: 63 cf rjmp .-314 ; 0x3e56 <main+0x56> - -00003f90 <putch>: - } -} - -void putch(char ch) { - 3f90: 98 2f mov r25, r24 -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - 3f92: 80 91 c0 00 lds r24, 0x00C0 - 3f96: 85 ff sbrs r24, 5 - 3f98: fc cf rjmp .-8 ; 0x3f92 <putch+0x2> - UDR0 = ch; - 3f9a: 90 93 c6 00 sts 0x00C6, r25 - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f9e: 08 95 ret - -00003fa0 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fa0: a8 95 wdr - [uartBit] "I" (UART_RX_BIT) - : - "r25" -); -#else - while(!(UCSR0A & _BV(RXC0))); - 3fa2: 80 91 c0 00 lds r24, 0x00C0 - 3fa6: 87 ff sbrs r24, 7 - 3fa8: fc cf rjmp .-8 ; 0x3fa2 <getch+0x2> - ch = UDR0; - 3faa: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3fae: 08 95 ret - -00003fb0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fb0: f7 df rcall .-18 ; 0x3fa0 <getch> - length = getch(); - 3fb2: f6 df rcall .-20 ; 0x3fa0 <getch> - 3fb4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fb8: f3 cf rjmp .-26 ; 0x3fa0 <getch> - -00003fba <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fba: e0 e6 ldi r30, 0x60 ; 96 - 3fbc: f0 e0 ldi r31, 0x00 ; 0 - 3fbe: 98 e1 ldi r25, 0x18 ; 24 - 3fc0: 90 83 st Z, r25 - WDTCSR = x; - 3fc2: 80 83 st Z, r24 -} - 3fc4: 08 95 ret - -00003fc6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fc6: 80 e0 ldi r24, 0x00 ; 0 - 3fc8: f8 df rcall .-16 ; 0x3fba <watchdogConfig> - __asm__ __volatile__ ( - 3fca: ee 27 eor r30, r30 - 3fcc: ff 27 eor r31, r31 - 3fce: 09 94 ijmp - -00003fd0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fd0: e7 df rcall .-50 ; 0x3fa0 <getch> - 3fd2: 80 32 cpi r24, 0x20 ; 32 - 3fd4: 09 f0 breq .+2 ; 0x3fd8 <verifySpace+0x8> - 3fd6: f7 df rcall .-18 ; 0x3fc6 <appStart> - putch(STK_INSYNC); - 3fd8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fda: da cf rjmp .-76 ; 0x3f90 <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fdc: 1f 93 push r17 - 3fde: 18 2f mov r17, r24 - -00003fe0 <getNch>: - do getch(); while (--count); - 3fe0: df df rcall .-66 ; 0x3fa0 <getch> - 3fe2: 11 50 subi r17, 0x01 ; 1 - 3fe4: e9 f7 brne .-6 ; 0x3fe0 <getNch> - verifySpace(); - 3fe6: f4 df rcall .-24 ; 0x3fd0 <verifySpace> -} - 3fe8: 1f 91 pop r17 - 3fea: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_pro_20mhz.hex b/bootloaders/optiboot/optiboot_pro_20mhz.hex deleted file mode 100644 index 19c9ae4..0000000 --- a/bootloaders/optiboot/optiboot_pro_20mhz.hex +++ /dev/null @@ -1,33 +0,0 @@ -:103E000085E08093810082E08093C00088E1809308
-:103E1000C10086E08093C20085E18093C40084B72E
-:103E200014BE81FFD0D08DE0C8D0259A86E02CE367
-:103E30003BEF91E0309385002093840096BBB09BCC
-:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
-:103E600083E024C0823411F484E103C0853419F462
-:103E700085E0B4D08AC08535A1F492D0082F10E037
-:103E800010930102009300028BD090E0982F8827B6
-:103E9000802B912B880F991F909301028093000231
-:103EA00073C0863529F484E099D080E071D06DC06C
-:103EB000843609F043C07CD0E0910002F091010209
-:103EC00083E080935700E895C0E0D1E069D0899302
-:103ED000809102028150809302028823B9F778D042
-:103EE00007B600FCFDCF4091000250910102A0E016
-:103EF000B1E02C9130E011968C91119790E0982FC1
-:103F00008827822B932B1296FA010C01D09257002E
-:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
-:103F2000E0910002F0910102E0925700E89507B697
-:103F300000FCFDCFF0925700E89527C08437B9F414
-:103F400037D046D0E0910002F09101023196F09313
-:103F50000102E09300023197E4918E2F19D08091F5
-:103F60000202815080930202882361F70EC08537D8
-:103F700039F42ED08EE10CD084E90AD086E096CFB9
-:103F8000813511F488E019D023D080E101D063CFCE
-:103F9000982F8091C00085FFFCCF9093C6000895B4
-:103FA000A8958091C00087FFFCCF8091C60008953E
-:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
-:103FC00090838083089580E0F8DFEE27FF2709942F
-:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
-:0C3FE000DFDF1150E9F7F4DF1F910895B6
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_pro_20mhz.lst b/bootloaders/optiboot/optiboot_pro_20mhz.lst deleted file mode 100644 index 62178d3..0000000 --- a/bootloaders/optiboot/optiboot_pro_20mhz.lst +++ /dev/null @@ -1,520 +0,0 @@ - -optiboot_pro_20mhz.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001ec 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000240 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 0000006a 00000000 00000000 00000268 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000269 00000000 00000000 000002d2 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000196 00000000 00000000 0000053b 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003d3 00000000 00000000 000006d1 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 00000090 00000000 00000000 00000aa4 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 00000135 00000000 00000000 00000b34 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001d1 00000000 00000000 00000c69 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000068 00000000 00000000 00000e3a 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 -#if LED_START_FLASHES > 0 - // Set up Timer 1 for timeout counter - TCCR1B = _BV(CS12) | _BV(CS10); // div 1024 -#endif -#ifndef SOFT_UART - UCSR0A = _BV(U2X0); //Double speed mode USART0 - 3e06: 82 e0 ldi r24, 0x02 ; 2 - 3e08: 80 93 c0 00 sts 0x00C0, r24 - UCSR0B = _BV(RXEN0) | _BV(TXEN0); - 3e0c: 88 e1 ldi r24, 0x18 ; 24 - 3e0e: 80 93 c1 00 sts 0x00C1, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - 3e12: 86 e0 ldi r24, 0x06 ; 6 - 3e14: 80 93 c2 00 sts 0x00C2, r24 - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); - 3e18: 85 e1 ldi r24, 0x15 ; 21 - 3e1a: 80 93 c4 00 sts 0x00C4, r24 -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e1e: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e20: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e22: 81 ff sbrs r24, 1 - 3e24: d0 d0 rcall .+416 ; 0x3fc6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e26: 8d e0 ldi r24, 0x0D ; 13 - 3e28: c8 d0 rcall .+400 ; 0x3fba <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e2a: 25 9a sbi 0x04, 5 ; 4 - 3e2c: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e2e: 2c e3 ldi r18, 0x3C ; 60 - 3e30: 3b ef ldi r19, 0xFB ; 251 - TIFR1 = _BV(TOV1); - 3e32: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e34: 30 93 85 00 sts 0x0085, r19 - 3e38: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e3c: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e3e: b0 9b sbis 0x16, 0 ; 22 - 3e40: fe cf rjmp .-4 ; 0x3e3e <main+0x3e> - LED_PIN |= _BV(LED); - 3e42: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e44: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e46: 81 50 subi r24, 0x01 ; 1 - 3e48: a9 f7 brne .-22 ; 0x3e34 <main+0x34> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e4a: dd 24 eor r13, r13 - 3e4c: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e4e: a5 e0 ldi r26, 0x05 ; 5 - 3e50: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e52: f1 e1 ldi r31, 0x11 ; 17 - 3e54: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e56: a4 d0 rcall .+328 ; 0x3fa0 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e58: 81 34 cpi r24, 0x41 ; 65 - 3e5a: 21 f4 brne .+8 ; 0x3e64 <main+0x64> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e5c: 81 e0 ldi r24, 0x01 ; 1 - 3e5e: be d0 rcall .+380 ; 0x3fdc <verifySpace+0xc> - putch(0x03); - 3e60: 83 e0 ldi r24, 0x03 ; 3 - 3e62: 24 c0 rjmp .+72 ; 0x3eac <main+0xac> - } - else if(ch == STK_SET_DEVICE) { - 3e64: 82 34 cpi r24, 0x42 ; 66 - 3e66: 11 f4 brne .+4 ; 0x3e6c <main+0x6c> - // SET DEVICE is ignored - getNch(20); - 3e68: 84 e1 ldi r24, 0x14 ; 20 - 3e6a: 03 c0 rjmp .+6 ; 0x3e72 <main+0x72> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e6c: 85 34 cpi r24, 0x45 ; 69 - 3e6e: 19 f4 brne .+6 ; 0x3e76 <main+0x76> - // SET DEVICE EXT is ignored - getNch(5); - 3e70: 85 e0 ldi r24, 0x05 ; 5 - 3e72: b4 d0 rcall .+360 ; 0x3fdc <verifySpace+0xc> - 3e74: 8a c0 rjmp .+276 ; 0x3f8a <main+0x18a> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e76: 85 35 cpi r24, 0x55 ; 85 - 3e78: a1 f4 brne .+40 ; 0x3ea2 <main+0xa2> - // LOAD ADDRESS - address = getch(); - 3e7a: 92 d0 rcall .+292 ; 0x3fa0 <getch> - 3e7c: 08 2f mov r16, r24 - 3e7e: 10 e0 ldi r17, 0x00 ; 0 - 3e80: 10 93 01 02 sts 0x0201, r17 - 3e84: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e88: 8b d0 rcall .+278 ; 0x3fa0 <getch> - 3e8a: 90 e0 ldi r25, 0x00 ; 0 - 3e8c: 98 2f mov r25, r24 - 3e8e: 88 27 eor r24, r24 - 3e90: 80 2b or r24, r16 - 3e92: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e94: 88 0f add r24, r24 - 3e96: 99 1f adc r25, r25 - 3e98: 90 93 01 02 sts 0x0201, r25 - 3e9c: 80 93 00 02 sts 0x0200, r24 - 3ea0: 73 c0 rjmp .+230 ; 0x3f88 <main+0x188> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3ea2: 86 35 cpi r24, 0x56 ; 86 - 3ea4: 29 f4 brne .+10 ; 0x3eb0 <main+0xb0> - // UNIVERSAL command is ignored - getNch(4); - 3ea6: 84 e0 ldi r24, 0x04 ; 4 - 3ea8: 99 d0 rcall .+306 ; 0x3fdc <verifySpace+0xc> - putch(0x00); - 3eaa: 80 e0 ldi r24, 0x00 ; 0 - 3eac: 71 d0 rcall .+226 ; 0x3f90 <putch> - 3eae: 6d c0 rjmp .+218 ; 0x3f8a <main+0x18a> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3eb0: 84 36 cpi r24, 0x64 ; 100 - 3eb2: 09 f0 breq .+2 ; 0x3eb6 <main+0xb6> - 3eb4: 43 c0 rjmp .+134 ; 0x3f3c <main+0x13c> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3eb6: 7c d0 rcall .+248 ; 0x3fb0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3eb8: e0 91 00 02 lds r30, 0x0200 - 3ebc: f0 91 01 02 lds r31, 0x0201 - 3ec0: 83 e0 ldi r24, 0x03 ; 3 - 3ec2: 80 93 57 00 sts 0x0057, r24 - 3ec6: e8 95 spm - 3ec8: c0 e0 ldi r28, 0x00 ; 0 - 3eca: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3ecc: 69 d0 rcall .+210 ; 0x3fa0 <getch> - 3ece: 89 93 st Y+, r24 - while (--length); - 3ed0: 80 91 02 02 lds r24, 0x0202 - 3ed4: 81 50 subi r24, 0x01 ; 1 - 3ed6: 80 93 02 02 sts 0x0202, r24 - 3eda: 88 23 and r24, r24 - 3edc: b9 f7 brne .-18 ; 0x3ecc <main+0xcc> - - // Read command terminator, start reply - verifySpace(); - 3ede: 78 d0 rcall .+240 ; 0x3fd0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3ee0: 07 b6 in r0, 0x37 ; 55 - 3ee2: 00 fc sbrc r0, 0 - 3ee4: fd cf rjmp .-6 ; 0x3ee0 <main+0xe0> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ee6: 40 91 00 02 lds r20, 0x0200 - 3eea: 50 91 01 02 lds r21, 0x0201 - 3eee: a0 e0 ldi r26, 0x00 ; 0 - 3ef0: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3ef2: 2c 91 ld r18, X - 3ef4: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ef6: 11 96 adiw r26, 0x01 ; 1 - 3ef8: 8c 91 ld r24, X - 3efa: 11 97 sbiw r26, 0x01 ; 1 - 3efc: 90 e0 ldi r25, 0x00 ; 0 - 3efe: 98 2f mov r25, r24 - 3f00: 88 27 eor r24, r24 - 3f02: 82 2b or r24, r18 - 3f04: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3f06: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3f08: fa 01 movw r30, r20 - 3f0a: 0c 01 movw r0, r24 - 3f0c: d0 92 57 00 sts 0x0057, r13 - 3f10: e8 95 spm - 3f12: 11 24 eor r1, r1 - addrPtr += 2; - 3f14: 4e 5f subi r20, 0xFE ; 254 - 3f16: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f18: f1 e0 ldi r31, 0x01 ; 1 - 3f1a: a0 38 cpi r26, 0x80 ; 128 - 3f1c: bf 07 cpc r27, r31 - 3f1e: 49 f7 brne .-46 ; 0x3ef2 <main+0xf2> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f20: e0 91 00 02 lds r30, 0x0200 - 3f24: f0 91 01 02 lds r31, 0x0201 - 3f28: e0 92 57 00 sts 0x0057, r14 - 3f2c: e8 95 spm - boot_spm_busy_wait(); - 3f2e: 07 b6 in r0, 0x37 ; 55 - 3f30: 00 fc sbrc r0, 0 - 3f32: fd cf rjmp .-6 ; 0x3f2e <main+0x12e> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f34: f0 92 57 00 sts 0x0057, r15 - 3f38: e8 95 spm - 3f3a: 27 c0 rjmp .+78 ; 0x3f8a <main+0x18a> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f3c: 84 37 cpi r24, 0x74 ; 116 - 3f3e: b9 f4 brne .+46 ; 0x3f6e <main+0x16e> - // READ PAGE - we only read flash - getLen(); - 3f40: 37 d0 rcall .+110 ; 0x3fb0 <getLen> - verifySpace(); - 3f42: 46 d0 rcall .+140 ; 0x3fd0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f44: e0 91 00 02 lds r30, 0x0200 - 3f48: f0 91 01 02 lds r31, 0x0201 - 3f4c: 31 96 adiw r30, 0x01 ; 1 - 3f4e: f0 93 01 02 sts 0x0201, r31 - 3f52: e0 93 00 02 sts 0x0200, r30 - 3f56: 31 97 sbiw r30, 0x01 ; 1 - 3f58: e4 91 lpm r30, Z+ - 3f5a: 8e 2f mov r24, r30 - 3f5c: 19 d0 rcall .+50 ; 0x3f90 <putch> - while (--length); - 3f5e: 80 91 02 02 lds r24, 0x0202 - 3f62: 81 50 subi r24, 0x01 ; 1 - 3f64: 80 93 02 02 sts 0x0202, r24 - 3f68: 88 23 and r24, r24 - 3f6a: 61 f7 brne .-40 ; 0x3f44 <main+0x144> - 3f6c: 0e c0 rjmp .+28 ; 0x3f8a <main+0x18a> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f6e: 85 37 cpi r24, 0x75 ; 117 - 3f70: 39 f4 brne .+14 ; 0x3f80 <main+0x180> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f72: 2e d0 rcall .+92 ; 0x3fd0 <verifySpace> - putch(SIGNATURE_0); - 3f74: 8e e1 ldi r24, 0x1E ; 30 - 3f76: 0c d0 rcall .+24 ; 0x3f90 <putch> - putch(SIGNATURE_1); - 3f78: 84 e9 ldi r24, 0x94 ; 148 - 3f7a: 0a d0 rcall .+20 ; 0x3f90 <putch> - putch(SIGNATURE_2); - 3f7c: 86 e0 ldi r24, 0x06 ; 6 - 3f7e: 96 cf rjmp .-212 ; 0x3eac <main+0xac> - } - else if (ch == 'Q') { - 3f80: 81 35 cpi r24, 0x51 ; 81 - 3f82: 11 f4 brne .+4 ; 0x3f88 <main+0x188> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f84: 88 e0 ldi r24, 0x08 ; 8 - 3f86: 19 d0 rcall .+50 ; 0x3fba <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f88: 23 d0 rcall .+70 ; 0x3fd0 <verifySpace> - } - putch(STK_OK); - 3f8a: 80 e1 ldi r24, 0x10 ; 16 - 3f8c: 01 d0 rcall .+2 ; 0x3f90 <putch> - 3f8e: 63 cf rjmp .-314 ; 0x3e56 <main+0x56> - -00003f90 <putch>: - } -} - -void putch(char ch) { - 3f90: 98 2f mov r25, r24 -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - 3f92: 80 91 c0 00 lds r24, 0x00C0 - 3f96: 85 ff sbrs r24, 5 - 3f98: fc cf rjmp .-8 ; 0x3f92 <putch+0x2> - UDR0 = ch; - 3f9a: 90 93 c6 00 sts 0x00C6, r25 - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f9e: 08 95 ret - -00003fa0 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3fa0: a8 95 wdr - [uartBit] "I" (UART_RX_BIT) - : - "r25" -); -#else - while(!(UCSR0A & _BV(RXC0))); - 3fa2: 80 91 c0 00 lds r24, 0x00C0 - 3fa6: 87 ff sbrs r24, 7 - 3fa8: fc cf rjmp .-8 ; 0x3fa2 <getch+0x2> - ch = UDR0; - 3faa: 80 91 c6 00 lds r24, 0x00C6 -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3fae: 08 95 ret - -00003fb0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fb0: f7 df rcall .-18 ; 0x3fa0 <getch> - length = getch(); - 3fb2: f6 df rcall .-20 ; 0x3fa0 <getch> - 3fb4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fb8: f3 cf rjmp .-26 ; 0x3fa0 <getch> - -00003fba <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fba: e0 e6 ldi r30, 0x60 ; 96 - 3fbc: f0 e0 ldi r31, 0x00 ; 0 - 3fbe: 98 e1 ldi r25, 0x18 ; 24 - 3fc0: 90 83 st Z, r25 - WDTCSR = x; - 3fc2: 80 83 st Z, r24 -} - 3fc4: 08 95 ret - -00003fc6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fc6: 80 e0 ldi r24, 0x00 ; 0 - 3fc8: f8 df rcall .-16 ; 0x3fba <watchdogConfig> - __asm__ __volatile__ ( - 3fca: ee 27 eor r30, r30 - 3fcc: ff 27 eor r31, r31 - 3fce: 09 94 ijmp - -00003fd0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fd0: e7 df rcall .-50 ; 0x3fa0 <getch> - 3fd2: 80 32 cpi r24, 0x20 ; 32 - 3fd4: 09 f0 breq .+2 ; 0x3fd8 <verifySpace+0x8> - 3fd6: f7 df rcall .-18 ; 0x3fc6 <appStart> - putch(STK_INSYNC); - 3fd8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fda: da cf rjmp .-76 ; 0x3f90 <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fdc: 1f 93 push r17 - 3fde: 18 2f mov r17, r24 - -00003fe0 <getNch>: - do getch(); while (--count); - 3fe0: df df rcall .-66 ; 0x3fa0 <getch> - 3fe2: 11 50 subi r17, 0x01 ; 1 - 3fe4: e9 f7 brne .-6 ; 0x3fe0 <getNch> - verifySpace(); - 3fe6: f4 df rcall .-24 ; 0x3fd0 <verifySpace> -} - 3fe8: 1f 91 pop r17 - 3fea: 08 95 ret diff --git a/bootloaders/optiboot/optiboot_pro_8MHz.hex b/bootloaders/optiboot/optiboot_pro_8MHz.hex deleted file mode 100644 index 9d31a7a..0000000 --- a/bootloaders/optiboot/optiboot_pro_8MHz.hex +++ /dev/null @@ -1,34 +0,0 @@ -:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E028E13EEF91E030937C
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF089598E09A95F1F7089555
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
-:0400000300003E00BB
-:00000001FF
diff --git a/bootloaders/optiboot/optiboot_pro_8MHz.lst b/bootloaders/optiboot/optiboot_pro_8MHz.lst deleted file mode 100644 index 94603e2..0000000 --- a/bootloaders/optiboot/optiboot_pro_8MHz.lst +++ /dev/null @@ -1,533 +0,0 @@ - -optiboot_pro_8MHz.elf: file format elf32-avr - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 000001fc 00003e00 00003e00 00000054 2**1 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .debug_aranges 00000028 00000000 00000000 00000250 2**0 - CONTENTS, READONLY, DEBUGGING - 2 .debug_pubnames 00000078 00000000 00000000 00000278 2**0 - CONTENTS, READONLY, DEBUGGING - 3 .debug_info 00000277 00000000 00000000 000002f0 2**0 - CONTENTS, READONLY, DEBUGGING - 4 .debug_abbrev 00000194 00000000 00000000 00000567 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_line 000003bb 00000000 00000000 000006fb 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_frame 000000a0 00000000 00000000 00000ab8 2**2 - CONTENTS, READONLY, DEBUGGING - 7 .debug_str 0000013f 00000000 00000000 00000b58 2**0 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000001a0 00000000 00000000 00000c97 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_ranges 00000070 00000000 00000000 00000e37 2**0 - CONTENTS, READONLY, DEBUGGING - -Disassembly of section .text: - -00003e00 <main>: -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3e00: 85 e0 ldi r24, 0x05 ; 5 - 3e02: 80 93 81 00 sts 0x0081, r24 - UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); - UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); -#endif - - // Adaboot no-wait mod - ch = MCUSR; - 3e06: 84 b7 in r24, 0x34 ; 52 - MCUSR = 0; - 3e08: 14 be out 0x34, r1 ; 52 - if (!(ch & _BV(EXTRF))) appStart(); - 3e0a: 81 ff sbrs r24, 1 - 3e0c: e4 d0 rcall .+456 ; 0x3fd6 <appStart> - - // Set up watchdog to trigger after 500ms - watchdogConfig(WATCHDOG_500MS); - 3e0e: 8d e0 ldi r24, 0x0D ; 13 - 3e10: dc d0 rcall .+440 ; 0x3fca <watchdogConfig> - - /* Set LED pin as output */ - LED_DDR |= _BV(LED); - 3e12: 25 9a sbi 0x04, 5 ; 4 - -#ifdef SOFT_UART - /* Set TX pin as output */ - UART_DDR |= _BV(UART_TX_BIT); - 3e14: 51 9a sbi 0x0a, 1 ; 10 - 3e16: 86 e0 ldi r24, 0x06 ; 6 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e18: 28 e1 ldi r18, 0x18 ; 24 - 3e1a: 3e ef ldi r19, 0xFE ; 254 - TIFR1 = _BV(TOV1); - 3e1c: 91 e0 ldi r25, 0x01 ; 1 -} - -#if LED_START_FLASHES > 0 -void flash_led(uint8_t count) { - do { - TCNT1 = -(F_CPU/(1024*16)); - 3e1e: 30 93 85 00 sts 0x0085, r19 - 3e22: 20 93 84 00 sts 0x0084, r18 - TIFR1 = _BV(TOV1); - 3e26: 96 bb out 0x16, r25 ; 22 - while(!(TIFR1 & _BV(TOV1))); - 3e28: b0 9b sbis 0x16, 0 ; 22 - 3e2a: fe cf rjmp .-4 ; 0x3e28 <main+0x28> - LED_PIN |= _BV(LED); - 3e2c: 1d 9a sbi 0x03, 5 ; 3 - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3e2e: a8 95 wdr - TCNT1 = -(F_CPU/(1024*16)); - TIFR1 = _BV(TOV1); - while(!(TIFR1 & _BV(TOV1))); - LED_PIN |= _BV(LED); - watchdogReset(); - } while (--count); - 3e30: 81 50 subi r24, 0x01 ; 1 - 3e32: a9 f7 brne .-22 ; 0x3e1e <main+0x1e> - /* get character from UART */ - ch = getch(); - - if(ch == STK_GET_PARAMETER) { - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e34: dd 24 eor r13, r13 - 3e36: d3 94 inc r13 - boot_page_fill((uint16_t)(void*)addrPtr,a); - addrPtr += 2; - } while (--ch); - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3e38: a5 e0 ldi r26, 0x05 ; 5 - 3e3a: ea 2e mov r14, r26 - boot_spm_busy_wait(); - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3e3c: f1 e1 ldi r31, 0x11 ; 17 - 3e3e: ff 2e mov r15, r31 -#endif - - /* Forever loop */ - for (;;) { - /* get character from UART */ - ch = getch(); - 3e40: ab d0 rcall .+342 ; 0x3f98 <getch> - - if(ch == STK_GET_PARAMETER) { - 3e42: 81 34 cpi r24, 0x41 ; 65 - 3e44: 21 f4 brne .+8 ; 0x3e4e <main+0x4e> - // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy - getNch(1); - 3e46: 81 e0 ldi r24, 0x01 ; 1 - 3e48: d1 d0 rcall .+418 ; 0x3fec <verifySpace+0xc> - putch(0x03); - 3e4a: 83 e0 ldi r24, 0x03 ; 3 - 3e4c: 24 c0 rjmp .+72 ; 0x3e96 <main+0x96> - } - else if(ch == STK_SET_DEVICE) { - 3e4e: 82 34 cpi r24, 0x42 ; 66 - 3e50: 11 f4 brne .+4 ; 0x3e56 <main+0x56> - // SET DEVICE is ignored - getNch(20); - 3e52: 84 e1 ldi r24, 0x14 ; 20 - 3e54: 03 c0 rjmp .+6 ; 0x3e5c <main+0x5c> - } - else if(ch == STK_SET_DEVICE_EXT) { - 3e56: 85 34 cpi r24, 0x45 ; 69 - 3e58: 19 f4 brne .+6 ; 0x3e60 <main+0x60> - // SET DEVICE EXT is ignored - getNch(5); - 3e5a: 85 e0 ldi r24, 0x05 ; 5 - 3e5c: c7 d0 rcall .+398 ; 0x3fec <verifySpace+0xc> - 3e5e: 8a c0 rjmp .+276 ; 0x3f74 <main+0x174> - } - else if(ch == STK_LOAD_ADDRESS) { - 3e60: 85 35 cpi r24, 0x55 ; 85 - 3e62: a1 f4 brne .+40 ; 0x3e8c <main+0x8c> - // LOAD ADDRESS - address = getch(); - 3e64: 99 d0 rcall .+306 ; 0x3f98 <getch> - 3e66: 08 2f mov r16, r24 - 3e68: 10 e0 ldi r17, 0x00 ; 0 - 3e6a: 10 93 01 02 sts 0x0201, r17 - 3e6e: 00 93 00 02 sts 0x0200, r16 - address = (address & 0xff) | (getch() << 8); - 3e72: 92 d0 rcall .+292 ; 0x3f98 <getch> - 3e74: 90 e0 ldi r25, 0x00 ; 0 - 3e76: 98 2f mov r25, r24 - 3e78: 88 27 eor r24, r24 - 3e7a: 80 2b or r24, r16 - 3e7c: 91 2b or r25, r17 - address += address; // Convert from word address to byte address - 3e7e: 88 0f add r24, r24 - 3e80: 99 1f adc r25, r25 - 3e82: 90 93 01 02 sts 0x0201, r25 - 3e86: 80 93 00 02 sts 0x0200, r24 - 3e8a: 73 c0 rjmp .+230 ; 0x3f72 <main+0x172> - verifySpace(); - } - else if(ch == STK_UNIVERSAL) { - 3e8c: 86 35 cpi r24, 0x56 ; 86 - 3e8e: 29 f4 brne .+10 ; 0x3e9a <main+0x9a> - // UNIVERSAL command is ignored - getNch(4); - 3e90: 84 e0 ldi r24, 0x04 ; 4 - 3e92: ac d0 rcall .+344 ; 0x3fec <verifySpace+0xc> - putch(0x00); - 3e94: 80 e0 ldi r24, 0x00 ; 0 - 3e96: 71 d0 rcall .+226 ; 0x3f7a <putch> - 3e98: 6d c0 rjmp .+218 ; 0x3f74 <main+0x174> - } - /* Write memory, length is big endian and is in bytes */ - else if(ch == STK_PROG_PAGE) { - 3e9a: 84 36 cpi r24, 0x64 ; 100 - 3e9c: 09 f0 breq .+2 ; 0x3ea0 <main+0xa0> - 3e9e: 43 c0 rjmp .+134 ; 0x3f26 <main+0x126> - // PROGRAM PAGE - we support flash programming only, not EEPROM - uint8_t *bufPtr; - uint16_t addrPtr; - - getLen(); - 3ea0: 8f d0 rcall .+286 ; 0x3fc0 <getLen> - - // Immediately start page erase - this will 4.5ms - boot_page_erase((uint16_t)(void*)address); - 3ea2: e0 91 00 02 lds r30, 0x0200 - 3ea6: f0 91 01 02 lds r31, 0x0201 - 3eaa: 83 e0 ldi r24, 0x03 ; 3 - 3eac: 80 93 57 00 sts 0x0057, r24 - 3eb0: e8 95 spm - 3eb2: c0 e0 ldi r28, 0x00 ; 0 - 3eb4: d1 e0 ldi r29, 0x01 ; 1 - - // While that is going on, read in page contents - bufPtr = buff; - do *bufPtr++ = getch(); - 3eb6: 70 d0 rcall .+224 ; 0x3f98 <getch> - 3eb8: 89 93 st Y+, r24 - while (--length); - 3eba: 80 91 02 02 lds r24, 0x0202 - 3ebe: 81 50 subi r24, 0x01 ; 1 - 3ec0: 80 93 02 02 sts 0x0202, r24 - 3ec4: 88 23 and r24, r24 - 3ec6: b9 f7 brne .-18 ; 0x3eb6 <main+0xb6> - - // Read command terminator, start reply - verifySpace(); - 3ec8: 8b d0 rcall .+278 ; 0x3fe0 <verifySpace> - - // If only a partial page is to be programmed, the erase might not be complete. - // So check that here - boot_spm_busy_wait(); - 3eca: 07 b6 in r0, 0x37 ; 55 - 3ecc: 00 fc sbrc r0, 0 - 3ece: fd cf rjmp .-6 ; 0x3eca <main+0xca> - } -#endif - - // Copy buffer into programming buffer - bufPtr = buff; - addrPtr = (uint16_t)(void*)address; - 3ed0: 40 91 00 02 lds r20, 0x0200 - 3ed4: 50 91 01 02 lds r21, 0x0201 - 3ed8: a0 e0 ldi r26, 0x00 ; 0 - 3eda: b1 e0 ldi r27, 0x01 ; 1 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - 3edc: 2c 91 ld r18, X - 3ede: 30 e0 ldi r19, 0x00 ; 0 - a |= (*bufPtr++) << 8; - 3ee0: 11 96 adiw r26, 0x01 ; 1 - 3ee2: 8c 91 ld r24, X - 3ee4: 11 97 sbiw r26, 0x01 ; 1 - 3ee6: 90 e0 ldi r25, 0x00 ; 0 - 3ee8: 98 2f mov r25, r24 - 3eea: 88 27 eor r24, r24 - 3eec: 82 2b or r24, r18 - 3eee: 93 2b or r25, r19 -#ifdef VIRTUAL_BOOT_PARTITION -#define rstVect (*(uint16_t*)(0x204)) -#define wdtVect (*(uint16_t*)(0x206)) -#endif -/* main program starts here */ -int main(void) { - 3ef0: 12 96 adiw r26, 0x02 ; 2 - ch = SPM_PAGESIZE / 2; - do { - uint16_t a; - a = *bufPtr++; - a |= (*bufPtr++) << 8; - boot_page_fill((uint16_t)(void*)addrPtr,a); - 3ef2: fa 01 movw r30, r20 - 3ef4: 0c 01 movw r0, r24 - 3ef6: d0 92 57 00 sts 0x0057, r13 - 3efa: e8 95 spm - 3efc: 11 24 eor r1, r1 - addrPtr += 2; - 3efe: 4e 5f subi r20, 0xFE ; 254 - 3f00: 5f 4f sbci r21, 0xFF ; 255 - } while (--ch); - 3f02: f1 e0 ldi r31, 0x01 ; 1 - 3f04: a0 38 cpi r26, 0x80 ; 128 - 3f06: bf 07 cpc r27, r31 - 3f08: 49 f7 brne .-46 ; 0x3edc <main+0xdc> - - // Write from programming buffer - boot_page_write((uint16_t)(void*)address); - 3f0a: e0 91 00 02 lds r30, 0x0200 - 3f0e: f0 91 01 02 lds r31, 0x0201 - 3f12: e0 92 57 00 sts 0x0057, r14 - 3f16: e8 95 spm - boot_spm_busy_wait(); - 3f18: 07 b6 in r0, 0x37 ; 55 - 3f1a: 00 fc sbrc r0, 0 - 3f1c: fd cf rjmp .-6 ; 0x3f18 <main+0x118> - -#if defined(RWWSRE) - // Reenable read access to flash - boot_rww_enable(); - 3f1e: f0 92 57 00 sts 0x0057, r15 - 3f22: e8 95 spm - 3f24: 27 c0 rjmp .+78 ; 0x3f74 <main+0x174> -#endif - - } - /* Read memory block mode, length is big endian. */ - else if(ch == STK_READ_PAGE) { - 3f26: 84 37 cpi r24, 0x74 ; 116 - 3f28: b9 f4 brne .+46 ; 0x3f58 <main+0x158> - // READ PAGE - we only read flash - getLen(); - 3f2a: 4a d0 rcall .+148 ; 0x3fc0 <getLen> - verifySpace(); - 3f2c: 59 d0 rcall .+178 ; 0x3fe0 <verifySpace> - else ch = pgm_read_byte_near(address); - address++; - putch(ch); - } while (--length); -#else - do putch(pgm_read_byte_near(address++)); - 3f2e: e0 91 00 02 lds r30, 0x0200 - 3f32: f0 91 01 02 lds r31, 0x0201 - 3f36: 31 96 adiw r30, 0x01 ; 1 - 3f38: f0 93 01 02 sts 0x0201, r31 - 3f3c: e0 93 00 02 sts 0x0200, r30 - 3f40: 31 97 sbiw r30, 0x01 ; 1 - 3f42: e4 91 lpm r30, Z+ - 3f44: 8e 2f mov r24, r30 - 3f46: 19 d0 rcall .+50 ; 0x3f7a <putch> - while (--length); - 3f48: 80 91 02 02 lds r24, 0x0202 - 3f4c: 81 50 subi r24, 0x01 ; 1 - 3f4e: 80 93 02 02 sts 0x0202, r24 - 3f52: 88 23 and r24, r24 - 3f54: 61 f7 brne .-40 ; 0x3f2e <main+0x12e> - 3f56: 0e c0 rjmp .+28 ; 0x3f74 <main+0x174> -#endif - } - - /* Get device signature bytes */ - else if(ch == STK_READ_SIGN) { - 3f58: 85 37 cpi r24, 0x75 ; 117 - 3f5a: 39 f4 brne .+14 ; 0x3f6a <main+0x16a> - // READ SIGN - return what Avrdude wants to hear - verifySpace(); - 3f5c: 41 d0 rcall .+130 ; 0x3fe0 <verifySpace> - putch(SIGNATURE_0); - 3f5e: 8e e1 ldi r24, 0x1E ; 30 - 3f60: 0c d0 rcall .+24 ; 0x3f7a <putch> - putch(SIGNATURE_1); - 3f62: 84 e9 ldi r24, 0x94 ; 148 - 3f64: 0a d0 rcall .+20 ; 0x3f7a <putch> - putch(SIGNATURE_2); - 3f66: 86 e0 ldi r24, 0x06 ; 6 - 3f68: 96 cf rjmp .-212 ; 0x3e96 <main+0x96> - } - else if (ch == 'Q') { - 3f6a: 81 35 cpi r24, 0x51 ; 81 - 3f6c: 11 f4 brne .+4 ; 0x3f72 <main+0x172> - // Adaboot no-wait mod - watchdogConfig(WATCHDOG_16MS); - 3f6e: 88 e0 ldi r24, 0x08 ; 8 - 3f70: 2c d0 rcall .+88 ; 0x3fca <watchdogConfig> - verifySpace(); - } - else { - // This covers the response to commands like STK_ENTER_PROGMODE - verifySpace(); - 3f72: 36 d0 rcall .+108 ; 0x3fe0 <verifySpace> - } - putch(STK_OK); - 3f74: 80 e1 ldi r24, 0x10 ; 16 - 3f76: 01 d0 rcall .+2 ; 0x3f7a <putch> - 3f78: 63 cf rjmp .-314 ; 0x3e40 <main+0x40> - -00003f7a <putch>: -void putch(char ch) { -#ifndef SOFT_UART - while (!(UCSR0A & _BV(UDRE0))); - UDR0 = ch; -#else - __asm__ __volatile__ ( - 3f7a: 2a e0 ldi r18, 0x0A ; 10 - 3f7c: 30 e0 ldi r19, 0x00 ; 0 - 3f7e: 80 95 com r24 - 3f80: 08 94 sec - 3f82: 10 f4 brcc .+4 ; 0x3f88 <putch+0xe> - 3f84: 59 98 cbi 0x0b, 1 ; 11 - 3f86: 02 c0 rjmp .+4 ; 0x3f8c <putch+0x12> - 3f88: 59 9a sbi 0x0b, 1 ; 11 - 3f8a: 00 00 nop - 3f8c: 15 d0 rcall .+42 ; 0x3fb8 <uartDelay> - 3f8e: 14 d0 rcall .+40 ; 0x3fb8 <uartDelay> - 3f90: 86 95 lsr r24 - 3f92: 2a 95 dec r18 - 3f94: b1 f7 brne .-20 ; 0x3f82 <putch+0x8> - [uartBit] "I" (UART_TX_BIT) - : - "r25" - ); -#endif -} - 3f96: 08 95 ret - -00003f98 <getch>: - return getch(); -} - -// Watchdog functions. These are only safe with interrupts turned off. -void watchdogReset() { - __asm__ __volatile__ ( - 3f98: a8 95 wdr -#ifdef LED_DATA_FLASH - LED_PIN |= _BV(LED); -#endif - - return ch; -} - 3f9a: 29 e0 ldi r18, 0x09 ; 9 - 3f9c: 30 e0 ldi r19, 0x00 ; 0 - 3f9e: 48 99 sbic 0x09, 0 ; 9 - 3fa0: fe cf rjmp .-4 ; 0x3f9e <getch+0x6> - 3fa2: 0a d0 rcall .+20 ; 0x3fb8 <uartDelay> - 3fa4: 09 d0 rcall .+18 ; 0x3fb8 <uartDelay> - 3fa6: 08 d0 rcall .+16 ; 0x3fb8 <uartDelay> - 3fa8: 88 94 clc - 3faa: 48 99 sbic 0x09, 0 ; 9 - 3fac: 08 94 sec - 3fae: 2a 95 dec r18 - 3fb0: 11 f0 breq .+4 ; 0x3fb6 <getch+0x1e> - 3fb2: 87 95 ror r24 - 3fb4: f7 cf rjmp .-18 ; 0x3fa4 <getch+0xc> - 3fb6: 08 95 ret - -00003fb8 <uartDelay>: -#if UART_B_VALUE > 255 -#error Baud rate too slow for soft UART -#endif - -void uartDelay() { - __asm__ __volatile__ ( - 3fb8: 98 e0 ldi r25, 0x08 ; 8 - 3fba: 9a 95 dec r25 - 3fbc: f1 f7 brne .-4 ; 0x3fba <uartDelay+0x2> - 3fbe: 08 95 ret - -00003fc0 <getLen>: - } while (--count); -} -#endif - -uint8_t getLen() { - getch(); - 3fc0: eb df rcall .-42 ; 0x3f98 <getch> - length = getch(); - 3fc2: ea df rcall .-44 ; 0x3f98 <getch> - 3fc4: 80 93 02 02 sts 0x0202, r24 - return getch(); -} - 3fc8: e7 cf rjmp .-50 ; 0x3f98 <getch> - -00003fca <watchdogConfig>: - "wdr\n" - ); -} - -void watchdogConfig(uint8_t x) { - WDTCSR = _BV(WDCE) | _BV(WDE); - 3fca: e0 e6 ldi r30, 0x60 ; 96 - 3fcc: f0 e0 ldi r31, 0x00 ; 0 - 3fce: 98 e1 ldi r25, 0x18 ; 24 - 3fd0: 90 83 st Z, r25 - WDTCSR = x; - 3fd2: 80 83 st Z, r24 -} - 3fd4: 08 95 ret - -00003fd6 <appStart>: - -void appStart() { - watchdogConfig(WATCHDOG_OFF); - 3fd6: 80 e0 ldi r24, 0x00 ; 0 - 3fd8: f8 df rcall .-16 ; 0x3fca <watchdogConfig> - __asm__ __volatile__ ( - 3fda: ee 27 eor r30, r30 - 3fdc: ff 27 eor r31, r31 - 3fde: 09 94 ijmp - -00003fe0 <verifySpace>: - do getch(); while (--count); - verifySpace(); -} - -void verifySpace() { - if (getch() != CRC_EOP) appStart(); - 3fe0: db df rcall .-74 ; 0x3f98 <getch> - 3fe2: 80 32 cpi r24, 0x20 ; 32 - 3fe4: 09 f0 breq .+2 ; 0x3fe8 <verifySpace+0x8> - 3fe6: f7 df rcall .-18 ; 0x3fd6 <appStart> - putch(STK_INSYNC); - 3fe8: 84 e1 ldi r24, 0x14 ; 20 -} - 3fea: c7 cf rjmp .-114 ; 0x3f7a <putch> - ::[count] "M" (UART_B_VALUE) - ); -} -#endif - -void getNch(uint8_t count) { - 3fec: 1f 93 push r17 - 3fee: 18 2f mov r17, r24 - -00003ff0 <getNch>: - do getch(); while (--count); - 3ff0: d3 df rcall .-90 ; 0x3f98 <getch> - 3ff2: 11 50 subi r17, 0x01 ; 1 - 3ff4: e9 f7 brne .-6 ; 0x3ff0 <getNch> - verifySpace(); - 3ff6: f4 df rcall .-24 ; 0x3fe0 <verifySpace> -} - 3ff8: 1f 91 pop r17 - 3ffa: 08 95 ret diff --git a/bootloaders/optiboot/pin_defs.h b/bootloaders/optiboot/pin_defs.h new file mode 100644 index 0000000..27d7772 --- /dev/null +++ b/bootloaders/optiboot/pin_defs.h @@ -0,0 +1,80 @@ +#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__) +/* Onboard LED is connected to pin PB0 on Sanguino */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB0 + +/* Ports for soft UART */ +#ifdef SOFT_UART +#define UART_PORT PORTD +#define UART_PIN PIND +#define UART_DDR DDRD +#define UART_TX_BIT 1 +#define UART_RX_BIT 0 +#endif +#endif + +/* Mega support */ +#if defined(__AVR_ATmega1280__) +/* Onboard LED is connected to pin PB7 on Arduino Mega */ +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN PINB +#define LED PINB7 + +/* Ports for soft UART */ +#ifdef SOFT_UART +#define UART_PORT PORTE +#define UART_PIN PINE +#define UART_DDR DDRE +#define UART_TX_BIT 1 +#define UART_RX_BIT 0 +#endif +#endif diff --git a/bootloaders/optiboot/stk500.h b/bootloaders/optiboot/stk500.h new file mode 100644 index 0000000..ca0dd91 --- /dev/null +++ b/bootloaders/optiboot/stk500.h @@ -0,0 +1,39 @@ +/* STK500 constants list, from AVRDUDE */ +#define STK_OK 0x10 +#define STK_FAILED 0x11 // Not used +#define STK_UNKNOWN 0x12 // Not used +#define STK_NODEVICE 0x13 // Not used +#define STK_INSYNC 0x14 // ' ' +#define STK_NOSYNC 0x15 // Not used +#define ADC_CHANNEL_ERROR 0x16 // Not used +#define ADC_MEASURE_OK 0x17 // Not used +#define PWM_CHANNEL_ERROR 0x18 // Not used +#define PWM_ADJUST_OK 0x19 // Not used +#define CRC_EOP 0x20 // 'SPACE' +#define STK_GET_SYNC 0x30 // '0' +#define STK_GET_SIGN_ON 0x31 // '1' +#define STK_SET_PARAMETER 0x40 // '@' +#define STK_GET_PARAMETER 0x41 // 'A' +#define STK_SET_DEVICE 0x42 // 'B' +#define STK_SET_DEVICE_EXT 0x45 // 'E' +#define STK_ENTER_PROGMODE 0x50 // 'P' +#define STK_LEAVE_PROGMODE 0x51 // 'Q' +#define STK_CHIP_ERASE 0x52 // 'R' +#define STK_CHECK_AUTOINC 0x53 // 'S' +#define STK_LOAD_ADDRESS 0x55 // 'U' +#define STK_UNIVERSAL 0x56 // 'V' +#define STK_PROG_FLASH 0x60 // '`' +#define STK_PROG_DATA 0x61 // 'a' +#define STK_PROG_FUSE 0x62 // 'b' +#define STK_PROG_LOCK 0x63 // 'c' +#define STK_PROG_PAGE 0x64 // 'd' +#define STK_PROG_FUSE_EXT 0x65 // 'e' +#define STK_READ_FLASH 0x70 // 'p' +#define STK_READ_DATA 0x71 // 'q' +#define STK_READ_FUSE 0x72 // 'r' +#define STK_READ_LOCK 0x73 // 's' +#define STK_READ_PAGE 0x74 // 't' +#define STK_READ_SIGN 0x75 // 'u' +#define STK_READ_OSCCAL 0x76 // 'v' +#define STK_READ_FUSE_EXT 0x77 // 'w' +#define STK_READ_OSCCAL_EXT 0x78 // 'x' diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index ebdbe9a..bfec943 100755 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -40,7 +40,12 @@ extern "C"{ #define FALLING 2 #define RISING 3 -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +#define DEFAULT 0 +#define EXTERNAL 1 +#define INTERNAL 2 +#else +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__) #define INTERNAL1V1 2 #define INTERNAL2V56 3 #else @@ -48,6 +53,7 @@ extern "C"{ #endif #define DEFAULT 1 #define EXTERNAL 0 +#endif // undefine stdlib's abs if encountered #ifdef abs @@ -67,8 +73,8 @@ extern "C"{ #define noInterrupts() cli() #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) -#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) ) -#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) #define lowByte(w) ((uint8_t) ((w) & 0xff)) #define highByte(w) ((uint8_t) ((w) >> 8)) @@ -142,6 +148,7 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; #define NOT_A_PIN 0 #define NOT_A_PORT 0 +#ifdef ARDUINO_MAIN #define PA 1 #define PB 2 #define PC 3 @@ -153,6 +160,7 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; #define PJ 10 #define PK 11 #define PL 12 +#endif #define NOT_ON_TIMER 0 #define TIMER0A 1 @@ -169,9 +177,10 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; #define TIMER4A 11 #define TIMER4B 12 #define TIMER4C 13 -#define TIMER5A 14 -#define TIMER5B 15 -#define TIMER5C 16 +#define TIMER4D 14 +#define TIMER5A 15 +#define TIMER5B 16 +#define TIMER5C 17 #ifdef __cplusplus } // extern "C" @@ -202,4 +211,4 @@ long map(long, long, long, long, long); #include "pins_arduino.h" -#endif
\ No newline at end of file +#endif diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp new file mode 100644 index 0000000..14a0eae --- /dev/null +++ b/cores/arduino/CDC.cpp @@ -0,0 +1,175 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include <avr/wdt.h> + +#if defined(USBCON) +#ifdef CDC_ENABLED + +void Reboot() +{ + USB.detach(); + cli(); + asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB +} + +typedef struct +{ + u32 dwDTERate; + u8 bCharFormat; + u8 bParityType; + u8 bDataBits; + u8 lineState; +} LineInfo; + +static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; + +#define WEAK __attribute__ ((weak)) + +extern const CDCDescriptor _cdcInterface PROGMEM; +const CDCDescriptor _cdcInterface = +{ + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) +}; + +int WEAK CDC_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); +} + +bool WEAK CDC_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (CDC_GET_LINE_CODING == r) + { + USB_SendControl(0,(void*)&_usbLineInfo,7); + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (CDC_SET_LINE_CODING == r) + { + USB_RecvControl((void*)&_usbLineInfo,7); + return true; + } + + if (CDC_SET_CONTROL_LINE_STATE == r) + { + if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) // auto-reset is triggered when the port, already open at 1200 bps, is closed + Reboot(); + _usbLineInfo.lineState = setup.wValueL; + return true; + } + } + return false; +} + + +int _serialPeek = -1; +void Serial_::begin(uint16_t baud_count) +{ +} + +void Serial_::end(void) +{ +} + +int Serial_::available(void) +{ + u8 avail = USB_Available(CDC_RX); + if (_serialPeek != -1) + avail++; + return avail; +} + +// peek is nasty +int Serial_::peek(void) +{ + if (_serialPeek == -1) + _serialPeek = read(); + return _serialPeek; +} + +int Serial_::read(void) +{ + int c; + if (_serialPeek != -1) + { + c = _serialPeek; + _serialPeek = -1; + } else { + c = USB_Recv(CDC_RX); + } + return c; +} + +void Serial_::flush(void) +{ + USB_Flush(CDC_TX); +} + +size_t Serial_::write(uint8_t c) +{ + /* only try to send bytes if the high-level CDC connection itself + is open (not just the pipe) - the OS should set lineState when the port + is opened and clear lineState when the port is closed. + bytes sent before the user opens the connection or after + the connection is closed are lost - just like with a UART. */ + + // TODO - ZE - check behavior on different OSes and test what happens if an + // open connection isn't broken cleanly (cable is yanked out, host dies + // or locks up, or host virtual serial port hangs) + if (_usbLineInfo.lineState > 0) { + int r = USB_Send(CDC_TX,&c,1); + if (r > 0) { + return r; + } else { + setWriteError(); + return 0; + } + } + setWriteError(); + return 0; +} + +Serial_ Serial; + +#endif +#endif /* if defined(USBCON) */
\ No newline at end of file diff --git a/cores/arduino/Client.h b/cores/arduino/Client.h new file mode 100644 index 0000000..ea13483 --- /dev/null +++ b/cores/arduino/Client.h @@ -0,0 +1,26 @@ +#ifndef client_h +#define client_h +#include "Print.h" +#include "Stream.h" +#include "IPAddress.h" + +class Client : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual operator bool() = 0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp new file mode 100644 index 0000000..8ed1566 --- /dev/null +++ b/cores/arduino/HID.cpp @@ -0,0 +1,446 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include "USBDesc.h" + +#if defined(USBCON) +#ifdef HID_ENABLED + +//#define RAWHID_ENABLED + +// Singletons for mouse and keyboard + +Mouse_ Mouse; +Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ + +// HID report descriptor + +#define LSB(_x) ((_x) & 0xFF) +#define MSB(_x) ((_x) >> 8) + +#define RAWHID_USAGE_PAGE 0xFFC0 +#define RAWHID_USAGE 0x0C00 +#define RAWHID_TX_SIZE 64 +#define RAWHID_RX_SIZE 64 + +extern const u8 _hidReportDescriptor[] PROGMEM; +const u8 _hidReportDescriptor[] = { + + // Mouse + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x85, 0x01, // REPORT_ID (1) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + + // Keyboard + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x02, // REPORT_ID (2) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0, // END_COLLECTION + +#if RAWHID_ENABLED + // RAW HID + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + + 0xA1, 0x01, // Collection 0x01 + 0x85, 0x03, // REPORT_ID (3) + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + + 0x95, 64, // report count TX + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + + 0x95, 64, // report count RX + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +#endif +}; + +extern const HIDDescriptor _hidInterface PROGMEM; +const HIDDescriptor _hidInterface = +{ + D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_HIDREPORT(sizeof(_hidReportDescriptor)), + D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) +}; + +//================================================================================ +//================================================================================ +// Driver + +u8 _hid_protocol = 1; +u8 _hid_idle = 1; + +#define WEAK __attribute__ ((weak)) +#define WEAK + +int WEAK HID_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 1; // uses 1 + return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface)); +} + +int WEAK HID_GetDescriptor(int i) +{ + return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor)); +} + +void WEAK HID_SendReport(u8 id, const void* data, int len) +{ + USB_Send(HID_TX, &id, 1); + USB_Send(HID_TX | TRANSFER_RELEASE,data,len); +} + +bool WEAK HID_Setup(Setup& setup) +{ + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (HID_GET_REPORT == r) + { + //HID_GetReport(); + return true; + } + if (HID_GET_PROTOCOL == r) + { + //Send8(_hid_protocol); // TODO + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (HID_SET_PROTOCOL == r) + { + _hid_protocol = setup.wValueL; + return true; + } + + if (HID_SET_IDLE == r) + { + _hid_idle = setup.wValueL; + return true; + } + } + return false; +} + +//================================================================================ +//================================================================================ +// Mouse + +Mouse_::Mouse_() : _buttons(0) +{ +} + +void Mouse_::click(uint8_t b) +{ + _buttons = b; + move(0,0,0); + _buttons = 0; + move(0,0,0); +} + +void Mouse_::move(signed char x, signed char y, signed char wheel) +{ + u8 m[4]; + m[0] = _buttons; + m[1] = x; + m[2] = y; + m[3] = wheel; + HID_SendReport(1,m,4); +} + +void Mouse_::buttons(uint8_t b) +{ + if (b != _buttons) + { + _buttons = b; + move(0,0,0); + } +} + +void Mouse_::press(uint8_t b) +{ + buttons(_buttons | b); +} + +void Mouse_::release(uint8_t b) +{ + buttons(_buttons & ~b); +} + +bool Mouse_::isPressed(uint8_t b) +{ + if (b & _buttons > 0) + return true; + return false; +} + +//================================================================================ +//================================================================================ +// Keyboard + +Keyboard_::Keyboard_() : _keyMap(0) +{ +} + +void Keyboard_::sendReport(KeyReport* keys) +{ + HID_SendReport(2,keys,sizeof(KeyReport)); +} + +void Keyboard_::setKeyMap(KeyMap* keyMap) +{ + _keyMap = keyMap; +} + +extern +const uint8_t _asciimap[128] PROGMEM; + +#define SHIFT 0x80 +const uint8_t _asciimap[128] = +{ + 0x00, // NUL + 0x00, // SOH + 0x00, // STX + 0x00, // ETX + 0x00, // EOT + 0x00, // ENQ + 0x00, // ACK + 0x00, // BEL + 0x2a, // BS Backspace + 0x2b, // TAB Tab + 0x28, // LF Enter + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI + 0x00, // DEL + 0x00, // DC1 + 0x00, // DC2 + 0x00, // DC3 + 0x00, // DC4 + 0x00, // NAK + 0x00, // SYN + 0x00, // ETB + 0x00, // CAN + 0x00, // EM + 0x00, // SUB + 0x00, // ESC + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US + + 0x2c, // ' ' + 0x1e|SHIFT, // ! + 0x34|SHIFT, // " + 0x20|SHIFT, // # + 0x21|SHIFT, // $ + 0x22|SHIFT, // % + 0x24|SHIFT, // & + 0x34, // ' + 0x26|SHIFT, // ( + 0x27|SHIFT, // ) + 0x25|SHIFT, // * + 0x2e|SHIFT, // + + 0x36, // , + 0x2d, // - + 0x37, // . + 0x38, // / + 0x27, // 0 + 0x1e, // 1 + 0x1f, // 2 + 0x20, // 3 + 0x21, // 4 + 0x22, // 5 + 0x23, // 6 + 0x24, // 7 + 0x25, // 8 + 0x26, // 9 + 0x33|SHIFT, // : + 0x33, // ; + 0x36|SHIFT, // < + 0x2e, // = + 0x37|SHIFT, // > + 0x38|SHIFT, // ? + 0x1f|SHIFT, // @ + 0x04|SHIFT, // A + 0x05|SHIFT, // B + 0x06|SHIFT, // C + 0x07|SHIFT, // D + 0x08|SHIFT, // E + 0x09|SHIFT, // F + 0x0a|SHIFT, // G + 0x0b|SHIFT, // H + 0x0c|SHIFT, // I + 0x0d|SHIFT, // J + 0x0e|SHIFT, // K + 0x0f|SHIFT, // L + 0x10|SHIFT, // M + 0x11|SHIFT, // N + 0x12|SHIFT, // O + 0x13|SHIFT, // P + 0x14|SHIFT, // Q + 0x15|SHIFT, // R + 0x16|SHIFT, // S + 0x17|SHIFT, // T + 0x18|SHIFT, // U + 0x19|SHIFT, // V + 0x1a|SHIFT, // W + 0x1b|SHIFT, // X + 0x1c|SHIFT, // Y + 0x1d|SHIFT, // Z + 0x2f, // [ + 0x31, // bslash + 0x30, // ] + 0x23|SHIFT, // ^ + 0x2d|SHIFT, // _ + 0x35, // ` + 0x04, // a + 0x05, // b + 0x06, // c + 0x07, // d + 0x08, // e + 0x09, // f + 0x0a, // g + 0x0b, // h + 0x0c, // i + 0x0d, // j + 0x0e, // k + 0x0f, // l + 0x10, // m + 0x11, // n + 0x12, // o + 0x13, // p + 0x14, // q + 0x15, // r + 0x16, // s + 0x17, // t + 0x18, // u + 0x19, // v + 0x1a, // w + 0x1b, // x + 0x1c, // y + 0x1d, // z + 0x2f|SHIFT, // + 0x31|SHIFT, // | + 0x30|SHIFT, // } + 0x35|SHIFT, // ~ + 0 // DEL +}; + +uint8_t USBPutChar(uint8_t c); +size_t Keyboard_::write(uint8_t c) +{ + // Keydown + { + KeyReport keys = {0}; + if (_keyMap) + _keyMap->charToKey(c,&keys); + else + { + if (c >= 128) { + setWriteError(); + return 0; + } + c = pgm_read_byte(_asciimap + c); + if (!c) { + setWriteError(); + return 0; + } + if (c & 0x80) + { + keys.modifiers |= KEY_MODIFIER_LEFT_SHIFT; + c &= 0x7F; + } + keys.keys[0] = c; + } + sendReport(&keys); + } + // Keyup + { + KeyReport keys = {0}; + sendReport(&keys); + } + return 1; +} + +#endif + +#endif /* if defined(USBCON) */
\ No newline at end of file diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index db6b149..1b1fa71 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -50,6 +50,10 @@ struct ring_buffer volatile int tail; }; +#if defined(USBCON) + ring_buffer rx_buffer = { { 0 }, 0, 0}; + ring_buffer tx_buffer = { { 0 }, 0, 0}; +#endif #if defined(UBRRH) || defined(UBRR0H) ring_buffer rx_buffer = { { 0 }, 0, 0 }; ring_buffer tx_buffer = { { 0 }, 0, 0 }; @@ -81,13 +85,17 @@ inline void store_char(unsigned char c, ring_buffer *buffer) } } +#if !defined(USART0_RX_vect) && defined(USART1_RX_vect) +// do nothing - on the 32u4 the first USART is USART1 +#else #if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \ !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \ !defined(SIG_UART_RECV) - #error Don't know what the Data Received vector is called for the first UART + #error "Don't know what the Data Received vector is called for the first UART" #else void serialEvent() __attribute__((weak)); void serialEvent() {} + #define serialEvent_implemented #if defined(USART_RX_vect) SIGNAL(USART_RX_vect) #elif defined(SIG_USART0_RECV) @@ -108,18 +116,18 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #error UDR not defined #endif store_char(c, &rx_buffer); - serialEvent(); } #endif +#endif #if defined(USART1_RX_vect) void serialEvent1() __attribute__((weak)); void serialEvent1() {} + #define serialEvent1_implemented SIGNAL(USART1_RX_vect) { unsigned char c = UDR1; store_char(c, &rx_buffer1); - serialEvent1(); } #elif defined(SIG_USART1_RECV) #error SIG_USART1_RECV @@ -128,11 +136,11 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #if defined(USART2_RX_vect) && defined(UDR2) void serialEvent2() __attribute__((weak)); void serialEvent2() {} + #define serialEvent2_implemented SIGNAL(USART2_RX_vect) { unsigned char c = UDR2; store_char(c, &rx_buffer2); - serialEvent2(); } #elif defined(SIG_USART2_RECV) #error SIG_USART2_RECV @@ -141,19 +149,38 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #if defined(USART3_RX_vect) && defined(UDR3) void serialEvent3() __attribute__((weak)); void serialEvent3() {} + #define serialEvent3_implemented SIGNAL(USART3_RX_vect) { unsigned char c = UDR3; store_char(c, &rx_buffer3); - serialEvent3(); } #elif defined(SIG_USART3_RECV) #error SIG_USART3_RECV #endif +void serialEventRun(void) +{ +#ifdef serialEvent_implemented + if (Serial.available()) serialEvent(); +#endif +#ifdef serialEvent1_implemented + if (Serial1.available()) serialEvent1(); +#endif +#ifdef serialEvent2_implemented + if (Serial2.available()) serialEvent2(); +#endif +#ifdef serialEvent3_implemented + if (Serial3.available()) serialEvent3(); +#endif +} + +#if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect) +// do nothing - on the 32u4 the first USART is USART1 +#else #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) - #error Don't know what the Data Register Empty vector is called for the first UART + #error "Don't know what the Data Register Empty vector is called for the first UART" #else #if defined(UART0_UDRE_vect) ISR(UART0_UDRE_vect) @@ -188,6 +215,7 @@ ISR(USART_UDRE_vect) } } #endif +#endif #ifdef USART1_UDRE_vect ISR(USART1_UDRE_vect) @@ -352,12 +380,13 @@ void HardwareSerial::flush() ; } -void HardwareSerial::write(uint8_t c) +size_t HardwareSerial::write(uint8_t c) { int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; // If the output buffer is full, there's nothing for it other than to // wait for the interrupt handler to empty it a bit + // ???: return 0 here instead? while (i == _tx_buffer->tail) ; @@ -365,6 +394,8 @@ void HardwareSerial::write(uint8_t c) _tx_buffer->head = i; sbi(*_ucsrb, _udrie); + + return 1; } // Preinstantiate Objects ////////////////////////////////////////////////////// @@ -374,7 +405,7 @@ void HardwareSerial::write(uint8_t c) #elif defined(UBRR0H) && defined(UBRR0L) HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0); #elif defined(USBCON) - #warning no serial port defined (port 0) + // do nothing - Serial object and buffers are initialized in CDC code #else #error no serial port defined (port 0) #endif diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index eefdcbe..176abe1 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -55,14 +55,15 @@ class HardwareSerial : public Stream virtual int peek(void); virtual int read(void); virtual void flush(void); - virtual void write(uint8_t); + virtual size_t write(uint8_t); using Print::write; // pull in write(str) and write(buf, size) from Print }; #if defined(UBRRH) || defined(UBRR0H) extern HardwareSerial Serial; #elif defined(USBCON) - #include "usb_api.h" + #include "USBAPI.h" +// extern HardwareSerial Serial_; #endif #if defined(UBRR1H) extern HardwareSerial Serial1; @@ -74,4 +75,6 @@ class HardwareSerial : public Stream extern HardwareSerial Serial3; #endif +extern void serialEventRun(void) __attribute__((weak)); + #endif diff --git a/libraries/Ethernet/IPAddress.cpp b/cores/arduino/IPAddress.cpp index 610ff4c..fe3deb7 100644 --- a/libraries/Ethernet/IPAddress.cpp +++ b/cores/arduino/IPAddress.cpp @@ -42,3 +42,15 @@ bool IPAddress::operator==(const uint8_t* addr) return memcmp(addr, _address, sizeof(_address)) == 0; } +size_t IPAddress::printTo(Print& p) const +{ + size_t n = 0; + for (int i =0; i < 3; i++) + { + n += p.print(_address[i], DEC); + n += p.print('.'); + } + n += p.print(_address[3], DEC); + return n; +} + diff --git a/libraries/Ethernet/IPAddress.h b/cores/arduino/IPAddress.h index 487e420..2585aec 100644 --- a/libraries/Ethernet/IPAddress.h +++ b/cores/arduino/IPAddress.h @@ -26,9 +26,11 @@ #ifndef IPAddress_h #define IPAddress_h +#include <Printable.h> + // A class to make it easier to handle and pass around IP addresses -class IPAddress { +class IPAddress : public Printable { private: uint8_t _address[4]; // IPv4 address // Access the raw byte array containing the address. Because this returns a pointer @@ -58,6 +60,8 @@ public: IPAddress& operator=(const uint8_t *address); IPAddress& operator=(uint32_t address); + virtual size_t printTo(Print& p) const; + friend class EthernetClass; friend class UDP; friend class Client; diff --git a/cores/arduino/Platform.h b/cores/arduino/Platform.h new file mode 100644 index 0000000..8b8f742 --- /dev/null +++ b/cores/arduino/Platform.h @@ -0,0 +1,23 @@ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#include <inttypes.h> +#include <avr/pgmspace.h> +#include <avr/eeprom.h> +#include <avr/interrupt.h> +#include <util/delay.h> + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + +#include "Arduino.h" + +#if defined(USBCON) + #include "USBDesc.h" + #include "USBCore.h" + #include "USBAPI.h" +#endif /* if defined(USBCON) */ + +#endif diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 0a580b7..ff9b154 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -30,156 +30,180 @@ // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ -void Print::write(const char *str) +size_t Print::write(const uint8_t *buffer, size_t size) { - while (*str) - write(*str++); -} - -/* default implementation: may be overridden */ -void Print::write(const uint8_t *buffer, size_t size) -{ - while (size--) - write(*buffer++); + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; } -void Print::print(const __FlashStringHelper *ifsh) +size_t Print::print(const __FlashStringHelper *ifsh) { const prog_char *p = (const prog_char *)ifsh; + size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); - if (c == 0) return; - write(c); + if (c == 0) break; + n += write(c); } + return n; } -void Print::print(const String &s) +size_t Print::print(const String &s) { - for (int i = 0; i < s.length(); i++) { - write(s[i]); + size_t n = 0; + for (uint16_t i = 0; i < s.length(); i++) { + n += write(s[i]); } + return n; } -void Print::print(const char str[]) +size_t Print::print(const char str[]) { - write(str); + return write(str); } -void Print::print(char c) +size_t Print::print(char c) { - write(c); + return write(c); } -void Print::print(unsigned char b, int base) +size_t Print::print(unsigned char b, int base) { - print((unsigned long) b, base); + return print((unsigned long) b, base); } -void Print::print(int n, int base) +size_t Print::print(int n, int base) { - print((long) n, base); + return print((long) n, base); } -void Print::print(unsigned int n, int base) +size_t Print::print(unsigned int n, int base) { - print((unsigned long) n, base); + return print((unsigned long) n, base); } -void Print::print(long n, int base) +size_t Print::print(long n, int base) { if (base == 0) { - write(n); + return write(n); } else if (base == 10) { if (n < 0) { - print('-'); + int t = print('-'); n = -n; + return printNumber(n, 10) + t; } - printNumber(n, 10); + return printNumber(n, 10); } else { - printNumber(n, base); + return printNumber(n, base); } } -void Print::print(unsigned long n, int base) +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) { - if (base == 0) write(n); - else printNumber(n, base); + size_t n = print(ifsh); + n += println(); + return n; } -void Print::print(double n, int digits) +size_t Print::print(const Printable& x) { - printFloat(n, digits); + return x.printTo(*this); } -void Print::println(const __FlashStringHelper *ifsh) +size_t Print::println(void) { - print(ifsh); - println(); + size_t n = print('\r'); + n += print('\n'); + return n; } -void Print::println(void) +size_t Print::println(const String &s) { - print('\r'); - print('\n'); + size_t n = print(s); + n += println(); + return n; } -void Print::println(const String &s) +size_t Print::println(const char c[]) { - print(s); - println(); + size_t n = print(c); + n += println(); + return n; } -void Print::println(const char c[]) +size_t Print::println(char c) { - print(c); - println(); + size_t n = print(c); + n += println(); + return n; } -void Print::println(char c) +size_t Print::println(unsigned char b, int base) { - print(c); - println(); + size_t n = print(b, base); + n += println(); + return n; } -void Print::println(unsigned char b, int base) +size_t Print::println(int num, int base) { - print(b, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(int n, int base) +size_t Print::println(unsigned int num, int base) { - print(n, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(unsigned int n, int base) +size_t Print::println(long num, int base) { - print(n, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(long n, int base) +size_t Print::println(unsigned long num, int base) { - print(n, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(unsigned long n, int base) +size_t Print::println(double num, int digits) { - print(n, base); - println(); + size_t n = print(num, digits); + n += println(); + return n; } -void Print::println(double n, int digits) +size_t Print::println(const Printable& x) { - print(n, digits); - println(); + size_t n = print(x); + n += println(); + return n; } // Private Methods ///////////////////////////////////////////////////////////// -void Print::printNumber(unsigned long n, uint8_t base) { +size_t Print::printNumber(unsigned long n, uint8_t base) { char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -195,15 +219,17 @@ void Print::printNumber(unsigned long n, uint8_t base) { *--str = c < 10 ? c + '0' : c + 'A' - 10; } while(n); - write(str); + return write(str); } -void Print::printFloat(double number, uint8_t digits) +size_t Print::printFloat(double number, uint8_t digits) { + size_t n = 0; + // Handle negative numbers if (number < 0.0) { - print('-'); + n += print('-'); number = -number; } @@ -217,18 +243,21 @@ void Print::printFloat(double number, uint8_t digits) // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; - print(int_part); + n += print(int_part); // Print the decimal point, but only if there are digits beyond - if (digits > 0) - print("."); + if (digits > 0) { + n += print("."); + } // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int toPrint = int(remainder); - print(toPrint); + n += print(toPrint); remainder -= toPrint; } + + return n; } diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index a447753..1af6b72 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -24,6 +24,7 @@ #include <stdio.h> // for size_t #include "WString.h" +#include "Printable.h" #define DEC 10 #define HEX 16 @@ -33,35 +34,45 @@ class Print { private: - void printNumber(unsigned long, uint8_t); - void printFloat(double, uint8_t); + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } public: - virtual void write(uint8_t) = 0; - virtual void write(const char *str); - virtual void write(const uint8_t *buffer, size_t size); + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); } + virtual size_t write(const uint8_t *buffer, size_t size); - void print(const __FlashStringHelper *); - void print(const String &); - void print(const char[]); - void print(char); - void print(unsigned char, int = DEC); - void print(int, int = DEC); - void print(unsigned int, int = DEC); - void print(long, int = DEC); - void print(unsigned long, int = DEC); - void print(double, int = 2); + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); - void println(const __FlashStringHelper *); - void println(const String &s); - void println(const char[]); - void println(char); - void println(unsigned char, int = DEC); - void println(int, int = DEC); - void println(unsigned int, int = DEC); - void println(long, int = DEC); - void println(unsigned long, int = DEC); - void println(double, int = 2); - void println(void); + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); }; #endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h new file mode 100644 index 0000000..d03c9af --- /dev/null +++ b/cores/arduino/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include <new.h> + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/cores/arduino/Server.h b/cores/arduino/Server.h new file mode 100644 index 0000000..9674c76 --- /dev/null +++ b/cores/arduino/Server.h @@ -0,0 +1,9 @@ +#ifndef server_h +#define server_h + +class Server : public Print { +public: + virtual void begin() =0; +}; + +#endif diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp new file mode 100644 index 0000000..5fad8dd --- /dev/null +++ b/cores/arduino/Stream.cpp @@ -0,0 +1,244 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, NULL); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + size_t index = 0; // maximum target string length is 64k bytes! + size_t termIndex = 0; + int c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = timedRead()) > 0){ + if( c == target[index]){ + //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); + if(++index >= targetLen){ // return true if all chars in the target match + return true; + } + } + else{ + index = 0; // reset index if any char does not match + } + if(termLen > 0 && c == terminator[termIndex]){ + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } + else + termIndex = 0; + } + return false; +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + boolean isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar){ + boolean isNegative = false; + boolean isFraction = false; + long value = 0; + char c; + float fraction = 1.0; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h index 93d8275..13f11be 100644 --- a/cores/arduino/Stream.h +++ b/cores/arduino/Stream.h @@ -15,6 +15,8 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis */ #ifndef Stream_h @@ -23,13 +25,70 @@ #include <inttypes.h> #include "Print.h" +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + class Stream : public Print { + private: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + public: virtual int available() = 0; virtual int read() = 0; virtual int peek() = 0; virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + // returns true if target string is found, false if timed out + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + + protected: + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(char skipChar); // as above but the given skipChar is ignored }; #endif diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h new file mode 100644 index 0000000..26a2032 --- /dev/null +++ b/cores/arduino/USBAPI.h @@ -0,0 +1,166 @@ + + +#ifndef __USBAPI__ +#define __USBAPI__ + +#if defined(USBCON) + +//================================================================================ +//================================================================================ +// USB + +class USB_ +{ +public: + USB_(); + bool configured(); + + void attach(); + void detach(); // Serial port goes down too... + void poll(); +}; +extern USB_ USB; + +//================================================================================ +//================================================================================ +// Serial over CDC (Serial1 is the physical port) + +class Serial_ : public Stream +{ +public: + void begin(uint16_t baud_count); + void end(void); + + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); +}; +extern Serial_ Serial; + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class Mouse_ +{ +private: + uint8_t _buttons; + void buttons(uint8_t b); +public: + Mouse_(); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default +}; +extern Mouse_ Mouse; + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_MODIFIER_LEFT_CTRL 0x01 +#define KEY_MODIFIER_LEFT_SHIFT 0x02 +#define KEY_MODIFIER_LEFT_ALT 0x04 +#define KEY_MODIFIER_LEFT_GUI 0x08 +#define KEY_MODIFIER_RIGHT_CTRL 0x010 +#define KEY_MODIFIER_RIGHT_SHIFT 0x020 +#define KEY_MODIFIER_RIGHT_ALT 0x040 +#define KEY_MODIFIER_RIGHT_GUI 0x080 + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct +{ + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +// Map a character into a key report +// Called from Print to map text to keycodes +class KeyMap +{ +public: + virtual void charToKey(int c, KeyReport* keyReport) = 0; +}; + +// +class Keyboard_ : public Print +{ +private: + KeyMap* _keyMap; + void sendReport(KeyReport* keys); + void setKeyMap(KeyMap* keyMap); +public: + Keyboard_(); + virtual size_t write(uint8_t); +}; +extern Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ +// Low level API + +typedef struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} Setup; + +//================================================================================ +//================================================================================ +// HID 'Driver' + +int HID_GetInterface(uint8_t* interfaceNum); +int HID_GetDescriptor(int i); +bool HID_Setup(Setup& setup); +void HID_SendReport(uint8_t id, const void* data, int len); + +//================================================================================ +//================================================================================ +// MSC 'Driver' + +int MSC_GetInterface(uint8_t* interfaceNum); +int MSC_GetDescriptor(int i); +bool MSC_Setup(Setup& setup); +bool MSC_Data(uint8_t rx,uint8_t tx); + +//================================================================================ +//================================================================================ +// CSC 'Driver' + +int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetDescriptor(int i); +bool CDC_Setup(Setup& setup); + +//================================================================================ +//================================================================================ + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +int USB_SendControl(uint8_t flags, const void* d, int len); +int USB_RecvControl(void* d, int len); + +uint8_t USB_Available(uint8_t ep); +int USB_Send(uint8_t ep, const void* data, int len); // blocking +int USB_Recv(uint8_t ep, void* data, int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif + +#endif /* if defined(USBCON) */
\ No newline at end of file diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp new file mode 100644 index 0000000..398bc73 --- /dev/null +++ b/cores/arduino/USBCore.cpp @@ -0,0 +1,660 @@ + + +/* Copyright (c) 2010, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#include "Platform.h" +#include "USBAPI.h" +#include "USBDesc.h" + +#if defined(USBCON) + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ +#define TX_RX_LED_PULSE_MS 100 +volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ +volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */ + +//================================================================== +//================================================================== + +extern const u16 STRING_LANGUAGE[] PROGMEM; +extern const u16 STRING_IPRODUCT[] PROGMEM; +extern const u16 STRING_IMANUFACTURER[] PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM; + +const u16 STRING_LANGUAGE[2] = { + (3<<8) | (2+2), + 0x0409 // English +}; + +const u16 STRING_IPRODUCT[17] = { + (3<<8) | (2+2*16), +#if USB_PID == USB_PID_LEONARDO + 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' +#elif USB_PID == USB_PID_MICRO + 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' ' +#endif +}; + +const u16 STRING_IMANUFACTURER[12] = { + (3<<8) | (2+2*11), + 'A','r','d','u','i','n','o',' ','L','L','C' +}; + +#ifdef CDC_ENABLED +#define DEVICE_CLASS 0x02 +#else +#define DEVICE_CLASS 0x00 +#endif + +// DEVICE DESCRIPTOR +const DeviceDescriptor USB_DeviceDescriptor = + D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +const DeviceDescriptor USB_DeviceDescriptorA = + D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); + +//================================================================== +//================================================================== + +volatile u8 _usbConfiguration = 0; + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1<<TXINI))); +} + +static inline void ClearIN(void) +{ + UEINTX = ~(1<<TXINI); +} + +static inline void WaitOUT(void) +{ + while (!(UEINTX & (1<<RXOUTI))) + ; +} + +static inline u8 WaitForINOrOUT() +{ + while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI)))) + ; + return (UEINTX & (1<<RXOUTI)) == 0; +} + +static inline void ClearOUT(void) +{ + UEINTX = ~(1<<RXOUTI); +} + +void Recv(volatile u8* data, u8 count) +{ + while (count--) + *data++ = UEDATX; + + RXLED1; // light the RX LED + RxLEDPulse = TX_RX_LED_PULSE_MS; +} + +static inline u8 Recv8() +{ + RXLED1; // light the RX LED + RxLEDPulse = TX_RX_LED_PULSE_MS; + + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; +} + +static inline u8 ReceivedSetupInt() +{ + return UEINTX & (1<<RXSTPI); +} + +static inline void ClearSetupInt() +{ + UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI)); +} + +static inline void Stall() +{ + UECONX = (1<<STALLRQ) | (1<<EPEN); +} + +static inline u8 ReadWriteAllowed() +{ + return UEINTX & (1<<RWAL); +} + +static inline u8 Stalled() +{ + return UEINTX & (1<<STALLEDI); +} + +static inline u8 FifoFree() +{ + return UEINTX & (1<<FIFOCON); +} + +static inline void ReleaseRX() +{ + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 +} + +static inline u8 FrameNumber() +{ + return UDFNUML; +} + +//================================================================== +//================================================================== + +u8 USBGetConfiguration(void) +{ + return _usbConfiguration; +} + +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + { + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + } +}; + +// Number of bytes, assumes a rx endpoint +u8 USB_Available(u8 ep) +{ + LockEP lock(ep); + return FifoByteCount(); +} + +// Non Blocking receive +// Return number of bytes read +int USB_Recv(u8 ep, void* d, int len) +{ + if (!_usbConfiguration || len < 0) + return -1; + + LockEP lock(ep); + u8 n = FifoByteCount(); + len = min(n,len); + n = len; + u8* dst = (u8*)d; + while (n--) + *dst++ = Recv8(); + if (len && !FifoByteCount()) // release empty buffer + ReleaseRX(); + + return len; +} + +// Recv 1 byte if ready +int USB_Recv(u8 ep) +{ + u8 c; + if (USB_Recv(ep,&c,1) != 1) + return -1; + return c; +} + +// Space in send EP +u8 USB_SendSpace(u8 ep) +{ + LockEP lock(ep); + if (!ReadWriteAllowed()) + return 0; + return 64 - FifoByteCount(); +} + +// Blocking Send of data to an endpoint +int USB_Send(u8 ep, const void* d, int len) +{ + if (!_usbConfiguration) + return -1; + + int r = len; + const u8* data = (const u8*)d; + u8 zero = ep & TRANSFER_ZERO; + u8 timeout = 250; // 250ms timeout on send? TODO + while (len) + { + u8 n = USB_SendSpace(ep); + if (n == 0) + { + if (!(--timeout)) + return -1; + delay(1); + continue; + } + + if (n > len) + n = len; + len -= n; + { + LockEP lock(ep); + if (ep & TRANSFER_ZERO) + { + while (n--) + Send8(0); + } + else if (ep & TRANSFER_PGM) + { + while (n--) + Send8(pgm_read_byte(data++)); + } + else + { + while (n--) + Send8(*data++); + } + if (!ReadWriteAllowed() || ((len == 0) && (ep & TRANSFER_RELEASE))) // Release full buffer + ReleaseTX(); + } + } + TXLED1; // light the TX LED + TxLEDPulse = TX_RX_LED_PULSE_MS; + return r; +} + +extern const u8 _initEndpoints[] PROGMEM; +const u8 _initEndpoints[] = +{ + 0, + +#ifdef CDC_ENABLED + EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM + EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT + EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED + EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT +#endif +}; + +#define EP_SINGLE_64 0x32 // EP0 +#define EP_DOUBLE_64 0x36 // Other endpoints + +static +void InitEP(u8 index, u8 type, u8 size) +{ + UENUM = index; + UECONX = 1; + UECFG0X = type; + UECFG1X = size; +} + +static +void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints); i++) + { + UENUM = i; + UECONX = 1; + UECFG0X = pgm_read_byte(_initEndpoints+i); + UECFG1X = EP_DOUBLE_64; + } + UERST = 0x7E; // And reset them + UERST = 0; +} + +// Handle CLASS_INTERFACE requests +static +bool ClassInterfaceRequest(Setup& setup) +{ + u8 i = setup.wIndex; + +#ifdef CDC_ENABLED + if (CDC_ACM_INTERFACE == i) + return CDC_Setup(setup); +#endif + +#ifdef HID_ENABLED + if (HID_INTERFACE == i) + return HID_Setup(setup); +#endif + return false; +} + +int _cmark; +int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + _cend = end; +} + +static +bool SendControl(u8 d) +{ + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + return false; + Send8(d); + if (!((_cmark + 1) & 0x3F)) + ClearIN(); // Fifo is full, release this packet + } + _cmark++; + return true; +}; + +// Clipped by _cmark/_cend +int USB_SendControl(u8 flags, const void* d, int len) +{ + int sent = len; + const u8* data = (const u8*)d; + bool pgm = flags & TRANSFER_PGM; + while (len--) + { + u8 c = pgm ? pgm_read_byte(data++) : *data++; + if (!SendControl(c)) + return -1; + } + return sent; +} + +// Does not timeout or cross fifo boundaries +// Will only work for transfers <= 64 bytes +// TODO +int USB_RecvControl(void* d, int len) +{ + WaitOUT(); + Recv((u8*)d,len); + ClearOUT(); + return len; +} + +int SendInterfaces() +{ + int total = 0; + u8 interfaces = 0; + +#ifdef CDC_ENABLED + total = CDC_GetInterface(&interfaces); +#endif + +#ifdef HID_ENABLED + total += HID_GetInterface(&interfaces); +#endif + + return interfaces; +} + +// Construct a dynamic configuration descriptor +// This really needs dynamic endpoint allocation etc +// TODO +static +bool SendConfiguration(int maxlen) +{ + // Count and measure interfaces + InitControl(0); + int interfaces = SendInterfaces(); + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); + + // Now send them + InitControl(maxlen); + USB_SendControl(0,&config,sizeof(ConfigDescriptor)); + SendInterfaces(); + return true; +} + +u8 _cdcComposite = 0; + +static +bool SendDescriptor(Setup& setup) +{ + u8 t = setup.wValueH; + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + return SendConfiguration(setup.wLength); + + InitControl(setup.wLength); +#ifdef HID_ENABLED + if (HID_REPORT_DESCRIPTOR_TYPE == t) + return HID_GetDescriptor(t); +#endif + + u8 desc_length = 0; + const u8* desc_addr = 0; + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + if (setup.wLength == 8) + _cdcComposite = 1; + desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + if (setup.wValueL == 0) + desc_addr = (const u8*)&STRING_LANGUAGE; + else if (setup.wValueL == IPRODUCT) + desc_addr = (const u8*)&STRING_IPRODUCT; + else if (setup.wValueL == IMANUFACTURER) + desc_addr = (const u8*)&STRING_IMANUFACTURER; + else + return false; + } + + if (desc_addr == 0) + return false; + if (desc_length == 0) + desc_length = pgm_read_byte(desc_addr); + + USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); + return true; +} + +// Endpoint 0 interrupt +ISR(USB_COM_vect) +{ + SetEP(0); + if (!ReceivedSetupInt()) + return; + + Setup setup; + Recv((u8*)&setup,8); + ClearSetupInt(); + + u8 requestType = setup.bmRequestType; + if (requestType & REQUEST_DEVICETOHOST) + WaitIN(); + else + ClearIN(); + + bool ok = true; + if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) + { + // Standard Requests + u8 r = setup.bRequest; + if (GET_STATUS == r) + { + Send8(0); // TODO + Send8(0); + } + else if (CLEAR_FEATURE == r) + { + } + else if (SET_FEATURE == r) + { + } + else if (SET_ADDRESS == r) + { + WaitIN(); + UDADDR = setup.wValueL | (1<<ADDEN); + } + else if (GET_DESCRIPTOR == r) + { + ok = SendDescriptor(setup); + } + else if (SET_DESCRIPTOR == r) + { + ok = false; + } + else if (GET_CONFIGURATION == r) + { + Send8(1); + } + else if (SET_CONFIGURATION == r) + { + if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) + { + InitEndpoints(); + _usbConfiguration = setup.wValueL; + } else + ok = false; + } + else if (GET_INTERFACE == r) + { + } + else if (SET_INTERFACE == r) + { + } + } + else + { + InitControl(setup.wLength); // Max length of transfer + ok = ClassInterfaceRequest(setup); + } + + if (ok) + ClearIN(); + else + { + Stall(); + } +} + +void USB_Flush(u8 ep) +{ + SetEP(ep); + if (FifoByteCount()) + ReleaseTX(); +} + +// General interrupt +ISR(USB_GEN_vect) +{ + u8 udint = UDINT; + UDINT = 0; + + // End of Reset + if (udint & (1<<EORSTI)) + { + InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64); // init ep0 + _usbConfiguration = 0; // not configured yet + UEIENX = 1 << RXSTPE; // Enable interrupts for ep0 + } + + // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too + if (udint & (1<<SOFI)) + { +#ifdef CDC_ENABLED + USB_Flush(CDC_TX); // Send a tx frame if found +#endif + + // check whether the one-shot period has elapsed. if so, turn off the LED + if (TxLEDPulse && !(--TxLEDPulse)) + TXLED0; + if (RxLEDPulse && !(--RxLEDPulse)) + RXLED0; + } +} + +// VBUS or counting frames +// Any frame counting? +u8 USBConnected() +{ + u8 f = UDFNUML; + delay(3); + return f != UDFNUML; +} + +//======================================================================= +//======================================================================= + +USB_ USB; + +USB_::USB_() +{ +} + +void USB_::attach() +{ + _usbConfiguration = 0; + UHWCON = 0x01; // power internal reg + USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled + PLLCSR = 0x12; // Need 16 MHz xtal + while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll + ; + USBCON = ((1<<USBE)|(1<<OTGPADE)); // start USB clock + UDIEN = (1<<EORSTE)|(1<<SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame) + UDCON = 0; // enable attach resistor + + TX_RX_LED_INIT; +} + +void USB_::detach() +{ +} + +// Check for interrupts +// TODO: VBUS detection +bool USB_::configured() +{ + return _usbConfiguration; +} + +void USB_::poll() +{ +} + +#endif /* if defined(USBCON) */
\ No newline at end of file diff --git a/cores/arduino/USBCore.h b/cores/arduino/USBCore.h new file mode 100644 index 0000000..8d13806 --- /dev/null +++ b/cores/arduino/USBCore.h @@ -0,0 +1,303 @@ + +// Copyright (c) 2010, Peter Barrett +/* +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + +// Standard requests +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 + + +// bmRequestType +#define REQUEST_HOSTTODEVICE 0x00 +#define REQUEST_DEVICETOHOST 0x80 +#define REQUEST_DIRECTION 0x80 + +#define REQUEST_STANDARD 0x00 +#define REQUEST_CLASS 0x20 +#define REQUEST_VENDOR 0x40 +#define REQUEST_TYPE 0x60 + +#define REQUEST_DEVICE 0x00 +#define REQUEST_INTERFACE 0x01 +#define REQUEST_ENDPOINT 0x02 +#define REQUEST_OTHER 0x03 +#define REQUEST_RECIPIENT 0x03 + +#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE) +#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE) + +// Class requests + +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 + +#define MSC_RESET 0xFF +#define MSC_GET_MAX_LUN 0xFE + +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +// Descriptors + +#define USB_DEVICE_DESC_SIZE 18 +#define USB_CONFIGUARTION_DESC_SIZE 9 +#define USB_INTERFACE_DESC_SIZE 9 +#define USB_ENDPOINT_DESC_SIZE 7 + +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 + +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +// bMaxPower in Configuration Descriptor +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +// bEndpointAddress in Endpoint Descriptor +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 + +#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define CDC_V1_10 0x0110 +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_HEADER 0x00 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_UNION 0x06 +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 +#define CDC_DATA_INTERFACE_CLASS 0x0A + +#define MSC_SUBCLASS_SCSI 0x06 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + +#define HID_HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 + + +// Device +typedef struct { + u8 len; // 18 + u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE + u16 usbVersion; // 0x200 + u8 deviceClass; + u8 deviceSubClass; + u8 deviceProtocol; + u8 packetSize0; // Packet 0 + u16 idVendor; + u16 idProduct; + u16 deviceVersion; // 0x100 + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; + +// Config +typedef struct { + u8 len; // 9 + u8 dtype; // 2 + u16 clen; // total length + u8 numInterfaces; + u8 config; + u8 iconfig; + u8 attributes; + u8 maxPower; +} ConfigDescriptor; + +// String + +// Interface +typedef struct +{ + u8 len; // 9 + u8 dtype; // 4 + u8 number; + u8 alternate; + u8 numEndpoints; + u8 interfaceClass; + u8 interfaceSubClass; + u8 protocol; + u8 iInterface; +} InterfaceDescriptor; + +// Endpoint +typedef struct +{ + u8 len; // 7 + u8 dtype; // 5 + u8 addr; + u8 attr; + u16 packetSize; + u8 interval; +} EndpointDescriptor; + +// Interface Association Descriptor +// Used to bind 2 interfaces together in CDC compostite device +typedef struct +{ + u8 len; // 8 + u8 dtype; // 11 + u8 firstInterface; + u8 interfaceCount; + u8 functionClass; + u8 funtionSubClass; + u8 functionProtocol; + u8 iInterface; +} IADDescriptor; + +// CDC CS interface descriptor +typedef struct +{ + u8 len; // 5 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; + u8 d1; +} CDCCSInterfaceDescriptor; + +typedef struct +{ + u8 len; // 4 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; +} CDCCSInterfaceDescriptor4; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; + u8 bDataInterface; +} CMFunctionalDescriptor; + +typedef struct +{ + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; +} ACMFunctionalDescriptor; + +typedef struct +{ + // IAD + IADDescriptor iad; // Only needed on compound device + + // Control + InterfaceDescriptor cif; // + CDCCSInterfaceDescriptor header; + CMFunctionalDescriptor callManagement; // Call Management + ACMFunctionalDescriptor controlManagement; // ACM + CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION + EndpointDescriptor cifin; + + // Data + InterfaceDescriptor dif; + EndpointDescriptor in; + EndpointDescriptor out; +} CDCDescriptor; + +typedef struct +{ + InterfaceDescriptor msc; + EndpointDescriptor in; + EndpointDescriptor out; +} MSCDescriptor; + +typedef struct +{ + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct +{ + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + + +#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ + { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } + +#define D_CONFIG(_totalLength,_interfaces) \ + { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } + +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } + +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } + +#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ + { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } +#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } + + +#endif
\ No newline at end of file diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h new file mode 100644 index 0000000..549ed9e --- /dev/null +++ b/cores/arduino/USBDesc.h @@ -0,0 +1,67 @@ + + +/* Copyright (c) 2011, Peter Barrett +** +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#define CDC_ENABLED +#define HID_ENABLED + + +#ifdef CDC_ENABLED +#define CDC_INTERFACE_COUNT 2 +#define CDC_ENPOINT_COUNT 3 +#else +#define CDC_INTERFACE_COUNT 0 +#define CDC_ENPOINT_COUNT 0 +#endif + +#ifdef HID_ENABLED +#define HID_INTERFACE_COUNT 1 +#define HID_ENPOINT_COUNT 1 +#else +#define HID_INTERFACE_COUNT 0 +#define HID_ENPOINT_COUNT 0 +#endif + +#define CDC_ACM_INTERFACE 0 // CDC ACM +#define CDC_DATA_INTERFACE 1 // CDC Data +#define CDC_FIRST_ENDPOINT 1 +#define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First +#define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) +#define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) + +#define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface +#define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT) +#define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT) + +#define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) + +#ifdef CDC_ENABLED +#define CDC_RX CDC_ENDPOINT_OUT +#define CDC_TX CDC_ENDPOINT_IN +#endif + +#ifdef HID_ENABLED +#define HID_TX HID_ENDPOINT_INT +#endif + +#define IMANUFACTURER 1 +#define IPRODUCT 2 +#define USB_PID_LEONARDO 0x0034 +#define USB_PID_MICRO 0x0035 +#define USB_VID 0x2341 // arduino LLC vid +#define USB_PID ARDUINO_MODEL_USB_PID + diff --git a/cores/arduino/Udp.h b/cores/arduino/Udp.h new file mode 100644 index 0000000..dc5644b --- /dev/null +++ b/cores/arduino/Udp.h @@ -0,0 +1,88 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp_h +#define udp_h + +#include <Stream.h> +#include <IPAddress.h> + +class UDP : public Stream { + +public: + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop() =0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port) =0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port) =0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() =0; + // Write a single byte into the packet + virtual size_t write(uint8_t) =0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size) =0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() =0; + // Number of bytes remaining in the current packet + virtual int available() =0; + // Read a single byte from the current packet + virtual int read() =0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len) =0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) =0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() =0; + virtual void flush() =0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() =0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() =0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c index 75c713b..1449cfb 100755 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -110,6 +110,21 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { #warning attachInterrupt may need some more work for this cpu (case 1) #endif break; + + case 2: + #if defined(EICRA) && defined(ISC20) && defined(ISC21) && defined(EIMSK) + EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); + EIMSK |= (1 << INT2); + #elif defined(MCUCR) && defined(ISC20) && defined(ISC21) && defined(GICR) + MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); + GICR |= (1 << INT2); + #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK) + MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); + GIMSK |= (1 << INT2); + #else + #warning attachInterrupt may need some more work for this cpu (case 1) + #endif + break; #endif } } @@ -237,6 +252,13 @@ SIGNAL(INT1_vect) { intFunc[EXTERNAL_INT_1](); } +#if defined(EICRA) && defined(ISC20) +SIGNAL(INT2_vect) { + if(intFunc[EXTERNAL_INT_2]) + intFunc[EXTERNAL_INT_2](); +} +#endif + #endif /* diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index f90cef0..3e81331 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -498,7 +498,7 @@ int String::lastIndexOf( char theChar ) const return lastIndexOf(theChar, len - 1); } -int String::lastIndexOf(char ch, int fromIndex) const +int String::lastIndexOf(char ch, unsigned int fromIndex) const { if (fromIndex >= len || fromIndex < 0) return -1; char tempchar = buffer[fromIndex + 1]; @@ -514,7 +514,7 @@ int String::lastIndexOf(const String &s2) const return lastIndexOf(s2, len - s2.len); } -int String::lastIndexOf(const String &s2, int fromIndex) const +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const { if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1; if (fromIndex >= len) fromIndex = len - 1; @@ -522,7 +522,7 @@ int String::lastIndexOf(const String &s2, int fromIndex) const for (char *p = buffer; p <= buffer + fromIndex; p++) { p = strstr(p, s2.buffer); if (!p) break; - if (p - buffer <= fromIndex) found = p - buffer; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; } return found; } @@ -593,7 +593,7 @@ void String::replace(const String& find, const String& replace) if (size == len) return; if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! int index = len - 1; - while ((index = lastIndexOf(find, index)) >= 0) { + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { readFrom = buffer + index + find.len; memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); len += diff; diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h index a601aca..d76d2a3 100644 --- a/cores/arduino/WString.h +++ b/cores/arduino/WString.h @@ -154,9 +154,9 @@ public: int indexOf( const String &str ) const; int indexOf( const String &str, unsigned int fromIndex ) const; int lastIndexOf( char ch ) const; - int lastIndexOf( char ch, int fromIndex ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; int lastIndexOf( const String &str ) const; - int lastIndexOf( const String &str, int fromIndex ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; String substring( unsigned int beginIndex ) const; String substring( unsigned int beginIndex, unsigned int endIndex ) const; diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 3c46f1e..34450f4 100755 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -1,14 +1,19 @@ -#define ARDUINO_MAIN #include <Arduino.h> int main(void) { init(); +#if defined(USBCON) + USB.attach(); +#endif + setup(); - for (;;) + for (;;) { loop(); + if (serialEventRun) serialEventRun(); + } return 0; } diff --git a/cores/arduino/new.cpp b/cores/arduino/new.cpp new file mode 100644 index 0000000..0f6d422 --- /dev/null +++ b/cores/arduino/new.cpp @@ -0,0 +1,18 @@ +#include <new.h> + +void * operator new(size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; +void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; +void __cxa_guard_abort (__guard *) {}; + +void __cxa_pure_virtual(void) {}; + diff --git a/cores/arduino/new.h b/cores/arduino/new.h new file mode 100644 index 0000000..cd940ce --- /dev/null +++ b/cores/arduino/new.h @@ -0,0 +1,22 @@ +/* Header to define new/delete operators as they aren't provided by avr-gcc by default + Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 + */ + +#ifndef NEW_H +#define NEW_H + +#include <stdlib.h> + +void * operator new(size_t size); +void operator delete(void * ptr); + +__extension__ typedef int __guard __attribute__((mode (__DI__))); + +extern "C" int __cxa_guard_acquire(__guard *); +extern "C" void __cxa_guard_release (__guard *); +extern "C" void __cxa_guard_abort (__guard *); + +extern "C" void __cxa_pure_virtual(void); + +#endif + diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c index ce4cad6..e7f7cde 100755 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -41,7 +41,11 @@ volatile unsigned long timer0_overflow_count = 0; volatile unsigned long timer0_millis = 0; static unsigned char timer0_fract = 0; +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +SIGNAL(TIM0_OVF_vect) +#else SIGNAL(TIMER0_OVF_vect) +#endif { // copy these to local variables so they can be stored in registers // (volatile variables must be read from memory on every access) @@ -120,8 +124,26 @@ void delayMicroseconds(unsigned int us) // calling avrlib's delay_us() function with low values (e.g. 1 or // 2 microseconds) gives delays longer than desired. //delay_us(us); +#if F_CPU >= 20000000L + // for the 20 MHz clock on rare Arduino boards -#if F_CPU >= 16000000L + // for a one-microsecond delay, simply wait 2 cycle and return. The overhead + // of the function call yields a delay of exactly a one microsecond. + __asm__ __volatile__ ( + "nop" "\n\t" + "nop"); //just waiting 2 cycle + if (--us == 0) + return; + + // the following loop takes a 1/5 of a microsecond (4 cycles) + // per iteration, so execute it five times for each microsecond of + // delay requested. + us = (us<<2) + us; // x5 us + + // account for the time taken in the preceeding commands. + us -= 2; + +#elif F_CPU >= 16000000L // for the 16 MHz clock on most Arduino boards // for a one-microsecond delay, simply return. the overhead @@ -217,11 +239,15 @@ void init() // set timer 1 prescale factor to 64 sbi(TCCR1B, CS11); +#if F_CPU >= 8000000L sbi(TCCR1B, CS10); +#endif #elif defined(TCCR1) && defined(CS11) && defined(CS10) sbi(TCCR1, CS11); +#if F_CPU >= 8000000L sbi(TCCR1, CS10); #endif +#endif // put timer 1 in 8-bit phase correct pwm mode #if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index d248f4c..902b153 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -43,11 +43,16 @@ int analogRead(uint8_t pin) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) if (pin >= 54) pin -= 54; // allow for channel or pin numbers +#elif defined(__AVR_ATmega32U4__) + if (pin >= 18) pin -= 18; // allow for channel or pin numbers #else if (pin >= 14) pin -= 14; // allow for channel or pin numbers #endif - -#if defined(ADCSRB) && defined(MUX5) + +#if defined(__AVR_ATmega32U4__) + pin = analogPinToChannel(pin); + ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); +#elif defined(ADCSRB) && defined(MUX5) // the MUX5 bit of ADCSRB selects whether we're reading from channels // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); @@ -222,6 +227,14 @@ void analogWrite(uint8_t pin, int val) OCR4C = val; // set pwm duty break; #endif + + #if defined(TCCR4A) && defined(COM4D1) + case TIMER4D: + // connect pwm to pin on timer 4, channel D + sbi(TCCR4A, COM4D1); + OCR4D = val; // set pwm duty + break; + #endif #if defined(TCCR5A) && defined(COM5A1) case TIMER5A: diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index dd1b949..97ef134 100755 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -24,6 +24,7 @@ $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ */ +#define ARDUINO_MAIN #include "wiring_private.h" #include "pins_arduino.h" diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h index 74c0d06..f0ceb0c 100755 --- a/cores/arduino/wiring_private.h +++ b/cores/arduino/wiring_private.h @@ -27,7 +27,6 @@ #include <avr/io.h> #include <avr/interrupt.h> -#include <avr/delay.h> #include <stdio.h> #include <stdarg.h> @@ -55,6 +54,8 @@ extern "C"{ #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define EXTERNAL_NUM_INTERRUPTS 8 +#elif defined(__AVR_ATmega1284P__) +#define EXTERNAL_NUM_INTERRUPTS 3 #else #define EXTERNAL_NUM_INTERRUPTS 2 #endif diff --git a/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex new file mode 100644 index 0000000..7720cf4 --- /dev/null +++ b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex @@ -0,0 +1,467 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123420001000102DC0109023E0002017D
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:103000004BC0000064C0000062C0000060C000004F
+:103010005EC000005CC000005AC0000058C0000044
+:1030200056C0000054C0000052C00000EEC40000B2
+:103030004EC000004CC000004AC0000048C0000064
+:1030400046C0000044C0000042C0000040C0000074
+:103050003EC000003CC000003AC0000038C0000084
+:1030600036C0000034C0000032C0000030C0000094
+:103070002EC000002CC000002AC0000028C00000A4
+:1030800026C0000024C0000022C0000020C00000B4
+:103090001EC000001CC0000011241FBECFEFD2E0F4
+:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
+:1030B00005900D92AA33B107D9F711E0AAE3B1E068
+:1030C00001C01D92AB35B107E1F772D314C698CF9A
+:1030D000982F15C08091F200882371F48091E80048
+:1030E0008B7F8093E80003C08EB3882351F08091DA
+:1030F000E80082FFF9CF02C08091F100915099233E
+:1031000049F7089520914A01309149018091480181
+:103110009091470180933F0190934001C9018093B2
+:103120004101909342010895DF93CF9300D000D0E6
+:1031300000D0CDB7DEB780914501843009F45AC084
+:10314000853030F4813059F0833009F0D7C01FC08A
+:10315000853009F4A0C0863009F0D0C0C3C080918A
+:103160004601823008F0CAC0CDDF80914601882335
+:1031700061F480913F019091400123E0FC01209394
+:103180005700E89507B600FCFDCF85E008C08091A8
+:103190004601882311F0823029F4B4DF89E080935E
+:1031A0000101ACC0813009F0A9C020E030E040E06E
+:1031B00050E0F90184918F3F81F0CA01AA27BB2713
+:1031C00080933E013093400120933F018AE0809339
+:1031D000010185E080933B0191C02F5F3F4F4F4F2E
+:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
+:1031F00001F784C080914601833051F581E08093CE
+:103200003A0180914B0190914C01892B71F0809192
+:103210004701813009F072C080914A0190914901C3
+:1032200090933D0180933C0169C0809147018823C0
+:1032300061F42CE088E190E00FB6F894A8958093B3
+:1032400060000FBE2093600059C01092000156C06C
+:10325000882309F053C0809147018F3F09F04EC089
+:10326000E0E0F0E093E085E090935700E89507B642
+:1032700000FCFDCF80935700E89507B600FCFDCF1A
+:10328000E058FF4F20E3E030F20771F781E18093CF
+:103290005700E89533C0DE011196E5E0F1E083E0E8
+:1032A00001900D928150E1F7DE011496E2E0F1E029
+:1032B00083E001900D928150E1F790914701809158
+:1032C0004601882329F4FE01E90FF11D818107C021
+:1032D0008130A1F4FE01BC97E90FF11D808180933C
+:1032E00050010CC080914601833041F48091470128
+:1032F000882321F48091480180933E0126960FB6E1
+:10330000F894DEBF0FBECDBFCF91DF9108952F920D
+:103310003F924F925F926F927F929F92AF92BF9235
+:10332000CF92DF92EF92FF920F931F93CF93DF9391
+:103330008091590190915A0190934C0180934B01D7
+:1033400080914D01882351F080914D0181508093EF
+:103350004D0180914D01882309F45D9A80914E01C1
+:10336000882351F080914E01815080934E018091CD
+:103370004E01882309F45C9A80915401833009F44A
+:10338000B2C1843030F4813071F0823009F0E3C191
+:1033900011C1853009F4C5C1853008F4BAC1863041
+:1033A00009F0D9C1CDC15C9883E080934E01809132
+:1033B000E800877F8093E80080913A01882329F014
+:1033C000B3DE5D9A5C9A10923A0120914B013091E4
+:1033D0004C012115310529F42AC08EB3882309F444
+:1033E000BAC18091E80082FFF8CF8091F10080930C
+:1033F00045012150304030934C0120934B01E6E4CD
+:10340000F1E00CC08091F10081932150304081E0C7
+:10341000EB34F80719F43183208308C08091F2005F
+:10342000882381F730934C0120934B017DDE8091FE
+:103430000101853009F0BAC080914B0190914C0197
+:10344000892B21F482E080930101B0C08AE140DE43
+:1034500080913F018F713CDEC0914101D0914201CA
+:1034600020913F013091400121968E01021B130BE8
+:10347000219780914601882309F093C01801369462
+:103480002794C901A0913E01B0E09C01AD0162E02A
+:10349000E62EF12C012D112DE20EF31E041F151F37
+:1034A00059016A0190E099249394B5E0A3E048C0E3
+:1034B0008091F200882371F48091E8008B7F8093E3
+:1034C000E80004C08EB3882309F445C18091E80068
+:1034D00082FFF8CF0894210831088091F100682F0D
+:1034E0008091F100782FF5010B0190925700E8953B
+:1034F00011249F5F903419F021143104A1F4F901D3
+:10350000B0935700E89507B600FCFDCF21143104B5
+:1035100051F0F701A0935700E89507B600FCFDCFE6
+:10352000A801970190E042E0442E512C612C712CAF
+:10353000E40CF51C061D171DA40CB51CC61CD71CDD
+:103540002114310409F0B4CFD0934001C0933F015E
+:1035500081E180935700E89527C08091F20088238D
+:1035600071F48091E8008B7F8093E80004C08EB3F3
+:10357000882309F4F0C08091E80082FFF8CF6091C1
+:10358000F10080913F0190914001A7D380913F01CC
+:103590009091400101969093400180933F0101502A
+:1035A000104001151105C9F680E192DD8091E80017
+:1035B0008B7FC3C08091E800877F8093E8005D988F
+:1035C00083E080934D0104C08EB3882309F4C3C007
+:1035D0008091E80080FFF8CF80910101893091F05F
+:1035E0008A3069F480914601813049F480913F012D
+:1035F000909140018093F1009093F1009BC08091E5
+:10360000500196C0609141017091420120913F01AB
+:10361000309140016F5F7F4F7B01E21AF30A6150E6
+:10362000704080914601882389F58701169507959A
+:10363000C901A0913E01B0E09C01AD011FC0809185
+:10364000F200803271F48091E8008E7F8093E80070
+:1036500004C08EB3882309F47EC08091E80080FF07
+:10366000F8CFF901859194918093F1009093F10046
+:10367000015010402E5F3F4F4F4F5F4F0115110516
+:10368000F1F67093400160933F0129C0823039F513
+:1036900023C08091F200803271F48091E8008E7F27
+:1036A0008093E80004C08EB3882309F454C080914D
+:1036B000E80080FFF8CF00913F0110914001C80160
+:1036C00004D38093F1000F5F1F4F109340010093CC
+:1036D0003F010894E108F108E114F104D1F682E019
+:1036E0008093010127C08091E800877F8093E800E4
+:1036F00080913B018093F1001092F1001092F10053
+:103700001092F100809101018093F1001092F1007C
+:1037100011C08091E800877F8093E80010923B0100
+:1037200019C08091E800877F8093E80080910101B3
+:103730008093F1008091E8008E7F8093E8000AC0BA
+:103740008091E800877F8093E8005D9A5C9A82E030
+:103750008093010187D0DF91CF911F910F91FF904E
+:10376000EF90DF90CF90BF90AF909F907F906F9041
+:103770005F904F903F902F9008952BD181E085BFAF
+:1037800015BE089584B7877F84BF88E10FB6F8948B
+:1037900080936000109260000FBE81E085BF82E0E0
+:1037A00085BF8AB180638AB98BB180638BB90CC144
+:1037B000E9DF789401C080D2809100018823D9F795
+:1037C00080913A018823B9F7D8DFE0913C01F0916C
+:1037D0003D010995FA01923071F0933089F09130F2
+:1037E00029F488E091E022E130E019C080E090E027
+:1037F00020E030E014C08AE191E02BE130E00FC01E
+:10380000882339F480913501282F30E085E391E059
+:1038100006C080914301282F30E083E491E091833A
+:103820008083C90108958091EB0081608093EB0053
+:103830001092ED006093EC004093ED008091EE005B
+:10384000881F8827881F08951092F4001092F000B6
+:103850001092E8001092ED00EBEEF0E080818E7F98
+:10386000808308958091530188238CF403C08EB324
+:103870008823B1F08091E80082FFF9CF8091E800C1
+:103880008B7F8093E80008958EB3882349F0809160
+:10389000E80080FFF9CF8091E8008E7F8093E800F8
+:1038A00008959C014091590150915A0146175707BC
+:1038B00018F4F90120E038C06115710511F0AB0171
+:1038C000F8CF8091E8008E7F8093E80040E050E0E0
+:1038D000F0CF8091E80083FF02C081E008958091DD
+:1038E000E80082FD2DC08EB3882381F18EB3853030
+:1038F00079F18091E80080FF17C09091F20006C036
+:1039000081918093F100415050409F5F41155105D6
+:1039100011F09032A8F320E0903209F421E0809178
+:10392000E8008E7F8093E8004115510591F622232F
+:1039300081F606C08EB3882349F08EB3853041F0FE
+:103940008091E80082FFF6CF80E0089582E008953C
+:1039500083E0089554D056D01EBA1092510184E0ED
+:1039600089BD89B5826089BD09B400FEFDCF809113
+:10397000D800982F9F779093D80080688093D800C4
+:10398000809163008E7F809363008091D8008F7D4B
+:103990008093D8008091E0008E7F8093E00080913A
+:1039A000E1008E7F8093E1008091E200816080934E
+:1039B000E2008091E100877F8093E1008091E20046
+:1039C00088608093E2000895C5DF81E08093520112
+:1039D0000895C0DFE0EEF0E0808181608083E8ED53
+:1039E000F0E080818F7780830AD00CD019BCE3E6A9
+:1039F000F0E08081816080831092520108951092DE
+:103A0000E20008951092E10008951F920F920FB600
+:103A10000F9211242F933F934F935F936F937F9354
+:103A20008F939F93AF93BF93EF93FF938091E100A8
+:103A300080FF1BC08091E20080FF17C08091E100F1
+:103A40008E7F8093E1008091E2008E7F8093E20080
+:103A50008091E20080618093E2008091D8008062D2
+:103A60008093D80019BC1EBA26D18091E10084FF52
+:103A700029C08091E20084FF25C084E089BD89B51A
+:103A8000826089BD09B400FEFDCF8091D8008F7D92
+:103A90008093D8008091E1008F7E8093E100809137
+:103AA000E2008F7E8093E2008091E200816080934B
+:103AB000E20080915101882311F481E001C084E08B
+:103AC0008EBBF9D08091E10083FF22C08091E2009B
+:103AD00083FF1EC08091E100877F8093E10082E038
+:103AE0008EBB109251018091E1008E7F8093E100A6
+:103AF0008091E2008E7F8093E2008091E2008061FD
+:103B00008093E200A1DE80E060E042E28CDED3D070
+:103B10008091E10082FF0AC08091E20082FF06C02E
+:103B20008091E1008B7F8093E100C5D0FF91EF9100
+:103B3000BF91AF919F918F917F916F915F914F91C5
+:103B40003F912F910F900FBE0F901F9018951F93CC
+:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
+:103B6000F100819381E0EB35F807C9F7909153019B
+:103B700080915401853011F1863040F48130B9F0E4
+:103B8000813070F0833009F081C011C0883009F4B1
+:103B900053C0893009F462C0863009F077C02DC067
+:103BA000903809F474C0923809F070C070C099233D
+:103BB00009F46DC0923009F069C069C0992309F019
+:103BC00065C0109155018091E800877F8093E800DF
+:103BD00049DE04C08EB3882309F459C08091E800FF
+:103BE00080FFF8CF812F8F7711F492E001C093E02E
+:103BF0009EBB80688093E3004AC09058923008F0E2
+:103C000045C0809155019091560160915701AE01D8
+:103C10004F5F5F4FDFDDBC010097C9F18091E80085
+:103C2000877F8093E80089819A813BDE8091E8005C
+:103C30008B7F8093E8002BC0903841F58091E8009D
+:103C4000877F8093E800809151018093F1008091FB
+:103C5000E8008E7F8093E80005DE19C09923B1F457
+:103C600090915501923098F48091E800877F80937D
+:103C7000E80090935101F6DD80915101882311F401
+:103C800083E001C084E08EBB16D001C040DB809190
+:103C9000E80083FF0AC08091EB0080628093EB0014
+:103CA0008091E800877F8093E8000F900F90CF917C
+:103CB000DF911F91089508958EB3882329F0809194
+:103CC000E80083FF01C043CF0895F999FECF92BD6C
+:103CD00081BDF89A992780B50895262FF999FECFCE
+:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
+:0A3CF0000FBE01960895F894FFCF6F
+:103CFA0001021E948920DCFB120110010000002041
+:103D0A00EB03EF2F00000001000109021B00010173
+:103D1A000080320904000000FE01020009210300AC
+:0A3D2A0000000C000104030904006E
+:0400000300003000C9
+:00000001FF
diff --git a/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-MegaADK-Rev3.hex b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-MegaADK-Rev3.hex new file mode 100644 index 0000000..b47bdf6 --- /dev/null +++ b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-MegaADK-Rev3.hex @@ -0,0 +1,467 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123440001000102DC0109023E0002017B
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:103000004BC0000064C0000062C0000060C000004F
+:103010005EC000005CC000005AC0000058C0000044
+:1030200056C0000054C0000052C00000EEC40000B2
+:103030004EC000004CC000004AC0000048C0000064
+:1030400046C0000044C0000042C0000040C0000074
+:103050003EC000003CC000003AC0000038C0000084
+:1030600036C0000034C0000032C0000030C0000094
+:103070002EC000002CC000002AC0000028C00000A4
+:1030800026C0000024C0000022C0000020C00000B4
+:103090001EC000001CC0000011241FBECFEFD2E0F4
+:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
+:1030B00005900D92AA33B107D9F711E0AAE3B1E068
+:1030C00001C01D92AB35B107E1F772D314C698CF9A
+:1030D000982F15C08091F200882371F48091E80048
+:1030E0008B7F8093E80003C08EB3882351F08091DA
+:1030F000E80082FFF9CF02C08091F100915099233E
+:1031000049F7089520914A01309149018091480181
+:103110009091470180933F0190934001C9018093B2
+:103120004101909342010895DF93CF9300D000D0E6
+:1031300000D0CDB7DEB780914501843009F45AC084
+:10314000853030F4813059F0833009F0D7C01FC08A
+:10315000853009F4A0C0863009F0D0C0C3C080918A
+:103160004601823008F0CAC0CDDF80914601882335
+:1031700061F480913F019091400123E0FC01209394
+:103180005700E89507B600FCFDCF85E008C08091A8
+:103190004601882311F0823029F4B4DF89E080935E
+:1031A0000101ACC0813009F0A9C020E030E040E06E
+:1031B00050E0F90184918F3F81F0CA01AA27BB2713
+:1031C00080933E013093400120933F018AE0809339
+:1031D000010185E080933B0191C02F5F3F4F4F4F2E
+:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
+:1031F00001F784C080914601833051F581E08093CE
+:103200003A0180914B0190914C01892B71F0809192
+:103210004701813009F072C080914A0190914901C3
+:1032200090933D0180933C0169C0809147018823C0
+:1032300061F42CE088E190E00FB6F894A8958093B3
+:1032400060000FBE2093600059C01092000156C06C
+:10325000882309F053C0809147018F3F09F04EC089
+:10326000E0E0F0E093E085E090935700E89507B642
+:1032700000FCFDCF80935700E89507B600FCFDCF1A
+:10328000E058FF4F20E3E030F20771F781E18093CF
+:103290005700E89533C0DE011196E5E0F1E083E0E8
+:1032A00001900D928150E1F7DE011496E2E0F1E029
+:1032B00083E001900D928150E1F790914701809158
+:1032C0004601882329F4FE01E90FF11D818107C021
+:1032D0008130A1F4FE01BC97E90FF11D808180933C
+:1032E00050010CC080914601833041F48091470128
+:1032F000882321F48091480180933E0126960FB6E1
+:10330000F894DEBF0FBECDBFCF91DF9108952F920D
+:103310003F924F925F926F927F929F92AF92BF9235
+:10332000CF92DF92EF92FF920F931F93CF93DF9391
+:103330008091590190915A0190934C0180934B01D7
+:1033400080914D01882351F080914D0181508093EF
+:103350004D0180914D01882309F45D9A80914E01C1
+:10336000882351F080914E01815080934E018091CD
+:103370004E01882309F45C9A80915401833009F44A
+:10338000B2C1843030F4813071F0823009F0E3C191
+:1033900011C1853009F4C5C1853008F4BAC1863041
+:1033A00009F0D9C1CDC15C9883E080934E01809132
+:1033B000E800877F8093E80080913A01882329F014
+:1033C000B3DE5D9A5C9A10923A0120914B013091E4
+:1033D0004C012115310529F42AC08EB3882309F444
+:1033E000BAC18091E80082FFF8CF8091F10080930C
+:1033F00045012150304030934C0120934B01E6E4CD
+:10340000F1E00CC08091F10081932150304081E0C7
+:10341000EB34F80719F43183208308C08091F2005F
+:10342000882381F730934C0120934B017DDE8091FE
+:103430000101853009F0BAC080914B0190914C0197
+:10344000892B21F482E080930101B0C08AE140DE43
+:1034500080913F018F713CDEC0914101D0914201CA
+:1034600020913F013091400121968E01021B130BE8
+:10347000219780914601882309F093C01801369462
+:103480002794C901A0913E01B0E09C01AD0162E02A
+:10349000E62EF12C012D112DE20EF31E041F151F37
+:1034A00059016A0190E099249394B5E0A3E048C0E3
+:1034B0008091F200882371F48091E8008B7F8093E3
+:1034C000E80004C08EB3882309F445C18091E80068
+:1034D00082FFF8CF0894210831088091F100682F0D
+:1034E0008091F100782FF5010B0190925700E8953B
+:1034F00011249F5F903419F021143104A1F4F901D3
+:10350000B0935700E89507B600FCFDCF21143104B5
+:1035100051F0F701A0935700E89507B600FCFDCFE6
+:10352000A801970190E042E0442E512C612C712CAF
+:10353000E40CF51C061D171DA40CB51CC61CD71CDD
+:103540002114310409F0B4CFD0934001C0933F015E
+:1035500081E180935700E89527C08091F20088238D
+:1035600071F48091E8008B7F8093E80004C08EB3F3
+:10357000882309F4F0C08091E80082FFF8CF6091C1
+:10358000F10080913F0190914001A7D380913F01CC
+:103590009091400101969093400180933F0101502A
+:1035A000104001151105C9F680E192DD8091E80017
+:1035B0008B7FC3C08091E800877F8093E8005D988F
+:1035C00083E080934D0104C08EB3882309F4C3C007
+:1035D0008091E80080FFF8CF80910101893091F05F
+:1035E0008A3069F480914601813049F480913F012D
+:1035F000909140018093F1009093F1009BC08091E5
+:10360000500196C0609141017091420120913F01AB
+:10361000309140016F5F7F4F7B01E21AF30A6150E6
+:10362000704080914601882389F58701169507959A
+:10363000C901A0913E01B0E09C01AD011FC0809185
+:10364000F200803271F48091E8008E7F8093E80070
+:1036500004C08EB3882309F47EC08091E80080FF07
+:10366000F8CFF901859194918093F1009093F10046
+:10367000015010402E5F3F4F4F4F5F4F0115110516
+:10368000F1F67093400160933F0129C0823039F513
+:1036900023C08091F200803271F48091E8008E7F27
+:1036A0008093E80004C08EB3882309F454C080914D
+:1036B000E80080FFF8CF00913F0110914001C80160
+:1036C00004D38093F1000F5F1F4F109340010093CC
+:1036D0003F010894E108F108E114F104D1F682E019
+:1036E0008093010127C08091E800877F8093E800E4
+:1036F00080913B018093F1001092F1001092F10053
+:103700001092F100809101018093F1001092F1007C
+:1037100011C08091E800877F8093E80010923B0100
+:1037200019C08091E800877F8093E80080910101B3
+:103730008093F1008091E8008E7F8093E8000AC0BA
+:103740008091E800877F8093E8005D9A5C9A82E030
+:103750008093010187D0DF91CF911F910F91FF904E
+:10376000EF90DF90CF90BF90AF909F907F906F9041
+:103770005F904F903F902F9008952BD181E085BFAF
+:1037800015BE089584B7877F84BF88E10FB6F8948B
+:1037900080936000109260000FBE81E085BF82E0E0
+:1037A00085BF8AB180638AB98BB180638BB90CC144
+:1037B000E9DF789401C080D2809100018823D9F795
+:1037C00080913A018823B9F7D8DFE0913C01F0916C
+:1037D0003D010995FA01923071F0933089F09130F2
+:1037E00029F488E091E022E130E019C080E090E027
+:1037F00020E030E014C08AE191E02BE130E00FC01E
+:10380000882339F480913501282F30E085E391E059
+:1038100006C080914301282F30E083E491E091833A
+:103820008083C90108958091EB0081608093EB0053
+:103830001092ED006093EC004093ED008091EE005B
+:10384000881F8827881F08951092F4001092F000B6
+:103850001092E8001092ED00EBEEF0E080818E7F98
+:10386000808308958091530188238CF403C08EB324
+:103870008823B1F08091E80082FFF9CF8091E800C1
+:103880008B7F8093E80008958EB3882349F0809160
+:10389000E80080FFF9CF8091E8008E7F8093E800F8
+:1038A00008959C014091590150915A0146175707BC
+:1038B00018F4F90120E038C06115710511F0AB0171
+:1038C000F8CF8091E8008E7F8093E80040E050E0E0
+:1038D000F0CF8091E80083FF02C081E008958091DD
+:1038E000E80082FD2DC08EB3882381F18EB3853030
+:1038F00079F18091E80080FF17C09091F20006C036
+:1039000081918093F100415050409F5F41155105D6
+:1039100011F09032A8F320E0903209F421E0809178
+:10392000E8008E7F8093E8004115510591F622232F
+:1039300081F606C08EB3882349F08EB3853041F0FE
+:103940008091E80082FFF6CF80E0089582E008953C
+:1039500083E0089554D056D01EBA1092510184E0ED
+:1039600089BD89B5826089BD09B400FEFDCF809113
+:10397000D800982F9F779093D80080688093D800C4
+:10398000809163008E7F809363008091D8008F7D4B
+:103990008093D8008091E0008E7F8093E00080913A
+:1039A000E1008E7F8093E1008091E200816080934E
+:1039B000E2008091E100877F8093E1008091E20046
+:1039C00088608093E2000895C5DF81E08093520112
+:1039D0000895C0DFE0EEF0E0808181608083E8ED53
+:1039E000F0E080818F7780830AD00CD019BCE3E6A9
+:1039F000F0E08081816080831092520108951092DE
+:103A0000E20008951092E10008951F920F920FB600
+:103A10000F9211242F933F934F935F936F937F9354
+:103A20008F939F93AF93BF93EF93FF938091E100A8
+:103A300080FF1BC08091E20080FF17C08091E100F1
+:103A40008E7F8093E1008091E2008E7F8093E20080
+:103A50008091E20080618093E2008091D8008062D2
+:103A60008093D80019BC1EBA26D18091E10084FF52
+:103A700029C08091E20084FF25C084E089BD89B51A
+:103A8000826089BD09B400FEFDCF8091D8008F7D92
+:103A90008093D8008091E1008F7E8093E100809137
+:103AA000E2008F7E8093E2008091E200816080934B
+:103AB000E20080915101882311F481E001C084E08B
+:103AC0008EBBF9D08091E10083FF22C08091E2009B
+:103AD00083FF1EC08091E100877F8093E10082E038
+:103AE0008EBB109251018091E1008E7F8093E100A6
+:103AF0008091E2008E7F8093E2008091E2008061FD
+:103B00008093E200A1DE80E060E042E28CDED3D070
+:103B10008091E10082FF0AC08091E20082FF06C02E
+:103B20008091E1008B7F8093E100C5D0FF91EF9100
+:103B3000BF91AF919F918F917F916F915F914F91C5
+:103B40003F912F910F900FBE0F901F9018951F93CC
+:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
+:103B6000F100819381E0EB35F807C9F7909153019B
+:103B700080915401853011F1863040F48130B9F0E4
+:103B8000813070F0833009F081C011C0883009F4B1
+:103B900053C0893009F462C0863009F077C02DC067
+:103BA000903809F474C0923809F070C070C099233D
+:103BB00009F46DC0923009F069C069C0992309F019
+:103BC00065C0109155018091E800877F8093E800DF
+:103BD00049DE04C08EB3882309F459C08091E800FF
+:103BE00080FFF8CF812F8F7711F492E001C093E02E
+:103BF0009EBB80688093E3004AC09058923008F0E2
+:103C000045C0809155019091560160915701AE01D8
+:103C10004F5F5F4FDFDDBC010097C9F18091E80085
+:103C2000877F8093E80089819A813BDE8091E8005C
+:103C30008B7F8093E8002BC0903841F58091E8009D
+:103C4000877F8093E800809151018093F1008091FB
+:103C5000E8008E7F8093E80005DE19C09923B1F457
+:103C600090915501923098F48091E800877F80937D
+:103C7000E80090935101F6DD80915101882311F401
+:103C800083E001C084E08EBB16D001C040DB809190
+:103C9000E80083FF0AC08091EB0080628093EB0014
+:103CA0008091E800877F8093E8000F900F90CF917C
+:103CB000DF911F91089508958EB3882329F0809194
+:103CC000E80083FF01C043CF0895F999FECF92BD6C
+:103CD00081BDF89A992780B50895262FF999FECFCE
+:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
+:0A3CF0000FBE01960895F894FFCF6F
+:103CFA0001021E948920DCFB120110010000002041
+:103D0A00EB03EF2F00000001000109021B00010173
+:103D1A000080320904000000FE01020009210300AC
+:0A3D2A0000000C000104030904006E
+:0400000300003000C9
+:00000001FF
diff --git a/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex new file mode 100644 index 0000000..c2c7b2d --- /dev/null +++ b/firmwares/Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex @@ -0,0 +1,467 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123430001000102DC0109023E0002017C
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:103000004BC0000064C0000062C0000060C000004F
+:103010005EC000005CC000005AC0000058C0000044
+:1030200056C0000054C0000052C00000EEC40000B2
+:103030004EC000004CC000004AC0000048C0000064
+:1030400046C0000044C0000042C0000040C0000074
+:103050003EC000003CC000003AC0000038C0000084
+:1030600036C0000034C0000032C0000030C0000094
+:103070002EC000002CC000002AC0000028C00000A4
+:1030800026C0000024C0000022C0000020C00000B4
+:103090001EC000001CC0000011241FBECFEFD2E0F4
+:1030A000DEBFCDBF11E0A0E0B1E0EAEFFCE302C07B
+:1030B00005900D92AA33B107D9F711E0AAE3B1E068
+:1030C00001C01D92AB35B107E1F772D314C698CF9A
+:1030D000982F15C08091F200882371F48091E80048
+:1030E0008B7F8093E80003C08EB3882351F08091DA
+:1030F000E80082FFF9CF02C08091F100915099233E
+:1031000049F7089520914A01309149018091480181
+:103110009091470180933F0190934001C9018093B2
+:103120004101909342010895DF93CF9300D000D0E6
+:1031300000D0CDB7DEB780914501843009F45AC084
+:10314000853030F4813059F0833009F0D7C01FC08A
+:10315000853009F4A0C0863009F0D0C0C3C080918A
+:103160004601823008F0CAC0CDDF80914601882335
+:1031700061F480913F019091400123E0FC01209394
+:103180005700E89507B600FCFDCF85E008C08091A8
+:103190004601882311F0823029F4B4DF89E080935E
+:1031A0000101ACC0813009F0A9C020E030E040E06E
+:1031B00050E0F90184918F3F81F0CA01AA27BB2713
+:1031C00080933E013093400120933F018AE0809339
+:1031D000010185E080933B0191C02F5F3F4F4F4F2E
+:1031E0005F4F2030F0E33F07F0E04F07F0E05F076C
+:1031F00001F784C080914601833051F581E08093CE
+:103200003A0180914B0190914C01892B71F0809192
+:103210004701813009F072C080914A0190914901C3
+:1032200090933D0180933C0169C0809147018823C0
+:1032300061F42CE088E190E00FB6F894A8958093B3
+:1032400060000FBE2093600059C01092000156C06C
+:10325000882309F053C0809147018F3F09F04EC089
+:10326000E0E0F0E093E085E090935700E89507B642
+:1032700000FCFDCF80935700E89507B600FCFDCF1A
+:10328000E058FF4F20E3E030F20771F781E18093CF
+:103290005700E89533C0DE011196E5E0F1E083E0E8
+:1032A00001900D928150E1F7DE011496E2E0F1E029
+:1032B00083E001900D928150E1F790914701809158
+:1032C0004601882329F4FE01E90FF11D818107C021
+:1032D0008130A1F4FE01BC97E90FF11D808180933C
+:1032E00050010CC080914601833041F48091470128
+:1032F000882321F48091480180933E0126960FB6E1
+:10330000F894DEBF0FBECDBFCF91DF9108952F920D
+:103310003F924F925F926F927F929F92AF92BF9235
+:10332000CF92DF92EF92FF920F931F93CF93DF9391
+:103330008091590190915A0190934C0180934B01D7
+:1033400080914D01882351F080914D0181508093EF
+:103350004D0180914D01882309F45D9A80914E01C1
+:10336000882351F080914E01815080934E018091CD
+:103370004E01882309F45C9A80915401833009F44A
+:10338000B2C1843030F4813071F0823009F0E3C191
+:1033900011C1853009F4C5C1853008F4BAC1863041
+:1033A00009F0D9C1CDC15C9883E080934E01809132
+:1033B000E800877F8093E80080913A01882329F014
+:1033C000B3DE5D9A5C9A10923A0120914B013091E4
+:1033D0004C012115310529F42AC08EB3882309F444
+:1033E000BAC18091E80082FFF8CF8091F10080930C
+:1033F00045012150304030934C0120934B01E6E4CD
+:10340000F1E00CC08091F10081932150304081E0C7
+:10341000EB34F80719F43183208308C08091F2005F
+:10342000882381F730934C0120934B017DDE8091FE
+:103430000101853009F0BAC080914B0190914C0197
+:10344000892B21F482E080930101B0C08AE140DE43
+:1034500080913F018F713CDEC0914101D0914201CA
+:1034600020913F013091400121968E01021B130BE8
+:10347000219780914601882309F093C01801369462
+:103480002794C901A0913E01B0E09C01AD0162E02A
+:10349000E62EF12C012D112DE20EF31E041F151F37
+:1034A00059016A0190E099249394B5E0A3E048C0E3
+:1034B0008091F200882371F48091E8008B7F8093E3
+:1034C000E80004C08EB3882309F445C18091E80068
+:1034D00082FFF8CF0894210831088091F100682F0D
+:1034E0008091F100782FF5010B0190925700E8953B
+:1034F00011249F5F903419F021143104A1F4F901D3
+:10350000B0935700E89507B600FCFDCF21143104B5
+:1035100051F0F701A0935700E89507B600FCFDCFE6
+:10352000A801970190E042E0442E512C612C712CAF
+:10353000E40CF51C061D171DA40CB51CC61CD71CDD
+:103540002114310409F0B4CFD0934001C0933F015E
+:1035500081E180935700E89527C08091F20088238D
+:1035600071F48091E8008B7F8093E80004C08EB3F3
+:10357000882309F4F0C08091E80082FFF8CF6091C1
+:10358000F10080913F0190914001A7D380913F01CC
+:103590009091400101969093400180933F0101502A
+:1035A000104001151105C9F680E192DD8091E80017
+:1035B0008B7FC3C08091E800877F8093E8005D988F
+:1035C00083E080934D0104C08EB3882309F4C3C007
+:1035D0008091E80080FFF8CF80910101893091F05F
+:1035E0008A3069F480914601813049F480913F012D
+:1035F000909140018093F1009093F1009BC08091E5
+:10360000500196C0609141017091420120913F01AB
+:10361000309140016F5F7F4F7B01E21AF30A6150E6
+:10362000704080914601882389F58701169507959A
+:10363000C901A0913E01B0E09C01AD011FC0809185
+:10364000F200803271F48091E8008E7F8093E80070
+:1036500004C08EB3882309F47EC08091E80080FF07
+:10366000F8CFF901859194918093F1009093F10046
+:10367000015010402E5F3F4F4F4F5F4F0115110516
+:10368000F1F67093400160933F0129C0823039F513
+:1036900023C08091F200803271F48091E8008E7F27
+:1036A0008093E80004C08EB3882309F454C080914D
+:1036B000E80080FFF8CF00913F0110914001C80160
+:1036C00004D38093F1000F5F1F4F109340010093CC
+:1036D0003F010894E108F108E114F104D1F682E019
+:1036E0008093010127C08091E800877F8093E800E4
+:1036F00080913B018093F1001092F1001092F10053
+:103700001092F100809101018093F1001092F1007C
+:1037100011C08091E800877F8093E80010923B0100
+:1037200019C08091E800877F8093E80080910101B3
+:103730008093F1008091E8008E7F8093E8000AC0BA
+:103740008091E800877F8093E8005D9A5C9A82E030
+:103750008093010187D0DF91CF911F910F91FF904E
+:10376000EF90DF90CF90BF90AF909F907F906F9041
+:103770005F904F903F902F9008952BD181E085BFAF
+:1037800015BE089584B7877F84BF88E10FB6F8948B
+:1037900080936000109260000FBE81E085BF82E0E0
+:1037A00085BF8AB180638AB98BB180638BB90CC144
+:1037B000E9DF789401C080D2809100018823D9F795
+:1037C00080913A018823B9F7D8DFE0913C01F0916C
+:1037D0003D010995FA01923071F0933089F09130F2
+:1037E00029F488E091E022E130E019C080E090E027
+:1037F00020E030E014C08AE191E02BE130E00FC01E
+:10380000882339F480913501282F30E085E391E059
+:1038100006C080914301282F30E083E491E091833A
+:103820008083C90108958091EB0081608093EB0053
+:103830001092ED006093EC004093ED008091EE005B
+:10384000881F8827881F08951092F4001092F000B6
+:103850001092E8001092ED00EBEEF0E080818E7F98
+:10386000808308958091530188238CF403C08EB324
+:103870008823B1F08091E80082FFF9CF8091E800C1
+:103880008B7F8093E80008958EB3882349F0809160
+:10389000E80080FFF9CF8091E8008E7F8093E800F8
+:1038A00008959C014091590150915A0146175707BC
+:1038B00018F4F90120E038C06115710511F0AB0171
+:1038C000F8CF8091E8008E7F8093E80040E050E0E0
+:1038D000F0CF8091E80083FF02C081E008958091DD
+:1038E000E80082FD2DC08EB3882381F18EB3853030
+:1038F00079F18091E80080FF17C09091F20006C036
+:1039000081918093F100415050409F5F41155105D6
+:1039100011F09032A8F320E0903209F421E0809178
+:10392000E8008E7F8093E8004115510591F622232F
+:1039300081F606C08EB3882349F08EB3853041F0FE
+:103940008091E80082FFF6CF80E0089582E008953C
+:1039500083E0089554D056D01EBA1092510184E0ED
+:1039600089BD89B5826089BD09B400FEFDCF809113
+:10397000D800982F9F779093D80080688093D800C4
+:10398000809163008E7F809363008091D8008F7D4B
+:103990008093D8008091E0008E7F8093E00080913A
+:1039A000E1008E7F8093E1008091E200816080934E
+:1039B000E2008091E100877F8093E1008091E20046
+:1039C00088608093E2000895C5DF81E08093520112
+:1039D0000895C0DFE0EEF0E0808181608083E8ED53
+:1039E000F0E080818F7780830AD00CD019BCE3E6A9
+:1039F000F0E08081816080831092520108951092DE
+:103A0000E20008951092E10008951F920F920FB600
+:103A10000F9211242F933F934F935F936F937F9354
+:103A20008F939F93AF93BF93EF93FF938091E100A8
+:103A300080FF1BC08091E20080FF17C08091E100F1
+:103A40008E7F8093E1008091E2008E7F8093E20080
+:103A50008091E20080618093E2008091D8008062D2
+:103A60008093D80019BC1EBA26D18091E10084FF52
+:103A700029C08091E20084FF25C084E089BD89B51A
+:103A8000826089BD09B400FEFDCF8091D8008F7D92
+:103A90008093D8008091E1008F7E8093E100809137
+:103AA000E2008F7E8093E2008091E200816080934B
+:103AB000E20080915101882311F481E001C084E08B
+:103AC0008EBBF9D08091E10083FF22C08091E2009B
+:103AD00083FF1EC08091E100877F8093E10082E038
+:103AE0008EBB109251018091E1008E7F8093E100A6
+:103AF0008091E2008E7F8093E2008091E2008061FD
+:103B00008093E200A1DE80E060E042E28CDED3D070
+:103B10008091E10082FF0AC08091E20082FF06C02E
+:103B20008091E1008B7F8093E100C5D0FF91EF9100
+:103B3000BF91AF919F918F917F916F915F914F91C5
+:103B40003F912F910F900FBE0F901F9018951F93CC
+:103B5000DF93CF9300D0CDB7DEB7E3E5F1E08091FE
+:103B6000F100819381E0EB35F807C9F7909153019B
+:103B700080915401853011F1863040F48130B9F0E4
+:103B8000813070F0833009F081C011C0883009F4B1
+:103B900053C0893009F462C0863009F077C02DC067
+:103BA000903809F474C0923809F070C070C099233D
+:103BB00009F46DC0923009F069C069C0992309F019
+:103BC00065C0109155018091E800877F8093E800DF
+:103BD00049DE04C08EB3882309F459C08091E800FF
+:103BE00080FFF8CF812F8F7711F492E001C093E02E
+:103BF0009EBB80688093E3004AC09058923008F0E2
+:103C000045C0809155019091560160915701AE01D8
+:103C10004F5F5F4FDFDDBC010097C9F18091E80085
+:103C2000877F8093E80089819A813BDE8091E8005C
+:103C30008B7F8093E8002BC0903841F58091E8009D
+:103C4000877F8093E800809151018093F1008091FB
+:103C5000E8008E7F8093E80005DE19C09923B1F457
+:103C600090915501923098F48091E800877F80937D
+:103C7000E80090935101F6DD80915101882311F401
+:103C800083E001C084E08EBB16D001C040DB809190
+:103C9000E80083FF0AC08091EB0080628093EB0014
+:103CA0008091E800877F8093E8000F900F90CF917C
+:103CB000DF911F91089508958EB3882329F0809194
+:103CC000E80083FF01C043CF0895F999FECF92BD6C
+:103CD00081BDF89A992780B50895262FF999FECFCE
+:103CE0001FBA92BD81BD20BD0FB6F894FA9AF99A19
+:0A3CF0000FBE01960895F894FFCF6F
+:103CFA0001021E948920DCFB120110010000002041
+:103D0A00EB03EF2F00000001000109021B00010173
+:103D1A000080320904000000FE01020009210300AC
+:0A3D2A0000000C000104030904006E
+:0400000300003000C9
+:00000001FF
diff --git a/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex new file mode 100644 index 0000000..efbbf15 --- /dev/null +++ b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex @@ -0,0 +1,254 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123420001000102DC0109023E0002017D
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:00000001FF
diff --git a/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-MegaADK-Rev3.hex b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-MegaADK-Rev3.hex new file mode 100644 index 0000000..3af6a24 --- /dev/null +++ b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-MegaADK-Rev3.hex @@ -0,0 +1,254 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123440001000102DC0109023E0002017B
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:00000001FF
diff --git a/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Uno-Rev3.hex b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Uno-Rev3.hex new file mode 100644 index 0000000..d1404ee --- /dev/null +++ b/firmwares/arduino-usbserial/Arduino-usbserial-atmega16u2-Uno-Rev3.hex @@ -0,0 +1,254 @@ +:1000000090C00000A9C00000A7C00000A5C000006B
+:10001000A3C00000A1C000009FC000009DC0000060
+:100020009BC0000099C0000097C0000048C40000B9
+:100030000CC4000091C000008FC000008DC0000003
+:100040008BC0000089C0000087C0000085C0000090
+:1000500083C0000081C000007FC0000002C100001A
+:100060007BC0000079C0000077C0000075C00000B0
+:1000700073C0000071C000006FC000006DC00000C0
+:100080006BC0000069C0000067C0000065C00000D0
+:1000900063C0000061C000001201100102000008EE
+:1000A0004123430001000102DC0109023E0002017C
+:1000B00000C0320904000001020201000524000111
+:1000C0001004240206052406000107058203080027
+:1000D000FF09040100020A000000070504024000B5
+:1000E00001070583024000010403090432034100B3
+:1000F00072006400750069006E006F002000280027
+:100100007700770077002E006100720064007500B0
+:1001100069006E006F002E0063006300290000007C
+:10012000000011241FBECFEFD2E0DEBFCDBF11E033
+:10013000A0E0B1E0ECEAFFE002C005900D92A6312C
+:10014000B107D9F712E0A6E1B1E001C01D92AF32CC
+:10015000B107E1F7F1D028C753CF9C01DC01AE57BE
+:10016000BF4FED91FC91119741911196FC93EE9345
+:1001700080589F4FE817F90711F42D933C939FB7D0
+:10018000F894F901EC57FF4F8081815080839FBF25
+:10019000842F0895DF92EF92FF920F931F93FC013B
+:1001A0008489813019F0823021F405C040E3D42ED7
+:1001B00004C0DD2402C030E2D32E8389823011F4E2
+:1001C00088E0D82A8589873031F0883031F0863050
+:1001D00031F482E003C084E001C086E0D82A1092A6
+:1001E000C9001092C8001092CA00E784F088018903
+:1001F000128980E0E81681EEF80680E0080780E0CA
+:10020000180719F420E130E00FC0C801B701969536
+:1002100087957795679560587B47814E9F4FA801DA
+:100220009701A0D6215030403093CD002093CC00D0
+:10023000D092CA0080E0E81681EEF80680E0080758
+:1002400080E0180711F082E001C080E08093C800D0
+:1002500088E98093C9001F910F91FF90EF90DF9084
+:1002600008951F920F920FB60F9211242F938F9320
+:100270009F93EF93FF939091CE008EB38430F1F46F
+:10028000E0919901F0919A019083E0919901F091A8
+:100290009A01CF01019690939A018093990189590F
+:1002A000914021F489E191E0928381839FB7F89492
+:1002B00080919D018F5F80939D019FBFFF91EF9182
+:1002C0009F918F912F910F900FBE0F901F901895B7
+:1002D000FC01858580FF02C05F9808955F9A0895AC
+:1002E00080E091E0D5C580E091E088C584B7877F44
+:1002F00084BF28E10FB6F89420936000109260004C
+:100300000FBE87E690E09093CD008093CC0086E00E
+:100310008093CA001092C8002093C900539A5A9A39
+:100320008AB180638AB98BB180638BB983D284E050
+:1003300085BD5F9A579A08950F931F93CF93DF93CC
+:10034000D5DF2FB7F8948EE991E090931F02809348
+:100350001E0290932102809320022FBF2FB7F894A2
+:1003600089E191E090939A018093990190939C0187
+:1003700080939B012FBF7894CEE9D1E003E08FB743
+:10038000F894909122028FBF903809F180E091E0BB
+:10039000ABD497FD1CC0E0911E02F0911F02808338
+:1003A000E0911E02F0911F02CF01019690931F026F
+:1003B00080931E028E51924011F4D283C1839FB765
+:1003C000F894809122028F5F809322029FBF8FB7A3
+:1003D000F89410919D018FBFA89902C0113678F151
+:1003E000A89A80919D01882361F05D980093160181
+:1003F00008C089E191E0B1DE682F80E091E0DAD4B5
+:1004000011501123B1F780911601882351F080918A
+:10041000160181508093160180911601882309F4FA
+:100420005D9A80911701882351F0809117018150C6
+:100430008093170180911701882309F45C9A8FB784
+:10044000F894909122028FBF992369F08EE991E090
+:1004500084DE982F8091C80085FFFCCF9093CE005A
+:100460005C980093170180E091E095D42AD487CF5F
+:10047000DA01923049F0933061F09130F9F4E8E913
+:10048000F0E022E130E01EC0EAEAF0E02EE330E0E6
+:1004900019C0813049F0813018F0823079F408C0F9
+:1004A000E8EEF0E0849107C0ECEEF0E0849103C048
+:1004B000E0E2F1E08491282F30E004C0E0E0F0E0D9
+:1004C00020E030E0ED93FC93C901089528E030E08E
+:1004D00040E003C04F5F220F331F28173907D0F3C6
+:1004E000842F8295807F08958093E9008091EB00AE
+:1004F00081608093EB001092ED006093EC004093DC
+:10050000ED008091EE00881F8827881F08951092C3
+:10051000F40090E09093E9001092F0001092E8004F
+:100520001092ED008091EB008E7F8093EB009F5F37
+:10053000953081F708958091270288238CF403C0B9
+:100540008EB38823B1F08091E80082FFF9CF8091CB
+:10055000E8008B778093E80008958EB3882349F0F4
+:100560008091E80080FFF9CF8091E8008E7780933A
+:10057000E800089594E68091EC0080FF05C080912A
+:10058000E80080FF05C023C08091E80082FD1FC005
+:100590008EB3882311F482E008958EB3853011F470
+:1005A00083E008958091EB0085FF02C081E008950B
+:1005B0008091E10082FFDFCF8091E1008B7F80930B
+:1005C000E100992311F484E008959150D4CF80E0A4
+:1005D00008959C0140912D0250912E024617570715
+:1005E00018F4F90120E038C06115710511F0AB0174
+:1005F000F8CF8091E8008E778093E80040E050E0EB
+:10060000F0CF8091E80083FF02C081E008958091DF
+:10061000E80082FD2DC08EB3882381F18EB3853032
+:1006200079F18091E80080FF17C09091F20006C038
+:1006300081918093F100415050409F5F41155105D9
+:1006400011F09830A8F320E0983009F421E080916F
+:10065000E8008E778093E8004115510591F622233A
+:1006600081F606C08EB3882349F08EB3853041F001
+:100670008091E80082FFF6CF80E0089582E008953F
+:1006800083E008959C0140912D0250912E0246175F
+:10069000570710F490E03BC06115710511F0AB01F4
+:1006A000F9CF8091E8008E778093E80040E050E039
+:1006B000F1CF8091E80083FF02C081E0089580912E
+:1006C000E80082FD30C08EB3882399F18EB3853067
+:1006D00091F18091E80080FF1AC08091F20009C07A
+:1006E000F9012F5F3F4FE491E093F10041505040FA
+:1006F0008F5F4115510511F0883090F390E08830FC
+:1007000009F491E08091E8008E778093E80041152C
+:10071000510579F6992369F606C08EB3882349F00E
+:100720008EB3853041F08091E80082FFF6CF80E003
+:10073000089582E0089583E008959C016115710594
+:1007400029F48091E8008B778093E800F90120C0BC
+:100750008091E80083FF02C081E008958EB3882372
+:1007600039F18EB3853031F18091E80082FFF0CF0E
+:1007700006C08091F10081936150704021F080911A
+:10078000F2008823B1F78091E8008B778093E8002E
+:1007900061157105E9F606C08EB3882349F08EB362
+:1007A000853041F08091E80080FFF6CF80E0089529
+:1007B00082E0089583E0089542D044D01EBA10929A
+:1007C0002502109224021092230284E089BD89B58B
+:1007D000826089BD09B400FEFDCF8091D800982FBA
+:1007E0009F779093D80080688093D80080916300B1
+:1007F0008E7F809363008091D8008F7D8093D80096
+:100800008091E0008E7F8093E0008091E1008E7FF8
+:100810008093E1008091E20081608093E20080910A
+:10082000E100877F8093E1008091E20088608093FF
+:10083000E2000895C1DF81E08093260208951092BE
+:10084000E20008951092E10008951F920F920FB6F2
+:100850000F9211241F932F933F934F935F936F93A6
+:100860007F938F939F93AF93BF93EF93FF93E9EEA3
+:10087000F0E0108117701082E0EFF0E08081877F58
+:1008800080837894C3D0F894A9EEB0E01C92E0EF96
+:10089000F0E08081886080831C93FF91EF91BF918D
+:1008A000AF919F918F917F916F915F914F913F9108
+:1008B0002F911F910F900FBE0F901F9018951F92B0
+:1008C0000F920FB60F9211242F933F934F935F9384
+:1008D0006F937F938F939F93AF93BF93EF93FF9308
+:1008E0008091E10080FF1BC08091E20080FF17C073
+:1008F0008091E1008E7F8093E1008091E2008E7F05
+:100900008093E2008091E20080618093E200809118
+:10091000D80080628093D80019BC1EBAD1D18091D2
+:10092000E10084FF29C08091E20084FF25C084E0BB
+:1009300089BD89B5826089BD09B400FEFDCF809173
+:10094000D8008F7D8093D8008091E1008F7E8093C6
+:10095000E1008091E2008F7E8093E2008091E200CE
+:1009600081608093E20080912502882311F481E068
+:1009700001C084E08EBBA4D18091E10083FF27C039
+:100980008091E20083FF23C08091E100877F809304
+:10099000E10082E08EBB109225028091E1008E7F03
+:1009A0008093E1008091E2008E7F8093E20080914D
+:1009B000E20080618093E200AADD80E060E042E036
+:1009C00093DD8091F00088608093F00079D1809170
+:1009D000E10082FF0AC08091E20082FF06C08091A0
+:1009E000E1008B7F8093E1006BD1FF91EF91BF918C
+:1009F000AF919F918F917F916F915F914F913F91B7
+:100A00002F910F900FBE0F901F9018951F93DF939B
+:100A1000CF93CDB7DEB7AC970FB6F894DEBF0FBE5D
+:100A2000CDBFE7E2F2E08091F100819322E0EF3266
+:100A3000F207C9F78091270230912802353009F476
+:100A400087C0363040F43130C9F1313070F0333086
+:100A500009F01DC133C0383009F4EFC0393009F452
+:100A6000FEC0363009F013C192C0803821F08238C0
+:100A700009F00DC108C090912302809124028823BF
+:100A800099F0926011C080912B0287708093E900E9
+:100A90008091EB0090E025E0969587952A95E1F707
+:100AA000982F91701092E9008091E800877F8093E1
+:100AB000E8009093F1001092F100CAC0882319F069
+:100AC000823009F0E4C090E08F719070009721F0BF
+:100AD000029709F0DDC00CC080912902813009F035
+:100AE000D7C010922402333069F5809324022AC0C3
+:100AF00080912902882331F520912B02277009F477
+:100B0000C7C02093E9008091EB0080FFC1C0333063
+:100B100021F48091EB00806213C08091EB00806132
+:100B20008093EB0081E090E002C0880F991F2A9526
+:100B3000E2F78093EA001092EA008091EB0088606F
+:100B40008093EB001092E9008091E800877F83C0DA
+:100B5000882309F09CC0109129028091E800877FCA
+:100B60008093E800E8DC04C08EB3882309F490C0C9
+:100B70008091E80080FFF8CF812F8F7711F492E009
+:100B800001C093E09EBB80688093E30081C08058E1
+:100B9000823008F07CC08091290290912A0223E0E3
+:100BA0008C3D920799F55FB7F894DE0115964EE0FB
+:100BB00020E030E061E2E42FF0E0609357008491A0
+:100BC00020FF03C082958F704F5F982F9F70892FF1
+:100BD000805D8A3308F0895F8C9311961C9211977F
+:100BE0002F5F3F4F12962431310529F75FBF8AE20C
+:100BF0008B8383E08C838091E800877F8093E8007B
+:100C0000CE0103966AE270E0E4DC11C060912B0231
+:100C1000AE014F5F5F4F2CDCBC010097C9F18091A2
+:100C2000E800877F8093E80089819A812BDD80919D
+:100C3000E8008B778093E8002BC0803841F58091E5
+:100C4000E800877F8093E800809125028093F1007F
+:100C50008091E8008E778093E8006DDC19C08823CE
+:100C6000B1F490912902923098F48091E800877F46
+:100C70008093E800909325025EDC80912502882312
+:100C800011F483E001C084E08EBB2DDB01C028DBC2
+:100C90008091E80083FF0AC08091EB00806280931E
+:100CA000EB008091E800877F8093E800AC960FB658
+:100CB000F894DEBF0FBECDBFCF91DF911F91089595
+:100CC00008951F938EB3882361F01091E90010926C
+:100CD000E9008091E80083FF01C098DE177010934F
+:100CE000E9001F9108950895FC018EB3843021F529
+:100CF00087859089A189B2890097A105B105E1F0A6
+:100D000085818093E9008091E80082FF15C0809181
+:100D1000F200882319F42FEF3FEF04C08091F10017
+:100D2000282F30E08091F200882341F48091E80080
+:100D30008B778093E80002C02FEF3FEFC901089541
+:100D4000FC018EB3843011F587859089A189B28921
+:100D50000097A105B105D1F081818093E9008091D0
+:100D6000F2008823A9F09091E8008091E8008E7746
+:100D70008093E80095FD0CC0FDDB982F882349F493
+:100D80008091E8008E778093E80003C092E001C074
+:100D900090E0892F0895FC018EB3843051F487854B
+:100DA0009089A189B2890097A105B10511F0CF0101
+:100DB000C7CF08951F93FC01162F8EB38430D9F44A
+:100DC00087859089A189B2890097A105B10599F01D
+:100DD00081818093E9008091E80085FD08C08091C1
+:100DE000E8008E778093E800C5DB882329F4109310
+:100DF000F10080E001C082E01F9108950F931F93DE
+:100E0000CF93DF93EC010D96FC0189E0DF011D9289
+:100E10008A95E9F72A813B8109818C81882311F425
+:100E200010E001C014E0C90151DB182B1260802FC3
+:100E300061E8412F59DB882329F12E813F810D8103
+:100E40008885882311F410E001C014E0C9013EDB5D
+:100E5000182B1260802F60E8412F46DB882391F029
+:100E60002A853B8509858C85882311F410E001C013
+:100E700014E0C9012BDB182B1260802F61EC412F8D
+:100E800033DB01C080E0DF91CF911F910F91089576
+:100E9000CF93DF93EC018091E80083FF60C08881ED
+:100EA00090E020912B0230912C022817390709F08D
+:100EB00056C080912802813261F0823220F4803263
+:100EC00009F04DC019C0823269F1833209F047C080
+:100ED00038C080912702813A09F041C08091E80032
+:100EE000877F8093E800CE010F9667E070E071DBAA
+:100EF0008091E8008B7713C080912702813279F5C9
+:100F00008091E800877F8093E800CE010F9667E02C
+:100F100070E013DCCE013ED98091E8008E7780939B
+:100F2000E8001DC0809127028132C9F48091E80059
+:100F3000877F8093E800809129028D87CE01C8D9F0
+:100F40000DC080912702813251F48091E800877FA3
+:100F50008093E800CE0160912902C5DEECDADF91D2
+:100F6000CF910895A1E21A2EAA1BBB1BFD010DC053
+:100F7000AA1FBB1FEE1FFF1FA217B307E407F50749
+:100F800020F0A21BB30BE40BF50B661F771F881F25
+:100F9000991F1A9469F760957095809590959B01BB
+:0C0FA000AC01BD01CF010895F894FFCF13
+:100FAC0000034000000440000002080000000000A4
+:060FBC000000000000002F
+:00000001FF
diff --git a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino index d1e29bd..d1e29bd 100644 --- a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.pde +++ b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.pde b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino index 88e3488..88e3488 100644 --- a/libraries/EEPROM/examples/eeprom_read/eeprom_read.pde +++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino diff --git a/libraries/EEPROM/examples/eeprom_write/eeprom_write.pde b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino index ae7c57e..ae7c57e 100644 --- a/libraries/EEPROM/examples/eeprom_write/eeprom_write.pde +++ b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino diff --git a/libraries/Ethernet/Client.h b/libraries/Ethernet/Client.h deleted file mode 100644 index 582f493..0000000 --- a/libraries/Ethernet/Client.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef client_h -#define client_h -#include "Arduino.h" -#include "Print.h" - -class Client : public Stream { - -public: - Client(); - Client(uint8_t sock); - - uint8_t status(); - int connect(IPAddress ip, uint16_t port); - int connect(const char *host, uint16_t port); - virtual void write(uint8_t); - virtual void write(const char *str); - virtual void write(const uint8_t *buf, size_t size); - virtual int available(); - virtual int read(); - virtual int read(uint8_t *buf, size_t size); - virtual int peek(); - virtual void flush(); - void stop(); - uint8_t connected(); - operator bool(); - - friend class Server; - -private: - static uint16_t _srcport; - uint8_t _sock; -}; - -#endif diff --git a/libraries/Ethernet/Dhcp.cpp b/libraries/Ethernet/Dhcp.cpp index c20d2e6..62bbfeb 100755 --- a/libraries/Ethernet/Dhcp.cpp +++ b/libraries/Ethernet/Dhcp.cpp @@ -163,15 +163,15 @@ void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) // OPT - host name
buffer[16] = hostName;
- buffer[17] = strlen(HOST_NAME) + 3; // length of hostname + last 3 bytes of mac address
+ buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address
strcpy((char*)&(buffer[18]), HOST_NAME);
- buffer[24] = _dhcpMacAddr[3];
- buffer[25] = _dhcpMacAddr[4];
- buffer[26] = _dhcpMacAddr[5];
+ printByte((char*)&(buffer[24]), _dhcpMacAddr[3]);
+ printByte((char*)&(buffer[26]), _dhcpMacAddr[4]);
+ printByte((char*)&(buffer[28]), _dhcpMacAddr[5]);
//put data in W5100 transmit buffer
- _dhcpUdpSocket.write(buffer, 27);
+ _dhcpUdpSocket.write(buffer, 30);
if(messageType == DHCP_REQUEST)
{
@@ -243,7 +243,7 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr // Skip to the option part
// Doing this a byte at a time so we don't have to put a big buffer
// on the stack (as we don't have lots of memory lying around)
- for (int i =0; i < (240 - sizeof(RIP_MSG_FIXED)); i++)
+ for (int i =0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++)
{
_dhcpUdpSocket.read(); // we don't care about the returned byte
}
@@ -271,11 +271,19 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr case routersOnSubnet :
opt_len = _dhcpUdpSocket.read();
_dhcpUdpSocket.read(_dhcpGatewayIp, 4);
+ for (int i = 0; i < opt_len-4; i++)
+ {
+ _dhcpUdpSocket.read();
+ }
break;
case dns :
opt_len = _dhcpUdpSocket.read();
_dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
+ for (int i = 0; i < opt_len-4; i++)
+ {
+ _dhcpUdpSocket.read();
+ }
break;
case dhcpServerIdentifier :
@@ -339,3 +347,13 @@ IPAddress DhcpClass::getDnsServerIp() return IPAddress(_dhcpDnsServerIp);
}
+void DhcpClass::printByte(char * buf, uint8_t n ) {
+ char *str = &buf[1];
+ buf[0]='0';
+ do {
+ unsigned long m = n;
+ n /= 16;
+ char c = m - 16 * n;
+ *str-- = c < 10 ? c + '0' : c + 'A' - 10;
+ } while(n);
+}
diff --git a/libraries/Ethernet/Dhcp.h b/libraries/Ethernet/Dhcp.h index c003494..149876d 100755 --- a/libraries/Ethernet/Dhcp.h +++ b/libraries/Ethernet/Dhcp.h @@ -4,7 +4,7 @@ #ifndef Dhcp_h
#define Dhcp_h
-#include "Udp.h"
+#include "EthernetUdp.h"
/* DHCP state machine. */
#define STATE_DHCP_START 0
@@ -139,10 +139,11 @@ private: uint8_t _dhcpGatewayIp[4];
uint8_t _dhcpDhcpServerIp[4];
uint8_t _dhcpDnsServerIp[4];
- UDP _dhcpUdpSocket;
+ EthernetUDP _dhcpUdpSocket;
void presend_DHCP();
void send_DHCP_MESSAGE(uint8_t, uint16_t);
+ void printByte(char *, uint8_t);
uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
public:
diff --git a/libraries/Ethernet/Dns.cpp b/libraries/Ethernet/Dns.cpp index a049c76..b3c1a9d 100644 --- a/libraries/Ethernet/Dns.cpp +++ b/libraries/Ethernet/Dns.cpp @@ -3,7 +3,7 @@ // Released under Apache License, version 2.0 #include "w5100.h" -#include "Udp.h" +#include "EthernetUdp.h" #include "util.h" #include "Dns.h" @@ -252,7 +252,7 @@ uint16_t DNSClient::BuildRequest(const char* aName) } -uint16_t DNSClient::ProcessResponse(int aTimeout, IPAddress& aAddress) +uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) { uint32_t startTime = millis(); @@ -285,7 +285,7 @@ uint16_t DNSClient::ProcessResponse(int aTimeout, IPAddress& aAddress) uint16_t header_flags = htons(*((uint16_t*)&header[2])); // Check that it's a response to this request if ( ( iRequestId != (*((uint16_t*)&header[0])) ) || - (header_flags & QUERY_RESPONSE_MASK != RESPONSE_FLAG) ) + ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) { // Mark the entire packet as read iUdp.flush(); @@ -310,7 +310,7 @@ uint16_t DNSClient::ProcessResponse(int aTimeout, IPAddress& aAddress) } // Skip over any questions - for (int i =0; i < htons(*((uint16_t*)&header[4])); i++) + for (uint16_t i =0; i < htons(*((uint16_t*)&header[4])); i++) { // Skip over the name uint8_t len; @@ -340,7 +340,7 @@ uint16_t DNSClient::ProcessResponse(int aTimeout, IPAddress& aAddress) // type A answer) and some authority and additional resource records but // we're going to ignore all of them. - for (int i =0; i < answerCount; i++) + for (uint16_t i =0; i < answerCount; i++) { // Skip the name uint8_t len; @@ -407,7 +407,7 @@ uint16_t DNSClient::ProcessResponse(int aTimeout, IPAddress& aAddress) else { // This isn't an answer type we're after, move onto the next one - for (int i =0; i < htons(header_flags); i++) + for (uint16_t i =0; i < htons(header_flags); i++) { iUdp.read(); // we don't care about the returned byte } diff --git a/libraries/Ethernet/Dns.h b/libraries/Ethernet/Dns.h index 9582351..6bcb98a 100644 --- a/libraries/Ethernet/Dns.h +++ b/libraries/Ethernet/Dns.h @@ -5,7 +5,7 @@ #ifndef DNSClient_h
#define DNSClient_h
-#include <Udp.h>
+#include <EthernetUdp.h>
class DNSClient
{
@@ -31,11 +31,11 @@ public: protected:
uint16_t BuildRequest(const char* aName);
- uint16_t ProcessResponse(int aTimeout, IPAddress& aAddress);
+ uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);
IPAddress iDNSServer;
uint16_t iRequestId;
- UDP iUdp;
+ EthernetUDP iUdp;
};
#endif
diff --git a/libraries/Ethernet/Ethernet.cpp b/libraries/Ethernet/Ethernet.cpp index 937f5b4..c298f3d 100644 --- a/libraries/Ethernet/Ethernet.cpp +++ b/libraries/Ethernet/Ethernet.cpp @@ -34,26 +34,36 @@ int EthernetClass::begin(uint8_t *mac_address) void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip) { + // Assume the DNS server will be the machine on the same network as the local IP + // but with last octet being '1' + IPAddress dns_server = local_ip; + dns_server[3] = 1; + begin(mac_address, local_ip, dns_server); +} + +void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server) +{ // Assume the gateway will be the machine on the same network as the local IP // but with last octet being '1' IPAddress gateway = local_ip; gateway[3] = 1; - begin(mac_address, local_ip, gateway); + begin(mac_address, local_ip, dns_server, gateway); } -void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway) +void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway) { IPAddress subnet(255, 255, 255, 0); - begin(mac_address, local_ip, gateway, subnet); + begin(mac_address, local_ip, dns_server, gateway, subnet); } -void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress gateway, IPAddress subnet) +void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) { W5100.init(); W5100.setMACAddress(mac); W5100.setIPAddress(local_ip._address); W5100.setGatewayIp(gateway._address); W5100.setSubnetMask(subnet._address); + _dnsServerAddress = dns_server; } IPAddress EthernetClass::localIP() diff --git a/libraries/Ethernet/Ethernet.h b/libraries/Ethernet/Ethernet.h index fdf0b7f..c916dda 100644 --- a/libraries/Ethernet/Ethernet.h +++ b/libraries/Ethernet/Ethernet.h @@ -4,8 +4,8 @@ #include <inttypes.h> //#include "w5100.h" #include "IPAddress.h" -#include "Client.h" -#include "Server.h" +#include "EthernetClient.h" +#include "EthernetServer.h" #define MAX_SOCK_NUM 4 @@ -20,16 +20,17 @@ public: // Returns 0 if the DHCP configuration failed, and 1 if it succeeded int begin(uint8_t *mac_address); void begin(uint8_t *mac_address, IPAddress local_ip); - void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway); - void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress gateway, IPAddress subnet); + void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server); + void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway); + void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); IPAddress localIP(); IPAddress subnetMask(); IPAddress gatewayIP(); IPAddress dnsServerIP(); - friend class Client; - friend class Server; + friend class EthernetClient; + friend class EthernetServer; }; extern EthernetClass Ethernet; diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/EthernetClient.cpp index f146ac5..a77a62b 100644 --- a/libraries/Ethernet/Client.cpp +++ b/libraries/Ethernet/EthernetClient.cpp @@ -8,19 +8,19 @@ extern "C" { #include "Arduino.h" #include "Ethernet.h" -#include "Client.h" -#include "Server.h" +#include "EthernetClient.h" +#include "EthernetServer.h" #include "Dns.h" -uint16_t Client::_srcport = 1024; +uint16_t EthernetClient::_srcport = 1024; -Client::Client() : _sock(MAX_SOCK_NUM) { +EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) { } -Client::Client(uint8_t sock) : _sock(sock) { +EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) { } -int Client::connect(const char* host, uint16_t port) { +int EthernetClient::connect(const char* host, uint16_t port) { // Look up the host first int ret = 0; DNSClient dns; @@ -35,7 +35,7 @@ int Client::connect(const char* host, uint16_t port) { } } -int Client::connect(IPAddress ip, uint16_t port) { +int EthernetClient::connect(IPAddress ip, uint16_t port) { if (_sock != MAX_SOCK_NUM) return 0; @@ -54,7 +54,7 @@ int Client::connect(IPAddress ip, uint16_t port) { if (_srcport == 0) _srcport = 1024; socket(_sock, SnMR::TCP, _srcport, 0); - if (!::connect(_sock, ip.raw_address(), port)) { + if (!::connect(_sock, rawIPAddress(ip), port)) { _sock = MAX_SOCK_NUM; return 0; } @@ -70,28 +70,29 @@ int Client::connect(IPAddress ip, uint16_t port) { return 1; } -void Client::write(uint8_t b) { - if (_sock != MAX_SOCK_NUM) - send(_sock, &b, 1); +size_t EthernetClient::write(uint8_t b) { + return write(&b, 1); } -void Client::write(const char *str) { - if (_sock != MAX_SOCK_NUM) - send(_sock, (const uint8_t *)str, strlen(str)); -} - -void Client::write(const uint8_t *buf, size_t size) { - if (_sock != MAX_SOCK_NUM) - send(_sock, buf, size); +size_t EthernetClient::write(const uint8_t *buf, size_t size) { + if (_sock == MAX_SOCK_NUM) { + setWriteError(); + return 0; + } + if (!send(_sock, buf, size)) { + setWriteError(); + return 0; + } + return size; } -int Client::available() { +int EthernetClient::available() { if (_sock != MAX_SOCK_NUM) return W5100.getRXReceivedSize(_sock); return 0; } -int Client::read() { +int EthernetClient::read() { uint8_t b; if ( recv(_sock, &b, 1) > 0 ) { @@ -105,11 +106,11 @@ int Client::read() { } } -int Client::read(uint8_t *buf, size_t size) { +int EthernetClient::read(uint8_t *buf, size_t size) { return recv(_sock, buf, size); } -int Client::peek() { +int EthernetClient::peek() { uint8_t b; // Unlike recv, peek doesn't check to see if there's any data available, so we must if (!available()) @@ -118,12 +119,12 @@ int Client::peek() { return b; } -void Client::flush() { +void EthernetClient::flush() { while (available()) read(); } -void Client::stop() { +void EthernetClient::stop() { if (_sock == MAX_SOCK_NUM) return; @@ -143,7 +144,7 @@ void Client::stop() { _sock = MAX_SOCK_NUM; } -uint8_t Client::connected() { +uint8_t EthernetClient::connected() { if (_sock == MAX_SOCK_NUM) return 0; uint8_t s = status(); @@ -151,14 +152,14 @@ uint8_t Client::connected() { (s == SnSR::CLOSE_WAIT && !available())); } -uint8_t Client::status() { +uint8_t EthernetClient::status() { if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED; return W5100.readSnSR(_sock); } // the next function allows us to use the client returned by -// Server::available() as the condition in an if-statement. +// EthernetServer::available() as the condition in an if-statement. -Client::operator bool() { +EthernetClient::operator bool() { return _sock != MAX_SOCK_NUM; } diff --git a/libraries/Ethernet/EthernetClient.h b/libraries/Ethernet/EthernetClient.h new file mode 100644 index 0000000..44740fe --- /dev/null +++ b/libraries/Ethernet/EthernetClient.h @@ -0,0 +1,37 @@ +#ifndef ethernetclient_h +#define ethernetclient_h +#include "Arduino.h" +#include "Print.h" +#include "Client.h" +#include "IPAddress.h" + +class EthernetClient : public Client { + +public: + EthernetClient(); + EthernetClient(uint8_t sock); + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool(); + + friend class EthernetServer; + + using Print::write; + +private: + static uint16_t _srcport; + uint8_t _sock; +}; + +#endif diff --git a/libraries/Ethernet/Server.cpp b/libraries/Ethernet/EthernetServer.cpp index 4271741..0308b92 100644 --- a/libraries/Ethernet/Server.cpp +++ b/libraries/Ethernet/EthernetServer.cpp @@ -5,18 +5,18 @@ extern "C" { } #include "Ethernet.h" -#include "Client.h" -#include "Server.h" +#include "EthernetClient.h" +#include "EthernetServer.h" -Server::Server(uint16_t port) +EthernetServer::EthernetServer(uint16_t port) { _port = port; } -void Server::begin() +void EthernetServer::begin() { for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { - Client client(sock); + EthernetClient client(sock); if (client.status() == SnSR::CLOSED) { socket(sock, SnMR::TCP, _port, 0); listen(sock); @@ -26,12 +26,12 @@ void Server::begin() } } -void Server::accept() +void EthernetServer::accept() { int listening = 0; for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { - Client client(sock); + EthernetClient client(sock); if (EthernetClass::_server_port[sock] == _port) { if (client.status() == SnSR::LISTEN) { @@ -48,12 +48,12 @@ void Server::accept() } } -Client Server::available() +EthernetClient EthernetServer::available() { accept(); for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { - Client client(sock); + EthernetClient client(sock); if (EthernetClass::_server_port[sock] == _port && (client.status() == SnSR::ESTABLISHED || client.status() == SnSR::CLOSE_WAIT)) { @@ -64,29 +64,28 @@ Client Server::available() } } - return Client(MAX_SOCK_NUM); + return EthernetClient(MAX_SOCK_NUM); } -void Server::write(uint8_t b) +size_t EthernetServer::write(uint8_t b) { - write(&b, 1); + return write(&b, 1); } -void Server::write(const char *str) -{ - write((const uint8_t *)str, strlen(str)); -} - -void Server::write(const uint8_t *buffer, size_t size) +size_t EthernetServer::write(const uint8_t *buffer, size_t size) { + size_t n = 0; + accept(); for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { - Client client(sock); + EthernetClient client(sock); if (EthernetClass::_server_port[sock] == _port && client.status() == SnSR::ESTABLISHED) { - client.write(buffer, size); + n += client.write(buffer, size); } } + + return n; } diff --git a/libraries/Ethernet/EthernetServer.h b/libraries/Ethernet/EthernetServer.h new file mode 100644 index 0000000..86ccafe --- /dev/null +++ b/libraries/Ethernet/EthernetServer.h @@ -0,0 +1,22 @@ +#ifndef ethernetserver_h +#define ethernetserver_h + +#include "Server.h" + +class EthernetClient; + +class EthernetServer : +public Server { +private: + uint16_t _port; + void accept(); +public: + EthernetServer(uint16_t); + EthernetClient available(); + virtual void begin(); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + using Print::write; +}; + +#endif diff --git a/libraries/Ethernet/Udp.cpp b/libraries/Ethernet/EthernetUdp.cpp index aed5d98..9c752fc 100644 --- a/libraries/Ethernet/Udp.cpp +++ b/libraries/Ethernet/EthernetUdp.cpp @@ -33,10 +33,10 @@ #include "Dns.h" /* Constructor */ -UDP::UDP() : _sock(MAX_SOCK_NUM) {} +EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {} -/* Start UDP socket, listening at local port PORT */ -uint8_t UDP::begin(uint16_t port) { +/* Start EthernetUDP socket, listening at local port PORT */ +uint8_t EthernetUDP::begin(uint16_t port) { if (_sock != MAX_SOCK_NUM) return 0; @@ -59,12 +59,12 @@ uint8_t UDP::begin(uint16_t port) { /* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes. * returned value includes 8 byte UDP header!*/ -int UDP::available() { +int EthernetUDP::available() { return W5100.getRXReceivedSize(_sock); } -/* Release any resources being used by this UDP instance */ -void UDP::stop() +/* Release any resources being used by this EthernetUDP instance */ +void EthernetUDP::stop() { if (_sock == MAX_SOCK_NUM) return; @@ -75,7 +75,7 @@ void UDP::stop() _sock = MAX_SOCK_NUM; } -int UDP::beginPacket(const char *host, uint16_t port) +int EthernetUDP::beginPacket(const char *host, uint16_t port) { // Look up the host first int ret = 0; @@ -91,35 +91,30 @@ int UDP::beginPacket(const char *host, uint16_t port) } } -int UDP::beginPacket(IPAddress ip, uint16_t port) +int EthernetUDP::beginPacket(IPAddress ip, uint16_t port) { _offset = 0; - return startUDP(_sock, ip.raw_address(), port); + return startUDP(_sock, rawIPAddress(ip), port); } -int UDP::endPacket() +int EthernetUDP::endPacket() { return sendUDP(_sock); } -void UDP::write(uint8_t byte) +size_t EthernetUDP::write(uint8_t byte) { - write(&byte, 1); + return write(&byte, 1); } -void UDP::write(const char *str) -{ - size_t len = strlen(str); - write((const uint8_t *)str, len); -} - -void UDP::write(const uint8_t *buffer, size_t size) +size_t EthernetUDP::write(const uint8_t *buffer, size_t size) { uint16_t bytes_written = bufferData(_sock, _offset, buffer, size); _offset += bytes_written; + return bytes_written; } -int UDP::parsePacket() +int EthernetUDP::parsePacket() { if (available() > 0) { @@ -142,7 +137,7 @@ int UDP::parsePacket() return 0; } -int UDP::read() +int EthernetUDP::read() { uint8_t byte; if (recv(_sock, &byte, 1) > 0) @@ -154,7 +149,7 @@ int UDP::read() return -1; } -int UDP::read(unsigned char* buffer, size_t len) +int EthernetUDP::read(unsigned char* buffer, size_t len) { /* In the readPacket that copes with truncating packets, the buffer was filled with this code. Not sure why it loops round reading out a byte @@ -168,7 +163,7 @@ int UDP::read(unsigned char* buffer, size_t len) return recv(_sock, buffer, len); } -int UDP::peek() +int EthernetUDP::peek() { uint8_t b; // Unlike recv, peek doesn't check to see if there's any data available, so we must @@ -178,7 +173,7 @@ int UDP::peek() return b; } -void UDP::flush() +void EthernetUDP::flush() { while (available()) { diff --git a/libraries/Ethernet/Udp.h b/libraries/Ethernet/EthernetUdp.h index 99df53f..9a2b653 100644 --- a/libraries/Ethernet/Udp.h +++ b/libraries/Ethernet/EthernetUdp.h @@ -34,15 +34,14 @@ * bjoern@cs.stanford.edu 12/30/2008 */ -#ifndef udp_h -#define udp_h +#ifndef ethernetudp_h +#define ethernetudp_h -#include <Stream.h> -#include <IPAddress.h> +#include <Udp.h> #define UDP_TX_PACKET_MAX_SIZE 24 -class UDP : public Stream { +class EthernetUDP : public UDP { private: uint8_t _sock; // socket ID for Wiz5100 uint16_t _port; // local port to listen on @@ -51,31 +50,31 @@ private: uint16_t _offset; // offset into the packet being sent public: - UDP(); // Constructor - uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - void stop(); // Finish with the UDP socket + EthernetUDP(); // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket // Sending UDP packets // Start building up a packet to send to the remote host specific in ip and port // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - int beginPacket(IPAddress ip, uint16_t port); + virtual int beginPacket(IPAddress ip, uint16_t port); // Start building up a packet to send to the remote host specific in host and port // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - int beginPacket(const char *host, uint16_t port); + virtual int beginPacket(const char *host, uint16_t port); // Finish off this packet and send it // Returns 1 if the packet was sent successfully, 0 if there was an error - int endPacket(); + virtual int endPacket(); // Write a single byte into the packet - virtual void write(uint8_t); - // Write a string of characters into the packet - virtual void write(const char *str); + virtual size_t write(uint8_t); // Write size bytes from buffer into the packet - virtual void write(const uint8_t *buffer, size_t size); + virtual size_t write(const uint8_t *buffer, size_t size); + + using Print::write; // Start processing the next available incoming packet // Returns the size of the packet in bytes, or 0 if no packets are available - int parsePacket(); + virtual int parsePacket(); // Number of bytes remaining in the current packet virtual int available(); // Read a single byte from the current packet @@ -91,9 +90,9 @@ public: virtual void flush(); // Finish reading the current packet // Return the IP address of the host who sent the current incoming packet - IPAddress remoteIP() { return _remoteIP; }; + virtual IPAddress remoteIP() { return _remoteIP; }; // Return the port of the host who sent the current incoming packet - uint16_t remotePort() { return _remotePort; }; + virtual uint16_t remotePort() { return _remotePort; }; }; #endif diff --git a/libraries/Ethernet/Server.h b/libraries/Ethernet/Server.h deleted file mode 100644 index 6aa5d3a..0000000 --- a/libraries/Ethernet/Server.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef server_h -#define server_h - -#include "Print.h" - -class Client; - -class Server : -public Print { -private: - uint16_t _port; - void accept(); -public: - Server(uint16_t); - Client available(); - void begin(); - virtual void write(uint8_t); - virtual void write(const char *str); - virtual void write(const uint8_t *buf, size_t size); -}; - -#endif diff --git a/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.pde b/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino index 3f43d96..bfbcb6d 100644 --- a/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.pde +++ b/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino @@ -39,7 +39,7 @@ IPAddress subnet(255, 255, 255, 0); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): -Server server(80); +EthernetServer server(80); //Sensor's memory register addresses: @@ -96,7 +96,7 @@ void loop() { } // listen for incoming Ethernet connections: - listenForClients(); + listenForEthernetClients(); } @@ -124,9 +124,9 @@ void getData() { Serial.println(" Pa"); } -void listenForClients() { +void listenForEthernetClients() { // listen for incoming clients - Client client = server.available(); + EthernetClient client = server.available(); if (client) { Serial.println("Got a client"); // an http request ends with a blank line diff --git a/libraries/Ethernet/examples/ChatServer/ChatServer.pde b/libraries/Ethernet/examples/ChatServer/ChatServer.ino index 8267a5d..9f819fd 100644 --- a/libraries/Ethernet/examples/ChatServer/ChatServer.pde +++ b/libraries/Ethernet/examples/ChatServer/ChatServer.ino @@ -29,7 +29,7 @@ IPAddress gateway(192,168,1, 1); IPAddress subnet(255, 255, 0, 0); // telnet defaults to port 23 -Server server(23); +EthernetServer server(23); boolean gotAMessage = false; // whether or not you got a message from the client yet void setup() { @@ -43,7 +43,7 @@ void setup() { void loop() { // wait for a new client: - Client client = server.available(); + EthernetClient client = server.available(); // when the client sends the first byte, say hello: if (client) { diff --git a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.pde b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino index 50a557d..630dd17 100644 --- a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.pde +++ b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino @@ -24,7 +24,7 @@ byte mac[] = { // Initialize the Ethernet client library // with the IP address and port of the server // that you want to connect to (port 80 is default for HTTP): -Client client; +EthernetClient client; void setup() { // start the serial library: diff --git a/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino new file mode 100644 index 0000000..5082054 --- /dev/null +++ b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino @@ -0,0 +1,80 @@ +/* + DHCP Chat Server + + A simple server that distributes any incoming messages to all + connected clients. To use telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + THis version attempts to get an IP address using DHCP + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 21 May 2011 + by Tom Igoe + Based on ChatServer example by David A. Mellis + + */ + +#include <SPI.h> +#include <Ethernet.h> + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network. +// gateway and subnet are optional: +byte mac[] = { + 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; +IPAddress ip(192,168,1, 177); +IPAddress gateway(192,168,1, 1); +IPAddress subnet(255, 255, 0, 0); + +// telnet defaults to port 23 +EthernetServer server(23); +boolean gotAMessage = false; // whether or not you got a message from the client yet + +void setup() { + // open the serial port + Serial.begin(9600); + // start the Ethernet connection: + Serial.println("Trying to get an IP address using DHCP"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // initialize the ethernet device not using DHCP: + Ethernet.begin(mac, ip, gateway, subnet); + } + // print your local IP address: + Serial.print("My IP address: "); + ip = Ethernet.localIP(); + for (byte thisByte = 0; thisByte < 4; thisByte++) { + // print the value of each byte of the IP address: + Serial.print(ip[thisByte], DEC); + Serial.print("."); + } + Serial.println(); + // start listening for clients + server.begin(); + +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!gotAMessage) { + Serial.println("We have a new client"); + client.println("Hello, client!"); + gotAMessage = true; + } + + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.print(thisChar); + } +} + diff --git a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.pde b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino index 7bec73a..5c7a53a 100644 --- a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.pde +++ b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino @@ -25,7 +25,7 @@ char serverName[] = "www.google.com"; // Initialize the Ethernet client library // with the IP address and port of the server // that you want to connect to (port 80 is default for HTTP): -Client client; +EthernetClient client; void setup() { // start the serial library: diff --git a/libraries/Ethernet/examples/PachubeClient/PachubeClient.pde b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino index af9bf1f..a169443 100644 --- a/libraries/Ethernet/examples/PachubeClient/PachubeClient.pde +++ b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino @@ -11,7 +11,7 @@ * Ethernet shield attached to pins 10, 11, 12, 13 created 15 March 2010 - updated 4 Sep 2010 + updated 26 Oct 2011 by Tom Igoe http://www.tigoe.net/pcomp/code/category/arduinowiring/873 @@ -28,8 +28,11 @@ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; +// fill in an available IP address on your network here, +// for manual configuration: +IPAddress ip(10,0,1,20); // initialize the library instance: -Client client; +EthernetClient client; long lastConnectionTime = 0; // last time you connected to the server, in milliseconds boolean lastConnected = false; // state of the connection last time through the main loop @@ -47,6 +50,12 @@ void setup() { } // give the ethernet module time to boot up: delay(1000); + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Configure manually: + Ethernet.begin(mac, ip); + } } void loop() { diff --git a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.pde b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino index e6dbf09..4a03100 100644 --- a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.pde +++ b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino @@ -14,7 +14,7 @@ * Ethernet shield attached to pins 10, 11, 12, 13 created 15 March 2010 - updated 4 Sep 2010 + updated 26 Oct 2011 by Tom Igoe This code is in the public domain. @@ -28,25 +28,28 @@ // fill in your address here: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; +// fill in an available IP address on your network here, +// for manual configuration: +IPAddress ip(10,0,1,20); // initialize the library instance: -Client client; +EthernetClient client; long lastConnectionTime = 0; // last time you connected to the server, in milliseconds boolean lastConnected = false; // state of the connection last time through the main loop const int postingInterval = 10000; //delay between updates to Pachube.com void setup() { - // start the ethernet connection and serial port: + // start serial port: Serial.begin(9600); + // give the ethernet module time to boot up: + delay(1000); + // start the Ethernet connection: if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); - // no point in carrying on, so do nothing forevermore: - for(;;) - ; + // Configure manually: + Ethernet.begin(mac, ip); } - // give the ethernet module time to boot up: - delay(1000); } void loop() { diff --git a/libraries/Ethernet/examples/TelnetClient/TelnetClient.pde b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino index 7502d21..5cf1ad8 100644 --- a/libraries/Ethernet/examples/TelnetClient/TelnetClient.pde +++ b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino @@ -33,7 +33,7 @@ IPAddress server(1,1,1,1); // with the IP address and port of the server // that you want to connect to (port 23 is default for telnet; // if you're using Processing's ChatServer, use port 10002): -Client client; +EthernetClient client; void setup() { // start the Ethernet connection: diff --git a/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino new file mode 100644 index 0000000..f113e17 --- /dev/null +++ b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino @@ -0,0 +1,124 @@ +/* + Twitter Client with Strings + + This sketch connects to Twitter using an Ethernet shield. It parses the XML + returned, and looks for <text>this is a tweet</text> + + You can use the Arduino Ethernet shield, or the Adafruit Ethernet shield, + either one will work, as long as it's got a Wiznet Ethernet module on board. + + This example uses the DHCP routines in the Ethernet library which is part of the + Arduino core from version 1.0 beta 1 + + This example uses the String library, which is part of the Arduino core from + version 0019. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 21 May 2011 + by Tom Igoe + + This code is in the public domain. + + */ +#include <SPI.h> +#include <Ethernet.h> + + +// Enter a MAC address and IP address for your controller below. +// The IP address will be dependent on your local network: +byte mac[] = { + 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 }; +IPAddress ip(192,168,1,20); + +// initialize the library instance: +EthernetClient client; + +const int requestInterval = 60000; // delay between requests + +char serverName[] = "api.twitter.com"; // twitter URL + +boolean requested; // whether you've made a request since connecting +long lastAttemptTime = 0; // last time you connected to the server, in milliseconds + +String currentLine = ""; // string to hold the text from server +String tweet = ""; // string to hold the tweet +boolean readingTweet = false; // if you're currently reading the tweet + +void setup() { + // reserve space for the strings: + currentLine.reserve(256); + tweet.reserve(150); + +// initialize serial: + Serial.begin(9600); + // attempt a DHCP connection: + if (!Ethernet.begin(mac)) { + // if DHCP fails, start with a hard-coded address: + Ethernet.begin(mac, ip); + } + // connect to Twitter: + connectToServer(); +} + + + +void loop() +{ + if (client.connected()) { + if (client.available()) { + // read incoming bytes: + char inChar = client.read(); + + // add incoming byte to end of line: + currentLine += inChar; + + // if you get a newline, clear the line: + if (inChar == '\n') { + currentLine = ""; + } + // if the current line ends with <text>, it will + // be followed by the tweet: + if ( currentLine.endsWith("<text>")) { + // tweet is beginning. Clear the tweet string: + readingTweet = true; + tweet = ""; + } + // if you're currently reading the bytes of a tweet, + // add them to the tweet String: + if (readingTweet) { + if (inChar != '<') { + tweet += inChar; + } + else { + // if you got a "<" character, + // you've reached the end of the tweet: + readingTweet = false; + Serial.println(tweet); + // close the connection to the server: + client.stop(); + } + } + } + } + else if (millis() - lastAttemptTime > requestInterval) { + // if you're not connected, and two minutes have passed since + // your last connection, then attempt to connect again: + connectToServer(); + } +} + +void connectToServer() { + // attempt to connect, and wait a millisecond: + Serial.println("connecting to server..."); + if (client.connect(serverName, 80)) { + Serial.println("making HTTP request..."); + // make HTTP GET request to twitter: + client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino&count=1 HTTP/1.1"); + client.println("HOST: api.twitter.com"); + client.println(); + } + // note the time of this connect attempt: + lastAttemptTime = millis(); +} diff --git a/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino index 081d691..4d4045c 100644 --- a/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde +++ b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino @@ -15,7 +15,7 @@ #include <SPI.h> // needed for Arduino versions later than 0018 #include <Ethernet.h> -#include <Udp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008 +#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008 // Enter a MAC address and IP address for your controller below. @@ -30,8 +30,8 @@ unsigned int localPort = 8888; // local port to listen on char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, char ReplyBuffer[] = "acknowledged"; // a string to send back -// A UDP instance to let us send and receive packets over UDP -UDP Udp; +// An EthernetUDP instance to let us send and receive packets over UDP +EthernetUDP Udp; void setup() { // start the Ethernet and UDP: diff --git a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino index 7c2d3ea..b4e24b8 100644 --- a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde +++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino @@ -18,7 +18,7 @@ #include <SPI.h> #include <Ethernet.h> -#include <Udp.h> +#include <EthernetUdp.h> // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield @@ -34,7 +34,7 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets // A UDP instance to let us send and receive packets over UDP -UDP Udp; +EthernetUDP Udp; void setup() { diff --git a/libraries/Ethernet/examples/WebClient/WebClient.pde b/libraries/Ethernet/examples/WebClient/WebClient.ino index 646c3aa..1806854 100644 --- a/libraries/Ethernet/examples/WebClient/WebClient.pde +++ b/libraries/Ethernet/examples/WebClient/WebClient.ino @@ -23,7 +23,7 @@ IPAddress server(173,194,33,104); // Google // Initialize the Ethernet client library // with the IP address and port of the server // that you want to connect to (port 80 is default for HTTP): -Client client; +EthernetClient client; void setup() { // start the serial library: diff --git a/libraries/Ethernet/examples/WebServer/WebServer.pde b/libraries/Ethernet/examples/WebServer/WebServer.ino index c69a56a..6837f83 100644 --- a/libraries/Ethernet/examples/WebServer/WebServer.pde +++ b/libraries/Ethernet/examples/WebServer/WebServer.ino @@ -1,5 +1,5 @@ /* - Web Server + Web Server A simple web server that shows the value of the analog input pins. using an Arduino Wiznet Ethernet shield. @@ -26,7 +26,7 @@ IPAddress ip(192,168,1, 177); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): -Server server(80); +EthernetServer server(80); void setup() { @@ -38,7 +38,7 @@ void setup() void loop() { // listen for incoming clients - Client client = server.available(); + EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; diff --git a/libraries/Ethernet/keywords.txt b/libraries/Ethernet/keywords.txt index 7fdcedf..6b37cbe 100644 --- a/libraries/Ethernet/keywords.txt +++ b/libraries/Ethernet/keywords.txt @@ -7,8 +7,8 @@ ####################################### Ethernet KEYWORD1 -Client KEYWORD1 -Server KEYWORD1 +EthernetClient KEYWORD1 +EthernetServer KEYWORD1 IPAddress KEYWORD1 ####################################### diff --git a/libraries/Ethernet/util.h b/libraries/Ethernet/util.h index 220011b..5042e82 100644 --- a/libraries/Ethernet/util.h +++ b/libraries/Ethernet/util.h @@ -1,7 +1,7 @@ #ifndef UTIL_H #define UTIL_H -#define htons(x) ( (x)<<8 | ((x)>>8)&0xFF ) +#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) #define ntohs(x) htons(x) #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ diff --git a/libraries/Ethernet/utility/socket.cpp b/libraries/Ethernet/utility/socket.cpp index 4875845..fd3e442 100644 --- a/libraries/Ethernet/utility/socket.cpp +++ b/libraries/Ethernet/utility/socket.cpp @@ -9,7 +9,6 @@ static uint16_t local_port; */ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag) { - uint8_t ret; if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE)) { close(s); @@ -144,15 +143,15 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len) * * @return received data size for success else -1. */ -uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len) +int16_t recv(SOCKET s, uint8_t *buf, int16_t len) { // Check how much data is available - uint16_t ret = W5100.getRXReceivedSize(s); + int16_t ret = W5100.getRXReceivedSize(s); if ( ret == 0 ) { // No data available. uint8_t status = W5100.readSnSR(s); - if ( s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::CLOSE_WAIT ) + if ( status == SnSR::LISTEN || status == SnSR::CLOSED || status == SnSR::CLOSE_WAIT ) { // The remote end has closed its side of the connection, so this is the eof state ret = 0; diff --git a/libraries/Ethernet/utility/socket.h b/libraries/Ethernet/utility/socket.h index 37ea93f..45e0fb3 100755 --- a/libraries/Ethernet/utility/socket.h +++ b/libraries/Ethernet/utility/socket.h @@ -9,7 +9,7 @@ extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TC extern void disconnect(SOCKET s); // disconnect the connection extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection) extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP) -extern uint16_t recv(SOCKET s, uint8_t * buf, uint16_t len); // Receive data (TCP) +extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP) extern uint16_t peek(SOCKET s, uint8_t *buf); extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW) extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW) diff --git a/libraries/Ethernet/utility/w5100.cpp b/libraries/Ethernet/utility/w5100.cpp index aafabae..9c748fd 100644 --- a/libraries/Ethernet/utility/w5100.cpp +++ b/libraries/Ethernet/utility/w5100.cpp @@ -140,7 +140,7 @@ uint8_t W5100Class::write(uint16_t _addr, uint8_t _data) uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) { - for (int i=0; i<_len; i++) + for (uint16_t i=0; i<_len; i++) { setSS(); SPI.transfer(0xF0); @@ -166,7 +166,7 @@ uint8_t W5100Class::read(uint16_t _addr) uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) { - for (int i=0; i<_len; i++) + for (uint16_t i=0; i<_len; i++) { setSS(); SPI.transfer(0x0F); diff --git a/libraries/Ethernet/utility/w5100.h b/libraries/Ethernet/utility/w5100.h index 9872c7c..153aedb 100755 --- a/libraries/Ethernet/utility/w5100.h +++ b/libraries/Ethernet/utility/w5100.h @@ -270,7 +270,10 @@ private: } \ static uint16_t read##name(SOCKET _s) { \ uint16_t res = readSn(_s, address); \ - res = (res << 8) + readSn(_s, address + 1); \ + uint16_t res2 = readSn(_s,address + 1); \ + res = res << 8; \ + res2 = res2 & 0xFF; \ + res = res | res2; \ return res; \ } #define __SOCKET_REGISTER_N(name, address, size) \ @@ -324,6 +327,10 @@ private: inline static void initSS() { DDRB |= _BV(4); }; inline static void setSS() { PORTB &= ~_BV(4); }; inline static void resetSS() { PORTB |= _BV(4); }; +#elif defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__) + inline static void initSS() { DDRB |= _BV(0); }; + inline static void setSS() { PORTB &= ~_BV(0); }; + inline static void resetSS() { PORTB |= _BV(0); }; #else inline static void initSS() { DDRB |= _BV(2); }; inline static void setSS() { PORTB &= ~_BV(2); }; diff --git a/libraries/Firmata/Boards.h b/libraries/Firmata/Boards.h index f716320..06f69c6 100644 --- a/libraries/Firmata/Boards.h +++ b/libraries/Firmata/Boards.h @@ -3,7 +3,13 @@ #ifndef Firmata_Boards_h #define Firmata_Boards_h -#include <Arduino.h> // for digitalRead, digitalWrite, etc +#include <inttypes.h> + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" // for digitalRead, digitalWrite, etc +#else +#include "WProgram.h" +#endif // Normally Servo.h must be included before Firmata.h (which then includes // this file). If Servo.h wasn't included, this allows the code to still @@ -118,35 +124,58 @@ writePort(port, value, bitmask): Write an 8 bit port. * Board Specific Configuration *============================================================================*/ +#ifndef digitalPinHasPWM +#define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) +#endif + // Arduino Duemilanove, Diecimila, and NG #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) +#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 +#define TOTAL_ANALOG_PINS 6 +#define TOTAL_PINS 20 // 14 digital + 6 analog +#else #define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 24 // 14 digital + 2 unused + 8 analog +#define TOTAL_PINS 22 // 14 digital + 8 analog +#endif #define VERSION_BLINK_PIN 13 -#define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 16 && (p) <= 21)) -#define IS_PIN_ANALOG(p) ((p) >= 16 && (p) <= 23) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) -#define IS_PIN_SERVO(p) ((p) >= 2 && (p) <= 13 && (p) - 2 < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) -#define PIN_TO_DIGITAL(p) (((p) < 16) ? (p) : (p) - 2) -#define PIN_TO_ANALOG(p) ((p) - 16) +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) #define ARDUINO_PINOUT_OPTIMIZE 1 +// Wiring (and board) +#elif defined(WIRING) +#define VERSION_BLINK_PIN WLED +#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) +#define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS)) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN) +#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) +#define PIN_TO_SERVO(p) (p) + + // old Arduinos #elif defined(__AVR_ATmega8__) #define TOTAL_ANALOG_PINS 6 -#define TOTAL_PINS 22 // 14 digital + 2 unused + 6 analog +#define TOTAL_PINS 20 // 14 digital + 6 analog #define VERSION_BLINK_PIN 13 -#define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 16 && (p) <= 21)) -#define IS_PIN_ANALOG(p) ((p) >= 16 && (p) <= 21) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) -#define IS_PIN_SERVO(p) ((p) >= 2 && (p) <= 13 && (p) - 2 < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) -#define PIN_TO_DIGITAL(p) (((p) < 16) ? (p) : (p) - 2) -#define PIN_TO_ANALOG(p) ((p) - 16) +#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) +#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) +#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) +#define PIN_TO_DIGITAL(p) (p) +#define PIN_TO_ANALOG(p) ((p) - 14) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) #define ARDUINO_PINOUT_OPTIMIZE 1 @@ -159,23 +188,15 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) +#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) ((p) - 54) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) #define PIN_TO_SERVO(p) ((p) - 2) -// Wiring -#elif defined(__AVR_ATmega128__) -#define TOTAL_ANALOG_PINS 8 -#define TOTAL_PINS 51 -#define VERSION_BLINK_PIN 48 -// TODO: hardware abstraction for wiring board - - // Teensy 1.0 #elif defined(__AVR_AT90USB162__) #define TOTAL_ANALOG_PINS 0 @@ -183,7 +204,7 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 6 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) (0) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) #define IS_PIN_I2C(p) (0) #define PIN_TO_DIGITAL(p) (p) @@ -199,9 +220,9 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 11 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) +#define IS_PIN_I2C(p) ((p) == 5 || (p) == 6) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) @@ -215,9 +236,9 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 6 #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) +#define IS_PIN_I2C(p) ((p) == 0 || (p) == 1) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) ((p) - 38) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) @@ -231,9 +252,9 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 0 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) +#define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) ((p) - 24) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) @@ -247,9 +268,9 @@ writePort(port, value, bitmask): Write an 8 bit port. #define VERSION_BLINK_PIN 13 #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS) -#define IS_PIN_PWM(p) IS_PIN_DIGITAL(p) +#define IS_PIN_PWM(p) digitalPinHasPWM(p) #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) -#define IS_PIN_I2C(p) (0) +#define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) ((p) - 36) #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) @@ -270,9 +291,9 @@ static inline unsigned char readPort(byte, byte) __attribute__((always_inline, u static inline unsigned char readPort(byte port, byte bitmask) { #if defined(ARDUINO_PINOUT_OPTIMIZE) - if (port == 0) return PIND & B11111100 & bitmask; // ignore Rx/Tx 0/1 - if (port == 1) return PINB & B00111111 & bitmask; // pins 8-13 (14,15 are disabled for the crystal) - if (port == 2) return PINC & bitmask; + if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1 + if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask; + if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask; return 0; #else unsigned char out=0, pin=port*8; @@ -297,17 +318,27 @@ static inline unsigned char writePort(byte port, byte value, byte bitmask) { #if defined(ARDUINO_PINOUT_OPTIMIZE) if (port == 0) { - bitmask = bitmask & 0xFC; // Tx & Rx pins + bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins + byte valD = value & bitmask; + byte maskD = ~bitmask; cli(); - PORTD = (PORTD & ~bitmask) | (bitmask & value); + PORTD = (PORTD & maskD) | valD; sei(); } else if (port == 1) { + byte valB = (value & bitmask) & 0x3F; + byte valC = (value & bitmask) >> 6; + byte maskB = ~(bitmask & 0x3F); + byte maskC = ~((bitmask & 0xC0) >> 6); cli(); - PORTB = (PORTB & ~bitmask) | (bitmask & value); + PORTB = (PORTB & maskB) | valB; + PORTC = (PORTC & maskC) | valC; sei(); } else if (port == 2) { + bitmask = bitmask & 0x0F; + byte valC = (value & bitmask) << 2; + byte maskC = ~(bitmask << 2); cli(); - PORTC = (PORTC & ~bitmask) | (bitmask & value); + PORTC = (PORTC & maskC) | valC; sei(); } #else diff --git a/libraries/Firmata/Firmata.cpp b/libraries/Firmata/Firmata.cpp index e30deae..e81c10b 100644 --- a/libraries/Firmata/Firmata.cpp +++ b/libraries/Firmata/Firmata.cpp @@ -14,9 +14,8 @@ //* Includes //****************************************************************************** -#include "Arduino.h" -#include "HardwareSerial.h" #include "Firmata.h" +#include "HardwareSerial.h" extern "C" { #include <string.h> @@ -27,27 +26,27 @@ extern "C" { //* Support Functions //****************************************************************************** -void sendValueAsTwo7bitBytes(int value) +void FirmataClass::sendValueAsTwo7bitBytes(int value) { - Serial.print(value & B01111111, BYTE); // LSB - Serial.print(value >> 7 & B01111111, BYTE); // MSB + FirmataSerial.write(value & B01111111); // LSB + FirmataSerial.write(value >> 7 & B01111111); // MSB } -void startSysex(void) +void FirmataClass::startSysex(void) { - Serial.print(START_SYSEX, BYTE); + FirmataSerial.write(START_SYSEX); } -void endSysex(void) +void FirmataClass::endSysex(void) { - Serial.print(END_SYSEX, BYTE); + FirmataSerial.write(END_SYSEX); } //****************************************************************************** //* Constructors //****************************************************************************** -FirmataClass::FirmataClass(void) +FirmataClass::FirmataClass(Stream &s) : FirmataSerial(s) { firmwareVersionCount = 0; systemReset(); @@ -66,33 +65,36 @@ void FirmataClass::begin(void) /* begin method for overriding default serial bitrate */ void FirmataClass::begin(long speed) { -#if defined(__AVR_ATmega128__) // Wiring - Serial.begin((uint32_t)speed); -#else Serial.begin(speed); -#endif + FirmataSerial = Serial; blinkVersion(); - delay(300); + printVersion(); + printFirmwareVersion(); +} + +void FirmataClass::begin(Stream &s) +{ + FirmataSerial = s; + systemReset(); printVersion(); printFirmwareVersion(); } // output the protocol version message to the serial port void FirmataClass::printVersion(void) { - Serial.print(REPORT_VERSION, BYTE); - Serial.print(FIRMATA_MAJOR_VERSION, BYTE); - Serial.print(FIRMATA_MINOR_VERSION, BYTE); + FirmataSerial.write(REPORT_VERSION); + FirmataSerial.write(FIRMATA_MAJOR_VERSION); + FirmataSerial.write(FIRMATA_MINOR_VERSION); } void FirmataClass::blinkVersion(void) { // flash the pin with the protocol version pinMode(VERSION_BLINK_PIN,OUTPUT); - pin13strobe(FIRMATA_MAJOR_VERSION, 200, 400); - delay(300); - pin13strobe(2,1,4); // separator, a quick burst - delay(300); - pin13strobe(FIRMATA_MINOR_VERSION, 200, 400); + pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210); + delay(250); + pin13strobe(FIRMATA_MINOR_VERSION, 40, 210); + delay(125); } void FirmataClass::printFirmwareVersion(void) @@ -101,9 +103,9 @@ void FirmataClass::printFirmwareVersion(void) if(firmwareVersionCount) { // make sure that the name has been set before reporting startSysex(); - Serial.print(REPORT_FIRMWARE, BYTE); - Serial.print(firmwareVersionVector[0]); // major version number - Serial.print(firmwareVersionVector[1]); // minor version number + FirmataSerial.write(REPORT_FIRMWARE); + FirmataSerial.write(firmwareVersionVector[0]); // major version number + FirmataSerial.write(firmwareVersionVector[1]); // minor version number for(i=2; i<firmwareVersionCount; ++i) { sendValueAsTwo7bitBytes(firmwareVersionVector[i]); } @@ -141,7 +143,7 @@ void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte int FirmataClass::available(void) { - return Serial.available(); + return FirmataSerial.available(); } @@ -175,7 +177,7 @@ void FirmataClass::processSysexMessage(void) void FirmataClass::processInput(void) { - int inputData = Serial.read(); // this is 'int' to handle -1 when no data + int inputData = FirmataSerial.read(); // this is 'int' to handle -1 when no data int command; // TODO make sure it handles -1 properly @@ -267,7 +269,7 @@ void FirmataClass::processInput(void) void FirmataClass::sendAnalog(byte pin, int value) { // pin can only be 0-15, so chop higher bits - Serial.print(ANALOG_MESSAGE | (pin & 0xF), BYTE); + FirmataSerial.write(ANALOG_MESSAGE | (pin & 0xF)); sendValueAsTwo7bitBytes(value); } @@ -298,9 +300,9 @@ void FirmataClass::sendDigital(byte pin, int value) // send an 8-bit port in a single digital message (protocol v2) void FirmataClass::sendDigitalPort(byte portNumber, int portData) { - Serial.print(DIGITAL_MESSAGE | (portNumber & 0xF),BYTE); - Serial.print((byte)portData % 128, BYTE); // Tx bits 0-6 - Serial.print(portData >> 7, BYTE); // Tx bits 7-13 + FirmataSerial.write(DIGITAL_MESSAGE | (portNumber & 0xF)); + FirmataSerial.write((byte)portData % 128); // Tx bits 0-6 + FirmataSerial.write(portData >> 7); // Tx bits 7-13 } @@ -308,7 +310,7 @@ void FirmataClass::sendSysex(byte command, byte bytec, byte* bytev) { byte i; startSysex(); - Serial.print(command, BYTE); + FirmataSerial.write(command); for(i=0; i<bytec; i++) { sendValueAsTwo7bitBytes(bytev[i]); } @@ -437,6 +439,6 @@ void FirmataClass::pin13strobe(int count, int onInterval, int offInterval) // make one instance for the user to use -FirmataClass Firmata; +FirmataClass Firmata(Serial); diff --git a/libraries/Firmata/Firmata.h b/libraries/Firmata/Firmata.h index 86535d9..74f1ccc 100644 --- a/libraries/Firmata/Firmata.h +++ b/libraries/Firmata/Firmata.h @@ -13,16 +13,15 @@ #ifndef Firmata_h #define Firmata_h -#include <Arduino.h> -#include <inttypes.h> - +#include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */ /* Version numbers for the protocol. The protocol is still changing, so these * version numbers are important. This number can be queried so that host * software can test whether it will be compatible with the currently * installed firmware. */ #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes -#define FIRMATA_MINOR_VERSION 2 // for backwards compatible changes +#define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes +#define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases #define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages @@ -66,8 +65,8 @@ #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL // pin modes -//#define INPUT 0x00 // defined in Arduino.h -//#define OUTPUT 0x01 // defined in Arduino.h +//#define INPUT 0x00 // defined in wiring.h +//#define OUTPUT 0x01 // defined in wiring.h #define ANALOG 0x02 // analog pin in analogInput mode #define PWM 0x03 // digital pin in PWM output mode #define SERVO 0x04 // digital pin in Servo output mode @@ -88,10 +87,11 @@ extern "C" { class FirmataClass { public: - FirmataClass(); + FirmataClass(Stream &s); /* Arduino constructors */ void begin(); void begin(long); + void begin(Stream &s); /* querying functions */ void printVersion(void); void blinkVersion(void); @@ -116,6 +116,7 @@ public: void detach(byte command); private: + Stream &FirmataSerial; /* firmware name and version */ byte firmwareVersionCount; byte *firmwareVersionVector; @@ -141,6 +142,9 @@ private: void processSysexMessage(void); void systemReset(void); void pin13strobe(int count, int onInterval, int offInterval); + void sendValueAsTwo7bitBytes(int value); + void startSysex(void); + void endSysex(void); }; extern FirmataClass Firmata; @@ -155,8 +159,5 @@ extern FirmataClass Firmata; */ #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y) -/* Hardware Abstraction Layer */ -#include "Boards.h" - #endif /* Firmata_h */ diff --git a/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.pde b/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino index 5bca72a..bff7366 100644 --- a/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.pde +++ b/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* * This firmware reads all inputs and sends them as fast as it can. It was * inspired by the ease-of-use of the Arduino2Max program. @@ -56,7 +67,7 @@ void loop() byte i; for (i=0; i<TOTAL_PORTS; i++) { - sendPort(i, readPort(i)); + sendPort(i, readPort(i, 0xff)); } /* make sure that the FTDI buffer doesn't go over 60 bytes, otherwise you get long, random delays. So only read analogs every 20ms or so */ diff --git a/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino index df8b674..ff1d664 100644 --- a/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.pde +++ b/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This firmware supports as many analog ports as possible, all analog inputs, * four PWM outputs, and two with servo support. * diff --git a/libraries/Firmata/examples/AnalogFirmata/Makefile b/libraries/Firmata/examples/AnalogFirmata/Makefile deleted file mode 100644 index e968c0a..0000000 --- a/libraries/Firmata/examples/AnalogFirmata/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -CC = avr-gcc -CXX = avr-g++ -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - - diff --git a/libraries/Firmata/examples/EchoString/EchoString.pde b/libraries/Firmata/examples/EchoString/EchoString.ino index e5c4e6f..5079697 100644 --- a/libraries/Firmata/examples/EchoString/EchoString.pde +++ b/libraries/Firmata/examples/EchoString/EchoString.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This sketch accepts strings and raw sysex messages and echos them back. * * This example code is in the public domain. @@ -14,12 +25,7 @@ void stringCallback(char *myString) void sysexCallback(byte command, byte argc, byte*argv) { - Serial.write(START_SYSEX); - Serial.write(command); - for(byte i=0; i<argc; i++) { - Serial.write(argv[i]); - } - Serial.write(END_SYSEX); + Firmata.sendSysex(command, argc, argv); } void setup() diff --git a/libraries/Firmata/examples/EchoString/Makefile b/libraries/Firmata/examples/EchoString/Makefile deleted file mode 100644 index e968c0a..0000000 --- a/libraries/Firmata/examples/EchoString/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -CC = avr-gcc -CXX = avr-g++ -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - - diff --git a/libraries/Firmata/examples/I2CFirmata/I2CFirmata.pde b/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino index 11202e9..1da8963 100644 --- a/libraries/Firmata/examples/I2CFirmata/I2CFirmata.pde +++ b/libraries/Firmata/examples/I2CFirmata/I2CFirmata.ino @@ -1,4 +1,15 @@ /* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + +/* Copyright (C) 2009 Jeff Hoefs. All rights reserved. Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. @@ -48,7 +59,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes) { if (theRegister != REGISTER_NOT_SPECIFIED) { Wire.beginTransmission(address); - Wire.send((byte)theRegister); + Wire.write((byte)theRegister); Wire.endTransmission(); delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck } @@ -63,7 +74,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes) i2cRxData[0] = address; i2cRxData[1] = theRegister; for (int i = 0; i < numBytes; i++) { - i2cRxData[2 + i] = Wire.receive(); + i2cRxData[2 + i] = Wire.read(); } // send slave address, register and received bytes Firmata.sendSysex(I2C_REPLY, numBytes + 2, i2cRxData); @@ -95,7 +106,7 @@ void sysexCallback(byte command, byte argc, byte *argv) Wire.beginTransmission(slaveAddress); for (byte i = 2; i < argc; i += 2) { data = argv[i] + (argv[i + 1] << 7); - Wire.send(data); + Wire.write(data); } Wire.endTransmission(); delayMicroseconds(70); // TODO is this needed? diff --git a/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.pde b/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino index 56a47ac..d306c70 100644 --- a/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.pde +++ b/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino @@ -1,4 +1,15 @@ /* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + +/* Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. This library is free software; you can redistribute it and/or diff --git a/libraries/Firmata/examples/ServoFirmata/Makefile b/libraries/Firmata/examples/ServoFirmata/Makefile deleted file mode 100644 index e968c0a..0000000 --- a/libraries/Firmata/examples/ServoFirmata/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -CC = avr-gcc -CXX = avr-g++ -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - - diff --git a/libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino index 6f78ccd..cdcfff0 100644 --- a/libraries/Firmata/examples/ServoFirmata/ServoFirmata.pde +++ b/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* This firmware supports as many servos as possible using the Servo library * included in Arduino 0017 * diff --git a/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile b/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile deleted file mode 100644 index e968c0a..0000000 --- a/libraries/Firmata/examples/SimpleAnalogFirmata/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -CC = avr-gcc -CXX = avr-g++ -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - - diff --git a/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino index b505b33..44ea91e 100644 --- a/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.pde +++ b/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Supports as many analog inputs and analog PWM outputs as possible. * * This example code is in the public domain. diff --git a/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile b/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile deleted file mode 100644 index e968c0a..0000000 --- a/libraries/Firmata/examples/SimpleDigitalFirmata/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -CC = avr-gcc -CXX = avr-g++ -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - - diff --git a/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino index 64b566e..a0d764f 100644 --- a/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.pde +++ b/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino @@ -1,3 +1,14 @@ +/* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + /* Supports as many digital inputs and outputs as possible. * * This example code is in the public domain. @@ -52,7 +63,7 @@ void loop() byte i; for (i=0; i<TOTAL_PORTS; i++) { - outputPort(i, readPort(i)); + outputPort(i, readPort(i, 0xff)); } while(Firmata.available()) { diff --git a/libraries/Firmata/examples/StandardFirmata/Makefile b/libraries/Firmata/examples/StandardFirmata/Makefile deleted file mode 100644 index 835187a..0000000 --- a/libraries/Firmata/examples/StandardFirmata/Makefile +++ /dev/null @@ -1,273 +0,0 @@ -# Arduino makefile -# -# This makefile allows you to build sketches from the command line -# without the Arduino environment (or Java). -# -# The Arduino environment does preliminary processing on a sketch before -# compiling it. If you're using this makefile instead, you'll need to do -# a few things differently: -# -# - Give your program's file a .cpp extension (e.g. foo.cpp). -# -# - Put this line at top of your code: #include <WProgram.h> -# -# - Write prototypes for all your functions (or define them before you -# call them). A prototype declares the types of parameters a -# function will take and what type of value it will return. This -# means that you can have a call to a function before the definition -# of the function. A function prototype looks like the first line of -# the function, with a semi-colon at the end. For example: -# int digitalRead(int pin); -# -# Instructions for using the makefile: -# -# 1. Copy this file into the folder with your sketch. -# -# 2. Below, modify the line containing "TARGET" to refer to the name of -# of your program's file without an extension (e.g. TARGET = foo). -# -# 3. Modify the line containg "ARDUINO" to point the directory that -# contains the Arduino core (for normal Arduino installations, this -# is the hardware/cores/arduino sub-directory). -# -# 4. Modify the line containing "PORT" to refer to the filename -# representing the USB or serial connection to your Arduino board -# (e.g. PORT = /dev/tty.USB0). If the exact name of this file -# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*). -# -# 5. At the command line, change to the directory containing your -# program's file and the makefile. -# -# 6. Type "make" and press enter to compile/verify your program. -# -# 7. Type "make upload", reset your Arduino board, and press enter to -# upload your program to the Arduino board. -# -# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $ - -PORT = /dev/tty.usbserial-* -TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|') -ARDUINO = /Applications/arduino -ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino -ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries -ARDUINO_TOOLS = $(ARDUINO)/hardware/tools -INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \ - -I$(ARDUINO_LIB_SRC)/EEPROM \ - -I$(ARDUINO_LIB_SRC)/Firmata \ - -I$(ARDUINO_LIB_SRC)/Matrix \ - -I$(ARDUINO_LIB_SRC)/Servo \ - -I$(ARDUINO_LIB_SRC)/Wire \ - -I$(ARDUINO_LIB_SRC) -SRC = $(wildcard $(ARDUINO_SRC)/*.c) -CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \ - $(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \ - $(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \ - $(ARDUINO_LIB_SRC)/Servo/Servo.cpp \ - $(ARDUINO_SRC)/Print.cpp \ - $(ARDUINO_SRC)/WMath.cpp -HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h) - -MCU = atmega168 -#MCU = atmega8 -F_CPU = 16000000 -FORMAT = ihex -UPLOAD_RATE = 19200 - -# Name of this Makefile (used for "make depend"). -MAKEFILE = Makefile - -# Debugging format. -# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. -# AVR (extended) COFF requires stabs, plus an avr-objcopy run. -DEBUG = stabs - -OPT = s - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU) -CXXDEFS = -DF_CPU=$(F_CPU) - -# Compiler flag to set the C Standard level. -# c89 - "ANSI" C -# gnu89 - c89 plus GCC extensions -# c99 - ISO C99 standard (not yet fully implemented) -# gnu99 - c99 plus GCC extensions -CSTANDARD = -std=gnu99 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) - -CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) -CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs -LDFLAGS = - - -# Programming support using avrdude. Settings and variables. -AVRDUDE_PROGRAMMER = stk500 -AVRDUDE_PORT = $(PORT) -AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex -AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \ - -b $(UPLOAD_RATE) -q -V - -# Program settings -ARDUINO_AVR_BIN = $(ARDUINO_TOOLS)/avr/bin -CC = $(ARDUINO_AVR_BIN)/avr-gcc -CXX = $(ARDUINO_AVR_BIN)/avr-g++ -OBJCOPY = $(ARDUINO_AVR_BIN)/avr-objcopy -OBJDUMP = $(ARDUINO_AVR_BIN)/avr-objdump -SIZE = $(ARDUINO_AVR_BIN)/avr-size -NM = $(ARDUINO_AVR_BIN)/avr-nm -#AVRDUDE = $(ARDUINO_AVR_BIN)/avrdude -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Define all object files. -OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) - -# Define all listing files. -LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) - - -# Default target. -all: build - -build: applet/$(TARGET).hex - -eep: applet/$(TARGET).eep -lss: applet/$(TARGET).lss -sym: applet/$(TARGET).sym - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -extcoff: applet/$(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof - - -.SUFFIXES: .elf .hex .eep .lss .sym .pde - -.elf.hex: - $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.eep: - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ - -# Create extended listing file from ELF output file. -.elf.lss: - $(OBJDUMP) -h -S $< > $@ - -# Create a symbol table from ELF output file. -.elf.sym: - $(NM) -n $< > $@ - - -# Compile: create object files from C++ source files. -.cpp.o: $(HEADERS) - $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ - -# Compile: create object files from C source files. -.c.o: $(HEADERS) - $(CC) -c $(ALL_CFLAGS) $< -o $@ - - -# Compile: create assembler files from C source files. -.c.s: - $(CC) -S $(ALL_CFLAGS) $< -o $@ - - -# Assemble: create object files from assembler source files. -.S.o: - $(CC) -c $(ALL_ASFLAGS) $< -o $@ - - - -applet/$(TARGET).cpp: $(TARGET).pde - test -d applet || mkdir applet - echo '#include "WProgram.h"' > applet/$(TARGET).cpp - echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp - sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \ - grep -v 'loop()' >> applet/$(TARGET).cpp - cat $(TARGET).pde >> applet/$(TARGET).cpp - cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp - -# Link: create ELF output file from object files. -applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ) - $(CC) $(ALL_CFLAGS) $(OBJ) -lm --output $@ $(LDFLAGS) -# $(CC) $(ALL_CFLAGS) $(OBJ) $(ARDUINO_TOOLS)/avr/avr/lib/avr5/crtm168.o --output $@ $(LDFLAGS) - -pd_close_serial: - echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true - -# Program the device. -upload: applet/$(TARGET).hex - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) - - -pd_test: build pd_close_serial upload - -# Target: clean project. -clean: - $(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \ - applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \ - applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \ - $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) - rmdir -- applet - -depend: - if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ - then \ - sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ - $(MAKEFILE).$$$$ && \ - $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ - fi - echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ - >> $(MAKEFILE); \ - $(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE) - -.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test - -# for emacs -etags: - make etags_`uname -s` - etags *.pde \ - $(ARDUINO_SRC)/*.[ch] \ - $(ARDUINO_SRC)/*.cpp \ - $(ARDUINO_LIB_SRC)/*/*.[ch] \ - $(ARDUINO_LIB_SRC)/*/*.cpp \ - $(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \ - $(ARDUINO)/hardware/tools/avr/avr/include/*.[ch] - -etags_Darwin: -# etags -a - -etags_Linux: -# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h - -etags_MINGW: -# etags -a /usr/include/*.h /usr/include/sys/*.h - - -path: - echo $(PATH) - echo $$PATH - diff --git a/libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino index cd43366..1a987ee 100644 --- a/libraries/Firmata/examples/StandardFirmata/StandardFirmata.pde +++ b/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino @@ -1,5 +1,19 @@ /* + * Firmata is a generic protocol for communicating with microcontrollers + * from software on a host computer. It is intended to work with + * any host computer software package. + * + * To download a host software package, please clink on the following link + * to open the download page in your default browser. + * + * http://firmata.org/wiki/Download + */ + +/* Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. + Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. + Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. + Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,8 +30,22 @@ */ #include <Servo.h> +#include <Wire.h> #include <Firmata.h> +// move the following defines to Firmata.h? +#define I2C_WRITE B00000000 +#define I2C_READ B00001000 +#define I2C_READ_CONTINUOUSLY B00010000 +#define I2C_STOP_READING B00011000 +#define I2C_READ_WRITE_MODE_MASK B00011000 +#define I2C_10BIT_ADDRESS_MODE_MASK B00100000 + +#define MAX_QUERIES 8 +#define MINIMUM_SAMPLING_INTERVAL 10 + +#define REGISTER_NOT_SPECIFIED -1 + /*============================================================================== * GLOBAL VARIABLES *============================================================================*/ @@ -39,12 +67,69 @@ unsigned long currentMillis; // store the current value from millis() unsigned long previousMillis; // for comparison with currentMillis int samplingInterval = 19; // how often to run the main loop (in ms) -Servo servos[MAX_SERVOS]; +/* i2c data */ +struct i2c_device_info { + byte addr; + byte reg; + byte bytes; +}; + +/* for i2c read continuous more */ +i2c_device_info query[MAX_QUERIES]; + +byte i2cRxData[32]; +boolean isI2CEnabled = false; +signed char queryIndex = -1; +unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() +Servo servos[MAX_SERVOS]; /*============================================================================== * FUNCTIONS *============================================================================*/ +void readAndReportData(byte address, int theRegister, byte numBytes) { + // allow I2C requests that don't require a register read + // for example, some devices using an interrupt pin to signify new data available + // do not always require the register read so upon interrupt you call Wire.requestFrom() + if (theRegister != REGISTER_NOT_SPECIFIED) { + Wire.beginTransmission(address); + #if ARDUINO >= 100 + Wire.write((byte)theRegister); + #else + Wire.send((byte)theRegister); + #endif + Wire.endTransmission(); + delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck + } else { + theRegister = 0; // fill the register with a dummy value + } + + Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom + + // check to be sure correct number of bytes were returned by slave + if(numBytes == Wire.available()) { + i2cRxData[0] = address; + i2cRxData[1] = theRegister; + for (int i = 0; i < numBytes; i++) { + #if ARDUINO >= 100 + i2cRxData[2 + i] = Wire.read(); + #else + i2cRxData[2 + i] = Wire.receive(); + #endif + } + } + else { + if(numBytes > Wire.available()) { + Firmata.sendString("I2C Read Error: Too many bytes received"); + } else { + Firmata.sendString("I2C Read Error: Too few bytes received"); + } + } + + // send slave address, register and received bytes + Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData); +} + void outputPort(byte portNumber, byte portValue, byte forceSend) { // pins not configured as INPUT are cleared to zeros @@ -88,6 +173,11 @@ void checkDigitalInputs(void) */ void setPinModeCallback(byte pin, int mode) { + if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) { + // disable i2c so pins can be used for other functions + // the following if statements should reconfigure the pins properly + disableI2CPins(); + } if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { servos[PIN_TO_SERVO(pin)].detach(); } @@ -138,14 +228,15 @@ void setPinModeCallback(byte pin, int mode) pinConfig[pin] = SERVO; if (!servos[PIN_TO_SERVO(pin)].attached()) { servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); - } else { - Firmata.sendString("Servo only on pins from 2 to 13"); } } break; case I2C: - pinConfig[pin] = mode; - Firmata.sendString("I2C mode not yet supported"); + if (IS_PIN_I2C(pin)) { + // mark the pin as i2c + // the user must call I2C_CONFIG to enable I2C for a device + pinConfig[pin] = I2C; + } break; default: Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM @@ -232,7 +323,104 @@ void reportDigitalCallback(byte port, int value) void sysexCallback(byte command, byte argc, byte *argv) { + byte mode; + byte slaveAddress; + byte slaveRegister; + byte data; + unsigned int delayTime; + switch(command) { + case I2C_REQUEST: + mode = argv[1] & I2C_READ_WRITE_MODE_MASK; + if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { + Firmata.sendString("10-bit addressing mode is not yet supported"); + return; + } + else { + slaveAddress = argv[0]; + } + + switch(mode) { + case I2C_WRITE: + Wire.beginTransmission(slaveAddress); + for (byte i = 2; i < argc; i += 2) { + data = argv[i] + (argv[i + 1] << 7); + #if ARDUINO >= 100 + Wire.write(data); + #else + Wire.send(data); + #endif + } + Wire.endTransmission(); + delayMicroseconds(70); + break; + case I2C_READ: + if (argc == 6) { + // a slave register is specified + slaveRegister = argv[2] + (argv[3] << 7); + data = argv[4] + (argv[5] << 7); // bytes to read + readAndReportData(slaveAddress, (int)slaveRegister, data); + } + else { + // a slave register is NOT specified + data = argv[2] + (argv[3] << 7); // bytes to read + readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data); + } + break; + case I2C_READ_CONTINUOUSLY: + if ((queryIndex + 1) >= MAX_QUERIES) { + // too many queries, just ignore + Firmata.sendString("too many queries"); + break; + } + queryIndex++; + query[queryIndex].addr = slaveAddress; + query[queryIndex].reg = argv[2] + (argv[3] << 7); + query[queryIndex].bytes = argv[4] + (argv[5] << 7); + break; + case I2C_STOP_READING: + byte queryIndexToSkip; + // if read continuous mode is enabled for only 1 i2c device, disable + // read continuous reporting for that device + if (queryIndex <= 0) { + queryIndex = -1; + } else { + // if read continuous mode is enabled for multiple devices, + // determine which device to stop reading and remove it's data from + // the array, shifiting other array data to fill the space + for (byte i = 0; i < queryIndex + 1; i++) { + if (query[i].addr = slaveAddress) { + queryIndexToSkip = i; + break; + } + } + + for (byte i = queryIndexToSkip; i<queryIndex + 1; i++) { + if (i < MAX_QUERIES) { + query[i].addr = query[i+1].addr; + query[i].reg = query[i+1].addr; + query[i].bytes = query[i+1].bytes; + } + } + queryIndex--; + } + break; + default: + break; + } + break; + case I2C_CONFIG: + delayTime = (argv[0] + (argv[1] << 7)); + + if(delayTime > 0) { + i2cReadDelayTime = delayTime; + } + + if (!isI2CEnabled) { + enableI2CPins(); + } + + break; case SERVO_CONFIG: if(argc > 4) { // these vars are here for clarity, they'll optimized away by the compiler @@ -241,7 +429,6 @@ void sysexCallback(byte command, byte argc, byte *argv) int maxPulse = argv[3] + (argv[4] << 7); if (IS_PIN_SERVO(pin)) { - // servos are pins from 2 to 13, so offset for array if (servos[PIN_TO_SERVO(pin)].attached()) servos[PIN_TO_SERVO(pin)].detach(); servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); @@ -250,10 +437,14 @@ void sysexCallback(byte command, byte argc, byte *argv) } break; case SAMPLING_INTERVAL: - if (argc > 1) + if (argc > 1) { samplingInterval = argv[0] + (argv[1] << 7); - else - Firmata.sendString("Not enough data"); + if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) { + samplingInterval = MINIMUM_SAMPLING_INTERVAL; + } + } else { + //Firmata.sendString("Not enough data"); + } break; case EXTENDED_ANALOG: if (argc > 1) { @@ -285,6 +476,10 @@ void sysexCallback(byte command, byte argc, byte *argv) Serial.write(SERVO); Serial.write(14); } + if (IS_PIN_I2C(pin)) { + Serial.write(I2C); + Serial.write(1); // to do: determine appropriate value + } Serial.write(127); } Serial.write(END_SYSEX); @@ -315,33 +510,52 @@ void sysexCallback(byte command, byte argc, byte *argv) } } - -/*============================================================================== - * SETUP() - *============================================================================*/ -void setup() +void enableI2CPins() { byte i; + // is there a faster way to do this? would probaby require importing + // Arduino.h to get SCL and SDA pins + for (i=0; i < TOTAL_PINS; i++) { + if(IS_PIN_I2C(i)) { + // mark pins as i2c so they are ignore in non i2c data requests + setPinModeCallback(i, I2C); + } + } + + isI2CEnabled = true; + + // is there enough time before the first I2C request to call this here? + Wire.begin(); +} - Firmata.setFirmwareVersion(2, 2); - - Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); - Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); - Firmata.attach(REPORT_ANALOG, reportAnalogCallback); - Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); - Firmata.attach(SET_PIN_MODE, setPinModeCallback); - Firmata.attach(START_SYSEX, sysexCallback); +/* disable the i2c pins so they can be used for other functions */ +void disableI2CPins() { + isI2CEnabled = false; + // disable read continuous mode for all devices + queryIndex = -1; + // uncomment the following if or when the end() method is added to Wire library + // Wire.end(); +} - // TODO: load state from EEPROM here +/*============================================================================== + * SETUP() + *============================================================================*/ - /* these are initialized to zero by the compiler startup code - for (i=0; i < TOTAL_PORTS; i++) { - reportPINs[i] = false; - portConfigInputs[i] = 0; +void systemResetCallback() +{ + // initialize a defalt state + // TODO: option to load config from EEPROM instead of default + if (isI2CEnabled) { + disableI2CPins(); + } + for (byte i=0; i < TOTAL_PORTS; i++) { + reportPINs[i] = false; // by default, reporting off + portConfigInputs[i] = 0; // until activated previousPINs[i] = 0; } - */ - for (i=0; i < TOTAL_PINS; i++) { + // pins with analog capability default to analog input + // otherwise, pins default to digital output + for (byte i=0; i < TOTAL_PINS; i++) { if (IS_PIN_ANALOG(i)) { // turns off pullup, configures everything setPinModeCallback(i, ANALOG); @@ -350,16 +564,34 @@ void setup() setPinModeCallback(i, OUTPUT); } } - // by defult, do not report any analog inputs + // by default, do not report any analog inputs analogInputsToReport = 0; - Firmata.begin(57600); - /* send digital inputs to set the initial state on the host computer, * since once in the loop(), this firmware will only send on change */ - for (i=0; i < TOTAL_PORTS; i++) { + /* + TODO: this can never execute, since no pins default to digital input + but it will be needed when/if we support EEPROM stored config + for (byte i=0; i < TOTAL_PORTS; i++) { outputPort(i, readPort(i, portConfigInputs[i]), true); } + */ +} + +void setup() +{ + Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION); + + Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); + Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); + Firmata.attach(REPORT_ANALOG, reportAnalogCallback); + Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); + Firmata.attach(SET_PIN_MODE, setPinModeCallback); + Firmata.attach(START_SYSEX, sysexCallback); + Firmata.attach(SYSTEM_RESET, systemResetCallback); + + Firmata.begin(57600); + systemResetCallback(); // reset to default config } /*============================================================================== @@ -394,5 +626,11 @@ void loop() } } } + // report i2c data for all device with read continuous mode enabled + if (queryIndex > -1) { + for (byte i = 0; i < queryIndex + 1; i++) { + readAndReportData(query[i].addr, query[i].reg, query[i].bytes); + } + } } } diff --git a/libraries/Firmata/examples/StandardFirmata_2_2_forUNO_0_3/StandardFirmata_2_2_forUNO_0_3.pde b/libraries/Firmata/examples/StandardFirmata_2_2_forUNO_0_3/StandardFirmata_2_2_forUNO_0_3.pde deleted file mode 100644 index 4cfa658..0000000 --- a/libraries/Firmata/examples/StandardFirmata_2_2_forUNO_0_3/StandardFirmata_2_2_forUNO_0_3.pde +++ /dev/null @@ -1,436 +0,0 @@ -/* - This introduces modifications on the normal Firmata made for Arduino so that the LED - blinks until receiving the first command over serial. - - Copyright (C) 2010 David Cuartielles. All rights reserved. - - based at 99.9% on Firmata by HC Steiner according to the following license terms: - - Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - See file LICENSE.txt for further informations on licensing terms. - - formatted using the GNU C formatting and indenting -*/ - -/* - * TODO: use Program Control to load stored profiles from EEPROM - */ - -#include <Servo.h> -#include <Firmata.h> - -/*============================================================================== - * GLOBAL VARIABLES - *============================================================================*/ - -/* has the command arrived? */ -boolean firstCommand = false; -int dataOnSerial = 0; -boolean statusLed = false; - -/* analog inputs */ -int analogInputsToReport = 0; // bitwise array to store pin reporting - -/* digital input ports */ -byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence -byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent - -/* pins configuration */ -byte pinConfig[TOTAL_PINS]; // configuration of every pin -byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else -int pinState[TOTAL_PINS]; // any value that has been written - -/* timer variables */ -unsigned long currentMillis; // store the current value from millis() -unsigned long previousMillis; // for comparison with currentMillis -int samplingInterval = 19; // how often to run the main loop (in ms) -unsigned long toggleMillis; - -Servo servos[MAX_SERVOS]; - -/*============================================================================== - * FUNCTIONS - *============================================================================*/ - -void toggleLed() -{ - if (millis() - toggleMillis > 500) { - statusLed = !statusLed; - digitalWrite(13, statusLed); - toggleMillis = millis(); - } -} - -void outputPort(byte portNumber, byte portValue, byte forceSend) -{ - // pins not configured as INPUT are cleared to zeros - portValue = portValue & portConfigInputs[portNumber]; - // only send if the value is different than previously sent - if(forceSend || previousPINs[portNumber] != portValue) { - Firmata.sendDigitalPort(portNumber, portValue); - previousPINs[portNumber] = portValue; - } -} - -/* ----------------------------------------------------------------------------- - * check all the active digital inputs for change of state, then add any events - * to the Serial output queue using Serial.print() */ -void checkDigitalInputs(void) -{ - /* Using non-looping code allows constants to be given to readPort(). - * The compiler will apply substantial optimizations if the inputs - * to readPort() are compile-time constants. */ - if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false); - if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false); - if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false); - if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false); - if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false); - if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false); - if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false); - if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false); - if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false); - if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false); - if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false); - if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false); - if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false); - if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false); - if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false); - if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false); -} - -// ----------------------------------------------------------------------------- -/* sets the pin mode to the correct state and sets the relevant bits in the - * two bit-arrays that track Digital I/O and PWM status - */ -void setPinModeCallback(byte pin, int mode) -{ - if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { - servos[PIN_TO_SERVO(pin)].detach(); - } - if (IS_PIN_ANALOG(pin)) { - reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting - } - if (IS_PIN_DIGITAL(pin)) { - if (mode == INPUT) { - portConfigInputs[pin/8] |= (1 << (pin & 7)); - } else { - portConfigInputs[pin/8] &= ~(1 << (pin & 7)); - } - } - pinState[pin] = 0; - switch(mode) { - case ANALOG: - if (IS_PIN_ANALOG(pin)) { - if (IS_PIN_DIGITAL(pin)) { - pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver - digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups - } - pinConfig[pin] = ANALOG; - } - break; - case INPUT: - if (IS_PIN_DIGITAL(pin)) { - pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver - digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups - pinConfig[pin] = INPUT; - } - break; - case OUTPUT: - if (IS_PIN_DIGITAL(pin)) { - digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM - pinMode(PIN_TO_DIGITAL(pin), OUTPUT); - pinConfig[pin] = OUTPUT; - } - break; - case PWM: - if (IS_PIN_PWM(pin)) { - pinMode(PIN_TO_PWM(pin), OUTPUT); - analogWrite(PIN_TO_PWM(pin), 0); - pinConfig[pin] = PWM; - } - break; - case SERVO: - if (IS_PIN_SERVO(pin)) { - pinConfig[pin] = SERVO; - if (!servos[PIN_TO_SERVO(pin)].attached()) { - servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); - } else { - Firmata.sendString("Servo only on pins from 2 to 13"); - } - } - break; - case I2C: - pinConfig[pin] = mode; - Firmata.sendString("I2C mode not yet supported"); - break; - default: - Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM - } - // TODO: save status to EEPROM here, if changed -} - -void analogWriteCallback(byte pin, int value) -{ - if (pin < TOTAL_PINS) { - switch(pinConfig[pin]) { - case SERVO: - if (IS_PIN_SERVO(pin)) - servos[PIN_TO_SERVO(pin)].write(value); - pinState[pin] = value; - break; - case PWM: - if (IS_PIN_PWM(pin)) - analogWrite(PIN_TO_PWM(pin), value); - pinState[pin] = value; - break; - } - } -} - -void digitalWriteCallback(byte port, int value) -{ - byte pin, lastPin, mask=1, pinWriteMask=0; - - if (port < TOTAL_PORTS) { - // create a mask of the pins on this port that are writable. - lastPin = port*8+8; - if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS; - for (pin=port*8; pin < lastPin; pin++) { - // do not disturb non-digital pins (eg, Rx & Tx) - if (IS_PIN_DIGITAL(pin)) { - // only write to OUTPUT and INPUT (enables pullup) - // do not touch pins in PWM, ANALOG, SERVO or other modes - if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) { - pinWriteMask |= mask; - pinState[pin] = ((byte)value & mask) ? 1 : 0; - } - } - mask = mask << 1; - } - writePort(port, (byte)value, pinWriteMask); - } -} - - -// ----------------------------------------------------------------------------- -/* sets bits in a bit array (int) to toggle the reporting of the analogIns - */ -//void FirmataClass::setAnalogPinReporting(byte pin, byte state) { -//} -void reportAnalogCallback(byte analogPin, int value) -{ - if (analogPin < TOTAL_ANALOG_PINS) { - if(value == 0) { - analogInputsToReport = analogInputsToReport &~ (1 << analogPin); - } else { - analogInputsToReport = analogInputsToReport | (1 << analogPin); - } - } - // TODO: save status to EEPROM here, if changed -} - -void reportDigitalCallback(byte port, int value) -{ - if (port < TOTAL_PORTS) { - reportPINs[port] = (byte)value; - } - // do not disable analog reporting on these 8 pins, to allow some - // pins used for digital, others analog. Instead, allow both types - // of reporting to be enabled, but check if the pin is configured - // as analog when sampling the analog inputs. Likewise, while - // scanning digital pins, portConfigInputs will mask off values from any - // pins configured as analog -} - -/*============================================================================== - * SYSEX-BASED commands - *============================================================================*/ - -void sysexCallback(byte command, byte argc, byte *argv) -{ - switch(command) { - case SERVO_CONFIG: - if(argc > 4) { - // these vars are here for clarity, they'll optimized away by the compiler - byte pin = argv[0]; - int minPulse = argv[1] + (argv[2] << 7); - int maxPulse = argv[3] + (argv[4] << 7); - - if (IS_PIN_SERVO(pin)) { - // servos are pins from 2 to 13, so offset for array - if (servos[PIN_TO_SERVO(pin)].attached()) - servos[PIN_TO_SERVO(pin)].detach(); - servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); - setPinModeCallback(pin, SERVO); - } - } - break; - case SAMPLING_INTERVAL: - if (argc > 1) - samplingInterval = argv[0] + (argv[1] << 7); - else - Firmata.sendString("Not enough data"); - break; - case EXTENDED_ANALOG: - if (argc > 1) { - int val = argv[1]; - if (argc > 2) val |= (argv[2] << 7); - if (argc > 3) val |= (argv[3] << 14); - analogWriteCallback(argv[0], val); - } - break; - case CAPABILITY_QUERY: - Serial.write(START_SYSEX); - Serial.write(CAPABILITY_RESPONSE); - for (byte pin=0; pin < TOTAL_PINS; pin++) { - if (IS_PIN_DIGITAL(pin)) { - Serial.write((byte)INPUT); - Serial.write(1); - Serial.write((byte)OUTPUT); - Serial.write(1); - } - if (IS_PIN_ANALOG(pin)) { - Serial.write(ANALOG); - Serial.write(10); - } - if (IS_PIN_PWM(pin)) { - Serial.write(PWM); - Serial.write(8); - } - if (IS_PIN_SERVO(pin)) { - Serial.write(SERVO); - Serial.write(14); - } - Serial.write(127); - } - Serial.write(END_SYSEX); - break; - case PIN_STATE_QUERY: - if (argc > 0) { - byte pin=argv[0]; - Serial.write(START_SYSEX); - Serial.write(PIN_STATE_RESPONSE); - Serial.write(pin); - if (pin < TOTAL_PINS) { - Serial.write((byte)pinConfig[pin]); - Serial.write((byte)pinState[pin] & 0x7F); - if (pinState[pin] & 0xFF80) Serial.write((byte)(pinState[pin] >> 7) & 0x7F); - if (pinState[pin] & 0xC000) Serial.write((byte)(pinState[pin] >> 14) & 0x7F); - } - Serial.write(END_SYSEX); - } - break; - case ANALOG_MAPPING_QUERY: - Serial.write(START_SYSEX); - Serial.write(ANALOG_MAPPING_RESPONSE); - for (byte pin=0; pin < TOTAL_PINS; pin++) { - Serial.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127); - } - Serial.write(END_SYSEX); - break; - } -} - -/*============================================================================== - * SETUP() - *============================================================================*/ -void setup() -{ - byte i; - - Firmata.setFirmwareVersion(2, 2); - - Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); - Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); - Firmata.attach(REPORT_ANALOG, reportAnalogCallback); - Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); - Firmata.attach(SET_PIN_MODE, setPinModeCallback); - Firmata.attach(START_SYSEX, sysexCallback); - - // TODO: load state from EEPROM here - - /* these are initialized to zero by the compiler startup code - for (i=0; i < TOTAL_PORTS; i++) { - reportPINs[i] = false; - portConfigInputs[i] = 0; - previousPINs[i] = 0; - } - */ - for (i=0; i < TOTAL_PINS; i++) { - if (IS_PIN_ANALOG(i)) { - // turns off pullup, configures everything - setPinModeCallback(i, ANALOG); - } else { - // sets the output to 0, configures portConfigInputs - setPinModeCallback(i, OUTPUT); - } - } - // by defult, do not report any analog inputs - analogInputsToReport = 0; - - Firmata.begin(57600); - - /* send digital inputs to set the initial state on the host computer, - * since once in the loop(), this firmware will only send on change */ - for (i=0; i < TOTAL_PORTS; i++) { - outputPort(i, readPort(i, portConfigInputs[i]), true); - } - - /* init the toggleLed counter */ - toggleMillis = millis(); - pinMode(13, OUTPUT); -} - -/*============================================================================== - * LOOP() - *============================================================================*/ -void loop() -{ - byte pin, analogPin; - - /* DIGITALREAD - as fast as possible, check for changes and output them to the - * FTDI buffer using Serial.print() */ - checkDigitalInputs(); - - //XXX: hack Firmata to blink until serial command arrives - dataOnSerial = Firmata.available(); - if (dataOnSerial > 0 && !firstCommand) { - firstCommand = true; - } - //XXX: do the blink if the first command hasn't arrived yet - // configures pin 13 as output and then back as input - if (!firstCommand) { - toggleLed(); - } - - /* SERIALREAD - processing incoming messagse as soon as possible, while still - * checking digital inputs. */ - while(dataOnSerial) { - Firmata.processInput(); - dataOnSerial = Firmata.available(); - } - - /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over - * 60 bytes. use a timer to sending an event character every 4 ms to - * trigger the buffer to dump. */ - - currentMillis = millis(); - if (currentMillis - previousMillis > samplingInterval) { - previousMillis += samplingInterval; - /* ANALOGREAD - do all analogReads() at the configured sampling interval */ - for(pin=0; pin<TOTAL_PINS; pin++) { - if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) { - analogPin = PIN_TO_ANALOG(pin); - if (analogInputsToReport & (1 << analogPin)) { - Firmata.sendAnalog(analogPin, analogRead(analogPin)); - } - } - } - } -} diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp new file mode 100644 index 0000000..0653487 --- /dev/null +++ b/libraries/LiquidCrystal/LiquidCrystal.cpp @@ -0,0 +1,310 @@ +#include "LiquidCrystal.h" + +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include "Arduino.h" + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ + init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ + init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + _rs_pin = rs; + _rw_pin = rw; + _enable_pin = enable; + + _data_pins[0] = d0; + _data_pins[1] = d1; + _data_pins[2] = d2; + _data_pins[3] = d3; + _data_pins[4] = d4; + _data_pins[5] = d5; + _data_pins[6] = d6; + _data_pins[7] = d7; + + pinMode(_rs_pin, OUTPUT); + // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# + if (_rw_pin != 255) { + pinMode(_rw_pin, OUTPUT); + } + pinMode(_enable_pin, OUTPUT); + + if (fourbitmode) + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + else + _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; + + begin(16, 1); +} + +void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + _currline = 0; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + digitalWrite(_rs_pin, LOW); + digitalWrite(_enable_pin, LOW); + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::setCursor(uint8_t col, uint8_t row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row >= _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8_t value) { + send(value, LOW); +} + +inline size_t LiquidCrystal::write(uint8_t value) { + send(value, HIGH); + return 1; // assume sucess +} + +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal::send(uint8_t value, uint8_t mode) { + digitalWrite(_rs_pin, mode); + + // if there is a RW pin indicated, set it low to Write + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + if (_displayfunction & LCD_8BITMODE) { + write8bits(value); + } else { + write4bits(value>>4); + write4bits(value); + } +} + +void LiquidCrystal::pulseEnable(void) { + digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); + digitalWrite(_enable_pin, HIGH); + delayMicroseconds(1); // enable pulse must be >450ns + digitalWrite(_enable_pin, LOW); + delayMicroseconds(100); // commands need > 37us to settle +} + +void LiquidCrystal::write4bits(uint8_t value) { + for (int i = 0; i < 4; i++) { + pinMode(_data_pins[i], OUTPUT); + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} + +void LiquidCrystal::write8bits(uint8_t value) { + for (int i = 0; i < 8; i++) { + pinMode(_data_pins[i], OUTPUT); + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h new file mode 100755 index 0000000..24ec5af --- /dev/null +++ b/libraries/LiquidCrystal/LiquidCrystal.h @@ -0,0 +1,106 @@ +#ifndef LiquidCrystal_h +#define LiquidCrystal_h + +#include <inttypes.h> +#include "Print.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal : public Print { +public: + LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); + LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); + + void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); + virtual size_t write(uint8_t); + void command(uint8_t); + + using Print::write; +private: + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void write8bits(uint8_t); + void pulseEnable(); + + uint8_t _rs_pin; // LOW: command. HIGH: character. + uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD. + uint8_t _enable_pin; // activated by a HIGH pulse. + uint8_t _data_pins[8]; + + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _initialized; + + uint8_t _numlines,_currline; +}; + +#endif diff --git a/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino new file mode 100644 index 0000000..27123ad --- /dev/null +++ b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino @@ -0,0 +1,73 @@ +/* + LiquidCrystal Library - Autoscroll + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch demonstrates the use of the autoscroll() + and noAutoscroll() functions to make new text scroll or not. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16,2); +} + +void loop() { + // set the cursor to (0,0): + lcd.setCursor(0, 0); + // print from 0 to 9: + for (int thisChar = 0; thisChar < 10; thisChar++) { + lcd.print(thisChar); + delay(500); + } + + // set the cursor to (16,1): + lcd.setCursor(16,1); + // set the display to automatically scroll: + lcd.autoscroll(); + // print from 0 to 9: + for (int thisChar = 0; thisChar < 10; thisChar++) { + lcd.print(thisChar); + delay(500); + } + // turn off automatic scrolling + lcd.noAutoscroll(); + + // clear screen for the next loop: + lcd.clear(); +} + diff --git a/libraries/LiquidCrystal/examples/Blink/Blink.ino b/libraries/LiquidCrystal/examples/Blink/Blink.ino new file mode 100644 index 0000000..e410424 --- /dev/null +++ b/libraries/LiquidCrystal/examples/Blink/Blink.ino @@ -0,0 +1,61 @@ +/* + LiquidCrystal Library - Blink + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and makes the + cursor block blink. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the blinking cursor: + lcd.noBlink(); + delay(3000); + // Turn on the blinking cursor: + lcd.blink(); + delay(3000); +} + + diff --git a/libraries/LiquidCrystal/examples/Cursor/Cursor.ino b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino new file mode 100644 index 0000000..28e2a6a --- /dev/null +++ b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino @@ -0,0 +1,60 @@ +/* + LiquidCrystal Library - Cursor + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and + uses the cursor() and noCursor() methods to turn + on and off the cursor. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the cursor: + lcd.noCursor(); + delay(500); + // Turn on the cursor: + lcd.cursor(); + delay(500); +} + diff --git a/libraries/LiquidCrystal/examples/CustomCharacter/CustomCharacter.ino b/libraries/LiquidCrystal/examples/CustomCharacter/CustomCharacter.ino new file mode 100644 index 0000000..d3ce479 --- /dev/null +++ b/libraries/LiquidCrystal/examples/CustomCharacter/CustomCharacter.ino @@ -0,0 +1,138 @@ +/* + LiquidCrystal Library - Custom Characters + + Demonstrates how to add custom characters on an LCD display. + The LiquidCrystal library works with all LCD displays that are + compatible with the Hitachi HD44780 driver. There are many of + them out there, and you can usually tell them by the 16-pin interface. + + This sketch prints "I <heart> Arduino!" and a little dancing man + to the LCD. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K potentiometer: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + * 10K poterntiometer on pin A0 + + created21 Mar 2011 + by Tom Igoe + Based on Adafruit's example at + https://github.com/adafruit/SPI_VFD/blob/master/examples/createChar/createChar.pde + + This example code is in the public domain. + http://www.arduino.cc/en/Tutorial/LiquidCrystal + + Also useful: + http://icontexto.com/charactercreator/ + + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +// make some custom characters: +byte heart[8] = { + 0b00000, + 0b01010, + 0b11111, + 0b11111, + 0b11111, + 0b01110, + 0b00100, + 0b00000 +}; + +byte smiley[8] = { + 0b00000, + 0b00000, + 0b01010, + 0b00000, + 0b00000, + 0b10001, + 0b01110, + 0b00000 +}; + +byte frownie[8] = { + 0b00000, + 0b00000, + 0b01010, + 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001 +}; + +byte armsDown[8] = { + 0b00100, + 0b01010, + 0b00100, + 0b00100, + 0b01110, + 0b10101, + 0b00100, + 0b01010 +}; + +byte armsUp[8] = { + 0b00100, + 0b01010, + 0b00100, + 0b10101, + 0b01110, + 0b00100, + 0b00100, + 0b01010 +}; +void setup() { + // create a new character + lcd.createChar(0, heart); + // create a new character + lcd.createChar(1, smiley); + // create a new character + lcd.createChar(2, frownie); + // create a new character + lcd.createChar(3, armsDown); + // create a new character + lcd.createChar(4, armsUp); + + // set up the lcd's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the lcd. + lcd.print("I "); + lcd.write(0); + lcd.print(" Arduino! "); + lcd.write(1); + +} + +void loop() { + // read the potentiometer on A0: + int sensorReading = analogRead(A0); + // map the result to 200 - 1000: + int delayTime = map(sensorReading, 0, 1023, 200, 1000); + // set the cursor to the bottom row, 5th position: + lcd.setCursor(4, 1); + // draw the little man, arms down: + lcd.write(3); + delay(delayTime); + lcd.setCursor(4, 1); + // draw him arms up: + lcd.write(4); + delay(delayTime); +} + + + diff --git a/libraries/LiquidCrystal/examples/Display/Display.ino b/libraries/LiquidCrystal/examples/Display/Display.ino new file mode 100644 index 0000000..b000731 --- /dev/null +++ b/libraries/LiquidCrystal/examples/Display/Display.ino @@ -0,0 +1,60 @@ +/* + LiquidCrystal Library - display() and noDisplay() + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and uses the + display() and noDisplay() functions to turn on and off + the display. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the display: + lcd.noDisplay(); + delay(500); + // Turn on the display: + lcd.display(); + delay(500); +} + diff --git a/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino b/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino new file mode 100644 index 0000000..e99957d --- /dev/null +++ b/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino @@ -0,0 +1,58 @@ +/* + LiquidCrystal Library - Hello World + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD + and shows the time. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // set the cursor to column 0, line 1 + // (note: line 1 is the second row, since counting begins with 0): + lcd.setCursor(0, 1); + // print the number of seconds since reset: + lcd.print(millis()/1000); +} + diff --git a/libraries/LiquidCrystal/examples/Scroll/Scroll.ino b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino new file mode 100644 index 0000000..71e5e8c --- /dev/null +++ b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino @@ -0,0 +1,85 @@ +/* + LiquidCrystal Library - scrollDisplayLeft() and scrollDisplayRight() + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and uses the + scrollDisplayLeft() and scrollDisplayRight() methods to scroll + the text. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); + delay(1000); +} + +void loop() { + // scroll 13 positions (string length) to the left + // to move it offscreen left: + for (int positionCounter = 0; positionCounter < 13; positionCounter++) { + // scroll one position left: + lcd.scrollDisplayLeft(); + // wait a bit: + delay(150); + } + + // scroll 29 positions (string length + display length) to the right + // to move it offscreen right: + for (int positionCounter = 0; positionCounter < 29; positionCounter++) { + // scroll one position right: + lcd.scrollDisplayRight(); + // wait a bit: + delay(150); + } + + // scroll 16 positions (display length + string length) to the left + // to move it back to center: + for (int positionCounter = 0; positionCounter < 16; positionCounter++) { + // scroll one position left: + lcd.scrollDisplayLeft(); + // wait a bit: + delay(150); + } + + // delay at the end of the full loop: + delay(1000); + +} + diff --git a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino new file mode 100644 index 0000000..9727cee --- /dev/null +++ b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino @@ -0,0 +1,65 @@ +/* + LiquidCrystal Library - Serial Input + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch displays text sent over the serial port + (e.g. from the Serial Monitor) on an attached LCD. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup(){ + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // initialize the serial communications: + Serial.begin(9600); +} + +void loop() +{ + // when characters arrive over the serial port... + if (Serial.available()) { + // wait a bit for the entire message to arrive + delay(100); + // clear the screen + lcd.clear(); + // read all the available characters + while (Serial.available() > 0) { + // display each character to the LCD + lcd.write(Serial.read()); + } + } +} diff --git a/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino new file mode 100644 index 0000000..51bab1f --- /dev/null +++ b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino @@ -0,0 +1,87 @@ + /* + LiquidCrystal Library - TextDirection + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch demonstrates how to use leftToRight() and rightToLeft() + to move the cursor. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + + */ + +// include the library code: +#include <LiquidCrystal.h> + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +int thisChar = 'a'; + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // turn on the cursor: + lcd.cursor(); + Serial.begin(9600); +} + +void loop() { + // reverse directions at 'm': + if (thisChar == 'm') { + // go right for the next letter + lcd.rightToLeft(); + } + // reverse again at 's': + if (thisChar == 's') { + // go left for the next letter + lcd.leftToRight(); + } + // reset at 'z': + if (thisChar > 'z') { + // go to (0,0): + lcd.home(); + // start again at 0 + thisChar = 'a'; + } + // print the character + lcd.write(thisChar); + // wait a second: + delay(1000); + // increment the letter: + thisChar++; +} + + + + + + + + diff --git a/libraries/LiquidCrystal/examples/setCursor/setCursor.ino b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino new file mode 100644 index 0000000..3c4edf3 --- /dev/null +++ b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino @@ -0,0 +1,71 @@ +/* + LiquidCrystal Library - setCursor + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints to all the positions of the LCD using the + setCursor(0 method: + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include <LiquidCrystal.h> + +// these constants won't change. But you can change the size of +// your LCD using them: +const int numRows = 2; +const int numCols = 16; + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(numCols,numRows); +} + +void loop() { + // loop from ASCII 'a' to ASCII 'z': + for (int thisLetter = 'a'; thisLetter <= 'z'; thisLetter++) { + // loop over the columns: + for (int thisCol = 0; thisCol < numRows; thisCol++) { + // loop over the rows: + for (int thisRow = 0; thisRow < numCols; thisRow++) { + // set the cursor position: + lcd.setCursor(thisRow,thisCol); + // print the letter: + lcd.write(thisLetter); + delay(200); + } + } + } +} + + diff --git a/libraries/LiquidCrystal/keywords.txt b/libraries/LiquidCrystal/keywords.txt new file mode 100755 index 0000000..132845c --- /dev/null +++ b/libraries/LiquidCrystal/keywords.txt @@ -0,0 +1,37 @@ +####################################### +# Syntax Coloring Map For LiquidCrystal +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LiquidCrystal KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +clear KEYWORD2 +home KEYWORD2 +print KEYWORD2 +setCursor KEYWORD2 +cursor KEYWORD2 +noCursor KEYWORD2 +blink KEYWORD2 +noBlink KEYWORD2 +display KEYWORD2 +noDisplay KEYWORD2 +autoscroll KEYWORD2 +noAutoscroll KEYWORD2 +leftToRight KEYWORD2 +rightToLeft KEYWORD2 +scrollDisplayLeft KEYWORD2 +scrollDisplayRight KEYWORD2 +createChar KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/SD/File.cpp b/libraries/SD/File.cpp index 9ef8196..88d9e9a 100644 --- a/libraries/SD/File.cpp +++ b/libraries/SD/File.cpp @@ -18,7 +18,7 @@ uint8_t nfilecount=0; */ -File::File(SdFile f, char *n) { +File::File(SdFile f, const char *n) { // oh man you are kidding me, new() doesnt exist? Ok we do it by hand! _file = (SdFile *)malloc(sizeof(SdFile)); if (_file) { @@ -58,19 +58,23 @@ boolean File::isDirectory(void) { } -void File::write(uint8_t val) { - if (_file) - _file->write(val); -} - -void File::write(const char *str) { - if (_file) - _file->write(str); +size_t File::write(uint8_t val) { + return write(&val, 1); } -void File::write(const uint8_t *buf, size_t size) { - if (_file) - _file->write(buf, size); +size_t File::write(const uint8_t *buf, size_t size) { + size_t t; + if (!_file) { + setWriteError(); + return 0; + } + _file->clearWriteError(); + t = _file->write(buf, size); + if (_file->getWriteError()) { + setWriteError(); + return 0; + } + return t; } int File::peek() { @@ -97,7 +101,10 @@ int File::read(void *buf, uint16_t nbyte) { int File::available() { if (! _file) return 0; - return size() - position(); + + uint32_t n = size() - position(); + + return n > 0X7FFF ? 0X7FFF : n; } void File::flush() { diff --git a/libraries/SD/SD.cpp b/libraries/SD/SD.cpp index 64dc40b..c746809 100644 --- a/libraries/SD/SD.cpp +++ b/libraries/SD/SD.cpp @@ -348,7 +348,7 @@ boolean SDClass::begin(uint8_t csPin) { // this little helper is used to traverse paths -SdFile SDClass::getParentDir(char *filepath, int *index) { +SdFile SDClass::getParentDir(const char *filepath, int *index) { // get parent directory SdFile d1 = root; // start with the mostparent, root! SdFile d2; @@ -357,7 +357,7 @@ SdFile SDClass::getParentDir(char *filepath, int *index) { SdFile *parent = &d1; SdFile *subdir = &d2; - char *origpath = filepath; + const char *origpath = filepath; while (strchr(filepath, '/')) { @@ -404,7 +404,7 @@ SdFile SDClass::getParentDir(char *filepath, int *index) { } -File SDClass::open(char *filepath, uint8_t mode) { +File SDClass::open(const char *filepath, uint8_t mode) { /* Open the supplied file path for reading or writing. diff --git a/libraries/SD/SD.h b/libraries/SD/SD.h index 584e2ae..f21ec0f 100644 --- a/libraries/SD/SD.h +++ b/libraries/SD/SD.h @@ -29,12 +29,11 @@ class File : public Stream { SdFile *_file; // underlying file pointer public: - File(SdFile f, char *name); // wraps an underlying SdFile + File(SdFile f, const char *name); // wraps an underlying SdFile File(void); // 'empty' constructor ~File(void); // destructor - virtual void write(uint8_t); - virtual void write(const char *str); - virtual void write(const uint8_t *buf, size_t size); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); virtual int read(); virtual int peek(); virtual int available(); @@ -50,6 +49,8 @@ public: boolean isDirectory(void); File openNextFile(uint8_t mode = O_RDONLY); void rewindDirectory(void); + + using Print::write; }; class SDClass { @@ -61,7 +62,7 @@ private: SdFile root; // my quick&dirty iterator, should be replaced - SdFile getParentDir(char *filepath, int *indx); + SdFile getParentDir(const char *filepath, int *indx); public: // This needs to be called to set up the connection to the SD card // before other methods are used. @@ -70,7 +71,7 @@ public: // Open the specified file/directory with the supplied mode (e.g. read or // write, etc). Returns a File object for interacting with the file. // Note that currently only one file can be open at a time. - File open(char *filename, uint8_t mode = FILE_READ); + File open(const char *filename, uint8_t mode = FILE_READ); // Methods to determine if the requested file path exists. boolean exists(char *filepath); diff --git a/libraries/SD/examples/CardInfo/CardInfo.pde b/libraries/SD/examples/CardInfo/CardInfo.ino index 7abfd33..fb2f6c3 100644 --- a/libraries/SD/examples/CardInfo/CardInfo.pde +++ b/libraries/SD/examples/CardInfo/CardInfo.ino @@ -80,7 +80,7 @@ void setup() // print the type and size of the first FAT-type volume - long volumesize; + uint32_t volumesize; Serial.print("\nVolume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); diff --git a/libraries/SD/examples/Datalogger/Datalogger.pde b/libraries/SD/examples/Datalogger/Datalogger.ino index 73d81af..73d81af 100644 --- a/libraries/SD/examples/Datalogger/Datalogger.pde +++ b/libraries/SD/examples/Datalogger/Datalogger.ino diff --git a/libraries/SD/examples/DumpFile/DumpFile.pde b/libraries/SD/examples/DumpFile/DumpFile.ino index 961717f..961717f 100644 --- a/libraries/SD/examples/DumpFile/DumpFile.pde +++ b/libraries/SD/examples/DumpFile/DumpFile.ino diff --git a/libraries/SD/examples/Files/Files.pde b/libraries/SD/examples/Files/Files.ino index 5ed9fea..5ed9fea 100644 --- a/libraries/SD/examples/Files/Files.pde +++ b/libraries/SD/examples/Files/Files.ino diff --git a/libraries/SD/examples/ReadWrite/ReadWrite.pde b/libraries/SD/examples/ReadWrite/ReadWrite.ino index 9957218..9957218 100644 --- a/libraries/SD/examples/ReadWrite/ReadWrite.pde +++ b/libraries/SD/examples/ReadWrite/ReadWrite.ino diff --git a/libraries/SD/examples/listfiles/listfiles.pde b/libraries/SD/examples/listfiles/listfiles.ino index b2435a2..b2435a2 100644 --- a/libraries/SD/examples/listfiles/listfiles.pde +++ b/libraries/SD/examples/listfiles/listfiles.ino diff --git a/libraries/SD/utility/SdFat.h b/libraries/SD/utility/SdFat.h index 048fa71..344326f 100644 --- a/libraries/SD/utility/SdFat.h +++ b/libraries/SD/utility/SdFat.h @@ -141,7 +141,7 @@ class SdFile : public Print { * Set writeError to false before calling print() and/or write() and check
* for true after calls to print() and/or write().
*/
- bool writeError;
+ //bool writeError;
/**
* Cancel unbuffered reads for this file.
* See setUnbufferedRead()
@@ -283,9 +283,9 @@ class SdFile : public Print { }
/** \return SdVolume that contains this file. */
SdVolume* volume(void) const {return vol_;}
- void write(uint8_t b);
- int16_t write(const void* buf, uint16_t nbyte);
- void write(const char* str);
+ size_t write(uint8_t b);
+ size_t write(const void* buf, uint16_t nbyte);
+ size_t write(const char* str);
void write_P(PGM_P str);
void writeln_P(PGM_P str);
//------------------------------------------------------------------------------
diff --git a/libraries/SD/utility/SdFatUtil.h b/libraries/SD/utility/SdFatUtil.h index c626bfe..283fcb2 100644 --- a/libraries/SD/utility/SdFatUtil.h +++ b/libraries/SD/utility/SdFatUtil.h @@ -30,10 +30,11 @@ /** Store and print a string in flash memory followed by a CR/LF.*/
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
/** Defined so doxygen works for function definitions. */
-#define NOINLINE __attribute__((noinline))
+#define NOINLINE __attribute__((noinline,unused))
+#define UNUSEDOK __attribute__((unused))
//------------------------------------------------------------------------------
/** Return the number of bytes currently free in RAM. */
-static int FreeRam(void) {
+static UNUSEDOK int FreeRam(void) {
extern int __bss_end;
extern int* __brkval;
int free_memory;
diff --git a/libraries/SD/utility/SdFile.cpp b/libraries/SD/utility/SdFile.cpp index 40444a7..e786f56 100644 --- a/libraries/SD/utility/SdFile.cpp +++ b/libraries/SD/utility/SdFile.cpp @@ -590,7 +590,7 @@ void SdFile::printDirName(const dir_t& dir, uint8_t width) { Serial.print('.');
w++;
}
- Serial.print(dir.name[i]);
+ Serial.write(dir.name[i]);
w++;
}
if (DIR_IS_SUBDIR(&dir)) {
@@ -1121,7 +1121,7 @@ uint8_t SdFile::truncate(uint32_t length) { * for a read-only file, device is full, a corrupt file system or an I/O error.
*
*/
-int16_t SdFile::write(const void* buf, uint16_t nbyte) {
+size_t SdFile::write(const void* buf, uint16_t nbyte) {
// convert void* to uint8_t* - must be before goto statements
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
@@ -1210,8 +1210,9 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) { writeErrorReturn:
// return for write error
- writeError = true;
- return -1;
+ //writeError = true;
+ setWriteError();
+ return 0;
}
//------------------------------------------------------------------------------
/**
@@ -1219,8 +1220,8 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) { *
* Use SdFile::writeError to check for errors.
*/
-void SdFile::write(uint8_t b) {
- write(&b, 1);
+size_t SdFile::write(uint8_t b) {
+ return write(&b, 1);
}
//------------------------------------------------------------------------------
/**
@@ -1228,8 +1229,8 @@ void SdFile::write(uint8_t b) { *
* Use SdFile::writeError to check for errors.
*/
-void SdFile::write(const char* str) {
- write(str, strlen(str));
+size_t SdFile::write(const char* str) {
+ return write(str, strlen(str));
}
//------------------------------------------------------------------------------
/**
diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 79c89d4..f647d5c 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -22,7 +22,7 @@ #define SPI_CLOCK_DIV2 0x04 #define SPI_CLOCK_DIV8 0x05 #define SPI_CLOCK_DIV32 0x06 -#define SPI_CLOCK_DIV64 0x07 +//#define SPI_CLOCK_DIV64 0x07 #define SPI_MODE0 0x00 #define SPI_MODE1 0x04 diff --git a/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.pde b/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino index 9d77a42..9d77a42 100644 --- a/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.pde +++ b/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino diff --git a/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor/BarometricPressureSensor.pde b/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor/BarometricPressureSensor.ino index 9c9c9b6..9c9c9b6 100644 --- a/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor/BarometricPressureSensor.pde +++ b/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor/BarometricPressureSensor.ino diff --git a/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.pde b/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino index ef97dae..ef97dae 100644 --- a/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.pde +++ b/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino diff --git a/libraries/Servo/examples/Knob/Knob.pde b/libraries/Servo/examples/Knob/Knob.ino index 886e107..886e107 100644 --- a/libraries/Servo/examples/Knob/Knob.pde +++ b/libraries/Servo/examples/Knob/Knob.ino diff --git a/libraries/Servo/examples/Sweep/Sweep.pde b/libraries/Servo/examples/Sweep/Sweep.ino index fb326e7..fb326e7 100644 --- a/libraries/Servo/examples/Sweep/Sweep.pde +++ b/libraries/Servo/examples/Sweep/Sweep.ino diff --git a/libraries/SoftwareSerial/SoftwareSerial.cpp b/libraries/SoftwareSerial/SoftwareSerial.cpp index b8a1fc4..c15bdda 100755 --- a/libraries/SoftwareSerial/SoftwareSerial.cpp +++ b/libraries/SoftwareSerial/SoftwareSerial.cpp @@ -42,7 +42,6 @@ http://arduiniana.org. #include <avr/pgmspace.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
-#include "icrmacros.h"
//
// Lookup table
//
@@ -441,10 +440,12 @@ int SoftwareSerial::available() return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
-void SoftwareSerial::write(uint8_t b)
+size_t SoftwareSerial::write(uint8_t b)
{
- if (_tx_delay == 0)
- return;
+ if (_tx_delay == 0) {
+ setWriteError();
+ return 0;
+ }
uint8_t oldSREG = SREG;
cli(); // turn off interrupts for a clean txmit
@@ -485,6 +486,8 @@ void SoftwareSerial::write(uint8_t b) SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay);
+
+ return 1;
}
void SoftwareSerial::flush()
diff --git a/libraries/SoftwareSerial/SoftwareSerial.h b/libraries/SoftwareSerial/SoftwareSerial.h index 2fc998c..a6a60b5 100755 --- a/libraries/SoftwareSerial/SoftwareSerial.h +++ b/libraries/SoftwareSerial/SoftwareSerial.h @@ -89,10 +89,12 @@ public: bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
int peek();
- virtual void write(uint8_t byte);
+ virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
+
+ using Print::write;
// public only for easy access by interrupt handlers
static inline void handle_interrupt();
diff --git a/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.pde b/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.pde deleted file mode 100755 index 1db4536..0000000 --- a/libraries/SoftwareSerial/examples/TwoPortRXExample/TwoPortRXExample.pde +++ /dev/null @@ -1,50 +0,0 @@ -#include <SoftwareSerial.h>
-
-SoftwareSerial ss(2, 3);
-SoftwareSerial ss2(4, 5);
-
-/* This sample shows how to correctly process received data
- on two different "soft" serial ports. Here we listen on
- the first port (ss) until we receive a '?' character. Then
- we begin listening on the other soft port.
-*/
-
-void setup()
-{
- // Start the HW serial port
- Serial.begin(57600);
-
- // Start each soft serial port
- ss.begin(4800);
- ss2.begin(4800);
-
- // By default, the most recently "begun" port is listening.
- // We want to listen on ss, so let's explicitly select it.
- ss.listen();
-
- // Simply wait for a ? character to come down the pipe
- Serial.println("Data from the first port: ");
- char c = 0;
- do
- if (ss.available())
- {
- c = (char)ss.read();
- Serial.print(c);
- }
- while (c != '?');
-
- // Now listen on the second port
- ss2.listen();
-
- Serial.println("Data from the second port: ");
-}
-
-void loop()
-{
- if (ss2.available())
- {
- char c = (char)ss2.read();
- Serial.print(c);
- }
-}
-
diff --git a/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino new file mode 100644 index 0000000..e870c6f --- /dev/null +++ b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino @@ -0,0 +1,78 @@ +/* + Software serial multple serial test + + Receives from the two software serial ports, + sends to the hardware serial port. + + In order to listen on a software port, you call port.listen(). + When using two software serial ports, you have to switch ports + by listen()ing on each one in turn. Pick a logical time to switch + ports, like the end of an expected transmission, or when the + buffer is empty. This example switches ports when there is nothing + more to read from a port + + The circuit: + Two devices which communicate serially are needed. + * First serial device's TX attached to digital pin 2, RX to pin 3 + * Second serial device's TX attached to digital pin 4, RX to pin 5 + + created 18 Apr. 2011 + by Tom Igoe + based on Mikal Hart's twoPortRXExample + + This example code is in the public domain. + + */ + +#include <SoftwareSerial.h> +// software serial #1: TX = digital pin 2, RX = digital pin 3 +SoftwareSerial portOne(2, 3); + +// software serial #2: TX = digital pin 4, RX = digital pin 5 +SoftwareSerial portTwo(4, 5); + +void setup() +{ + // Start the hardware serial port + Serial.begin(9600); + + // Start each software serial port + portOne.begin(9600); + portTwo.begin(9600); +} + +void loop() +{ + // By default, the last intialized port is listening. + // when you want to listen on a port, explicitly select it: + portOne.listen(); + Serial.println("Data from port one:"); + // while there is data coming in, read it + // and send to the hardware serial port: + while (portOne.available() > 0) { + char inByte = portOne.read(); + Serial.write(inByte); + } + + // blank line to separate data from the two ports: + Serial.println(); + + // Now listen on the second port + portTwo.listen(); + // while there is data coming in, read it + // and send to the hardware serial port: + Serial.println("Data from port two:"); + while (portTwo.available() > 0) { + char inByte = portTwo.read(); + Serial.write(inByte); + } + + // blank line to separate data from the two ports: + Serial.println(); +} + + + + + + diff --git a/libraries/SoftwareSerial/icrmacros.h b/libraries/SoftwareSerial/icrmacros.h deleted file mode 100755 index 936eae8..0000000 --- a/libraries/SoftwareSerial/icrmacros.h +++ /dev/null @@ -1,69 +0,0 @@ -/*
-icrmacros.h
-
-A place to put useful ICR (interrupt change register) macros
-
-If you want to support non-Arduino processors you can extend or replace
-this file.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-The latest version of this library can always be found at
-http://arduiniana.org.
-*/
-
-// Abstractions for maximum portability between processors
-// These are macros to associate pins to pin change interrupts
-#if !defined(digitalPinToPCICR) // Courtesy Paul Stoffregen
-
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
-
-#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
-#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
-#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
-#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
-
-#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-// Specifically for the Arduino Mega 2560 (or 1280 on the original Arduino Mega)
-// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins)
-// Only pins available for RECEIVE (TRANSMIT can be on any pin):
-// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me)
-// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
-
-#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \
- (((p) >= 50) && ((p) <= 53)) || \
- (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )
-
-#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \
- ( (((p) >= 62) && ((p) <= 69)) ? 2 : \
- 0 ) )
-
-#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \
- ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \
- ((uint8_t *)0) ) )
-
-#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \
- ( ((p) == 50) ? 3 : \
- ( ((p) == 51) ? 2 : \
- ( ((p) == 52) ? 1 : \
- ( ((p) == 53) ? 0 : \
- ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \
- 0 ) ) ) ) ) )
-
-#else
-#error This processor is not supported by SoftwareSerial
-#endif
-#endif
-
diff --git a/libraries/Stepper/Stepper.cpp b/libraries/Stepper/Stepper.cpp new file mode 100644 index 0000000..5d6b5e5 --- /dev/null +++ b/libraries/Stepper/Stepper.cpp @@ -0,0 +1,220 @@ +/* + Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4 + + Original library (0.1) by Tom Igoe. + Two-wire modifications (0.2) by Sebastian Gassner + Combination version (0.3) by Tom Igoe and David Mellis + Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley + + Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires + + When wiring multiple stepper motors to a microcontroller, + you quickly run out of output pins, with each motor requiring 4 connections. + + By making use of the fact that at any time two of the four motor + coils are the inverse of the other two, the number of + control connections can be reduced from 4 to 2. + + A slightly modified circuit around a Darlington transistor array or an L293 H-bridge + connects to only 2 microcontroler pins, inverts the signals received, + and delivers the 4 (2 plus 2 inverted ones) output signals required + for driving a stepper motor. + + The sequence of control signals for 4 control wires is as follows: + + Step C0 C1 C2 C3 + 1 1 0 1 0 + 2 0 1 1 0 + 3 0 1 0 1 + 4 1 0 0 1 + + The sequence of controls signals for 2 control wires is as follows + (columns C1 and C2 from above): + + Step C0 C1 + 1 0 1 + 2 1 1 + 3 1 0 + 4 0 0 + + The circuits can be found at + +http://www.arduino.cc/en/Tutorial/Stepper + + + */ + + +#include "Arduino.h" +#include "Stepper.h" + +/* + * two-wire constructor. + * Sets which wires should control the motor. + */ +Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2) +{ + this->step_number = 0; // which step the motor is on + this->speed = 0; // the motor speed, in revolutions per minute + this->direction = 0; // motor direction + this->last_step_time = 0; // time stamp in ms of the last step taken + this->number_of_steps = number_of_steps; // total number of steps for this motor + + // Arduino pins for the motor control connection: + this->motor_pin_1 = motor_pin_1; + this->motor_pin_2 = motor_pin_2; + + // setup the pins on the microcontroller: + pinMode(this->motor_pin_1, OUTPUT); + pinMode(this->motor_pin_2, OUTPUT); + + // When there are only 2 pins, set the other two to 0: + this->motor_pin_3 = 0; + this->motor_pin_4 = 0; + + // pin_count is used by the stepMotor() method: + this->pin_count = 2; +} + + +/* + * constructor for four-pin version + * Sets which wires should control the motor. + */ + +Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4) +{ + this->step_number = 0; // which step the motor is on + this->speed = 0; // the motor speed, in revolutions per minute + this->direction = 0; // motor direction + this->last_step_time = 0; // time stamp in ms of the last step taken + this->number_of_steps = number_of_steps; // total number of steps for this motor + + // Arduino pins for the motor control connection: + this->motor_pin_1 = motor_pin_1; + this->motor_pin_2 = motor_pin_2; + this->motor_pin_3 = motor_pin_3; + this->motor_pin_4 = motor_pin_4; + + // setup the pins on the microcontroller: + pinMode(this->motor_pin_1, OUTPUT); + pinMode(this->motor_pin_2, OUTPUT); + pinMode(this->motor_pin_3, OUTPUT); + pinMode(this->motor_pin_4, OUTPUT); + + // pin_count is used by the stepMotor() method: + this->pin_count = 4; +} + +/* + Sets the speed in revs per minute + +*/ +void Stepper::setSpeed(long whatSpeed) +{ + this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed; +} + +/* + Moves the motor steps_to_move steps. If the number is negative, + the motor moves in the reverse direction. + */ +void Stepper::step(int steps_to_move) +{ + int steps_left = abs(steps_to_move); // how many steps to take + + // determine direction based on whether steps_to_mode is + or -: + if (steps_to_move > 0) {this->direction = 1;} + if (steps_to_move < 0) {this->direction = 0;} + + + // decrement the number of steps, moving one step each time: + while(steps_left > 0) { + // move only if the appropriate delay has passed: + if (millis() - this->last_step_time >= this->step_delay) { + // get the timeStamp of when you stepped: + this->last_step_time = millis(); + // increment or decrement the step number, + // depending on direction: + if (this->direction == 1) { + this->step_number++; + if (this->step_number == this->number_of_steps) { + this->step_number = 0; + } + } + else { + if (this->step_number == 0) { + this->step_number = this->number_of_steps; + } + this->step_number--; + } + // decrement the steps left: + steps_left--; + // step the motor to step number 0, 1, 2, or 3: + stepMotor(this->step_number % 4); + } + } +} + +/* + * Moves the motor forward or backwards. + */ +void Stepper::stepMotor(int thisStep) +{ + if (this->pin_count == 2) { + switch (thisStep) { + case 0: /* 01 */ + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + break; + case 1: /* 11 */ + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, HIGH); + break; + case 2: /* 10 */ + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + break; + case 3: /* 00 */ + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, LOW); + break; + } + } + if (this->pin_count == 4) { + switch (thisStep) { + case 0: // 1010 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + break; + case 1: // 0110 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, HIGH); + digitalWrite(motor_pin_4, LOW); + break; + case 2: //0101 + digitalWrite(motor_pin_1, LOW); + digitalWrite(motor_pin_2, HIGH); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + break; + case 3: //1001 + digitalWrite(motor_pin_1, HIGH); + digitalWrite(motor_pin_2, LOW); + digitalWrite(motor_pin_3, LOW); + digitalWrite(motor_pin_4, HIGH); + break; + } + } +} + +/* + version() returns the version of the library: +*/ +int Stepper::version(void) +{ + return 4; +} diff --git a/libraries/Stepper/Stepper.h b/libraries/Stepper/Stepper.h new file mode 100644 index 0000000..4094aee --- /dev/null +++ b/libraries/Stepper/Stepper.h @@ -0,0 +1,83 @@ +/* + Stepper.h - - Stepper library for Wiring/Arduino - Version 0.4 + + Original library (0.1) by Tom Igoe. + Two-wire modifications (0.2) by Sebastian Gassner + Combination version (0.3) by Tom Igoe and David Mellis + Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley + + Drives a unipolar or bipolar stepper motor using 2 wires or 4 wires + + When wiring multiple stepper motors to a microcontroller, + you quickly run out of output pins, with each motor requiring 4 connections. + + By making use of the fact that at any time two of the four motor + coils are the inverse of the other two, the number of + control connections can be reduced from 4 to 2. + + A slightly modified circuit around a Darlington transistor array or an L293 H-bridge + connects to only 2 microcontroler pins, inverts the signals received, + and delivers the 4 (2 plus 2 inverted ones) output signals required + for driving a stepper motor. + + The sequence of control signals for 4 control wires is as follows: + + Step C0 C1 C2 C3 + 1 1 0 1 0 + 2 0 1 1 0 + 3 0 1 0 1 + 4 1 0 0 1 + + The sequence of controls signals for 2 control wires is as follows + (columns C1 and C2 from above): + + Step C0 C1 + 1 0 1 + 2 1 1 + 3 1 0 + 4 0 0 + + The circuits can be found at + http://www.arduino.cc/en/Tutorial/Stepper +*/ + +// ensure this library description is only included once +#ifndef Stepper_h +#define Stepper_h + +// library interface description +class Stepper { + public: + // constructors: + Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2); + Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4); + + // speed setter method: + void setSpeed(long whatSpeed); + + // mover method: + void step(int number_of_steps); + + int version(void); + + private: + void stepMotor(int this_step); + + int direction; // Direction of rotation + int speed; // Speed in RPMs + unsigned long step_delay; // delay between steps, in ms, based on speed + int number_of_steps; // total number of steps this motor can take + int pin_count; // whether you're driving the motor with 2 or 4 pins + int step_number; // which step the motor is on + + // motor pin numbers: + int motor_pin_1; + int motor_pin_2; + int motor_pin_3; + int motor_pin_4; + + long last_step_time; // time stamp in ms of when the last step was taken +}; + +#endif + diff --git a/libraries/Stepper/examples/MotorKnob/MotorKnob.ino b/libraries/Stepper/examples/MotorKnob/MotorKnob.ino new file mode 100644 index 0000000..d428186 --- /dev/null +++ b/libraries/Stepper/examples/MotorKnob/MotorKnob.ino @@ -0,0 +1,41 @@ +/* + * MotorKnob + * + * A stepper motor follows the turns of a potentiometer + * (or other sensor) on analog input 0. + * + * http://www.arduino.cc/en/Reference/Stepper + * This example code is in the public domain. + */ + +#include <Stepper.h> + +// change this to the number of steps on your motor +#define STEPS 100 + +// create an instance of the stepper class, specifying +// the number of steps of the motor and the pins it's +// attached to +Stepper stepper(STEPS, 8, 9, 10, 11); + +// the previous reading from the analog input +int previous = 0; + +void setup() +{ + // set the speed of the motor to 30 RPMs + stepper.setSpeed(30); +} + +void loop() +{ + // get the sensor value + int val = analogRead(0); + + // move a number of steps equal to the change in the + // sensor reading + stepper.step(val - previous); + + // remember the previous value of the sensor + previous = val; +}
\ No newline at end of file diff --git a/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino b/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino new file mode 100644 index 0000000..2dbb57d --- /dev/null +++ b/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino @@ -0,0 +1,44 @@ + +/* + Stepper Motor Control - one revolution + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + + The motor should revolve one revolution in one direction, then + one revolution in the other direction. + + + Created 11 Mar. 2007 + Modified 30 Nov. 2009 + by Tom Igoe + + */ + +#include <Stepper.h> + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution + // for your motor + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +void setup() { + // set the speed at 60 rpm: + myStepper.setSpeed(60); + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // step one revolution in one direction: + Serial.println("clockwise"); + myStepper.step(stepsPerRevolution); + delay(500); + + // step one revolution in the other direction: + Serial.println("counterclockwise"); + myStepper.step(-stepsPerRevolution); + delay(500); +} + diff --git a/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino b/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino new file mode 100644 index 0000000..36d3299 --- /dev/null +++ b/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino @@ -0,0 +1,44 @@ + +/* + Stepper Motor Control - one step at a time + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + + The motor will step one step at a time, very slowly. You can use this to + test that you've got the four wires of your stepper wired to the correct + pins. If wired correctly, all steps should be in the same direction. + + Use this also to count the number of steps per revolution of your motor, + if you don't know it. Then plug that number into the oneRevolution + example to see if you got it right. + + Created 30 Nov. 2009 + by Tom Igoe + + */ + +#include <Stepper.h> + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution + // for your motor + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +int stepCount = 0; // number of steps the motor has taken + +void setup() { + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // step one step: + myStepper.step(1); + Serial.print("steps:" ); + Serial.println(stepCount); + stepCount++; + delay(500); +} + diff --git a/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino new file mode 100644 index 0000000..dbd0f7f --- /dev/null +++ b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino @@ -0,0 +1,49 @@ + +/* + Stepper Motor Control - speed control + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + A potentiometer is connected to analog input 0. + + The motor will rotate in a clockwise direction. The higher the potentiometer value, + the faster the motor speed. Because setSpeed() sets the delay between steps, + you may notice the motor is less responsive to changes in the sensor value at + low speeds. + + Created 30 Nov. 2009 + Modified 28 Oct 2010 + by Tom Igoe + + */ + +#include <Stepper.h> + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution +// for your motor + + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +int stepCount = 0; // number of steps the motor has taken + +void setup() { + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // read the sensor value: + int sensorReading = analogRead(A0); + // map it to a range from 0 to 100: + int motorSpeed = map(sensorReading, 0, 1023, 0, 100); + // set the motor speed: + if (motorSpeed > 0) { + myStepper.setSpeed(motorSpeed); + // step 1/100 of a revolution: + myStepper.step(stepsPerRevolution/100); + } +} + + diff --git a/libraries/Stepper/keywords.txt b/libraries/Stepper/keywords.txt new file mode 100644 index 0000000..19a0fad --- /dev/null +++ b/libraries/Stepper/keywords.txt @@ -0,0 +1,28 @@ +####################################### +# Syntax Coloring Map For Test +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Stepper KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +step KEYWORD2 +setSpeed KEYWORD2 +version KEYWORD2 + +###################################### +# Instances (KEYWORD2) +####################################### +direction KEYWORD2 +speed KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 5818bee..d83f478 100755 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -124,13 +124,14 @@ uint8_t TwoWire::endTransmission(void) // must be called in: // slave tx event callback // or after beginTransmission(address) -void TwoWire::write(uint8_t data) +size_t TwoWire::write(uint8_t data) { if(transmitting){ // in master transmitter mode // don't bother if buffer is full if(txBufferLength >= BUFFER_LENGTH){ - return; + setWriteError(); + return 0; } // put byte in tx buffer txBuffer[txBufferIndex] = data; @@ -142,12 +143,13 @@ void TwoWire::write(uint8_t data) // reply to master twi_transmit(&data, 1); } + return 1; } // must be called in: // slave tx event callback // or after beginTransmission(address) -void TwoWire::write(const uint8_t *data, size_t quantity) +size_t TwoWire::write(const uint8_t *data, size_t quantity) { if(transmitting){ // in master transmitter mode @@ -159,14 +161,7 @@ void TwoWire::write(const uint8_t *data, size_t quantity) // reply to master twi_transmit(data, quantity); } -} - -// must be called in: -// slave tx event callback -// or after beginTransmission(address) -void TwoWire::write(const char *data) -{ - write((uint8_t*)data, strlen(data)); + return quantity; } // must be called in: diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 51df04e..9ea4afd 100755 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -52,15 +52,20 @@ class TwoWire : public Stream uint8_t endTransmission(void); uint8_t requestFrom(uint8_t, uint8_t); uint8_t requestFrom(int, int); - virtual void write(uint8_t); - virtual void write(const char *); - virtual void write(const uint8_t *, size_t); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *, size_t); virtual int available(void); virtual int read(void); virtual int peek(void); virtual void flush(void); void onReceive( void (*)(int) ); void onRequest( void (*)(void) ); + + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; }; extern TwoWire Wire; diff --git a/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde b/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino index 9c41c18..9c41c18 100755 --- a/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.pde +++ b/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino diff --git a/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde b/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino index 38da1c5..38da1c5 100644 --- a/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.pde +++ b/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino diff --git a/libraries/Wire/examples/master_reader/master_reader.pde b/libraries/Wire/examples/master_reader/master_reader.ino index 4124d7d..4124d7d 100644 --- a/libraries/Wire/examples/master_reader/master_reader.pde +++ b/libraries/Wire/examples/master_reader/master_reader.ino diff --git a/libraries/Wire/examples/master_writer/master_writer.pde b/libraries/Wire/examples/master_writer/master_writer.ino index ccaa036..ccaa036 100644 --- a/libraries/Wire/examples/master_writer/master_writer.pde +++ b/libraries/Wire/examples/master_writer/master_writer.ino diff --git a/libraries/Wire/examples/slave_receiver/slave_receiver.pde b/libraries/Wire/examples/slave_receiver/slave_receiver.ino index 60dd4bd..60dd4bd 100644 --- a/libraries/Wire/examples/slave_receiver/slave_receiver.pde +++ b/libraries/Wire/examples/slave_receiver/slave_receiver.ino diff --git a/libraries/Wire/examples/slave_sender/slave_sender.pde b/libraries/Wire/examples/slave_sender/slave_sender.ino index d3b238a..d3b238a 100644 --- a/libraries/Wire/examples/slave_sender/slave_sender.pde +++ b/libraries/Wire/examples/slave_sender/slave_sender.ino diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c index cef8373..d80114b 100644 --- a/libraries/Wire/utility/twi.c +++ b/libraries/Wire/utility/twi.c @@ -23,6 +23,7 @@ #include <avr/io.h> #include <avr/interrupt.h> #include <compat/twi.h> +#include "Arduino.h" // for digitalWrite #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) @@ -32,6 +33,7 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif +#include "pins_arduino.h" #include "twi.h" static volatile uint8_t twi_state; @@ -63,18 +65,10 @@ void twi_init(void) { // initialize state twi_state = TWI_READY; - - #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) - // activate internal pull-ups for twi - // as per note from atmega8 manual pg167 - sbi(PORTC, 4); - sbi(PORTC, 5); - #else - // activate internal pull-ups for twi - // as per note from atmega128 manual pg204 - sbi(PORTD, 0); - sbi(PORTD, 1); - #endif + + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); // initialize twi prescaler and bit rate cbi(TWSR, TWPS0); diff --git a/platform.txt b/platform.txt new file mode 100644 index 0000000..4599f8a --- /dev/null +++ b/platform.txt @@ -0,0 +1,47 @@ + +# AVR compile variables +# --------------------- + +name=Arduino +# Default "compiler.path" is correct, change only if you want to overidde the initial value +#compiler.path={0}/hardware/tools/avr/bin/ +compiler.c.cmd=avr-gcc +compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections +compiler.c.elf.flags=-Os -Wl,--gc-sections +compiler.c.elf.cmd=avr-gcc +compiler.S.flags=-c -g -assembler-with-cpp +compiler.cpp.cmd=avr-g++ +compiler.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections +compiler.ar.cmd=avr-ar +compiler.ar.flags=rcs +compiler.objcopy.cmd=avr-objcopy +compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 +compiler.elf2hex.flags=-O ihex -R .eeprom +compiler.elf2hex.cmd=avr-objcopy +compiler.ldflags= +compiler.upload.cmd= +compiler.upload.flags= + +# AVR compile patterns +# -------------------- + +## Compile c files +recipe.c.o.pattern={toolchain_path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide_version} {includes} {source_file} -o {object_file} + +## Compile c++ files +recipe.cpp.o.pattern={toolchain_path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide_version} {includes} {source_file} -o {object_file} + +## Create archives +recipe.ar.pattern={toolchain_path}{compiler.ar.cmd} {compiler.ar.flags} {build_path}{archive_file} {object_file} + +## Combine gc-sections, archives, and objects +recipe.c.combine.pattern={toolchain_path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build_path}{project_name}.elf {object_files} {build_path}{archive_file} -L{build_path} -lm + +## Create eeprom +recipe.objcopy.eep.pattern={toolchain_path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build_path}{project_name}.elf {build_path}{project_name}.eep + +## Create hex +recipe.objcopy.hex.pattern={toolchain_path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build_path}{project_name}.elf {build_path}{project_name}.hex + + + diff --git a/platforms.txt b/platforms.txt deleted file mode 100755 index a82454e..0000000 --- a/platforms.txt +++ /dev/null @@ -1,64 +0,0 @@ -#########Compiler Recipe################################# -##compile c object files -##Default.recipe, overide if overide exists, these defauls should remain the same, if you need to change them do it as an overide. - -#default.recipe.c.o.pattern={0}{1}|{2}|{3}{4}|-DF_CPU={5}|-D{6}={7}|{8}|{9}|-o|{10} -#default.recipe.cpp.o.pattern={0}{1}|{2}|{3}{4}|-DF_CPU={5}|-D{6}={7}|{8}|{9}|-o|{10} -#default.recipe.ar.pattern={0}{1}|{2}|{3}{4}|{5} -#default.recipe.c.combine.pattern={0}{1}|{2}|{3}{4}|-o|{5}{6}.elf|{7}|{8}|-L{9}|-lm -#default.recipe.objcopy.eep.pattern={0}{1}|{2}|{3}.elf|{4}.eep -#default.recipe.objcopy.hex.pattern={0}{1}|{2}|{3}.elf|{4}.hex - -########avr compile pattern ########## -#avr.recipe.c.o.pattern={0=compiler.path}{1=compiler.c.cmd}{2=compiler.c.flags}{3=compiler.cpudef}{4=build.mcu}-DF_CPU={5=build.f_cpu}-D{7=ARDUINO}={6=Base.REVISION}{7=-I/INCLUDE_PATHS} {8=SOURCE_NAME} -o{9=OBJECT_NAME} -#object name seems to have build path in it. -avr.recipe.c.o.pattern={0}{1}|{2}|{3}{4}|-DF_CPU={5}|-D{6}={7}|{8}|{9}|-o|{10} - - -##compile cc object files -#avr.recipe.cc.o.pattern={0=compiler.path}{1=compiler.cc.cmd}{2=compiler.c.flags}{3=compiler.cpudef}{4=build.mcu}-DF_CPU={5=build.f_cpu}-DARDUINO={6=Base.REVISION}{-7=I/INCLUDE_PATHS} {8=SOURCE_NAME} -o{9=BUILD_PATH}{10=OBJECT_NAME} -avr.recipe.cpp.o.pattern={0}{1}|{2}|{3}{4}|-DF_CPU={5}|-D{6}={7}|{8}|{9}|-o|{10} -##create archives -#avr.recipe.ar.pattern={0=compiler.path}{1=compiler.ar.cmd}{2=compiler.ar.flags}{3=BUILD_PATH}{4=CORE_NAME=core.a}{5=BUILD_PATH}{6=OBJECT_NAME} -avr.recipe.ar.pattern={0}{1}|{2}|{3}{4}|{5} - -##combine gc-sections| archives, and objects -#avr.recipe.c.combine.pattern={0=compiler.path}{1=compiler.c.cmd}{2=compiler.combine.flags}{3=compiler.cpudef}{4=build.mcu} -o {5=BUILD_PATH}{6=SOURCE_NAME}.elf {7=BUILD_PATH}{8=SOURCE_NAME}.o {9=BUILD_PATH}{10=CORE_NAME=core.a} -L{11=BUILD_PATH} -lm -#avr.recipe.c.combine.pattern={0}{1}|{2}|{3}{4}|-o|{5}{6}.elf|{7}{8}|{9}|-L{10}|-lm -avr.recipe.c.combine.pattern={0}{1}|{2}|{3}{4}|-o|{5}{6}.elf|{7}|{8}|-L{9}|-lm - -##create eeprom -#avr.recipe.objcopy.eep.pattern={0=compiler.path}{1=compiler.objcopy.cmd}{2=compiler.objcopy.eep.flags} {3=BUILD_PATH}{4=SOURCE_NAME}.elf {5=BUILD_PATH}{6=SOURCE_NAME}.eep -avr.recipe.objcopy.eep.pattern={0}{1}|{2}|{3}.elf|{4}.eep - -##create hex -#avr.recipe.objcopy.hex.pattern={0=compiler.path}{1=compiler.objcopy.cmd}{2=compiler.objcopy.elf.flags} {3=BUILD_PATH}{4=SOURCE_NAME}.elf {5=BUILD_PATH}{6=SOURCE_NAME}.hex -avr.recipe.objcopy.hex.pattern={0}{1}|{2}|{3}.elf|{4}.hex - - - -######################################################## -avr.name=avr -#avr.compiler.path Official default is correct, only need to change this if you want to overide the initial default -#avr.compiler.path={0}/hardware/tools/avr/bin/ -avr.compiler.c.cmd=avr-gcc -avr.compiler.c.flags=|-c|-g|-Os|-w|-ffunction-sections|-fdata-sections -avr.compiler.c.elf.flags=|-Os|-Wl,--gc-sections -avr.compiler.c.elf.cmd=avr-gcc -avr.compiler.S.flags=|-c|-g|-assembler-with-cpp -avr.compiler.cpp.cmd=avr-g++ -avr.compiler.cpp.flags=|-c|-g|-Os|-w|-fno-exceptions|-ffunction-sections|-fdata-sections -avr.compiler.ar.cmd=avr-ar -avr.compiler.ar.flags=rcs -avr.compiler.objcopy.cmd=avr-objcopy -avr.compiler.objcopy.eep.flags=|-O|ihex|-j|.eeprom|--set-section-flags=.eeprom=alloc,load|--no-change-warnings|--change-section-lma|.eeprom=0 -avr.compiler.elf2hex.flags=|-O|ihex|-R|.eeprom -avr.compiler.elf2hex.cmd=avr-objcopy -avr.compiler.ldflags= -avr.compiler.cpudef=-mmcu= -avr.compiler.upload.cmd= -avr.compiler.upload.flags= -avr.compiler.define=-DARDUINO= -avr.library.path=./hardware/avr/cores/arduino -avr.library.core.path=./libraries - diff --git a/programmers.txt b/programmers.txt index 466f602..02457d9 100644 --- a/programmers.txt +++ b/programmers.txt @@ -9,6 +9,10 @@ avrispmkii.protocol=stk500v2 usbtinyisp.name=USBtinyISP usbtinyisp.protocol=usbtiny +usbasp.name=USBasp +usbasp.communication=usb +usbasp.protocol=usbasp + parallel.name=Parallel Programmer parallel.protocol=dapa parallel.force=true @@ -17,4 +21,4 @@ parallel.force=true arduinoisp.name=Arduino as ISP arduinoisp.communication=serial arduinoisp.protocol=stk500v1 -arduinoisp.speed=19200 +arduinoisp.speed=9600 diff --git a/variants/eightanaloginputs/pins_arduino.h b/variants/eightanaloginputs/pins_arduino.h new file mode 100644 index 0000000..52b37ef --- /dev/null +++ b/variants/eightanaloginputs/pins_arduino.h @@ -0,0 +1,27 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#include "../standard/pins_arduino.h" +#undef NUM_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS 8 diff --git a/variants/leonardo/pins_arduino.h b/variants/leonardo/pins_arduino.h new file mode 100644 index 0000000..15afb4e --- /dev/null +++ b/variants/leonardo/pins_arduino.h @@ -0,0 +1,253 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include <avr/pgmspace.h> + +#define ARDUINO_MODEL_USB_PID 0x0034 + +#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0) +#define TXLED0 PORTD |= (1<<5) +#define TXLED1 PORTD &= ~(1<<5) +#define RXLED0 PORTB |= (1<<0) +#define RXLED1 PORTB &= ~(1<<0) + +const static uint8_t SDA = 2; +const static uint8_t SCL = 3; + +// Map SPI port to 'new' pins D14..D17 +const static uint8_t SS = 17; +const static uint8_t MOSI = 16; +const static uint8_t MISO = 14; +const static uint8_t SCK = 15; + +// Mapping of analog pins as digital I/O +// A6-A11 share with digital pins +const static uint8_t A0 = 18; +const static uint8_t A1 = 19; +const static uint8_t A2 = 20; +const static uint8_t A3 = 21; +const static uint8_t A4 = 22; +const static uint8_t A5 = 23; +const static uint8_t A6 = 24; // D4 +const static uint8_t A7 = 25; // D6 +const static uint8_t A8 = 26; // D8 +const static uint8_t A9 = 27; // D9 +const static uint8_t A10 = 28; // D10 +const static uint8_t A11 = 29; // D12 + +// __AVR_ATmega32U4__ has an unusual mapping of pins to channels +extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; +#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) + +#ifdef ARDUINO_MAIN + +// On the Arduino board, digital pins are also used +// for the analog output (software PWM). Analog input +// pins are a separate set. + +// ATMEL ATMEGA32U4 / ARDUINO LEONARDO +// +// D0 PD2 RXD1/INT2 +// D1 PD3 TXD1/INT3 +// D2 PD1 SDA SDA/INT1 +// D3# PD0 PWM8/SCL OC0B/SCL/INT0 +// D4 A6 PD4 ADC8 +// D5# PC6 ??? OC3A/#OC4A +// D6# A7 PD7 FastPWM #OC4D/ADC10 +// D7 PE6 INT6/AIN0 +// +// D8 A8 PB4 ADC11/PCINT4 +// D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5 +// D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6 +// D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7 +// D12 A11 PD6 T1/#OC4D/ADC9 +// D13# PC7 PWM10 CLK0/OC4A +// +// A0 D18 PF7 ADC7 +// A1 D19 PF6 ADC6 +// A2 D20 PF5 ADC5 +// A3 D21 PF4 ADC4 +// A4 D22 PF1 ADC1 +// A5 D23 PF0 ADC0 +// +// New pins D14..D17 to map SPI port to digital pins +// +// MISO D14 PB3 MISO,PCINT3 +// SCK D15 PB1 SCK,PCINT1 +// MOSI D16 PB2 MOSI,PCINT2 +// SS D17 PB0 RXLED,SS/PCINT0 +// +// TXLED PD5 +// RXLED PB0 +// HWB PE2 HWB + +// these arrays map port names (e.g. port B) to the +// appropriate addresses for various functions (e.g. reading +// and writing) +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &DDRB, + (uint16_t) &DDRC, + (uint16_t) &DDRD, + (uint16_t) &DDRE, + (uint16_t) &DDRF, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &PORTB, + (uint16_t) &PORTC, + (uint16_t) &PORTD, + (uint16_t) &PORTE, + (uint16_t) &PORTF, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) &PINB, + (uint16_t) &PINC, + (uint16_t) &PIND, + (uint16_t) &PINE, + (uint16_t) &PINF, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[30] = { + PD, // D0 - PD2 + PD, // D1 - PD3 + PD, // D2 - PD1 + PD, // D3 - PD0 + PD, // D4 - PD4 + PC, // D5 - PC6 + PD, // D6 - PD7 + PE, // D7 - PE6 + + PB, // D8 - PB4 + PB, // D9 - PB5 + PB, // D10 - PB6 + PB, // D11 - PB7 + PD, // D12 - PD6 + PC, // D13 - PC7 + + PB, // D14 - MISO - PB3 + PB, // D15 - SCK - PB1 + PB, // D16 - MOSI - PB2 + PB, // D17 - SS - PB0 + + PF, // D18 - A0 - PF7 + PF, // D19 - A1 - PF6 + PF, // D20 - A2 - PF5 + PF, // D21 - A3 - PF4 + PF, // D22 - A4 - PF1 + PF, // D23 - A5 - PF0 + + PD, // D24 / D4 - A6 - PD4 + PD, // D25 / D6 - A7 - PD7 + PB, // D26 / D8 - A8 - PB4 + PB, // D27 / D9 - A9 - PB5 + PB, // D28 / D10 - A10 - PB6 + PD, // D29 / D12 - A11 - PD6 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[30] = { + _BV(2), // D0 - PD2 + _BV(3), // D1 - PD3 + _BV(1), // D2 - PD1 + _BV(0), // D3 - PD0 + _BV(4), // D4 - PD4 + _BV(6), // D5 - PC6 + _BV(7), // D6 - PD7 + _BV(6), // D7 - PE6 + + _BV(4), // D8 - PB4 + _BV(5), // D9 - PB5 + _BV(6), // D10 - PB6 + _BV(7), // D11 - PB7 + _BV(6), // D12 - PD6 + _BV(7), // D13 - PC7 + + _BV(3), // D14 - MISO - PB3 + _BV(1), // D15 - SCK - PB1 + _BV(2), // D16 - MOSI - PB2 + _BV(0), // D17 - SS - PB0 + + _BV(7), // D18 - A0 - PF7 + _BV(6), // D19 - A1 - PF6 + _BV(5), // D20 - A2 - PF5 + _BV(4), // D21 - A3 - PF4 + _BV(1), // D22 - A4 - PF1 + _BV(0), // D23 - A5 - PF0 + + _BV(4), // D24 / D4 - A6 - PD4 + _BV(7), // D25 / D6 - A7 - PD7 + _BV(4), // D26 / D8 - A8 - PB4 + _BV(5), // D27 / D9 - A9 - PB5 + _BV(6), // D28 / D10 - A10 - PB6 + _BV(6), // D29 / D12 - A11 - PD6 +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[18] = { + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + TIMER0B, /* 3 */ + NOT_ON_TIMER, + TIMER3A, /* 5 */ + TIMER4D, /* 6 */ + NOT_ON_TIMER, + + NOT_ON_TIMER, + TIMER1A, /* 9 */ + TIMER1B, /* 10 */ + TIMER0A, /* 11 */ + + NOT_ON_TIMER, + TIMER4A, /* 13 */ + + NOT_ON_TIMER, + NOT_ON_TIMER, +}; + +const uint8_t PROGMEM analog_pin_to_channel_PGM[12] = { + 7, // A0 PF7 ADC7 + 6, // A1 PF6 ADC6 + 5, // A2 PF5 ADC5 + 4, // A3 PF4 ADC4 + 1, // A4 PF1 ADC1 + 0, // A5 PF0 ADC0 + 8, // A6 D4 PD4 ADC8 + 10, // A7 D6 PD7 ADC10 + 11, // A8 D8 PB4 ADC11 + 12, // A9 D9 PB5 ADC12 + 13, // A10 D10 PB6 ADC13 + 9 // A11 D12 PD6 ADC9 +}; + +#endif /* ARDUINO_MAIN */ +#endif /* Pins_Arduino_h */ diff --git a/variants/mega/pins_arduino.h b/variants/mega/pins_arduino.h index e3785e4..57ec97f 100644 --- a/variants/mega/pins_arduino.h +++ b/variants/mega/pins_arduino.h @@ -27,11 +27,20 @@ #include <avr/pgmspace.h> +#define NUM_DIGITAL_PINS 70 +#define NUM_ANALOG_INPUTS 16 +#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) +#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) + const static uint8_t SS = 53; const static uint8_t MOSI = 51; const static uint8_t MISO = 50; const static uint8_t SCK = 52; +const static uint8_t SDA = 20; +const static uint8_t SCL = 21; +const static uint8_t LED_BUILTIN = 13; + const static uint8_t A0 = 54; const static uint8_t A1 = 55; const static uint8_t A2 = 56; @@ -49,6 +58,31 @@ const static uint8_t A13 = 67; const static uint8_t A14 = 68; const static uint8_t A15 = 69; +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) +// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ + 0 ) ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ + ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ + ((uint8_t *)0) ) ) + +#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ + ( ((p) == 50) ? 3 : \ + ( ((p) == 51) ? 2 : \ + ( ((p) == 52) ? 1 : \ + ( ((p) == 53) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ + 0 ) ) ) ) ) ) + #ifdef ARDUINO_MAIN const uint16_t PROGMEM port_to_mode_PGM[] = { diff --git a/variants/micro/pins_arduino.h b/variants/micro/pins_arduino.h new file mode 100644 index 0000000..c9f25eb --- /dev/null +++ b/variants/micro/pins_arduino.h @@ -0,0 +1,27 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#include "../leonardo/pins_arduino.h" +#undef ARDUINO_MODEL_USB_PID +#define ARDUINO_MODEL_USB_PID 0x0035
\ No newline at end of file diff --git a/variants/standard/pins_arduino.h b/variants/standard/pins_arduino.h index 8fabb17..6e774d4 100644 --- a/variants/standard/pins_arduino.h +++ b/variants/standard/pins_arduino.h @@ -27,11 +27,25 @@ #include <avr/pgmspace.h> +#define NUM_DIGITAL_PINS 20 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) + +#if defined(__AVR_ATmega8__) +#define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) +#else +#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) +#endif + const static uint8_t SS = 10; const static uint8_t MOSI = 11; const static uint8_t MISO = 12; const static uint8_t SCK = 13; +const static uint8_t SDA = 18; +const static uint8_t SCL = 19; +const static uint8_t LED_BUILTIN = 13; + const static uint8_t A0 = 14; const static uint8_t A1 = 15; const static uint8_t A2 = 16; @@ -41,6 +55,11 @@ const static uint8_t A5 = 19; const static uint8_t A6 = 20; const static uint8_t A7 = 21; +#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0)) +#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) +#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) +#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) + #ifdef ARDUINO_MAIN // On the Arduino board, digital pins are also used |