aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boards.txt20
-rw-r--r--bootloaders/caterina/Caterina-Leonardo.hex1024
-rwxr-xr-xbootloaders/caterina/Caterina.c714
-rwxr-xr-xbootloaders/caterina/Caterina.h99
-rwxr-xr-xbootloaders/caterina/Descriptors.c262
-rwxr-xr-xbootloaders/caterina/Descriptors.h139
-rwxr-xr-xbootloaders/caterina/Makefile728
-rw-r--r--bootloaders/diskloader/DiskLoader-Leonardo.hex115
-rw-r--r--bootloaders/diskloader/Makefile105
-rw-r--r--bootloaders/diskloader/src/DiskLoader.cpp239
-rw-r--r--bootloaders/diskloader/src/Platform.h51
-rw-r--r--bootloaders/diskloader/src/USBCore.cpp510
-rw-r--r--bootloaders/diskloader/src/USBCore.h246
-rw-r--r--bootloaders/diskloader/src/USBDesc.cpp87
-rw-r--r--bootloaders/diskloader/src/USBDesc.h65
-rwxr-xr-xcores/arduino/Arduino.h1
-rw-r--r--cores/arduino/CDC.cpp106
-rw-r--r--cores/arduino/HID.cpp144
-rw-r--r--cores/arduino/HardwareSerial.cpp8
-rw-r--r--cores/arduino/HardwareSerial.h1
-rwxr-xr-xcores/arduino/Print.cpp5
-rwxr-xr-xcores/arduino/Print.h5
-rw-r--r--cores/arduino/Stream.cpp44
-rw-r--r--cores/arduino/Stream.h2
-rw-r--r--cores/arduino/USBAPI.h82
-rw-r--r--cores/arduino/USBCore.cpp34
-rw-r--r--cores/arduino/USBDesc.h4
-rw-r--r--[-rwxr-xr-x]cores/arduino/WInterrupts.c66
-rw-r--r--cores/arduino/WString.cpp4
-rw-r--r--[-rwxr-xr-x]cores/arduino/main.cpp2
-rw-r--r--[-rwxr-xr-x]cores/arduino/wiring.c11
-rw-r--r--cores/arduino/wiring_analog.c26
-rw-r--r--[-rwxr-xr-x]cores/arduino/wiring_digital.c18
-rwxr-xr-xcores/arduino/wiring_private.h2
-rw-r--r--libraries/EEPROM/examples/eeprom_read/eeprom_read.ino4
-rwxr-xr-xlibraries/Ethernet/Dhcp.cpp158
-rwxr-xr-xlibraries/Ethernet/Dhcp.h19
-rw-r--r--libraries/Ethernet/Ethernet.cpp38
-rw-r--r--libraries/Ethernet/Ethernet.h3
-rw-r--r--libraries/Ethernet/EthernetClient.cpp2
-rw-r--r--libraries/Ethernet/EthernetUdp.cpp73
-rw-r--r--libraries/Ethernet/EthernetUdp.h1
-rw-r--r--libraries/Ethernet/examples/ChatServer/ChatServer.ino44
-rw-r--r--libraries/Ethernet/examples/CosmClient/CosmClient.ino159
-rw-r--r--libraries/Ethernet/examples/CosmClientString/CosmClientString.ino146
-rw-r--r--libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino8
-rw-r--r--libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino9
-rw-r--r--libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino9
-rw-r--r--libraries/Ethernet/examples/PachubeClient/PachubeClient.ino83
-rw-r--r--libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino87
-rw-r--r--libraries/Ethernet/examples/TelnetClient/TelnetClient.ino8
-rw-r--r--libraries/Ethernet/examples/TwitterClient/TwitterClient.ino21
-rw-r--r--libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino7
-rw-r--r--libraries/Ethernet/examples/WebClient/WebClient.ino7
-rw-r--r--libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino110
-rw-r--r--libraries/Ethernet/examples/WebServer/WebServer.ino37
-rwxr-xr-xlibraries/Ethernet/utility/w5100.h6
-rw-r--r--libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Blink/Blink.ino2
-rw-r--r--libraries/LiquidCrystal/examples/Cursor/Cursor.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Display/Display.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Scroll/Scroll.ino3
-rw-r--r--libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino2
-rw-r--r--libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino3
-rw-r--r--libraries/LiquidCrystal/examples/setCursor/setCursor.ino3
-rw-r--r--libraries/SD/examples/CardInfo/CardInfo.ino8
-rw-r--r--libraries/SD/examples/Datalogger/Datalogger.ino8
-rw-r--r--libraries/SD/examples/DumpFile/DumpFile.ino9
-rw-r--r--libraries/SD/examples/Files/Files.ino8
-rw-r--r--libraries/SD/examples/ReadWrite/ReadWrite.ino8
-rw-r--r--libraries/SD/examples/listfiles/listfiles.ino8
-rw-r--r--libraries/SD/utility/Sd2PinMap.h63
-rw-r--r--libraries/SD/utility/SdFatUtil.h2
-rw-r--r--libraries/SPI/SPI.cpp27
-rwxr-xr-xlibraries/Servo/Servo.cpp4
-rw-r--r--libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino36
-rw-r--r--libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino25
-rw-r--r--libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino5
-rwxr-xr-xlibraries/Wire/Wire.cpp43
-rwxr-xr-xlibraries/Wire/Wire.h5
-rw-r--r--libraries/Wire/utility/twi.c75
-rwxr-xr-xlibraries/Wire/utility/twi.h4
-rw-r--r--platform.txt38
-rw-r--r--variants/leonardo/pins_arduino.h45
-rw-r--r--variants/mega/pins_arduino.h46
-rw-r--r--variants/micro/pins_arduino.h27
-rw-r--r--variants/standard/pins_arduino.h36
87 files changed, 4672 insertions, 1888 deletions
diff --git a/boards.txt b/boards.txt
index af2ad8e..85a9bf3 100644
--- a/boards.txt
+++ b/boards.txt
@@ -7,10 +7,15 @@ uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
+
uno.bootloader.tool=avrdude
-uno.bootloader.erase.params=-e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xde:m -Ulfuse:w:0xff:m
-uno.bootloader.write.params=-Uflash:w:{bootloader.file}:i -Ulock:w:0x0F:m
-uno.bootloader.file={runtime.ide.path}/hardware/arduino/avr/optiboot/optiboot_atmega328.hex
+uno.bootloader.low_fuses=0xFF
+uno.bootloader.high_fuses=0xDE
+uno.bootloader.extended_fuses=0x05
+uno.bootloader.unlock_bits=0x3F
+uno.bootloader.lock_bits=0x0F
+uno.bootloader.file=optiboot/optiboot_atmega328.hex
+
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
@@ -145,23 +150,28 @@ mega.build.variant=mega
##############################################################
leonardo.name=Arduino Leonardo
+leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
+leonardo.upload.use_1200bps_touch=true
+
+leonardo.bootloader.tool=avrdude
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
-leonardo.bootloader.path=caterina
-leonardo.bootloader.file=Caterina-Leonardo.hex
+leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F
+
leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.core=arduino
leonardo.build.variant=leonardo
+leonardo.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid}
##############################################################
diff --git a/bootloaders/caterina/Caterina-Leonardo.hex b/bootloaders/caterina/Caterina-Leonardo.hex
new file mode 100644
index 0000000..de7b53c
--- /dev/null
+++ b/bootloaders/caterina/Caterina-Leonardo.hex
@@ -0,0 +1,1024 @@
+:200000000C946E010C9496010C9496010C9496010C9496010C9496010C9496010C94960150
+:200020000C9496010C9496010C9410050C949B050C9496010C9496010C9496010C94960181
+:200040000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C94B501C9
+:200060000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C949601C8
+:200080000C9496010C9496010C9496010C9496010C9496010C9496010C9496010C949601A8
+:2000A0000C9496010C9496010C94960100000000240027002A002D003000000000002500A4
+:2000C00028002B002E003100000000002300260029002C002F00040404040403040502027D
+:2000E0000202040302020202060606060606040402020204040802011040804010204080A8
+:200100004080080204018040201002011080102040400000000200080E0000030401000BB2
+:200120000000070605040100080A0B0C0D09040309042203410072006400750069006E00CD
+:200140006F0020004C0065006F006E006100720064006F00180341007200640075006900CC
+:200160006E006F0020004C004C004300120100020000004041233680000101020001120120
+:200180000002020000404123368000010102000100C18081C1080B00020202010009040052
+:2001A000000102020000052400100105240101010424020605240600010705810310004094
+:2001C00009040100020A000000070502024000000705830240000005010902A1010901A186
+:2001E000008501050919012903150025019503750181029501750581030501093009310943
+:20020000381581257F750895038106C0C005010906A1018502050719E029E715002501754D
+:20022000019508810295017508810395067508150025650507190029658100C0090402004C
+:2002400001030000000921010100012265000705840340000100000000000000002A2B2895
+:200260000000000000000000000000000000000000000000002C9EB4A0A1A2A434A6A7A553
+:20028000AE362D3738271E1F20212223242526B333B62EB7B89F8485868788898A8B8C8D58
+:2002A0008E8F909192939495969798999A9B9C9D2F3130A3AD350405060708090A0B0C0D7C
+:2002C0000E0F101112131415161718191A1B1C1DAFB1B0B500004C042E072C0811241FBE36
+:2002E000CFEFDAE0DEBFCDBF11E0A0E0B1E0EEECF2E102C005900D92AC32B107D9F711E061
+:20030000ACE2B1E001C01D92AD39B107E1F712E0CCEDD2E004C02297FE010E946109C63DF0
+:20032000D107C9F70E9486030C9465090C9400008091000161E00E94530364E873E080E002
+:2003400090E00E94FD018091000160E00E9453036CE474E080E090E00E94FD010895809181
+:20036000000161E00E94B60208951F920F920FB60F9211242F933F938F939F93AF93BF93DB
+:200380008091300190913101A0913201B0913301309134010196A11DB11D232F2D5F2D3794
+:2003A00020F02D570196A11DB11D209334018093300190933101A0933201B0933301809117
+:2003C0002C0190912D01A0912E01B0912F010196A11DB11D80932C0190932D01A0932E01BA
+:2003E000B0932F01BF91AF919F918F913F912F910F900FBE0F901F9018959B01AC017FB734
+:20040000F89480912C0190912D01A0912E01B0912F0166B5A89B05C06F3F19F00196A11DC3
+:20042000B11D7FBFBA2FA92F982F8827860F911DA11DB11D62E0880F991FAA1FBB1F6A9577
+:20044000D1F7BC012DC0FFB7F89480912C0190912D01A0912E01B0912F01E6B5A89B05C0E7
+:20046000EF3F19F00196A11DB11DFFBFBA2FA92F982F88278E0F911DA11DB11DE2E0880FFD
+:20048000991FAA1FBB1FEA95D1F7861B970B885E9340C8F2215030404040504068517C4F8F
+:2004A000211531054105510571F60895789484B5826084BD84B5816084BD85B5826085BD0F
+:2004C00085B5816085BDEEE6F0E0808181608083E1E8F0E010828081826080838081816043
+:2004E0008083E0E8F0E0808181608083E1EBF0E0808184608083E0EBF0E080818160808378
+:20050000E1E9F0E0808182608083808181608083E0E9F0E0808181608083E1ECF0E080815A
+:2005200084608083808182608083808181608083E3ECF0E0808181608083E0ECF0E08081E8
+:2005400082608083E2ECF0E0808181608083EAE7F0E08081846080838081826080838081C3
+:20056000816080838081806880830895CF93DF93482F50E0CA018C509F4FFC0134914A52A0
+:200580005F4FFA018491882369F190E0880F991FFC01E455FF4FA591B491FC01E654FF4F55
+:2005A000C591D491662351F42FB7F8948C91932F909589238C93888189230BC0623061F40A
+:2005C0002FB7F8948C91932F909589238C938881832B88832FBF06C09FB7F8948C91832BB7
+:2005E0008C939FBFDF91CF9108958730C1F1883080F48330F9F0843030F4813029F182308B
+:2006000009F050C024C08430C9F0863009F04AC022C08A3091F18B3030F4883031F1893037
+:2006200009F040C026C08C3091F18C3060F18E30C9F533C0809180008F7703C08091800036
+:200640008F7D80938000089584B58F7702C084B58F7D84BD08958091B0008F7703C080919F
+:20066000B0008F7D8093B0000895809190008F7707C0809190008F7D03C080919000877FD9
+:200680008093900008958091C0008F7703C08091C0008F7D8093C00008958091C200877F5A
+:2006A0008093C2000895FF920F931F93F62E482F50E0CA018E5E9E4FFC012491CA018C501B
+:2006C0009F4FFC0114914A525F4FFA0104910023C9F0222319F0822F0E94F502E02FF0E05D
+:2006E000EE0FFF1FE654FF4FA591B4919FB7F894FF2021F48C911095812302C08C91812BD5
+:200700008C939FBF1F910F91FF900895CF93DF930E9456028DE391E00E944D040E94AF01EC
+:20072000C0E0D0E00E9498012097E1F30E940000F9CF282F809137018823C1F057FF1AC00D
+:2007400015C02898909336018091F1008193E217F307B9F74115510539F08091F20088236E
+:2007600019F48BE68093E800AFBF02C04FEF5FEFCA010895AFB7F89427702093E9008091A6
+:20078000F200282F30E0241735070CF4A901FB019B01240F311D94E6DACFDF93CF930F922E
+:2007A000CDB7DEB7BE016F5F7F4F41E050E00E949903019719F02FEF3FEF03C08981282F25
+:2007C00030E0C9010F90CF91DF910895FF920F931F93F82E142F052F40913A0150913B0188
+:2007E000212F302FC901DC01FB016EEF29C0F7FE02C0949101C090812091380130913901CE
+:2008000024173507ACF48091E8008570E1F38091E80082FF03C02FEF3FEF17C09093F1008B
+:20082000C90101968F739070892B11F46093E8002F5F3F4F3093390120933801119731964D
+:200840001097A9F6812F902F9C01C9011F910F91FF9008959C018091E80082FFFCCFF90124
+:20086000260F311D03C08091F1008193E217F307D1F7289884E6809336018BEF8093E80078
+:20088000CB0108958093E9008091F200882319F08AE38093E800089508951092370181E05F
+:2008A0008093D70080EA8093D80082E189BD09B400FEFDCF61E070E080E090E00E94FD01C8
+:2008C00080E98093D8008CE08093E2001092E000559A209A08955F926F927F928F929F9246
+:2008E000AF92BF92CF92DF92EF92FF920F931F93CF93DF93E82E842E752E809137018823FB
+:2009000071F18B01242F352FC901EC017AEFF72E67E0962E9E2050E4552E8E2D90E040E220
+:20092000A42EB12CA822B9223AE3632E20E4C22ED12CC822D92258C09FB7F8949092E900DA
+:200940008091E80085FD02C020E004C08091F200252D281B9FBF222361F4FA9419F42FEF4D
+:200960003FEF4DC061E070E080E090E00E94FD013BC0822F90E0C817D9070CF42C2FC21B28
+:20098000D1094FB7F8949092E900A114B10421F406C01092F10021502223D9F719C0E7FCC6
+:2009A00003C0F801922F10C0C801322F06C0FC010196E491E093F10031503323C1F706C038
+:2009C00081918093F10091509923D1F7020F111D8091E80085FF05C0209729F4C114D1049D
+:2009E00011F06092E8004FBF209709F0A5CF5D9884E680933501282D372DC9019C01C90158
+:200A0000DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F907F906F905F90089564
+:200A20001F920F920FB60F9211241F932F933F934F935F936F937F938F939F93AF93BF93B3
+:200A4000EF93FF938091E1001092E100982F83FF0FC01092E90081E08093EB001092EC007D
+:200A600082E38093ED001092370188E08093F00092FF36C083E08093E9008091F200882338
+:200A800049F08AE38093E80005C082E891E00E94710701C012E09FB7F8941093E9008091C9
+:200AA000F2009FBF882389F780913501882351F08091350181508093350180913501882335
+:200AC00009F45D9A80913601882351F08091360181508093360180913601882309F4289AD9
+:200AE000FF91EF91BF91AF919F918F917F916F915F914F913F912F911F910F900FBE0F90DB
+:200B00001F9018950F931F93DF93CF930F92CDB7DEB719828E010F5F1F4FC8010E9490078F
+:200B2000C8010E942909898190E00F90CF91DF911F910F9108951F920F920FB60F92112455
+:200B4000EF92FF921F932F933F934F935F936F937F938F939F93AF93BF93EF93FF93DF93E7
+:200B6000CF93CDB7DEB76197DEBFCDBF1092E9008091E80083FF0FC1FE0131969E01275F18
+:200B80003F4F03C08091F1008193E217F307D1F7289884E68093360182EF8093E800998139
+:200BA00097FF05C08091E80080FFFCCF03C08EEF8093E800292F30E0C90180769070892B80
+:200BC00009F0C2C08A81882329F41092F1001092F100D6C0813009F4D3C0833009F4D0C08A
+:200BE000853049F48091E80080FFFCCF8B8180688093E300C5C0863009F07CC01C81EF805A
+:200C0000F8841230C1F51092E900109239011092380110923B0110923A010E94820599E0C1
+:200C2000FE013996DF01292F1D922A95E9F799871A8791E09E8790E8988B9AEF998B209110
+:200C4000380130913901275F3F4F3C872B878D871092E9001092390110923801F0923B01C3
+:200C6000E0923A0180E0BF0149E050E00E94E6030E94820585C01092E9001092390110924C
+:200C80003801F0923B01E0923A01123241F482E290E00E942109892B09F476C071C011303E
+:200CA00079F488E0E816F10419F481E080933C0180913C01882309F06BC0ECE6F1E013C01B
+:200CC000133009F061C08B81882319F4EEE2F1E00AC0823019F4E2E3F1E005C0813009F0C4
+:200CE00053C0E4E5F1E0449180E8BF0150E00E94E60346C0873009F447C0883021F481E0A0
+:200D00008093F1003DC08930D9F523703070232BD9F5E1E9F1E091E031E026E39093E900CA
+:200D20003093EB0084918093EC002093ED009F5F3196953099F78EE78093EA001092EA0039
+:200D40008B81809337011CC08F8198851092E900109239011092380190933B0180933A0144
+:200D60008D81882329F4CE0101960E949C0706C0823051F4CE0101960E94F207882321F078
+:200D80008EEF8093E80007C081E28093EB0003C0EEE7F1E0A8CF6196DEBFCDBFCF91DF91E3
+:200DA000FF91EF91BF91AF919F918F917F916F915F914F913F912F911F91FF90EF900F9076
+:200DC0000FBE0F901F90189520917E0130917F018091800190918101281B390B2F733070DC
+:200DE000C901089520917E0130917F0180918001909181012817390719F42FEF3FEF09C045
+:200E0000E0918001F0918101E25CFE4F8081282F30E0C901089520917E0130917F01809101
+:200E20008001909181012817390719F42FEF3FEF13C0E0918001F0918101E25CFE4F2081C2
+:200E4000809180019091810101968F739070909381018093800130E0C901089510928501EC
+:200E60001092840188EE93E0A0E0B0E08093860190938701A0938801B093890180E191E0B2
+:200E8000909383018093820108950F931F93DF93CF930F92CDB7DEB78C0169838091090102
+:200EA000882369F083E0BE016F5F7F4F41E050E00E946B041816190614F49C0107C081E0F4
+:200EC00090E0F8019383828320E030E0C9010F90CF91DF911F910F91089583E00E9442040D
+:200EE000089582E00E94CD03482F20917E0130917F012F5F3F4F2F73307080918001909188
+:200F000081012817390759F0E0917E01F0917F01E25CFE4F408330937F0120937E01089536
+:200F2000FC0180818E5F808380E865E971E042E450E00E94E6030895FC0181819081913A63
+:200F400059F4813209F04CC080E062E071E047E050E00E94E60342C0913209F041C0803246
+:200F600039F482E091E067E070E00E942A0436C0823209F035C0828180930901809102013E
+:200F800090910301A0910401B0910501805B9440A040B04019F58091090180FD12C087E74A
+:200FA00097E790930108809300082BE088E190E00FB6F894A895809360000FBE20936000A7
+:200FC0000DC088E10FB6F89480936000109260000FBEA895109201081092000881E00895B8
+:200FE00080E00895FC0191818081813A31F4913089F080E0933089F40DC0813269F49B3082
+:2010000021F4828180930A0105C09A3029F4828180930B0181E0089580E00895EF92FF92BF
+:201020000F931F938C01E62EDC01ED91FC910480F581E02D0995F82ED801ED91FC9106809E
+:20104000F781E02DC8016E2D09958F2D90E01F910F91FF90EF900895109290011092940178
+:201060001092930182E291E090939201809391010895EF92FF920F931F93DF93CF930F9292
+:20108000CDB7DEB789838B017A0184E0BE016F5F7F4F41E050E00E946B0484E4B801A7013A
+:2010A0000E946B040F90CF91DF911F910F91FF90EF90089582E048E050E00E94390808957B
+:2010C000FC0116821782108611861286138614823496BF010E945A080895DC01683810F046
+:2010E000685829C0E62FF0E067FF13C0E058F04081E090E002C0880F991FEA95E2F7809572
+:2011000014962C911497282314962C93149760E012C0EB5AFD4F6491662319F420E030E020
+:201120001DC067FF08C014968C9114978D7F14968C9314976F77FD0190E0662321F08681BD
+:20114000861709F416829F5F31969630B1F7CD011496BD010E945A0821E030E0C901089578
+:20116000CF93DF93DC01683810F0685825C0E62FF0E067FF12C0E058F04081E090E002C061
+:20118000880F991FEA95E2F714962C911497282B14962C93149760E00FC0EB5AFD4F64919A
+:2011A0006623D9F167FF08C014968C911497826014968C9314976F7716968C9116978617ED
+:2011C000A9F117968C911797861781F118968C911897861759F119968C911997861731F152
+:2011E0001A968C911A97861709F11B968C911B978617E1F0ED01E0E0F0E09E2F8E818823E7
+:2012000021F4EA0FFB1F668306C09F5F31962196E630F10591F7963049F481E090E013966A
+:201220009C938E93129720E030E007C0CD011496BD010E945A0821E030E0C901DF91CF91F9
+:20124000089580E867ED71E045E650E00E94E6030895FC0180818F5F808380E86CE372E069
+:2012600049E150E00E94E6030895CF92DF92EF92FF920F931F93CF93DF937C016B018A016C
+:20128000C0E0D0E00FC0D6016D916D01D701ED91FC910190F081E02DC7010995C80FD91FC5
+:2012A000015010400115110571F7CE01DF91CF911F910F91FF90EF90DF90CF900895EE0F94
+:2012C000FF1F0590F491E02D0994F894FFCF0D0000E1000000000000010100000000450796
+:2012E0003509E4060B07F2066D077107000000000E083509B0086D086008FFFFFFFFFFFFED
+:20130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:20132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:20134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:20136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:20138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:2013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:2013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:2013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:20140000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:20142000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:20144000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:20146000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:20148000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:2014A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:2014C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:2014E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:20150000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:20152000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:20154000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:20156000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:20158000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:2015A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:2015C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:2015E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:20160000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:20162000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:20164000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:20166000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:20168000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:2016A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:2016C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:2016E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:20170000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:20172000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:20174000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:20176000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:20178000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:2017A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:2017C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:2017E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:20180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:20182000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:20184000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:20186000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:20188000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:2018A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:2018C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:2018E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:20190000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:20192000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:20194000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:20196000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:20198000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:2019A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:2019C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:2019E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:201A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:201A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:201A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:201A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:201A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:201AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:201AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:201AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:201B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:201B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:201B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:201B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:201B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:201BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:201BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:201BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:201C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:201C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:201C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:201C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:201C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:201CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:201CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:201CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:201D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:201D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:201D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:201D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:201D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:201DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:201DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:201DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:201E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:201E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:201E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:201E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:201E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:201EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:201EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:201EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:201F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:201F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:201F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:201F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:201F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:201FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:201FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:201FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:20200000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:20202000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:20204000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:20206000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:20208000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:2020A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:2020C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:2020E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:20210000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:20212000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:20214000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:20216000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:20218000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:2021A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:2021C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:2021E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:20220000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:20222000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:20224000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:20226000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:20228000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:2022A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:2022C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:2022E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:20230000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:20232000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:20234000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:20236000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:20238000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:2023A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:2023C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:2023E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:20240000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:20242000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:20244000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:20246000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:20248000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:2024A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:2024C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:2024E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:20250000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:20252000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:20254000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:20256000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:20258000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:2025A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:2025C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:2025E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:20260000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:20262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:20264000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:20266000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:20268000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:2026A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:2026C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:2026E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:20270000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:20272000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:20274000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:20276000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:20278000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:2027A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:2027C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:2027E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:20280000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:20282000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:20284000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:20286000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:20288000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:2028A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:2028C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:2028E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:20290000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:20292000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:20294000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:20296000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:20298000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:2029A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:2029C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:2029E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:202A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:202A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:202A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:202A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:202A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:202AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:202AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:202AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:202B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:202B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:202B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:202B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:202B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:202BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:202BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:202BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:202C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:202C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:202C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:202C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:202C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:202CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:202CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:202CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:202D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:202D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:202D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:202D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:202D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:202DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:202DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:202DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:202E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:202E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:202E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:202E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:202E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:202EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:202EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:202EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:202F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:202F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:202F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:202F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:202F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:202FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:202FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:202FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:20300000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:20302000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:20304000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:20306000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:20308000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:2030A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:2030C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:2030E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:20310000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:20312000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:20314000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:20316000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:20318000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:2031A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:2031C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:2031E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:20320000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:20322000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:20324000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:20326000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:20328000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:2032A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:2032C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:2032E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:20330000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:20332000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:20334000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:20336000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:20338000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:2033A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:2033C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:2033E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:20340000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:20342000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:20344000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:20346000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:20348000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:2034A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:2034C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:2034E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:20350000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:20352000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:20354000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:20356000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:20358000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:2035A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:2035C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:2035E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:20360000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:20362000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:20364000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:20366000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:20368000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:2036A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:2036C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:2036E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:20370000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:20372000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:20374000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:20376000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:20378000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:2037A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:2037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:2037E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:20380000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:20382000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:20384000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:20386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:20388000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:2038A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:2038C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:2038E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:20390000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:20392000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:20394000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:20396000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:20398000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:2039A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:2039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:2039E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:203A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:203A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:203A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:203A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:203A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:203AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:203AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:203AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:203B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:203B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:203B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:203B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:203B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:203BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:203BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:203BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:203C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:203C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:203C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:203C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:203C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:203CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:203CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:203CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:203D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:203D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:203D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:203D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:203D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:203DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:203DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:203DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:203E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:203E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:203E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:203E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:203E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:203EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:203EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:203EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:203F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:203F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:203F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:203F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:203F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:203FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:203FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:203FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:20400000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:20402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:20404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:20406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:20408000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:2040A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:2040C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:2040E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:20410000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:20412000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:20414000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:20416000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:20418000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:2041A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:2041C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:2041E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:20420000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:20422000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:20424000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:20426000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:20428000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:2042A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:2042C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:2042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:20430000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:20432000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:20434000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:20436000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:20438000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:2043A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:2043C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:2043E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:20440000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:20442000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:20444000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:20446000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:20448000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:2044A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:2044C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:2044E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:20450000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:20452000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:20454000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:20456000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:20458000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:2045A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:2045C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:2045E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:20460000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:20462000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:20464000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:20466000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:20468000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:2046A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:2046C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:2046E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:20470000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:20472000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:20474000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:20476000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:20478000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:2047A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:2047C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:2047E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:20480000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:20482000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:20484000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:20486000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:20488000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:2048A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:2048C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:2048E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:20490000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:20492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:20494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:20496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:20498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:2049A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:2049C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:2049E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:204A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:204A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:204A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:204A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:204A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:204AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:204AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:204AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:204B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:204B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:204B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:204B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:204B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:204BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:204BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:204BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:204C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:204C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:204C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:204C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:204C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:204CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:204CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:204CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:204D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:204D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:204D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:204D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:204D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:204DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:204DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:204DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:204E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:204E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:204E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:204E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:204E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:204EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:204EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:204EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:204F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:204F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:204F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:204F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:204F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:204FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:204FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:204FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:20500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
+:20502000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
+:20504000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
+:20506000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
+:20508000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
+:2050A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
+:2050C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+:2050E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:20510000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
+:20512000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
+:20514000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
+:20516000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
+:20518000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
+:2051A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
+:2051C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
+:2051E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
+:20520000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
+:20522000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
+:20524000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
+:20526000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
+:20528000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
+:2052A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
+:2052C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
+:2052E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
+:20530000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
+:20532000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
+:20534000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
+:20536000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
+:20538000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
+:2053A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
+:2053C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
+:2053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
+:20540000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC
+:20542000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C
+:20544000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C
+:20546000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C
+:20548000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C
+:2054A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C
+:2054C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+:2054E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC
+:20550000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB
+:20552000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B
+:20554000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B
+:20556000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B
+:20558000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B
+:2055A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B
+:2055C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+:2055E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+:20560000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA
+:20562000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A
+:20564000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A
+:20566000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A
+:20568000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A
+:2056A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A
+:2056C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA
+:2056E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA
+:20570000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9
+:20572000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89
+:20574000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69
+:20576000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49
+:20578000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29
+:2057A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:2057C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+:2057E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9
+:20580000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8
+:20582000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88
+:20584000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:20586000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+:20588000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28
+:2058A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08
+:2058C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8
+:2058E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8
+:20590000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7
+:20592000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:20594000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:20596000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:20598000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27
+:2059A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:2059C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7
+:2059E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7
+:205A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6
+:205A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86
+:205A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:205A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46
+:205A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26
+:205AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06
+:205AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6
+:205AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
+:205B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5
+:205B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85
+:205B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65
+:205B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:205B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:205BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:205BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
+:205BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
+:205C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4
+:205C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:205C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:205C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:205C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24
+:205CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04
+:205CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4
+:205CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+:205D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3
+:205D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83
+:205D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63
+:205D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43
+:205D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23
+:205DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03
+:205DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3
+:205DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3
+:205E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2
+:205E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82
+:205E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62
+:205E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:205E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:205EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:205EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
+:205EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
+:205F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1
+:205F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81
+:205F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61
+:205F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
+:205F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
+:205FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01
+:205FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+:205FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1
+:20600000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
+:20602000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
+:20604000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
+:20606000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
+:20608000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
+:2060A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+:2060C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
+:2060E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
+:20610000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
+:20612000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
+:20614000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
+:20616000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
+:20618000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
+:2061A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+:2061C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
+:2061E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+:20620000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
+:20622000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
+:20624000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
+:20626000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
+:20628000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
+:2062A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+:2062C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
+:2062E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
+:20630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
+:20632000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
+:20634000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
+:20636000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
+:20638000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
+:2063A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
+:2063C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
+:2063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
+:20640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
+:20642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
+:20644000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
+:20646000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
+:20648000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
+:2064A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+:2064C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
+:2064E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
+:20650000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
+:20652000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
+:20654000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
+:20656000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
+:20658000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
+:2065A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+:2065C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
+:2065E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
+:20660000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
+:20662000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
+:20664000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
+:20666000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
+:20668000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
+:2066A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+:2066C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
+:2066E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:20670000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
+:20672000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
+:20674000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
+:20676000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
+:20678000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:2067A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
+:2067C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
+:2067E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
+:20680000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98
+:20682000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78
+:20684000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:20686000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38
+:20688000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18
+:2068A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+:2068C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8
+:2068E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8
+:20690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:20692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:20694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:20696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:20698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:2069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+:2069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7
+:2069E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7
+:206A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96
+:206A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76
+:206A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56
+:206A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36
+:206A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16
+:206AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+:206AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6
+:206AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6
+:206B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95
+:206B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75
+:206B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:206B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:206B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:206BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:206BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
+:206BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5
+:206C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:206C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:206C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:206C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:206C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14
+:206CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+:206CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4
+:206CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4
+:206D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93
+:206D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73
+:206D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53
+:206D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33
+:206D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13
+:206DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
+:206DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3
+:206DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3
+:206E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:206E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72
+:206E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:206E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:206E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:206EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:206EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
+:206EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2
+:206F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91
+:206F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71
+:206F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51
+:206F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31
+:206F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11
+:206FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1
+:206FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1
+:206FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1
+:2070000055C000006EC000006CC000006AC0000068C0000066C0000064C0000062C0000043
+:2070200060C000005EC00000EEC400005AC0000058C0000056C0000054C0000052C00000F2
+:2070400050C0000078C000004CC000004AC0000048C0000046C0000044C0000042C00000BE
+:2070600040C000003EC000003CC000003AC0000038C0000036C0000034C0000032C0000048
+:2070800030C000002EC000002CC000002AC0000028C0000026C0000024C0000022C00000A8
+:2070A00020C000001EC000001CC0000011241FBECFEFDAE0DEBFCDBF11E0A0E0B1E0EAE2B5
+:2070C000FFE702C005900D92A83AB107D9F711E0A8EAB1E001C01D92AE3BB107E1F78FD30B
+:2070E00022C78ECFF89410926F0010928100109285001092840081E085BF15BE47985D9AEF
+:20710000289A0C94000008952091B2013091B3012F5F3F4F3093B3012093B201932F37FFA6
+:2071200003C08EEF831B982F990F921710F447980895479A08951F920F920FB60F9211246E
+:207140002F938F939F93EF93FF9310928500109284008091A8019091A901009741F00197D3
+:207160009093A9018093A801892B09F45D9A8091AA019091AB01009741F001979093AB0126
+:207180008093AA01892B09F4289AE0E0F0E0859194918F5F9F4F49F08091AC019091AD0151
+:2071A00001969093AD018093AC01FF91EF919F918F912F910F900FBE0F901F90189584E0BC
+:2071C0008093E9000DC08091E8008B778093E80003C08EB3882351F08091E80082FFF9CFBE
+:2071E0008091E80085FFEFCF8091F1000895982F83E08093E9008091E80085FD0DC0809136
+:20720000E8008E778093E80003C08EB3882369F08091E80080FFF9CF9093F1005D9884E6CB
+:2072200090E09093A9018093A80108954F925F926F927F928F929F92AF92BF92CF92DF921E
+:20724000EF92FF920F931F93CF93DF9384E08093E9008091E80082FF57C2289884E690E067
+:207260009093AB018093AA01AADF182F853481F48CE49DE19093AD018093AC0107B600FC4B
+:20728000FDCFF999FECF81E180935700E89503C0843519F494DF8DE00DC28C34E1F38035F9
+:2072A000D1F3843721F484E4A2DF80E003C2813611F489E5FFC18134B1F481DF182F7FDFE3
+:2072C00090E0880F991FAA2797FDA095BA2F312F330F20E0442737FD4095542F822B932B68
+:2072E000A42BB52BB8C1803711F483E5E3C1833549F4C0E0D1E089917ADF21E0C730D20714
+:20730000D1F7D9C1863521F481E371DF80E3D2C1833731F487E86BDF85E969DF8EE1CAC149
+:207320008536B9F4E0E0F0E093E085E090935700E89507B600FCFDCF80935700E89507B65D
+:2073400000FCFDCFE058FF4FA0E7E030FA0771F7A2CF823739F4E1E0F0E089E08093570024
+:207360008491A8C1863439F4E0E0F0E089E08093570084919FC18E3439F4E3E0F0E089E0E5
+:2073800080935700849196C1813539F4E2E0F0E089E08093570084918DC1823631F489E521
+:2073A00026DF80E024DF80E885C1823419F0873609F0E5C01092AD011092AC0100DF082FE8
+:2073C000FEDEF82EFCDE682E8554823008F071C1902F80E0CF2DD0E0C82BD92B10926F00B3
+:2073E000173609F04BC081E180935700E895DD24CC24C3943FC0E090AE01F090AF010091CC
+:20740000B0011091B101B6E46B16D9F4ED2DF0E0EE29FF29E4918E2FEADEDD2081F082E08D
+:2074200090E0A0E0B0E0E80EF91E0A1F1B1FE092AE01F092AF010093B0011093B101DC2470
+:2074400018C0D801C701B695A7959795879555D5CEDE82E090E0A0E0B0E0E80EF91E0A1FF6
+:207460001B1FE092AE01F092AF010093B0011093B1012197209709F0BECF7DC08090AE01F5
+:207480009090AF01A090B001B090B10196E4691609F05DC083E0F40180935700E89507B63E
+:2074A00000FCFDCF54C0F6E46F1661F5772031F1E090AE01F090AF010091B0011091B1019E
+:2074C0007EDED82ECC24852D90E08C299D29F7010C0140925700E895112482E090E0A0E08B
+:2074E000B0E0E80EF91E0A1F1B1FE092AE01F092AF010093B0011093B10102C060DE582E1A
+:20750000742423C0E090AE01F090AF010091B0011091B10116950795F794E79450DE682FFA
+:20752000C701F3D48091AE019091AF01A091B001B091B1010296A11DB11D8093AE0190934D
+:20754000AF01A093B001B093B101219704C05524772444244394209709F0A5CF96E46916B6
+:2075600041F485E0F40180935700E89507B600FCFDCF8DE03CDE82E080936F009CC0833492
+:2075800071F40091AE011091AF0119DE90E021E0F8010C0120935700E89511247CCE8336C8
+:2075A00019F5E090AE01F090AF010091B0011091B10105DEF701E16090E021E00C0120938C
+:2075C0005700E895112482E090E0A0E0B0E0E80EF91E0A1F1B1FE092AE01F092AF0100936A
+:2075E000B0011093B10157CE8D3661F4E091AE01F091AF0185E080935700E89507B600FCF2
+:20760000FDCF49CE823551F4E091AE01F091AF0105911491812FEBDD802F4CC0843421F5FE
+:20762000E090AE01F090AF010091B0011091B10116950795F794E794C2DD682FC70165D4E2
+:207640008091AE019091AF01A091B001B091B1010296A11DB11D8093AE019093AF01A093D8
+:20766000B001B093B10117CE843609F5E090AE01F090AF010091B0011091B101D801C70142
+:20768000B695A7959795879538D4B1DD82E090E0A0E0B0E0E80EF91E0A1F1B1FE092AE010E
+:2076A000F092AF010093B0011093B10104C08B3111F08FE39CDD83E08093E9009091E8002B
+:2076C0008091E8008E778093E80095FF04C010C08EB38823C9F08091E80080FFF9CF809193
+:2076E000E8008E778093E80003C08EB3882361F08091E80080FFF9CF84E08093E9008091F1
+:20770000E8008B778093E800DF91CF911F910F91FF90EF90DF90CF90BF90AF909F908F90AC
+:207720007F906F905F904F9008959091B601892F8F77813249F58091B7018032A1F081328A
+:2077400019F5913A09F58091E800877F8093E8008DE091E067E070E007D28091E8008B770F
+:207760008093E8000895913279F48091E800877F8093E8008DE091E067E070E059D2809196
+:20778000E8008E778093E800089582E061EC42E0B1D083E061E842E1ADD084E060E842E1F7
+:2077A000A9C084B7877F84BF88E10FB6F89480936000109260000FBE20E880E090E00FB643
+:2077C000F89420936100809361000FBE81E085BF92E095BF3F9A209A559AE1E6F0E02083A1
+:2077E000108247985D9A289A109289008AEF8093880090936F0083E080938100ECC040911A
+:20780000000850910108109201081092000824B714BE88E10FB6F894809360001092600045
+:207820000FBE822F90E0FC01E270F07021FD14C0213019F4859194910BC0283069F480918F
+:20784000090190910A014817590731F0859194918F5F9F4F09F046DCA4DF78941092AD0101
+:207860001092AC010CC0E2DC36D38091AC019091AD0181549F4110F01092140145DC8091FB
+:207880001401882381F78091E00081608093E00029DC80E090E00895FA01923049F09330C0
+:2078A00061F09130F9F485E191E022E130E01EC087E291E02EE330E019C0882329F485E6FA
+:2078C00091E024E030E012C0813029F489E691E022E230E00BC0823029F48DE891E028E106
+:2078E00030E004C080E090E020E030E091838083C90108958093E9008091EB00816080936A
+:20790000EB001092ED006093EC004093ED008091EE00881F8827881F08958091B601882342
+:207920008CF403C08EB38823B1F08091E80082FFF9CF8091E8008B778093E80008958EB361
+:20794000882349F08091E80080FFF9CF8091E8008E778093E8000895EF92FF920F931F9307
+:2079600045D04CD008ED10E0F80180818F77808380818068808380818F7D808319BC1EBA45
+:207980001092B40180EEE82EF12CF70180818B7F8083F80180818160808380E060E042E049
+:2079A000A9DFE1EEF0E080818E7F8083E2EEF0E0808181608083808188608083F701808125
+:2079C0008E7F8083F8018081806180831F910F91FF90EF900895E7EDF0E080818160808335
+:2079E0008AE482BF81E08093B501B6CFE8EDF0E080818E7F80831092E20008951092DA00D6
+:207A00001092E10008951F920F920FB60F9211242F933F934F935F936F937F938F939F9389
+:207A2000AF93BF93EF93FF938091DA0080FF1BC08091D80080FF17C08091DA008E7F80930F
+:207A4000DA008091D90080FF0BC080E189BD82E189BD09B400FEFDCF81E08EBB3BD203C0C7
+:207A600019BC1EBA37D28091E10080FF17C08091E20080FF13C08091E2008E7F8093E200CE
+:207A80008091E20080618093E2008091D80080628093D80019BC85E08EBB1CD28091E10004
+:207AA00084FF2CC08091E20084FF28C080E189BD82E189BD09B400FEFDCF8091D8008F7D2D
+:207AC0008093D8008091E1008F7E8093E1008091E2008F7E8093E2008091E20081608093EC
+:207AE000E2008091B401882331F48091E30087FD02C081E001C084E08EBBECD18091E10056
+:207B000083FF21C08091E20083FF1DC08091E100877F8093E10082E08EBB1092B4018091B1
+:207B2000E1008E7F8093E1008091E2008E7F8093E2008091E20080618093E20080E060E005
+:207B400042E0D8DEC7D1FF91EF91BF91AF919F918F917F916F915F914F913F912F910F90B6
+:207B60000FBE0F901F9018959C014091BC015091BD014617570718F4F90190E044C06115C8
+:207B8000710511F0AB01F8CF8091E8008E778093E80040E050E0F0CF8EB3882309F444C006
+:207BA000853009F443C08091E80083FF02C081E008958091E80082FD31C08091E80080FFF4
+:207BC00022C08091F3009091F200782F60E0292F30E0262B372B07C081918093F10041503C
+:207BE00050402F5F3F4F4115510519F02830310598F390E02830310509F491E08091E800A6
+:207C00008E778093E8004115510531F6992321F605C08EB3882341F0853041F08091E800FD
+:207C200082FFF7CF80E0089582E0089583E008959C016115710529F48091E8008B7780934D
+:207C4000E800F90126C08EB3882391F1853091F18091E80083FF02C081E008958091E80083
+:207C600082FFF1CF06C08091F10081936150704059F02091F3008091F200322F20E090E0C5
+:207C8000822B932B892B79F78091E8008B778093E80061157105B9F605C08EB3882341F0E2
+:207CA000853041F08091E80080FFF7CF80E0089582E0089583E008950F931F93DF93CF937C
+:207CC00000D0CDB7DEB7E6EBF1E08091F100819381E0EE3BF807C9F728DD8091E80083FF3A
+:207CE000E4C08091B6019091B701953009F46DC0963040F4913081F1913070F0933009F046
+:207D0000D4C02AC0983009F4A3C0993009F4B2C0963009F0CAC07CC0803809F4C6C082380B
+:207D200009F0C3C08091BA0187708093E9008091EB001092E9002091E800277F2093E800A7
+:207D400090E025E0969587952A95E1F781708093F1001092F10087C0882319F0823009F0A2
+:207D6000A4C08F71823009F0A0C08091B801882331F52091BA01277009F497C02093E90006
+:207D80008091EB0080FF1BC0933021F48091EB00806213C08091EB0080618093EB0081E0C8
+:207DA00090E002C0880F991F2A95E2F78093EA001092EA008091EB0088608093EB0010929D
+:207DC000E9008091E800877F51C0882309F06DC01091B8011F770FB7F8948091E800877F98
+:207DE0008093E8009ADD8091E80080FFFCCF8091E3008078812B8093E30080688093E30062
+:207E0000112311F482E001C083E08EBB0FBF4DC08058823008F049C08091B8019091B9014F
+:207E20006091BA01AE014F5F5F4F36DDBC01009709F43BC08091E800877F8093E800898128
+:207E40009A8192DE8091E8008B778093E8002DC0803859F58091E800877F8093E8008091A3
+:207E6000B4018093F1008091E8008E778093E80054DD1BC08823C9F49091B8019230A8F4A4
+:207E80008091E800877F8093E8009093B40145DD8091B401882331F48091E30087FD02C01E
+:207EA00081E001C084E08EBB70DC8091E80083FF0AC08091EB0080628093EB008091E8008D
+:207EC000877F8093E8000F900F90CF91DF911F910F91089508951F938EB3882361F0109179
+:207EE000E9001092E9008091E80083FF01C0E4DE17701093E9001F910895F999FECF92BD02
+:207F000081BDF89A992780B50895262FF999FECF1FBA92BD81BD20BD0FB6F894FA9AF99A90
+:207F20000FBE01960895F894FFCF4341544552494E4100777700080000000000000801128E
+:207F4000011001020000084123360001000201000109023E00020100803209040000010258
+:207F60000201000524001001042402040524060001070582030800FF09040100020A0000B4
+:207F8000000705040210000107058302100001040309042203410072006400750069006E80
+:207FA000006F0020004C0065006F006E006100720064006F00000018034100720064007557
+:127FC0000069006E006F0020004C004C0043000000006E
+:00000001FF
diff --git a/bootloaders/caterina/Caterina.c b/bootloaders/caterina/Caterina.c
new file mode 100755
index 0000000..abcba2b
--- /dev/null
+++ b/bootloaders/caterina/Caterina.c
@@ -0,0 +1,714 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim 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, 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.
+*/
+
+/** \file
+ *
+ * Main source file for the CDC class bootloader. This file contains the complete bootloader logic.
+ */
+
+#define INCLUDE_FROM_CATERINA_C
+#include "Caterina.h"
+
+/** Contains the current baud rate and other settings of the first virtual serial port. This must be retained as some
+ * operating systems will not open the port unless the settings can be set successfully.
+ */
+static CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 0,
+ .CharFormat = CDC_LINEENCODING_OneStopBit,
+ .ParityType = CDC_PARITY_None,
+ .DataBits = 8 };
+
+/** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host,
+ * and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued
+ * command.)
+ */
+static uint32_t CurrAddress;
+
+/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
+ * via a watchdog reset. When cleared the bootloader will exit, starting the watchdog and entering an infinite
+ * loop until the AVR restarts and the application runs.
+ */
+static bool RunBootloader = true;
+
+/* Pulse generation counters to keep track of the time remaining for each pulse type */
+#define TX_RX_LED_PULSE_PERIOD 100
+uint16_t TxLEDPulse = 0; // time remaining for Tx LED pulse
+uint16_t RxLEDPulse = 0; // time remaining for Rx LED pulse
+
+/* Bootloader timeout timer */
+#define TIMEOUT_PERIOD 8000
+uint16_t Timeout = 0;
+
+uint16_t bootKey = 0x7777;
+volatile uint16_t *const bootKeyPtr = (volatile uint16_t *)0x0800;
+
+void StartSketch(void)
+{
+ cli();
+
+ /* Undo TIMER1 setup and clear the count before running the sketch */
+ TIMSK1 = 0;
+ TCCR1B = 0;
+ TCNT1H = 0; // 16-bit write to TCNT1 requires high byte be written first
+ TCNT1L = 0;
+
+ /* Relocate the interrupt vector table to the application section */
+ MCUCR = (1 << IVCE);
+ MCUCR = 0;
+
+ L_LED_OFF();
+ TX_LED_OFF();
+ RX_LED_OFF();
+
+ /* jump to beginning of application space */
+ __asm__ volatile("jmp 0x0000");
+}
+
+/* Breathing animation on L LED indicates bootloader is running */
+uint16_t LLEDPulse;
+void LEDPulse(void)
+{
+ LLEDPulse++;
+ uint8_t p = LLEDPulse >> 8;
+ if (p > 127)
+ p = 254-p;
+ p += p;
+ if (((uint8_t)LLEDPulse) > p)
+ L_LED_OFF();
+ else
+ L_LED_ON();
+}
+
+/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
+ * runs the bootloader processing routine until it times out or is instructed to exit.
+ */
+int main(void)
+{
+ /* Save the value of the boot key memory before it is overwritten */
+ uint16_t bootKeyPtrVal = *bootKeyPtr;
+ *bootKeyPtr = 0;
+
+ /* Check the reason for the reset so we can act accordingly */
+ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register
+ MCUSR = 0; // clear all reset flags
+
+ /* Watchdog may be configured with a 15 ms period so must disable it before going any further */
+ wdt_disable();
+
+ if (mcusr_state & (1<<EXTRF)) {
+ // External reset - we should continue to self-programming mode.
+ } else if (mcusr_state == (1<<PORF) && pgm_read_word(0) != 0xFFFF) {
+ // After a power-on reset skip the bootloader and jump straight to sketch
+ // if one exists.
+ StartSketch();
+ } else if ((mcusr_state == (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) {
+ // If it looks like an "accidental" watchdog reset then start the sketch.
+ StartSketch();
+ }
+
+ /* Setup hardware required for the bootloader */
+ SetupHardware();
+
+ /* Enable global interrupts so that the USB stack can function */
+ sei();
+
+ Timeout = 0;
+
+ while (RunBootloader)
+ {
+ CDC_Task();
+ USB_USBTask();
+ /* Time out and start the sketch if one is present */
+ if (Timeout > TIMEOUT_PERIOD)
+ RunBootloader = false;
+
+ LEDPulse();
+ }
+
+ /* Disconnect from the host - USB interface will be reset later along with the AVR */
+ USB_Detach();
+
+ /* Jump to beginning of application space to run the sketch - do not reset */
+ StartSketch();
+}
+
+/** Configures all hardware required for the bootloader. */
+void SetupHardware(void)
+{
+ /* Disable watchdog if enabled by bootloader/fuses */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ /* Disable clock division */
+ clock_prescale_set(clock_div_1);
+
+ /* Relocate the interrupt vector table to the bootloader section */
+ MCUCR = (1 << IVCE);
+ MCUCR = (1 << IVSEL);
+
+ LED_SETUP();
+ CPU_PRESCALE(0);
+ L_LED_OFF();
+ TX_LED_OFF();
+ RX_LED_OFF();
+
+ /* Initialize TIMER1 to handle bootloader timeout and LED tasks.
+ * With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
+ * Our chosen compare match generates an interrupt every 1 ms.
+ * This interrupt is disabled selectively when doing memory reading, erasing,
+ * or writing since SPM has tight timing requirements.
+ */
+ OCR1AH = 0;
+ OCR1AL = 250;
+ TIMSK1 = (1 << OCIE1A); // enable timer 1 output compare A match interrupt
+ TCCR1B = ((1 << CS11) | (1 << CS10)); // 1/64 prescaler on timer 1 input
+
+ /* Initialize USB Subsystem */
+ USB_Init();
+}
+
+//uint16_t ctr = 0;
+ISR(TIMER1_COMPA_vect, ISR_BLOCK)
+{
+ /* Reset counter */
+ TCNT1H = 0;
+ TCNT1L = 0;
+
+ /* Check whether the TX or RX LED one-shot period has elapsed. if so, turn off the LED */
+ if (TxLEDPulse && !(--TxLEDPulse))
+ TX_LED_OFF();
+ if (RxLEDPulse && !(--RxLEDPulse))
+ RX_LED_OFF();
+
+ if (pgm_read_word(0) != 0xFFFF)
+ Timeout++;
+}
+
+/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
+ * to relay data to and from the attached USB host.
+ */
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ /* Setup CDC Notification, Rx and Tx Endpoints */
+ Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+
+ Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+
+ Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+}
+
+/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
+ * the device from the USB host before passing along unhandled control requests to the library for processing
+ * internally.
+ */
+void EVENT_USB_Device_ControlRequest(void)
+{
+ /* Ignore any requests that aren't directed to the CDC interface */
+ if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
+ (REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ return;
+ }
+
+ /* Process CDC specific control requests */
+ switch (USB_ControlRequest.bRequest)
+ {
+ case CDC_REQ_GetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ /* Write the line coding data to the control endpoint */
+ Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case CDC_REQ_SetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ /* Read the line coding data in from the host into the global struct */
+ Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+#if !defined(NO_BLOCK_SUPPORT)
+/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending
+ * on the AVR910 protocol command issued.
+ *
+ * \param[in] Command Single character AVR910 protocol command indicating what memory operation to perform
+ */
+static void ReadWriteMemoryBlock(const uint8_t Command)
+{
+ uint16_t BlockSize;
+ char MemoryType;
+
+ bool HighByte = false;
+ uint8_t LowByte = 0;
+
+ BlockSize = (FetchNextCommandByte() << 8);
+ BlockSize |= FetchNextCommandByte();
+
+ MemoryType = FetchNextCommandByte();
+
+ if ((MemoryType != 'E') && (MemoryType != 'F'))
+ {
+ /* Send error byte back to the host */
+ WriteNextResponseByte('?');
+
+ return;
+ }
+
+ /* Disable timer 1 interrupt - can't afford to process nonessential interrupts
+ * while doing SPM tasks */
+ TIMSK1 = 0;
+
+ /* Check if command is to read memory */
+ if (Command == 'g')
+ {
+ /* Re-enable RWW section */
+ boot_rww_enable();
+
+ while (BlockSize--)
+ {
+ if (MemoryType == 'F')
+ {
+ /* Read the next FLASH byte from the current FLASH page */
+ #if (FLASHEND > 0xFFFF)
+ WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte));
+ #else
+ WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte));
+ #endif
+
+ /* If both bytes in current word have been read, increment the address counter */
+ if (HighByte)
+ CurrAddress += 2;
+
+ HighByte = !HighByte;
+ }
+ else
+ {
+ /* Read the next EEPROM byte into the endpoint */
+ WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1)));
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ }
+ }
+ else
+ {
+ uint32_t PageStartAddress = CurrAddress;
+
+ if (MemoryType == 'F')
+ {
+ boot_page_erase(PageStartAddress);
+ boot_spm_busy_wait();
+ }
+
+ while (BlockSize--)
+ {
+ if (MemoryType == 'F')
+ {
+ /* If both bytes in current word have been written, increment the address counter */
+ if (HighByte)
+ {
+ /* Write the next FLASH word to the current FLASH page */
+ boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ else
+ {
+ LowByte = FetchNextCommandByte();
+ }
+
+ HighByte = !HighByte;
+ }
+ else
+ {
+ /* Write the next EEPROM byte from the endpoint */
+ eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
+
+ /* Increment the address counter after use */
+ CurrAddress += 2;
+ }
+ }
+
+ /* If in FLASH programming mode, commit the page after writing */
+ if (MemoryType == 'F')
+ {
+ /* Commit the flash page to memory */
+ boot_page_write(PageStartAddress);
+
+ /* Wait until write operation has completed */
+ boot_spm_busy_wait();
+ }
+
+ /* Send response byte back to the host */
+ WriteNextResponseByte('\r');
+ }
+
+ /* Re-enable timer 1 interrupt disabled earlier in this routine */
+ TIMSK1 = (1 << OCIE1A);
+}
+#endif
+
+/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
+ * to allow reception of the next data packet from the host.
+ *
+ * \return Next received byte from the host in the CDC data OUT endpoint
+ */
+static uint8_t FetchNextCommandByte(void)
+{
+ /* Select the OUT endpoint so that the next data byte can be read */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* If OUT endpoint empty, clear it and wait for the next packet from the host */
+ while (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearOUT();
+
+ while (!(Endpoint_IsOUTReceived()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return 0;
+ }
+ }
+
+ /* Fetch the next byte from the OUT endpoint */
+ return Endpoint_Read_8();
+}
+
+/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the
+ * bank when full ready for the next byte in the packet to the host.
+ *
+ * \param[in] Response Next response byte to send to the host
+ */
+static void WriteNextResponseByte(const uint8_t Response)
+{
+ /* Select the IN endpoint so that the next data byte can be written */
+ Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+
+ /* If IN endpoint full, clear it and wait until ready for the next packet to the host */
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+ }
+
+ /* Write the next byte to the IN endpoint */
+ Endpoint_Write_8(Response);
+
+ TX_LED_ON();
+ TxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+}
+
+#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'
+
+/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions
+ * and send the appropriate response back to the host.
+ */
+void CDC_Task(void)
+{
+ /* Select the OUT endpoint */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* Check if endpoint has a command in it sent from the host */
+ if (!(Endpoint_IsOUTReceived()))
+ return;
+
+ RX_LED_ON();
+ RxLEDPulse = TX_RX_LED_PULSE_PERIOD;
+
+ /* Read in the bootloader command (first byte sent from host) */
+ uint8_t Command = FetchNextCommandByte();
+
+ if (Command == 'E')
+ {
+ /* We nearly run out the bootloader timeout clock,
+ * leaving just a few hundred milliseconds so the
+ * bootloder has time to respond and service any
+ * subsequent requests */
+ Timeout = TIMEOUT_PERIOD - 500;
+
+ /* Re-enable RWW section - must be done here in case
+ * user has disabled verification on upload. */
+ boot_rww_enable_safe();
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'T')
+ {
+ FetchNextCommandByte();
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if ((Command == 'L') || (Command == 'P'))
+ {
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 't')
+ {
+ // Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader
+ WriteNextResponseByte(0x44);
+ WriteNextResponseByte(0x00);
+ }
+ else if (Command == 'a')
+ {
+ // Indicate auto-address increment is supported
+ WriteNextResponseByte('Y');
+ }
+ else if (Command == 'A')
+ {
+ // Set the current address to that given by the host
+ CurrAddress = (FetchNextCommandByte() << 9);
+ CurrAddress |= (FetchNextCommandByte() << 1);
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'p')
+ {
+ // Indicate serial programmer back to the host
+ WriteNextResponseByte('S');
+ }
+ else if (Command == 'S')
+ {
+ // Write the 7-byte software identifier to the endpoint
+ for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++)
+ WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]);
+ }
+ else if (Command == 'V')
+ {
+ WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR);
+ WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR);
+ }
+ else if (Command == 's')
+ {
+ WriteNextResponseByte(AVR_SIGNATURE_3);
+ WriteNextResponseByte(AVR_SIGNATURE_2);
+ WriteNextResponseByte(AVR_SIGNATURE_1);
+ }
+ else if (Command == 'e')
+ {
+ // Clear the application section of flash
+ for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
+ {
+ boot_page_erase(CurrFlashAddress);
+ boot_spm_busy_wait();
+ boot_page_write(CurrFlashAddress);
+ boot_spm_busy_wait();
+ }
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ #if !defined(NO_LOCK_BYTE_WRITE_SUPPORT)
+ else if (Command == 'l')
+ {
+ // Set the lock bits to those given by the host
+ boot_lock_bits_set(FetchNextCommandByte());
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ #endif
+ else if (Command == 'r')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS));
+ }
+ else if (Command == 'F')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS));
+ }
+ else if (Command == 'N')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS));
+ }
+ else if (Command == 'Q')
+ {
+ WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS));
+ }
+ #if !defined(NO_BLOCK_SUPPORT)
+ else if (Command == 'b')
+ {
+ WriteNextResponseByte('Y');
+
+ // Send block size to the host
+ WriteNextResponseByte(SPM_PAGESIZE >> 8);
+ WriteNextResponseByte(SPM_PAGESIZE & 0xFF);
+ }
+ else if ((Command == 'B') || (Command == 'g'))
+ {
+ // Keep resetting the timeout counter if we're receiving self-programming instructions
+ Timeout = 0;
+ // Delegate the block write/read to a separate function for clarity
+ ReadWriteMemoryBlock(Command);
+ }
+ #endif
+ #if !defined(NO_FLASH_BYTE_SUPPORT)
+ else if (Command == 'C')
+ {
+ // Write the high byte to the current flash page
+ boot_page_fill(CurrAddress, FetchNextCommandByte());
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'c')
+ {
+ // Write the low byte to the current flash page
+ boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
+
+ // Increment the address
+ CurrAddress += 2;
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'm')
+ {
+ // Commit the flash page to memory
+ boot_page_write(CurrAddress);
+
+ // Wait until write operation has completed
+ boot_spm_busy_wait();
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'R')
+ {
+ #if (FLASHEND > 0xFFFF)
+ uint16_t ProgramWord = pgm_read_word_far(CurrAddress);
+ #else
+ uint16_t ProgramWord = pgm_read_word(CurrAddress);
+ #endif
+
+ WriteNextResponseByte(ProgramWord >> 8);
+ WriteNextResponseByte(ProgramWord & 0xFF);
+ }
+ #endif
+ #if !defined(NO_EEPROM_BYTE_SUPPORT)
+ else if (Command == 'D')
+ {
+ // Read the byte from the endpoint and write it to the EEPROM
+ eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
+
+ // Increment the address after use
+ CurrAddress += 2;
+
+ // Send confirmation byte back to the host
+ WriteNextResponseByte('\r');
+ }
+ else if (Command == 'd')
+ {
+ // Read the EEPROM byte and write it to the endpoint
+ WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1))));
+
+ // Increment the address after use
+ CurrAddress += 2;
+ }
+ #endif
+ else if (Command != 27)
+ {
+ // Unknown (non-sync) command, return fail code
+ WriteNextResponseByte('?');
+ }
+
+
+ /* Select the IN endpoint */
+ Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+
+ /* Remember if the endpoint is completely full before clearing it */
+ bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
+
+ /* Send the endpoint data to the host */
+ Endpoint_ClearIN();
+
+ /* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
+ if (IsEndpointFull)
+ {
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+
+ Endpoint_ClearIN();
+ }
+
+ /* Wait until the data has been sent to the host */
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+
+ /* Select the OUT endpoint */
+ Endpoint_SelectEndpoint(CDC_RX_EPNUM);
+
+ /* Acknowledge the command from the host */
+ Endpoint_ClearOUT();
+}
+
diff --git a/bootloaders/caterina/Caterina.h b/bootloaders/caterina/Caterina.h
new file mode 100755
index 0000000..f8251d4
--- /dev/null
+++ b/bootloaders/caterina/Caterina.h
@@ -0,0 +1,99 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim 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, 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.
+*/
+
+/** \file
+ *
+ * Header file for BootloaderCDC.c.
+ */
+
+#ifndef _CDC_H_
+#define _CDC_H_
+
+ /* Includes: */
+ #include <avr/io.h>
+ #include <avr/wdt.h>
+ #include <avr/boot.h>
+ #include <avr/eeprom.h>
+ #include <avr/power.h>
+ #include <avr/interrupt.h>
+ #include <stdbool.h>
+
+ #include "Descriptors.h"
+
+ #include <LUFA/Drivers/USB/USB.h>
+ /* Macros: */
+ /** Version major of the CDC bootloader. */
+ #define BOOTLOADER_VERSION_MAJOR 0x01
+
+ /** Version minor of the CDC bootloader. */
+ #define BOOTLOADER_VERSION_MINOR 0x00
+
+ /** Hardware version major of the CDC bootloader. */
+ #define BOOTLOADER_HWVERSION_MAJOR 0x01
+
+ /** Hardware version minor of the CDC bootloader. */
+ #define BOOTLOADER_HWVERSION_MINOR 0x00
+
+ /** Eight character bootloader firmware identifier reported to the host when requested */
+ #define SOFTWARE_IDENTIFIER "CATERINA"
+
+ #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+ #define LED_SETUP() DDRC |= (1<<7); DDRB |= (1<<0); DDRD |= (1<<5);
+ #define L_LED_OFF() PORTC &= ~(1<<7)
+ #define L_LED_ON() PORTC |= (1<<7)
+ #define L_LED_TOGGLE() PORTC ^= (1<<7)
+ #define TX_LED_OFF() PORTD |= (1<<5)
+ #define TX_LED_ON() PORTD &= ~(1<<5)
+ #define RX_LED_OFF() PORTB |= (1<<0)
+ #define RX_LED_ON() PORTB &= ~(1<<0)
+
+ /* Type Defines: */
+ /** Type define for a non-returning pointer to the start of the loaded application in flash memory. */
+ typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
+
+ /* Function Prototypes: */
+ void StartSketch(void);
+ void LEDPulse(void);
+
+ void CDC_Task(void);
+ void SetupHardware(void);
+
+ void EVENT_USB_Device_ConfigurationChanged(void);
+
+ #if defined(INCLUDE_FROM_CATERINA_C) || defined(__DOXYGEN__)
+ #if !defined(NO_BLOCK_SUPPORT)
+ static void ReadWriteMemoryBlock(const uint8_t Command);
+ #endif
+ static uint8_t FetchNextCommandByte(void);
+ static void WriteNextResponseByte(const uint8_t Response);
+ #endif
+
+#endif
+
diff --git a/bootloaders/caterina/Descriptors.c b/bootloaders/caterina/Descriptors.c
new file mode 100755
index 0000000..c5feaf5
--- /dev/null
+++ b/bootloaders/caterina/Descriptors.c
@@ -0,0 +1,262 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim 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, 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.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "Descriptors.h"
+
+/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_NoSpecificSubclass,
+ .Protocol = CDC_CSCP_NoSpecificProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = DEVICE_VID,
+ .ProductID = DEVICE_PID,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x02,
+ .ProductStrIndex = 0x01,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const USB_Descriptor_Configuration_t ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = 2,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = USB_CONFIG_ATTR_BUSPOWERED,
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x00,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x02,
+
+ .Capabilities = 0x04,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = 0x06,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},
+
+ #if DEVICE_PID == 0x0036
+ .UnicodeString = L"Arduino Leonardo"
+ #else
+ .UnicodeString = L"USB IO board "
+ #endif
+};
+
+const USB_Descriptor_String_t ManufNameString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+
+ #if DEVICE_VID == 0x2341
+ .UnicodeString = L"Arduino LLC"
+ #else
+ .UnicodeString = L"Unknown "
+ #endif
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ if (!(DescriptorNumber))
+ {
+ Address = &LanguageString;
+ Size = LanguageString.Header.Size;
+ }
+ else if (DescriptorNumber == DeviceDescriptor.ProductStrIndex)
+ {
+ Address = &ProductString;
+ Size = ProductString.Header.Size;
+ } else if (DescriptorNumber == DeviceDescriptor.ManufacturerStrIndex)
+ {
+ Address = &ManufNameString;
+ Size = ManufNameString.Header.Size;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/bootloaders/caterina/Descriptors.h b/bootloaders/caterina/Descriptors.h
new file mode 100755
index 0000000..94091ae
--- /dev/null
+++ b/bootloaders/caterina/Descriptors.h
@@ -0,0 +1,139 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim 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, 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.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <LUFA/Drivers/USB/USB.h>
+
+ /* Macros: */
+ #if defined(__AVR_AT90USB1287__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x97
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB647__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x96
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB1286__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x97
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_AT90USB646__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x96
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_ATmega32U6__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x88
+ #elif defined(__AVR_ATmega32U4__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x87
+ #elif defined(__AVR_ATmega16U4__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x88
+ #elif defined(__AVR_ATmega32U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x95
+ #define AVR_SIGNATURE_3 0x8A
+ #elif defined(__AVR_ATmega16U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x89
+ #elif defined(__AVR_AT90USB162__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x82
+ #elif defined(__AVR_ATmega8U2__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x93
+ #define AVR_SIGNATURE_3 0x89
+ #elif defined(__AVR_AT90USB82__)
+ #define AVR_SIGNATURE_1 0x1E
+ #define AVR_SIGNATURE_2 0x94
+ #define AVR_SIGNATURE_3 0x82
+ #else
+ #error The selected AVR part is not currently supported by this bootloader.
+ #endif
+
+ /** Endpoint number for the CDC control interface event notification endpoint. */
+ #define CDC_NOTIFICATION_EPNUM 2
+
+ /** Endpoint number for the CDC data interface TX (data IN) endpoint. */
+ #define CDC_TX_EPNUM 3
+
+ /** Endpoint number for the CDC data interface RX (data OUT) endpoint. */
+ #define CDC_RX_EPNUM 4
+
+ /** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
+ #define CDC_TXRX_EPSIZE 16
+
+ /** Size of the CDC control interface notification endpoint bank, in bytes. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // CDC Control Interface
+ USB_Descriptor_Interface_t CDC_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
+ // CDC Data Interface
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/bootloaders/caterina/Makefile b/bootloaders/caterina/Makefile
new file mode 100755
index 0000000..873f8bd
--- /dev/null
+++ b/bootloaders/caterina/Makefile
@@ -0,0 +1,728 @@
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+# >> Modified for use with the LUFA project. <<
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+# Carlos Lamas
+# Dean Camera
+# Opendous Inc.
+# Denver Gingerich
+#
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device, using avrdude.
+# Please customize the avrdude settings below first!
+#
+# make doxygen = Generate DoxyGen documentation for the project (must have
+# DoxyGen installed)
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+# USB vendor ID (VID)
+# official Arduino LLC VID
+# VID = 0x2341
+
+
+# USB product ID (PID)
+# official Leonardo PID
+# PID = 0x0036
+
+
+# MCU name
+MCU = atmega32u4
+
+
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+
+# Target board (see library "Board Types" documentation, NONE for projects not requiring
+# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
+# "Board" inside the application directory.
+BOARD = USER
+
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+
+# Starting byte address of the bootloader, as a byte address - computed via the formula
+# BOOT_START = ((FLASH_SIZE_KB - BOOT_SECTION_SIZE_KB) * 1024)
+#
+# Note that the bootloader size and start address given in AVRStudio is in words and not
+# bytes, and so will need to be doubled to obtain the byte address needed by AVR-GCC.
+FLASH_SIZE_KB = 32
+BOOT_SECTION_SIZE_KB = 4
+BOOT_START = 0x$(shell echo "obase=16; ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024" | bc)
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = Caterina
+
+
+# Object files directory
+# To put object files in current directory, use a dot (.), do NOT make
+# this an empty or blank macro!
+OBJDIR = .
+
+
+# Path to the LUFA library
+LUFA_PATH = ../../../../../LUFA-111009
+
+
+# LUFA library compile-time options and predefined tokens
+LUFA_OPTS = -D USB_DEVICE_ONLY
+LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
+LUFA_OPTS += -D ORDERED_EP_CONFIG
+LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
+LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
+LUFA_OPTS += -D USE_RAM_DESCRIPTORS
+LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
+LUFA_OPTS += -D NO_INTERNAL_SERIAL
+LUFA_OPTS += -D NO_DEVICE_SELF_POWER
+LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
+LUFA_OPTS += -D NO_SOF_EVENTS
+
+#LUFA_OPTS += -D NO_BLOCK_SUPPORT
+#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
+#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
+LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
+
+
+# Create the LUFA source path variables by including the LUFA root makefile
+include $(LUFA_PATH)/LUFA/makefile
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(TARGET).c \
+ Descriptors.c \
+ $(LUFA_SRC_USB) \
+
+
+# List C++ source files here. (C dependencies are automatically generated.)
+CPPSRC =
+
+
+# List Assembler source files here.
+# Make them always end in a capital .S. Files ending in a lowercase .s
+# will not be considered source files but generated files (assembler
+# output from the compiler), and will be deleted upon "make clean"!
+# Even though the DOS/Win* filesystem matches both .s and .S the same,
+# it will preserve the spelling of the filenames, and gcc itself does
+# care about how the name is spelled on its command-line.
+ASRC =
+
+
+# Optimization level, can be [0, 1, 2, 3, s].
+# 0 = turn off optimization. s = optimize for size.
+# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
+OPT = s
+
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
+# AVR Studio 4.10 requires dwarf-2.
+# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
+DEBUG = dwarf-2
+
+
+# List any extra directories to look for include files here.
+# Each directory must be seperated by a space.
+# Use forward slashes for directory separators.
+# For a directory that has spaces, enclose it in quotes.
+EXTRAINCDIRS = $(LUFA_PATH)/
+
+
+# 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=c99
+
+
+# Place -D or -U options here for C sources
+CDEFS = -DF_CPU=$(F_CPU)UL
+CDEFS += -DF_USB=$(F_USB)UL
+CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
+CDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+CDEFS += -DDEVICE_VID=$(VID)UL
+CDEFS += -DDEVICE_PID=$(PID)UL
+CDEFS += $(LUFA_OPTS)
+
+
+# Place -D or -U options here for ASM sources
+ADEFS = -DF_CPU=$(F_CPU)
+ADEFS += -DF_USB=$(F_USB)UL
+ADEFS += -DBOARD=BOARD_$(BOARD)
+ADEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+ADEFS += $(LUFA_OPTS)
+
+
+# Place -D or -U options here for C++ sources
+CPPDEFS = -DF_CPU=$(F_CPU)UL
+CPPDEFS += -DF_USB=$(F_USB)UL
+CPPDEFS += -DBOARD=BOARD_$(BOARD)
+CPPDEFS += -DBOOT_START_ADDR=$(BOOT_START)UL
+CPPDEFS += $(LUFA_OPTS)
+#CPPDEFS += -D__STDC_LIMIT_MACROS
+#CPPDEFS += -D__STDC_CONSTANT_MACROS
+
+
+
+#---------------- Compiler Options C ----------------
+# -g*: generate debugging information
+# -O*: optimization level
+# -f...: tuning, see GCC manual and avr-libc documentation
+# -Wall...: warning level
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns...: create assembler listing
+CFLAGS = -g$(DEBUG)
+CFLAGS += $(CDEFS)
+CFLAGS += -O$(OPT)
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -ffunction-sections
+CFLAGS += -fno-inline-small-functions
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -fno-strict-aliasing
+CFLAGS += -Wall
+CFLAGS += -Wstrict-prototypes
+#CFLAGS += -mshort-calls
+#CFLAGS += -fno-unit-at-a-time
+#CFLAGS += -Wundef
+#CFLAGS += -Wunreachable-code
+#CFLAGS += -Wsign-compare
+CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+
+
+#---------------- Compiler Options C++ ----------------
+# -g*: generate debugging information
+# -O*: optimization level
+# -f...: tuning, see GCC manual and avr-libc documentation
+# -Wall...: warning level
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns...: create assembler listing
+CPPFLAGS = -g$(DEBUG)
+CPPFLAGS += $(CPPDEFS)
+CPPFLAGS += -O$(OPT)
+CPPFLAGS += -funsigned-char
+CPPFLAGS += -funsigned-bitfields
+CPPFLAGS += -fpack-struct
+CPPFLAGS += -fshort-enums
+CPPFLAGS += -fno-exceptions
+CPPFLAGS += -Wall
+CPPFLAGS += -Wundef
+#CPPFLAGS += -mshort-calls
+#CPPFLAGS += -fno-unit-at-a-time
+#CPPFLAGS += -Wstrict-prototypes
+#CPPFLAGS += -Wunreachable-code
+#CPPFLAGS += -Wsign-compare
+CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
+CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+#CPPFLAGS += $(CSTANDARD)
+
+
+#---------------- Assembler Options ----------------
+# -Wa,...: tell GCC to pass this to the assembler.
+# -adhlns: create listing
+# -gstabs: have the assembler create line number information; note that
+# for use in COFF files, additional information about filenames
+# and function names needs to be present in the assembler source
+# files -- see avr-libc docs [FIXME: not yet described there]
+# -listing-cont-lines: Sets the maximum number of continuation lines of hex
+# dump that will be displayed for a given single line of source input.
+ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
+
+
+#---------------- Library Options ----------------
+# Minimalistic printf version
+PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
+
+# Floating point printf version (requires MATH_LIB = -lm below)
+PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
+
+# If this is left blank, then it will use the Standard printf version.
+PRINTF_LIB =
+#PRINTF_LIB = $(PRINTF_LIB_MIN)
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
+
+
+# Minimalistic scanf version
+SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
+
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
+SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
+
+# If this is left blank, then it will use the Standard scanf version.
+SCANF_LIB =
+#SCANF_LIB = $(SCANF_LIB_MIN)
+#SCANF_LIB = $(SCANF_LIB_FLOAT)
+
+
+MATH_LIB = -lm
+
+
+# List any extra directories to look for libraries here.
+# Each directory must be seperated by a space.
+# Use forward slashes for directory separators.
+# For a directory that has spaces, enclose it in quotes.
+EXTRALIBDIRS =
+
+
+
+#---------------- External Memory Options ----------------
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# used for variables (.data/.bss) and heap (malloc()).
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
+
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),
+# only used for heap (malloc()).
+#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
+
+EXTMEMOPTS =
+
+
+
+#---------------- Linker Options ----------------
+# -Wl,...: tell GCC to pass this to linker.
+# -Map: create map file
+# --cref: add cross reference to map file
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
+LDFLAGS += -Wl,--section-start=.text=$(BOOT_START)
+LDFLAGS += -Wl,--relax
+LDFLAGS += -Wl,--gc-sections
+LDFLAGS += $(EXTMEMOPTS)
+LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+#LDFLAGS += -T linker_script.x
+
+
+
+#---------------- Programming Options (avrdude) ----------------
+
+# Programming hardware
+# Type: avrdude -c ?
+# to get a full listing.
+#
+AVRDUDE_PROGRAMMER = avrispmkII
+
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = usb
+
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+#AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level. Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+
+
+#---------------- Debugging Options ----------------
+
+# For simulavr only - target MCU frequency.
+DEBUG_MFREQ = $(F_CPU)
+
+# Set the DEBUG_UI to either gdb or insight.
+# DEBUG_UI = gdb
+DEBUG_UI = insight
+
+# Set the debugging back-end to either avarice, simulavr.
+DEBUG_BACKEND = avarice
+#DEBUG_BACKEND = simulavr
+
+# GDB Init Filename.
+GDBINIT_FILE = __avr_gdbinit
+
+# When using avarice settings for the JTAG
+JTAG_DEV = /dev/com1
+
+# Debugging port used to communicate between GDB / avarice / simulavr.
+DEBUG_PORT = 4242
+
+# Debugging host used to communicate between GDB / avarice / simulavr, normally
+# just set to localhost unless doing some sort of crazy debugging when
+# avarice is running on a different computer.
+DEBUG_HOST = localhost
+
+
+
+#============================================================================
+
+
+# Define programs and commands.
+SHELL = sh
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+AR = avr-ar rcs
+NM = avr-nm
+AVRDUDE = /Applications/avrdude -C /Applications/avrdude.conf -B 1
+REMOVE = rm -f
+REMOVEDIR = rm -rf
+COPY = cp
+WINSHELL = cmd
+
+
+# Define Messages
+# English
+MSG_ERRORS_NONE = Errors: none
+MSG_BEGIN = -------- begin --------
+MSG_END = -------- end --------
+MSG_SIZE_BEFORE = Size before:
+MSG_SIZE_AFTER = Size after:
+MSG_COFF = Converting to AVR COFF:
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
+MSG_FLASH = Creating load file for Flash:
+MSG_EEPROM = Creating load file for EEPROM:
+MSG_EXTENDED_LISTING = Creating Extended Listing:
+MSG_SYMBOL_TABLE = Creating Symbol Table:
+MSG_LINKING = Linking:
+MSG_COMPILING = Compiling C:
+MSG_COMPILING_CPP = Compiling C++:
+MSG_ASSEMBLING = Assembling:
+MSG_CLEANING = Cleaning project:
+MSG_CREATING_LIBRARY = Creating library:
+
+
+
+
+# Define all object files.
+OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
+
+# Define all listing files.
+LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
+
+
+# Compiler flags to generate dependency files.
+GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
+
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
+ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+
+
+
+# Default target.
+all: begin gccversion sizebefore build sizeafter end
+
+# Change the build target to build a HEX file or a library.
+build: elf hex eep lss sym
+#build: lib
+
+
+elf: $(TARGET).elf
+hex: $(TARGET).hex
+eep: $(TARGET).eep
+lss: $(TARGET).lss
+sym: $(TARGET).sym
+LIBNAME=lib$(TARGET).a
+lib: $(LIBNAME)
+
+
+
+# Eye candy.
+# AVR Studio 3.x does not check make's exit code but relies on
+# the following magic strings to be generated by the compile job.
+begin:
+ @echo
+ @echo $(MSG_BEGIN)
+
+end:
+ @echo $(MSG_END)
+ @echo
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
+ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
+MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
+FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
+
+
+sizebefore:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+sizeafter:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+
+
+# Display compiler version information.
+gccversion :
+ @$(CC) --version
+
+
+# Program the device.
+program: $(TARGET).hex $(TARGET).eep
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+
+
+# Generate avr-gdb config/init file which does the following:
+# define the reset signal, load the target file, connect to target, and set
+# a breakpoint at main().
+gdb-config:
+ @$(REMOVE) $(GDBINIT_FILE)
+ @echo define reset >> $(GDBINIT_FILE)
+ @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
+ @echo end >> $(GDBINIT_FILE)
+ @echo file $(TARGET).elf >> $(GDBINIT_FILE)
+ @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
+ifeq ($(DEBUG_BACKEND),simulavr)
+ @echo load >> $(GDBINIT_FILE)
+endif
+ @echo break main >> $(GDBINIT_FILE)
+
+debug: gdb-config $(TARGET).elf
+ifeq ($(DEBUG_BACKEND), avarice)
+ @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
+ @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
+ $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
+ @$(WINSHELL) /c pause
+
+else
+ @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
+ $(DEBUG_MFREQ) --port $(DEBUG_PORT)
+endif
+ @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
+
+
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT = $(OBJCOPY) --debugging
+COFFCONVERT += --change-section-address .data-0x800000
+COFFCONVERT += --change-section-address .bss-0x800000
+COFFCONVERT += --change-section-address .noinit-0x800000
+COFFCONVERT += --change-section-address .eeprom-0x810000
+
+
+
+coff: $(TARGET).elf
+ @echo
+ @echo $(MSG_COFF) $(TARGET).cof
+ $(COFFCONVERT) -O coff-avr $< $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+ @echo
+ @echo $(MSG_EXTENDED_COFF) $(TARGET).cof
+ $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
+
+
+
+# Create final output files (.hex, .eep) from ELF output file.
+%.hex: %.elf
+ @echo
+ @echo $(MSG_FLASH) $@
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
+
+%.eep: %.elf
+ @echo
+ @echo $(MSG_EEPROM) $@
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
+
+# Create extended listing file from ELF output file.
+%.lss: %.elf
+ @echo
+ @echo $(MSG_EXTENDED_LISTING) $@
+ $(OBJDUMP) -h -S -z $< > $@
+
+# Create a symbol table from ELF output file.
+%.sym: %.elf
+ @echo
+ @echo $(MSG_SYMBOL_TABLE) $@
+ $(NM) -n $< > $@
+
+
+
+# Create library from object files.
+.SECONDARY : $(TARGET).a
+.PRECIOUS : $(OBJ)
+%.a: $(OBJ)
+ @echo
+ @echo $(MSG_CREATING_LIBRARY) $@
+ $(AR) $@ $(OBJ)
+
+
+# Link: create ELF output file from object files.
+.SECONDARY : $(TARGET).elf
+.PRECIOUS : $(OBJ)
+%.elf: $(OBJ)
+ @echo
+ @echo $(MSG_LINKING) $@
+ $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
+
+
+# Compile: create object files from C source files.
+$(OBJDIR)/%.o : %.c
+ @echo
+ @echo $(MSG_COMPILING) $<
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create object files from C++ source files.
+$(OBJDIR)/%.o : %.cpp
+ @echo
+ @echo $(MSG_COMPILING_CPP) $<
+ $(CC) -c $(ALL_CPPFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+%.s : %.c
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C++ source files.
+%.s : %.cpp
+ $(CC) -S $(ALL_CPPFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+$(OBJDIR)/%.o : %.S
+ @echo
+ @echo $(MSG_ASSEMBLING) $<
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+# Create preprocessed source for use in sending a bug report.
+%.i : %.c
+ $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
+
+
+# Target: clean project.
+clean: begin clean_list end
+
+clean_list :
+ @echo
+ @echo $(MSG_CLEANING)
+ $(REMOVE) $(TARGET).hex
+ $(REMOVE) $(TARGET).eep
+ $(REMOVE) $(TARGET).cof
+ $(REMOVE) $(TARGET).elf
+ $(REMOVE) $(TARGET).map
+ $(REMOVE) $(TARGET).sym
+ $(REMOVE) $(TARGET).lss
+ $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
+ $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
+ $(REMOVE) $(SRC:.c=.s)
+ $(REMOVE) $(SRC:.c=.d)
+ $(REMOVE) $(SRC:.c=.i)
+ $(REMOVEDIR) .dep
+
+doxygen:
+ @echo Generating Project Documentation \($(TARGET)\)...
+ @doxygen Doxygen.conf
+ @echo Documentation Generation Complete.
+
+clean_doxygen:
+ rm -rf Documentation
+
+checksource:
+ @for f in $(SRC) $(CPPSRC) $(ASRC); do \
+ if [ -f $$f ]; then \
+ echo "Found Source File: $$f" ; \
+ else \
+ echo "Source File Not Found: $$f" ; \
+ fi; done
+
+
+# Create object files directory
+$(shell mkdir $(OBJDIR) 2>/dev/null)
+
+
+# Include the dependency files.
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+
+# Listing of phony targets.
+.PHONY : all begin finish end sizebefore sizeafter gccversion \
+build elf hex eep lss sym coff extcoff doxygen clean \
+clean_list clean_doxygen program debug gdb-config checksource
+
diff --git a/bootloaders/diskloader/DiskLoader-Leonardo.hex b/bootloaders/diskloader/DiskLoader-Leonardo.hex
deleted file mode 100644
index 0d0c167..0000000
--- a/bootloaders/diskloader/DiskLoader-Leonardo.hex
+++ /dev/null
@@ -1,115 +0,0 @@
-: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
deleted file mode 100644
index 6ac3db3..0000000
--- a/bootloaders/diskloader/Makefile
+++ /dev/null
@@ -1,105 +0,0 @@
-###############################################################################
-# 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
deleted file mode 100644
index 6580618..0000000
--- a/bootloaders/diskloader/src/DiskLoader.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-
-
-#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
deleted file mode 100644
index 04c5b79..0000000
--- a/bootloaders/diskloader/src/Platform.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-#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
deleted file mode 100644
index 208121e..0000000
--- a/bootloaders/diskloader/src/USBCore.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-
-
-/* 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
deleted file mode 100644
index 537c0ec..0000000
--- a/bootloaders/diskloader/src/USBCore.h
+++ /dev/null
@@ -1,246 +0,0 @@
-
-// 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
deleted file mode 100644
index ade072a..0000000
--- a/bootloaders/diskloader/src/USBDesc.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-/* 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
deleted file mode 100644
index a970fa4..0000000
--- a/bootloaders/diskloader/src/USBDesc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-/* 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/cores/arduino/Arduino.h b/cores/arduino/Arduino.h
index bfec943..830c995 100755
--- a/cores/arduino/Arduino.h
+++ b/cores/arduino/Arduino.h
@@ -20,6 +20,7 @@ extern "C"{
#define INPUT 0x0
#define OUTPUT 0x1
+#define INPUT_PULLUP 0x2
#define true 0x1
#define false 0x0
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 14a0eae..1ee3a48 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -23,12 +23,20 @@
#if defined(USBCON)
#ifdef CDC_ENABLED
-void Reboot()
+#if (RAMEND < 1000)
+#define SERIAL_BUFFER_SIZE 16
+#else
+#define SERIAL_BUFFER_SIZE 64
+#endif
+
+struct ring_buffer
{
- USB.detach();
- cli();
- asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB
-}
+ unsigned char buffer[SERIAL_BUFFER_SIZE];
+ volatile int head;
+ volatile int tail;
+};
+
+ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
typedef struct
{
@@ -92,9 +100,28 @@ bool WEAK CDC_Setup(Setup& setup)
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;
+
+ // auto-reset into the bootloader is triggered when the port, already
+ // open at 1200 bps, is closed. this is the signal to start the watchdog
+ // with a relatively long period so it can finish housekeeping tasks
+ // like servicing endpoints before the sketch ends
+ if (1200 == _usbLineInfo.dwDTERate) {
+ // We check DTR state to determine if host port is open (bit 0 of lineState).
+ if ((_usbLineInfo.lineState & 0x01) == 0) {
+ *(uint16_t *)0x0800 = 0x7777;
+ wdt_enable(WDTO_120MS);
+ } else {
+ // Most OSs do some intermediate steps when configuring ports and DTR can
+ // twiggle more than once before stabilizing.
+ // To avoid spurious resets we set the watchdog to 250ms and eventually
+ // cancel if DTR goes back high.
+
+ wdt_disable();
+ wdt_reset();
+ *(uint16_t *)0x0800 = 0x0;
+ }
+ }
return true;
}
}
@@ -111,33 +138,49 @@ void Serial_::end(void)
{
}
+void Serial_::accept(void)
+{
+ ring_buffer *buffer = &cdc_rx_buffer;
+ int c = USB_Recv(CDC_RX);
+ int i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
+
+ // if we should be storing the received character into the location
+ // just before the tail (meaning that the head would advance to the
+ // current location of the tail), we're about to overflow the buffer
+ // and so we don't write the character or advance the head.
+ if (i != buffer->tail) {
+ buffer->buffer[buffer->head] = c;
+ buffer->head = i;
+ }
+}
+
int Serial_::available(void)
{
- u8 avail = USB_Available(CDC_RX);
- if (_serialPeek != -1)
- avail++;
- return avail;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE;
}
-// peek is nasty
int Serial_::peek(void)
{
- if (_serialPeek == -1)
- _serialPeek = read();
- return _serialPeek;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ if (buffer->head == buffer->tail) {
+ return -1;
+ } else {
+ return buffer->buffer[buffer->tail];
+ }
}
int Serial_::read(void)
{
- int c;
- if (_serialPeek != -1)
- {
- c = _serialPeek;
- _serialPeek = -1;
+ ring_buffer *buffer = &cdc_rx_buffer;
+ // if the head isn't ahead of the tail, we don't have any characters
+ if (buffer->head == buffer->tail) {
+ return -1;
} else {
- c = USB_Recv(CDC_RX);
- }
- return c;
+ unsigned char c = buffer->buffer[buffer->tail];
+ buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE;
+ return c;
+ }
}
void Serial_::flush(void)
@@ -169,7 +212,22 @@ size_t Serial_::write(uint8_t c)
return 0;
}
+// This operator is a convenient way for a sketch to check whether the
+// port has actually been configured and opened by the host (as opposed
+// to just being connected to the host). It can be used, for example, in
+// setup() before printing to ensure that an application on the host is
+// actually ready to receive and display the data.
+// We add a short delay before returning to fix a bug observed by Federico
+// where the port is configured (lineState != 0) but not quite opened.
+Serial_::operator bool() {
+ bool result = false;
+ if (_usbLineInfo.lineState > 0)
+ result = true;
+ delay(10);
+ return result;
+}
+
Serial_ Serial;
#endif
-#endif /* if defined(USBCON) */ \ No newline at end of file
+#endif /* if defined(USBCON) */
diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp
index 8ed1566..ac63608 100644
--- a/cores/arduino/HID.cpp
+++ b/cores/arduino/HID.cpp
@@ -144,7 +144,6 @@ u8 _hid_protocol = 1;
u8 _hid_idle = 1;
#define WEAK __attribute__ ((weak))
-#define WEAK
int WEAK HID_GetInterface(u8* interfaceNum)
{
@@ -202,7 +201,15 @@ bool WEAK HID_Setup(Setup& setup)
//================================================================================
// Mouse
-Mouse_::Mouse_() : _buttons(0)
+Mouse_::Mouse_(void) : _buttons(0)
+{
+}
+
+void Mouse_::begin(void)
+{
+}
+
+void Mouse_::end(void)
{
}
@@ -245,7 +252,7 @@ void Mouse_::release(uint8_t b)
bool Mouse_::isPressed(uint8_t b)
{
- if (b & _buttons > 0)
+ if ((b & _buttons) > 0)
return true;
return false;
}
@@ -254,18 +261,21 @@ bool Mouse_::isPressed(uint8_t b)
//================================================================================
// Keyboard
-Keyboard_::Keyboard_() : _keyMap(0)
+Keyboard_::Keyboard_(void)
{
}
-void Keyboard_::sendReport(KeyReport* keys)
+void Keyboard_::begin(void)
+{
+}
+
+void Keyboard_::end(void)
{
- HID_SendReport(2,keys,sizeof(KeyReport));
}
-void Keyboard_::setKeyMap(KeyMap* keyMap)
+void Keyboard_::sendReport(KeyReport* keys)
{
- _keyMap = keyMap;
+ HID_SendReport(2,keys,sizeof(KeyReport));
}
extern
@@ -406,41 +416,105 @@ const uint8_t _asciimap[128] =
};
uint8_t USBPutChar(uint8_t c);
-size_t Keyboard_::write(uint8_t c)
+
+// press() adds the specified key (printing, non-printing, or modifier)
+// to the persistent key report and sends the report. Because of the way
+// USB HID works, the host acts like the key remains pressed until we
+// call release(), releaseAll(), or otherwise clear the report and resend.
+size_t Keyboard_::press(uint8_t k)
{
- // 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;
+ uint8_t i;
+ if (k >= 136) { // it's a non-printing key (not a modifier)
+ k = k - 136;
+ } else if (k >= 128) { // it's a modifier key
+ _keyReport.modifiers |= (1<<(k-128));
+ k = 0;
+ } else { // it's a printing key
+ k = pgm_read_byte(_asciimap + k);
+ if (!k) {
+ setWriteError();
+ return 0;
+ }
+ if (k & 0x80) { // it's a capital letter or other character reached with shift
+ _keyReport.modifiers |= 0x02; // the left shift modifier
+ k &= 0x7F;
+ }
+ }
+
+ // Add k to the key report only if it's not already present
+ // and if there is an empty slot.
+ if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
+ _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
+ _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
+
+ for (i=0; i<6; i++) {
+ if (_keyReport.keys[i] == 0x00) {
+ _keyReport.keys[i] = k;
+ break;
}
- keys.keys[0] = c;
}
- sendReport(&keys);
+ if (i == 6) {
+ setWriteError();
+ return 0;
+ }
}
- // Keyup
- {
- KeyReport keys = {0};
- sendReport(&keys);
+ sendReport(&_keyReport);
+ return 1;
+}
+
+// release() takes the specified key out of the persistent key report and
+// sends the report. This tells the OS the key is no longer pressed and that
+// it shouldn't be repeated any more.
+size_t Keyboard_::release(uint8_t k)
+{
+ uint8_t i;
+ if (k >= 136) { // it's a non-printing key (not a modifier)
+ k = k - 136;
+ } else if (k >= 128) { // it's a modifier key
+ _keyReport.modifiers &= ~(1<<(k-128));
+ k = 0;
+ } else { // it's a printing key
+ k = pgm_read_byte(_asciimap + k);
+ if (!k) {
+ return 0;
+ }
+ if (k & 0x80) { // it's a capital letter or other character reached with shift
+ _keyReport.modifiers &= ~(0x02); // the left shift modifier
+ k &= 0x7F;
+ }
}
+
+ // Test the key report to see if k is present. Clear it if it exists.
+ // Check all positions in case the key is present more than once (which it shouldn't be)
+ for (i=0; i<6; i++) {
+ if (0 != k && _keyReport.keys[i] == k) {
+ _keyReport.keys[i] = 0x00;
+ }
+ }
+
+ sendReport(&_keyReport);
return 1;
}
+void Keyboard_::releaseAll(void)
+{
+ _keyReport.keys[0] = 0;
+ _keyReport.keys[1] = 0;
+ _keyReport.keys[2] = 0;
+ _keyReport.keys[3] = 0;
+ _keyReport.keys[4] = 0;
+ _keyReport.keys[5] = 0;
+ _keyReport.modifiers = 0;
+ sendReport(&_keyReport);
+}
+
+size_t Keyboard_::write(uint8_t c)
+{
+ uint8_t p = press(c); // Keydown
+ uint8_t r = release(c); // Keyup
+ return (p); // just return the result of press() since release() almost always returns 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 1b1fa71..f40ddee 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -46,8 +46,8 @@
struct ring_buffer
{
unsigned char buffer[SERIAL_BUFFER_SIZE];
- volatile int head;
- volatile int tail;
+ volatile unsigned int head;
+ volatile unsigned int tail;
};
#if defined(USBCON)
@@ -398,6 +398,10 @@ size_t HardwareSerial::write(uint8_t c)
return 1;
}
+HardwareSerial::operator bool() {
+ return true;
+}
+
// Preinstantiate Objects //////////////////////////////////////////////////////
#if defined(UBRRH) && defined(UBRRL)
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index 176abe1..bf4924c 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -57,6 +57,7 @@ class HardwareSerial : public Stream
virtual void flush(void);
virtual size_t write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
+ operator bool();
};
#if defined(UBRRH) || defined(UBRR0H)
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
index ff9b154..711251c 100755
--- a/cores/arduino/Print.cpp
+++ b/cores/arduino/Print.cpp
@@ -41,7 +41,7 @@ size_t Print::write(const uint8_t *buffer, size_t size)
size_t Print::print(const __FlashStringHelper *ifsh)
{
- const prog_char *p = (const prog_char *)ifsh;
+ const char PROGMEM *p = (const char PROGMEM *)ifsh;
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
@@ -226,6 +226,9 @@ size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
+ if (isnan(number)) return print("nan");
+ if (isinf(number)) return print("inf");
+
// Handle negative numbers
if (number < 0.0)
{
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
index 1af6b72..dc76150 100755
--- a/cores/arduino/Print.h
+++ b/cores/arduino/Print.h
@@ -46,7 +46,10 @@ class Print
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)); }
+ size_t write(const char *str) {
+ if (str == NULL) return 0;
+ return write((const uint8_t *)str, strlen(str));
+ }
virtual size_t write(const uint8_t *buffer, size_t size);
size_t print(const __FlashStringHelper *);
diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp
index 5fad8dd..aafb7fc 100644
--- a/cores/arduino/Stream.cpp
+++ b/cores/arduino/Stream.cpp
@@ -99,25 +99,27 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
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
+ return true; // return true if target is a null string
while( (c = timedRead()) > 0){
+
+ if(c != target[index])
+ index = 0; // reset index if any char does not match
+
if( c == target[index]){
- //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
+ //////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
+ if(++termIndex >= termLen)
+ return false; // return false if terminate string found before target string
}
else
- termIndex = 0;
+ termIndex = 0;
}
return false;
}
@@ -242,3 +244,27 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
return index; // return number of characters, not including null terminator
}
+String Stream::readString()
+{
+ String ret;
+ int c = timedRead();
+ while (c >= 0)
+ {
+ ret += (char)c;
+ c = timedRead();
+ }
+ return ret;
+}
+
+String Stream::readStringUntil(char terminator)
+{
+ String ret;
+ int c = timedRead();
+ while (c >= 0 && c != terminator)
+ {
+ ret += (char)c;
+ c = timedRead();
+ }
+ return ret;
+}
+
diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h
index 13f11be..58bbf75 100644
--- a/cores/arduino/Stream.h
+++ b/cores/arduino/Stream.h
@@ -82,6 +82,8 @@ class Stream : public Print
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
+ String readString();
+ String readStringUntil(char terminator);
protected:
long parseInt(char skipChar); // as above but the given skipChar is ignored
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index 26a2032..eb2e593 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -9,17 +9,17 @@
//================================================================================
// USB
-class USB_
+class USBDevice_
{
public:
- USB_();
+ USBDevice_();
bool configured();
void attach();
void detach(); // Serial port goes down too...
void poll();
};
-extern USB_ USB;
+extern USBDevice_ USBDevice;
//================================================================================
//================================================================================
@@ -27,15 +27,20 @@ extern USB_ USB;
class Serial_ : public Stream
{
+private:
+ ring_buffer *_cdc_rx_buffer;
public:
void begin(uint16_t baud_count);
void end(void);
virtual int available(void);
+ virtual void accept(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t);
+ using Print::write; // pull in write(str) and write(buf, size) from Print
+ operator bool();
};
extern Serial_ Serial;
@@ -54,12 +59,14 @@ private:
uint8_t _buttons;
void buttons(uint8_t b);
public:
- Mouse_();
+ Mouse_(void);
+ void begin(void);
+ void end(void);
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
+ bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
};
extern Mouse_ Mouse;
@@ -67,14 +74,42 @@ 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
+#define KEY_LEFT_CTRL 0x80
+#define KEY_LEFT_SHIFT 0x81
+#define KEY_LEFT_ALT 0x82
+#define KEY_LEFT_GUI 0x83
+#define KEY_RIGHT_CTRL 0x84
+#define KEY_RIGHT_SHIFT 0x85
+#define KEY_RIGHT_ALT 0x86
+#define KEY_RIGHT_GUI 0x87
+
+#define KEY_UP_ARROW 0xDA
+#define KEY_DOWN_ARROW 0xD9
+#define KEY_LEFT_ARROW 0xD8
+#define KEY_RIGHT_ARROW 0xD7
+#define KEY_BACKSPACE 0xB2
+#define KEY_TAB 0xB3
+#define KEY_RETURN 0xB0
+#define KEY_ESC 0xB1
+#define KEY_INSERT 0xD1
+#define KEY_DELETE 0xD4
+#define KEY_PAGE_UP 0xD3
+#define KEY_PAGE_DOWN 0xD6
+#define KEY_HOME 0xD2
+#define KEY_END 0xD5
+#define KEY_CAPS_LOCK 0xC1
+#define KEY_F1 0xC2
+#define KEY_F2 0xC3
+#define KEY_F3 0xC4
+#define KEY_F4 0xC5
+#define KEY_F5 0xC6
+#define KEY_F6 0xC7
+#define KEY_F7 0xC8
+#define KEY_F8 0xC9
+#define KEY_F9 0xCA
+#define KEY_F10 0xCB
+#define KEY_F11 0xCC
+#define KEY_F12 0xCD
// Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
@@ -84,24 +119,19 @@ typedef struct
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;
+ KeyReport _keyReport;
void sendReport(KeyReport* keys);
- void setKeyMap(KeyMap* keyMap);
public:
- Keyboard_();
- virtual size_t write(uint8_t);
+ Keyboard_(void);
+ void begin(void);
+ void end(void);
+ virtual size_t write(uint8_t k);
+ virtual size_t press(uint8_t k);
+ virtual size_t release(uint8_t k);
+ virtual void releaseAll(void);
};
extern Keyboard_ Keyboard;
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index 4c71b34..6766be6 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -51,16 +51,20 @@ const u16 STRING_LANGUAGE[2] = {
const u16 STRING_IPRODUCT[17] = {
(3<<8) | (2+2*16),
-#if USB_PID == USB_PID_LEONARDO
+#if USB_PID == 0x8036
'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',' ',' ',' '
+#else
+ 'U','S','B',' ','I','O',' ','B','o','a','r','d',' ',' ',' ',' '
#endif
};
const u16 STRING_IMANUFACTURER[12] = {
(3<<8) | (2+2*11),
+#if USB_VID == 0x2341
'A','r','d','u','i','n','o',' ','L','L','C'
+#else
+ 'U','n','k','n','o','w','n',' ',' ',' ',' '
+#endif
};
#ifdef CDC_ENABLED
@@ -230,7 +234,7 @@ int USB_Recv(u8 ep, void* d, int len)
n = len;
u8* dst = (u8*)d;
while (n--)
- *dst++ = USBD_Recv8();
+ *dst++ = Recv8();
if (len && !FifoByteCount()) // release empty buffer
ReleaseRX();
@@ -599,6 +603,8 @@ ISR(USB_GEN_vect)
{
#ifdef CDC_ENABLED
USB_Flush(CDC_TX); // Send a tx frame if found
+ while (USB_Available(CDC_RX)) // Handle received bytes (if any)
+ Serial.accept();
#endif
// check whether the one-shot period has elapsed. if so, turn off the LED
@@ -621,13 +627,13 @@ u8 USBConnected()
//=======================================================================
//=======================================================================
-USB_ USB;
+USBDevice_ USBDevice;
-USB_::USB_()
+USBDevice_::USBDevice_()
{
}
-void USB_::attach()
+void USBDevice_::attach()
{
_usbConfiguration = 0;
UHWCON = 0x01; // power internal reg
@@ -635,6 +641,12 @@ void USB_::attach()
PLLCSR = 0x12; // Need 16 MHz xtal
while (!(PLLCSR & (1<<PLOCK))) // wait for lock pll
;
+
+ // Some tests on specific versions of macosx (10.7.3), reported some
+ // strange behaviuors when the board is reset using the serial
+ // port touch at 1200 bps. This delay fixes this behaviour.
+ delay(1);
+
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
@@ -642,19 +654,19 @@ void USB_::attach()
TX_RX_LED_INIT;
}
-void USB_::detach()
+void USBDevice_::detach()
{
}
// Check for interrupts
// TODO: VBUS detection
-bool USB_::configured()
+bool USBDevice_::configured()
{
return _usbConfiguration;
}
-void USB_::poll()
+void USBDevice_::poll()
{
}
-#endif /* if defined(USBCON) */ \ No newline at end of file
+#endif /* if defined(USBCON) */
diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h
index 549ed9e..900713e 100644
--- a/cores/arduino/USBDesc.h
+++ b/cores/arduino/USBDesc.h
@@ -60,8 +60,4 @@
#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/WInterrupts.c b/cores/arduino/WInterrupts.c
index 1449cfb..62efc9c 100755..100644
--- a/cores/arduino/WInterrupts.c
+++ b/cores/arduino/WInterrupts.c
@@ -32,7 +32,7 @@
#include "wiring_private.h"
-volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
+static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
// volatile static voidFuncPtr twiIntFunc;
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
@@ -47,7 +47,27 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
// Enable the interrupt.
switch (interruptNum) {
-#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
+#if defined(__AVR_ATmega32U4__)
+ // I hate doing this, but the register assignment differs between the 1280/2560
+ // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
+ // even present on the 32U4 this is the only way to distinguish between them.
+ case 0:
+ EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
+ EIMSK |= (1<<INT0);
+ break;
+ case 1:
+ EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
+ EIMSK |= (1<<INT1);
+ break;
+ case 2:
+ EICRA = (EICRA & ~((1<<ISC20) | (1<<ISC21))) | (mode << ISC20);
+ EIMSK |= (1<<INT2);
+ break;
+ case 3:
+ EICRA = (EICRA & ~((1<<ISC30) | (1<<ISC31))) | (mode << ISC30);
+ EIMSK |= (1<<INT3);
+ break;
+#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
@@ -80,7 +100,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
EIMSK |= (1 << INT7);
break;
-#else
+#else
case 0:
#if defined(EICRA) && defined(ISC00) && defined(EIMSK)
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
@@ -121,8 +141,6 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
#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
@@ -136,7 +154,20 @@ void detachInterrupt(uint8_t interruptNum) {
// to the number of the EIMSK bit to clear, as this isn't true on the
// ATmega8. There, INT0 is 6 and INT1 is 7.)
switch (interruptNum) {
-#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
+#if defined(__AVR_ATmega32U4__)
+ case 0:
+ EIMSK &= ~(1<<INT0);
+ break;
+ case 1:
+ EIMSK &= ~(1<<INT1);
+ break;
+ case 2:
+ EIMSK &= ~(1<<INT2);
+ break;
+ case 3:
+ EIMSK &= ~(1<<INT3);
+ break;
+#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EIMSK &= ~(1 << INT0);
break;
@@ -198,7 +229,28 @@ void attachInterruptTwi(void (*userFunc)(void) ) {
}
*/
-#if defined(EICRA) && defined(EICRB)
+#if defined(__AVR_ATmega32U4__)
+SIGNAL(INT0_vect) {
+ if(intFunc[EXTERNAL_INT_0])
+ intFunc[EXTERNAL_INT_0]();
+}
+
+SIGNAL(INT1_vect) {
+ if(intFunc[EXTERNAL_INT_1])
+ intFunc[EXTERNAL_INT_1]();
+}
+
+SIGNAL(INT2_vect) {
+ if(intFunc[EXTERNAL_INT_2])
+ intFunc[EXTERNAL_INT_2]();
+}
+
+SIGNAL(INT3_vect) {
+ if(intFunc[EXTERNAL_INT_3])
+ intFunc[EXTERNAL_INT_3]();
+}
+
+#elif defined(EICRA) && defined(EICRB)
SIGNAL(INT0_vect) {
if(intFunc[EXTERNAL_INT_2])
diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp
index 3e81331..c6839fc 100644
--- a/cores/arduino/WString.cpp
+++ b/cores/arduino/WString.cpp
@@ -500,7 +500,7 @@ int String::lastIndexOf( char theChar ) const
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
- if (fromIndex >= len || fromIndex < 0) return -1;
+ if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
@@ -516,7 +516,7 @@ int String::lastIndexOf(const String &s2) 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 (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp
index 34450f4..3d4e079 100755..100644
--- a/cores/arduino/main.cpp
+++ b/cores/arduino/main.cpp
@@ -5,7 +5,7 @@ int main(void)
init();
#if defined(USBCON)
- USB.attach();
+ USBDevice.attach();
#endif
setup();
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
index e7f7cde..ac8bb6f 100755..100644
--- a/cores/arduino/wiring.c
+++ b/cores/arduino/wiring.c
@@ -278,12 +278,21 @@ void init()
sbi(TCCR3B, CS30);
sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
#endif
-
+
+#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
+ sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
+ sbi(TCCR4B, CS41);
+ sbi(TCCR4B, CS40);
+ sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
+ sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
+ sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
+#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
sbi(TCCR4B, CS40);
sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
#endif
+#endif /* end timer4 block for ATMEGA1280/2560 and similar */
#if defined(TCCR5B) && defined(CS51) && defined(WGM50)
sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c
index 902b153..0e9881f 100644
--- a/cores/arduino/wiring_analog.c
+++ b/cores/arduino/wiring_analog.c
@@ -45,6 +45,8 @@ int analogRead(uint8_t pin)
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
+#elif defined(__AVR_ATmega1284__)
+ if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif
@@ -204,14 +206,17 @@ void analogWrite(uint8_t pin, int val)
break;
#endif
- #if defined(TCCR4A) && defined(COM4A1)
+ #if defined(TCCR4A)
case TIMER4A:
- // connect pwm to pin on timer 4, channel A
+ //connect pwm to pin on timer 4, channel A
sbi(TCCR4A, COM4A1);
- OCR4A = val; // set pwm duty
+ #if defined(COM4A0) // only used on 32U4
+ cbi(TCCR4A, COM4A0);
+ #endif
+ OCR4A = val; // set pwm duty
break;
#endif
-
+
#if defined(TCCR4A) && defined(COM4B1)
case TIMER4B:
// connect pwm to pin on timer 4, channel B
@@ -228,14 +233,18 @@ void analogWrite(uint8_t pin, int val)
break;
#endif
- #if defined(TCCR4A) && defined(COM4D1)
- case TIMER4D:
+ #if defined(TCCR4C) && defined(COM4D1)
+ case TIMER4D:
// connect pwm to pin on timer 4, channel D
- sbi(TCCR4A, COM4D1);
- OCR4D = val; // set pwm duty
+ sbi(TCCR4C, COM4D1);
+ #if defined(COM4D0) // only used on 32U4
+ cbi(TCCR4C, COM4D0);
+ #endif
+ OCR4D = val; // set pwm duty
break;
#endif
+
#if defined(TCCR5A) && defined(COM5A1)
case TIMER5A:
// connect pwm to pin on timer 5, channel A
@@ -270,3 +279,4 @@ void analogWrite(uint8_t pin, int val)
}
}
}
+
diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c
index 97ef134..be323b1 100755..100644
--- a/cores/arduino/wiring_digital.c
+++ b/cores/arduino/wiring_digital.c
@@ -32,17 +32,25 @@ void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
- volatile uint8_t *reg;
+ volatile uint8_t *reg, *out;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
+ out = portOutputRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
+ *out &= ~bit;
+ SREG = oldSREG;
+ } else if (mode == INPUT_PULLUP) {
+ uint8_t oldSREG = SREG;
+ cli();
+ *reg &= ~bit;
+ *out |= bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
@@ -107,13 +115,17 @@ static void turnOffPWM(uint8_t timer)
#if defined(TCCR4A) && defined(COM4A1)
case TIMER4A: cbi(TCCR4A, COM4A1); break;
- #endif
+ #endif
#if defined(TCCR4A) && defined(COM4B1)
case TIMER4B: cbi(TCCR4A, COM4B1); break;
#endif
#if defined(TCCR4A) && defined(COM4C1)
case TIMER4C: cbi(TCCR4A, COM4C1); break;
- #endif
+ #endif
+ #if defined(TCCR4C) && defined(COM4D1)
+ case TIMER4D: cbi(TCCR4C, COM4D1); break;
+ #endif
+
#if defined(TCCR5A)
case TIMER5A: cbi(TCCR5A, COM5A1); break;
case TIMER5B: cbi(TCCR5A, COM5B1); break;
diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h
index f0ceb0c..026ce1a 100755
--- a/cores/arduino/wiring_private.h
+++ b/cores/arduino/wiring_private.h
@@ -56,6 +56,8 @@ extern "C"{
#define EXTERNAL_NUM_INTERRUPTS 8
#elif defined(__AVR_ATmega1284P__)
#define EXTERNAL_NUM_INTERRUPTS 3
+#elif defined(__AVR_ATmega32U4__)
+#define EXTERNAL_NUM_INTERRUPTS 4
#else
#define EXTERNAL_NUM_INTERRUPTS 2
#endif
diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
index 88e3488..0709b2d 100644
--- a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
+++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
@@ -14,7 +14,11 @@ byte value;
void setup()
{
+ // initialize serial and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
}
void loop()
diff --git a/libraries/Ethernet/Dhcp.cpp b/libraries/Ethernet/Dhcp.cpp
index 62bbfeb..e4d27f7 100755
--- a/libraries/Ethernet/Dhcp.cpp
+++ b/libraries/Ethernet/Dhcp.cpp
@@ -11,13 +11,33 @@
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
{
- uint8_t dhcp_state = STATE_DHCP_START;
- uint8_t messageType = 0;
-
- // zero out _dhcpMacAddr, _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
- memset(_dhcpMacAddr, 0, 26);
+ _dhcpLeaseTime=0;
+ _dhcpT1=0;
+ _dhcpT2=0;
+ _lastCheck=0;
+ _timeout = timeout;
+ _responseTimeout = responseTimeout;
+
+ // zero out _dhcpMacAddr
+ memset(_dhcpMacAddr, 0, 6);
+ reset_DHCP_lease();
memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
+ _dhcp_state = STATE_DHCP_START;
+ return request_DHCP_lease();
+}
+
+void DhcpClass::reset_DHCP_lease(){
+ // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
+ memset(_dhcpLocalIp, 0, 20);
+}
+
+//return:0 on error, 1 if request is sent and response is received
+int DhcpClass::request_DHCP_lease(){
+
+ uint8_t messageType = 0;
+
+
// Pick an initial transaction ID
_dhcpTransactionId = random(1UL, 2000UL);
@@ -35,55 +55,75 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long
unsigned long startTime = millis();
- while(dhcp_state != STATE_DHCP_LEASED)
+ while(_dhcp_state != STATE_DHCP_LEASED)
{
- if(dhcp_state == STATE_DHCP_START)
+ if(_dhcp_state == STATE_DHCP_START)
{
_dhcpTransactionId++;
send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
- dhcp_state = STATE_DHCP_DISCOVER;
+ _dhcp_state = STATE_DHCP_DISCOVER;
+ }
+ else if(_dhcp_state == STATE_DHCP_REREQUEST){
+ _dhcpTransactionId++;
+ send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
+ _dhcp_state = STATE_DHCP_REQUEST;
}
- else if(dhcp_state == STATE_DHCP_DISCOVER)
+ else if(_dhcp_state == STATE_DHCP_DISCOVER)
{
uint32_t respId;
- messageType = parseDHCPResponse(responseTimeout, respId);
+ messageType = parseDHCPResponse(_responseTimeout, respId);
if(messageType == DHCP_OFFER)
{
// We'll use the transaction ID that the offer came with,
// rather than the one we were up to
_dhcpTransactionId = respId;
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
- dhcp_state = STATE_DHCP_REQUEST;
+ _dhcp_state = STATE_DHCP_REQUEST;
}
}
- else if(dhcp_state == STATE_DHCP_REQUEST)
+ else if(_dhcp_state == STATE_DHCP_REQUEST)
{
uint32_t respId;
- messageType = parseDHCPResponse(responseTimeout, respId);
+ messageType = parseDHCPResponse(_responseTimeout, respId);
if(messageType == DHCP_ACK)
{
- dhcp_state = STATE_DHCP_LEASED;
+ _dhcp_state = STATE_DHCP_LEASED;
result = 1;
+ //use default lease time if we didn't get it
+ if(_dhcpLeaseTime == 0){
+ _dhcpLeaseTime = DEFAULT_LEASE;
+ }
+ //calculate T1 & T2 if we didn't get it
+ if(_dhcpT1 == 0){
+ //T1 should be 50% of _dhcpLeaseTime
+ _dhcpT1 = _dhcpLeaseTime >> 1;
+ }
+ if(_dhcpT2 == 0){
+ //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
+ _dhcpT2 = _dhcpT1 << 1;
+ }
+ _renewInSec = _dhcpT1;
+ _rebindInSec = _dhcpT2;
}
else if(messageType == DHCP_NAK)
- dhcp_state = STATE_DHCP_START;
+ _dhcp_state = STATE_DHCP_START;
}
if(messageType == 255)
{
messageType = 0;
- dhcp_state = STATE_DHCP_START;
+ _dhcp_state = STATE_DHCP_START;
}
- if(result != 1 && ((millis() - startTime) > timeout))
+ if(result != 1 && ((millis() - startTime) > _timeout))
break;
}
// We're done with the socket now
_dhcpUdpSocket.stop();
_dhcpTransactionId++;
-
+
return result;
}
@@ -302,8 +342,26 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
}
}
break;
-
+
+ case dhcpT1value :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
+ _dhcpT1 = ntohl(_dhcpT1);
+ break;
+
+ case dhcpT2value :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
+ _dhcpT2 = ntohl(_dhcpT2);
+ break;
+
case dhcpIPaddrLeaseTime :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
+ _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
+ _renewInSec = _dhcpLeaseTime;
+ break;
+
default :
opt_len = _dhcpUdpSocket.read();
// Skip over the rest of this option
@@ -322,6 +380,68 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
return type;
}
+
+/*
+ returns:
+ 0/DHCP_CHECK_NONE: nothing happened
+ 1/DHCP_CHECK_RENEW_FAIL: renew failed
+ 2/DHCP_CHECK_RENEW_OK: renew success
+ 3/DHCP_CHECK_REBIND_FAIL: rebind fail
+ 4/DHCP_CHECK_REBIND_OK: rebind success
+*/
+int DhcpClass::checkLease(){
+ //this uses a signed / unsigned trick to deal with millis overflow
+ unsigned long now = millis();
+ signed long snow = (long)now;
+ int rc=DHCP_CHECK_NONE;
+ if (_lastCheck != 0){
+ signed long factor;
+ //calc how many ms past the timeout we are
+ factor = snow - (long)_secTimeout;
+ //if on or passed the timeout, reduce the counters
+ if ( factor >= 0 ){
+ //next timeout should be now plus 1000 ms minus parts of second in factor
+ _secTimeout = snow + 1000 - factor % 1000;
+ //how many seconds late are we, minimum 1
+ factor = factor / 1000 +1;
+
+ //reduce the counters by that mouch
+ //if we can assume that the cycle time (factor) is fairly constant
+ //and if the remainder is less than cycle time * 2
+ //do it early instead of late
+ if(_renewInSec < factor*2 )
+ _renewInSec = 0;
+ else
+ _renewInSec -= factor;
+
+ if(_rebindInSec < factor*2 )
+ _rebindInSec = 0;
+ else
+ _rebindInSec -= factor;
+ }
+
+ //if we have a lease but should renew, do it
+ if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
+ _dhcp_state = STATE_DHCP_REREQUEST;
+ rc = 1 + request_DHCP_lease();
+ }
+
+ //if we have a lease or is renewing but should bind, do it
+ if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
+ //this should basically restart completely
+ _dhcp_state = STATE_DHCP_START;
+ reset_DHCP_lease();
+ rc = 3 + request_DHCP_lease();
+ }
+ }
+ else{
+ _secTimeout = snow + 1000;
+ }
+
+ _lastCheck = now;
+ return rc;
+}
+
IPAddress DhcpClass::getLocalIp()
{
return IPAddress(_dhcpLocalIp);
diff --git a/libraries/Ethernet/Dhcp.h b/libraries/Ethernet/Dhcp.h
index 149876d..4a47936 100755
--- a/libraries/Ethernet/Dhcp.h
+++ b/libraries/Ethernet/Dhcp.h
@@ -45,6 +45,13 @@
#define MAX_DHCP_OPT 16
#define HOST_NAME "WIZnet"
+#define DEFAULT_LEASE (900) //default lease time in seconds
+
+#define DHCP_CHECK_NONE (0)
+#define DHCP_CHECK_RENEW_FAIL (1)
+#define DHCP_CHECK_RENEW_OK (2)
+#define DHCP_CHECK_REBIND_FAIL (3)
+#define DHCP_CHECK_REBIND_OK (4)
enum
{
@@ -139,8 +146,19 @@ private:
uint8_t _dhcpGatewayIp[4];
uint8_t _dhcpDhcpServerIp[4];
uint8_t _dhcpDnsServerIp[4];
+ uint32_t _dhcpLeaseTime;
+ uint32_t _dhcpT1, _dhcpT2;
+ signed long _renewInSec;
+ signed long _rebindInSec;
+ signed long _lastCheck;
+ unsigned long _timeout;
+ unsigned long _responseTimeout;
+ unsigned long _secTimeout;
+ uint8_t _dhcp_state;
EthernetUDP _dhcpUdpSocket;
+ int request_DHCP_lease();
+ void reset_DHCP_lease();
void presend_DHCP();
void send_DHCP_MESSAGE(uint8_t, uint16_t);
void printByte(char *, uint8_t);
@@ -154,6 +172,7 @@ public:
IPAddress getDnsServerIp();
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
+ int checkLease();
};
#endif
diff --git a/libraries/Ethernet/Ethernet.cpp b/libraries/Ethernet/Ethernet.cpp
index c298f3d..5d28f71 100644
--- a/libraries/Ethernet/Ethernet.cpp
+++ b/libraries/Ethernet/Ethernet.cpp
@@ -10,7 +10,8 @@ uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
int EthernetClass::begin(uint8_t *mac_address)
{
- DhcpClass dhcp;
+ _dhcp = new DhcpClass();
+
// Initialise the basic info
W5100.init();
@@ -18,15 +19,15 @@ int EthernetClass::begin(uint8_t *mac_address)
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
// Now try to get our config info from a DHCP server
- int ret = dhcp.beginWithDHCP(mac_address);
+ int ret = _dhcp->beginWithDHCP(mac_address);
if(ret == 1)
{
// We've successfully found a DHCP server and got our configuration info, so set things
// accordingly
- W5100.setIPAddress(dhcp.getLocalIp().raw_address());
- W5100.setGatewayIp(dhcp.getGatewayIp().raw_address());
- W5100.setSubnetMask(dhcp.getSubnetMask().raw_address());
- _dnsServerAddress = dhcp.getDnsServerIp();
+ W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
+ W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
}
return ret;
@@ -66,6 +67,31 @@ void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server
_dnsServerAddress = dns_server;
}
+int EthernetClass::maintain(){
+ int rc = DHCP_CHECK_NONE;
+ if(_dhcp != NULL){
+ //we have a pointer to dhcp, use it
+ rc = _dhcp->checkLease();
+ switch ( rc ){
+ case DHCP_CHECK_NONE:
+ //nothing done
+ break;
+ case DHCP_CHECK_RENEW_OK:
+ case DHCP_CHECK_REBIND_OK:
+ //we might have got a new IP.
+ W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
+ W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
+ break;
+ default:
+ //this is actually a error, it will retry though
+ break;
+ }
+ }
+ return rc;
+}
+
IPAddress EthernetClass::localIP()
{
IPAddress ret;
diff --git a/libraries/Ethernet/Ethernet.h b/libraries/Ethernet/Ethernet.h
index c916dda..2a07ff3 100644
--- a/libraries/Ethernet/Ethernet.h
+++ b/libraries/Ethernet/Ethernet.h
@@ -6,12 +6,14 @@
#include "IPAddress.h"
#include "EthernetClient.h"
#include "EthernetServer.h"
+#include "Dhcp.h"
#define MAX_SOCK_NUM 4
class EthernetClass {
private:
IPAddress _dnsServerAddress;
+ DhcpClass* _dhcp;
public:
static uint8_t _state[MAX_SOCK_NUM];
static uint16_t _server_port[MAX_SOCK_NUM];
@@ -23,6 +25,7 @@ public:
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);
+ int maintain();
IPAddress localIP();
IPAddress subnetMask();
diff --git a/libraries/Ethernet/EthernetClient.cpp b/libraries/Ethernet/EthernetClient.cpp
index a77a62b..9885efb 100644
--- a/libraries/Ethernet/EthernetClient.cpp
+++ b/libraries/Ethernet/EthernetClient.cpp
@@ -41,7 +41,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
- if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
_sock = i;
break;
}
diff --git a/libraries/Ethernet/EthernetUdp.cpp b/libraries/Ethernet/EthernetUdp.cpp
index 9c752fc..3760052 100644
--- a/libraries/Ethernet/EthernetUdp.cpp
+++ b/libraries/Ethernet/EthernetUdp.cpp
@@ -52,15 +52,16 @@ uint8_t EthernetUDP::begin(uint16_t port) {
return 0;
_port = port;
+ _remaining = 0;
socket(_sock, SnMR::UDP, _port, 0);
return 1;
}
-/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
- * returned value includes 8 byte UDP header!*/
+/* return number of bytes available in the current packet,
+ will return zero if parsePacket hasn't been called yet */
int EthernetUDP::available() {
- return W5100.getRXReceivedSize(_sock);
+ return _remaining;
}
/* Release any resources being used by this EthernetUDP instance */
@@ -116,11 +117,14 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
int EthernetUDP::parsePacket()
{
- if (available() > 0)
+ // discard any remaining bytes in the last packet
+ flush();
+
+ if (W5100.getRXReceivedSize(_sock) > 0)
{
//HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8];
- int ret =0;
+ int ret =0;
//read 8 header bytes and get IP and port from it
ret = recv(_sock,tmpBuf,8);
if (ret > 0)
@@ -128,8 +132,11 @@ int EthernetUDP::parsePacket()
_remoteIP = tmpBuf;
_remotePort = tmpBuf[4];
_remotePort = (_remotePort << 8) + tmpBuf[5];
+ _remaining = tmpBuf[6];
+ _remaining = (_remaining << 8) + tmpBuf[7];
+
// When we get here, any remaining bytes are the data
- ret = available();
+ ret = _remaining;
}
return ret;
}
@@ -140,34 +147,58 @@ int EthernetUDP::parsePacket()
int EthernetUDP::read()
{
uint8_t byte;
- if (recv(_sock, &byte, 1) > 0)
+
+ if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
{
// We read things without any problems
+ _remaining--;
return byte;
}
+
// If we get here, there's no data available
return -1;
}
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
- at a time.
- int i;
- for(i=0;i<(int)bufLen;i++) {
- recv(_sock,tmpBuf,1);
- buf[i]=tmpBuf[0];
+
+ if (_remaining > 0)
+ {
+
+ int got;
+
+ if (_remaining <= len)
+ {
+ // data should fit in the buffer
+ got = recv(_sock, buffer, _remaining);
+ }
+ else
+ {
+ // too much data for the buffer,
+ // grab as much as will fit
+ got = recv(_sock, buffer, len);
+ }
+
+ if (got > 0)
+ {
+ _remaining -= got;
+ return got;
+ }
+
}
- */
- return recv(_sock, buffer, len);
+
+ // If we get here, there's no data available or recv failed
+ return -1;
+
}
int EthernetUDP::peek()
{
uint8_t b;
- // Unlike recv, peek doesn't check to see if there's any data available, so we must
- if (!available())
+ // Unlike recv, peek doesn't check to see if there's any data available, so we must.
+ // If the user hasn't called parsePacket yet then return nothing otherwise they
+ // may get the UDP header
+ if (!_remaining)
return -1;
::peek(_sock, &b);
return b;
@@ -175,7 +206,11 @@ int EthernetUDP::peek()
void EthernetUDP::flush()
{
- while (available())
+ // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
+ // should only occur if recv fails after telling us the data is there, lets
+ // hope the w5100 always behaves :)
+
+ while (_remaining)
{
read();
}
diff --git a/libraries/Ethernet/EthernetUdp.h b/libraries/Ethernet/EthernetUdp.h
index 9a2b653..8a6b7ab 100644
--- a/libraries/Ethernet/EthernetUdp.h
+++ b/libraries/Ethernet/EthernetUdp.h
@@ -48,6 +48,7 @@ private:
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
uint16_t _offset; // offset into the packet being sent
+ uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
public:
EthernetUDP(); // Constructor
diff --git a/libraries/Ethernet/examples/ChatServer/ChatServer.ino b/libraries/Ethernet/examples/ChatServer/ChatServer.ino
index 9f819fd..d50e5a6 100644
--- a/libraries/Ethernet/examples/ChatServer/ChatServer.ino
+++ b/libraries/Ethernet/examples/ChatServer/ChatServer.ino
@@ -12,7 +12,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 10 August 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -23,41 +23,57 @@
// 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[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte mac[] = {
+ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
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
+boolean alreadyConnected = false; // whether or not the client was connected previously
void setup() {
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
- // open the serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
+ Serial.print("Chat server address:");
+ Serial.println(Ethernet.localIP());
}
void loop() {
// wait for a new client:
EthernetClient client = server.available();
-
+
// when the client sends the first byte, say hello:
if (client) {
- if (!gotAMessage) {
+ if (!alreadyConnected) {
+ // clead out the input buffer:
+ client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
- gotAMessage = true;
+ alreadyConnected = true;
+ }
+
+ if (client.available() > 0) {
+ // 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.write(thisChar);
}
-
- // 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/CosmClient/CosmClient.ino b/libraries/Ethernet/examples/CosmClient/CosmClient.ino
new file mode 100644
index 0000000..22815af
--- /dev/null
+++ b/libraries/Ethernet/examples/CosmClient/CosmClient.ino
@@ -0,0 +1,159 @@
+/*
+ Cosm sensor client
+
+ This sketch connects an analog sensor to Cosm (http://www.cosm.com)
+ using a Wiznet Ethernet shield. 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 has been updated to use version 2.0 of the cosm.com API.
+ To make it work, create a feed with a datastream, and give it the ID
+ sensor1. Or change the code below to match your feed.
+
+
+ Circuit:
+ * Analog sensor attached to analog in 0
+ * Ethernet shield attached to pins 10, 11, 12, 13
+
+ created 15 March 2010
+ updated 14 May 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
+
+http://arduino.cc/en/Tutorial/CosmClient
+ This code is in the public domain.
+
+ */
+
+#include <SPI.h>
+#include <Ethernet.h>
+
+#define APIKEY "YOUR API KEY GOES HERE" // replace your Cosm api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
+// assign a MAC address for the ethernet controller.
+// Newer Ethernet shields have a MAC address printed on a sticker on the shield
+// 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:
+EthernetClient client;
+
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+//IPAddress server(216,52,233,121); // numeric IP for api.cosm.com
+char server[] = "api.cosm.com"; // name address for cosm API
+
+unsigned 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 unsigned long postingInterval = 10*1000; //delay between updates to cosm.com
+
+void setup() {
+ // start serial port:
+ Serial.begin(9600);
+ // start the Ethernet connection:
+ if (Ethernet.begin(mac) == 0) {
+ Serial.println("Failed to configure Ethernet using DHCP");
+ // DHCP failed, so use a fixed IP address:
+ Ethernet.begin(mac, ip);
+ }
+}
+
+void loop() {
+ // read the analog sensor:
+ int sensorReading = analogRead(A0);
+
+ // if there's incoming data from the net connection.
+ // send it out the serial port. This is for debugging
+ // purposes only:
+ if (client.available()) {
+ char c = client.read();
+ Serial.print(c);
+ }
+
+ // if there's no net connection, but there was one last time
+ // through the loop, then stop the client:
+ if (!client.connected() && lastConnected) {
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+
+ // if you're not connected, and ten seconds have passed since
+ // your last connection, then connect again and send data:
+ if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
+ sendData(sensorReading);
+ }
+ // store the state of the connection for next time through
+ // the loop:
+ lastConnected = client.connected();
+}
+
+// this method makes a HTTP connection to the server:
+void sendData(int thisData) {
+ // if there's a successful connection:
+ if (client.connect(server, 80)) {
+ Serial.println("connecting...");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.cosm.com");
+ client.print("X-ApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
+ client.print("Content-Length: ");
+
+ // calculate the length of the sensor reading in bytes:
+ // 8 bytes for "sensor1," + number of digits of the data:
+ int thisLength = 8 + getLength(thisData);
+ client.println(thisLength);
+
+ // last pieces of the HTTP PUT request:
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
+
+ // here's the actual content of the PUT request:
+ client.print("sensor1,");
+ client.println(thisData);
+
+ }
+ else {
+ // if you couldn't make a connection:
+ Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
+}
+
+
+// This method calculates the number of digits in the
+// sensor reading. Since each digit of the ASCII decimal
+// representation is a byte, the number of digits equals
+// the number of bytes:
+
+int getLength(int someValue) {
+ // there's at least one byte:
+ int digits = 1;
+ // continually divide the value by ten,
+ // adding one to the digit count for each
+ // time you divide, until you're at 0:
+ int dividend = someValue /10;
+ while (dividend > 0) {
+ dividend = dividend /10;
+ digits++;
+ }
+ // return the number of digits:
+ return digits;
+}
+
diff --git a/libraries/Ethernet/examples/CosmClientString/CosmClientString.ino b/libraries/Ethernet/examples/CosmClientString/CosmClientString.ino
new file mode 100644
index 0000000..05b549b
--- /dev/null
+++ b/libraries/Ethernet/examples/CosmClientString/CosmClientString.ino
@@ -0,0 +1,146 @@
+/*
+ Cosm sensor client with Strings
+
+ This sketch connects an analog sensor to Cosm (http://www.cosm.com)
+ using a Wiznet Ethernet shield. 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 has been updated to use version 2.0 of the Cosm.com API.
+ To make it work, create a feed with two datastreams, and give them the IDs
+ sensor1 and sensor2. Or change the code below to match your feed.
+
+ This example uses the String library, which is part of the Arduino core from
+ version 0019.
+
+ Circuit:
+ * Analog sensor attached to analog in 0
+ * Ethernet shield attached to pins 10, 11, 12, 13
+
+ created 15 March 2010
+ updated 14 May 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
+
+ http://arduino.cc/en/Tutorial/CosmClientString
+ This code is in the public domain.
+
+ */
+
+#include <SPI.h>
+#include <Ethernet.h>
+
+
+#define APIKEY "YOUR API KEY GOES HERE" // replace your Cosm api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
+// assign a MAC address for the ethernet controller.
+// 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:
+EthernetClient client;
+
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+//IPAddress server(216,52,233,121); // numeric IP for api.cosm.com
+char server[] = "api.cosm.com"; // name address for Cosm API
+
+unsigned 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 unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
+
+void setup() {
+ // 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");
+ // DHCP failed, so use a fixed IP address:
+ Ethernet.begin(mac, ip);
+ }
+}
+
+void loop() {
+ // read the analog sensor:
+ int sensorReading = analogRead(A0);
+ // convert the data to a String to send it:
+
+ String dataString = "sensor1,";
+ dataString += sensorReading;
+
+ // you can append multiple readings to this String if your
+ // Cosm feed is set up to handle multiple values:
+ int otherSensorReading = analogRead(A1);
+ dataString += "\nsensor2,";
+ dataString += otherSensorReading;
+
+ // if there's incoming data from the net connection.
+ // send it out the serial port. This is for debugging
+ // purposes only:
+ if (client.available()) {
+ char c = client.read();
+ Serial.print(c);
+ }
+
+ // if there's no net connection, but there was one last time
+ // through the loop, then stop the client:
+ if (!client.connected() && lastConnected) {
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+
+ // if you're not connected, and ten seconds have passed since
+ // your last connection, then connect again and send data:
+ if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
+ sendData(dataString);
+ }
+ // store the state of the connection for next time through
+ // the loop:
+ lastConnected = client.connected();
+}
+
+// this method makes a HTTP connection to the server:
+void sendData(String thisData) {
+ // if there's a successful connection:
+ if (client.connect(server, 80)) {
+ Serial.println("connecting...");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.cosm.com");
+ client.print("X-ApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
+ client.print("Content-Length: ");
+ client.println(thisData.length());
+
+ // last pieces of the HTTP PUT request:
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
+
+ // here's the actual content of the PUT request:
+ client.println(thisData);
+ }
+ else {
+ // if you couldn't make a connection:
+ Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
+}
+
diff --git a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
index 630dd17..5eaaf24 100644
--- a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
+++ b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
@@ -9,6 +9,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 12 April 2011
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -27,8 +28,13 @@ byte mac[] = {
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ // this check is only needed on the Leonardo:
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
index 5082054..09cbd43 100644
--- a/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
+++ b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
@@ -12,6 +12,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 21 May 2011
+ modified 9 Apr 2012
by Tom Igoe
Based on ChatServer example by David A. Mellis
@@ -34,8 +35,14 @@ EthernetServer server(23);
boolean gotAMessage = false; // whether or not you got a message from the client yet
void setup() {
- // open the serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ // this check is only needed on the Leonardo:
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection:
Serial.println("Trying to get an IP address using DHCP");
if (Ethernet.begin(mac) == 0) {
diff --git a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
index 5c7a53a..c14abf4 100644
--- a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
+++ b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
@@ -9,7 +9,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 12 April 2011
+ modified 9 Apr 2012
by Tom Igoe, based on work by Adrian McEwen
*/
@@ -28,8 +28,13 @@ char serverName[] = "www.google.com";
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
index a169443..dfd2d40 100644
--- a/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
+++ b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
@@ -6,15 +6,20 @@
the Adafruit Ethernet shield, either one will work, as long as it's got
a Wiznet Ethernet module on board.
+ This example has been updated to use version 2.0 of the Pachube.com API.
+ To make it work, create a feed with a datastream, and give it the ID
+ sensor1. Or change the code below to match your feed.
+
+
Circuit:
* Analog sensor attached to analog in 0
* Ethernet shield attached to pins 10, 11, 12, 13
created 15 March 2010
- updated 26 Oct 2011
- by Tom Igoe
+ modified 9 Apr 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
- http://www.tigoe.net/pcomp/code/category/arduinowiring/873
+http://arduino.cc/en/Tutorial/PachubeClient
This code is in the public domain.
*/
@@ -22,6 +27,10 @@
#include <SPI.h>
#include <Ethernet.h>
+#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
// assign a MAC address for the ethernet controller.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// fill in your address here:
@@ -34,26 +43,27 @@ IPAddress ip(10,0,1,20);
// initialize the library instance:
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
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+IPAddress server(216,52,233,122); // numeric IP for api.pachube.com
+//char server[] = "api.pachube.com"; // name address for pachube API
+
+unsigned 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 unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com
void setup() {
- // start serial port:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
- // 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(;;)
- ;
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
}
- // give the ethernet module time to boot up:
- delay(1000);
- // start the Ethernet connection:
+
+
+ // start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
- // Configure manually:
+ // DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}
@@ -91,34 +101,43 @@ void loop() {
// this method makes a HTTP connection to the server:
void sendData(int thisData) {
// if there's a successful connection:
- if (client.connect("www.pachube.com", 80)) {
+ if (client.connect(server, 80)) {
Serial.println("connecting...");
- // send the HTTP PUT request.
- // fill in your feed address here:
- client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
- client.print("Host: www.pachube.com\n");
- // fill in your Pachube API key here:
- client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.pachube.com");
+ client.print("X-PachubeApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
client.print("Content-Length: ");
// calculate the length of the sensor reading in bytes:
- int thisLength = getLength(thisData);
- client.println(thisLength, DEC);
+ // 8 bytes for "sensor1," + number of digits of the data:
+ int thisLength = 8 + getLength(thisData);
+ client.println(thisLength);
// last pieces of the HTTP PUT request:
- client.print("Content-Type: text/csv\n");
- client.println("Connection: close\n");
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
// here's the actual content of the PUT request:
- client.println(thisData, DEC);
-
- // note the time that the connection was made:
- lastConnectionTime = millis();
+ client.print("sensor1,");
+ client.println(thisData);
+
}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
}
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
}
diff --git a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
index 4a03100..2a96e9f 100644
--- a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
+++ b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
@@ -1,11 +1,15 @@
/*
- Pachube sensor client with Strings
+ Cosm sensor client with Strings
- This sketch connects an analog sensor to Pachube (http://www.pachube.com)
+ This sketch connects an analog sensor to Cosm (http://www.cosm.com)
using a Wiznet Ethernet shield. 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 has been updated to use version 2.0 of the Cosm.com API.
+ To make it work, create a feed with two datastreams, and give them the IDs
+ sensor1 and sensor2. Or change the code below to match your feed.
+
This example uses the String library, which is part of the Arduino core from
version 0019.
@@ -14,9 +18,10 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 15 March 2010
- updated 26 Oct 2011
- by Tom Igoe
+ modified 9 Apr 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
+ http://arduino.cc/en/Tutorial/CosmClientString
This code is in the public domain.
*/
@@ -24,10 +29,17 @@
#include <SPI.h>
#include <Ethernet.h>
+
+/#define APIKEY "YOUR API KEY GOES HERE" // replace your Cosm api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
+
// assign a MAC address for the ethernet controller.
// fill in your address here:
-byte mac[] = {
+ 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);
@@ -35,19 +47,29 @@ IPAddress ip(10,0,1,20);
// initialize the library instance:
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
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+IPAddress server(216,52,233,121); // numeric IP for api.cosm.com
+//char server[] = "api.cosm.com"; // name address for Cosm API
+
+unsigned 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 unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
void setup() {
- // start serial port:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// 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:
+ // DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}
@@ -56,13 +78,15 @@ void loop() {
// read the analog sensor:
int sensorReading = analogRead(A0);
// convert the data to a String to send it:
- String dataString = String(sensorReading);
+
+ String dataString = "sensor1,";
+ dataString += sensorReading;
// you can append multiple readings to this String if your
- // pachube feed is set up to handle multiple values:
+ // Cosm feed is set up to handle multiple values:
int otherSensorReading = analogRead(A1);
- dataString += ",";
- dataString += String(otherSensorReading);
+ dataString += "\nsensor2,";
+ dataString += otherSensorReading;
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
@@ -81,7 +105,7 @@ void loop() {
}
// if you're not connected, and ten seconds have passed since
- // your last connection, then connect again and send data:
+ // your last connection, then connect again and send data:
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
sendData(dataString);
}
@@ -93,29 +117,36 @@ void loop() {
// this method makes a HTTP connection to the server:
void sendData(String thisData) {
// if there's a successful connection:
- if (client.connect("www.pachube.com", 80)) {
+ if (client.connect(server, 80)) {
Serial.println("connecting...");
- // send the HTTP PUT request.
- // fill in your feed address here:
- client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
- client.print("Host: www.pachube.com\n");
- // fill in your Pachube API key here:
- client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.cosm.com");
+ client.print("X-CosmApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
client.print("Content-Length: ");
- client.println(thisData.length(), DEC);
+ client.println(thisData.length());
// last pieces of the HTTP PUT request:
- client.print("Content-Type: text/csv\n");
- client.println("Connection: close\n");
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
// here's the actual content of the PUT request:
client.println(thisData);
-
- // note the time that the connection was made:
- lastConnectionTime = millis();
}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
}
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
}
+
diff --git a/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
index 5cf1ad8..3457125 100644
--- a/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
+++ b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
@@ -13,6 +13,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 14 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -38,8 +39,13 @@ EthernetClient client;
void setup() {
// start the Ethernet connection:
Ethernet.begin(mac, ip);
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
diff --git a/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
index f113e17..3587d72 100644
--- a/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
+++ b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
@@ -14,9 +14,10 @@
version 0019.
Circuit:
- * Ethernet shield attached to pins 10, 11, 12, 13
+ * Ethernet shield attached to pins 10, 11, 12, 13
created 21 May 2011
+ modified 9 Apr 2012
by Tom Igoe
This code is in the public domain.
@@ -35,12 +36,12 @@ IPAddress ip(192,168,1,20);
// initialize the library instance:
EthernetClient client;
-const int requestInterval = 60000; // delay between requests
+const unsigned long 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
+unsigned 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
@@ -51,13 +52,22 @@ void setup() {
currentLine.reserve(256);
tweet.reserve(150);
-// initialize serial:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// attempt a DHCP connection:
+ Serial.println("Attempting to get an IP address using DHCP:");
if (!Ethernet.begin(mac)) {
// if DHCP fails, start with a hard-coded address:
+ Serial.println("failed to get an IP address using DHCP, trying manually");
Ethernet.begin(mac, ip);
}
+ Serial.print("My address:");
+ Serial.println(Ethernet.localIP());
// connect to Twitter:
connectToServer();
}
@@ -114,7 +124,7 @@ void connectToServer() {
Serial.println("connecting to server...");
if (client.connect(serverName, 80)) {
Serial.println("making HTTP request...");
- // make HTTP GET request to twitter:
+ // 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();
@@ -122,3 +132,4 @@ void connectToServer() {
// note the time of this connect attempt:
lastAttemptTime = millis();
}
+
diff --git a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
index b4e24b8..93ffe39 100644
--- a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
+++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
@@ -9,7 +9,7 @@
created 4 Sep 2010
by Michael Margolis
- modified 17 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
This code is in the public domain.
@@ -38,7 +38,12 @@ EthernetUDP Udp;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
diff --git a/libraries/Ethernet/examples/WebClient/WebClient.ino b/libraries/Ethernet/examples/WebClient/WebClient.ino
index 1806854..5d5d7f2 100644
--- a/libraries/Ethernet/examples/WebClient/WebClient.ino
+++ b/libraries/Ethernet/examples/WebClient/WebClient.ino
@@ -8,6 +8,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 18 Dec 2009
+ modified 9 Apr 2012
by David A. Mellis
*/
@@ -26,8 +27,12 @@ IPAddress server(173,194,33,104); // Google
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino b/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino
new file mode 100644
index 0000000..e0f06c4
--- /dev/null
+++ b/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino
@@ -0,0 +1,110 @@
+/*
+ Repeating Web client
+
+ This sketch connects to a a web server and makes a request
+ using a Wiznet Ethernet shield. 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 DNS, by assigning the Ethernet client with a MAC address,
+ IP address, and DNS address.
+
+ Circuit:
+ * Ethernet shield attached to pins 10, 11, 12, 13
+
+ created 19 Apr 2012
+ by Tom Igoe
+
+ http://arduino.cc/en/Tutorial/WebClientRepeating
+ This code is in the public domain.
+
+ */
+
+#include <SPI.h>
+#include <Ethernet.h>
+
+// assign a MAC address for the ethernet controller.
+// 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,0,20);
+
+// fill in your Domain Name Server address here:
+IPAddress myDns(1,1,1,1);
+
+// initialize the library instance:
+EthernetClient client;
+
+char server[] = "www.arduino.cc";
+
+unsigned 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 unsigned long postingInterval = 60*1000; // delay between updates, in milliseconds
+
+void setup() {
+ // start serial port:
+ Serial.begin(9600);
+ // give the ethernet module time to boot up:
+ delay(1000);
+ // start the Ethernet connection using a fixed IP address and DNS server:
+ Ethernet.begin(mac, ip, myDns);
+ // print the Ethernet board/shield's IP address:
+ Serial.print("My IP address: ");
+ Serial.println(Ethernet.localIP());
+}
+
+void loop() {
+ // if there's incoming data from the net connection.
+ // send it out the serial port. This is for debugging
+ // purposes only:
+ if (client.available()) {
+ char c = client.read();
+ Serial.print(c);
+ }
+
+ // if there's no net connection, but there was one last time
+ // through the loop, then stop the client:
+ if (!client.connected() && lastConnected) {
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+
+ // if you're not connected, and ten seconds have passed since
+ // your last connection, then connect again and send data:
+ if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
+ httpRequest();
+ }
+ // store the state of the connection for next time through
+ // the loop:
+ lastConnected = client.connected();
+}
+
+// this method makes a HTTP connection to the server:
+void httpRequest() {
+ // if there's a successful connection:
+ if (client.connect(server, 80)) {
+ Serial.println("connecting...");
+ // send the HTTP PUT request:
+ client.println("GET /latest.txt HTTP/1.1");
+ client.println("Host: www.arduino.cc");
+ client.println("User-Agent: arduino-ethernet");
+ client.println("Connection: close");
+ client.println();
+
+ // note the time that the connection was made:
+ lastConnectionTime = millis();
+ }
+ else {
+ // if you couldn't make a connection:
+ Serial.println("connection failed");
+ Serial.println("disconnecting.");
+ client.stop();
+ }
+}
+
+
+
+
diff --git a/libraries/Ethernet/examples/WebServer/WebServer.ino b/libraries/Ethernet/examples/WebServer/WebServer.ino
index 6837f83..ce8dbb1 100644
--- a/libraries/Ethernet/examples/WebServer/WebServer.ino
+++ b/libraries/Ethernet/examples/WebServer/WebServer.ino
@@ -10,7 +10,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 4 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -20,7 +20,8 @@
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
-byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte mac[] = {
+ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 177);
// Initialize the Ethernet server library
@@ -28,23 +29,33 @@ IPAddress ip(192,168,1, 177);
// (port 80 is default for HTTP):
EthernetServer server(80);
-void setup()
-{
+void setup() {
+ // Open serial communications and wait for port to open:
+ Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
+ Serial.print("server is at ");
+ Serial.println(Ethernet.localIP());
}
-void loop()
-{
+
+void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
+ Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
+ Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
@@ -52,16 +63,22 @@ void loop()
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
+ client.println("Connnection: close");
client.println();
-
+ client.println("<!DOCTYPE HTML>");
+ client.println("<html>");
+ // add a meta refresh tag, so the browser pulls again every 5 seconds:
+ client.println("<meta http-equiv=\"refresh\" content=\"5\">");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
+ int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
- client.print(analogRead(analogChannel));
- client.println("<br />");
+ client.print(sensorReading);
+ client.println("<br />");
}
+ client.println("</html>");
break;
}
if (c == '\n') {
@@ -78,5 +95,7 @@ void loop()
delay(1);
// close the connection:
client.stop();
+ Serial.println("client disonnected");
}
}
+
diff --git a/libraries/Ethernet/utility/w5100.h b/libraries/Ethernet/utility/w5100.h
index 153aedb..8dccd9f 100755
--- a/libraries/Ethernet/utility/w5100.h
+++ b/libraries/Ethernet/utility/w5100.h
@@ -327,7 +327,11 @@ 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__)
+#elif defined(__AVR_ATmega32U4__)
+ inline static void initSS() { DDRB |= _BV(6); };
+ inline static void setSS() { PORTB &= ~_BV(6); };
+ inline static void resetSS() { PORTB |= _BV(6); };
+#elif 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); };
diff --git a/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
index 27123ad..1127d8f 100644
--- a/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
+++ b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
@@ -32,7 +32,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalAutoscroll
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Blink/Blink.ino b/libraries/LiquidCrystal/examples/Blink/Blink.ino
index e410424..9667b5d 100644
--- a/libraries/LiquidCrystal/examples/Blink/Blink.ino
+++ b/libraries/LiquidCrystal/examples/Blink/Blink.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalBlink
*/
diff --git a/libraries/LiquidCrystal/examples/Cursor/Cursor.ino b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
index 28e2a6a..05862a4 100644
--- a/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
+++ b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalCursor
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Display/Display.ino b/libraries/LiquidCrystal/examples/Display/Display.ino
index b000731..a85effb 100644
--- a/libraries/LiquidCrystal/examples/Display/Display.ino
+++ b/libraries/LiquidCrystal/examples/Display/Display.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Scroll/Scroll.ino b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
index 71e5e8c..0d6d8dc 100644
--- a/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
+++ b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalScroll
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
index 9727cee..a6f8f40 100644
--- a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
+++ b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalSerial
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
index 51bab1f..cabd8ea 100644
--- a/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
+++ b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalTextDirection
*/
@@ -49,7 +49,6 @@ void setup() {
lcd.begin(16, 2);
// turn on the cursor:
lcd.cursor();
- Serial.begin(9600);
}
void loop() {
diff --git a/libraries/LiquidCrystal/examples/setCursor/setCursor.ino b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
index 3c4edf3..e45c491 100644
--- a/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
+++ b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
@@ -32,7 +32,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalSetCursor
+
*/
// include the library code:
diff --git a/libraries/SD/examples/CardInfo/CardInfo.ino b/libraries/SD/examples/CardInfo/CardInfo.ino
index fb2f6c3..0c2dfc5 100644
--- a/libraries/SD/examples/CardInfo/CardInfo.ino
+++ b/libraries/SD/examples/CardInfo/CardInfo.ino
@@ -16,7 +16,7 @@
created 28 Mar 2011
by Limor Fried
- modified 16 Mar 2011
+ modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
@@ -35,7 +35,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("\nInitializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/Datalogger/Datalogger.ino b/libraries/SD/examples/Datalogger/Datalogger.ino
index 73d81af..a7f85ee 100644
--- a/libraries/SD/examples/Datalogger/Datalogger.ino
+++ b/libraries/SD/examples/Datalogger/Datalogger.ino
@@ -13,7 +13,7 @@
** CS - pin 4
created 24 Nov 2010
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -30,7 +30,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
diff --git a/libraries/SD/examples/DumpFile/DumpFile.ino b/libraries/SD/examples/DumpFile/DumpFile.ino
index 961717f..d83089a 100644
--- a/libraries/SD/examples/DumpFile/DumpFile.ino
+++ b/libraries/SD/examples/DumpFile/DumpFile.ino
@@ -12,6 +12,9 @@
** CS - pin 4
created 22 December 2010
+ by Limor Fried
+ modified 9 Apr 2012
+ by Tom Igoe
This example code is in the public domain.
@@ -27,7 +30,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
diff --git a/libraries/SD/examples/Files/Files.ino b/libraries/SD/examples/Files/Files.ino
index 5ed9fea..a15b862 100644
--- a/libraries/SD/examples/Files/Files.ino
+++ b/libraries/SD/examples/Files/Files.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -23,7 +23,13 @@ File myFile;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/ReadWrite/ReadWrite.ino b/libraries/SD/examples/ReadWrite/ReadWrite.ino
index 9957218..5805fc8 100644
--- a/libraries/SD/examples/ReadWrite/ReadWrite.ino
+++ b/libraries/SD/examples/ReadWrite/ReadWrite.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -24,7 +24,13 @@ File myFile;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/listfiles/listfiles.ino b/libraries/SD/examples/listfiles/listfiles.ino
index b2435a2..876c3f8 100644
--- a/libraries/SD/examples/listfiles/listfiles.ino
+++ b/libraries/SD/examples/listfiles/listfiles.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -23,7 +23,13 @@ File root;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/utility/Sd2PinMap.h b/libraries/SD/utility/Sd2PinMap.h
index 4bd75a3..1c76dd3 100644
--- a/libraries/SD/utility/Sd2PinMap.h
+++ b/libraries/SD/utility/Sd2PinMap.h
@@ -166,44 +166,43 @@ static const pin_map_t digitalPinMap[] = {
};
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega32U4__)
-// Teensy 2.0
+// Leonardo
// Two Wire (aka I2C) ports
-uint8_t const SDA_PIN = 6;
-uint8_t const SCL_PIN = 5;
+uint8_t const SDA_PIN = 2;
+uint8_t const SCL_PIN = 3;
// SPI port
-uint8_t const SS_PIN = 0;
-uint8_t const MOSI_PIN = 2;
-uint8_t const MISO_PIN = 3;
-uint8_t const SCK_PIN = 1;
+uint8_t const SS_PIN = 17;
+uint8_t const MOSI_PIN = 16;
+uint8_t const MISO_PIN = 14;
+uint8_t const SCK_PIN = 15;
static const pin_map_t digitalPinMap[] = {
- {&DDRB, &PINB, &PORTB, 0}, // B0 0
- {&DDRB, &PINB, &PORTB, 1}, // B1 1
- {&DDRB, &PINB, &PORTB, 2}, // B2 2
- {&DDRB, &PINB, &PORTB, 3}, // B3 3
- {&DDRB, &PINB, &PORTB, 7}, // B7 4
- {&DDRD, &PIND, &PORTD, 0}, // D0 5
- {&DDRD, &PIND, &PORTD, 1}, // D1 6
- {&DDRD, &PIND, &PORTD, 2}, // D2 7
- {&DDRD, &PIND, &PORTD, 3}, // D3 8
- {&DDRC, &PINC, &PORTC, 6}, // C6 9
- {&DDRC, &PINC, &PORTC, 7}, // C7 10
- {&DDRD, &PIND, &PORTD, 6}, // D6 11
- {&DDRD, &PIND, &PORTD, 7}, // D7 12
- {&DDRB, &PINB, &PORTB, 4}, // B4 13
- {&DDRB, &PINB, &PORTB, 5}, // B5 14
- {&DDRB, &PINB, &PORTB, 6}, // B6 15
- {&DDRF, &PINF, &PORTF, 7}, // F7 16
- {&DDRF, &PINF, &PORTF, 6}, // F6 17
- {&DDRF, &PINF, &PORTF, 5}, // F5 18
- {&DDRF, &PINF, &PORTF, 4}, // F4 19
- {&DDRF, &PINF, &PORTF, 1}, // F1 20
- {&DDRF, &PINF, &PORTF, 0}, // F0 21
- {&DDRD, &PIND, &PORTD, 4}, // D4 22
- {&DDRD, &PIND, &PORTD, 5}, // D5 23
- {&DDRE, &PINE, &PORTE, 6} // E6 24
+ {&DDRD, &PIND, &PORTD, 2}, // D2 0
+ {&DDRD, &PIND, &PORTD, 3}, // D3 1
+ {&DDRD, &PIND, &PORTD, 1}, // D1 2
+ {&DDRD, &PIND, &PORTD, 0}, // D0 3
+ {&DDRD, &PIND, &PORTD, 4}, // D4 4
+ {&DDRC, &PINC, &PORTC, 6}, // C6 5
+ {&DDRD, &PIND, &PORTD, 7}, // D7 6
+ {&DDRE, &PINE, &PORTE, 6}, // E6 7
+ {&DDRB, &PINB, &PORTB, 4}, // B4 8
+ {&DDRB, &PINB, &PORTB, 5}, // B5 9
+ {&DDRB, &PINB, &PORTB, 6}, // B6 10
+ {&DDRB, &PINB, &PORTB, 7}, // B7 11
+ {&DDRD, &PIND, &PORTD, 6}, // D6 12
+ {&DDRC, &PINC, &PORTC, 7}, // C7 13
+ {&DDRB, &PINB, &PORTB, 3}, // B3 14
+ {&DDRB, &PINB, &PORTB, 1}, // B1 15
+ {&DDRB, &PINB, &PORTB, 2}, // B2 16
+ {&DDRB, &PINB, &PORTB, 0}, // B0 17
+ {&DDRF, &PINF, &PORTF, 7}, // F7 18
+ {&DDRF, &PINF, &PORTF, 6}, // F6 19
+ {&DDRF, &PINF, &PORTF, 5}, // F5 20
+ {&DDRF, &PINF, &PORTF, 4}, // F4 21
+ {&DDRF, &PINF, &PORTF, 1}, // F1 22
+ {&DDRF, &PINF, &PORTF, 0}, // F0 23
};
//------------------------------------------------------------------------------
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
diff --git a/libraries/SD/utility/SdFatUtil.h b/libraries/SD/utility/SdFatUtil.h
index 283fcb2..7d6b410 100644
--- a/libraries/SD/utility/SdFatUtil.h
+++ b/libraries/SD/utility/SdFatUtil.h
@@ -56,7 +56,7 @@ static UNUSEDOK int FreeRam(void) {
* \param[in] str Pointer to string stored in flash memory.
*/
static NOINLINE void SerialPrint_P(PGM_P str) {
- for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
+ for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c);
}
//------------------------------------------------------------------------------
/**
diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp
index 42915df..5e48073 100644
--- a/libraries/SPI/SPI.cpp
+++ b/libraries/SPI/SPI.cpp
@@ -14,27 +14,32 @@
SPIClass SPI;
void SPIClass::begin() {
- // Set direction register for SCK and MOSI pin.
- // MISO pin automatically overrides to INPUT.
+
+ // Set SS to high so a connected chip will be "deselected" by default
+ digitalWrite(SS, HIGH);
+
// When the SS pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
-
- pinMode(SCK, OUTPUT);
- pinMode(MOSI, OUTPUT);
pinMode(SS, OUTPUT);
-
- digitalWrite(SCK, LOW);
- digitalWrite(MOSI, LOW);
- digitalWrite(SS, HIGH);
- // Warning: if the SS pin ever becomes a LOW INPUT then SPI
- // automatically switches to Slave, so the data direction of
+ // Warning: if the SS pin ever becomes a LOW INPUT then SPI
+ // automatically switches to Slave, so the data direction of
// the SS pin MUST be kept as OUTPUT.
SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);
+
+ // Set direction register for SCK and MOSI pin.
+ // MISO pin automatically overrides to INPUT.
+ // By doing this AFTER enabling SPI, we avoid accidentally
+ // clocking in a single bit since the lines go directly
+ // from "input" to SPI control.
+ // http://code.google.com/p/arduino/issues/detail?id=888
+ pinMode(SCK, OUTPUT);
+ pinMode(MOSI, OUTPUT);
}
+
void SPIClass::end() {
SPCR &= ~_BV(SPE);
}
diff --git a/libraries/Servo/Servo.cpp b/libraries/Servo/Servo.cpp
index acac29a..a716433 100755
--- a/libraries/Servo/Servo.cpp
+++ b/libraries/Servo/Servo.cpp
@@ -89,7 +89,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
}
else {
// finished all channels so wait for the refresh period to expire before starting over
- if( (unsigned)*TCNTn < (usToTicks(REFRESH_INTERVAL) + 4) ) // allow a few ticks to ensure the next OCR1A not missed
+ if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
@@ -298,7 +298,7 @@ void Servo::writeMicroseconds(int value)
{
// calculate and store the values for the given channel
byte channel = this->servoIndex;
- if( (channel >= 0) && (channel < MAX_SERVOS) ) // ensure channel is valid
+ if( (channel < MAX_SERVOS) ) // ensure channel is valid
{
if( value < SERVO_MIN() ) // ensure pulse width is valid
value = SERVO_MIN();
diff --git a/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino b/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
index 1f535bd..6101bb1 100644
--- a/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
+++ b/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
@@ -1,10 +1,43 @@
+/*
+ Software serial multple serial test
+
+ Receives from the hardware serial, sends to software serial.
+ Receives from software serial, sends to hardware serial.
+
+ The circuit:
+ * RX is digital pin 10 (connect to TX of other device)
+ * TX is digital pin 11 (connect to RX of other device)
+
+ Note:
+ Not all pins on the Mega and Mega 2560 support change interrupts,
+ so only the following can be used for RX:
+ 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
+
+ Not all pins on the Leonardo support change interrupts,
+ so only the following can be used for RX:
+ 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
+
+ created back in the mists of time
+ modified 25 May 2012
+ by Tom Igoe
+ based on Mikal Hart's example
+
+ This example code is in the public domain.
+
+ */
#include <SoftwareSerial.h>
-SoftwareSerial mySerial(2, 3);
+SoftwareSerial mySerial(10, 11); // RX, TX
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(57600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
@@ -19,3 +52,4 @@ void loop() // run over and over
if (Serial.available())
mySerial.write(Serial.read());
}
+
diff --git a/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
index e870c6f..d607ee6 100644
--- a/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
+++ b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
@@ -16,7 +16,17 @@
* 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
+ Note:
+ Not all pins on the Mega and Mega 2560 support change interrupts,
+ so only the following can be used for RX:
+ 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
+
+ Not all pins on the Leonardo support change interrupts,
+ so only the following can be used for RX:
+ 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
+
created 18 Apr. 2011
+ modified 25 May 2012
by Tom Igoe
based on Mikal Hart's twoPortRXExample
@@ -25,16 +35,21 @@
*/
#include <SoftwareSerial.h>
-// software serial #1: TX = digital pin 2, RX = digital pin 3
-SoftwareSerial portOne(2, 3);
+// software serial #1: TX = digital pin 10, RX = digital pin 11
+SoftwareSerial portOne(10,11);
-// software serial #2: TX = digital pin 4, RX = digital pin 5
-SoftwareSerial portTwo(4, 5);
+// software serial #2: TX = digital pin 8, RX = digital pin 9
+// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
+SoftwareSerial portTwo(8,9);
void setup()
{
- // Start the hardware serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// Start each software serial port
portOne.begin(9600);
diff --git a/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
index dbd0f7f..1a67a55 100644
--- a/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
+++ b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
@@ -26,11 +26,10 @@ const int stepsPerRevolution = 200; // change this to fit the number of steps p
// 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
+int stepCount = 0; // number of steps the motor has taken
void setup() {
- // initialize the serial port:
- Serial.begin(9600);
+ // nothing to do inside the setup
}
void loop() {
diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp
index d83f478..4e7a17c 100755
--- a/libraries/Wire/Wire.cpp
+++ b/libraries/Wire/Wire.cpp
@@ -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
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
extern "C" {
@@ -73,14 +75,14 @@ void TwoWire::begin(int address)
begin((uint8_t)address);
}
-uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
+uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
// clamp to buffer length
if(quantity > BUFFER_LENGTH){
quantity = BUFFER_LENGTH;
}
// perform blocking read into buffer
- uint8_t read = twi_readFrom(address, rxBuffer, quantity);
+ uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;
@@ -88,9 +90,19 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
return read;
}
+uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
+{
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
+}
+
uint8_t TwoWire::requestFrom(int address, int quantity)
{
- return requestFrom((uint8_t)address, (uint8_t)quantity);
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
+}
+
+uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
+{
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
}
void TwoWire::beginTransmission(uint8_t address)
@@ -109,10 +121,23 @@ void TwoWire::beginTransmission(int address)
beginTransmission((uint8_t)address);
}
-uint8_t TwoWire::endTransmission(void)
+//
+// Originally, 'endTransmission' was an f(void) function.
+// It has been modified to take one parameter indicating
+// whether or not a STOP should be performed on the bus.
+// Calling endTransmission(false) allows a sketch to
+// perform a repeated start.
+//
+// WARNING: Nothing in the library keeps track of whether
+// the bus tenure has been properly ended with a STOP. It
+// is very possible to leave the bus in a hung state if
+// no call to endTransmission(true) is made. Some I2C
+// devices will behave oddly if they do not see a STOP.
+//
+uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
// transmit buffer (blocking)
- int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
+ int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
@@ -121,6 +146,14 @@ uint8_t TwoWire::endTransmission(void)
return ret;
}
+// This provides backwards compatibility with the original
+// definition, and expected behaviour, of endTransmission
+//
+uint8_t TwoWire::endTransmission(void)
+{
+ return endTransmission(true);
+}
+
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h
index 9ea4afd..a93d0f5 100755
--- a/libraries/Wire/Wire.h
+++ b/libraries/Wire/Wire.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
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#ifndef TwoWire_h
@@ -50,8 +52,11 @@ class TwoWire : public Stream
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
+ uint8_t endTransmission(uint8_t);
uint8_t requestFrom(uint8_t, uint8_t);
+ uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom(int, int);
+ uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c
index d80114b..6b2db3c 100644
--- a/libraries/Wire/utility/twi.c
+++ b/libraries/Wire/utility/twi.c
@@ -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
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#include <math.h>
@@ -37,14 +39,16 @@
#include "twi.h"
static volatile uint8_t twi_state;
-static uint8_t twi_slarw;
+static volatile uint8_t twi_slarw;
+static volatile uint8_t twi_sendStop; // should the transaction end with a stop
+static volatile uint8_t twi_inRepStart; // in the middle of a repeated start
static void (*twi_onSlaveTransmit)(void);
static void (*twi_onSlaveReceive)(uint8_t*, int);
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_masterBufferIndex;
-static uint8_t twi_masterBufferLength;
+static volatile uint8_t twi_masterBufferLength;
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_txBufferIndex;
@@ -65,6 +69,8 @@ void twi_init(void)
{
// initialize state
twi_state = TWI_READY;
+ twi_sendStop = true; // default value
+ twi_inRepStart = false;
// activate internal pullups for twi.
digitalWrite(SDA, 1);
@@ -103,9 +109,10 @@ void twi_setAddress(uint8_t address)
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes to read into array
+ * sendStop: Boolean indicating whether to send a stop at the end
* Output number of bytes read
*/
-uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
+uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
uint8_t i;
@@ -119,6 +126,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
continue;
}
twi_state = TWI_MRX;
+ twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
@@ -135,8 +143,20 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
twi_slarw = TW_READ;
twi_slarw |= address << 1;
- // send start condition
- TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+ if (true == twi_inRepStart) {
+ // if we're in the repeated start state, then we've already sent the start,
+ // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
+ // We need to remove ourselves from the repeated start state before we enable interrupts,
+ // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
+ // up. Also, don't enable the START interrupt. There may be one pending from the
+ // repeated start that we sent outselves, and that would really confuse things.
+ twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
+ TWDR = twi_slarw;
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
+ }
+ else
+ // send start condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
// wait for read operation to complete
while(TWI_MRX == twi_state){
@@ -162,13 +182,14 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
* data: pointer to byte array
* length: number of bytes in array
* wait: boolean indicating to wait for write or not
+ * sendStop: boolean indicating whether or not to send a stop at the end
* Output 0 .. success
* 1 .. length to long for buffer
* 2 .. address send, NACK received
* 3 .. data send, NACK received
* 4 .. other twi error (lost bus arbitration, bus error, ..)
*/
-uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
+uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
{
uint8_t i;
@@ -182,6 +203,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
continue;
}
twi_state = TWI_MTX;
+ twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
@@ -198,8 +220,23 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
twi_slarw = TW_WRITE;
twi_slarw |= address << 1;
- // send start condition
- TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+ // if we're in a repeated start, then we've already sent the START
+ // in the ISR. Don't do it again.
+ //
+ if (true == twi_inRepStart) {
+ // if we're in the repeated start state, then we've already sent the start,
+ // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
+ // We need to remove ourselves from the repeated start state before we enable interrupts,
+ // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
+ // up. Also, don't enable the START interrupt. There may be one pending from the
+ // repeated start that we sent outselves, and that would really confuse things.
+ twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
+ TWDR = twi_slarw;
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
+ }
+ else
+ // send start condition
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
// wait for write operation to complete
while(wait && (TWI_MTX == twi_state)){
@@ -343,7 +380,16 @@ SIGNAL(TWI_vect)
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
twi_reply(1);
}else{
- twi_stop();
+ if (twi_sendStop)
+ twi_stop();
+ else {
+ twi_inRepStart = true; // we're gonna send the START
+ // don't enable the interrupt. We'll generate the start, but we
+ // avoid handling the interrupt until we're in the next transaction,
+ // at the point where we would normally issue the start.
+ TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
+ twi_state = TWI_READY;
+ }
}
break;
case TW_MT_SLA_NACK: // address sent, nack received
@@ -374,6 +420,17 @@ SIGNAL(TWI_vect)
case TW_MR_DATA_NACK: // data received, nack sent
// put final byte into buffer
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+ if (twi_sendStop)
+ twi_stop();
+ else {
+ twi_inRepStart = true; // we're gonna send the START
+ // don't enable the interrupt. We'll generate the start, but we
+ // avoid handling the interrupt until we're in the next transaction,
+ // at the point where we would normally issue the start.
+ TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
+ twi_state = TWI_READY;
+ }
+ break;
case TW_MR_SLA_NACK: // address sent, nack received
twi_stop();
break;
diff --git a/libraries/Wire/utility/twi.h b/libraries/Wire/utility/twi.h
index 831b928..6526593 100755
--- a/libraries/Wire/utility/twi.h
+++ b/libraries/Wire/utility/twi.h
@@ -40,8 +40,8 @@
void twi_init(void);
void twi_setAddress(uint8_t);
- uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
- uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
+ uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
+ uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
uint8_t twi_transmit(const uint8_t*, uint8_t);
void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
void twi_attachSlaveTxEvent( void (*)(void) );
diff --git a/platform.txt b/platform.txt
index c47cd8b..557b2d3 100644
--- a/platform.txt
+++ b/platform.txt
@@ -6,12 +6,12 @@ name=Arduino
# Default "compiler.path" is correct, change only if you want to overidde the initial value
#compiler.path={ide.path}/tools/avr/bin/..
compiler.c.cmd=avr-gcc
-compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections
+compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD
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.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD
compiler.ar.cmd=avr-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=avr-objcopy
@@ -20,48 +20,56 @@ compiler.elf2hex.flags=-O ihex -R .eeprom
compiler.elf2hex.cmd=avr-objcopy
compiler.ldflags=
compiler.size.cmd=avr-size
+# this can be overriden in boards.txt
+build.extra_flags=
# AVR compile patterns
# --------------------
## Compile c files
-recipe.c.o.pattern={compiler.path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file}
+recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
-recipe.cpp.o.pattern={compiler.path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file}
+recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
## Create archives
-recipe.ar.pattern={compiler.path}{compiler.ar.cmd} {compiler.ar.flags} {build.path}/{archive_file} {object_file}
+recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}"
## Combine gc-sections, archives, and objects
-recipe.c.combine.pattern={compiler.path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build.path}/{build.project_name}.elf {object_files} {build.path}/{archive_file} -L{build.path} -lm
+recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
## Create eeprom
-recipe.objcopy.eep.pattern={compiler.path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.eep
+recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
## Create hex
-recipe.objcopy.hex.pattern={compiler.path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.hex
+recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
## Compute size
-recipe.size.pattern={compiler.path}{compiler.size.cmd} -A {build.path}/{build.project_name}.hex
+recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.hex"
recipe.size.regex=Total\s+([0-9]+).*
# AVR Uploader/Programmers tools
# -------------------
-tools.avrdude.cmd=avrdude
-tools.avrdude.path={runtime.ide.path}/hardware/tools
-tools.avrdude.config.path={path}/avrdude.conf
+tools.avrdude.cmd.path={runtime.ide.path}/hardware/tools/avr/bin/avrdude
+tools.avrdude.config.path={runtime.ide.path}/hardware/tools/avr/etc/avrdude.conf
+tools.avrdude.cmd.path.linux={runtime.ide.path}/hardware/tools/avrdude
+tools.avrdude.config.path.linux={runtime.ide.path}/hardware/tools/avrdude.conf
tools.avrdude.upload.params.verbose=-v -v -v -v
tools.avrdude.upload.params.quiet=-q -q
-tools.avrdude.upload.pattern={path}/{cmd} -C{config.path} {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D -Uflash:w:{build.path}/{build.project_name}.hex:i
+tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
tools.avrdude.program.params.verbose=-v -v -v -v
tools.avrdude.program.params.quiet=-q -q
-tools.avrdude.program.pattern={path}/{cmd} -C{config.path} {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -Uflash:w:{build.path}/{build.project_name}.hex:i
+tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
+
+tools.avrdude.erase.params.verbose=-v -v -v -v
+tools.avrdude.erase.params.quiet=-q -q
+tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m
tools.avrdude.bootloader.params.verbose=-v -v -v -v
tools.avrdude.bootloader.params.quiet=-q -q
-tools.avrdude.bootloader.pattern={path}/{cmd} -C{config.path} {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} {bootloader.params}
+tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.ide.path}/hardware/arduino/avr/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
+
diff --git a/variants/leonardo/pins_arduino.h b/variants/leonardo/pins_arduino.h
index 15afb4e..9f770d6 100644
--- a/variants/leonardo/pins_arduino.h
+++ b/variants/leonardo/pins_arduino.h
@@ -27,37 +27,40 @@
#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;
+static const uint8_t SDA = 2;
+static const 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;
+static const uint8_t SS = 17;
+static const uint8_t MOSI = 16;
+static const uint8_t MISO = 14;
+static const 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
+static const uint8_t A0 = 18;
+static const uint8_t A1 = 19;
+static const uint8_t A2 = 20;
+static const uint8_t A3 = 21;
+static const uint8_t A4 = 22;
+static const uint8_t A5 = 23;
+static const uint8_t A6 = 24; // D4
+static const uint8_t A7 = 25; // D6
+static const uint8_t A8 = 26; // D8
+static const uint8_t A9 = 27; // D9
+static const uint8_t A10 = 28; // D10
+static const uint8_t A11 = 29; // D12
+
+#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
+#define digitalPinToPCICRbit(p) 0
+#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
+#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
@@ -212,7 +215,7 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[30] = {
_BV(6), // D29 / D12 - A11 - PD6
};
-const uint8_t PROGMEM digital_pin_to_timer_PGM[18] = {
+const uint8_t PROGMEM digital_pin_to_timer_PGM[16] = {
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
diff --git a/variants/mega/pins_arduino.h b/variants/mega/pins_arduino.h
index 57ec97f..5a9b4cb 100644
--- a/variants/mega/pins_arduino.h
+++ b/variants/mega/pins_arduino.h
@@ -32,31 +32,31 @@
#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;
+static const uint8_t SS = 53;
+static const uint8_t MOSI = 51;
+static const uint8_t MISO = 50;
+static const uint8_t SCK = 52;
-const static uint8_t SDA = 20;
-const static uint8_t SCL = 21;
-const static uint8_t LED_BUILTIN = 13;
+static const uint8_t SDA = 20;
+static const uint8_t SCL = 21;
+static const uint8_t LED_BUILTIN = 13;
-const static uint8_t A0 = 54;
-const static uint8_t A1 = 55;
-const static uint8_t A2 = 56;
-const static uint8_t A3 = 57;
-const static uint8_t A4 = 58;
-const static uint8_t A5 = 59;
-const static uint8_t A6 = 60;
-const static uint8_t A7 = 61;
-const static uint8_t A8 = 62;
-const static uint8_t A9 = 63;
-const static uint8_t A10 = 64;
-const static uint8_t A11 = 65;
-const static uint8_t A12 = 66;
-const static uint8_t A13 = 67;
-const static uint8_t A14 = 68;
-const static uint8_t A15 = 69;
+static const uint8_t A0 = 54;
+static const uint8_t A1 = 55;
+static const uint8_t A2 = 56;
+static const uint8_t A3 = 57;
+static const uint8_t A4 = 58;
+static const uint8_t A5 = 59;
+static const uint8_t A6 = 60;
+static const uint8_t A7 = 61;
+static const uint8_t A8 = 62;
+static const uint8_t A9 = 63;
+static const uint8_t A10 = 64;
+static const uint8_t A11 = 65;
+static const uint8_t A12 = 66;
+static const uint8_t A13 = 67;
+static const uint8_t A14 = 68;
+static const 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):
diff --git a/variants/micro/pins_arduino.h b/variants/micro/pins_arduino.h
deleted file mode 100644
index c9f25eb..0000000
--- a/variants/micro/pins_arduino.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- 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 6e774d4..30b4266 100644
--- a/variants/standard/pins_arduino.h
+++ b/variants/standard/pins_arduino.h
@@ -37,23 +37,23 @@
#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;
-const static uint8_t A3 = 17;
-const static uint8_t A4 = 18;
-const static uint8_t A5 = 19;
-const static uint8_t A6 = 20;
-const static uint8_t A7 = 21;
+static const uint8_t SS = 10;
+static const uint8_t MOSI = 11;
+static const uint8_t MISO = 12;
+static const uint8_t SCK = 13;
+
+static const uint8_t SDA = 18;
+static const uint8_t SCL = 19;
+static const uint8_t LED_BUILTIN = 13;
+
+static const uint8_t A0 = 14;
+static const uint8_t A1 = 15;
+static const uint8_t A2 = 16;
+static const uint8_t A3 = 17;
+static const uint8_t A4 = 18;
+static const uint8_t A5 = 19;
+static const uint8_t A6 = 20;
+static const 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))
@@ -215,4 +215,4 @@ const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
#endif
-#endif \ No newline at end of file
+#endif