summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cproject1450
-rw-r--r--.project88
-rw-r--r--.pydevproject7
-rw-r--r--.settings/de.innot.avreclipse.core.prefs143
-rw-r--r--COPYING340
-rw-r--r--MANIFEST.in1
-rw-r--r--README107
-rw-r--r--df10ch_common.h54
-rw-r--r--df10ch_setup.py88
-rw-r--r--df10ch_setup_pkg/__init__.py21
-rw-r--r--df10ch_setup_pkg/areas_dlg.py235
-rw-r--r--df10ch_setup_pkg/bright_dlg.py83
-rw-r--r--df10ch_setup_pkg/device_dlg.py428
-rw-r--r--df10ch_setup_pkg/device_drv.py1011
-rw-r--r--df10ch_setup_pkg/firmware.py135
-rw-r--r--df10ch_setup_pkg/layout_dlg.py111
-rw-r--r--df10ch_setup_pkg/map_dlg.py256
-rw-r--r--df10ch_setup_pkg/setup_dlg.py58
-rw-r--r--df10ch_setup_pkg/white_cal_dlg.py172
-rw-r--r--df10ch_usb_proto.h116
-rw-r--r--kicad/10ch_pwm_ctrl-Lötseite.ps4881
-rw-r--r--kicad/10ch_pwm_ctrl.brd9112
-rw-r--r--kicad/10ch_pwm_ctrl.cache.bck16
-rw-r--r--kicad/10ch_pwm_ctrl.cache.dcm48
-rw-r--r--kicad/10ch_pwm_ctrl.cache.lib445
-rw-r--r--kicad/10ch_pwm_ctrl.cmp381
-rw-r--r--kicad/10ch_pwm_ctrl.lst117
-rw-r--r--kicad/10ch_pwm_ctrl.net855
-rw-r--r--kicad/10ch_pwm_ctrl.pro121
-rw-r--r--kicad/10ch_pwm_ctrl.sch1585
-rw-r--r--pwm_appl/10ch_pwm_appl.c1000
-rw-r--r--pwm_appl/Makefile106
-rw-r--r--pwm_boot/10ch_pwm_boot.c475
-rw-r--r--pwm_boot/Makefile102
-rw-r--r--setup.py35
-rw-r--r--usb_appl/10ch_usb_appl.c839
-rw-r--r--usb_appl/Makefile109
-rw-r--r--usb_appl/usbconfig.h392
-rw-r--r--usb_boot/10ch_usb_boot.c323
-rw-r--r--usb_boot/Makefile106
-rw-r--r--usb_boot/usbconfig.h391
-rw-r--r--usbdrv/Changelog.txt296
-rw-r--r--usbdrv/CommercialLicense.txt166
-rw-r--r--usbdrv/License.txt361
-rw-r--r--usbdrv/Readme.txt158
-rw-r--r--usbdrv/USB-ID-FAQ.txt149
-rw-r--r--usbdrv/USB-IDs-for-free.txt148
-rw-r--r--usbdrv/USBID-License.txt154
-rw-r--r--usbdrv/asmcommon.inc188
-rw-r--r--usbdrv/oddebug.c50
-rw-r--r--usbdrv/oddebug.h123
-rw-r--r--usbdrv/usbconfig-prototype.h369
-rw-r--r--usbdrv/usbdrv.c625
-rw-r--r--usbdrv/usbdrv.h735
-rw-r--r--usbdrv/usbdrvasm.S385
-rw-r--r--usbdrv/usbdrvasm.asm21
-rw-r--r--usbdrv/usbdrvasm12.inc393
-rw-r--r--usbdrv/usbdrvasm128.inc750
-rw-r--r--usbdrv/usbdrvasm15.inc423
-rw-r--r--usbdrv/usbdrvasm16.inc349
-rw-r--r--usbdrv/usbdrvasm165.inc453
-rw-r--r--usbdrv/usbdrvasm18-crc.inc707
-rw-r--r--usbdrv/usbdrvasm20.inc360
-rw-r--r--usbdrv/usbportability.h140
64 files changed, 33846 insertions, 0 deletions
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..d869e3a
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,1450 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+<storageModule moduleId="org.eclipse.cdt.core.settings">
+<cconfiguration id="de.innot.avreclipse.configuration.app.release.179373882.1868963946">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946" moduleId="org.eclipse.cdt.core.settings" name="USBBoot">
+<externalSettings/>
+<extensions>
+<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactName="df10ch" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="USB Controller Bootloader" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946" name="USBBoot" parent="de.innot.avreclipse.configuration.app.release">
+<folderInfo id="de.innot.avreclipse.configuration.app.release.179373882.1868963946." name="/" resourcePath="">
+<toolChain id="de.innot.avreclipse.toolchain.winavr.app.release.1889797059" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.release">
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release.1392325325" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release.1772338609" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release.111110491" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.release.1605296972" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release.629876872" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release"/>
+<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.release.571073066" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.release"/>
+<builder autoBuildTarget="all" buildPath="${workspace_loc:/df10ch/usb_boot}" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.release.1049698463" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="AVR GNU Make Builder" parallelizationNumber="1" superClass="de.innot.avreclipse.target.builder.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.assembler.winavr.app.release.634028739" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.release">
+<option id="de.innot.avreclipse.assembler.option.debug.level.838426459" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level" value="de.innot.avreclipse.assembler.option.debug.level.none" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.tool.assembler.input.192411604" superClass="de.innot.avreclipse.tool.assembler.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.compiler.winavr.app.release.1459664685" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.release">
+<option id="de.innot.avreclipse.compiler.option.debug.level.1770079713" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level" value="de.innot.avreclipse.compiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.compiler.option.optimize.869463696" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.compiler.winavr.input.1731965849" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.615787717" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release">
+<option id="de.innot.avreclipse.cppcompiler.option.debug.level.134610440" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level" value="de.innot.avreclipse.cppcompiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.cppcompiler.option.optimize.259705260" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.1464201078" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.cpplinker.app.release.1311768380" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.release"/>
+<tool id="de.innot.avreclipse.tool.archiver.winavr.base.53894481" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
+<tool id="de.innot.avreclipse.tool.objdump.winavr.app.release.533466266" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release.1284202138" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release.1678815732" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.size.winavr.app.release.983678900" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.avrdude.app.release.1437172762" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.release"/>
+</toolChain>
+</folderInfo>
+</configuration>
+</storageModule>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.;de.innot.avreclipse.tool.compiler.winavr.app.release.711426924;de.innot.avreclipse.compiler.winavr.input.1256057594">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cconfiguration>
+<cconfiguration id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251" moduleId="org.eclipse.cdt.core.settings" name="USBAppl">
+<externalSettings/>
+<extensions>
+<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactName="df10ch" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="USB Controller Application" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251" name="USBAppl" parent="de.innot.avreclipse.configuration.app.release">
+<folderInfo id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251." name="/" resourcePath="">
+<toolChain id="de.innot.avreclipse.toolchain.winavr.app.release.1802306255" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.release">
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release.9391028" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release.1814744466" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release.310757281" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.release.918541890" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release.126498718" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release"/>
+<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.release.1087763629" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.release"/>
+<builder autoBuildTarget="all" buildPath="${workspace_loc:/df10ch/usb_ctrl}" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.release.129825394" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="AVR GNU Make Builder" parallelizationNumber="1" superClass="de.innot.avreclipse.target.builder.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.assembler.winavr.app.release.339723547" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.release">
+<option id="de.innot.avreclipse.assembler.option.debug.level.460135536" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level" value="de.innot.avreclipse.assembler.option.debug.level.none" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.tool.assembler.input.1404154918" superClass="de.innot.avreclipse.tool.assembler.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.compiler.winavr.app.release.1911000040" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.release">
+<option id="de.innot.avreclipse.compiler.option.debug.level.256958179" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level" value="de.innot.avreclipse.compiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.compiler.option.optimize.579845510" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.compiler.winavr.input.164012582" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.2043456439" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release">
+<option id="de.innot.avreclipse.cppcompiler.option.debug.level.439734442" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level" value="de.innot.avreclipse.cppcompiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.cppcompiler.option.optimize.1572411659" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.1203158052" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.cpplinker.app.release.1472883350" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.release"/>
+<tool id="de.innot.avreclipse.tool.archiver.winavr.base.748439637" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
+<tool id="de.innot.avreclipse.tool.objdump.winavr.app.release.964101891" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release.478922316" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release.988162055" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.size.winavr.app.release.812522460" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.avrdude.app.release.976134550" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.release"/>
+</toolChain>
+</folderInfo>
+</configuration>
+</storageModule>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.;de.innot.avreclipse.tool.compiler.winavr.app.release.711426924;de.innot.avreclipse.compiler.winavr.input.1256057594">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cconfiguration>
+<cconfiguration id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634" moduleId="org.eclipse.cdt.core.settings" name="PWMBoot">
+<externalSettings/>
+<extensions>
+<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactName="df10ch" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="PWM Controller Bootloader" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634" name="PWMBoot" parent="de.innot.avreclipse.configuration.app.release">
+<folderInfo id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634." name="/" resourcePath="">
+<toolChain id="de.innot.avreclipse.toolchain.winavr.app.release.509793003" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.release">
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release.1833663192" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release.933766877" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release.1572967534" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.release.528760314" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release.1686631268" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release"/>
+<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.release.831065851" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.release"/>
+<builder autoBuildTarget="all" buildPath="${workspace_loc:/df10ch/pwm_boot}" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.release.505798138" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="AVR GNU Make Builder" parallelizationNumber="1" superClass="de.innot.avreclipse.target.builder.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.assembler.winavr.app.release.135454288" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.release">
+<option id="de.innot.avreclipse.assembler.option.debug.level.495421150" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level" value="de.innot.avreclipse.assembler.option.debug.level.none" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.tool.assembler.input.1695679093" superClass="de.innot.avreclipse.tool.assembler.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.compiler.winavr.app.release.1404887577" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.release">
+<option id="de.innot.avreclipse.compiler.option.debug.level.1255907304" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level" value="de.innot.avreclipse.compiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.compiler.option.optimize.265397763" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.compiler.winavr.input.815204937" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.660704880" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release">
+<option id="de.innot.avreclipse.cppcompiler.option.debug.level.19388362" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level" value="de.innot.avreclipse.cppcompiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.cppcompiler.option.optimize.2071884689" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.1300953313" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.cpplinker.app.release.86733989" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.release"/>
+<tool id="de.innot.avreclipse.tool.archiver.winavr.base.2049537136" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
+<tool id="de.innot.avreclipse.tool.objdump.winavr.app.release.1218233924" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release.739488513" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release.826764664" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.size.winavr.app.release.1283273879" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.avrdude.app.release.782808972" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.release"/>
+</toolChain>
+</folderInfo>
+</configuration>
+</storageModule>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.;de.innot.avreclipse.tool.compiler.winavr.app.release.711426924;de.innot.avreclipse.compiler.winavr.input.1256057594">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cconfiguration>
+<cconfiguration id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668">
+<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668" moduleId="org.eclipse.cdt.core.settings" name="PWMAppl">
+<externalSettings/>
+<extensions>
+<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+</extensions>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<configuration artifactName="df10ch" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app" description="PWM Controller Application" id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668" name="PWMAppl" parent="de.innot.avreclipse.configuration.app.release">
+<folderInfo id="de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668." name="/" resourcePath="">
+<toolChain id="de.innot.avreclipse.toolchain.winavr.app.release.64286207" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.release">
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release.1149043536" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release.1885480944" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release.1744032681" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.release.363938464" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.release"/>
+<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release.196386558" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release"/>
+<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.release.1346375790" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.release"/>
+<builder autoBuildTarget="all" buildPath="${workspace_loc:/df10ch/pwm_ctrl}" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="de.innot.avreclipse.target.builder.winavr.app.release.1921495593" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="AVR GNU Make Builder" parallelizationNumber="1" superClass="de.innot.avreclipse.target.builder.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.assembler.winavr.app.release.1935239171" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.release">
+<option id="de.innot.avreclipse.assembler.option.debug.level.875875061" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level" value="de.innot.avreclipse.assembler.option.debug.level.none" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.tool.assembler.input.1999615761" superClass="de.innot.avreclipse.tool.assembler.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.compiler.winavr.app.release.502047840" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.release">
+<option id="de.innot.avreclipse.compiler.option.debug.level.736327402" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level" value="de.innot.avreclipse.compiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.compiler.option.optimize.1199149585" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/>
+<inputType id="de.innot.avreclipse.compiler.winavr.input.942954014" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.1398790878" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release">
+<option id="de.innot.avreclipse.cppcompiler.option.debug.level.676591737" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level" value="de.innot.avreclipse.cppcompiler.option.debug.level.none" valueType="enumerated"/>
+<option id="de.innot.avreclipse.cppcompiler.option.optimize.959760363" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
+</tool>
+<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.79393653" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.cpplinker.app.release.711715656" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.release"/>
+<tool id="de.innot.avreclipse.tool.archiver.winavr.base.1632878248" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/>
+<tool id="de.innot.avreclipse.tool.objdump.winavr.app.release.624178283" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release.948716195" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release.1905725614" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.size.winavr.app.release.206832931" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.release"/>
+<tool id="de.innot.avreclipse.tool.avrdude.app.release.109370764" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.release"/>
+</toolChain>
+</folderInfo>
+</configuration>
+</storageModule>
+<storageModule moduleId="scannerConfiguration">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.;de.innot.avreclipse.tool.compiler.winavr.app.release.711426924;de.innot.avreclipse.compiler.winavr.input.1256057594">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.179373882;de.innot.avreclipse.configuration.app.release.179373882.">
+<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="makefileGenerator">
+<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
+<buildOutputProvider>
+<openAction enabled="true" filePath=""/>
+<parser enabled="true"/>
+</buildOutputProvider>
+<scannerInfoProvider id="specsFile">
+<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
+<parser enabled="true"/>
+</scannerInfoProvider>
+</profile>
+</scannerConfigBuildInfo>
+</storageModule>
+<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cconfiguration>
+</storageModule>
+<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+<project id="df10ch.de.innot.avreclipse.project.winavr.elf_2.1.0.410483182" name="AVR Cross Target Application" projectType="de.innot.avreclipse.project.winavr.elf_2.1.0"/>
+</storageModule>
+</cproject>
diff --git a/.project b/.project
new file mode 100644
index 0000000..2c52d78
--- /dev/null
+++ b/.project
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>df10ch</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.python.pydev.PyDevBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildLocation</key>
+ <value>${workspace_loc:/df10ch/usb_boot}</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>false</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ <nature>de.innot.avreclipse.core.avrnature</nature>
+ <nature>org.python.pydev.pythonNature</nature>
+ </natures>
+</projectDescription>
diff --git a/.pydevproject b/.pydevproject
new file mode 100644
index 0000000..f8c0075
--- /dev/null
+++ b/.pydevproject
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?>
+
+<pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
+</pydev_project>
diff --git a/.settings/de.innot.avreclipse.core.prefs b/.settings/de.innot.avreclipse.core.prefs
new file mode 100644
index 0000000..119ed06
--- /dev/null
+++ b/.settings/de.innot.avreclipse.core.prefs
@@ -0,0 +1,143 @@
+#Fri Jan 29 19:03:35 CET 2010
+avrtarget/ClockFrequency=16000000
+avrtarget/ExtRAMSize=0
+avrtarget/ExtendedRAM=false
+avrtarget/MCUType=atmega162
+avrtarget/UseEEPROM=false
+avrtarget/UseExtendedRAMforHeap=true
+avrtarget/avrdude/BitBangDelay=
+avrtarget/avrdude/Bitclock=
+avrtarget/avrdude/EEPROMFile=
+avrtarget/avrdude/EEPROMFromConfig=true
+avrtarget/avrdude/FlashFile=
+avrtarget/avrdude/FlashFromConfig=true
+avrtarget/avrdude/Fuses/ByteValues=192\:200\:249
+avrtarget/avrdude/Fuses/FileName=
+avrtarget/avrdude/Fuses/MCUid=atmega162
+avrtarget/avrdude/Fuses/UseFile=false
+avrtarget/avrdude/Fuses/Write=true
+avrtarget/avrdude/Locks/ByteValues=239
+avrtarget/avrdude/Locks/FileName=
+avrtarget/avrdude/Locks/MCUid=atmega162
+avrtarget/avrdude/Locks/UseFile=false
+avrtarget/avrdude/Locks/Write=true
+avrtarget/avrdude/NoChipErase=false
+avrtarget/avrdude/NoSigCheck=false
+avrtarget/avrdude/NoVerify=false
+avrtarget/avrdude/NoWrite=false
+avrtarget/avrdude/OtherOptions=
+avrtarget/avrdude/ProgrammerID=programmerconfig.1
+avrtarget/avrdude/UseCounter=false
+avrtarget/avrdude/WriteEEPROM=false
+avrtarget/avrdude/WriteFlash=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/ClockFrequency=16000000
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/ExtRAMSize=0
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/ExtendedRAM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/MCUType=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/UseEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/UseExtendedRAMforHeap=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Fuses/ByteValues=31\:201
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Fuses/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Fuses/MCUid=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Fuses/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Fuses/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Locks/ByteValues=239
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Locks/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Locks/MCUid=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Locks/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.1825585251/avrdude/Locks/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/ClockFrequency=16000000
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/ExtRAMSize=0
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/ExtendedRAM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/MCUType=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/UseEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/UseExtendedRAMforHeap=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/BitBangDelay=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Bitclock=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/EEPROMFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/EEPROMFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/FlashFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/FlashFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Fuses/ByteValues=192\:201\:249
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Fuses/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Fuses/MCUid=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Fuses/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Fuses/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Locks/ByteValues=239
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Locks/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Locks/MCUid=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Locks/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/Locks/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/NoChipErase=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/NoSigCheck=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/NoVerify=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/NoWrite=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/OtherOptions=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/ProgrammerID=programmerconfig.1
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/UseCounter=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/WriteEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634.870823668/avrdude/WriteFlash=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/ClockFrequency=16000000
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/ExtRAMSize=0
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/ExtendedRAM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/MCUType=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/UseEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/UseExtendedRAMforHeap=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/BitBangDelay=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Bitclock=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/EEPROMFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/EEPROMFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/FlashFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/FlashFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Fuses/ByteValues=192\:200\:249
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Fuses/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Fuses/MCUid=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Fuses/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Fuses/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Locks/ByteValues=239
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Locks/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Locks/MCUid=atmega162
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Locks/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/Locks/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/NoChipErase=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/NoSigCheck=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/NoVerify=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/NoWrite=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/OtherOptions=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/ProgrammerID=programmerconfig.1
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/UseCounter=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/WriteEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946.749902634/avrdude/WriteFlash=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/ClockFrequency=16000000
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/ExtRAMSize=0
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/ExtendedRAM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/MCUType=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/UseEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/UseExtendedRAMforHeap=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/BitBangDelay=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Bitclock=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/EEPROMFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/EEPROMFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/FlashFile=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/FlashFromConfig=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Fuses/ByteValues=31\:200
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Fuses/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Fuses/MCUid=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Fuses/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Fuses/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Locks/ByteValues=239
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Locks/FileName=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Locks/MCUid=atmega8
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Locks/UseFile=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/Locks/Write=true
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/NoChipErase=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/NoSigCheck=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/NoVerify=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/NoWrite=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/OtherOptions=
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/ProgrammerID=programmerconfig.1
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/UseCounter=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/WriteEEPROM=false
+avrtarget/de.innot.avreclipse.configuration.app.release.179373882.1868963946/avrdude/WriteFlash=true
+avrtarget/perConfig=true
+eclipse.preferences.version=1
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f90922e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..5ecd9c6
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+COPYING
diff --git a/README b/README
new file mode 100644
index 0000000..7d9f862
--- /dev/null
+++ b/README
@@ -0,0 +1,107 @@
+This is the ReadMe file to the DF10CH Atmolight Controller Project.
+
+Written by: Andreas Auras (yak54@gmx.net)
+
+See the file COPYING for license information.
+
+This project uses Objective Development's firmware-only USB driver V-USB
+for Atmel AVR microcontrollers. For more information please visit
+http://www.obdev.at/vusb/
+
+
+More documentation (currently only in german language) about this project can be found at:
+
+http://www.vdr-wiki.de/wiki/index.php/VDR_Wiki:DF10CH_Atmolight_Kontroller
+
+
+This directory contains the firmware, DF10CH setup program and KiCad files of hardware design:
+
+README The file you are currently reading
+df10ch_setup_pkg/ Python modules needed by the DF10CH setup program
+pwm_appl/ Application firmware for PWM-Prozessor
+pwm_boot/ Bootloader firmware for PWM-Prozessor
+usb_appl/ Application firmware for USB-Prozessor
+usb_boot/ Bootloader firmware for USB-Prozessor
+usbdrv/ Objective Development's firmware-only USB driver V-USB for Atmel AVR microcontrollers
+kicad/ KiCad files of hardware design: circuit and board layout
+df10ch_common.h Common include file used by firmware
+df10ch_usb_proto.h Include file with definitions of implemented USB communication protocol
+df10ch_setup.py Main python script of DF10CH setup program
+setup.py Python script used for installation of Df10CH setup program
+MANIFEST.in File used by Python installation script
+
+
+
+----------------------
+Building the hardware:
+----------------------
+
+You will find design files of circuit and board layout for use in KiCad within the kicad/ subdirectory.
+The files are generated with KiCad version 20090216-final.
+
+
+----------------------
+Building the firmware:
+----------------------
+
+For building the firmware for the two Atmel AVR microcontrollers you need AVR-GCC (>=20090313) installed.
+Each firmware subdirectory contains a Makefile for compiling and flashing of firmware:
+
+Compiling firmware:
+
+ make
+
+Flashing firmware with avrdude:
+
+ make prog --> programming of flash, fuse and lockbits
+ make flash --> only programming of flash
+
+Options to avrdude can be specified with:
+
+ make prog AVRDUDE="avrdude -c stk500v2 -P avrdoper"
+
+
+Normally only the bootloaders are flash into the processors. For this you need a dedicated AVR programmer.
+The application firmware could later be flash via the DF10CH setup program.
+This has the advantage that updates of the application firmware could be easily done over the USB
+interface without the need for a dedicated AVR programmer.
+If you like you could directly flash the application firmware without the bootloaders. But you will
+lose the firmware update feature of the DF10CH setup program.
+
+
+------------------------------------
+Installation of DF10Ch setup program
+------------------------------------
+
+For running the DF10CH setup program you need a installed python environment version 2.6,
+the python modules TKinter and PyUSB and a installed libusb library.
+On debian based systems these are packages: python2.6, python-tk, python-usb, libusb-1.0-0
+
+You can start the program directly from this distribution directory with:
+
+ ./df10ch_setup.py
+
+You can also install the program to the default python installation location with:
+
+ python setup.py install
+
+Now df10ch_setup.py should be simply in your standard PATH for execution. Start it with:
+
+ df10ch_setup.py
+
+
+The setup program understands the following command line option:
+
+ -d N Set debug level to N
+ -s N Set number of simulated controllers. With this option you can play with
+ the program without having hardware.
+
+
+
+
+
+
+
+
+
+
diff --git a/df10ch_common.h b/df10ch_common.h
new file mode 100644
index 0000000..a723cd3
--- /dev/null
+++ b/df10ch_common.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+// ---
+// Useful utility defines.
+//
+#define NOMEMINIT __attribute__((section(".noinit")))
+#define NORETURN __attribute__((noreturn))
+#define NOINLINE __attribute__((noinline))
+#define INLINE __attribute__((inline))
+#define nop() __asm__ __volatile__ ("nop" ::)
+#define FIX_POINTER(_ptr) __asm__ __volatile__("" : "=b" (_ptr) : "0" (_ptr))
+#define SIGNATURE_DATA uint8_t __signature[3] __attribute__((section(".signature")))
+
+#define set_bit(var, bit) var |= _BV(bit)
+#define clear_bit(var, bit) var &= ~_BV(bit)
+
+typedef union
+{
+ uint16_t word;
+ uint8_t bytes[2];
+} bytes_word_t;
+
+
+// Definitions for usb <--> pwm controller communication
+#define BAUD 125000UL
+
+#define REQ_HEADER_SIZE 8
+
+#define PWMRQ_DEVICE_TO_HOST 0x80
+#define PWMRQ_ID_MASK 0x3F
+#define PWMRP_KEEP_ALIVE 0x80
+#define PWMRP_HAS_PAYLOAD 0x40
+
+
+
diff --git a/df10ch_setup.py b/df10ch_setup.py
new file mode 100644
index 0000000..ea2fa51
--- /dev/null
+++ b/df10ch_setup.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+#
+# DF10CH setup program main script
+#
+
+import os
+from optparse import OptionParser
+from Tkinter import *
+
+from df10ch_setup_pkg.setup_dlg import SetupDialog
+from df10ch_setup_pkg.areas_dlg import AreasDialog
+from df10ch_setup_pkg.layout_dlg import LayoutDialog
+from df10ch_setup_pkg.device_dlg import DeviceDialog
+from df10ch_setup_pkg.map_dlg import ChannelMapDialog
+from df10ch_setup_pkg.white_cal_dlg import WhiteCalDialog
+from df10ch_setup_pkg.bright_dlg import BrightDialog
+import df10ch_setup_pkg.device_drv
+
+TITLE = "DF10CH Setup V1"
+print
+parser = OptionParser(version=TITLE)
+parser.add_option("-s", "--simulate", action="store", type="int", dest="simulate", default=0, help="Set simulated number of DF10CH controller's")
+parser.add_option("-d", "--debug", action="store", type="int", dest="debug", default=0, help="Set debug level")
+(options, args) = parser.parse_args()
+
+df10ch_setup_pkg.device_drv.SimulatedControllers = options.simulate
+
+root = Tk()
+root.title(TITLE)
+
+width = root.winfo_screenwidth()
+height = root.winfo_screenheight()
+fullscreen = 1
+if options.debug >= 1:
+ width=1280
+ height=720
+ fullscreen = 0
+#root.overrideredirect(1)
+#root.geometry("%dx%d+0+0" % (width, height))
+
+top = Toplevel()
+if os.name == "nt":
+ top.wm_attributes("-fullscreen", fullscreen, "-topmost", 0)
+ root.wm_attributes("-topmost", 1)
+else:
+ top.wm_attributes("-fullscreen", fullscreen)
+ root.transient(top)
+
+areasDlg = AreasDialog(top, width=width, height=height, bd=0, bg="black")
+areasDlg.root.grid(row=0, column=0)
+
+setupDlg = SetupDialog(root)
+layoutDlg = LayoutDialog(areasDlg, setupDlg.sheetMaster)
+mapDlg = ChannelMapDialog(areasDlg, setupDlg.sheetMaster)
+whiteCalDlg = WhiteCalDialog(areasDlg, setupDlg.sheetMaster)
+deviceDlg = DeviceDialog(layoutDlg, setupDlg.sheetMaster)
+brightDlg = BrightDialog(areasDlg, setupDlg.sheetMaster)
+
+setupDlg.addSheet(deviceDlg.root, "Devices")
+setupDlg.addSheet(layoutDlg.root, "RGB-Areas")
+setupDlg.addSheet(mapDlg.root, "Mapping")
+setupDlg.addSheet(whiteCalDlg.root, "White Calibration")
+setupDlg.addSheet(brightDlg.root, "Common Brightness")
+
+root.protocol("WM_DELETE_WINDOW", lambda: deviceDlg.storeAndQuit(root))
+
+root.update_idletasks()
+if deviceDlg.scanDevices():
+ root.mainloop()
diff --git a/df10ch_setup_pkg/__init__.py b/df10ch_setup_pkg/__init__.py
new file mode 100644
index 0000000..4ce758a
--- /dev/null
+++ b/df10ch_setup_pkg/__init__.py
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+# \ No newline at end of file
diff --git a/df10ch_setup_pkg/areas_dlg.py b/df10ch_setup_pkg/areas_dlg.py
new file mode 100644
index 0000000..3eeb8c7
--- /dev/null
+++ b/df10ch_setup_pkg/areas_dlg.py
@@ -0,0 +1,235 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import device_drv
+
+class AreasDialog:
+ def __init__(self, master=None, **args):
+ self.root = Canvas(master, **args)
+ self.selectedArea = None
+ self.selectCallbacks = list()
+
+ def configAreas(self, numAreas):
+ nTopLeft = numAreas[device_drv.AreaIndex("TopLeft")]
+ nTopRight = numAreas[device_drv.AreaIndex("TopRight")]
+ nBottomLeft = numAreas[device_drv.AreaIndex("BottomLeft")]
+ nBottomRight = numAreas[device_drv.AreaIndex("BottomRight")]
+ nCenter = numAreas[device_drv.AreaIndex("Center")]
+ nTop = numAreas[device_drv.AreaIndex("Top")]
+ nBottom = numAreas[device_drv.AreaIndex("Bottom")]
+ nLeft = numAreas[device_drv.AreaIndex("Left")]
+ nRight = numAreas[device_drv.AreaIndex("Right")]
+
+ cv = self.root
+ size = 0
+ width = int(cv["width"])
+ height = int(cv["height"])
+
+ sTop = nTop + nTopLeft + nTopRight
+ if sTop:
+ topSize = int(width / sTop)
+ topSizeEnd = width - topSize * (sTop - 1)
+ if not size or topSize < size:
+ size = topSize
+
+ sBottom = nBottom + nBottomLeft + nBottomRight
+ if sBottom:
+ bottomSize = int(width / sBottom)
+ bottomSizeEnd = width - bottomSize * (sBottom - 1)
+ if not size or bottomSize < size:
+ size = bottomSize
+
+ sLeft = nLeft + nTopLeft + nBottomLeft
+ if sLeft:
+ leftSize = int(height / sLeft)
+ leftSizeEnd = height - leftSize * (sLeft - 1)
+ if not size or leftSize < size:
+ size = leftSize
+
+ sRight = nRight + nTopRight + nBottomRight
+ if sRight:
+ rightSize = int(height / sRight)
+ rightSizeEnd = height - rightSize * (sRight - 1)
+ if not size or rightSize < size:
+ size = rightSize
+
+ if not size or int(width / 2) < size:
+ size = int(width / 2)
+ if not size or int(height / 2) < size:
+ size = int(height / 2)
+
+ pTop = [ None ] * nTop
+ x = 0
+
+ # top left corner
+ if nTopLeft:
+ pTopLeft = [ 0, 0, topSize, 0, topSize, size, size, size, size, leftSize, 0, leftSize ]
+ x = topSize
+ elif nTop == 1:
+ pTop[0] = [ 0, 0, width, 0, width - size, size, size, size ]
+ elif nTop > 1:
+ pTop[0] = [ 0, 0, topSize, 0, topSize, size, size, size ]
+
+ # top right corner
+ if nTopRight:
+ pTopRight = [ width, 0, width, rightSize, width - size, rightSize, width - size, size, width - topSizeEnd, size, width - topSizeEnd, 0 ]
+ elif nTop > 1:
+ pTop[nTop - 1] = [ width, 0, width - size, size, width - topSizeEnd, size, width - topSizeEnd, 0 ]
+
+ # top
+ for i in range(nTop):
+ if pTop[i] == None:
+ pTop[i] = [ x, 0, x + topSize, 0, x + topSize, size, x, size ]
+ x = x + topSize
+
+ pBottom = [ None ] * nBottom
+ x = 0
+
+ # bottom left corner
+ if nBottomLeft:
+ pBottomLeft = [ 0, height, 0, height - leftSizeEnd, size, height - leftSizeEnd, size, height - size, bottomSize, height - size, bottomSize, height ]
+ x = bottomSize
+ elif nBottom == 1:
+ pBottom[0] = [ 0, height, size, height - size, width - size, height - size, width, height ]
+ elif nBottom > 1:
+ pBottom[0] = [ 0, height, size, height - size, bottomSize, height - size, bottomSize, height ]
+
+ # bottom right corner
+ if nBottomRight:
+ pBottomRight = [ width, height, width - bottomSizeEnd, height, width - bottomSizeEnd, height - size, width - size, height - size, width - size, height - rightSizeEnd, width, height - rightSizeEnd ]
+ elif nBottom > 1:
+ pBottom[nBottom - 1] = [ width, height, width - bottomSizeEnd, height, width - bottomSizeEnd, height - size, width - size, height - size ]
+
+ # bottom
+ for i in range(nBottom):
+ if pBottom[i] == None:
+ pBottom[i] = [ x, height, x, height - size, x + bottomSize, height - size, x + bottomSize, height ]
+ x = x + bottomSize
+
+ pLeft = [ None ] * nLeft
+ y = 0
+
+ # left top corner
+ if nTopLeft:
+ y = leftSize
+ elif nLeft == 1:
+ pLeft[0] = [ 0, 0, size, size, size, height - size, 0, height ]
+ elif nLeft > 1:
+ pLeft[0] = [ 0, 0, size, size, size, leftSize, 0, leftSize ]
+
+ # left bottom corner
+ if not nBottomLeft and nLeft > 1:
+ pLeft[nLeft - 1] = [ 0, height, 0, height - leftSizeEnd, size, height - leftSizeEnd, size, height - size ]
+
+ # left
+ for i in range(nLeft):
+ if pLeft[i] == None:
+ pLeft[i] = [ 0, y, size, y, size, y + leftSize, 0, y + leftSize ]
+ y = y + leftSize
+
+ pRight = [ None ] * nRight
+ y = 0
+
+ # right top corner
+ if nTopRight:
+ y = rightSize
+ elif nRight == 1:
+ pRight[0] = [ width, 0, width, height, width - size, height - size, width - size, size ]
+ elif nRight > 1:
+ pRight[0] = [ width, 0, width, rightSize, width - size, rightSize, width - size, size ]
+
+ # right bottom corner
+ if not nBottomRight and nRight > 1:
+ pRight[nRight - 1] = [ width, height, width - size, height - size, width - size, height - rightSizeEnd, width, height - rightSizeEnd ]
+
+ # right
+ for i in range(nRight):
+ if pRight[i] == None:
+ pRight[i] = [ width, y, width, y + rightSize, width - size, y + rightSize, width - size, y ]
+ y = y + rightSize
+
+ # center
+ if nCenter:
+ pCenter = [ size, size, width - size, size, width - size, height - size, size, height - size ]
+
+ # Build canvas items
+ cv.delete(ALL)
+
+ if nTopLeft:
+ cv.create_polygon(pTopLeft, tags="TopLeft")
+ if nTopRight:
+ cv.create_polygon(pTopRight, tags="TopRight")
+ if nBottomLeft:
+ cv.create_polygon(pBottomLeft, tags="BottomLeft")
+ if nBottomRight:
+ cv.create_polygon(pBottomRight, tags="BottomRight")
+ if nCenter:
+ cv.create_polygon(pCenter, tags="Center")
+
+ for i in range(nTop):
+ cv.create_polygon(pTop[i], tags="Top-{0}".format(i + 1))
+ for i in range(nBottom):
+ cv.create_polygon(pBottom[i], tags="Bottom-{0}".format(i + 1))
+ for i in range(nLeft):
+ cv.create_polygon(pLeft[i], tags="Left-{0}".format(i + 1))
+ for i in range(nRight):
+ cv.create_polygon(pRight[i], tags="Right-{0}".format(i + 1))
+
+ for id in cv.find_all():
+ cv.itemconfigure(id, outline="#808080", width=3)
+ cv.tag_bind(id, "<Button-1>", self.cbSelectArea)
+
+ def initAreas(self, color):
+ self.root.configure(background=color)
+ for id in self.root.find_all():
+ self.root.itemconfigure(id, fill=color, outline="#808080")
+ self.selectedArea = None
+
+ def setAreaColor(self, area, color):
+ self.root.itemconfigure(area, fill=color)
+
+ def selectArea(self, area):
+ if self.selectedArea != area:
+ cv = self.root
+ if self.selectedArea:
+ cv.itemconfigure(self.selectedArea, outline="#808080")
+ idList = cv.find_withtag(area)
+ if len(idList):
+ id = idList[0]
+ cv.tag_raise(id)
+ cv.itemconfigure(id, outline="yellow")
+ self.selectedArea = area
+
+ def cbSelectArea(self, event):
+ cv = self.root
+ idList = cv.find_closest(cv.canvasx(event.x), cv.canvasx(event.y))
+ if len(idList):
+ id = idList[0]
+ if self.selectedArea:
+ cv.itemconfigure(self.selectedArea, outline="#808080")
+ self.selectedArea = cv.gettags(id)[0]
+ cv.tag_raise(id)
+ cv.itemconfigure(id, outline="yellow")
+
+ for cb in self.selectCallbacks:
+ cb.cbAreaSelected()
diff --git a/df10ch_setup_pkg/bright_dlg.py b/df10ch_setup_pkg/bright_dlg.py
new file mode 100644
index 0000000..0bf8bf4
--- /dev/null
+++ b/df10ch_setup_pkg/bright_dlg.py
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import tkFont
+import tkMessageBox
+import device_drv
+
+
+class BrightDialog:
+ def __init__(self, areasDlg, master=None, **args):
+ self.areasDlg = areasDlg
+
+ root = Frame(master, **args)
+ self.root = root
+ root.bind("<Map>", self.cbSheetSelected)
+
+ Label(root, text="Common Brightness Calibration", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=5, padx=5, pady=5)
+
+ self.varBright = DoubleVar()
+ self.scBright = Scale(root, label="Brightness", length=200, from_=0, to=1.0, resolution=0.01, orient=HORIZONTAL, variable=self.varBright, command=self.cbSetBright)
+ self.scBright.grid(row=1, column=0, rowspan=1, padx=20, pady=5)
+ self.varBright.set(0.0)
+
+ def cbSheetSelected(self, event):
+ self.loadValues()
+
+ def cbSetBright(self, val):
+ self.setBright()
+
+ def loadValues(self):
+ for ctrlId in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[ctrlId]
+ pwmChannelMap = list()
+ for portName in config.channelMap.keys():
+ configMapRec = config.channelMap[portName]
+ if configMapRec:
+ port, pin = device_drv.PORT_NAME_MAP[portName]
+ pwmChannelMap.append(dict(channel=0, port=port, pins=pin))
+
+ bright = float(config.commonBright) / float(config.commonPWMRes)
+ self.varBright.set(bright)
+
+ while len(pwmChannelMap) < device_drv.NCHANNELS:
+ pwmChannelMap.append(dict(channel=0, port=0, pins=0))
+
+ try:
+ config.ctrl.set_channel_map(0, pwmChannelMap)
+ config.ctrl.set_brightness(0, [ config.pwmRes ] + [ 0 ] * (device_drv.NCHANNELS - 1))
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ self.areasDlg.initAreas("black")
+ self.setBright()
+
+ def setBright(self):
+ try:
+ for ctrlId in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[ctrlId]
+ config.setCommonBright(int(round(self.varBright.get() * config.commonPWMRes)))
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
diff --git a/df10ch_setup_pkg/device_dlg.py b/df10ch_setup_pkg/device_dlg.py
new file mode 100644
index 0000000..a473117
--- /dev/null
+++ b/df10ch_setup_pkg/device_dlg.py
@@ -0,0 +1,428 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import tkFont
+import tkMessageBox
+import tkFileDialog
+import usb
+import pickle
+import string
+import time
+
+import device_drv
+import firmware
+
+class DeviceDialog:
+ def __init__(self, layoutDlg, master=None, **args):
+ self.layoutDlg = layoutDlg
+ self.selectedConfig = None
+ self.selectedDeviceIdx = -1
+
+ root = Frame(master, **args)
+ self.root = root
+ root.bind("<Map>", self.cbSheetSelected)
+
+ Label(root, text="Device Control", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=7, padx=5, pady=5)
+
+ self.varDeviceList = StringVar()
+ self.lbDevices = Listbox(root, selectmode=SINGLE, activestyle=NONE, width=20, height=8, listvariable=self.varDeviceList)
+ self.lbDevices.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, pady=5, sticky=N+S+E+W)
+ self.lbDevices.bind("<ButtonRelease-1>", self.cbSelectDevice)
+
+ self.varVersion = StringVar()
+ Label(root, text="Version:").grid(row=1, column=2, sticky=E)
+ self.etVersion = Label(root, textvariable=self.varVersion, anchor=W, relief=SUNKEN)
+ self.etVersion.grid(row=1, column=3, columnspan=4, padx=5, pady=5, sticky=W+E)
+
+ self.varPWMRes = StringVar()
+ Label(root, text="PWM Resolution:").grid(row=2, column=2, sticky=E)
+ self.etPWMRes = Label(root, textvariable=self.varPWMRes, anchor=W, relief=SUNKEN)
+ self.etPWMRes.grid(row=2, column=3, columnspan=4, padx=5, pady=5, sticky=W+E)
+
+ self.varPWMFreq = IntVar()
+ Label(root, text="PWM Frequency:").grid(row=3, column=2, sticky=E)
+ self.varPWMFreq.set(device_drv.MIN_PWM_FREQ)
+ self.scPWMFreq = Scale(root, length=250, from_=device_drv.MIN_PWM_FREQ, to=device_drv.MAX_PWM_FREQ, resolution=1, tickinterval=50, orient=HORIZONTAL, variable=self.varPWMFreq, command=self.cbSetPWMFreq)
+ self.scPWMFreq.grid(row=3, column=3, columnspan=4, padx=5, pady=5, sticky="W")
+
+ self.varCommonBright = IntVar()
+ Label(root, text="Common Brightness:").grid(row=4, column=2, sticky=E)
+ self.varCommonBright.set(0)
+ self.scCommonBright = Scale(root, length=250, from_=0, to=255, resolution=1, tickinterval=50, orient=HORIZONTAL, variable=self.varCommonBright, command=self.cbSetCommonBrightness)
+ self.scCommonBright.grid(row=4, column=3, columnspan=4, padx=5, pady=5, sticky=W)
+
+ self.btScanDevices = Button(root, text="Scan Devices", command=self.cbScanDevices)
+ self.btScanDevices.grid(row=5, column=0, padx=5, pady=5, ipadx=5)
+
+ self.btResetSetup = Button(root, text="Firmware update", command=self.cbFirmwareUpdate)
+ self.btResetSetup.grid(row=5, column=1, padx=5, pady=5, ipadx=5)
+
+ self.btStoreSetup = Button(root, text="Backup", command=self.cbBackupSetup)
+ self.btStoreSetup.grid(row=5, column=2, padx=5, pady=5, ipadx=5, sticky=E)
+
+ self.btStoreSetup = Button(root, text="Restore", command=self.cbRestoreSetup)
+ self.btStoreSetup.grid(row=5, column=3, padx=5, pady=5, ipadx=5, sticky=W)
+
+ self.btResetSetup = Button(root, text="Reset Setup", command=self.cbResetSetup)
+ self.btResetSetup.grid(row=5, column=4, padx=5, pady=5, ipadx=5, sticky=E)
+
+ self.btStoreSetup = Button(root, text="Store Setup", command=self.cbStoreSetup)
+ self.btStoreSetup.grid(row=5, column=5, padx=5, pady=5, ipadx=5, sticky=W)
+
+ self.varStatus = StringVar()
+ self.lbStatus = Label(root, textvariable=self.varStatus, anchor=W, relief=RIDGE)
+ self.lbStatus.grid(row=6, column=0, columnspan=6, padx=0, pady=0, sticky=W+E)
+
+
+ def cbSheetSelected(self, event):
+ if self.selectedConfig:
+ self.loadDeviceValues()
+
+ def cbFirmwareUpdate(self):
+ if len(device_drv.DeviceList):
+ self.firmwareUpdate()
+
+ def cbResetSetup(self):
+ if len(device_drv.ConfigMap):
+ self.resetSetup()
+ if self.selectedConfig:
+ self.loadDeviceValues()
+
+ def cbStoreSetup(self):
+ if len(device_drv.ConfigMap):
+ self.storeSetup()
+ if self.selectedConfig:
+ self.loadDeviceValues()
+
+ def cbBackupSetup(self):
+ if self.selectedConfig:
+ self.backupSetup()
+
+ def cbRestoreSetup(self):
+ if self.selectedConfig:
+ self.restoreSetup()
+
+ def cbSetCommonBrightness(self, val):
+ if self.selectedConfig:
+ try:
+ self.selectedConfig.setCommonBright(int(val))
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ def cbSetPWMFreq(self, val):
+ if self.selectedConfig:
+ try:
+ self.selectedConfig.setPWMFreq(int(val))
+ self.varPWMRes.set(self.selectedConfig.pwmRes)
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ def cbSelectDevice(self, event):
+ s = self.lbDevices.curselection()
+ if len(s) == 1:
+ self.selectDevice(int(s[0]))
+
+ def cbScanDevices(self):
+ self.scanDevices()
+
+ def scanDevices(self):
+ deviceList = None
+ self.selectedConfig = None
+ self.selectedDeviceIdx = -1
+ while not deviceList:
+ try:
+ device_drv.LoadConfigs()
+ if len(device_drv.DeviceList):
+ deviceList = device_drv.DeviceList
+ except (device_drv.AtmoControllerError, usb.USBError) as err:
+ if not tkMessageBox.askretrycancel(self.root.winfo_toplevel().title(), "Scanning for controllers fails:" + err.__str__(), icon=tkMessageBox.ERROR):
+ return False
+ else:
+ if not deviceList:
+ if not tkMessageBox.askretrycancel(self.root.winfo_toplevel().title(), "No Controllers found!", icon=tkMessageBox.ERROR):
+ return False
+
+ idList = ""
+ for dev in deviceList:
+ if len(idList) > 0:
+ idList = idList + " "
+ idList = idList + dev.id
+ self.varDeviceList.set(idList)
+
+ self.layoutDlg.setLayoutFromConfig()
+ self.selectDevice(0)
+ return True
+
+ def selectDevice(self, i):
+ self.selectedDeviceIdx = i
+ dev = device_drv.DeviceList[i]
+ id = dev.id
+ if id in device_drv.ConfigMap:
+ config = device_drv.ConfigMap[id]
+ if self.selectedConfig != config:
+ self.selectedConfig = config
+ self.scCommonBright.configure(to=self.selectedConfig.commonPWMRes)
+ self.loadDeviceValues()
+ else:
+ if dev.bootloader_mode():
+ s = "Bootloader USB:{0}".format(dev.version)
+ else:
+ s = "USB:{0} Bootloader PWM:{1:04X}".format(dev.version, dev.get_pwm_version())
+ self.varVersion.set(s)
+ self.lbDevices.selection_clear(0, END)
+ self.lbDevices.selection_set(i)
+ self.lbDevices.see(i)
+
+ def loadDeviceValues(self):
+ self.varVersion.set(self.selectedConfig.version)
+ self.varPWMRes.set(self.selectedConfig.pwmRes)
+ self.varPWMFreq.set(self.selectedConfig.pwmFreq)
+ self.varCommonBright.set(self.selectedConfig.commonBright)
+
+ def storeAndQuit(self, root):
+ if len(device_drv.ConfigMap):
+ if tkMessageBox.askokcancel(self.root.winfo_toplevel().title(), "Store Setup?", icon=tkMessageBox.QUESTION):
+ self.storeSetup()
+ self.resetDevices()
+ device_drv.ReleaseDevices()
+ root.quit()
+
+ def storeSetup(self):
+ self.layoutDlg.setConfigFromLayout()
+ try:
+ for id in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[id]
+ config.write()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ def resetSetup(self):
+ if tkMessageBox.askokcancel(self.root.winfo_toplevel().title(), "Really reset setup of all controllers?", default="cancel", icon=tkMessageBox.QUESTION):
+ try:
+ for id in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[id]
+ config.reset()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ def resetDevices(self):
+ try:
+ for id in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[id]
+ config.ctrl.reset_pwm_ctrl()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ def backupSetup(self):
+ self.layoutDlg.setConfigFromLayout()
+ ctrl = self.selectedConfig.ctrl
+ initialfile = ctrl.id
+ initialfile = string.replace(initialfile, "[", "(")
+ initialfile = string.replace(initialfile, "]", ")")
+ initialfile = string.replace(initialfile, ",", "_")
+ initialfile = initialfile + ".dfc"
+ self.selectedConfig.ctrl = None
+ file = None
+ try:
+ file = tkFileDialog.asksaveasfile("w", title="Backup Configuration for " + self.selectedConfig.id, defaultextension=".dfc", filetypes=[ ("DF10CH Config", "*.dfc") ], initialfile=initialfile)
+ if file:
+ pickle.dump(self.selectedConfig, file)
+ except IOError:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "Could not save configuration to file!")
+ finally:
+ self.selectedConfig.ctrl = ctrl
+ if file:
+ file.close()
+
+ def restoreSetup(self):
+ file = None
+ try:
+ file = tkFileDialog.askopenfile("r", title="Restore Configuration for " + self.selectedConfig.id, defaultextension=".dfc", filetypes=[ ("DF10CH Config", "*.dfc") ])
+ if file:
+ config = pickle.load(file)
+ else:
+ return
+ except IOError:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "Could not read configuration from file!")
+ return
+ finally:
+ if file:
+ file.close()
+
+ config.id = self.selectedConfig.id
+ config.ctrl = self.selectedConfig.ctrl
+
+ try:
+ config.ctrl.set_common_brightness(config.commonBright)
+ config.ctrl.set_pwm_freq(config.pwmFreq)
+ config.write()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ device_drv.ConfigMap[config.id] = config
+ self.selectedConfig = config
+ self.layoutDlg.setLayoutFromConfig()
+ self.scCommonBright.configure(to=self.selectedConfig.commonPWMRes)
+ self.loadDeviceValues()
+
+ def firmwareUpdate(self):
+ try:
+ filename = tkFileDialog.askopenfilename(title="Select firmware", defaultextension=".dff", filetypes=[ ("DF10CH Firmware", "*.dff") ])
+ if not filename or len(filename) == 0:
+ return
+ fw = firmware.FlashMem(filename, 64, True)
+ except (IOError, firmware.FirmwareFlashError) as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ target = fw.target
+ if target != "DF10CH-USB" and target != "DF10CH-PWM":
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "Unknown firmware target '{0}'!".format(target))
+ return
+
+ if target == "DF10CH-PWM":
+ for ctrl in device_drv.DeviceList:
+ if ctrl.bootloader_mode():
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "{0}: Firmware of USB controller must be installed first!".format(ctrl.id))
+ return
+
+ if not tkMessageBox.askokcancel(self.root.winfo_toplevel().title(), "Target controller: {0}, Firmware version: {1}. Really start firmware update?".format(target, fw.version), default="cancel", icon=tkMessageBox.QUESTION):
+ return
+
+ self.displayStatus("Start bootloaders...")
+
+ doFlash = True
+ doRefresh = False
+ try:
+ for ctrl in device_drv.DeviceList:
+ if target == "DF10CH-USB":
+ if not ctrl.bootloader_mode():
+ doRefresh = True
+ ctrl.start_bootloader()
+ else:
+ if not ctrl.get_pwm_bootloader_mode():
+ ctrl.start_pwm_ctrl_bootloader()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ doFlash = False
+
+ if doRefresh:
+ time.sleep(5.0)
+ try:
+ device_drv.FindDevices()
+ except (device_drv.AtmoControllerError, usb.USBError) as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ doFlash = False
+
+ for ctrl in device_drv.DeviceList:
+ try:
+ if target == "DF10CH-USB":
+ if ctrl.bootloader_mode():
+ if doFlash:
+ pageSize = ctrl.get_flash_page_size()
+ if pageSize != fw.pageSize:
+ fw = firmware.FlashMem(filename, pageSize)
+ firstPage = fw.getPageForAddr(0x0000)
+ i = 1
+ if firstPage:
+ fp = firmware.FlashPage(0x0000, pageSize)
+ ctrl.write_flash_page(fp.baseAddr, fp.data)
+ i = 2
+ n = len(fw.pageList)
+ for fp in fw.pageList:
+ if fp != firstPage:
+ self.displayStatus("Flashing USB controller {0}: {1}%".format(ctrl.id, i * 100 / n))
+ ctrl.write_flash_page(fp.baseAddr, fp.data)
+ i = i + 1
+ if firstPage:
+ ctrl.write_flash_page(firstPage.baseAddr, firstPage.data)
+ time.sleep(1.0)
+
+ i = 1
+ for fp in fw.pageList:
+ self.displayStatus("Verifying USB controller {0}: {1}%".format(ctrl.id, i * 100 / n))
+ data = ctrl.read_flash(fp.baseAddr, fp.pageSize)
+ fp.verify(data)
+ i = i + 1
+ time.sleep(1.0)
+ else:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "{0}: Bootloader of USB controller does not start!".format(ctrl.id))
+ doFlash = False
+ else:
+ if ctrl.get_pwm_bootloader_mode():
+ if doFlash:
+ pageSize = ctrl.get_pwm_flash_page_size()
+ if pageSize != fw.pageSize:
+ fw = firmware.FlashMem(filename, pageSize)
+ firstPage = fw.getPageForAddr(0x0000)
+ i = 1
+ if firstPage:
+ fp = firmware.FlashPage(0x0000, pageSize)
+ ctrl.write_pwm_flash_page(fp.baseAddr, fp.data)
+ i = 2
+ n = len(fw.pageList)
+ for fp in fw.pageList:
+ if fp != firstPage:
+ self.displayStatus("Flashing PWM controller {0}: {1}%".format(ctrl.id, i * 100 / n))
+ ctrl.write_pwm_flash_page(fp.baseAddr, fp.data)
+ i = i + 1
+ if firstPage:
+ ctrl.write_pwm_flash_page(firstPage.baseAddr, firstPage.data)
+ time.sleep(1.0)
+
+ i = 1
+ for fp in fw.pageList:
+ self.displayStatus("Verifying PWM controller {0}: {1}%".format(ctrl.id, i * 100 / n))
+ data = ctrl.read_pwm_flash(fp.baseAddr, fp.pageSize)
+ fp.verify(data)
+ i = i + 1
+ time.sleep(1.0)
+ else:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), "{0}: Bootloader of PWM controller does not start!".format(ctrl.id))
+ doFlash = False
+ except (device_drv.AtmoControllerError, firmware.FirmwareFlashError) as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ doFlash = False
+
+ doRefresh = False
+ for ctrl in device_drv.DeviceList:
+ try:
+ if target == "DF10CH-USB":
+ if ctrl.bootloader_mode():
+ doRefresh = True
+ ctrl.start_appl()
+ else:
+ if ctrl.get_pwm_bootloader_mode():
+ ctrl.reset_pwm_ctrl()
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+
+ if doRefresh:
+ self.displayStatus("Start firmware...")
+ time.sleep(5.0)
+ self.displayStatus("")
+ self.scanDevices()
+
+ def displayStatus(self, msg):
+ self.varStatus.set(msg)
+ self.root.update_idletasks()
diff --git a/df10ch_setup_pkg/device_drv.py b/df10ch_setup_pkg/device_drv.py
new file mode 100644
index 0000000..cf00272
--- /dev/null
+++ b/df10ch_setup_pkg/device_drv.py
@@ -0,0 +1,1011 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+import os
+import usb
+import time
+import pickle
+import string
+
+# ---
+# Communication protocol related defines for 10 channel RGB Controller.
+#
+VENDOR_ID = 0x16c0
+PRODUCT_ID = 0x05dc
+VENDOR_NAME = 'yak54@gmx.net'
+DEVICE_NAME = 'DF10CH'
+
+REQ_USB_START = 0 # Start of usb controller requests
+REQ_USB_BL_START = 64 # Start of usb controller boot loader requests
+REQ_PWM_START = 128 # Start of pwm controller requests
+REQ_PWM_BL_START = 192 # Start of pwm controller bootloader requests
+
+ # usb controller requests
+for i, key in enumerate([
+ 'REQ_START_BOOTLOADER', # start boot loader of usb controller
+
+ 'REQ_READ_EE_DATA', # read eeprom data (wLength: number of bytes, wIndex: eeprom start address)
+ 'REQ_WRITE_EE_DATA', # write eeprom data (wLength: number of bytes, wIndex: eeprom start address)
+
+ 'REQ_STOP_PWM_CTRL', # stop PWM controller
+ 'REQ_RESET_PWM_CTRL', # reset PWM controller
+ 'REQ_BOOTLOADER_RESET_PWM_CTRL', # reset PWM controller and signal bootloader start
+
+ 'REQ_SET_REPLY_TIMEOUT', # set reply timeout values (wValue: start timeout [ms], wIndex: timeout [ms])
+ 'REQ_GET_REPLY_ERR_STATUS' # get reply error status (COMM_ERR_...)
+ ], start = REQ_USB_START):
+ exec key + ' = ' + repr(i)
+
+ # usb controller boot loader requests
+for i, key in enumerate([
+ 'BL_REQ_WRITE_PAGE', # write flash page
+ 'BL_REQ_LEAVE_BOOT', # leave boot loader and start application
+ 'BL_REQ_GET_PAGE_SIZE', # return flash page size of device
+ 'BL_REQ_READ_FLASH' # read flash memory
+ ], start = REQ_USB_BL_START):
+ exec key + ' = ' + repr(i)
+
+ # pwm controller requests
+for i, key in enumerate([
+ 'PWM_REQ_GET_VERSION', # Get firmware version
+
+ 'PWM_REQ_SET_BRIGHTNESS', # Set channel brightness values (wLenght: number of bytes, wIndex: start channel)
+ 'PWM_REQ_SET_BRIGHTNESS_SYNCED',
+ 'PWM_REQ_GET_BRIGHTNESS',
+
+ 'PWM_REQ_SET_CHANNEL_MAP', # Set channel to port mapping (wLength: number of bytes, wIndex: start channel)
+ 'PWM_REQ_GET_CHANNEL_MAP',
+
+ 'PWM_REQ_SET_COMMON_PWM', # Set common pwm value (wValue.low: pwm value)
+ 'PWM_REQ_GET_COMMON_PWM',
+
+ 'PWM_REQ_STORE_SETUP', # Store actual calibration values
+ 'PWM_REQ_RESET_SETUP', # Reset calibration values to default
+
+ 'PWM_REQ_GET_REQUEST_ERR_STATUS', # Get request error status (COMM_ERR_...)
+
+ 'PWM_REQ_GET_MAX_PWM', # Get maximum internal PWM value
+
+ 'PWM_REQ_SET_PWM_FREQ',
+ 'PWM_REQ_GET_PWM_FREQ',
+
+ 'PWM_REQ_ECHO_TEST' ## Reply 8 byte header
+ ], start = REQ_PWM_START):
+ exec key + '=' + repr(i)
+
+ # pwm controller boot loader requests
+for i, key in enumerate([
+ 'BL_PWM_REQ_WRITE_PAGE', # write flash page
+ 'BL_PWM_REQ_GET_PAGE_SIZE', # return flash page size of device
+ 'BL_PWM_REQ_READ_FLASH', # read flash memory
+ 'BL_PWM_REQ_GET_REQUEST_ERR_STATUS', # Get request error status (COMM_ERR_...)
+ ], start = REQ_PWM_BL_START):
+ exec key + ' = ' + repr(i)
+
+ # Data payload related
+MAX_PWM_REQ_PAYLOAD_SIZE = 128
+MAX_PWM_REPLY_PAYLOAD_SIZE = 128
+
+# Error flag definition for communication error's between usb and pwm controller
+COMM_ERR_OVERRUN = 0
+COMM_ERR_FRAME = 1
+COMM_ERR_TIMEOUT = 2
+COMM_ERR_START = 3
+COMM_ERR_OVERFLOW = 4
+COMM_ERR_CRC = 5
+COMM_ERR_DUPLICATE = 6
+COMM_ERR_DEBUG = 7
+
+# Port channel mapping related
+NCHANNELS = 30 # Number of supported Channels
+
+NPORTS = 4
+PA_IDX = 0
+PB_IDX = 1
+PC_IDX = 2
+PD_IDX = 3
+
+def CM_CODE(port, channel):
+ return(((channel) << 2) | (port))
+def CM_CHANNEL(code):
+ return((code) >> 2)
+def CM_PORT(code):
+ return((code) & 0x03)
+def CM_BV(bit):
+ return (1<<bit)
+def CM_BIT(bv):
+ i = 0
+ while bv:
+ i = i + 1
+ bv = bv >> 1
+ return i - 1
+
+
+PORT_NAME_MAP = {
+ # J3
+" 1.1": ( PA_IDX, CM_BV(2) ),
+" 1.2": ( PA_IDX, CM_BV(1) ),
+" 1.3": ( PA_IDX, CM_BV(0) ),
+
+ # J4
+" 2.1": ( PA_IDX, CM_BV(5) ),
+" 2.2": ( PA_IDX, CM_BV(4) ),
+" 2.3": ( PA_IDX, CM_BV(3) ),
+
+ # J5
+" 3.1": ( PC_IDX, CM_BV(7) ),
+" 3.2": ( PA_IDX, CM_BV(7) ),
+" 3.3": ( PA_IDX, CM_BV(6) ),
+
+ # J6
+" 4.1": ( PC_IDX, CM_BV(4) ),
+" 4.2": ( PC_IDX, CM_BV(5) ),
+" 4.3": ( PC_IDX, CM_BV(6) ),
+
+ # J7
+" 5.1": ( PC_IDX, CM_BV(1) ),
+" 5.2": ( PC_IDX, CM_BV(2) ),
+" 5.3": ( PC_IDX, CM_BV(3) ),
+
+ # J8
+" 6.1": ( PD_IDX, CM_BV(6) ),
+" 6.2": ( PD_IDX, CM_BV(7) ),
+" 6.3": ( PC_IDX, CM_BV(0) ),
+
+ # J9
+" 7.1": ( PD_IDX, CM_BV(3) ),
+" 7.2": ( PD_IDX, CM_BV(4) ),
+" 7.3": ( PD_IDX, CM_BV(5) ),
+
+ # J10
+" 8.1": ( PB_IDX, CM_BV(6) ),
+" 8.2": ( PB_IDX, CM_BV(7) ),
+" 8.3": ( PD_IDX, CM_BV(2) ),
+
+ # J11
+" 9.1": ( PB_IDX, CM_BV(3) ),
+" 9.2": ( PB_IDX, CM_BV(4) ),
+" 9.3": ( PB_IDX, CM_BV(5) ),
+
+ # J12
+"10.1": ( PB_IDX, CM_BV(0) ),
+"10.2": ( PB_IDX, CM_BV(1) ),
+"10.3": ( PB_IDX, CM_BV(2) )
+}
+
+# Brightness related
+NBRIGHTS = 256
+NCOMMONBRIGHTS = 256
+
+# PWM frequency related
+MIN_PWM_FREQ = 50
+MAX_PWM_FREQ = 400
+
+# PWM controller version request related
+PWM_VERS_APPL = 0 # Is application firmware
+PWM_VERS_BOOT = 1 # Is bootloader firmware
+
+# USB related
+DEF_USB_TIMEOUT = 100
+DEF_RETRY = 3
+
+def GetCommErrMsg(stat):
+ if stat == 0:
+ rc = 'OK'
+ else:
+ rc = ''
+ if stat & (1<<COMM_ERR_OVERRUN):
+ rc = rc + " OVERRUN"
+ if stat & (1<<COMM_ERR_FRAME):
+ rc = rc + " FRAME"
+ if stat & (1<<COMM_ERR_TIMEOUT):
+ rc = rc + " TIMEOUT"
+ if stat & (1<<COMM_ERR_START):
+ rc = rc + " START"
+ if stat & (1<<COMM_ERR_OVERFLOW):
+ rc = rc + " OVERFLOW"
+ if stat & (1<<COMM_ERR_CRC):
+ rc = rc + " CRC"
+ if stat & (1<<COMM_ERR_DUPLICATE):
+ rc = rc + " DUPLICATE"
+ if stat & (1<<COMM_ERR_DEBUG):
+ rc = rc + " DEBUG"
+ return rc
+
+
+CONFIG_VALID_ID = 0xA0A1
+CONFIG_VERSION = 0x0001
+CONFIG_CLASS_VERSION = 0x0001
+
+DEFAULT_GAMMA_VAL = 22
+MIN_GAMMA_VAL = 10
+MAX_GAMMA_VAL = 50
+
+AREA_NAMES = "Top", "Bottom", "Left", "Right", "Center", "TopLeft", "TopRight", "BottomLeft", "BottomRight"
+MAX_AREAS = 30, 30, 30, 30, 1, 1, 1, 1, 1
+
+def NumBaseAreas():
+ return len(AREA_NAMES)
+
+def AreaIndex(area):
+ return AREA_NAMES.index(area)
+
+def AreaName(code, areaNum):
+ areaIdx = code >> 2
+ if areaIdx < 4:
+ return "{0}-{1}".format(AREA_NAMES[areaIdx], areaNum + 1)
+ if areaIdx < NumBaseAreas():
+ return AREA_NAMES[areaIdx]
+ return None
+
+COLOR_NAMES = "red", "green", "blue"
+
+def ColorIndex(name):
+ return COLOR_NAMES.index(name)
+
+def ColorName(code):
+ return COLOR_NAMES[code & 0x03]
+
+def AreaCode(area, color):
+ s = string.split(area, '-')
+ areaIdx = AreaIndex(s[0])
+ if areaIdx < 4:
+ areaNum = int(s[1]) - 1
+ else:
+ areaNum = 0
+ return ((areaIdx << 2) + (color & 0x03)), areaNum
+
+
+class AtmoControllerError(Exception):
+ def __init__(self, dev, msg):
+ self.id = dev.id
+ self.message = msg
+
+ def __str__(self):
+ return '{0}: {1}'.format(self.id, self.message)
+
+
+
+class DF10CHController:
+ '''
+ Interface to DF10CH RGB Controller
+ '''
+
+ def __init__(self, usbdev, busnum, devnum, version, serial):
+ self.usbdev = usbdev
+ self.busnum = busnum
+ self.devnum = devnum
+ self.version = version
+ self.serial = serial
+ self.id = 'DF10CH[{0},{1}]'.format(self.busnum, self.devnum)
+
+ def release(self):
+ self.usbdev.releaseInterface()
+
+ def bootloader_mode(self):
+ return self.serial == "BL"
+
+ def ctrl_write(self, req, value, index, data, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY):
+ while retry > 0:
+ try:
+ retry = retry - 1
+ written = self.usbdev.controlMsg(usb.ENDPOINT_OUT|usb.RECIP_DEVICE|usb.TYPE_VENDOR, req, data, value, index, timeout)
+ except usb.USBError as err:
+ if retry == 0:
+ raise AtmoControllerError(self, err.__str__())
+ else:
+ if written != len(data):
+ raise AtmoControllerError(self, 'could not write all payload data to device')
+ break
+
+ def ctrl_read(self, req, value = 0, index = 0, size = 0, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY):
+ while retry > 0:
+ try:
+ retry = retry - 1
+ data = self.usbdev.controlMsg(usb.ENDPOINT_IN|usb.RECIP_DEVICE|usb.TYPE_VENDOR, req, size, value, index, timeout)
+ except usb.USBError as err:
+ if retry == 0:
+ raise AtmoControllerError(self, err.__str__())
+ else:
+ if len(data) != size:
+ raise AtmoControllerError(self, 'could not read all payload data')
+ break
+ return data
+
+ def pwm_ctrl_write(self, req, value, index, data, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY):
+ if len(data) > MAX_PWM_REQ_PAYLOAD_SIZE:
+ raise AtmoControllerError(self, 'to many bytes in payload request data')
+ self.ctrl_write(req, value, index, data, timeout, retry)
+
+ def pwm_ctrl_read(self, req, value = 0, index = 0, size = 0, timeout = DEF_USB_TIMEOUT, retry = DEF_RETRY):
+ if size > MAX_PWM_REPLY_PAYLOAD_SIZE:
+ raise AtmoControllerError(self, 'to many bytes for reply payload data')
+ return self.ctrl_read(req, value, index, size, timeout, retry)
+
+ def verify_reply_data(self, start, data, rdata, msg):
+ for i in range(len(data)):
+ if data[i] != rdata[i]:
+ raise AtmoControllerError(self, '{4}: verify of written {3} data fails {0:04X}: write {1:02X} read {2:02X}'.format(start + i, data[i], rdata[i], msg, self.id))
+
+ def read_ee_data(self, start, size):
+ return self.ctrl_read(REQ_READ_EE_DATA, 0, start, size)
+
+ def write_ee_data(self, start, data):
+ self.ctrl_write(REQ_WRITE_EE_DATA, 0, start, data, DEF_USB_TIMEOUT + len(data) * 10)
+ eedata = self.read_ee_data(start, len(data))
+ self.verify_reply_data(start, data, eedata, 'eeprom')
+
+ def stop_pwm_ctrl(self):
+ self.ctrl_read(REQ_STOP_PWM_CTRL)
+
+ def reset_pwm_ctrl(self):
+ self.ctrl_read(REQ_RESET_PWM_CTRL)
+
+ def start_pwm_ctrl_bootloader(self):
+ self.ctrl_read(REQ_BOOTLOADER_RESET_PWM_CTRL)
+
+ def set_reply_timeout(self, start_timeout, timeout):
+ self.ctrl_read(REQ_SET_REPLY_TIMEOUT, start_timeout, timeout)
+
+ def get_reply_error_status(self):
+ data = self.ctrl_read(REQ_GET_REPLY_ERR_STATUS, 0, 0, 1)
+ return data[0]
+
+ def start_bootloader(self):
+ self.ctrl_read(REQ_START_BOOTLOADER)
+
+ def start_appl(self):
+ self.ctrl_read(BL_REQ_LEAVE_BOOT)
+
+ def get_flash_page_size(self):
+ data = self.ctrl_read(BL_REQ_GET_PAGE_SIZE, 0, 0, 2)
+ return data[0] + data[1] * 256
+
+ def write_flash_page(self, addr, data):
+ self.ctrl_write(BL_REQ_WRITE_PAGE, 0, addr, data)
+
+ def read_flash(self, addr, len):
+ return self.ctrl_read(BL_REQ_READ_FLASH, 0, addr, len)
+
+ def get_request_error_status(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_REQUEST_ERR_STATUS, 0, 0, 1)
+ return data[0]
+
+ def set_brightness(self, start, values):
+ data = list();
+ for i in range(len(values)):
+ data.append(values[i] & 0x00FF)
+ data.append(values[i] / 256)
+ self.pwm_ctrl_write(PWM_REQ_SET_BRIGHTNESS, 0, start, data)
+
+ def set_brightness_synced(self, start, values):
+ data = list();
+ for i in range(len(values)):
+ data.append(values[i] & 0x00FF)
+ data.append(values[i] / 256)
+ self.pwm_ctrl_write(PWM_REQ_SET_BRIGHTNESS_SYNCED, 0, start, data)
+
+ def get_brightness(self, start, nch):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_BRIGHTNESS, 0, start, nch * 2)
+ values = list()
+ for i in range(nch):
+ values.append(data[i*2] + data[i*2+1] * 256)
+ return values;
+
+ def get_channel_map(self, start, nch):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_CHANNEL_MAP, 0, start, nch * 2)
+ map = list()
+ for i in range(nch):
+ map.append(dict(channel=CM_CHANNEL(data[i*2]), port=CM_PORT(data[i*2]), pins=data[i*2+1]))
+ return map;
+
+ def set_channel_map(self, start, map):
+ data = list()
+ for mapRec in map:
+ data.append(CM_CODE(mapRec['port'], mapRec['channel']))
+ data.append(mapRec['pins'])
+ self.pwm_ctrl_write(PWM_REQ_SET_CHANNEL_MAP, 0, start, data)
+
+ def set_common_brightness(self, value):
+ self.pwm_ctrl_read(PWM_REQ_SET_COMMON_PWM, value)
+
+ def get_common_brightness(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_COMMON_PWM, 0, 0, 2)
+ return data[0] + data[1] * 256;
+
+ def get_max_pwm_value(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_MAX_PWM, 0, 0, 4)
+ return data[0] + 256 * data[1]
+
+ def get_common_max_pwm_value(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_MAX_PWM, 0, 0, 4)
+ return data[2] + 256 * data[3]
+
+ def set_pwm_freq(self, value):
+ self.pwm_ctrl_read(PWM_REQ_SET_PWM_FREQ, value)
+
+ def get_pwm_freq(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_PWM_FREQ, 0, 0, 2)
+ return data[0] + 256 * data[1]
+
+ def store_setup(self):
+ self.pwm_ctrl_read(PWM_REQ_STORE_SETUP, 0, 0, 0, 1500)
+
+ def reset_setup(self):
+ self.pwm_ctrl_read(PWM_REQ_RESET_SETUP)
+
+ def get_pwm_bootloader_mode(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_VERSION, 0, 0, 2)
+ return (data[0] == PWM_VERS_BOOT)
+
+ def get_pwm_version(self):
+ data = self.pwm_ctrl_read(PWM_REQ_GET_VERSION, 0, 0, 2)
+ return data[1]
+
+ def get_pwm_flash_page_size(self):
+ data = self.pwm_ctrl_read(BL_PWM_REQ_GET_PAGE_SIZE, 0, 0, 2)
+ return data[0] + data[1] * 256
+
+ def write_pwm_flash_page(self, addr, data):
+ self.pwm_ctrl_write(BL_PWM_REQ_WRITE_PAGE, 0, addr, data)
+
+ def read_pwm_flash(self, addr, len):
+ return self.pwm_ctrl_read(BL_PWM_REQ_READ_FLASH, 0, addr, len)
+
+ def get_bootloader_request_error_status(self):
+ data = self.pwm_ctrl_read(BL_PWM_REQ_GET_REQUEST_ERR_STATUS, 0, 0, 1)
+ return data[0]
+
+
+dummySerial = "AP"
+
+class dummyController:
+ def __init__(self, busnum, devnum):
+ self.busnum = busnum
+ self.devnum = devnum
+ self.serial = dummySerial
+ self.id = 'DUMMY[{0},{1}]'.format(self.busnum, self.devnum)
+ self.version = 0x0101
+ self.ee_data = [ 0xFF ] * 512
+ self._reset_setup()
+ self.start_timeout = 50
+ self.timeout = 10
+ self.bright = [ 0] * NCHANNELS
+ self.flash = dict()
+ self.pwm_vers = PWM_VERS_APPL
+ self.pwm_flash = dict()
+
+ def _reset_setup(self):
+ self.common_bright = NCOMMONBRIGHTS - 1
+ self.pwm_freq = 100
+ self.max_pwm = int(16000000 / (16 * 9 * self.pwm_freq) - 1);
+ self.ch_map = [ dict(channel=0, port=0, pins=0) ] * 30
+
+ def release(self):
+ print "{0}: release interface".format(self.id)
+
+ def bootloader_mode(self):
+ return self.serial == "BL"
+
+ def read_ee_data(self, start, size):
+ return self.ee_data[start: start + size]
+
+ def write_ee_data(self, start, data):
+ self.ee_data[start: start + len(data)] = data
+ print "{0}: set ee data:".format(self.id), self.ee_data
+
+ def stop_pwm_ctrl(self):
+ self.pwm_vers = PWM_VERS_APPL
+ print "{0}: stop pwm controller".format(self.id)
+
+ def reset_pwm_ctrl(self):
+ self.pwm_vers = PWM_VERS_APPL
+ print "{0}: reset pwm controller".format(self.id)
+
+ def start_pwm_ctrl_bootloader(self):
+ self.pwm_vers = PWM_VERS_BOOT
+ print "{0}: start pwm controller bootloader".format(self.id)
+
+ def set_reply_timeout(self, start_timeout, timeout):
+ self.start_timeout = start_timeout
+ self.timeout = timeout
+ print "{0}: set start_timeout {1} timeout {2}".format(self.id, start_timeout, timeout)
+
+ def get_reply_error_status(self):
+ return 0
+
+ def start_bootloader(self):
+ print "start bootloader"
+ global dummySerial
+ dummySerial = "BL"
+
+ def start_appl(self):
+ print "start appl"
+ global dummySerial
+ dummySerial = "AP"
+
+ def get_flash_page_size(self):
+ return 64
+
+ def write_flash_page(self, addr, data):
+ print "write flash page {0:04X}: {1}".format(addr, data)
+ self.flash[addr] = data
+
+ def read_flash(self, addr, len):
+ if not addr in self.flash:
+ self.flash[addr] = [ 255 ] * len
+ return self.flash[addr]
+
+ def get_request_error_status(self):
+ return 0
+
+ def set_brightness(self, start, values):
+ self.bright[start: start + len(values)] = values
+ print "{0}: set bright:".format(self.id), self.bright
+
+ def set_brightness_synced(self, start, values):
+ self.bright[start: start + len(values)] = values
+ print "{0}: set bright synced:".format(self.id), self.bright
+
+ def get_brightness(self, start, nch):
+ return self.bright[start: start + nch]
+
+ def get_channel_map(self, start, nch):
+ return self.ch_map[start: start + nch]
+
+ def set_channel_map(self, start, map):
+ self.ch_map[start: start + len(map)] = map
+ print "{0}: set channel map:".format(self.id), self.ch_map
+
+ def set_common_brightness(self, value):
+ self.common_bright = value
+ print "{0}: set common brightness:".format(self.id), self.common_bright
+
+ def get_common_brightness(self):
+ return self.common_bright
+
+ def get_max_pwm_value(self):
+ return self.max_pwm
+
+ def get_common_max_pwm_value(self):
+ return NCOMMONBRIGHTS - 1
+
+ def set_pwm_freq(self, value):
+ self.pwm_freq = value
+ self.max_pwm = int(16000000 / (16 * 9 * value) - 1);
+ print "{0}: set pwm freq {1} max pwm {2}".format(self.id, self.pwm_freq, self.max_pwm)
+
+ def get_pwm_freq(self):
+ return self.pwm_freq
+
+ def store_setup(self):
+ global dummyDevices
+ file = open("dummyctrls.objs", "w")
+ pickle.dump(dummyDevices, file)
+ file.close()
+ print "{0}: store setup".format(self.id)
+
+ def reset_setup(self):
+ self._reset_setup()
+ global dummyDevices
+ file = open("dummyctrls.objs", "w")
+ pickle.dump(dummyDevices, file)
+ file.close()
+ print "{0}: reset setup".format(self.id)
+
+ def get_pwm_bootloader_mode(self):
+ return self.pwm_vers == PWM_VERS_BOOT
+
+ def get_pwm_version(self):
+ return 1
+
+ def get_bootloader_request_error_status(self):
+ return 0
+
+ def get_pwm_flash_page_size(self):
+ return 128
+
+ def write_pwm_flash_page(self, addr, data):
+ print "write pwm flash page {0:04X}: {1}".format(addr, data)
+ self.pwm_flash[addr] = data
+
+ def read_pwm_flash(self, addr, len):
+ if not addr in self.pwm_flash:
+ self.pwm_flash[addr] = [ 255 ] * len
+ return self.pwm_flash[addr]
+
+
+dummyDevices = None
+SimulatedControllers = 0
+
+def loadDummyDevices():
+ global dummyDevices
+ try:
+ file = open("dummyctrls.objs", "r")
+ dummyDevices = pickle.load(file)
+ file.close()
+ except IOError:
+ dummyDevices = list()
+
+ if len(dummyDevices) > SimulatedControllers:
+ dummyDevices[SimulatedControllers: len(dummyDevices)] = []
+ while len(dummyDevices) < SimulatedControllers:
+ dummyDevices.append(dummyController(0, len(dummyDevices) + 1))
+
+ return dummyDevices
+
+
+class ControllerConfig:
+
+ def __init__(self, ctrl):
+ self.classVersion = CONFIG_CLASS_VERSION
+ self.ctrl = ctrl
+ self.id = ctrl.id
+ self.read()
+
+ def read(self):
+ self.ctrl.reset_pwm_ctrl()
+ self.pwmRes = self.ctrl.get_max_pwm_value()
+ self.commonPWMRes = self.ctrl.get_common_max_pwm_value()
+ self.pwmFreq = self.ctrl.get_pwm_freq()
+ self.commonBright = self.ctrl.get_common_brightness()
+ self.numAreas = [ 0 ] * NumBaseAreas()
+
+ eedata = self.ctrl.read_ee_data(1, 5 + len(self.numAreas) + NCHANNELS * 6)
+ #print "read eedata:", eedata
+ configValidId = eedata[0] + eedata[1] * 256
+ if configValidId == CONFIG_VALID_ID:
+ configVersion = "{0:04X}".format(eedata[2] + eedata[3] * 256)
+ for p in range(len(self.numAreas)):
+ self.numAreas[p] = eedata[4 + p]
+ if self.numAreas[p] > MAX_AREAS[p]: self.numAreas = MAX_AREAS[p]
+ else:
+ configVersion = ""
+ self.version = "USB:{0} PWM:{1:04X} CONFIG:{2}".format(self.ctrl.version, self.ctrl.get_pwm_version(), configVersion)
+ pwmChannelMap = self.ctrl.get_channel_map(0, NCHANNELS)
+ #print "read pwmChannelMap", pwmChannelMap
+ self.channelMap = dict()
+ self.numReqChannels = 0
+ for portName in PORT_NAME_MAP.keys():
+ foundArea = None
+ port, pin = PORT_NAME_MAP[portName]
+ for channelRec in pwmChannelMap:
+ reqChannel = channelRec['channel']
+ outPort = channelRec['port']
+ outPins = channelRec['pins']
+ if outPort == port and (outPins & pin):
+ if configValidId == CONFIG_VALID_ID:
+ p = 4 + len(self.numAreas)
+ self.numReqChannels = eedata[p]
+ if self.numReqChannels > NCHANNELS: self.numReqChannels = 0
+ p = p + 1
+ for i in range(self.numReqChannels):
+ if eedata[p] == reqChannel:
+ area = AreaName(eedata[p + 1], eedata[p + 2])
+ if area:
+ foundArea = area
+ color = eedata[p + 1] & 0x03
+ gamma = eedata[p + 3]
+ if gamma < MIN_GAMMA_VAL: gamma = MIN_GAMMA_VAL
+ if gamma > MAX_GAMMA_VAL: gamma = MAX_GAMMA_VAL
+ whiteCal = eedata[p + 4] + eedata[p + 5] * 256
+ if whiteCal > self.pwmRes: whiteCal = self.pwmRes
+ break
+ p = p + 6
+ break
+ if foundArea:
+ self.channelMap[portName] = dict(area=foundArea, color=color, gamma=gamma, whiteCal=whiteCal)
+ else:
+ self.channelMap[portName] = None
+ #print "read channelMap:", self.channelMap
+
+ def write(self):
+ #print "write channelMap:", self.channelMap
+ eedata = list()
+ eedata.append(CONFIG_VALID_ID & 0x00FF)
+ eedata.append(CONFIG_VALID_ID >> 8)
+ eedata.append(CONFIG_VERSION & 0x00FF)
+ eedata.append(CONFIG_VERSION >> 8)
+ eedata.extend(self.numAreas)
+ eedata.append(0)
+
+ reqChannelMap = dict()
+ pwmChannelMap = list()
+ n = 0
+ for portName in self.channelMap.keys():
+ port, pin = PORT_NAME_MAP[portName]
+ channelRec = self.channelMap[portName]
+ if channelRec:
+ area = channelRec['area']
+ color = channelRec['color']
+ whiteCal = channelRec['whiteCal']
+ if whiteCal > self.pwmRes: whiteCal = self.pwmRes
+ gamma = channelRec['gamma']
+ areaCode, areaNum = AreaCode(area, color)
+ key = '{0}{1}{2}{3}'.format(areaCode, areaNum, gamma, whiteCal)
+ if key in reqChannelMap:
+ reqChannel = reqChannelMap[key]
+ else:
+ reqChannel = n
+ n = n + 1
+ reqChannelMap[key] = reqChannel
+ eedata.append(reqChannel)
+ eedata.append(areaCode)
+ eedata.append(areaNum)
+ eedata.append(gamma)
+ eedata.append(whiteCal & 0x00FF)
+ eedata.append(whiteCal >> 8)
+ pwmChannelMap.append(dict(channel=reqChannel, port=port, pins=pin))
+
+ eedata[4 + len(self.numAreas)] = n
+
+ self.numReqChannels = 0
+ while len(pwmChannelMap) < NCHANNELS:
+ pwmChannelMap.append(dict(channel=0, port=0, pins=0))
+
+ #print "write pwmChannelMap:", pwmChannelMap
+ #print "write eedata:", eedata
+ self.ctrl.write_ee_data(1, eedata)
+ self.ctrl.set_channel_map(0, pwmChannelMap)
+ self.ctrl.store_setup()
+ self.read()
+
+ def reset(self):
+ self.ctrl.write_ee_data(1, [ 0xFF, 0xFF ])
+ self.ctrl.reset_setup()
+ self.read()
+
+ def setCommonBright(self, v):
+ if self.commonBright != v:
+ self.ctrl.set_common_brightness(v)
+ self.commonBright = v
+
+ def setPWMFreq(self, v):
+ if self.pwmFreq != v:
+ self.ctrl.set_pwm_freq(v)
+ self.pwmRes = self.ctrl.get_max_pwm_value()
+ self.pwmFreq = v
+
+
+DeviceList = list()
+
+def FindDevices():
+ global DeviceList
+
+ ReleaseDevices()
+
+ if SimulatedControllers:
+ DeviceList = loadDummyDevices()
+ return
+
+ busses = usb.busses()
+ busnum = 0
+ for bus in busses:
+ devnum = 0
+ for dev in bus.devices:
+ if dev.idProduct == PRODUCT_ID and dev.idVendor == VENDOR_ID:
+ try:
+ handle = dev.open()
+ if handle.getString(dev.iManufacturer, 64) == VENDOR_NAME and handle.getString(dev.iProduct, 64) == DEVICE_NAME:
+ handle.setConfiguration(1)
+ handle.claimInterface(0)
+ serial = handle.getString(dev.iSerialNumber, 64)
+ if os.name == "nt":
+ bn = bus.location
+ dn = dev.devnum
+ else:
+ bn = busnum
+ dn = devnum
+ ctrl = DF10CHController(handle, bn, dn, dev.deviceVersion, serial)
+ DeviceList.append(ctrl)
+ except usb.USBError:
+ pass
+ devnum = devnum + 1
+ busnum = busnum + 1
+
+
+def ReleaseDevices():
+ global DeviceList
+ for dev in DeviceList:
+ try:
+ dev.release()
+ except usb.USBError:
+ pass
+ DeviceList = list()
+
+
+ConfigMap = dict()
+
+def LoadConfigs():
+ global ConfigMap, DeviceList
+ ConfigMap = dict()
+ FindDevices()
+ for ctrl in DeviceList:
+ if not ctrl.bootloader_mode() and not ctrl.get_pwm_bootloader_mode():
+ config = ControllerConfig(ctrl)
+ ConfigMap[ctrl.id] = config
+
+
+if __name__ == "__main__":
+ def calc_gamma_tab(gamma, max_pwm):
+ result = list();
+ for i in range (256):
+ v = pow (i / 255.0, gamma)
+ iv = int(round(v * max_pwm))
+ result.append(iv)
+ return result
+
+ FindDevices()
+ if len(DeviceList):
+ dev = DeviceList[0]
+
+ #dev.set_reply_timeout(150, 10)
+
+ if 0:
+# data = range(128, 0, -1)
+# print "write"
+# dev.write_ee_data(0, data)
+ print "read"
+ for i in range(50):
+ eedata = dev.read_ee_data(0, 254)
+ print eedata
+
+ #print "set reply timeout"
+ #dev.set_reply_timeout(950,5)
+
+ if 1:
+ import firmware
+ fw = firmware.FlashMem("/home/andy/python_ws/df10ch/pwm_ctrl/10ch_pwm_ctrl.dff", 128, True)
+ if dev.bootloader_mode():
+ dev.start_appl()
+ time.sleep(5)
+ if not dev.get_pwm_bootloader_mode():
+ dev.start_pwm_ctrl_bootloader()
+ print dev.bootloader_mode(), dev.get_pwm_bootloader_mode()
+ try:
+ for i in range(50):
+ print i
+ for fp in fw.pageList:
+ #print fp.baseAddr
+ data = dev.read_pwm_flash(fp.baseAddr, fp.pageSize)
+ fp.verify(data)
+ except:
+ pass
+ print "get request error status"
+ stat = dev.get_bootloader_request_error_status()
+ print GetCommErrMsg(stat)
+
+ if 0:
+ print 'get pwm version'
+ v = dev.get_pwm_version()
+ print "pwm version: ", v
+
+ if 0:
+ print 'set brighness'
+ #dev.set_pwm_freq(100)
+ f = dev.get_pwm_freq()
+ print "freq: ", f
+ m = dev.get_max_pwm_value()
+ print "max pwm: ", m
+ gtab = calc_gamma_tab(2.2, m)
+ #while 1:
+ t = time.clock()
+ n = 0
+ for i in range(9):
+ for v in range(NBRIGHTS):
+ data = [ gtab[v] ]
+ dev.set_brightness_synced(i, data)
+ n = n + 1
+ for v in range(NBRIGHTS-1,-1,-1):
+ data = [ gtab[v] ]
+ dev.set_brightness_synced(i, data)
+ n = n + 1
+ t1 = time.clock()
+ print "mean time ", (t1 - t) / n
+ print "get request error status"
+ stat = dev.get_request_error_status()
+ print GetCommErrMsg(stat)
+ print "get reply error status"
+ stat = dev.get_reply_error_status()
+ print GetCommErrMsg(stat)
+
+ if 0:
+ print 'set brighness'
+ dev.set_pwm_freq(100)
+ f = dev.get_pwm_freq()
+ print "freq: ", f
+ m = dev.get_max_pwm_value()
+ print "max pwm: ", m
+ gtab = calc_gamma_tab(2.2, m)
+ rows = list()
+ for i in range(256):
+ data = list()
+ for c in range(30):
+ v = i + c
+ if v >= NBRIGHTS:
+ v = v - NBRIGHTS
+ data.append(gtab[v])
+ rows.append(data)
+ data = list()
+ for c in range(30):
+ v = NBRIGHTS - i - c - 1
+ if v < 0:
+ v = v + NBRIGHTS
+ data.append(gtab[v])
+ rows.append(data)
+ while 1:
+ t = time.clock()
+ n = 0
+ for data in rows:
+ dev.set_brightness(0, data)
+ n = n + 1
+ t1 = time.clock()
+ print "mean time ", (t1 - t) / n
+ stat = dev.get_request_error_status()
+ if stat:
+ print "get request error status"
+ print GetCommErrMsg(stat)
+ stat = dev.get_reply_error_status()
+ if stat:
+ print "get reply error status"
+ print GetCommErrMsg(stat)
+
+ if 0:
+ print 'get channel map'
+ data = dev.get_channel_map(0, NCHANNELS)
+ print data
+
+ if 0:
+ print "common brightness test"
+ data = [ 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
+ dev.set_brightness(0, data)
+ for v in range(NBRIGHTS-1,-1,-1):
+ print v
+ dev.set_common_brightness(v)
+ time.sleep(0.01)
+ time.sleep(1)
+ for v in range(NBRIGHTS):
+ dev.set_common_brightness(v)
+ time.sleep(0.01)
+
+ if 0:
+ print "reset setup"
+ dev.reset_setup()
+
+ if 0:
+ print "store setup"
+ dev.store_setup()
+
+ if 0:
+ print "get request error status"
+ stat = dev.get_request_error_status()
+ print GetCommErrMsg(stat)
+
+ if 1:
+ print "get reply error status"
+ stat = dev.get_reply_error_status()
+ print GetCommErrMsg(stat)
+ else:
+ print "No controller found!"
+
+
+
diff --git a/df10ch_setup_pkg/firmware.py b/df10ch_setup_pkg/firmware.py
new file mode 100644
index 0000000..24dc577
--- /dev/null
+++ b/df10ch_setup_pkg/firmware.py
@@ -0,0 +1,135 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+import array
+import fileinput
+import string
+
+class FirmwareFlashError(Exception):
+ def __init__(self, msg = None):
+ self.message = msg
+
+ def __str__(self):
+ return self.message
+
+
+class FlashPage:
+
+ def __init__(self, addr, pageSize):
+ self.pageSize = pageSize
+ self.baseAddr = addr - addr % pageSize
+ self.data = array.array('B', [ 0xFF ] * pageSize)
+
+ def insert(self, addr, value):
+ self.data[addr % self.pageSize] = value
+
+ def verify(self, data):
+ for i in range(self.pageSize):
+ if data[i] != self.data[i]:
+ raise FirmwareFlashError("verify of flash data against firmware fails at {0:04X}: {1:02X} <> {2:02X}".format(self.baseAddr + i, data[i], self.data[i]))
+
+ def __str__(self):
+ s = "{0:04X}: ".format(self.baseAddr)
+ for v in self.data:
+ s = s + "{0:02X} ".format(v)
+ return s
+
+
+class FlashMem:
+
+ def __init__(self, fileName, pageSize, targetInfoMustExist = False):
+ self.pageSize = pageSize
+ self.pageList = list()
+ self.lastLookupPage = None
+ self.target = None
+ self.version = None
+ self.loadFromHexFile(fileName)
+ if targetInfoMustExist and (not self.target or not self.version):
+ raise FirmwareFlashError("no target and/or version information found!")
+
+ def getPageForAddr(self, addr):
+ baseAddr = addr - addr % self.pageSize
+ if self.lastLookupPage and self.lastLookupPage.baseAddr == baseAddr:
+ return self.lastLookupPage;
+ for p in self.pageList:
+ if p.baseAddr == baseAddr:
+ self.lastLookupPage = p
+ return p
+ return None
+
+ def insert(self, addr, value):
+ p = self.getPageForAddr(addr)
+ if not p:
+ p = FlashPage(addr, self.pageSize)
+ self.pageList.append(p)
+ p.insert(addr, value)
+
+ def loadFromHexFile(self, fileName):
+ file = None
+ try:
+ file = fileinput.FileInput(fileName)
+ for line in file:
+ line = string.rstrip(line)
+ lineLen = len(line)
+ if not lineLen:
+ continue
+ lineType = line[0:1]
+ if lineType == "#":
+ continue
+ if lineType == "@":
+ try:
+ self.target, self.version = string.split(line[1:])
+ except:
+ raise FirmwareFlashError()
+ continue
+ if lineLen < 9 or lineType != ":":
+ raise FirmwareFlashError()
+ try:
+ n = int(line[1:3], 16)
+ addr = int(line[3:7], 16)
+ type = int(line[7:9], 16)
+ except:
+ raise FirmwareFlashError()
+ if type != 0:
+ break
+ if n > 0:
+ if lineLen < (9 + 2 * n):
+ raise FirmwareFlashError()
+ for i in range(n):
+ try:
+ data = int(line[i * 2 + 9: i * 2 + 11], 16)
+ except:
+ raise FirmwareFlashError()
+ self.insert(addr + i, data)
+ except IOError as err:
+ raise FirmwareFlashError("could not read firmware file '{0}': {1}".format(fileName, err.__str__()))
+ except FirmwareFlashError:
+ raise FirmwareFlashError("could not read firmware file '{0}': syntax error at line {1}".format(fileName, file.lineno()))
+ finally:
+ if file:
+ file.close()
+
+if __name__ == "__main__":
+ m = FlashMem("10ch_usb_ctrl.hex", 16)
+ print "target:", m.target, "version:", m.version
+ for p in m.pageList:
+ print p \ No newline at end of file
diff --git a/df10ch_setup_pkg/layout_dlg.py b/df10ch_setup_pkg/layout_dlg.py
new file mode 100644
index 0000000..500c029
--- /dev/null
+++ b/df10ch_setup_pkg/layout_dlg.py
@@ -0,0 +1,111 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import tkFont
+
+import device_drv
+
+
+class LayoutDialog:
+ def __init__(self, areasDlg, master=None, **args):
+ self.areasDlg = areasDlg
+ self.numAreas = [ 0 ] * device_drv.NumBaseAreas()
+ self.varNumAreas = list()
+ for i in range(device_drv.NumBaseAreas()):
+ self.varNumAreas.append(StringVar())
+
+ root = Frame(master, **args)
+ self.root = root
+
+ Label(root, text="Configure RGB-Areas", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=5, padx=5, pady=5)
+ Label(root, text="Top").grid(row=1, column=2)
+ Label(root, text="TopLeft").grid(row=1, column=0, sticky=E)
+ Label(root, text="Left").grid(row=3, column=0, sticky=E)
+ Label(root, text="BottomLeft").grid(row=5, column=0, sticky=E)
+ Label(root, text="TopRight").grid(row=1, column=4, sticky=W)
+ Label(root, text="Right").grid(row=3, column=4, sticky=W)
+ Label(root, text="BottomRight").grid(row=5, column=4, sticky=W)
+ Label(root, text="Bottom").grid(row=5, column=2)
+
+ i = device_drv.AreaIndex("TopLeft")
+ self.sbTopLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2)
+ self.sbTopLeft.grid(row=2, column=1, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("TopRight")
+ self.sbTopRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2)
+ self.sbTopRight.grid(row=2, column=3, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("BottomLeft")
+ self.sbBottomLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2)
+ self.sbBottomLeft.grid(row=4, column=1, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("BottomRight")
+ self.sbBottomRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2)
+ self.sbBottomRight.grid(row=4, column=3, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("Center")
+ self.sbCenter = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], width=2)
+ self.sbCenter.grid(row=3, column=2, padx=20, pady=20)
+
+ i = device_drv.AreaIndex("Top")
+ self.sbTop = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3)
+ self.sbTop.grid(row=2, column=2, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("Bottom")
+ self.sbBottom = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3)
+ self.sbBottom.grid(row=4, column=2, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("Left")
+ self.sbLeft = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3)
+ self.sbLeft.grid(row=3, column=1, padx=5, pady=5)
+
+ i = device_drv.AreaIndex("Right")
+ self.sbRight = Spinbox(root, textvariable=self.varNumAreas[i], from_=0, to=device_drv.MAX_AREAS[i], increment=1, width=3)
+ self.sbRight.grid(row=3, column=3, padx=5, pady=5)
+
+ self.btApply = Button(root, text="Apply", command=self.cbApply)
+ self.btApply.grid(row=6, column=4, padx=20, pady=20, ipadx=5)
+
+ def cbApply(self):
+ for i in range(device_drv.NumBaseAreas()):
+ self.numAreas[i] = int(self.varNumAreas[i].get())
+ self.areasDlg.configAreas(self.numAreas)
+
+ def setLayoutFromConfig(self):
+ for i in range(device_drv.NumBaseAreas()):
+ self.numAreas[i] = 0
+ for ctrlId in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[ctrlId]
+ for i in range(device_drv.NumBaseAreas()):
+ if config.numAreas[i] > self.numAreas[i]:
+ self.numAreas[i] = config.numAreas[i]
+ for i in range(device_drv.NumBaseAreas()):
+ self.varNumAreas[i].set(self.numAreas[i])
+ self.areasDlg.configAreas(self.numAreas)
+
+ def setConfigFromLayout(self):
+ for ctrlId in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[ctrlId]
+ for i in range(device_drv.NumBaseAreas()):
+ config.numAreas[i] = self.numAreas[i]
+
diff --git a/df10ch_setup_pkg/map_dlg.py b/df10ch_setup_pkg/map_dlg.py
new file mode 100644
index 0000000..b8cd575
--- /dev/null
+++ b/df10ch_setup_pkg/map_dlg.py
@@ -0,0 +1,256 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import tkFont
+import tkMessageBox
+import device_drv
+import string
+
+class ChannelMapDialog:
+ def __init__(self, areasDlg, master=None, **args):
+ self.areasDlg = areasDlg
+ areasDlg.selectCallbacks.append(self)
+
+ self.actualIdx = None
+ self.actualCtrlId = None
+ self.actualPortName = None
+ self.actualArea = None
+ self.actualColor = None
+ self.channelList = None
+
+ root = Frame(master, **args)
+ self.root = root
+ root.bind("<Map>", self.cbSheetSelected)
+
+ Label(root, text="Channel Mapping", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=4, padx=5, pady=5)
+
+ self.yScroll = Scrollbar (root, orient=VERTICAL)
+ self.yScroll.grid(row=1, column=1, rowspan=4, sticky=N+S)
+ self.lbChannels = Listbox(root, selectmode=SINGLE, activestyle=NONE, width=35, height=30, yscrollcommand=self.yScroll.set)
+ self.lbChannels.grid(row=1, column=0, rowspan=4, padx=5, pady=5, sticky=N+S+W+E)
+ self.lbChannels.bind("<ButtonRelease-1>", self.cbSelectChannel)
+ self.yScroll["command"] = self.lbChannels.yview
+
+ frSingleColor = Frame(root, borderwidth=5, relief=RIDGE, padx=0, pady=0)
+ frSingleColor.grid(row=2, column = 2, columnspan = 2, padx=5, pady=5, sticky=W+E)
+
+ Label(frSingleColor, text="Set color for channel:").grid(row=0, column=0, columnspan=3, padx=5, pady=5, sticky="W")
+
+ self.btRed = Button(frSingleColor, text="Red", bg="red", command=lambda: self.cbSetColor("red"))
+ self.btRed.grid(row=1, column=0, padx=5, pady=5, ipadx=5, sticky=W+E)
+
+ self.btGreen = Button(frSingleColor, text="Green", bg="green", command=lambda: self.cbSetColor("green"))
+ self.btGreen.grid(row=1, column=1, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btBlue = Button(frSingleColor, text="Blue", bg="blue", command=lambda: self.cbSetColor("blue"))
+ self.btBlue.grid(row=1, column=2, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ frGroupColor = Frame(root, borderwidth=5, relief=RIDGE, padx=0, pady=0)
+ frGroupColor.grid(row = 3, column = 2, columnspan = 2, padx=5, pady=5, sticky=W+E)
+
+ Label(frGroupColor, text="Set color for channel group:").grid(row=0, column=0, columnspan=3, padx=5, pady=5, sticky="W")
+
+ self.btRGB = Button(frGroupColor, text="RGB", command=lambda: self.cbSetGroupColor("red", "green", "blue"))
+ self.btRGB.grid(row=1, column=0, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btRBG = Button(frGroupColor, text="RBG", command=lambda: self.cbSetGroupColor("red", "blue", "green"))
+ self.btRBG.grid(row=1, column=1, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btBRG = Button(frGroupColor, text="GRB", command=lambda: self.cbSetGroupColor("green", "red", "blue"))
+ self.btBRG.grid(row=1, column=2, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btGRB = Button(frGroupColor, text="BRG", command=lambda: self.cbSetGroupColor("blue", "red", "green"))
+ self.btGRB.grid(row=2, column=0, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btBGR = Button(frGroupColor, text="GBR", command=lambda: self.cbSetGroupColor("green", "blue", "red"))
+ self.btBGR.grid(row=2, column=1, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+ self.btGBR = Button(frGroupColor, text="BGR", command=lambda: self.cbSetGroupColor("blue", "green", "red"))
+ self.btGBR.grid(row=2, column=2, padx=5, pady=5, ipadx = 5, sticky=W)
+
+ #frNavi = Frame(root, padx=0, pady=0)
+ #frNavi.grid(row = 1, column = 2, columnspan = 2, padx=5, pady=5, sticky=N+S+W+E)
+
+ self.btNext = Button(root, text="Next Ch", command=self.cbNext)
+ self.btNext.grid(row=1, column=2, padx=5, pady=5, ipadx=5, sticky=W+E)
+
+ self.btPrev = Button(root, text="Prev Ch", command=self.cbPrev)
+ self.btPrev.grid(row=1, column=3, padx=5, pady=5, ipadx=5, sticky=W+E)
+
+ self.btDelete = Button(root, text="Delete mapping", command=self.cbDelete)
+ self.btDelete.grid(row=4, column=2, columnspan=2, padx=5, pady=5, ipadx = 5, sticky=W+E)
+
+
+ def cbSelectChannel(self, event):
+ s = self.lbChannels.curselection()
+ if len(s) == 1:
+ self.selectChannel(int(s[0]))
+
+ def cbAreaSelected(self):
+ if self.root.winfo_ismapped() and self.actualIdx != None:
+ self.selectArea(self.areasDlg.selectedArea, self.actualColor)
+ self.storeActual()
+
+ def cbSetGroupColor(self, *colors):
+ actIdx = self.actualIdx
+ if actIdx != None:
+ port, p = string.split(self.actualPortName, ".")
+ for pinNum in range(3):
+ portName = "{0}.{1}".format(port, pinNum + 1)
+ for i, mapRec in enumerate(self.channelList):
+ if mapRec['ctrlId'] == self.actualCtrlId and mapRec['portName'] == portName:
+ self.actualPortName = portName
+ self.actualColor = colors[pinNum]
+ self.actualIdx = i
+ self.storeActual()
+ break
+ self.selectChannel(actIdx)
+
+ def cbSetColor(self, color):
+ if self.actualIdx != None:
+ self.selectArea(self.actualArea, color)
+ self.storeActual()
+
+ def cbDelete(self):
+ if self.actualIdx != None:
+ self.storeActual(True)
+
+ def cbNext(self):
+ if self.actualIdx != None:
+ i = self.actualIdx + 1
+ if i == len(self.channelList):
+ i = 0
+ self.selectChannel(i)
+
+ def cbPrev(self):
+ if self.actualIdx != None:
+ i = self.actualIdx - 1
+ if i < 0:
+ i = len(self.channelList) - 1
+ self.selectChannel(i)
+
+ def cbSheetSelected(self, event):
+ self.loadValues()
+
+ def storeActual(self, delete=False):
+ config = device_drv.ConfigMap[self.actualCtrlId]
+ if delete:
+ config.channelMap[self.actualPortName] = None
+ self.channelList[self.actualIdx] = dict(ctrlId=self.actualCtrlId, portName=self.actualPortName, area=None, color=None)
+ else:
+ self.channelList[self.actualIdx] = dict(ctrlId=self.actualCtrlId, portName=self.actualPortName, area=self.actualArea, color=self.actualColor)
+
+ if not delete and self.actualArea and self.actualColor:
+ configMapRec = config.channelMap[self.actualPortName]
+ if configMapRec:
+ configMapRec['area'] = self.actualArea
+ configMapRec['color'] = device_drv.ColorIndex(self.actualColor)
+ else:
+ configMapRec = dict(area=self.actualArea, color=device_drv.ColorIndex(self.actualColor), gamma=device_drv.DEFAULT_GAMMA_VAL, whiteCal=config.pwmRes)
+ config.channelMap[self.actualPortName] = configMapRec
+ text = "{0}: {1} -> {2}: {3}".format(self.actualCtrlId, self.actualPortName, self.actualArea, self.actualColor)
+ else:
+ text = "{0}: {1}".format(self.actualCtrlId, self.actualPortName)
+
+ self.lbChannels.delete(self.actualIdx, self.actualIdx)
+ self.lbChannels.insert(self.actualIdx, text)
+ self.lbChannels.selection_set(self.actualIdx)
+
+ def loadValues(self):
+ self.actualIdx = None
+ self.channelList = list()
+ self.lbChannels.delete(0, END)
+ for ctrlId in sorted(device_drv.ConfigMap.keys()):
+ config = device_drv.ConfigMap[ctrlId]
+ for portName in sorted(config.channelMap.keys()):
+ configMapRec = config.channelMap[portName]
+ if configMapRec:
+ area = configMapRec['area']
+ color = device_drv.ColorName(configMapRec['color'])
+ text = "{0}: {1} -> {2}: {3}".format(ctrlId, portName, area, color)
+ else:
+ area = None
+ color = None
+ text = "{0}: {1}".format(ctrlId, portName)
+ self.channelList.append(dict(ctrlId=ctrlId, portName=portName, area=area, color=color))
+ self.lbChannels.insert(END, text)
+
+ pwmChannelMap = list()
+ while len(pwmChannelMap) < device_drv.NCHANNELS:
+ pwmChannelMap.append(dict(channel=0, port=0, pins=0))
+
+ try:
+ config.ctrl.set_channel_map(0, pwmChannelMap)
+ config.ctrl.set_brightness(0, [ config.pwmRes ] + [ 0 ] * (device_drv.NCHANNELS - 1))
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ self.areasDlg.initAreas("black")
+ self.actualCtrlId = None
+ self.actualPortName = None
+ if len(self.channelList):
+ self.selectChannel(0)
+
+ def selectChannel(self, i):
+ self.actualIdx = i
+
+ self.lbChannels.selection_clear(0, END)
+ self.lbChannels.selection_set(i)
+ self.lbChannels.see(i)
+
+ mapRec = self.channelList[i]
+ self.selectLight(mapRec['ctrlId'], mapRec['portName'])
+ self.selectArea(mapRec['area'], mapRec['color'])
+
+ def selectLight(self, ctrlId, portName):
+ if ctrlId != self.actualCtrlId or portName != self.actualPortName:
+ if self.actualCtrlId and ctrlId != self.actualCtrlId:
+ config = device_drv.ConfigMap[self.actualCtrlId]
+ try:
+ config.ctrl.set_channel_map(0, [ dict(channel=0, port=0, pins=0) ])
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ port, pin = device_drv.PORT_NAME_MAP[portName]
+ config = device_drv.ConfigMap[ctrlId]
+ try:
+ config.ctrl.set_channel_map(0, [ dict(channel=0, port=port, pins=pin) ])
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ self.actualCtrlId = ctrlId
+ self.actualPortName = portName
+
+ def selectArea(self, area, color):
+ if self.actualArea:
+ self.areasDlg.setAreaColor(self.actualArea, "black")
+ self.actualColor = color
+ if area:
+ self.actualArea = area
+ if not color:
+ color = "black"
+ self.areasDlg.setAreaColor(area, color)
+ self.areasDlg.selectArea(area)
diff --git a/df10ch_setup_pkg/setup_dlg.py b/df10ch_setup_pkg/setup_dlg.py
new file mode 100644
index 0000000..23fc853
--- /dev/null
+++ b/df10ch_setup_pkg/setup_dlg.py
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+
+class SetupDialog:
+
+ def __init__(self, master, side=LEFT):
+
+ self.activeSheet = None
+ self.count = 0
+ self.choice = IntVar(0)
+
+ if side in (TOP, BOTTOM):
+ self.side = LEFT
+ else:
+ self.side = TOP
+
+ self.tabsMaster = Frame(master, borderwidth=2, relief=RIDGE)
+ self.tabsMaster.pack(side=side, fill=BOTH)
+ self.sheetMaster = Frame(master, borderwidth=2, relief=RIDGE)
+ self.sheetMaster.pack(fill=BOTH)
+
+
+ def addSheet(self, sheet, title):
+ b = Radiobutton(self.tabsMaster, text=title, padx=5, pady=10, indicatoron=0, \
+ variable=self.choice, value=self.count, \
+ command=lambda: self.displaySheet(sheet))
+ b.pack(fill=BOTH, side=self.side)
+ if not self.activeSheet:
+ sheet.pack(fill=BOTH, expand=1)
+ self.activeSheet = sheet
+ self.count += 1
+
+
+ def displaySheet(self, sheet):
+ self.activeSheet.forget()
+ sheet.pack(fill=BOTH, expand=1)
+ self.activeSheet = sheet
diff --git a/df10ch_setup_pkg/white_cal_dlg.py b/df10ch_setup_pkg/white_cal_dlg.py
new file mode 100644
index 0000000..3843e78
--- /dev/null
+++ b/df10ch_setup_pkg/white_cal_dlg.py
@@ -0,0 +1,172 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# This file is part of the DF10CH setup program
+#
+
+from Tkinter import *
+import tkFont
+import tkMessageBox
+import device_drv
+
+
+class WhiteCalDialog:
+ def __init__(self, areasDlg, master=None, **args):
+ self.areasMap = None
+ self.selectedArea = None
+
+ self.areasDlg = areasDlg
+ areasDlg.selectCallbacks.append(self)
+
+ root = Frame(master, **args)
+ self.root = root
+ root.bind("<Map>", self.cbSheetSelected)
+
+ Label(root, text="White Calibration", font=tkFont.Font(weight="bold")).grid(row=0, column=0, columnspan=5, padx=5, pady=5)
+ Label(root, text="Max. value:").grid(row=1, column=0, sticky=E)
+ Label(root, text="Gamma value:").grid(row=2, column=0, sticky=E)
+
+
+ self.varWhiteCal = DoubleVar(), DoubleVar(), DoubleVar()
+ self.scRed = Scale(root, label="Red", bg="red", length=200, from_=1.0, to=0.0, resolution=0.01, orient=VERTICAL, variable=self.varWhiteCal[device_drv.ColorIndex("red")], command=self.cbSetWhiteCal)
+ self.scRed.grid(row=1, column=1, rowspan=1, padx=5, pady=5)
+ self.scGreen = Scale(root, label="Green", bg="green", length=200, from_=1.0, to=0.0, resolution=0.01, orient=VERTICAL, variable=self.varWhiteCal[device_drv.ColorIndex("green")], command=self.cbSetWhiteCal)
+ self.scGreen.grid(row=1, column=2, rowspan=1, padx=5, pady=5)
+ self.scBlue = Scale(root, label="Blue", bg="blue", length=200, from_=1.0, to=0.0, resolution=0.01, orient=VERTICAL, variable=self.varWhiteCal[device_drv.ColorIndex("blue")], command=self.cbSetWhiteCal)
+ self.scBlue.grid(row=1, column=3, rowspan=1, padx=5, pady=5)
+
+ self.varGamma = StringVar(), StringVar(), StringVar()
+ self.sbRed = Spinbox(root, textvariable=self.varGamma[device_drv.ColorIndex("red")], from_=device_drv.MIN_GAMMA_VAL/10.0, to=device_drv.MAX_GAMMA_VAL/10.0, format='%2.1f', increment=0.1, width=2, command=self.cbSetGamma)
+ self.sbRed.grid(row=2, column=1, padx=5, pady=5, sticky=W+E)
+ self.sbGreen = Spinbox(root, textvariable=self.varGamma[device_drv.ColorIndex("green")], from_=device_drv.MIN_GAMMA_VAL/10.0, to=device_drv.MAX_GAMMA_VAL/10.0, format='%2.1f', increment=0.1, width=2, command=self.cbSetGamma)
+ self.sbGreen.grid(row=2, column=2, padx=5, pady=5, sticky=W+E)
+ self.sbBlue = Spinbox(root, textvariable=self.varGamma[device_drv.ColorIndex("blue")], from_=device_drv.MIN_GAMMA_VAL/10.0, to=device_drv.MAX_GAMMA_VAL/10.0, format='%2.1f', increment=0.1, width=2, command=self.cbSetGamma)
+ self.sbBlue.grid(row=2, column=3, padx=5, pady=5, sticky=W+E)
+
+ self.varBright = DoubleVar()
+ self.scBright = Scale(root, label="Brightness", length=200, from_=1.00, to=0.0, resolution=0.01, orient=VERTICAL, variable=self.varBright, command=self.cbSetBright)
+ self.scBright.grid(row=1, column=4, rowspan=1, padx=20, pady=5)
+ self.varBright.set(1.0)
+
+ self.varSelectAll = IntVar()
+ self.btSelectAll = Checkbutton(root, text="Select All", command=self.cbSelectAll, variable=self.varSelectAll)
+ self.btSelectAll.grid(row=2, column=4, padx=20, pady=20, ipadx=5, sticky=W+E)
+
+
+ def cbSelectAll(self):
+ self.setBright()
+
+ def cbSheetSelected(self, event):
+ self.loadValues()
+
+ def cbSetWhiteCal(self, val):
+ self.update()
+
+ def cbSetGamma(self):
+ self.update()
+
+ def cbSetBright(self, val):
+ self.setBright()
+
+ def cbAreaSelected(self):
+ if self.root.winfo_ismapped():
+ self.selectArea(self.areasDlg.selectedArea)
+
+ def loadValues(self):
+ self.areasMap = dict()
+ area = None
+ for ctrlId in device_drv.ConfigMap.keys():
+ config = device_drv.ConfigMap[ctrlId]
+ pwmChannelMap = list()
+ brightList = list()
+ reqChannel = 0
+ for portName in config.channelMap.keys():
+ configMapRec = config.channelMap[portName]
+ if configMapRec:
+ port, pin = device_drv.PORT_NAME_MAP[portName]
+ pwmChannelMap.append(dict(channel=reqChannel, port=port, pins=pin))
+ area = configMapRec['area']
+ gamma = configMapRec['gamma'] / 10.0
+ whiteCal = configMapRec['whiteCal']
+ bright = int(round(pow(self.varBright.get(), gamma) * whiteCal))
+ brightList.append(bright)
+ cRec = dict(ctrlId=ctrlId, portName=portName, configMapRec=configMapRec, reqChannel=reqChannel)
+ if not area in self.areasMap: self.areasMap[area] = list()
+ self.areasMap[area].append(cRec)
+ reqChannel = reqChannel + 1
+
+ while reqChannel < device_drv.NCHANNELS:
+ brightList.append(0)
+ pwmChannelMap.append(dict(channel=0, port=0, pins=0))
+ reqChannel = reqChannel + 1
+
+ try:
+ config.ctrl.set_channel_map(0, pwmChannelMap)
+ config.ctrl.set_brightness(0, brightList)
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
+
+ if area:
+ self.selectArea(area)
+ self.setBright()
+
+ def setBright(self):
+ self.areasDlg.initAreas("#{0:02X}{0:02X}{0:02X}".format(int(round(self.varBright.get() * 255.0))))
+ if not self.varSelectAll.get() and self.selectedArea:
+ self.areasDlg.selectArea(self.selectedArea)
+ self.update()
+
+ def selectArea(self, area):
+ if area in self.areasMap:
+ self.varSelectAll.set(0)
+ self.selectedArea = area
+ self.areasDlg.selectArea(area)
+ for cRec in self.areasMap[area]:
+ ctrlId = cRec['ctrlId']
+ config = device_drv.ConfigMap[ctrlId]
+ configMapRec = cRec['configMapRec']
+ color = configMapRec['color']
+ whiteCal = float(configMapRec['whiteCal']) / float(config.pwmRes)
+ gamma = float(configMapRec['gamma']) / 10.0
+ self.varGamma[color].set(gamma)
+ self.varWhiteCal[color].set(whiteCal)
+
+ def update(self):
+ for area in self.areasMap.keys():
+ for cRec in self.areasMap[area]:
+ ctrlId = cRec['ctrlId']
+ reqChannel = cRec['reqChannel']
+ configMapRec = cRec['configMapRec']
+ color = configMapRec['color']
+ config = device_drv.ConfigMap[ctrlId]
+ if self.varSelectAll.get() or self.selectedArea == area:
+ gamma = float(self.varGamma[color].get())
+ whiteCal = int(self.varWhiteCal[color].get() * config.pwmRes)
+ configMapRec['gamma'] = int(gamma * 10.0)
+ configMapRec['whiteCal'] = whiteCal
+ else:
+ gamma = float(configMapRec['gamma']) / 10.0
+ whiteCal = configMapRec['whiteCal']
+ bright = int(round(pow(self.varBright.get(), gamma) * whiteCal))
+ try:
+ config.ctrl.set_brightness(reqChannel, [ bright ])
+ except device_drv.AtmoControllerError as err:
+ tkMessageBox.showerror(self.root.winfo_toplevel().title(), err.__str__())
+ return
diff --git a/df10ch_usb_proto.h b/df10ch_usb_proto.h
new file mode 100644
index 0000000..cb10912
--- /dev/null
+++ b/df10ch_usb_proto.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+/* ---
+ * Communication protocol related defines for DF10CH Atmolight Controller.
+ */
+
+#define REQ_USB_START 0 // Start of usb controller requests
+#define REQ_USB_BL_START 64 // Start of usb controller boot loader requests
+#define REQ_PWM_START 128 // Start of pwm controller requests
+#define REQ_PWM_BL_START 192 // Start of pwm controller boot loader requests
+
+enum
+{
+ // usb controller requests
+ REQ_START_BOOTLOADER = REQ_USB_START, // start boot loader of usb controller
+ REQ_READ_EE_DATA, // read eeprom data (wLength: number of bytes, wIndex: eeprom start address)
+ REQ_WRITE_EE_DATA, // write eeprom data (wLength: number of bytes, wIndex: eeprom start address)
+
+ REQ_STOP_PWM_CTRL, // stop PWM controller
+ REQ_RESET_PWM_CTRL, // reset PWM controller
+ REQ_BOOTLOADER_RESET_PWM_CTRL, // reset PWM controller and signal bootloader start
+
+ REQ_SET_REPLY_TIMEOUT, // set reply timeout values (wValue: start timeout [ms], wIndex: timeout [ms])
+
+ REQ_GET_REPLY_ERR_STATUS, // get reply error status (COMM_ERR_...)
+
+ // usb controller boot loader requests
+ BL_REQ_WRITE_PAGE = REQ_USB_BL_START, // write flash page
+ BL_REQ_LEAVE_BOOT, // leave boot loader and start application
+ BL_REQ_GET_PAGE_SIZE, // return flash page size of device
+ BL_REQ_READ_FLASH, // return flash contents
+
+ // pwm controller requests
+ PWM_REQ_GET_VERSION = REQ_PWM_START, // Get firmware version (returns 1 byte)
+ PWM_REQ_SET_BRIGHTNESS, // Set channel brightness values (wLenght: number of bytes, wIndex: start channel)
+ PWM_REQ_SET_BRIGHTNESS_SYNCED, // Same as above but wait until buffer flip
+ PWM_REQ_GET_BRIGHTNESS,
+
+ PWM_REQ_SET_CHANNEL_MAP, // Set channel to port mapping (wLength: number of bytes, wIndex: start channel)
+ PWM_REQ_GET_CHANNEL_MAP,
+
+ PWM_REQ_SET_COMMON_PWM, // Set common pwm value (wValue.low: pwm value)
+ PWM_REQ_GET_COMMON_PWM,
+
+ PWM_REQ_STORE_SETUP, // Store actual calibration values
+ PWM_REQ_RESET_SETUP, // Reset calibration values to default
+
+ PWM_REQ_GET_REQUEST_ERR_STATUS, // Get request error status (COMM_ERR_...)
+
+ PWM_REQ_GET_MAX_PWM, // Get maximum internal PWM value
+
+ PWM_REQ_SET_PWM_FREQ, // Set pwm frequency (wValue: frequency [hz])
+ PWM_REQ_GET_PWM_FREQ, // Get pwm frequency (returns word)
+
+ PWM_REQ_ECHO_TEST, // Reply 8 byte header
+
+ // pwm controller boot loader requests
+ BL_PWM_REQ_WRITE_PAGE = REQ_PWM_BL_START, // write flash page
+ BL_PWM_REQ_GET_PAGE_SIZE, // return flash page size of device
+ BL_PWM_REQ_READ_FLASH, // return flash contents
+ BL_PWM_REQ_GET_REQUEST_ERR_STATUS // Get request error status (COMM_ERR_...)
+};
+
+// Data payload related
+#define MAX_REQ_PAYLOAD_SIZE 128
+#define MAX_REPLY_PAYLOAD_SIZE 128
+
+// Error flag definition for communication error's of usb and pwm controller
+#define COMM_ERR_OVERRUN 0
+#define COMM_ERR_FRAME 1
+#define COMM_ERR_TIMEOUT 2
+#define COMM_ERR_START 3
+#define COMM_ERR_OVERFLOW 4
+#define COMM_ERR_CRC 5
+#define COMM_ERR_DUPLICATE 6
+#define COMM_ERR_DEBUG 7
+
+// Port channel mapping related
+#define NCHANNELS 30 // Number of supported Channels
+
+#define NPORTS 4
+#define PA_IDX 0
+#define PB_IDX 1
+#define PC_IDX 2
+#define PD_IDX 3
+
+#define CM_CODE(port, channel) (((channel) << 2) | (port))
+#define CM_CHANNEL(code) ((code) >> 2)
+#define CM_PORT(code) ((code) & 0x03)
+
+// PWM frequency related
+#define MIN_PWM_FREQ 50
+#define MAX_PWM_FREQ 400
+
+// PWM controller version request related
+#define PWM_VERS_APPL 0 // Is application firmware
+#define PWM_VERS_BOOT 1 // Is bootloader firmware
diff --git a/kicad/10ch_pwm_ctrl-Lötseite.ps b/kicad/10ch_pwm_ctrl-Lötseite.ps
new file mode 100644
index 0000000..e27450d
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl-Lötseite.ps
@@ -0,0 +1,4881 @@
+%!PS-Adobe-3.0
+%%Creator: PCBNEW-PS
+%%CreationDate: Tue Feb 09 13:07:54 2010
+%%Title: D:/data/atmega/aurora/kicad/10ch_pwm_ctrl-Lötseite.ps
+%%Pages: 1
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 843
+%%DocumentMedia: A4 595 842 0 () ()
+%%Orientation: Landscape
+%%EndComments
+%%Page: 1 1
+/line {
+ newpath
+ moveto
+ lineto
+ stroke
+} bind def
+/cir0 { newpath 0 360 arc stroke } bind def
+/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def
+/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def
+/arc0 { newpath arc stroke } bind def
+/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def
+/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill grestore stroke } bind def
+/poly0 { stroke } bind def
+/poly1 { closepath gsave fill grestore stroke } bind def
+/poly2 { closepath gsave fill grestore stroke } bind def
+/rect0 { rectstroke } bind def
+/rect1 { rectfill } bind def
+/rect2 { rectfill } bind def
+gsave
+72 72 scale % Talk inches
+1 setlinecap
+1 setlinejoin
+1 setlinewidth
+8.267000 0.000000 translate 90 rotate
+0.000100 0.000100 scale % Move to User coordinates
+50 setlinewidth
+120 setlinewidth
+0.000 0.000 0.000 setrgbcolor
+19089 33512 19729 33512 line
+19729 33459 19729 33779 line
+19729 33779 19657 33832 line
+19657 33832 19160 33832 line
+19160 33832 19089 33779 line
+19089 33779 19089 33459 line
+19089 34112 19729 34112 line
+19729 34112 19729 34485 line
+19444 34112 19444 34325 line
+19089 34872 19089 35085 line
+19089 34978 19729 34978 line
+19657 34978 19515 34872 line
+19089 35418 19729 35791 line
+19160 35418 19657 35418 line
+19657 35418 19729 35471 line
+19729 35471 19729 35738 line
+19729 35738 19657 35791 line
+19657 35791 19160 35791 line
+19160 35791 19089 35738 line
+19089 35738 19089 35471 line
+19089 35471 19160 35418 line
+19160 36444 19089 36391 line
+19089 36391 19089 36124 line
+19089 36124 19160 36071 line
+19160 36071 19657 36071 line
+19657 36071 19729 36124 line
+19729 36124 19729 36391 line
+19729 36391 19657 36444 line
+19089 36724 19729 36724 line
+19089 37097 19729 37097 line
+19373 36724 19373 37097 line
+19729 38030 19089 38243 line
+19089 38243 19729 38457 line
+19729 38683 19729 39056 line
+19729 39056 19657 39056 line
+19657 39056 19444 38843 line
+19444 38843 19444 39003 line
+19444 39003 19373 39056 line
+19373 39056 19160 39056 line
+19160 39056 19089 39003 line
+19089 39003 19089 38736 line
+19089 38736 19160 38683 line
+19089 40802 19231 40749 line
+19231 40749 19586 40749 line
+19586 40749 19729 40802 line
+19160 41668 19089 41615 line
+19089 41615 19089 41348 line
+19089 41348 19160 41295 line
+19160 41295 19657 41295 line
+19657 41295 19729 41348 line
+19729 41348 19729 41615 line
+19729 41615 19657 41668 line
+19089 42108 19231 42161 line
+19231 42161 19586 42161 line
+19586 42161 19729 42108 line
+19089 43254 19586 43254 line
+19586 43254 19729 43361 line
+19729 43361 19729 43521 line
+19729 43521 19586 43627 line
+19586 43627 19089 43627 line
+19444 43254 19444 43627 line
+19089 43907 19515 43907 line
+19444 43907 19515 43960 line
+19515 43960 19515 44174 line
+19515 44174 19444 44227 line
+19444 44227 19089 44227 line
+19729 44933 19089 44933 line
+19089 44933 19089 44613 line
+19089 44613 19160 44560 line
+19160 44560 19444 44560 line
+19444 44560 19515 44613 line
+19515 44613 19515 44933 line
+19089 45213 19515 45213 line
+19373 45213 19515 45320 line
+19515 45320 19515 45480 line
+19515 45480 19373 45586 line
+19302 45866 19302 46239 line
+19302 46239 19444 46239 line
+19444 46239 19515 46186 line
+19515 46186 19515 45919 line
+19515 45919 19444 45866 line
+19444 45866 19160 45866 line
+19160 45866 19089 45919 line
+19089 45919 19089 46186 line
+19089 46186 19160 46239 line
+19515 46519 19515 46839 line
+19515 46839 19444 46892 line
+19444 46892 19089 46892 line
+19089 46892 19089 46572 line
+19089 46572 19160 46519 line
+19160 46519 19231 46519 line
+19231 46519 19302 46572 line
+19302 46572 19302 46892 line
+19160 47172 19089 47225 line
+19089 47225 19089 47492 line
+19089 47492 19160 47545 line
+19160 47545 19231 47545 line
+19231 47545 19302 47492 line
+19302 47492 19302 47225 line
+19302 47225 19373 47172 line
+19373 47172 19444 47172 line
+19444 47172 19515 47225 line
+19515 47225 19515 47492 line
+19515 47492 19444 47545 line
+19089 48478 19586 48478 line
+19586 48478 19729 48585 line
+19729 48585 19729 48745 line
+19729 48745 19586 48851 line
+19586 48851 19089 48851 line
+19444 48478 19444 48851 line
+19515 49131 19231 49131 line
+19231 49131 19089 49238 line
+19089 49238 19089 49398 line
+19089 49398 19231 49504 line
+19231 49504 19515 49504 line
+19089 49784 19515 49784 line
+19373 49784 19515 49891 line
+19515 49891 19515 50051 line
+19515 50051 19373 50157 line
+19515 50437 19515 50757 line
+19515 50757 19444 50810 line
+19444 50810 19089 50810 line
+19089 50810 19089 50490 line
+19089 50490 19160 50437 line
+19160 50437 19231 50437 line
+19231 50437 19302 50490 line
+19302 50490 19302 50810 line
+19160 51090 19089 51143 line
+19089 51143 19089 51410 line
+19089 51410 19160 51463 line
+19160 51463 19231 51463 line
+19231 51463 19302 51410 line
+19302 51410 19302 51143 line
+19302 51143 19373 51090 line
+19373 51090 19444 51090 line
+19444 51090 19515 51143 line
+19515 51143 19515 51410 line
+19515 51410 19444 51463 line
+19089 52556 19231 52503 line
+19231 52503 19586 52503 line
+19586 52503 19729 52556 line
+19160 53422 19089 53369 line
+19089 53369 19089 53102 line
+19089 53102 19160 53049 line
+19160 53049 19444 53049 line
+19444 53049 19515 53102 line
+19515 53102 19515 53369 line
+19515 53369 19444 53422 line
+19089 53755 19160 53702 line
+19160 53702 19444 53702 line
+19444 53702 19515 53755 line
+19515 53755 19515 54022 line
+19515 54022 19444 54075 line
+19444 54075 19160 54075 line
+19160 54075 19089 54022 line
+19089 54022 19089 53755 line
+18876 54355 19515 54355 line
+19444 54355 19515 54408 line
+19515 54408 19515 54675 line
+19515 54675 19444 54728 line
+19444 54728 19160 54728 line
+19160 54728 19089 54675 line
+19089 54675 19089 54408 line
+19089 54408 19160 54355 line
+18876 55008 19515 55008 line
+19444 55008 19515 55061 line
+19515 55061 19515 55328 line
+19515 55328 19444 55381 line
+19444 55381 19160 55381 line
+19160 55381 19089 55328 line
+19089 55328 19089 55061 line
+19089 55061 19160 55008 line
+19302 55661 19302 56034 line
+19302 56034 19444 56034 line
+19444 56034 19515 55981 line
+19515 55981 19515 55714 line
+19515 55714 19444 55661 line
+19444 55661 19160 55661 line
+19160 55661 19089 55714 line
+19089 55714 19089 55981 line
+19089 55981 19160 56034 line
+19089 56314 19515 56314 line
+19373 56314 19515 56421 line
+19515 56421 19515 56581 line
+19515 56581 19373 56687 line
+19160 57620 19089 57673 line
+19089 57673 19089 57940 line
+19089 57940 19160 57993 line
+19160 57993 19231 57993 line
+19231 57993 19302 57940 line
+19302 57940 19302 57673 line
+19302 57673 19373 57620 line
+19373 57620 19444 57620 line
+19444 57620 19515 57673 line
+19515 57673 19515 57940 line
+19515 57940 19444 57993 line
+19729 58433 19657 58433 line
+19444 58433 19160 58433 line
+19160 58433 19089 58486 line
+19089 58486 19089 58540 line
+19729 59299 19089 59299 line
+19089 59299 19089 58979 line
+19089 58979 19160 58926 line
+19160 58926 19444 58926 line
+19444 58926 19515 58979 line
+19515 58979 19515 59299 line
+19302 59579 19302 59952 line
+19302 59952 19444 59952 line
+19444 59952 19515 59899 line
+19515 59899 19515 59632 line
+19515 59632 19444 59579 line
+19444 59579 19160 59579 line
+19160 59579 19089 59632 line
+19089 59632 19089 59899 line
+19089 59899 19160 59952 line
+19089 60392 19231 60445 line
+19231 60445 19586 60445 line
+19586 60445 19729 60392 line
+150 setlinewidth
+17402 66371 17402 46686 line
+80394 66371 17402 66371 line
+80394 27001 80394 66371 line
+17402 27001 80394 27001 line
+17402 46686 17402 27001 line
+50 setlinewidth
+newpath 72000 30170 945 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+1890 setlinewidth
+72000 31625 72000 33515 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 74000 31070 945 0 360 arc fill stroke
+newpath 66000 30170 945 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+1890 setlinewidth
+66000 31625 66000 33515 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 68000 31070 945 0 360 arc fill stroke
+newpath 61850 63920 500 0 360 arc fill stroke
+newpath 55650 63920 500 0 360 arc fill stroke
+620 setlinewidth
+58950 63540 58950 63820 line
+58150 63540 58150 63820 line
+59750 63540 59750 63820 line
+58550 62540 58550 62820 line
+57750 62540 57750 62820 line
+59350 62540 59350 62820 line
+50 setlinewidth
+newpath 53600 63920 500 0 360 arc fill stroke
+newpath 47400 63920 500 0 360 arc fill stroke
+620 setlinewidth
+50700 63540 50700 63820 line
+49900 63540 49900 63820 line
+51500 63540 51500 63820 line
+50300 62540 50300 62820 line
+49500 62540 49500 62820 line
+51100 62540 51100 62820 line
+50 setlinewidth
+newpath 45350 63920 500 0 360 arc fill stroke
+newpath 39150 63920 500 0 360 arc fill stroke
+620 setlinewidth
+42450 63540 42450 63820 line
+41650 63540 41650 63820 line
+43250 63540 43250 63820 line
+42050 62540 42050 62820 line
+41250 62540 41250 62820 line
+42850 62540 42850 62820 line
+50 setlinewidth
+newpath 37100 63920 500 0 360 arc fill stroke
+newpath 30900 63920 500 0 360 arc fill stroke
+620 setlinewidth
+34200 63540 34200 63820 line
+33400 63540 33400 63820 line
+35000 63540 35000 63820 line
+33800 62540 33800 62820 line
+33000 62540 33000 62820 line
+34600 62540 34600 62820 line
+50 setlinewidth
+newpath 28850 63920 500 0 360 arc fill stroke
+newpath 22650 63920 500 0 360 arc fill stroke
+620 setlinewidth
+25950 63540 25950 63820 line
+25150 63540 25150 63820 line
+26750 63540 26750 63820 line
+25550 62540 25550 62820 line
+24750 62540 24750 62820 line
+26350 62540 26350 62820 line
+50 setlinewidth
+newpath 22650 29420 500 0 360 arc fill stroke
+newpath 28850 29420 500 0 360 arc fill stroke
+620 setlinewidth
+25550 29800 25550 29520 line
+26350 29800 26350 29520 line
+24750 29800 24750 29520 line
+25950 30800 25950 30520 line
+26750 30800 26750 30520 line
+25150 30800 25150 30520 line
+50 setlinewidth
+newpath 30900 29420 500 0 360 arc fill stroke
+newpath 37100 29420 500 0 360 arc fill stroke
+620 setlinewidth
+33800 29800 33800 29520 line
+34600 29800 34600 29520 line
+33000 29800 33000 29520 line
+34200 30800 34200 30520 line
+35000 30800 35000 30520 line
+33400 30800 33400 30520 line
+50 setlinewidth
+newpath 39150 29420 500 0 360 arc fill stroke
+newpath 45350 29420 500 0 360 arc fill stroke
+620 setlinewidth
+42050 29800 42050 29520 line
+42850 29800 42850 29520 line
+41250 29800 41250 29520 line
+42450 30800 42450 30520 line
+43250 30800 43250 30520 line
+41650 30800 41650 30520 line
+50 setlinewidth
+newpath 47400 29420 500 0 360 arc fill stroke
+newpath 53600 29420 500 0 360 arc fill stroke
+620 setlinewidth
+50300 29800 50300 29520 line
+51100 29800 51100 29520 line
+49500 29800 49500 29520 line
+50700 30800 50700 30520 line
+51500 30800 51500 30520 line
+49900 30800 49900 30520 line
+50 setlinewidth
+newpath 55650 29420 500 0 360 arc fill stroke
+newpath 61850 29420 500 0 360 arc fill stroke
+620 setlinewidth
+58550 29800 58550 29520 line
+59350 29800 59350 29520 line
+57750 29800 57750 29520 line
+58950 30800 58950 30520 line
+59750 30800 59750 30520 line
+58150 30800 58150 30520 line
+50 setlinewidth
+newpath 66500 51170 275 0 360 arc fill stroke
+newpath 65500 51170 275 0 360 arc fill stroke
+newpath 66500 53170 275 0 360 arc fill stroke
+newpath 65500 53170 275 0 360 arc fill stroke
+newpath 63000 53170 350 0 360 arc fill stroke
+newpath 63000 55170 350 0 360 arc fill stroke
+newpath 71500 64420 330 0 360 arc fill stroke
+newpath 72500 64420 330 0 360 arc fill stroke
+newpath 65500 60320 300 0 360 arc fill stroke
+newpath 66500 60320 300 0 360 arc fill stroke
+newpath 66500 61107 300 0 360 arc fill stroke
+newpath 65500 61107 300 0 360 arc fill stroke
+newpath 63638 62170 531 0 360 arc fill stroke
+newpath 68362 62170 531 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+32690 53920 33310 53920 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+34000 54060 34000 53780 line
+35000 54060 35000 53780 line
+36000 54060 36000 53780 line
+37000 54060 37000 53780 line
+38000 54060 38000 53780 line
+39000 54060 39000 53780 line
+40000 54060 40000 53780 line
+41000 54060 41000 53780 line
+41000 57060 41000 56780 line
+40000 57060 40000 56780 line
+39000 57060 39000 56780 line
+38000 57060 38000 56780 line
+37000 57060 37000 56780 line
+36000 57060 36000 56780 line
+35000 57060 35000 56780 line
+34000 57060 34000 56780 line
+33000 57060 33000 56780 line
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+39310 39420 38690 39420 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+38000 39280 38000 39560 line
+37000 39280 37000 39560 line
+36000 39280 36000 39560 line
+35000 39280 35000 39560 line
+34000 39280 34000 39560 line
+33000 39280 33000 39560 line
+32000 39280 32000 39560 line
+31000 39280 31000 39560 line
+31000 36280 31000 36560 line
+32000 36280 32000 36560 line
+33000 36280 33000 36560 line
+34000 36280 34000 36560 line
+35000 36280 35000 36560 line
+36000 36280 36000 36560 line
+37000 36280 37000 36560 line
+38000 36280 38000 36560 line
+39000 36280 39000 36560 line
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+50310 39420 49690 39420 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+49000 39280 49000 39560 line
+48000 39280 48000 39560 line
+47000 39280 47000 39560 line
+46000 39280 46000 39560 line
+45000 39280 45000 39560 line
+44000 39280 44000 39560 line
+43000 39280 43000 39560 line
+42000 39280 42000 39560 line
+42000 36280 42000 36560 line
+43000 36280 43000 36560 line
+44000 36280 44000 36560 line
+45000 36280 45000 36560 line
+46000 36280 46000 36560 line
+47000 36280 47000 36560 line
+48000 36280 48000 36560 line
+49000 36280 49000 36560 line
+50000 36280 50000 36560 line
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+43690 53920 44310 53920 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+45000 54060 45000 53780 line
+46000 54060 46000 53780 line
+47000 54060 47000 53780 line
+48000 54060 48000 53780 line
+49000 54060 49000 53780 line
+50000 54060 50000 53780 line
+51000 54060 51000 53780 line
+52000 54060 52000 53780 line
+52000 57060 52000 56780 line
+51000 57060 51000 56780 line
+50000 57060 50000 56780 line
+49000 57060 49000 56780 line
+48000 57060 48000 56780 line
+47000 57060 47000 56780 line
+46000 57060 46000 56780 line
+45000 57060 45000 56780 line
+44000 57060 44000 56780 line
+50 setlinewidth
+newpath 62500 32670 350 0 360 arc fill stroke
+newpath 62500 33670 350 0 360 arc fill stroke
+newpath 53000 37420 350 0 360 arc fill stroke
+newpath 54000 37420 350 0 360 arc fill stroke
+newpath 55000 38420 350 0 360 arc fill stroke
+newpath 53000 38420 350 0 360 arc fill stroke
+newpath 62500 34670 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+550 setlinewidth
+69975 53170 70525 53170 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 71250 53170 275 0 360 arc fill stroke
+newpath 54000 38420 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+550 setlinewidth
+61500 40895 61500 41445 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 61500 40170 275 0 360 arc fill stroke
+newpath 62500 40170 275 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+550 setlinewidth
+71725 35670 72275 35670 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 73000 35670 275 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+3500 setlinewidth
+73750 41170 77250 41170 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 69000 42170 350 0 360 arc fill stroke
+newpath 69000 41170 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+700 setlinewidth
+68650 40170 69350 40170 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+51310 49670 50690 49670 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+50000 49530 50000 49810 line
+49000 49530 49000 49810 line
+48000 49530 48000 49810 line
+47000 49530 47000 49810 line
+46000 49530 46000 49810 line
+45000 49530 45000 49810 line
+44000 49530 44000 49810 line
+43000 49530 43000 49810 line
+42000 49530 42000 49810 line
+41000 49530 41000 49810 line
+40000 49530 40000 49810 line
+39000 49530 39000 49810 line
+38000 49530 38000 49810 line
+37000 49530 37000 49810 line
+36000 49530 36000 49810 line
+35000 49530 35000 49810 line
+34000 49530 34000 49810 line
+33000 49530 33000 49810 line
+32000 49530 32000 49810 line
+32000 43530 32000 43810 line
+33000 43530 33000 43810 line
+34000 43530 34000 43810 line
+35000 43530 35000 43810 line
+36000 43530 36000 43810 line
+37000 43530 37000 43810 line
+38000 43530 38000 43810 line
+39000 43530 39000 43810 line
+40000 43530 40000 43810 line
+41000 43530 41000 43810 line
+42000 43530 42000 43810 line
+43000 43530 43000 43810 line
+44000 43530 44000 43810 line
+45000 43530 45000 43810 line
+46000 43530 46000 43810 line
+47000 43530 47000 43810 line
+48000 43530 48000 43810 line
+49000 43530 49000 43810 line
+50000 43530 50000 43810 line
+51000 43530 51000 43810 line
+50 setlinewidth
+newpath 19370 62631 800 0 360 arc fill stroke
+newpath 19370 30741 800 0 360 arc fill stroke
+newpath 78425 62631 800 0 360 arc fill stroke
+newpath 78425 30741 800 0 360 arc fill stroke
+newpath 51000 42170 275 0 360 arc fill stroke
+newpath 51000 41170 275 0 360 arc fill stroke
+newpath 63000 49170 275 0 360 arc fill stroke
+newpath 63000 50170 275 0 360 arc fill stroke
+newpath 65500 58170 275 0 360 arc fill stroke
+newpath 64500 58170 275 0 360 arc fill stroke
+newpath 68750 35670 275 0 360 arc fill stroke
+newpath 68750 36670 275 0 360 arc fill stroke
+newpath 63250 37670 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+700 setlinewidth
+59600 37670 58900 37670 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 71250 47670 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+700 setlinewidth
+67600 47670 66900 47670 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 71250 46170 350 0 360 arc fill stroke
+0 setlinewidth 0 setlinecap 0 setlinejoin
+700 setlinewidth
+67600 46170 66900 46170 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 55500 53170 300 0 360 arc fill stroke
+newpath 55500 57170 300 0 360 arc fill stroke
+newpath 55500 43920 300 0 360 arc fill stroke
+newpath 55500 39920 300 0 360 arc fill stroke
+newpath 57750 41170 300 0 360 arc fill stroke
+newpath 57750 37170 300 0 360 arc fill stroke
+newpath 68000 38920 300 0 360 arc fill stroke
+newpath 64000 38920 300 0 360 arc fill stroke
+newpath 63250 36170 300 0 360 arc fill stroke
+newpath 59250 36170 300 0 360 arc fill stroke
+newpath 53250 45670 300 0 360 arc fill stroke
+newpath 53250 49670 300 0 360 arc fill stroke
+newpath 66000 44670 300 0 360 arc fill stroke
+newpath 62000 44670 300 0 360 arc fill stroke
+newpath 66000 46170 300 0 360 arc fill stroke
+newpath 62000 46170 300 0 360 arc fill stroke
+newpath 66000 47670 300 0 360 arc fill stroke
+newpath 62000 47670 300 0 360 arc fill stroke
+newpath 54500 49670 300 0 360 arc fill stroke
+newpath 54500 45670 300 0 360 arc fill stroke
+620 setlinewidth
+60360 44170 60640 44170 line
+60360 45170 60640 45170 line
+60360 46170 60640 46170 line
+60360 47170 60640 47170 line
+60360 48170 60640 48170 line
+60360 49170 60640 49170 line
+60360 50170 60640 50170 line
+60360 51170 60640 51170 line
+60360 52170 60640 52170 line
+60360 53170 60640 53170 line
+60360 54170 60640 54170 line
+60360 55170 60640 55170 line
+60360 56170 60640 56170 line
+0 setlinewidth 0 setlinecap 0 setlinejoin
+900 setlinewidth
+60500 42860 60500 43480 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+620 setlinewidth
+57360 56170 57640 56170 line
+57360 55170 57640 55170 line
+57360 54170 57640 54170 line
+57360 53170 57640 53170 line
+57360 52170 57640 52170 line
+57360 51170 57640 51170 line
+57360 50170 57640 50170 line
+57360 49170 57640 49170 line
+57360 48170 57640 48170 line
+57360 47170 57640 47170 line
+57360 46170 57640 46170 line
+57360 45170 57640 45170 line
+57360 44170 57640 44170 line
+57360 43170 57640 43170 line
+0 setlinewidth 0 setlinecap 0 setlinejoin
+600 setlinewidth
+61500 57620 61500 58220 line
+50 setlinewidth
+1 setlinecap 1 setlinejoin
+newpath 61500 58920 300 0 360 arc fill stroke
+newpath 70500 56170 300 0 360 arc fill stroke
+newpath 65500 56170 300 0 360 arc fill stroke
+newpath 32000 51170 500 0 360 arc fill stroke
+newpath 26000 51170 500 0 360 arc fill stroke
+500 setlinewidth
+71250 53170 71250 53920 line
+66500 51170 66500 53170 line
+63000 50170 66250 50170 line
+66500 50420 66500 51170 line
+66250 50170 66500 50420 line
+71250 63420 71500 63420 line
+68250 63420 71250 63420 line
+71500 63420 72250 63420 line
+72250 63420 72500 63670 line
+72500 63670 72500 64420 line
+71250 53170 71250 47670 line
+71250 47670 71250 46170 line
+71250 46170 71250 36670 line
+54000 41170 51000 41170 line
+63750 28420 63750 29670 line
+63750 29670 63750 33170 line
+63750 33170 63250 33670 line
+63250 33670 62500 33670 line
+57750 41170 54000 41170 line
+63750 28420 62500 28420 line
+32000 51170 32000 49670 line
+54000 38420 54000 41170 line
+71500 54170 71500 63420 line
+71250 53920 71500 54170 line
+66000 28420 66000 30170 line
+72000 28420 72000 30170 line
+63750 28420 66000 28420 line
+66000 28420 72000 28420 line
+72000 28420 74500 28420 line
+73500 35670 73000 35670 line
+54000 38420 54000 37420 line
+68362 63420 68250 63420 line
+74500 34670 73500 35670 line
+24000 51170 26000 51170 line
+74500 33670 74500 34670 line
+75750 32420 74500 33670 line
+75750 29670 75750 32420 line
+74500 28420 75750 29670 line
+61500 41170 64500 41170 line
+64500 57170 64500 57420 line
+61250 34170 56250 34170 line
+64500 58170 64500 58920 line
+64500 58920 64500 60670 line
+64500 60670 64937 61107 line
+64937 61107 65500 61107 line
+66500 53170 66500 53420 line
+64500 55420 64500 57420 line
+315 setlinewidth
+61500 58920 64500 58920 line
+55500 57170 55500 57420 line
+61000 58920 61500 58920 line
+60000 57920 61000 58920 line
+56000 57920 60000 57920 line
+55500 57420 56000 57920 line
+58750 51670 58500 51670 line
+59500 50420 59750 50170 line
+59750 50170 60500 50170 line
+58750 51670 59500 50920 line
+56650 49270 56650 51570 line
+56650 51570 56750 51670 line
+157 setlinewidth
+56750 51670 58500 51670 line
+315 setlinewidth
+57500 49170 56750 49170 line
+56750 49170 56650 49270 line
+59500 50920 59500 50420 line
+500 setlinewidth
+65500 61107 65500 62170 line
+68362 62170 68362 63420 line
+32000 49670 32000 47670 line
+54000 37420 54000 36420 line
+54000 36420 54000 36420 line
+68750 36670 71500 36670 line
+71500 36670 71250 36670 line
+71250 36670 72000 36670 line
+72000 36670 73000 36670 line
+73000 36670 73000 35670 line
+63638 62170 65500 62170 line
+65500 62920 66000 63420 line
+66000 63420 68250 63420 line
+65500 62170 65500 62920 line
+57750 41170 61500 41170 line
+61750 33670 61250 34170 line
+64500 57420 64500 58170 line
+56250 34170 54000 36420 line
+62500 33670 61750 33670 line
+62500 28420 61750 27670 line
+61750 27670 22500 27670 line
+22500 27670 21500 28670 line
+21500 28670 21500 48670 line
+21500 48670 24000 51170 line
+60500 50170 63000 50170 line
+66500 53420 64500 55420 line
+72000 34170 72000 32570 line
+69000 39420 69000 40170 line
+68500 38920 69000 39420 line
+66150 32570 67750 34170 line
+72000 35670 72000 34170 line
+67250 38170 68000 38920 line
+68750 35670 67750 35670 line
+67750 34170 72000 34170 line
+66000 32570 66150 32570 line
+665 setlinewidth
+72000 35670 68750 35670 line
+500 setlinewidth
+67750 35670 67250 36170 line
+68000 38920 68500 38920 line
+67250 36170 67250 38170 line
+315 setlinewidth
+60250 61170 60250 63180 line
+60250 63180 59750 63680 line
+51000 56920 51000 57420 line
+55000 59920 59000 59920 line
+53000 57920 55000 59920 line
+51000 57420 51500 57920 line
+51500 57920 53000 57920 line
+59750 63680 58950 63680 line
+59000 59920 60250 61170 line
+500 setlinewidth
+51500 30060 51100 29660 line
+27500 37170 23500 33170 line
+51100 29020 51100 29660 line
+24750 62680 24750 63280 line
+51500 30660 51500 30060 line
+59750 30660 59750 30060 line
+41250 62680 41250 63280 line
+35000 30060 34600 29660 line
+35000 30660 35000 30060 line
+26750 30660 26750 30060 line
+33000 63280 33400 63680 line
+43250 30060 42850 29660 line
+43250 30660 43250 30060 line
+59750 30060 59350 29660 line
+35000 30660 39510 30660 line
+40000 29670 41000 28670 line
+40000 30170 40000 29670 line
+42850 29020 42850 29660 line
+39510 30660 40000 30170 line
+49250 28670 50750 28670 line
+26750 30660 31490 30660 line
+24500 28670 26000 28670 line
+43250 30660 47760 30660 line
+26350 29020 26350 29660 line
+24750 62680 24750 59670 line
+33000 62680 33000 63280 line
+57750 62680 57750 63280 line
+24750 63280 25150 63680 line
+34250 28670 34600 29020 line
+49500 63280 49900 63680 line
+47760 30660 48250 30170 line
+26750 30060 26350 29660 line
+41000 28670 42500 28670 line
+26000 28670 26350 29020 line
+48250 29670 49250 28670 line
+48250 30170 48250 29670 line
+42500 28670 42850 29020 line
+23500 33170 23500 29670 line
+31750 29670 32750 28670 line
+33000 62680 28740 62680 line
+25150 64320 25150 63680 line
+25500 64670 25150 64320 line
+27250 64670 25500 64670 line
+27750 64170 27250 64670 line
+27750 63670 27750 64170 line
+28740 62680 27750 63670 line
+41250 62680 36990 62680 line
+33400 64320 33400 63680 line
+33750 64670 33400 64320 line
+35500 64670 33750 64670 line
+36000 64170 35500 64670 line
+36000 63670 36000 64170 line
+36990 62680 36000 63670 line
+49500 62680 45240 62680 line
+41650 64320 41650 63680 line
+42000 64670 41650 64320 line
+44000 64670 42000 64670 line
+44250 64420 44000 64670 line
+44250 63670 44250 64420 line
+45240 62680 44250 63670 line
+57750 62680 53490 62680 line
+49900 64320 49900 63680 line
+50250 64670 49900 64320 line
+52000 64670 50250 64670 line
+52500 64170 52000 64670 line
+52500 63670 52500 64170 line
+53490 62680 52500 63670 line
+51500 30660 56260 30660 line
+59350 29020 59350 29660 line
+59000 28670 59350 29020 line
+57500 28670 59000 28670 line
+56500 29670 57500 28670 line
+56500 30420 56500 29670 line
+56260 30660 56500 30420 line
+59750 30660 61740 30660 line
+62500 31420 62500 32670 line
+61740 30660 62500 31420 line
+50750 28670 51100 29020 line
+34600 29020 34600 29660 line
+49500 62680 49500 63280 line
+32750 28670 34250 28670 line
+57750 63280 58150 63680 line
+31750 30400 31750 29670 line
+31490 30660 31750 30400 line
+23500 29670 24500 28670 line
+24750 59670 27500 56920 line
+27500 56920 27500 37170 line
+41250 63280 41650 63680 line
+315 setlinewidth
+49000 56920 49000 58170 line
+58250 61420 58550 61720 line
+49000 58170 50250 59420 line
+50250 59420 51500 59420 line
+51500 59420 53500 61420 line
+58550 61720 58550 62680 line
+53500 61420 58250 61420 line
+52250 58670 54250 60670 line
+50000 57670 51000 58670 line
+58750 60670 59350 61270 line
+59350 61270 59350 62680 line
+50000 56920 50000 57670 line
+54250 60670 58750 60670 line
+51000 58670 52250 58670 line
+48000 58420 49750 60170 line
+52000 61420 52000 63180 line
+48000 56920 48000 58420 line
+50750 60170 52000 61420 line
+51500 63680 50700 63680 line
+49750 60170 50750 60170 line
+52000 63180 51500 63680 line
+49750 61670 50300 62220 line
+46000 56920 46000 59420 line
+48250 61670 49750 61670 line
+46000 59420 48250 61670 line
+50300 62220 50300 62680 line
+47000 58920 49000 60920 line
+47000 56920 47000 58920 line
+51100 61770 51100 62680 line
+50250 60920 51100 61770 line
+49000 60920 50250 60920 line
+45000 56920 45000 58170 line
+43250 63680 42450 63680 line
+43750 63180 43250 63680 line
+43750 59420 43750 63180 line
+45000 58170 43750 59420 line
+40000 56920 40000 59420 line
+42050 61470 42050 62680 line
+40000 59420 42050 61470 line
+44000 57420 42850 58570 line
+42850 58570 42850 62680 line
+44000 56920 44000 57420 line
+35000 63680 34200 63680 line
+35500 63180 35000 63680 line
+39000 58420 35500 61920 line
+35500 61920 35500 63180 line
+39000 56920 39000 58420 line
+37000 57920 33800 61120 line
+37000 56920 37000 57920 line
+33800 61120 33800 62680 line
+38000 58170 34600 61570 line
+34600 61570 34600 62680 line
+38000 56920 38000 58170 line
+36000 57670 33500 60170 line
+36000 56920 36000 57670 line
+27250 63180 26750 63680 line
+26750 63680 25950 63680 line
+28250 60170 27250 61170 line
+33500 60170 28250 60170 line
+27250 61170 27250 63180 line
+34000 56920 34000 57170 line
+32500 58670 27250 58670 line
+34000 57170 32500 58670 line
+27250 58670 25550 60370 line
+25550 60370 25550 62680 line
+26350 60820 26350 62680 line
+35000 57420 33000 59420 line
+27750 59420 26350 60820 line
+33000 59420 27750 59420 line
+35000 56920 35000 57420 line
+26250 34420 24250 32420 line
+24750 29660 25550 29660 line
+33000 36420 33000 36170 line
+33000 36170 33000 36420 line
+24750 29660 24250 30160 line
+31250 34420 26250 34420 line
+31250 34420 31250 34420 line
+24250 32420 24250 30160 line
+31250 34420 33000 36170 line
+25950 31370 27000 32420 line
+35000 35670 35000 36420 line
+27000 32420 31750 32420 line
+25950 30660 25950 31370 line
+31750 32420 35000 35670 line
+34000 35920 34000 36420 line
+25150 31820 26750 33420 line
+31500 33420 34000 35920 line
+25150 30660 25150 31820 line
+26750 33420 31500 33420 line
+32500 31920 32500 30160 line
+36000 36420 36000 35420 line
+36000 35420 32500 31920 line
+33000 29660 33800 29660 line
+32500 30160 33000 29660 line
+38000 34920 34200 31120 line
+34200 31120 34200 30660 line
+38000 36420 38000 34920 line
+37000 36420 37000 35170 line
+33400 31570 33400 30660 line
+37000 35170 33400 31570 line
+41250 29660 42050 29660 line
+40750 33170 40750 30160 line
+39000 34920 40750 33170 line
+40750 30160 41250 29660 line
+39000 36420 39000 34920 line
+42450 32620 42450 30660 line
+44000 36420 44000 34170 line
+44000 34170 42450 32620 line
+43000 36420 43000 34920 line
+43000 34920 41650 33570 line
+41650 33570 41650 30660 line
+49000 31170 49000 30160 line
+49000 30160 49500 29660 line
+49500 29660 50300 29660 line
+45000 35170 49000 31170 line
+45000 36420 45000 35170 line
+47000 36420 47000 35920 line
+50700 32220 50700 30660 line
+47000 35920 50700 32220 line
+46000 36420 46000 35670 line
+46000 35670 49900 31770 line
+49900 31770 49900 30660 line
+48000 36170 50750 33420 line
+50750 33420 53000 33420 line
+56750 31670 57250 31170 line
+57750 29660 58550 29660 line
+48000 36420 48000 36170 line
+57250 31170 57250 30160 line
+53250 33420 55000 31670 line
+57250 30160 57750 29660 line
+55000 31670 56750 31670 line
+53000 33420 53250 33420 line
+55750 33170 57750 33170 line
+51250 35170 53750 35170 line
+50000 36420 50000 36170 line
+50000 36420 51250 35170 line
+53750 35170 55750 33170 line
+57750 33170 58950 31970 line
+58950 31970 58950 30660 line
+49000 36420 49000 36170 line
+57250 32420 58150 31520 line
+53500 34420 55500 32420 line
+55500 32420 57250 32420 line
+49000 36170 50750 34420 line
+53250 34420 53500 34420 line
+58150 31520 58150 30660 line
+50750 34420 53250 34420 line
+60500 51170 63000 51170 line
+63000 51170 65500 51170 line
+63000 53170 63000 51170 line
+55000 48020 55350 48020 line
+63500 55170 65500 53170 line
+33000 49670 33000 48920 line
+42900 48020 55000 48020 line
+55000 48020 55100 48020 line
+42500 48420 42900 48020 line
+63000 55170 63500 55170 line
+42250 50670 42500 50420 line
+40750 50670 42250 50670 line
+40500 50420 40750 50670 line
+157 setlinewidth
+40500 48920 40500 50420 line
+315 setlinewidth
+40250 48670 40500 48920 line
+33250 48670 40250 48670 line
+33000 48920 33250 48670 line
+59250 52670 59750 52170 line
+59750 52170 60500 52170 line
+157 setlinewidth
+56500 52670 58500 52670 line
+315 setlinewidth
+56000 52170 56500 52670 line
+56000 48670 56000 52170 line
+55350 48020 56000 48670 line
+157 setlinewidth
+42500 50420 42500 48420 line
+315 setlinewidth
+61750 53920 63000 55170 line
+61750 52920 61750 53920 line
+61000 52170 61750 52920 line
+60500 52170 61000 52170 line
+59250 52670 58500 52670 line
+53250 56670 55500 58920 line
+61750 62170 64000 64420 line
+61750 61170 61750 62170 line
+59500 58920 61750 61170 line
+55500 58920 59500 58920 line
+64000 64420 71500 64420 line
+53250 49670 53250 56670 line
+500 setlinewidth
+65500 56170 65500 58170 line
+65500 60320 65500 58170 line
+315 setlinewidth
+66000 47670 67250 47670 line
+66500 60320 66850 60320 line
+67750 47670 67250 47670 line
+68250 48170 67750 47670 line
+68250 58920 68250 56670 line
+68250 56670 68250 48170 line
+66850 60320 68250 58920 line
+66000 46170 66000 47670 line
+69000 57420 69000 55920 line
+67250 45670 67250 46170 line
+67313 61107 69000 59420 line
+69000 59420 69000 57420 line
+69000 55920 69000 47420 line
+66000 44670 66250 44670 line
+66250 44670 67250 45670 line
+69000 47420 67750 46170 line
+67313 61107 66500 61107 line
+67250 46170 67750 46170 line
+31000 43920 31250 43670 line
+31250 43670 32000 43670 line
+33000 53920 34000 53920 line
+31000 45670 31000 52420 line
+31000 52420 32500 53920 line
+33000 53920 32500 53920 line
+31000 45670 31000 43920 line
+35000 49670 35000 53920 line
+36000 49670 36000 53920 line
+37000 49670 37000 53920 line
+38000 49670 38000 53920 line
+39000 49670 39000 53920 line
+40000 49670 40000 53920 line
+500 setlinewidth
+53000 38420 52000 38420 line
+30000 53170 31750 54920 line
+30000 43170 30000 53170 line
+31000 42170 30000 43170 line
+31000 39420 31000 42170 line
+52000 38420 42000 38420 line
+41000 53920 41000 54920 line
+42000 39420 42000 38420 line
+31000 39420 31000 38420 line
+52000 54920 41000 54920 line
+52000 53920 52000 54920 line
+31000 38420 42000 38420 line
+31750 54920 41000 54920 line
+30750 55920 41000 55920 line
+53000 37420 51000 37420 line
+51000 37420 42250 37420 line
+41000 56920 41000 55920 line
+42000 36420 42000 37420 line
+31000 37420 30000 37420 line
+31000 36420 31000 37420 line
+31000 37420 42250 37420 line
+28750 38670 28750 53920 line
+52000 55920 41000 55920 line
+52000 56920 52000 55920 line
+42000 37420 42250 37420 line
+30000 37420 28750 38670 line
+28750 53920 30750 55920 line
+315 setlinewidth
+39000 43670 39000 39420 line
+38000 43670 38000 39420 line
+37000 43670 37000 39420 line
+36000 43670 36000 39420 line
+35000 43670 35000 39420 line
+34000 43670 34000 39420 line
+33000 39420 32000 39420 line
+33000 43670 33000 39420 line
+50000 43670 50000 39420 line
+49000 43670 49000 39420 line
+48000 43670 48000 39420 line
+47000 43670 47000 39420 line
+46000 43670 46000 39420 line
+45000 43670 45000 39420 line
+44000 43670 44000 39420 line
+43000 43670 43000 39420 line
+44000 49670 44000 53920 line
+45000 49670 45000 53920 line
+46000 49670 46000 53920 line
+47000 49670 47000 53920 line
+48000 49670 48000 53920 line
+49000 49670 49000 53920 line
+50000 49670 50000 53920 line
+51000 49670 51000 53920 line
+500 setlinewidth
+66000 35920 66000 38920 line
+62500 34670 64750 34670 line
+66000 35920 64750 34670 line
+68250 41170 69000 41170 line
+66000 38920 68250 41170 line
+57250 35170 55000 37420 line
+62000 35170 62500 34670 line
+55000 38420 55000 37420 line
+62000 35170 57250 35170 line
+70250 53170 70250 55920 line
+70250 55920 70500 56170 line
+315 setlinewidth
+57500 51170 58000 51170 line
+59500 49170 60500 49170 line
+58500 50170 59500 49170 line
+58500 50670 58500 50170 line
+58000 51170 58500 50670 line
+500 setlinewidth
+60500 49170 63000 49170 line
+63000 49170 63000 42170 line
+51000 42170 63000 42170 line
+63000 42170 65250 42170 line
+65250 42170 70000 46920 line
+70000 46920 70000 49420 line
+70000 49420 70000 52670 line
+70000 52670 70250 52920 line
+70250 52920 70250 53170 line
+51000 43670 51000 42170 line
+315 setlinewidth
+55500 39920 56250 39170 line
+60500 39170 61500 40170 line
+56250 39170 57750 39170 line
+57750 39170 60500 39170 line
+57750 37170 57750 39170 line
+62500 38420 63250 37670 line
+62500 40170 62500 38420 line
+65000 36670 65000 39170 line
+64500 36170 65000 36670 line
+63250 36170 64500 36170 line
+68000 42170 69000 42170 line
+65000 39170 68000 42170 line
+54750 48670 55250 49170 line
+55250 52920 55500 53170 line
+55250 49170 55250 52920 line
+55500 53170 57500 53170 line
+43000 48920 43250 48670 line
+43000 49670 43000 48920 line
+43250 48670 54750 48670 line
+60500 45170 59000 45170 line
+56250 45920 56250 46920 line
+56250 46920 55750 47420 line
+55750 47420 54750 47420 line
+58500 45670 59000 45170 line
+157 setlinewidth
+56500 45670 58500 45670 line
+315 setlinewidth
+42250 47420 54750 47420 line
+42000 47670 42250 47420 line
+42000 47920 42000 47670 line
+42000 47920 42000 49670 line
+56500 45670 56250 45920 line
+60500 44170 58750 44170 line
+55500 46670 55500 45420 line
+55500 45420 56250 44670 line
+56250 44670 56500 44670 line
+58250 44670 58750 44170 line
+157 setlinewidth
+56500 44670 58250 44670 line
+315 setlinewidth
+55500 46670 54250 46670 line
+41000 49670 41000 47570 line
+41000 47570 41900 46670 line
+41900 46670 54250 46670 line
+54250 46670 54300 46670 line
+157 setlinewidth
+42500 44170 42500 42920 line
+315 setlinewidth
+42500 42920 42250 42670 line
+42250 42670 40250 42670 line
+40250 42670 40000 42920 line
+40000 42920 40000 43670 line
+51500 44670 52250 43920 line
+55500 43920 52250 43920 line
+43000 44670 50250 44670 line
+42500 44170 43000 44670 line
+50250 44670 51500 44670 line
+52150 46020 52900 46020 line
+41450 46020 52150 46020 line
+41000 45570 41450 46020 line
+41000 43670 41000 45570 line
+52900 46020 53250 45670 line
+54000 44920 54250 44920 line
+52050 45370 52500 44920 line
+52500 44920 54000 44920 line
+51250 45370 52050 45370 line
+54500 45170 54500 45670 line
+54250 44920 54500 45170 line
+42100 45370 51250 45370 line
+51250 45370 51300 45370 line
+42000 43670 42000 45270 line
+42000 45270 42100 45370 line
+64000 36920 64000 38920 line
+59250 37670 59250 36920 line
+59250 36920 59250 36170 line
+59250 36920 64000 36920 line
+62000 44920 62000 44670 line
+60750 46170 62000 44920 line
+60250 46170 60500 46170 line
+60500 46170 60750 46170 line
+61000 47170 62000 46170 line
+60500 47170 61000 47170 line
+60500 48170 61500 48170 line
+61500 48170 62000 47670 line
+54500 49670 54500 53670 line
+55000 54170 57500 54170 line
+54500 53670 55000 54170 line
+60500 56920 61500 57920 line
+60500 56170 60500 56920 line
+319 setlinewidth
+58484 53692 59516 53692 line
+58583 53948 59415 53948 line
+58609 54204 59392 54204 line
+58568 54460 59432 54460 line
+54066 54460 54136 54460 line
+58499 54716 59500 54716 line
+54066 54716 54392 54716 line
+58588 54972 59411 54972 line
+54066 54972 54850 54972 line
+58609 55228 59392 55228 line
+54066 55228 56392 55228 line
+58558 55484 59442 55484 line
+54066 55484 56442 55484 line
+58509 55740 59489 55740 line
+54066 55740 56489 55740 line
+58593 55996 59406 55996 line
+54066 55996 56406 55996 line
+58609 56252 59392 56252 line
+55782 56252 56392 56252 line
+54066 56252 55212 56252 line
+58549 56508 59452 56508 line
+56194 56508 56452 56508 line
+54241 56508 54807 56508 line
+58409 56764 59593 56764 line
+56367 56764 56593 56764 line
+54497 56764 54630 56764 line
+58109 57020 59694 57020 line
+56448 57020 56893 57020 line
+56456 57276 59769 57276 line
+56387 57532 59958 57532 line
+56237 57788 60214 57788 line
+55895 58044 60470 58044 line
+60024 58300 60544 58300 line
+60289 58556 60613 58556 line
+60545 58812 60545 58812 line
+31816 50840 34184 50840 line
+31816 51096 34184 51096 line
+31816 51352 34184 51352 line
+31816 51608 34184 51608 line
+31816 51864 34184 51864 line
+31854 52120 34184 52120 line
+32110 52376 34184 52376 line
+32366 52632 34184 52632 line
+33624 52888 33624 52888 line
+59316 50574 59480 50574 line
+59300 50830 59452 50830 line
+59199 51086 59391 51086 line
+58982 51342 59407 51342 line
+58726 51598 59168 51598 line
+58557 51854 58912 51854 line
+39223 44753 39773 44753 line
+38223 44753 38773 44753 line
+37223 44753 37773 44753 line
+36223 44753 36773 44753 line
+35223 44753 35773 44753 line
+34223 44753 34773 44753 line
+33223 44753 33773 44753 line
+32223 44753 32773 44753 line
+31816 45009 40184 45009 line
+31816 45265 40184 45265 line
+31816 45521 40184 45521 line
+31816 45777 40214 45777 line
+31816 46033 40329 46033 line
+31816 46289 40565 46289 line
+31816 46545 40821 46545 line
+31816 46801 40615 46801 line
+31816 47057 40369 47057 line
+31816 47313 40229 47313 line
+31816 47569 40184 47569 line
+31816 47825 40184 47825 line
+31816 48081 32687 48081 line
+31816 48337 32429 48337 line
+32254 48593 32254 48593 line
+63909 43218 65011 43218 line
+63909 43474 65267 43474 line
+63909 43730 65523 43730 line
+63909 43986 65328 43986 line
+63909 44242 65139 44242 line
+63909 44498 65057 44498 line
+63909 44754 65043 44754 line
+63909 45010 65103 45010 line
+63909 45266 65248 45266 line
+63909 45522 65294 45522 line
+63909 45778 65125 45778 line
+63909 46034 65051 46034 line
+63909 46290 65046 46290 line
+63909 46546 65119 46546 line
+63909 46802 65184 46802 line
+63909 47058 65184 47058 line
+63909 47314 65110 47314 line
+63909 47570 65044 47570 line
+63909 47826 65054 47826 line
+63909 48082 65134 48082 line
+63909 48338 65314 48338 line
+66266 48594 66573 48594 line
+63909 48594 65734 48594 line
+63909 48850 67434 48850 line
+63931 49106 67434 49106 line
+63914 49362 67434 49362 line
+63824 49618 67434 49618 line
+63891 49874 67434 49874 line
+63932 50130 67434 50130 line
+67008 50386 67434 50386 line
+67270 50642 67434 50642 line
+67396 50898 67434 50898 line
+67432 51154 67434 51154 line
+67405 51410 67434 51410 line
+67292 51666 67434 51666 line
+67056 51922 67434 51922 line
+63816 52178 67434 52178 line
+67081 52434 67434 52434 line
+63816 52434 64922 52434 line
+67304 52690 67434 52690 line
+63889 52690 64698 52690 line
+67407 52946 67434 52946 line
+63982 52946 64570 52946 line
+67433 53202 67434 53202 line
+64007 53202 64314 53202 line
+67392 53458 67434 53458 line
+63971 53458 64058 53458 line
+67260 53714 67434 53714 line
+66985 53970 67434 53970 line
+65985 53970 66016 53970 line
+65598 54226 67434 54226 line
+65342 54482 67434 54482 line
+65086 54738 67434 54738 line
+64830 54994 67434 54994 line
+61592 54994 61669 54994 line
+65777 55250 67434 55250 line
+64574 55250 65221 55250 line
+61609 55250 61925 55250 line
+66192 55506 67434 55506 line
+64318 55506 64809 55506 line
+61549 55506 62048 55506 line
+66366 55762 67434 55762 line
+64059 55762 64631 55762 line
+61518 55762 62184 55762 line
+66447 56018 67434 56018 line
+63547 56018 64554 56018 line
+61597 56018 62455 56018 line
+66456 56274 67434 56274 line
+61607 56274 64543 56274 line
+66409 56530 67434 56530 line
+61540 56530 64591 56530 line
+66409 56786 67434 56786 line
+61519 56786 64591 56786 line
+66409 57042 67434 57042 line
+62121 57042 64591 57042 line
+66409 57298 67434 57298 line
+62378 57298 64162 57298 line
+66409 57554 67434 57554 line
+62459 57554 63796 57554 line
+66409 57810 67434 57810 line
+62459 57810 63637 57810 line
+66431 58066 67434 58066 line
+62459 58066 63569 58066 line
+66422 58322 67434 58322 line
+62452 58322 63578 58322 line
+66409 58578 67434 58578 line
+62396 58578 63659 58578 line
+66409 58834 67182 58834 line
+62455 58834 63844 58834 line
+66409 59090 66926 59090 line
+62443 59090 64338 59090 line
+66409 59346 66670 59346 line
+62361 59346 64591 59346 line
+62174 59602 64591 59602 line
+61697 59858 64591 59858 line
+61847 60114 64564 60114 line
+62103 60370 64543 60370 line
+62353 60626 64589 60626 line
+62510 60882 64567 60882 line
+64230 61138 64543 61138 line
+62563 61138 63039 61138 line
+64545 61394 64582 61394 line
+62566 61394 62734 61394 line
+62566 61650 62566 61650 line
+50969 39469 54651 39469 line
+50969 39725 54562 39725 line
+50960 39981 54543 39981 line
+57975 40237 60413 40237 line
+56406 40237 57530 40237 line
+51088 40237 54594 40237 line
+50858 40237 50934 40237 line
+58428 40493 60622 40493 line
+56270 40493 57072 40493 line
+51643 40493 54732 40493 line
+58611 40749 60581 40749 line
+55985 40749 56886 40749 line
+51834 40749 55018 40749 line
+58694 41005 60566 41005 line
+51920 41005 56806 41005 line
+58707 41261 60566 41261 line
+51933 41261 56792 41261 line
+60072 31715 61509 31715 line
+59766 31971 61591 31971 line
+59721 32227 61591 32227 line
+59581 32483 61509 32483 line
+59335 32739 61493 32739 line
+59079 32995 61544 32995 line
+58823 33251 61581 33251 line
+58567 33507 61505 33507 line
+58308 33763 61493 33763 line
+56055 34019 61554 34019 line
+55799 34275 57113 34275 line
+55543 34531 56603 34531 line
+55287 34787 56347 34787 line
+55031 35043 56091 35043 line
+54775 35299 55835 35299 line
+54519 35555 55579 35555 line
+54250 35811 55323 35811 line
+51506 36067 55067 36067 line
+51250 36323 54811 36323 line
+54555 36579 54555 36579 line
+17977 27652 79819 27652 line
+59495 27908 79819 27908 line
+51245 27908 57005 27908 line
+42995 27908 48755 27908 line
+34745 27908 40505 27908 line
+26495 27908 32255 27908 line
+17977 27908 24005 27908 line
+59779 28164 79819 28164 line
+51529 28164 56720 28164 line
+43279 28164 48470 28164 line
+35029 28164 40220 28164 line
+26779 28164 31970 28164 line
+17977 28164 23720 28164 line
+62435 28420 79819 28420 line
+60026 28420 61259 28420 line
+56235 28420 56464 28420 line
+54185 28420 55059 28420 line
+51776 28420 53009 28420 line
+47985 28420 48214 28420 line
+45935 28420 46809 28420 line
+43526 28420 44759 28420 line
+39735 28420 39964 28420 line
+37685 28420 38559 28420 line
+35276 28420 36509 28420 line
+31485 28420 31714 28420 line
+29435 28420 30309 28420 line
+27026 28420 28259 28420 line
+23235 28420 23464 28420 line
+17977 28420 22059 28420 line
+72580 28676 79819 28676 line
+66580 28676 71415 28676 line
+62742 28676 65415 28676 line
+60189 28676 60958 28676 line
+54492 28676 54758 28676 line
+51939 28676 52708 28676 line
+46242 28676 46508 28676 line
+43689 28676 44458 28676 line
+37992 28676 38258 28676 line
+35439 28676 36208 28676 line
+29742 28676 30008 28676 line
+27189 28676 27958 28676 line
+17977 28676 21758 28676 line
+73023 28932 79819 28932 line
+67023 28932 70973 28932 line
+62900 28932 64973 28932 line
+60250 28932 60797 28932 line
+52000 28932 52547 28932 line
+43750 28932 44297 28932 line
+35500 28932 36047 28932 line
+27250 28932 27797 28932 line
+17977 28932 21597 28932 line
+73269 29188 79819 29188 line
+67269 29188 70726 29188 line
+62984 29188 64726 29188 line
+60259 29188 60715 29188 line
+52009 29188 52465 29188 line
+43759 29188 44215 29188 line
+35509 29188 35965 29188 line
+27259 29188 27715 29188 line
+17977 29188 21515 29188 line
+79104 29444 79819 29444 line
+73430 29444 77749 29444 line
+67430 29444 70563 29444 line
+63006 29444 64563 29444 line
+60413 29444 60693 29444 line
+52163 29444 52443 29444 line
+43913 29444 44193 29444 line
+35663 29444 35943 29444 line
+27413 29444 27693 29444 line
+20049 29444 21493 29444 line
+17977 29444 18694 29444 line
+79447 29700 79819 29700 line
+74832 29700 77402 29700 line
+68832 29700 70462 29700 line
+62976 29700 64462 29700 line
+60583 29700 60726 29700 line
+52333 29700 52476 29700 line
+44083 29700 44226 29700 line
+35833 29700 35976 29700 line
+27583 29700 27726 29700 line
+20392 29700 21526 29700 line
+17977 29700 18347 29700 line
+79656 29956 79819 29956 line
+75154 29956 77194 29956 line
+69154 29956 70409 29956 line
+62882 29956 64409 29956 line
+20601 29956 21620 29956 line
+17977 29956 18139 29956 line
+79786 30212 79819 30212 line
+75356 30212 77065 30212 line
+69356 30212 70398 30212 line
+62696 30212 64398 30212 line
+20731 30212 21804 30212 line
+17977 30212 18010 30212 line
+75486 30468 76991 30468 line
+69486 30468 70425 30468 line
+62832 30468 64425 30468 line
+20803 30468 22153 30468 line
+75565 30724 76966 30724 line
+69565 30724 70494 30724 line
+63088 30724 64494 30724 line
+20826 30724 22591 30724 line
+75599 30980 76985 30980 line
+69599 30980 70612 30980 line
+63289 30980 64612 30980 line
+20810 30980 22591 30980 line
+79799 31236 79819 31236 line
+75602 31236 77051 31236 line
+69602 31236 70522 31236 line
+63389 31236 64522 31236 line
+20744 31236 22591 31236 line
+17977 31236 17995 31236 line
+79678 31492 79819 31492 line
+75551 31492 77171 31492 line
+69551 31492 70409 31492 line
+63409 31492 64409 31492 line
+20623 31492 22591 31492 line
+17977 31492 18116 31492 line
+79482 31748 79819 31748 line
+75455 31748 77368 31748 line
+69455 31748 70396 31748 line
+63409 31748 64396 31748 line
+20427 31748 22591 31748 line
+17977 31748 18313 31748 line
+79163 32004 79819 32004 line
+75304 32004 77691 32004 line
+69304 32004 70396 32004 line
+63409 32004 64396 32004 line
+20108 32004 22591 32004 line
+17977 32004 18636 32004 line
+75078 32260 79819 32260 line
+69078 32260 70396 32260 line
+63421 32260 64396 32260 line
+17977 32260 22591 32260 line
+74698 32516 79819 32516 line
+68698 32516 70396 32516 line
+63498 32516 64396 32516 line
+17977 32516 22591 32516 line
+73604 32772 79819 32772 line
+67637 32772 70396 32772 line
+63508 32772 64396 32772 line
+17977 32772 22591 32772 line
+73604 33028 79819 33028 line
+67893 33028 70396 33028 line
+63444 33028 64396 33028 line
+20289 33028 22591 33028 line
+17977 33028 18529 33028 line
+73604 33284 79819 33284 line
+63431 33284 64396 33284 line
+20289 33284 22602 33284 line
+17977 33284 18529 33284 line
+73604 33540 79819 33540 line
+63504 33540 64396 33540 line
+20289 33540 22672 33540 line
+17977 33540 18529 33540 line
+73543 33796 79819 33796 line
+20289 33796 22843 33796 line
+17977 33796 18529 33796 line
+73328 34052 79819 34052 line
+20289 34052 23096 34052 line
+17977 34052 18529 34052 line
+72909 34308 79819 34308 line
+20289 34308 23352 34308 line
+17977 34308 18529 34308 line
+72909 34564 79819 34564 line
+20289 34564 23608 34564 line
+17977 34564 18529 34564 line
+73392 34820 79819 34820 line
+20289 34820 23864 34820 line
+17977 34820 18529 34820 line
+73724 35076 79819 35076 line
+20289 35076 24120 35076 line
+17977 35076 18529 35076 line
+73872 35332 79819 35332 line
+20289 35332 24376 35332 line
+17977 35332 18529 35332 line
+73931 35588 79819 35588 line
+20289 35588 24632 35588 line
+17977 35588 18529 35588 line
+73918 35844 79819 35844 line
+20289 35844 24888 35844 line
+17977 35844 18529 35844 line
+73833 36100 79819 36100 line
+20289 36100 25144 36100 line
+17977 36100 18529 36100 line
+73635 36356 79819 36356 line
+20289 36356 25400 36356 line
+17977 36356 18529 36356 line
+72292 36612 79819 36612 line
+20289 36612 25656 36612 line
+17977 36612 18529 36612 line
+69663 36868 79819 36868 line
+20289 36868 25912 36868 line
+17977 36868 18529 36868 line
+69570 37124 79819 37124 line
+20289 37124 26168 37124 line
+17977 37124 18529 37124 line
+69361 37380 79819 37380 line
+20289 37380 26424 37380 line
+17977 37380 18529 37380 line
+68159 37636 79819 37636 line
+20289 37636 26591 37636 line
+17977 37636 18529 37636 line
+68256 37892 79819 37892 line
+20289 37892 26591 37892 line
+17977 37892 18529 37892 line
+68975 38148 79819 38148 line
+20289 38148 26591 38148 line
+17977 38148 18529 38148 line
+69270 38404 79819 38404 line
+20289 38404 26591 38404 line
+17977 38404 18529 38404 line
+69526 38660 79819 38660 line
+20289 38660 26591 38660 line
+17977 38660 18529 38660 line
+77678 38916 79819 38916 line
+69757 38916 73322 38916 line
+20289 38916 26591 38916 line
+17977 38916 18529 38916 line
+77860 39172 79819 39172 line
+69869 39172 73139 39172 line
+20289 39172 26591 39172 line
+17977 39172 18529 39172 line
+77909 39428 79819 39428 line
+69909 39428 73091 39428 line
+20289 39428 26591 39428 line
+17977 39428 18529 39428 line
+77909 39684 79819 39684 line
+69995 39684 73091 39684 line
+63316 39684 63419 39684 line
+20289 39684 26591 39684 line
+17977 39684 18529 39684 line
+77909 39940 79819 39940 line
+70009 39940 73091 39940 line
+63405 39940 64616 39940 line
+20289 39940 26591 39940 line
+17977 39940 18529 39940 line
+77909 40196 79819 40196 line
+70009 40196 73091 40196 line
+63433 40196 64872 40196 line
+20289 40196 26591 40196 line
+17977 40196 18529 40196 line
+77909 40452 79819 40452 line
+70009 40452 73091 40452 line
+63394 40452 65128 40452 line
+20289 40452 26591 40452 line
+17977 40452 18529 40452 line
+77909 40708 79819 40708 line
+69985 40708 73091 40708 line
+63264 40708 65384 40708 line
+20289 40708 26591 40708 line
+17977 40708 18529 40708 line
+77909 40964 79819 40964 line
+69986 40964 73091 40964 line
+62994 40964 65640 40964 line
+20289 40964 26591 40964 line
+17977 40964 18529 40964 line
+77909 41220 79819 41220 line
+70007 41220 73091 41220 line
+62434 41220 65896 41220 line
+20289 41220 26591 41220 line
+17977 41220 18529 41220 line
+77909 41476 79819 41476 line
+69965 41476 73091 41476 line
+65829 41476 66152 41476 line
+20289 41476 26591 41476 line
+17977 41476 18529 41476 line
+77909 41732 79819 41732 line
+69908 41732 73091 41732 line
+66096 41732 66408 41732 line
+20289 41732 26591 41732 line
+17977 41732 18529 41732 line
+77909 41988 79819 41988 line
+69992 41988 73091 41988 line
+66352 41988 66664 41988 line
+20289 41988 26591 41988 line
+17977 41988 18529 41988 line
+77909 42244 79819 42244 line
+70007 42244 73091 42244 line
+66608 42244 66920 42244 line
+20289 42244 26591 42244 line
+17977 42244 18529 42244 line
+77909 42500 79819 42500 line
+69955 42500 73091 42500 line
+66864 42500 67176 42500 line
+20289 42500 26591 42500 line
+17977 42500 18529 42500 line
+77909 42756 79819 42756 line
+69821 42756 73091 42756 line
+67120 42756 67433 42756 line
+20289 42756 26591 42756 line
+17977 42756 18529 42756 line
+77904 43012 79819 43012 line
+69555 43012 73096 43012 line
+67376 43012 68446 43012 line
+20289 43012 26591 43012 line
+17977 43012 18529 43012 line
+77811 43268 79819 43268 line
+67632 43268 73190 43268 line
+20289 43268 26591 43268 line
+17977 43268 18529 43268 line
+77515 43524 79819 43524 line
+67888 43524 73486 43524 line
+20289 43524 26591 43524 line
+17977 43524 18529 43524 line
+68144 43780 79819 43780 line
+20289 43780 26591 43780 line
+17977 43780 18529 43780 line
+68400 44036 79819 44036 line
+20289 44036 26591 44036 line
+17977 44036 18529 44036 line
+68656 44292 79819 44292 line
+20289 44292 26591 44292 line
+17977 44292 18529 44292 line
+68912 44548 79819 44548 line
+20289 44548 26591 44548 line
+17977 44548 18529 44548 line
+69168 44804 79819 44804 line
+20289 44804 26591 44804 line
+17977 44804 18529 44804 line
+69424 45060 79819 45060 line
+20289 45060 26591 45060 line
+17977 45060 18529 45060 line
+71785 45316 79819 45316 line
+69680 45316 70712 45316 line
+20289 45316 26591 45316 line
+17977 45316 18529 45316 line
+72062 45572 79819 45572 line
+69936 45572 70436 45572 line
+20289 45572 26591 45572 line
+17977 45572 18529 45572 line
+72201 45828 79819 45828 line
+70192 45828 70300 45828 line
+20289 45828 26591 45828 line
+17977 45828 18529 45828 line
+72255 46084 79819 46084 line
+20289 46084 26591 46084 line
+17977 46084 18529 46084 line
+72245 46340 79819 46340 line
+20289 46340 26591 46340 line
+17977 46340 18529 46340 line
+72165 46596 79819 46596 line
+20289 46596 26591 46596 line
+17977 46596 18529 46596 line
+71994 46852 79819 46852 line
+20289 46852 26591 46852 line
+17977 46852 18529 46852 line
+72087 47108 79819 47108 line
+20289 47108 26591 47108 line
+17977 47108 18529 47108 line
+72214 47364 79819 47364 line
+20289 47364 26591 47364 line
+17977 47364 18529 47364 line
+72256 47620 79819 47620 line
+20289 47620 26591 47620 line
+17977 47620 18529 47620 line
+72238 47876 79819 47876 line
+20289 47876 26591 47876 line
+17977 47876 18529 47876 line
+72150 48132 79819 48132 line
+20289 48132 26591 48132 line
+17977 48132 18529 48132 line
+71958 48388 79819 48388 line
+20289 48388 26591 48388 line
+17977 48388 18529 48388 line
+71520 48644 79819 48644 line
+70909 48644 70975 48644 line
+20289 48644 26591 48644 line
+17977 48644 18529 48644 line
+70909 48900 79819 48900 line
+20289 48900 26591 48900 line
+17977 48900 18529 48900 line
+70909 49156 79819 49156 line
+20289 49156 26591 49156 line
+17977 49156 18529 49156 line
+70909 49412 79819 49412 line
+20289 49412 26591 49412 line
+17977 49412 18529 49412 line
+70909 49668 79819 49668 line
+20289 49668 26591 49668 line
+17977 49668 18529 49668 line
+70909 49924 79819 49924 line
+20289 49924 26591 49924 line
+17977 49924 18529 49924 line
+70909 50180 79819 50180 line
+20289 50180 26591 50180 line
+17977 50180 18529 50180 line
+70909 50436 79819 50436 line
+20289 50436 26591 50436 line
+17977 50436 18529 50436 line
+70909 50692 79819 50692 line
+20289 50692 26591 50692 line
+17977 50692 18529 50692 line
+70909 50948 79819 50948 line
+20289 50948 26591 50948 line
+17977 50948 18529 50948 line
+70909 51204 79819 51204 line
+20289 51204 26591 51204 line
+17977 51204 18529 51204 line
+70909 51460 79819 51460 line
+20289 51460 26591 51460 line
+17977 51460 18529 51460 line
+70909 51716 79819 51716 line
+20289 51716 26591 51716 line
+17977 51716 18529 51716 line
+70909 51972 79819 51972 line
+20289 51972 26591 51972 line
+17977 51972 18529 51972 line
+70909 52228 79819 52228 line
+20289 52228 26591 52228 line
+17977 52228 18529 52228 line
+71883 52484 79819 52484 line
+20289 52484 26591 52484 line
+17977 52484 18529 52484 line
+72080 52740 79819 52740 line
+20289 52740 26591 52740 line
+17977 52740 18529 52740 line
+72168 52996 79819 52996 line
+20289 52996 26591 52996 line
+17977 52996 18529 52996 line
+72183 53252 79819 53252 line
+20289 53252 26591 53252 line
+17977 53252 18529 53252 line
+72121 53508 79819 53508 line
+20289 53508 26591 53508 line
+17977 53508 18529 53508 line
+71977 53764 79819 53764 line
+20289 53764 26591 53764 line
+17977 53764 18529 53764 line
+71639 54020 79819 54020 line
+20289 54020 26591 54020 line
+17977 54020 18529 54020 line
+71159 54276 79819 54276 line
+20289 54276 26591 54276 line
+17977 54276 18529 54276 line
+71159 54532 79819 54532 line
+20289 54532 26591 54532 line
+17977 54532 18529 54532 line
+71159 54788 79819 54788 line
+20289 54788 26591 54788 line
+17977 54788 18529 54788 line
+71159 55044 79819 55044 line
+20289 55044 26591 55044 line
+17977 55044 18529 55044 line
+71159 55300 79819 55300 line
+20289 55300 26591 55300 line
+17977 55300 18529 55300 line
+71239 55556 79819 55556 line
+20289 55556 26591 55556 line
+17977 55556 18529 55556 line
+71389 55812 79819 55812 line
+20289 55812 26591 55812 line
+17977 55812 18529 55812 line
+71455 56068 79819 56068 line
+20289 56068 26591 56068 line
+17977 56068 18529 56068 line
+71446 56324 79819 56324 line
+20289 56324 26591 56324 line
+17977 56324 18529 56324 line
+71368 56580 79819 56580 line
+20289 56580 26554 56580 line
+17977 56580 18529 56580 line
+71189 56836 79819 56836 line
+20289 56836 26298 56836 line
+17977 56836 18529 56836 line
+70776 57092 79819 57092 line
+69816 57092 70226 57092 line
+20289 57092 26042 57092 line
+17977 57092 18529 57092 line
+69816 57348 79819 57348 line
+20289 57348 25786 57348 line
+17977 57348 18529 57348 line
+69816 57604 79819 57604 line
+20289 57604 25530 57604 line
+17977 57604 18529 57604 line
+69816 57860 79819 57860 line
+20289 57860 25274 57860 line
+17977 57860 18529 57860 line
+69816 58116 79819 58116 line
+20289 58116 25018 58116 line
+17977 58116 18529 58116 line
+69816 58372 79819 58372 line
+20289 58372 24762 58372 line
+17977 58372 18529 58372 line
+69816 58628 79819 58628 line
+20289 58628 24506 58628 line
+17977 58628 18529 58628 line
+69816 58884 79819 58884 line
+20289 58884 24250 58884 line
+17977 58884 18529 58884 line
+69816 59140 79819 59140 line
+20289 59140 24015 59140 line
+17977 59140 18529 59140 line
+69816 59396 79819 59396 line
+20289 59396 23887 59396 line
+17977 59396 18529 59396 line
+69778 59652 79819 59652 line
+20289 59652 23842 59652 line
+17977 59652 18529 59652 line
+69651 59908 79819 59908 line
+20289 59908 23841 59908 line
+17977 59908 18529 59908 line
+69410 60164 79819 60164 line
+20289 60164 23841 60164 line
+17977 60164 18529 60164 line
+69154 60420 79819 60420 line
+20289 60420 23841 60420 line
+17977 60420 18529 60420 line
+68898 60676 79819 60676 line
+20289 60676 23841 60676 line
+17977 60676 18529 60676 line
+68642 60932 79819 60932 line
+20289 60932 23841 60932 line
+17977 60932 18529 60932 line
+78644 61188 79819 61188 line
+69033 61188 78192 61188 line
+20289 61188 23841 61188 line
+17977 61188 18529 61188 line
+79277 61444 79819 61444 line
+69305 61444 77576 61444 line
+20222 61444 23841 61444 line
+17977 61444 18521 61444 line
+79554 61700 79819 61700 line
+69454 61700 77295 61700 line
+64729 61700 64745 61700 line
+20499 61700 23841 61700 line
+17977 61700 18240 61700 line
+79721 61956 79819 61956 line
+69532 61956 77124 61956 line
+66954 61956 67191 61956 line
+65954 61956 66048 61956 line
+64808 61956 65048 61956 line
+20666 61956 23841 61956 line
+17977 61956 18069 61956 line
+69549 62212 77021 62212 line
+64825 62212 67174 62212 line
+20770 62212 23841 62212 line
+69516 62468 76971 62468 line
+64792 62468 67210 62468 line
+20824 62468 23785 62468 line
+69420 62724 76968 62724 line
+64696 62724 67306 62724 line
+20828 62724 23785 62724 line
+69234 62980 77008 62980 line
+64510 62980 67490 62980 line
+23330 62980 23798 62980 line
+20788 62980 21973 62980 line
+79754 63236 79819 63236 line
+68895 63236 77097 63236 line
+64171 63236 67826 63236 line
+23584 63236 23841 63236 line
+20699 63236 21712 63236 line
+17977 63236 18042 63236 line
+79605 63492 79819 63492 line
+72839 63492 77247 63492 line
+71839 63492 72156 63492 line
+64225 63492 71156 63492 line
+23726 63492 23868 63492 line
+20550 63492 21574 63492 line
+17977 63492 18192 63492 line
+79373 63748 79819 63748 line
+73227 63748 77480 63748 line
+56797 63748 56974 63748 line
+48547 63748 48724 63748 line
+40297 63748 40474 63748 line
+32047 63748 32224 63748 line
+23797 63748 23974 63748 line
+20318 63748 21504 63748 line
+17977 63748 18425 63748 line
+78924 64004 79819 64004 line
+73396 64004 77930 64004 line
+56807 64004 57188 64004 line
+48557 64004 48938 64004 line
+40307 64004 40688 64004 line
+32057 64004 32438 64004 line
+23807 64004 24188 64004 line
+19869 64004 21494 64004 line
+17977 64004 18875 64004 line
+73476 64260 79819 64260 line
+60614 64260 60739 64260 line
+56763 64260 57288 64260 line
+48513 64260 48991 64260 line
+40263 64260 40741 64260 line
+32013 64260 32491 64260 line
+23763 64260 24241 64260 line
+17977 64260 21539 64260 line
+73487 64516 79819 64516 line
+62845 64516 62941 64516 line
+60423 64516 60855 64516 line
+56645 64516 57479 64516 line
+54595 64516 54655 64516 line
+48395 64516 49014 64516 line
+46345 64516 46405 64516 line
+40145 64516 40764 64516 line
+38095 64516 38155 64516 line
+31895 64516 32514 64516 line
+29845 64516 29905 64516 line
+23645 64516 24264 64516 line
+17977 64516 21655 64516 line
+73424 64772 79819 64772 line
+62636 64772 63197 64772 line
+59929 64772 61065 64772 line
+59129 64772 59569 64772 line
+58329 64772 58769 64772 line
+56436 64772 57969 64772 line
+54386 64772 54865 64772 line
+48186 64772 49116 64772 line
+46136 64772 46615 64772 line
+39936 64772 40866 64772 line
+37886 64772 38365 64772 line
+31686 64772 32616 64772 line
+29636 64772 30115 64772 line
+23436 64772 24366 64772 line
+17977 64772 21865 64772 line
+73283 65028 79819 65028 line
+62204 65028 63460 65028 line
+56004 65028 61502 65028 line
+53954 65028 55302 65028 line
+52928 65028 53252 65028 line
+47754 65028 49322 65028 line
+45704 65028 47052 65028 line
+44923 65028 45001 65028 line
+39504 65028 41072 65028 line
+37454 65028 38802 65028 line
+36428 65028 36752 65028 line
+31254 65028 32822 65028 line
+29204 65028 30552 65028 line
+28178 65028 28502 65028 line
+23004 65028 24572 65028 line
+17977 65028 22302 65028 line
+72986 65284 79819 65284 line
+71986 65284 72015 65284 line
+52672 65284 71016 65284 line
+44672 65284 49578 65284 line
+36172 65284 41328 65284 line
+27922 65284 33078 65284 line
+17977 65284 24828 65284 line
+52251 65540 79819 65540 line
+44251 65540 50001 65540 line
+35751 65540 41751 65540 line
+27500 65540 33501 65540 line
+17977 65540 25251 65540 line
+17977 65796 79819 65796 line
+newpath 79819 27576 moveto
+79819 30292 lineto
+79816 30278 lineto
+79700 30017 lineto
+79535 29783 lineto
+79328 29586 lineto
+79086 29432 lineto
+78819 29329 lineto
+78537 29279 lineto
+78251 29285 lineto
+77972 29347 lineto
+77710 29461 lineto
+77475 29625 lineto
+77276 29830 lineto
+77121 30071 lineto
+77016 30337 lineto
+76964 30618 lineto
+76968 30904 lineto
+77028 31184 lineto
+77140 31447 lineto
+77302 31683 lineto
+77506 31884 lineto
+77746 32040 lineto
+78011 32147 lineto
+78292 32201 lineto
+78578 32199 lineto
+78859 32141 lineto
+79122 32031 lineto
+79360 31871 lineto
+79561 31668 lineto
+79719 31429 lineto
+79819 31187 lineto
+79819 62182 lineto
+79816 62168 lineto
+79700 61907 lineto
+79535 61673 lineto
+79328 61476 lineto
+79086 61322 lineto
+78819 61219 lineto
+78537 61169 lineto
+78251 61175 lineto
+77972 61237 lineto
+77710 61351 lineto
+77475 61515 lineto
+77276 61720 lineto
+77121 61961 lineto
+77016 62227 lineto
+76964 62508 lineto
+76968 62794 lineto
+77028 63074 lineto
+77140 63337 lineto
+77302 63573 lineto
+77506 63774 lineto
+77746 63930 lineto
+78011 64037 lineto
+78292 64091 lineto
+78578 64089 lineto
+78859 64031 lineto
+79122 63921 lineto
+79360 63761 lineto
+79561 63558 lineto
+79719 63319 lineto
+79819 63077 lineto
+79819 65796 lineto
+17977 65796 lineto
+17977 63084 lineto
+18085 63337 lineto
+18247 63573 lineto
+18451 63774 lineto
+18691 63930 lineto
+18956 64037 lineto
+19237 64091 lineto
+19523 64089 lineto
+19804 64031 lineto
+20067 63921 lineto
+20305 63761 lineto
+20506 63558 lineto
+20664 63319 lineto
+20773 63055 lineto
+20829 62774 lineto
+20824 62447 lineto
+20761 62168 lineto
+20645 61907 lineto
+20480 61673 lineto
+20273 61476 lineto
+20046 61332 lineto
+20289 61332 lineto
+20289 32906 lineto
+18529 32906 lineto
+18529 61332 lineto
+18698 61332 lineto
+18655 61351 lineto
+18420 61515 lineto
+18221 61720 lineto
+18066 61961 lineto
+17977 62187 lineto
+17977 46686 lineto
+17977 31194 lineto
+18085 31447 lineto
+18247 31683 lineto
+18451 31884 lineto
+18691 32040 lineto
+18956 32147 lineto
+19237 32201 lineto
+19523 32199 lineto
+19804 32141 lineto
+20067 32031 lineto
+20305 31871 lineto
+20506 31668 lineto
+20664 31429 lineto
+20773 31165 lineto
+20829 30884 lineto
+20824 30557 lineto
+20761 30278 lineto
+20645 30017 lineto
+20480 29783 lineto
+20273 29586 lineto
+20031 29432 lineto
+19764 29329 lineto
+19482 29279 lineto
+19196 29285 lineto
+18917 29347 lineto
+18655 29461 lineto
+18420 29625 lineto
+18221 29830 lineto
+18066 30071 lineto
+17977 30297 lineto
+17977 27576 lineto
+58991 27576 lineto
+58991 27761 lineto
+57497 27761 lineto
+57487 27761 lineto
+57401 27771 lineto
+57320 27779 lineto
+57315 27781 lineto
+57311 27781 lineto
+57171 27826 lineto
+57151 27832 lineto
+57150 27833 lineto
+57142 27835 lineto
+57066 27877 lineto
+56994 27914 lineto
+56988 27919 lineto
+56986 27920 lineto
+56955 27946 lineto
+56857 28027 lineto
+56374 28510 lineto
+56367 28503 lineto
+56175 28382 lineto
+55963 28299 lineto
+55740 28260 lineto
+55513 28265 lineto
+55291 28313 lineto
+55083 28404 lineto
+54896 28534 lineto
+54738 28697 lineto
+54624 28874 lineto
+54612 28846 lineto
+54481 28660 lineto
+54317 28503 lineto
+54125 28382 lineto
+53913 28299 lineto
+53690 28260 lineto
+53463 28265 lineto
+53241 28313 lineto
+53033 28404 lineto
+52846 28534 lineto
+52688 28697 lineto
+52565 28888 lineto
+52482 29099 lineto
+52441 29322 lineto
+52444 29549 lineto
+52486 29751 lineto
+52350 29751 lineto
+52347 29743 lineto
+52338 29710 lineto
+52336 29708 lineto
+52335 29702 lineto
+52281 29605 lineto
+52255 29554 lineto
+52253 29552 lineto
+52250 29546 lineto
+52181 29465 lineto
+52142 29417 lineto
+52043 29319 lineto
+52023 29223 lineto
+52009 29191 lineto
+52009 29016 lineto
+52009 29007 lineto
+51989 28831 lineto
+51947 28703 lineto
+51938 28670 lineto
+51936 28668 lineto
+51935 28662 lineto
+51881 28565 lineto
+51855 28514 lineto
+51853 28512 lineto
+51850 28506 lineto
+51781 28425 lineto
+51742 28377 lineto
+51391 28026 lineto
+51391 28025 lineto
+51390 28025 lineto
+51384 28018 lineto
+51318 27967 lineto
+51253 27913 lineto
+51247 27911 lineto
+51245 27908 lineto
+51165 27867 lineto
+51096 27830 lineto
+51092 27830 lineto
+51087 27826 lineto
+50996 27800 lineto
+50927 27778 lineto
+50922 27778 lineto
+50917 27776 lineto
+50820 27768 lineto
+50750 27761 lineto
+50741 27761 lineto
+49247 27761 lineto
+49237 27761 lineto
+49151 27771 lineto
+49070 27779 lineto
+49065 27781 lineto
+49061 27781 lineto
+48921 27826 lineto
+48901 27832 lineto
+48900 27833 lineto
+48892 27835 lineto
+48816 27877 lineto
+48744 27914 lineto
+48738 27919 lineto
+48736 27920 lineto
+48705 27946 lineto
+48607 28027 lineto
+48124 28510 lineto
+48117 28503 lineto
+47925 28382 lineto
+47713 28299 lineto
+47490 28260 lineto
+47263 28265 lineto
+47041 28313 lineto
+46833 28404 lineto
+46646 28534 lineto
+46488 28697 lineto
+46374 28874 lineto
+46362 28846 lineto
+46231 28660 lineto
+46067 28503 lineto
+45875 28382 lineto
+45663 28299 lineto
+45440 28260 lineto
+45213 28265 lineto
+44991 28313 lineto
+44783 28404 lineto
+44596 28534 lineto
+44438 28697 lineto
+44315 28888 lineto
+44232 29099 lineto
+44191 29322 lineto
+44194 29549 lineto
+44236 29751 lineto
+44100 29751 lineto
+44097 29743 lineto
+44088 29710 lineto
+44086 29708 lineto
+44085 29702 lineto
+44031 29605 lineto
+44005 29554 lineto
+44003 29552 lineto
+44000 29546 lineto
+43931 29465 lineto
+43892 29417 lineto
+43793 29319 lineto
+43773 29223 lineto
+43759 29191 lineto
+43759 29016 lineto
+43759 29007 lineto
+43739 28831 lineto
+43697 28703 lineto
+43688 28670 lineto
+43686 28668 lineto
+43685 28662 lineto
+43631 28564 lineto
+43605 28514 lineto
+43603 28512 lineto
+43600 28506 lineto
+43531 28425 lineto
+43492 28377 lineto
+43141 28026 lineto
+43141 28025 lineto
+43140 28025 lineto
+43134 28018 lineto
+43068 27967 lineto
+43003 27913 lineto
+42997 27911 lineto
+42995 27908 lineto
+42915 27867 lineto
+42846 27830 lineto
+42842 27830 lineto
+42837 27826 lineto
+42746 27800 lineto
+42677 27778 lineto
+42672 27778 lineto
+42667 27776 lineto
+42570 27768 lineto
+42500 27761 lineto
+42491 27761 lineto
+40997 27761 lineto
+40987 27761 lineto
+40901 27771 lineto
+40820 27779 lineto
+40815 27781 lineto
+40811 27781 lineto
+40672 27826 lineto
+40651 27832 lineto
+40650 27833 lineto
+40642 27835 lineto
+40566 27877 lineto
+40494 27914 lineto
+40488 27919 lineto
+40486 27920 lineto
+40455 27946 lineto
+40357 28027 lineto
+39874 28510 lineto
+39867 28503 lineto
+39675 28382 lineto
+39463 28299 lineto
+39240 28260 lineto
+39013 28265 lineto
+38791 28313 lineto
+38583 28404 lineto
+38396 28534 lineto
+38238 28697 lineto
+38124 28874 lineto
+38112 28846 lineto
+37981 28660 lineto
+37817 28503 lineto
+37625 28382 lineto
+37413 28299 lineto
+37190 28260 lineto
+36963 28265 lineto
+36741 28313 lineto
+36533 28404 lineto
+36346 28534 lineto
+36188 28697 lineto
+36065 28888 lineto
+35982 29099 lineto
+35941 29322 lineto
+35944 29549 lineto
+35986 29751 lineto
+35850 29751 lineto
+35847 29743 lineto
+35838 29710 lineto
+35836 29708 lineto
+35835 29702 lineto
+35781 29604 lineto
+35755 29554 lineto
+35753 29552 lineto
+35750 29546 lineto
+35681 29465 lineto
+35642 29417 lineto
+35543 29319 lineto
+35523 29223 lineto
+35509 29191 lineto
+35509 29016 lineto
+35509 29007 lineto
+35489 28831 lineto
+35447 28703 lineto
+35438 28670 lineto
+35436 28668 lineto
+35435 28662 lineto
+35381 28564 lineto
+35355 28514 lineto
+35353 28512 lineto
+35350 28506 lineto
+35281 28425 lineto
+35242 28377 lineto
+34891 28026 lineto
+34891 28025 lineto
+34890 28025 lineto
+34884 28018 lineto
+34818 27967 lineto
+34753 27913 lineto
+34747 27911 lineto
+34745 27908 lineto
+34665 27867 lineto
+34596 27830 lineto
+34592 27830 lineto
+34587 27826 lineto
+34496 27800 lineto
+34427 27778 lineto
+34422 27778 lineto
+34417 27776 lineto
+34320 27768 lineto
+34250 27761 lineto
+34241 27761 lineto
+32747 27761 lineto
+32737 27761 lineto
+32651 27771 lineto
+32570 27779 lineto
+32565 27781 lineto
+32561 27781 lineto
+32422 27826 lineto
+32401 27832 lineto
+32400 27833 lineto
+32392 27835 lineto
+32316 27877 lineto
+32244 27914 lineto
+32238 27919 lineto
+32236 27920 lineto
+32205 27946 lineto
+32107 28027 lineto
+31624 28510 lineto
+31617 28503 lineto
+31425 28382 lineto
+31213 28299 lineto
+30990 28260 lineto
+30763 28265 lineto
+30541 28313 lineto
+30333 28404 lineto
+30146 28534 lineto
+29988 28697 lineto
+29874 28874 lineto
+29862 28846 lineto
+29731 28660 lineto
+29567 28503 lineto
+29375 28382 lineto
+29163 28299 lineto
+28940 28260 lineto
+28713 28265 lineto
+28491 28313 lineto
+28283 28404 lineto
+28096 28534 lineto
+27938 28697 lineto
+27815 28888 lineto
+27732 29099 lineto
+27691 29322 lineto
+27694 29549 lineto
+27736 29751 lineto
+27600 29751 lineto
+27597 29743 lineto
+27588 29710 lineto
+27586 29708 lineto
+27585 29702 lineto
+27531 29605 lineto
+27505 29554 lineto
+27503 29552 lineto
+27500 29546 lineto
+27431 29465 lineto
+27392 29417 lineto
+27293 29319 lineto
+27273 29223 lineto
+27259 29191 lineto
+27259 29016 lineto
+27259 29007 lineto
+27239 28831 lineto
+27197 28703 lineto
+27188 28670 lineto
+27186 28668 lineto
+27185 28662 lineto
+27131 28565 lineto
+27105 28514 lineto
+27103 28512 lineto
+27100 28506 lineto
+27031 28425 lineto
+26992 28377 lineto
+26641 28026 lineto
+26641 28025 lineto
+26640 28025 lineto
+26634 28018 lineto
+26568 27967 lineto
+26503 27913 lineto
+26497 27911 lineto
+26495 27908 lineto
+26415 27867 lineto
+26346 27830 lineto
+26342 27830 lineto
+26337 27826 lineto
+26246 27800 lineto
+26177 27778 lineto
+26172 27778 lineto
+26167 27776 lineto
+26070 27768 lineto
+26000 27761 lineto
+25991 27761 lineto
+24497 27761 lineto
+24487 27761 lineto
+24401 27771 lineto
+24320 27779 lineto
+24315 27781 lineto
+24311 27781 lineto
+24172 27826 lineto
+24151 27832 lineto
+24150 27833 lineto
+24142 27835 lineto
+24066 27877 lineto
+23994 27914 lineto
+23988 27919 lineto
+23986 27920 lineto
+23955 27946 lineto
+23857 28027 lineto
+23374 28510 lineto
+23367 28503 lineto
+23175 28382 lineto
+22963 28299 lineto
+22740 28260 lineto
+22513 28265 lineto
+22291 28313 lineto
+22083 28404 lineto
+21896 28534 lineto
+21738 28697 lineto
+21615 28888 lineto
+21532 29099 lineto
+21491 29322 lineto
+21494 29549 lineto
+21541 29771 lineto
+21630 29980 lineto
+21758 30168 lineto
+21921 30327 lineto
+22111 30451 lineto
+22321 30536 lineto
+22544 30579 lineto
+22591 30579 lineto
+22591 33173 lineto
+22591 33183 lineto
+22600 33269 lineto
+22609 33350 lineto
+22610 33356 lineto
+22611 33359 lineto
+22631 33424 lineto
+22661 33519 lineto
+22663 33525 lineto
+22665 33528 lineto
+22690 33575 lineto
+22740 33669 lineto
+22740 62760 lineto
+22513 62765 lineto
+22291 62813 lineto
+22083 62904 lineto
+21896 63034 lineto
+21738 63197 lineto
+21615 63388 lineto
+21532 63599 lineto
+21491 63822 lineto
+21494 64049 lineto
+21541 64271 lineto
+21630 64480 lineto
+21758 64668 lineto
+21921 64827 lineto
+22111 64951 lineto
+22321 65036 lineto
+22544 65079 lineto
+22771 65077 lineto
+22994 65032 lineto
+23203 64944 lineto
+23391 64817 lineto
+23551 64656 lineto
+23677 64467 lineto
+23764 64257 lineto
+23808 64034 lineto
+23804 63775 lineto
+23754 63553 lineto
+23662 63346 lineto
+23531 63160 lineto
+23367 63003 lineto
+23175 62882 lineto
+22963 62799 lineto
+22740 62760 lineto
+22740 33669 lineto
+22744 33676 lineto
+22748 33682 lineto
+22750 33684 lineto
+22775 33715 lineto
+22857 33813 lineto
+26591 37547 lineto
+26591 56543 lineto
+24105 59029 lineto
+24098 59036 lineto
+24046 59102 lineto
+23993 59167 lineto
+23990 59173 lineto
+23988 59175 lineto
+23946 59255 lineto
+23910 59324 lineto
+23909 59328 lineto
+23906 59333 lineto
+23879 59424 lineto
+23858 59493 lineto
+23857 59498 lineto
+23856 59503 lineto
+23847 59600 lineto
+23841 59670 lineto
+23841 59679 lineto
+23841 62212 lineto
+23823 62255 lineto
+23786 62440 lineto
+23785 62743 lineto
+23787 62933 lineto
+23827 63117 lineto
+23841 63150 lineto
+23841 63283 lineto
+23841 63293 lineto
+23850 63379 lineto
+23859 63460 lineto
+23860 63466 lineto
+23861 63469 lineto
+23881 63535 lineto
+23911 63629 lineto
+23913 63635 lineto
+23915 63638 lineto
+23940 63685 lineto
+23994 63786 lineto
+23998 63792 lineto
+24000 63794 lineto
+24025 63825 lineto
+24107 63923 lineto
+24206 64023 lineto
+24227 64117 lineto
+24241 64150 lineto
+24241 64323 lineto
+24241 64333 lineto
+24250 64419 lineto
+24259 64500 lineto
+24260 64506 lineto
+24261 64509 lineto
+24281 64574 lineto
+24311 64669 lineto
+24313 64675 lineto
+24315 64678 lineto
+24340 64725 lineto
+24394 64826 lineto
+24398 64832 lineto
+24400 64834 lineto
+24425 64865 lineto
+24507 64963 lineto
+24854 65310 lineto
+24859 65315 lineto
+24864 65320 lineto
+24866 65321 lineto
+24909 65357 lineto
+24997 65427 lineto
+24999 65429 lineto
+25004 65432 lineto
+25085 65474 lineto
+25154 65510 lineto
+25159 65512 lineto
+25162 65513 lineto
+25201 65525 lineto
+25323 65562 lineto
+25331 65563 lineto
+25332 65563 lineto
+25343 65565 lineto
+25500 65579 lineto
+27253 65579 lineto
+27263 65579 lineto
+27348 65570 lineto
+27430 65561 lineto
+27435 65560 lineto
+27439 65559 lineto
+27503 65539 lineto
+27599 65509 lineto
+27604 65507 lineto
+27608 65505 lineto
+27654 65480 lineto
+27756 65426 lineto
+27761 65422 lineto
+27764 65420 lineto
+27794 65395 lineto
+27893 65313 lineto
+28277 64929 lineto
+28311 64951 lineto
+28521 65036 lineto
+28744 65079 lineto
+28971 65077 lineto
+29194 65032 lineto
+29403 64944 lineto
+29591 64817 lineto
+29751 64656 lineto
+29875 64470 lineto
+29880 64480 lineto
+30008 64668 lineto
+30171 64827 lineto
+30361 64951 lineto
+30571 65036 lineto
+30794 65079 lineto
+31021 65077 lineto
+31244 65032 lineto
+31453 64944 lineto
+31641 64817 lineto
+31801 64656 lineto
+31927 64467 lineto
+32014 64257 lineto
+32058 64034 lineto
+32054 63775 lineto
+32012 63589 lineto
+32148 63589 lineto
+32161 63629 lineto
+32163 63635 lineto
+32165 63638 lineto
+32190 63685 lineto
+32244 63786 lineto
+32248 63792 lineto
+32250 63794 lineto
+32275 63825 lineto
+32357 63923 lineto
+32456 64023 lineto
+32477 64117 lineto
+32491 64150 lineto
+32491 64323 lineto
+32491 64333 lineto
+32500 64419 lineto
+32509 64500 lineto
+32510 64506 lineto
+32511 64509 lineto
+32531 64575 lineto
+32561 64669 lineto
+32563 64675 lineto
+32565 64678 lineto
+32590 64725 lineto
+32644 64826 lineto
+32648 64832 lineto
+32650 64834 lineto
+32675 64865 lineto
+32757 64963 lineto
+33104 65310 lineto
+33109 65315 lineto
+33114 65320 lineto
+33116 65321 lineto
+33159 65357 lineto
+33247 65427 lineto
+33249 65429 lineto
+33254 65432 lineto
+33335 65474 lineto
+33404 65510 lineto
+33409 65512 lineto
+33412 65513 lineto
+33451 65525 lineto
+33573 65562 lineto
+33581 65563 lineto
+33582 65563 lineto
+33593 65565 lineto
+33750 65579 lineto
+35503 65579 lineto
+35513 65579 lineto
+35598 65570 lineto
+35680 65561 lineto
+35685 65560 lineto
+35689 65559 lineto
+35754 65539 lineto
+35849 65509 lineto
+35854 65507 lineto
+35858 65505 lineto
+35904 65480 lineto
+36006 65426 lineto
+36011 65422 lineto
+36014 65420 lineto
+36044 65395 lineto
+36143 65313 lineto
+36527 64929 lineto
+36561 64951 lineto
+36771 65036 lineto
+36994 65079 lineto
+37221 65077 lineto
+37444 65032 lineto
+37653 64944 lineto
+37841 64817 lineto
+38001 64656 lineto
+38125 64470 lineto
+38130 64480 lineto
+38258 64668 lineto
+38421 64827 lineto
+38611 64951 lineto
+38821 65036 lineto
+39044 65079 lineto
+39271 65077 lineto
+39494 65032 lineto
+39703 64944 lineto
+39891 64817 lineto
+40051 64656 lineto
+40177 64467 lineto
+40264 64257 lineto
+40308 64034 lineto
+40304 63775 lineto
+40262 63589 lineto
+40398 63589 lineto
+40411 63629 lineto
+40413 63635 lineto
+40415 63638 lineto
+40440 63685 lineto
+40494 63786 lineto
+40498 63792 lineto
+40500 63794 lineto
+40525 63825 lineto
+40607 63923 lineto
+40706 64023 lineto
+40727 64117 lineto
+40741 64150 lineto
+40741 64323 lineto
+40741 64333 lineto
+40750 64419 lineto
+40759 64500 lineto
+40760 64506 lineto
+40761 64509 lineto
+40781 64574 lineto
+40811 64669 lineto
+40813 64675 lineto
+40815 64678 lineto
+40840 64725 lineto
+40894 64826 lineto
+40898 64832 lineto
+40900 64834 lineto
+40925 64865 lineto
+41007 64963 lineto
+41354 65310 lineto
+41359 65315 lineto
+41364 65320 lineto
+41366 65321 lineto
+41409 65357 lineto
+41497 65427 lineto
+41499 65429 lineto
+41504 65432 lineto
+41585 65474 lineto
+41654 65510 lineto
+41659 65512 lineto
+41662 65513 lineto
+41701 65525 lineto
+41823 65562 lineto
+41831 65563 lineto
+41832 65563 lineto
+41843 65565 lineto
+42000 65579 lineto
+44003 65579 lineto
+44013 65579 lineto
+44098 65570 lineto
+44180 65561 lineto
+44185 65560 lineto
+44189 65559 lineto
+44254 65539 lineto
+44349 65509 lineto
+44354 65507 lineto
+44358 65505 lineto
+44404 65480 lineto
+44506 65426 lineto
+44511 65422 lineto
+44514 65420 lineto
+44544 65395 lineto
+44643 65313 lineto
+44895 65061 lineto
+44902 65054 lineto
+44941 65004 lineto
+45021 65036 lineto
+45244 65079 lineto
+45471 65077 lineto
+45694 65032 lineto
+45903 64944 lineto
+46091 64817 lineto
+46251 64656 lineto
+46375 64470 lineto
+46380 64480 lineto
+46508 64668 lineto
+46671 64827 lineto
+46861 64951 lineto
+47071 65036 lineto
+47294 65079 lineto
+47521 65077 lineto
+47744 65032 lineto
+47953 64944 lineto
+48141 64817 lineto
+48301 64656 lineto
+48427 64467 lineto
+48514 64257 lineto
+48558 64034 lineto
+48554 63775 lineto
+48512 63589 lineto
+48648 63589 lineto
+48661 63629 lineto
+48663 63635 lineto
+48665 63638 lineto
+48690 63685 lineto
+48744 63786 lineto
+48748 63792 lineto
+48750 63794 lineto
+48775 63825 lineto
+48857 63923 lineto
+48956 64023 lineto
+48977 64117 lineto
+48991 64150 lineto
+48991 64323 lineto
+48991 64333 lineto
+49000 64419 lineto
+49009 64500 lineto
+49010 64506 lineto
+49011 64509 lineto
+49031 64574 lineto
+49061 64669 lineto
+49063 64675 lineto
+49065 64678 lineto
+49090 64725 lineto
+49144 64826 lineto
+49148 64832 lineto
+49150 64834 lineto
+49175 64865 lineto
+49257 64963 lineto
+49604 65310 lineto
+49609 65315 lineto
+49614 65320 lineto
+49616 65321 lineto
+49659 65357 lineto
+49747 65427 lineto
+49749 65429 lineto
+49754 65432 lineto
+49835 65474 lineto
+49904 65510 lineto
+49909 65512 lineto
+49912 65513 lineto
+49951 65525 lineto
+50073 65562 lineto
+50081 65563 lineto
+50082 65563 lineto
+50094 65565 lineto
+50250 65579 lineto
+52003 65579 lineto
+52013 65579 lineto
+52098 65570 lineto
+52180 65561 lineto
+52185 65560 lineto
+52189 65559 lineto
+52254 65539 lineto
+52349 65509 lineto
+52354 65507 lineto
+52358 65505 lineto
+52404 65480 lineto
+52506 65426 lineto
+52511 65422 lineto
+52514 65420 lineto
+52544 65395 lineto
+52643 65313 lineto
+53027 64929 lineto
+53061 64951 lineto
+53271 65036 lineto
+53494 65079 lineto
+53721 65077 lineto
+53944 65032 lineto
+54153 64944 lineto
+54341 64817 lineto
+54501 64656 lineto
+54625 64470 lineto
+54630 64480 lineto
+54758 64668 lineto
+54921 64827 lineto
+55111 64951 lineto
+55321 65036 lineto
+55544 65079 lineto
+55771 65077 lineto
+55994 65032 lineto
+56203 64944 lineto
+56391 64817 lineto
+56551 64656 lineto
+56677 64467 lineto
+56764 64257 lineto
+56808 64034 lineto
+56804 63775 lineto
+56762 63589 lineto
+56898 63589 lineto
+56911 63629 lineto
+56913 63635 lineto
+56915 63638 lineto
+56940 63685 lineto
+56994 63786 lineto
+56998 63792 lineto
+57000 63794 lineto
+57025 63825 lineto
+57107 63923 lineto
+57206 64023 lineto
+57227 64117 lineto
+57301 64291 lineto
+57408 64447 lineto
+57543 64580 lineto
+57701 64683 lineto
+57876 64754 lineto
+58062 64790 lineto
+58251 64788 lineto
+58436 64750 lineto
+58549 64703 lineto
+58676 64754 lineto
+58862 64790 lineto
+59051 64788 lineto
+59236 64750 lineto
+59349 64703 lineto
+59476 64754 lineto
+59662 64790 lineto
+59851 64788 lineto
+60036 64750 lineto
+60210 64677 lineto
+60367 64572 lineto
+60500 64438 lineto
+60605 64280 lineto
+60677 64105 lineto
+60693 64022 lineto
+60694 64049 lineto
+60741 64271 lineto
+60830 64480 lineto
+60958 64668 lineto
+61121 64827 lineto
+61311 64951 lineto
+61521 65036 lineto
+61744 65079 lineto
+61971 65077 lineto
+62194 65032 lineto
+62403 64944 lineto
+62591 64817 lineto
+62751 64656 lineto
+62877 64467 lineto
+62881 64456 lineto
+63424 64999 lineto
+63430 65004 lineto
+63472 65038 lineto
+63548 65100 lineto
+63553 65104 lineto
+63555 65104 lineto
+63601 65128 lineto
+63689 65174 lineto
+63691 65175 lineto
+63696 65177 lineto
+63764 65197 lineto
+63842 65220 lineto
+63847 65221 lineto
+63849 65221 lineto
+63871 65223 lineto
+64000 65236 lineto
+70942 65236 lineto
+71040 65300 lineto
+71220 65372 lineto
+71410 65409 lineto
+71604 65407 lineto
+71793 65368 lineto
+71972 65293 lineto
+72000 65275 lineto
+72040 65300 lineto
+72220 65372 lineto
+72410 65409 lineto
+72604 65407 lineto
+72793 65368 lineto
+72972 65293 lineto
+73133 65185 lineto
+73269 65048 lineto
+73376 64886 lineto
+73450 64707 lineto
+73488 64517 lineto
+73485 64296 lineto
+73442 64107 lineto
+73363 63930 lineto
+73252 63771 lineto
+73111 63638 lineto
+72948 63534 lineto
+72767 63464 lineto
+72576 63430 lineto
+72383 63434 lineto
+72193 63476 lineto
+72016 63553 lineto
+71997 63566 lineto
+71948 63534 lineto
+71767 63464 lineto
+71576 63430 lineto
+71383 63434 lineto
+71193 63476 lineto
+71016 63553 lineto
+70942 63604 lineto
+64337 63604 lineto
+64029 63296 lineto
+64206 63221 lineto
+64399 63091 lineto
+64564 62925 lineto
+64693 62731 lineto
+64782 62516 lineto
+64827 62287 lineto
+64823 62021 lineto
+64772 61793 lineto
+64703 61641 lineto
+64763 61726 lineto
+64897 61857 lineto
+65054 61960 lineto
+65228 62030 lineto
+65413 62066 lineto
+65601 62064 lineto
+65785 62027 lineto
+65958 61954 lineto
+66000 61926 lineto
+66054 61960 lineto
+66228 62030 lineto
+66413 62066 lineto
+66601 62064 lineto
+66785 62027 lineto
+66958 61954 lineto
+67004 61923 lineto
+67198 61923 lineto
+67171 62070 lineto
+67175 62303 lineto
+67223 62531 lineto
+67315 62745 lineto
+67447 62938 lineto
+67613 63101 lineto
+67808 63229 lineto
+68024 63316 lineto
+68253 63360 lineto
+68486 63358 lineto
+68715 63311 lineto
+68930 63221 lineto
+69123 63091 lineto
+69288 62925 lineto
+69417 62731 lineto
+69506 62516 lineto
+69551 62287 lineto
+69547 62021 lineto
+69496 61793 lineto
+69401 61580 lineto
+69267 61390 lineto
+69098 61229 lineto
+68901 61104 lineto
+68684 61019 lineto
+68574 61000 lineto
+69579 59995 lineto
+69584 59990 lineto
+69617 59948 lineto
+69680 59872 lineto
+69683 59867 lineto
+69684 59865 lineto
+69707 59819 lineto
+69754 59731 lineto
+69754 59729 lineto
+69757 59724 lineto
+69774 59665 lineto
+69800 59578 lineto
+69800 59572 lineto
+69801 59570 lineto
+69802 59556 lineto
+69816 59420 lineto
+69816 57420 lineto
+69816 57409 lineto
+69816 56841 lineto
+69897 56920 lineto
+70054 57023 lineto
+70228 57093 lineto
+70413 57129 lineto
+70601 57127 lineto
+70785 57090 lineto
+70958 57017 lineto
+71114 56912 lineto
+71246 56778 lineto
+71350 56622 lineto
+71421 56448 lineto
+71458 56264 lineto
+71455 56049 lineto
+71413 55866 lineto
+71337 55695 lineto
+71229 55541 lineto
+71159 55475 lineto
+71159 54104 lineto
+71165 54105 lineto
+71348 54103 lineto
+71527 54067 lineto
+71696 53996 lineto
+71848 53893 lineto
+71977 53763 lineto
+72078 53611 lineto
+72148 53442 lineto
+72184 53262 lineto
+72181 53053 lineto
+72141 52874 lineto
+72066 52707 lineto
+71961 52557 lineto
+71828 52431 lineto
+71674 52332 lineto
+71503 52266 lineto
+71322 52234 lineto
+71139 52238 lineto
+70960 52277 lineto
+70910 52299 lineto
+70909 52298 lineto
+70909 49420 lineto
+70909 49407 lineto
+70909 48620 lineto
+70964 48642 lineto
+71158 48679 lineto
+71356 48677 lineto
+71549 48638 lineto
+71732 48561 lineto
+71895 48451 lineto
+72035 48310 lineto
+72144 48146 lineto
+72220 47963 lineto
+72258 47769 lineto
+72255 47543 lineto
+72211 47350 lineto
+72131 47170 lineto
+72017 47008 lineto
+71925 46921 lineto
+72035 46810 lineto
+72144 46646 lineto
+72220 46463 lineto
+72258 46269 lineto
+72255 46043 lineto
+72211 45850 lineto
+72131 45670 lineto
+72017 45508 lineto
+71874 45372 lineto
+71707 45266 lineto
+71523 45195 lineto
+71328 45160 lineto
+71130 45164 lineto
+70937 45207 lineto
+70756 45286 lineto
+70594 45399 lineto
+70456 45541 lineto
+70349 45707 lineto
+70276 45891 lineto
+70272 45908 lineto
+65891 41526 lineto
+65891 41525 lineto
+65890 41525 lineto
+65884 41518 lineto
+65818 41467 lineto
+65753 41413 lineto
+65747 41411 lineto
+65745 41408 lineto
+65665 41367 lineto
+65596 41330 lineto
+65592 41330 lineto
+65587 41326 lineto
+65496 41300 lineto
+65427 41278 lineto
+65422 41278 lineto
+65417 41276 lineto
+65320 41268 lineto
+65250 41261 lineto
+65241 41261 lineto
+63000 41261 lineto
+62994 41261 lineto
+62987 41261 lineto
+62434 41261 lineto
+62434 41105 lineto
+62598 41103 lineto
+62777 41067 lineto
+62946 40996 lineto
+63098 40893 lineto
+63227 40763 lineto
+63328 40611 lineto
+63398 40442 lineto
+63434 40262 lineto
+63431 40053 lineto
+63391 39874 lineto
+63316 39707 lineto
+63316 39591 lineto
+63397 39670 lineto
+63554 39773 lineto
+63728 39843 lineto
+63913 39879 lineto
+64101 39877 lineto
+64285 39840 lineto
+64447 39772 lineto
+67425 42749 lineto
+67430 42754 lineto
+67472 42788 lineto
+67548 42850 lineto
+67553 42854 lineto
+67555 42854 lineto
+67601 42878 lineto
+67689 42924 lineto
+67691 42925 lineto
+67696 42927 lineto
+67755 42945 lineto
+67842 42970 lineto
+67848 42971 lineto
+67850 42971 lineto
+67880 42974 lineto
+68000 42986 lineto
+68008 42986 lineto
+68406 42986 lineto
+68531 43068 lineto
+68714 43142 lineto
+68908 43179 lineto
+69106 43177 lineto
+69299 43138 lineto
+69482 43061 lineto
+69645 42951 lineto
+69785 42810 lineto
+69894 42646 lineto
+69970 42463 lineto
+70008 42269 lineto
+70005 42043 lineto
+69961 41850 lineto
+69881 41670 lineto
+69879 41668 lineto
+69894 41646 lineto
+69970 41463 lineto
+70008 41269 lineto
+70005 41043 lineto
+69961 40850 lineto
+69943 40811 lineto
+69984 40712 lineto
+70009 40585 lineto
+70009 39751 lineto
+69983 39625 lineto
+69933 39505 lineto
+69909 39470 lineto
+69909 39417 lineto
+69909 39407 lineto
+69899 39322 lineto
+69891 39240 lineto
+69889 39235 lineto
+69889 39231 lineto
+69868 39166 lineto
+69839 39071 lineto
+69836 39066 lineto
+69835 39062 lineto
+69809 39016 lineto
+69756 38914 lineto
+69751 38909 lineto
+69750 38906 lineto
+69724 38876 lineto
+69643 38777 lineto
+69141 38275 lineto
+69134 38268 lineto
+69068 38217 lineto
+69003 38163 lineto
+68997 38161 lineto
+68995 38158 lineto
+68915 38117 lineto
+68846 38080 lineto
+68842 38080 lineto
+68837 38076 lineto
+68746 38050 lineto
+68677 38028 lineto
+68672 38028 lineto
+68667 38026 lineto
+68570 38018 lineto
+68500 38011 lineto
+68491 38011 lineto
+68376 38012 lineto
+68159 37794 lineto
+68159 37399 lineto
+68162 37401 lineto
+68315 37502 lineto
+68485 37570 lineto
+68665 37605 lineto
+68848 37603 lineto
+69027 37567 lineto
+69196 37496 lineto
+69348 37393 lineto
+69477 37263 lineto
+69578 37111 lineto
+69648 36942 lineto
+69684 36762 lineto
+69682 36661 lineto
+72014 36661 lineto
+72206 36639 lineto
+72317 36604 lineto
+72344 36604 lineto
+72470 36578 lineto
+72590 36528 lineto
+72604 36518 lineto
+72735 36570 lineto
+72915 36605 lineto
+73098 36603 lineto
+73277 36567 lineto
+73446 36496 lineto
+73598 36393 lineto
+73681 36310 lineto
+73681 38761 lineto
+73555 38787 lineto
+73435 38837 lineto
+73328 38910 lineto
+73237 39001 lineto
+73165 39109 lineto
+73116 39228 lineto
+73091 39355 lineto
+73091 42989 lineto
+73117 43115 lineto
+73167 43235 lineto
+73240 43342 lineto
+73331 43433 lineto
+73439 43505 lineto
+73558 43554 lineto
+73685 43579 lineto
+77319 43579 lineto
+77445 43553 lineto
+77565 43503 lineto
+77672 43430 lineto
+77763 43339 lineto
+77835 43231 lineto
+77884 43112 lineto
+77909 42985 lineto
+77909 39351 lineto
+77883 39225 lineto
+77833 39105 lineto
+77760 38998 lineto
+77669 38907 lineto
+77561 38835 lineto
+77442 38786 lineto
+77315 38761 lineto
+73681 38761 lineto
+73681 36310 lineto
+73727 36263 lineto
+73828 36111 lineto
+73898 35942 lineto
+73934 35762 lineto
+73931 35553 lineto
+73891 35374 lineto
+73816 35207 lineto
+73711 35057 lineto
+73578 34931 lineto
+73424 34832 lineto
+73253 34766 lineto
+73072 34734 lineto
+72909 34738 lineto
+72909 34174 lineto
+73014 34174 lineto
+73140 34148 lineto
+73260 34098 lineto
+73367 34025 lineto
+73458 33934 lineto
+73530 33826 lineto
+73579 33707 lineto
+73604 33580 lineto
+73604 32627 lineto
+73854 32674 lineto
+74169 32672 lineto
+74476 32609 lineto
+74766 32487 lineto
+75027 32311 lineto
+75248 32088 lineto
+75422 31826 lineto
+75542 31535 lineto
+75603 31227 lineto
+75598 30868 lineto
+75528 30561 lineto
+75400 30274 lineto
+75219 30017 lineto
+74991 29801 lineto
+74726 29632 lineto
+74433 29519 lineto
+74123 29464 lineto
+73809 29471 lineto
+73502 29538 lineto
+73477 29549 lineto
+73400 29374 lineto
+73219 29117 lineto
+72991 28901 lineto
+72726 28732 lineto
+72433 28619 lineto
+72123 28564 lineto
+71809 28571 lineto
+71502 28638 lineto
+71214 28764 lineto
+70956 28944 lineto
+70738 29170 lineto
+70567 29434 lineto
+70452 29726 lineto
+70395 30035 lineto
+70399 30350 lineto
+70465 30657 lineto
+70589 30946 lineto
+70681 31082 lineto
+70633 31115 lineto
+70542 31206 lineto
+70470 31314 lineto
+70421 31433 lineto
+70396 31560 lineto
+70396 33261 lineto
+68126 33261 lineto
+67604 32739 lineto
+67604 32627 lineto
+67854 32674 lineto
+68169 32672 lineto
+68476 32609 lineto
+68766 32487 lineto
+69027 32311 lineto
+69248 32088 lineto
+69422 31826 lineto
+69542 31535 lineto
+69603 31227 lineto
+69598 30868 lineto
+69528 30561 lineto
+69400 30274 lineto
+69219 30017 lineto
+68991 29801 lineto
+68726 29632 lineto
+68433 29519 lineto
+68123 29464 lineto
+67809 29471 lineto
+67502 29538 lineto
+67477 29549 lineto
+67400 29374 lineto
+67219 29117 lineto
+66991 28901 lineto
+66726 28732 lineto
+66433 28619 lineto
+66123 28564 lineto
+65809 28571 lineto
+65502 28638 lineto
+65214 28764 lineto
+64956 28944 lineto
+64738 29170 lineto
+64567 29434 lineto
+64452 29726 lineto
+64395 30035 lineto
+64399 30350 lineto
+64465 30657 lineto
+64589 30946 lineto
+64681 31082 lineto
+64633 31115 lineto
+64542 31206 lineto
+64470 31314 lineto
+64421 31433 lineto
+64396 31560 lineto
+64396 33584 lineto
+64422 33710 lineto
+64443 33761 lineto
+63507 33761 lineto
+63505 33543 lineto
+63461 33350 lineto
+63381 33170 lineto
+63379 33168 lineto
+63394 33146 lineto
+63470 32963 lineto
+63508 32769 lineto
+63505 32543 lineto
+63461 32350 lineto
+63409 32233 lineto
+63409 31417 lineto
+63409 31407 lineto
+63389 31231 lineto
+63347 31103 lineto
+63338 31070 lineto
+63336 31068 lineto
+63335 31062 lineto
+63281 30965 lineto
+63255 30914 lineto
+63253 30912 lineto
+63250 30906 lineto
+63181 30825 lineto
+63142 30777 lineto
+62636 30272 lineto
+62751 30156 lineto
+62877 29967 lineto
+62964 29757 lineto
+63008 29534 lineto
+63004 29275 lineto
+62954 29053 lineto
+62862 28846 lineto
+62731 28660 lineto
+62567 28503 lineto
+62375 28382 lineto
+62163 28299 lineto
+61940 28260 lineto
+61713 28265 lineto
+61491 28313 lineto
+61283 28404 lineto
+61096 28534 lineto
+60938 28697 lineto
+60815 28888 lineto
+60732 29099 lineto
+60691 29322 lineto
+60694 29549 lineto
+60736 29751 lineto
+60600 29751 lineto
+60597 29743 lineto
+60588 29710 lineto
+60586 29708 lineto
+60585 29702 lineto
+60531 29605 lineto
+60505 29554 lineto
+60503 29552 lineto
+60500 29546 lineto
+60431 29465 lineto
+60392 29417 lineto
+60293 29319 lineto
+60273 29223 lineto
+60259 29191 lineto
+60259 29016 lineto
+60259 29007 lineto
+60239 28831 lineto
+60197 28703 lineto
+60188 28670 lineto
+60186 28668 lineto
+60185 28662 lineto
+60131 28565 lineto
+60105 28514 lineto
+60103 28512 lineto
+60100 28506 lineto
+60031 28425 lineto
+59992 28377 lineto
+59641 28026 lineto
+59641 28025 lineto
+59640 28025 lineto
+59634 28018 lineto
+59568 27967 lineto
+59503 27913 lineto
+59497 27911 lineto
+59495 27908 lineto
+59415 27867 lineto
+59346 27830 lineto
+59342 27830 lineto
+59337 27826 lineto
+59246 27800 lineto
+59177 27778 lineto
+59172 27778 lineto
+59167 27776 lineto
+59070 27768 lineto
+59000 27761 lineto
+58991 27761 lineto
+58991 27576 lineto
+79819 27576 lineto
+poly0
+newpath 61363 31569 moveto
+61591 31797 lineto
+61591 32228 lineto
+61526 32391 lineto
+61491 32585 lineto
+61493 32783 lineto
+61535 32976 lineto
+61612 33158 lineto
+61621 33172 lineto
+61599 33207 lineto
+61526 33391 lineto
+61491 33585 lineto
+61493 33783 lineto
+61535 33976 lineto
+61612 34158 lineto
+61621 34172 lineto
+61599 34207 lineto
+61577 34261 lineto
+57246 34261 lineto
+57237 34261 lineto
+57061 34281 lineto
+56932 34323 lineto
+56900 34332 lineto
+56897 34334 lineto
+56892 34335 lineto
+56793 34389 lineto
+56744 34415 lineto
+56741 34417 lineto
+56736 34420 lineto
+56654 34489 lineto
+56607 34528 lineto
+54555 36579 lineto
+54457 36516 lineto
+54273 36445 lineto
+54078 36410 lineto
+53880 36414 lineto
+53687 36457 lineto
+53506 36536 lineto
+53497 36542 lineto
+53457 36516 lineto
+53273 36445 lineto
+53078 36410 lineto
+52880 36414 lineto
+52687 36457 lineto
+52563 36511 lineto
+51062 36511 lineto
+51587 35986 lineto
+53753 35986 lineto
+53761 35986 lineto
+53828 35979 lineto
+53911 35970 lineto
+53916 35969 lineto
+53920 35968 lineto
+54010 35940 lineto
+54063 35923 lineto
+54065 35922 lineto
+54071 35920 lineto
+54190 35855 lineto
+54204 35847 lineto
+54204 35847 lineto
+54211 35843 lineto
+54284 35782 lineto
+54327 35747 lineto
+54332 35742 lineto
+56087 33986 lineto
+57753 33986 lineto
+57761 33986 lineto
+57828 33979 lineto
+57911 33970 lineto
+57916 33969 lineto
+57920 33968 lineto
+58010 33940 lineto
+58063 33923 lineto
+58065 33922 lineto
+58071 33920 lineto
+58190 33855 lineto
+58204 33847 lineto
+58204 33847 lineto
+58211 33843 lineto
+58284 33782 lineto
+58327 33747 lineto
+58333 33741 lineto
+59529 32545 lineto
+59535 32539 lineto
+59564 32503 lineto
+59630 32422 lineto
+59704 32281 lineto
+59705 32276 lineto
+59707 32273 lineto
+59733 32182 lineto
+59750 32128 lineto
+59750 32127 lineto
+59752 32120 lineto
+59760 32027 lineto
+59766 31970 lineto
+59766 31962 lineto
+59766 31769 lineto
+59851 31768 lineto
+60036 31730 lineto
+60210 31657 lineto
+60341 31569 lineto
+61363 31569 lineto
+poly0
+newpath 54500 39299 moveto
+54531 39318 lineto
+54703 39388 lineto
+54644 39480 lineto
+54575 39655 lineto
+54541 39839 lineto
+54543 40027 lineto
+54582 40211 lineto
+54656 40384 lineto
+54763 40539 lineto
+54897 40670 lineto
+55054 40773 lineto
+55228 40843 lineto
+55413 40879 lineto
+55601 40877 lineto
+55785 40840 lineto
+55958 40767 lineto
+56114 40662 lineto
+56246 40528 lineto
+56350 40372 lineto
+56421 40198 lineto
+56432 40142 lineto
+56587 39986 lineto
+57750 39986 lineto
+57756 39986 lineto
+57761 39986 lineto
+60162 39986 lineto
+60598 40423 lineto
+60605 40453 lineto
+60652 40565 lineto
+60640 40584 lineto
+60591 40703 lineto
+60566 40830 lineto
+60566 41261 lineto
+58707 41261 lineto
+58705 41049 lineto
+58663 40866 lineto
+58587 40695 lineto
+58479 40541 lineto
+58343 40412 lineto
+58184 40311 lineto
+58009 40243 lineto
+57824 40210 lineto
+57636 40214 lineto
+57453 40254 lineto
+57280 40330 lineto
+57126 40437 lineto
+56996 40572 lineto
+56894 40730 lineto
+56825 40905 lineto
+56791 41089 lineto
+56792 41261 lineto
+51933 41261 lineto
+51931 41053 lineto
+51891 40874 lineto
+51816 40707 lineto
+51711 40557 lineto
+51578 40431 lineto
+51424 40332 lineto
+51253 40266 lineto
+51072 40234 lineto
+50889 40238 lineto
+50851 40247 lineto
+50895 40181 lineto
+50944 40062 lineto
+50969 39935 lineto
+50969 39329 lineto
+52000 39329 lineto
+52013 39329 lineto
+52558 39329 lineto
+52714 39392 lineto
+52908 39429 lineto
+53106 39427 lineto
+53299 39388 lineto
+53482 39311 lineto
+53500 39299 lineto
+53531 39318 lineto
+53714 39392 lineto
+53908 39429 lineto
+54106 39427 lineto
+54299 39388 lineto
+54482 39311 lineto
+54500 39299 lineto
+poly0
+newpath 63909 43079 moveto
+64872 43080 lineto
+65595 43802 lineto
+65530 43830 lineto
+65376 43937 lineto
+65246 44072 lineto
+65144 44230 lineto
+65075 44405 lineto
+65041 44589 lineto
+65043 44777 lineto
+65082 44961 lineto
+65156 45134 lineto
+65263 45289 lineto
+65397 45420 lineto
+65398 45422 lineto
+65376 45437 lineto
+65246 45572 lineto
+65144 45730 lineto
+65075 45905 lineto
+65041 46089 lineto
+65043 46277 lineto
+65082 46461 lineto
+65156 46634 lineto
+65184 46675 lineto
+65184 47169 lineto
+65144 47230 lineto
+65075 47405 lineto
+65041 47589 lineto
+65043 47777 lineto
+65082 47961 lineto
+65156 48134 lineto
+65263 48289 lineto
+65397 48420 lineto
+65554 48523 lineto
+65728 48593 lineto
+65913 48629 lineto
+66101 48627 lineto
+66285 48590 lineto
+66458 48517 lineto
+66462 48515 lineto
+66481 48533 lineto
+66589 48605 lineto
+66708 48654 lineto
+66835 48679 lineto
+67434 48679 lineto
+67434 51262 lineto
+67434 53262 lineto
+67434 56670 lineto
+67434 56681 lineto
+67434 58582 lineto
+66643 59373 lineto
+66574 59360 lineto
+66409 59364 lineto
+66409 58387 lineto
+66434 58262 lineto
+66431 58053 lineto
+66409 57955 lineto
+66409 56478 lineto
+66421 56448 lineto
+66458 56264 lineto
+66455 56049 lineto
+66413 55866 lineto
+66337 55695 lineto
+66229 55541 lineto
+66093 55412 lineto
+65934 55311 lineto
+65759 55243 lineto
+65574 55210 lineto
+65386 55214 lineto
+65203 55254 lineto
+65030 55330 lineto
+64876 55437 lineto
+64746 55572 lineto
+64644 55730 lineto
+64575 55905 lineto
+64541 56089 lineto
+64543 56277 lineto
+64582 56461 lineto
+64591 56483 lineto
+64591 57238 lineto
+64572 57234 lineto
+64389 57238 lineto
+64210 57277 lineto
+64042 57351 lineto
+63892 57455 lineto
+63765 57587 lineto
+63665 57741 lineto
+63598 57911 lineto
+63565 58091 lineto
+63567 58274 lineto
+63605 58453 lineto
+63677 58622 lineto
+63781 58773 lineto
+63912 58901 lineto
+64065 59002 lineto
+64235 59070 lineto
+64415 59105 lineto
+64591 59104 lineto
+64591 60015 lineto
+64575 60055 lineto
+64541 60239 lineto
+64543 60427 lineto
+64582 60611 lineto
+64625 60714 lineto
+64575 60842 lineto
+64541 61026 lineto
+64543 61214 lineto
+64582 61398 lineto
+64633 61519 lineto
+64543 61390 lineto
+64374 61229 lineto
+64177 61104 lineto
+63960 61019 lineto
+63730 60979 lineto
+63497 60984 lineto
+63269 61034 lineto
+63055 61127 lineto
+62864 61260 lineto
+62702 61428 lineto
+62576 61624 lineto
+62566 61650 lineto
+62566 61159 lineto
+62555 61068 lineto
+62550 61008 lineto
+62548 61003 lineto
+62548 61000 lineto
+62500 60849 lineto
+62447 60754 lineto
+62427 60715 lineto
+62424 60713 lineto
+62423 60709 lineto
+62371 60647 lineto
+62326 60592 lineto
+62321 60587 lineto
+61609 59876 lineto
+61785 59840 lineto
+61958 59767 lineto
+62114 59662 lineto
+62246 59528 lineto
+62350 59372 lineto
+62421 59198 lineto
+62458 59014 lineto
+62455 58799 lineto
+62413 58616 lineto
+62379 58540 lineto
+62385 58531 lineto
+62434 58412 lineto
+62459 58285 lineto
+62459 57551 lineto
+62433 57425 lineto
+62383 57305 lineto
+62310 57198 lineto
+62219 57107 lineto
+62111 57035 lineto
+61992 56986 lineto
+61865 56961 lineto
+61694 56961 lineto
+61443 56710 lineto
+61503 56619 lineto
+61574 56444 lineto
+61610 56258 lineto
+61608 56069 lineto
+61570 55884 lineto
+61497 55710 lineto
+61469 55670 lineto
+61503 55619 lineto
+61574 55444 lineto
+61610 55258 lineto
+61608 55069 lineto
+61572 54897 lineto
+62002 55327 lineto
+62035 55476 lineto
+62112 55658 lineto
+62224 55821 lineto
+62365 55959 lineto
+62531 56068 lineto
+62714 56142 lineto
+62908 56179 lineto
+63106 56177 lineto
+63299 56138 lineto
+63482 56061 lineto
+63609 55976 lineto
+63661 55970 lineto
+63666 55969 lineto
+63670 55968 lineto
+63760 55940 lineto
+63813 55923 lineto
+63815 55922 lineto
+63821 55920 lineto
+63940 55855 lineto
+63954 55847 lineto
+63954 55847 lineto
+63961 55843 lineto
+64034 55782 lineto
+64077 55747 lineto
+64082 55742 lineto
+65751 54073 lineto
+65777 54067 lineto
+65946 53996 lineto
+66000 53960 lineto
+66065 54002 lineto
+66235 54070 lineto
+66415 54105 lineto
+66598 54103 lineto
+66777 54067 lineto
+66946 53996 lineto
+67098 53893 lineto
+67227 53763 lineto
+67328 53611 lineto
+67398 53442 lineto
+67434 53262 lineto
+67431 53053 lineto
+67391 52874 lineto
+67316 52707 lineto
+67211 52557 lineto
+67078 52431 lineto
+66924 52332 lineto
+66753 52266 lineto
+66572 52234 lineto
+66389 52238 lineto
+66210 52277 lineto
+66042 52351 lineto
+65999 52381 lineto
+65924 52332 lineto
+65753 52266 lineto
+65572 52234 lineto
+65389 52238 lineto
+65210 52277 lineto
+65042 52351 lineto
+64892 52455 lineto
+64765 52587 lineto
+64665 52741 lineto
+64598 52911 lineto
+64596 52920 lineto
+63911 53605 lineto
+63970 53463 lineto
+64008 53269 lineto
+64005 53043 lineto
+63961 52850 lineto
+63881 52670 lineto
+63816 52578 lineto
+63816 51986 lineto
+65040 51986 lineto
+65065 52002 lineto
+65235 52070 lineto
+65415 52105 lineto
+65598 52103 lineto
+65777 52067 lineto
+65946 51996 lineto
+66000 51960 lineto
+66065 52002 lineto
+66235 52070 lineto
+66415 52105 lineto
+66598 52103 lineto
+66777 52067 lineto
+66946 51996 lineto
+67098 51893 lineto
+67227 51763 lineto
+67328 51611 lineto
+67398 51442 lineto
+67434 51262 lineto
+67431 51053 lineto
+67391 50874 lineto
+67316 50707 lineto
+67211 50557 lineto
+67078 50431 lineto
+66924 50332 lineto
+66753 50266 lineto
+66572 50234 lineto
+66389 50238 lineto
+66210 50277 lineto
+66042 50351 lineto
+65999 50381 lineto
+65924 50332 lineto
+65753 50266 lineto
+65572 50234 lineto
+65389 50238 lineto
+65210 50277 lineto
+65042 50351 lineto
+65037 50354 lineto
+63915 50354 lineto
+63934 50262 lineto
+63931 50053 lineto
+63891 49874 lineto
+63816 49707 lineto
+63789 49670 lineto
+63828 49611 lineto
+63898 49442 lineto
+63934 49262 lineto
+63931 49053 lineto
+63909 48955 lineto
+63909 43079 lineto
+poly0
+newpath 39500 44640 moveto
+39551 44673 lineto
+39726 44744 lineto
+39912 44780 lineto
+40101 44778 lineto
+40184 44761 lineto
+40184 45573 lineto
+40184 45581 lineto
+40191 45649 lineto
+40200 45731 lineto
+40201 45737 lineto
+40202 45740 lineto
+40230 45831 lineto
+40247 45883 lineto
+40248 45886 lineto
+40250 45891 lineto
+40315 46011 lineto
+40323 46024 lineto
+40323 46025 lineto
+40327 46031 lineto
+40388 46105 lineto
+40423 46147 lineto
+40429 46153 lineto
+40846 46570 lineto
+40421 46995 lineto
+40415 47001 lineto
+40385 47038 lineto
+40320 47118 lineto
+40246 47259 lineto
+40244 47265 lineto
+40243 47267 lineto
+40216 47358 lineto
+40200 47412 lineto
+40199 47414 lineto
+40198 47420 lineto
+40189 47515 lineto
+40184 47570 lineto
+40184 47578 lineto
+40184 47854 lineto
+33247 47854 lineto
+33239 47854 lineto
+33174 47862 lineto
+33088 47870 lineto
+33082 47872 lineto
+33080 47872 lineto
+33025 47890 lineto
+32936 47917 lineto
+32932 47919 lineto
+32929 47920 lineto
+32817 47982 lineto
+32796 47993 lineto
+32795 47994 lineto
+32789 47997 lineto
+32715 48059 lineto
+32673 48093 lineto
+32667 48099 lineto
+32421 48345 lineto
+32415 48351 lineto
+32385 48388 lineto
+32320 48468 lineto
+32254 48593 lineto
+32088 48560 lineto
+31899 48562 lineto
+31816 48580 lineto
+31816 45670 lineto
+31816 45659 lineto
+31816 44762 lineto
+31912 44780 lineto
+32101 44778 lineto
+32286 44740 lineto
+32460 44667 lineto
+32500 44640 lineto
+32551 44673 lineto
+32726 44744 lineto
+32912 44780 lineto
+33101 44778 lineto
+33286 44740 lineto
+33460 44667 lineto
+33500 44640 lineto
+33551 44673 lineto
+33726 44744 lineto
+33912 44780 lineto
+34101 44778 lineto
+34286 44740 lineto
+34460 44667 lineto
+34500 44640 lineto
+34551 44673 lineto
+34726 44744 lineto
+34912 44780 lineto
+35101 44778 lineto
+35286 44740 lineto
+35460 44667 lineto
+35500 44640 lineto
+35551 44673 lineto
+35726 44744 lineto
+35912 44780 lineto
+36101 44778 lineto
+36286 44740 lineto
+36460 44667 lineto
+36500 44640 lineto
+36551 44673 lineto
+36726 44744 lineto
+36912 44780 lineto
+37101 44778 lineto
+37286 44740 lineto
+37460 44667 lineto
+37500 44640 lineto
+37551 44673 lineto
+37726 44744 lineto
+37912 44780 lineto
+38101 44778 lineto
+38286 44740 lineto
+38460 44667 lineto
+38500 44640 lineto
+38551 44673 lineto
+38726 44744 lineto
+38912 44780 lineto
+39101 44778 lineto
+39286 44740 lineto
+39460 44667 lineto
+39500 44640 lineto
+poly0
+newpath 59419 50405 moveto
+59430 50456 lineto
+59503 50630 lineto
+59530 50671 lineto
+59497 50721 lineto
+59426 50896 lineto
+59390 51082 lineto
+59392 51271 lineto
+59423 51424 lineto
+59309 51486 lineto
+59296 51493 lineto
+59295 51494 lineto
+59289 51497 lineto
+59215 51559 lineto
+59173 51593 lineto
+59166 51600 lineto
+58912 51854 lineto
+58557 51854 lineto
+58528 51787 lineto
+58534 51782 lineto
+58577 51747 lineto
+58583 51741 lineto
+59079 51245 lineto
+59085 51239 lineto
+59114 51203 lineto
+59180 51122 lineto
+59254 50981 lineto
+59255 50976 lineto
+59257 50973 lineto
+59283 50882 lineto
+59300 50828 lineto
+59300 50827 lineto
+59302 50820 lineto
+59310 50726 lineto
+59316 50670 lineto
+59316 50662 lineto
+59316 50508 lineto
+59419 50405 lineto
+poly0
+newpath 33500 50640 moveto
+33551 50673 lineto
+33726 50744 lineto
+33912 50780 lineto
+34101 50778 lineto
+34184 50761 lineto
+34184 52829 lineto
+34088 52810 lineto
+33899 52812 lineto
+33714 52850 lineto
+33624 52888 lineto
+33621 52885 lineto
+33502 52836 lineto
+33375 52811 lineto
+32621 52811 lineto
+32558 52824 lineto
+31816 52082 lineto
+31816 50762 lineto
+31912 50780 lineto
+32101 50778 lineto
+32286 50740 lineto
+32460 50667 lineto
+32500 50640 lineto
+32551 50673 lineto
+32726 50744 lineto
+32912 50780 lineto
+33101 50778 lineto
+33286 50740 lineto
+33460 50667 lineto
+33500 50640 lineto
+poly0
+newpath 59433 53464 moveto
+59503 53630 lineto
+59530 53671 lineto
+59497 53721 lineto
+59426 53896 lineto
+59390 54082 lineto
+59392 54271 lineto
+59430 54456 lineto
+59503 54630 lineto
+59530 54671 lineto
+59497 54721 lineto
+59426 54896 lineto
+59390 55082 lineto
+59392 55271 lineto
+59430 55456 lineto
+59503 55630 lineto
+59530 55671 lineto
+59497 55721 lineto
+59426 55896 lineto
+59390 56082 lineto
+59392 56271 lineto
+59430 56456 lineto
+59503 56630 lineto
+59608 56787 lineto
+59684 56863 lineto
+59684 56923 lineto
+59684 56931 lineto
+59691 56999 lineto
+59700 57081 lineto
+59701 57087 lineto
+59702 57090 lineto
+59730 57181 lineto
+59747 57233 lineto
+59748 57236 lineto
+59750 57241 lineto
+59815 57361 lineto
+59823 57374 lineto
+59823 57375 lineto
+59827 57381 lineto
+59888 57455 lineto
+59923 57497 lineto
+59929 57503 lineto
+60541 58115 lineto
+60541 58289 lineto
+60567 58415 lineto
+60617 58535 lineto
+60620 58540 lineto
+60575 58655 lineto
+60545 58812 lineto
+60075 58341 lineto
+60069 58335 lineto
+60032 58306 lineto
+59952 58240 lineto
+59811 58166 lineto
+59805 58165 lineto
+59803 58163 lineto
+59712 58137 lineto
+59658 58120 lineto
+59656 58120 lineto
+59650 58118 lineto
+59555 58110 lineto
+59500 58104 lineto
+59492 58104 lineto
+55837 58104 lineto
+55812 58079 lineto
+55958 58017 lineto
+56114 57912 lineto
+56246 57778 lineto
+56350 57622 lineto
+56421 57448 lineto
+56458 57264 lineto
+56455 57049 lineto
+56413 56866 lineto
+56337 56695 lineto
+56229 56541 lineto
+56093 56412 lineto
+55934 56311 lineto
+55759 56243 lineto
+55574 56210 lineto
+55386 56214 lineto
+55203 56254 lineto
+55030 56330 lineto
+54876 56437 lineto
+54746 56572 lineto
+54644 56730 lineto
+54593 56860 lineto
+54066 56332 lineto
+54066 54390 lineto
+54425 54749 lineto
+54431 54755 lineto
+54467 54785 lineto
+54548 54850 lineto
+54689 54924 lineto
+54694 54926 lineto
+54697 54927 lineto
+54787 54954 lineto
+54842 54970 lineto
+54843 54971 lineto
+54850 54972 lineto
+54943 54981 lineto
+55000 54986 lineto
+55008 54986 lineto
+56408 54986 lineto
+56390 55082 lineto
+56392 55271 lineto
+56430 55456 lineto
+56503 55630 lineto
+56530 55671 lineto
+56497 55721 lineto
+56426 55896 lineto
+56390 56082 lineto
+56392 56271 lineto
+56430 56456 lineto
+56503 56630 lineto
+56608 56787 lineto
+56742 56920 lineto
+56900 57025 lineto
+57075 57097 lineto
+57260 57134 lineto
+57563 57135 lineto
+57753 57133 lineto
+57937 57093 lineto
+58111 57019 lineto
+58267 56912 lineto
+58400 56777 lineto
+58503 56619 lineto
+58574 56444 lineto
+58610 56258 lineto
+58608 56069 lineto
+58570 55884 lineto
+58497 55710 lineto
+58469 55670 lineto
+58503 55619 lineto
+58574 55444 lineto
+58610 55258 lineto
+58608 55069 lineto
+58570 54884 lineto
+58497 54710 lineto
+58469 54670 lineto
+58503 54619 lineto
+58574 54444 lineto
+58610 54258 lineto
+58608 54069 lineto
+58570 53884 lineto
+58497 53710 lineto
+58469 53670 lineto
+58503 53619 lineto
+58556 53486 lineto
+59253 53486 lineto
+59261 53486 lineto
+59328 53479 lineto
+59411 53470 lineto
+59416 53469 lineto
+59420 53468 lineto
+59433 53464 lineto
+poly0
+ 1 setgray
+50 setlinewidth
+newpath 32000 51170 159 0 360 arc fill stroke
+newpath 26000 51170 159 0 360 arc fill stroke
+400 setlinewidth
+71610 30170 72390 30170 line
+71610 32570 72390 32570 line
+74000 30680 74000 31460 line
+65610 30170 66390 30170 line
+65610 32570 66390 32570 line
+68000 30680 68000 31460 line
+50 setlinewidth
+newpath 61850 63920 472 0 360 arc fill stroke
+newpath 55650 63920 472 0 360 arc fill stroke
+newpath 58950 63680 160 0 360 arc fill stroke
+newpath 58150 63680 160 0 360 arc fill stroke
+newpath 59750 63680 160 0 360 arc fill stroke
+newpath 58550 62680 160 0 360 arc fill stroke
+newpath 57750 62680 160 0 360 arc fill stroke
+newpath 59350 62680 160 0 360 arc fill stroke
+newpath 53600 63920 472 0 360 arc fill stroke
+newpath 47400 63920 472 0 360 arc fill stroke
+newpath 50700 63680 160 0 360 arc fill stroke
+newpath 49900 63680 160 0 360 arc fill stroke
+newpath 51500 63680 160 0 360 arc fill stroke
+newpath 50300 62680 160 0 360 arc fill stroke
+newpath 49500 62680 160 0 360 arc fill stroke
+newpath 51100 62680 160 0 360 arc fill stroke
+newpath 45350 63920 472 0 360 arc fill stroke
+newpath 39150 63920 472 0 360 arc fill stroke
+newpath 42450 63680 160 0 360 arc fill stroke
+newpath 41650 63680 160 0 360 arc fill stroke
+newpath 43250 63680 160 0 360 arc fill stroke
+newpath 42050 62680 160 0 360 arc fill stroke
+newpath 41250 62680 160 0 360 arc fill stroke
+newpath 42850 62680 160 0 360 arc fill stroke
+newpath 37100 63920 472 0 360 arc fill stroke
+newpath 30900 63920 472 0 360 arc fill stroke
+newpath 34200 63680 160 0 360 arc fill stroke
+newpath 33400 63680 160 0 360 arc fill stroke
+newpath 35000 63680 160 0 360 arc fill stroke
+newpath 33800 62680 160 0 360 arc fill stroke
+newpath 33000 62680 160 0 360 arc fill stroke
+newpath 34600 62680 160 0 360 arc fill stroke
+newpath 28850 63920 472 0 360 arc fill stroke
+newpath 22650 63920 472 0 360 arc fill stroke
+newpath 25950 63680 160 0 360 arc fill stroke
+newpath 25150 63680 160 0 360 arc fill stroke
+newpath 26750 63680 160 0 360 arc fill stroke
+newpath 25550 62680 160 0 360 arc fill stroke
+newpath 24750 62680 160 0 360 arc fill stroke
+newpath 26350 62680 160 0 360 arc fill stroke
+newpath 22650 29420 472 0 360 arc fill stroke
+newpath 28850 29420 472 0 360 arc fill stroke
+newpath 25550 29660 160 0 360 arc fill stroke
+newpath 26350 29660 160 0 360 arc fill stroke
+newpath 24750 29660 160 0 360 arc fill stroke
+newpath 25950 30660 160 0 360 arc fill stroke
+newpath 26750 30660 160 0 360 arc fill stroke
+newpath 25150 30660 160 0 360 arc fill stroke
+newpath 30900 29420 472 0 360 arc fill stroke
+newpath 37100 29420 472 0 360 arc fill stroke
+newpath 33800 29660 160 0 360 arc fill stroke
+newpath 34600 29660 160 0 360 arc fill stroke
+newpath 33000 29660 160 0 360 arc fill stroke
+newpath 34200 30660 160 0 360 arc fill stroke
+newpath 35000 30660 160 0 360 arc fill stroke
+newpath 33400 30660 160 0 360 arc fill stroke
+newpath 39150 29420 472 0 360 arc fill stroke
+newpath 45350 29420 472 0 360 arc fill stroke
+newpath 42050 29660 160 0 360 arc fill stroke
+newpath 42850 29660 160 0 360 arc fill stroke
+newpath 41250 29660 160 0 360 arc fill stroke
+newpath 42450 30660 160 0 360 arc fill stroke
+newpath 43250 30660 160 0 360 arc fill stroke
+newpath 41650 30660 160 0 360 arc fill stroke
+newpath 47400 29420 472 0 360 arc fill stroke
+newpath 53600 29420 472 0 360 arc fill stroke
+newpath 50300 29660 160 0 360 arc fill stroke
+newpath 51100 29660 160 0 360 arc fill stroke
+newpath 49500 29660 160 0 360 arc fill stroke
+newpath 50700 30660 160 0 360 arc fill stroke
+newpath 51500 30660 160 0 360 arc fill stroke
+newpath 49900 30660 160 0 360 arc fill stroke
+newpath 55650 29420 472 0 360 arc fill stroke
+newpath 61850 29420 472 0 360 arc fill stroke
+newpath 58550 29660 160 0 360 arc fill stroke
+newpath 59350 29660 160 0 360 arc fill stroke
+newpath 57750 29660 160 0 360 arc fill stroke
+newpath 58950 30660 160 0 360 arc fill stroke
+newpath 59750 30660 160 0 360 arc fill stroke
+newpath 58150 30660 160 0 360 arc fill stroke
+newpath 66500 51170 160 0 360 arc fill stroke
+newpath 65500 51170 160 0 360 arc fill stroke
+newpath 66500 53170 160 0 360 arc fill stroke
+newpath 65500 53170 160 0 360 arc fill stroke
+newpath 63000 53170 160 0 360 arc fill stroke
+newpath 63000 55170 160 0 360 arc fill stroke
+newpath 71500 64420 160 0 360 arc fill stroke
+newpath 72500 64420 160 0 360 arc fill stroke
+newpath 65500 60320 160 0 360 arc fill stroke
+newpath 66500 60320 160 0 360 arc fill stroke
+newpath 66500 61107 160 0 360 arc fill stroke
+newpath 65500 61107 160 0 360 arc fill stroke
+newpath 63638 62170 453 0 360 arc fill stroke
+newpath 68362 62170 453 0 360 arc fill stroke
+newpath 33000 53920 160 0 360 arc fill stroke
+newpath 34000 53920 160 0 360 arc fill stroke
+newpath 35000 53920 160 0 360 arc fill stroke
+newpath 36000 53920 160 0 360 arc fill stroke
+newpath 37000 53920 160 0 360 arc fill stroke
+newpath 38000 53920 160 0 360 arc fill stroke
+newpath 39000 53920 160 0 360 arc fill stroke
+newpath 40000 53920 160 0 360 arc fill stroke
+newpath 41000 53920 160 0 360 arc fill stroke
+newpath 41000 56920 160 0 360 arc fill stroke
+newpath 40000 56920 160 0 360 arc fill stroke
+newpath 39000 56920 160 0 360 arc fill stroke
+newpath 38000 56920 160 0 360 arc fill stroke
+newpath 37000 56920 160 0 360 arc fill stroke
+newpath 36000 56920 160 0 360 arc fill stroke
+newpath 35000 56920 160 0 360 arc fill stroke
+newpath 34000 56920 160 0 360 arc fill stroke
+newpath 33000 56920 160 0 360 arc fill stroke
+newpath 39000 39420 160 0 360 arc fill stroke
+newpath 38000 39420 160 0 360 arc fill stroke
+newpath 37000 39420 160 0 360 arc fill stroke
+newpath 36000 39420 160 0 360 arc fill stroke
+newpath 35000 39420 160 0 360 arc fill stroke
+newpath 34000 39420 160 0 360 arc fill stroke
+newpath 33000 39420 160 0 360 arc fill stroke
+newpath 32000 39420 160 0 360 arc fill stroke
+newpath 31000 39420 160 0 360 arc fill stroke
+newpath 31000 36420 160 0 360 arc fill stroke
+newpath 32000 36420 160 0 360 arc fill stroke
+newpath 33000 36420 160 0 360 arc fill stroke
+newpath 34000 36420 160 0 360 arc fill stroke
+newpath 35000 36420 160 0 360 arc fill stroke
+newpath 36000 36420 160 0 360 arc fill stroke
+newpath 37000 36420 160 0 360 arc fill stroke
+newpath 38000 36420 160 0 360 arc fill stroke
+newpath 39000 36420 160 0 360 arc fill stroke
+newpath 50000 39420 160 0 360 arc fill stroke
+newpath 49000 39420 160 0 360 arc fill stroke
+newpath 48000 39420 160 0 360 arc fill stroke
+newpath 47000 39420 160 0 360 arc fill stroke
+newpath 46000 39420 160 0 360 arc fill stroke
+newpath 45000 39420 160 0 360 arc fill stroke
+newpath 44000 39420 160 0 360 arc fill stroke
+newpath 43000 39420 160 0 360 arc fill stroke
+newpath 42000 39420 160 0 360 arc fill stroke
+newpath 42000 36420 160 0 360 arc fill stroke
+newpath 43000 36420 160 0 360 arc fill stroke
+newpath 44000 36420 160 0 360 arc fill stroke
+newpath 45000 36420 160 0 360 arc fill stroke
+newpath 46000 36420 160 0 360 arc fill stroke
+newpath 47000 36420 160 0 360 arc fill stroke
+newpath 48000 36420 160 0 360 arc fill stroke
+newpath 49000 36420 160 0 360 arc fill stroke
+newpath 50000 36420 160 0 360 arc fill stroke
+newpath 44000 53920 160 0 360 arc fill stroke
+newpath 45000 53920 160 0 360 arc fill stroke
+newpath 46000 53920 160 0 360 arc fill stroke
+newpath 47000 53920 160 0 360 arc fill stroke
+newpath 48000 53920 160 0 360 arc fill stroke
+newpath 49000 53920 160 0 360 arc fill stroke
+newpath 50000 53920 160 0 360 arc fill stroke
+newpath 51000 53920 160 0 360 arc fill stroke
+newpath 52000 53920 160 0 360 arc fill stroke
+newpath 52000 56920 160 0 360 arc fill stroke
+newpath 51000 56920 160 0 360 arc fill stroke
+newpath 50000 56920 160 0 360 arc fill stroke
+newpath 49000 56920 160 0 360 arc fill stroke
+newpath 48000 56920 160 0 360 arc fill stroke
+newpath 47000 56920 160 0 360 arc fill stroke
+newpath 46000 56920 160 0 360 arc fill stroke
+newpath 45000 56920 160 0 360 arc fill stroke
+newpath 44000 56920 160 0 360 arc fill stroke
+newpath 62500 32670 159 0 360 arc fill stroke
+newpath 62500 33670 159 0 360 arc fill stroke
+newpath 53000 37420 159 0 360 arc fill stroke
+newpath 54000 37420 159 0 360 arc fill stroke
+newpath 55000 38420 159 0 360 arc fill stroke
+newpath 53000 38420 159 0 360 arc fill stroke
+newpath 62500 34670 159 0 360 arc fill stroke
+newpath 70250 53170 160 0 360 arc fill stroke
+newpath 71250 53170 160 0 360 arc fill stroke
+newpath 54000 38420 159 0 360 arc fill stroke
+newpath 61500 41170 160 0 360 arc fill stroke
+newpath 61500 40170 160 0 360 arc fill stroke
+newpath 62500 40170 160 0 360 arc fill stroke
+newpath 72000 35670 160 0 360 arc fill stroke
+newpath 73000 35670 160 0 360 arc fill stroke
+newpath 75500 41170 600 0 360 arc fill stroke
+newpath 69000 42170 225 0 360 arc fill stroke
+newpath 69000 41170 225 0 360 arc fill stroke
+newpath 69000 40170 225 0 360 arc fill stroke
+newpath 51000 49670 160 0 360 arc fill stroke
+newpath 50000 49670 160 0 360 arc fill stroke
+newpath 49000 49670 160 0 360 arc fill stroke
+newpath 48000 49670 160 0 360 arc fill stroke
+newpath 47000 49670 160 0 360 arc fill stroke
+newpath 46000 49670 160 0 360 arc fill stroke
+newpath 45000 49670 160 0 360 arc fill stroke
+newpath 44000 49670 160 0 360 arc fill stroke
+newpath 43000 49670 160 0 360 arc fill stroke
+newpath 42000 49670 160 0 360 arc fill stroke
+newpath 41000 49670 160 0 360 arc fill stroke
+newpath 40000 49670 160 0 360 arc fill stroke
+newpath 39000 49670 160 0 360 arc fill stroke
+newpath 38000 49670 160 0 360 arc fill stroke
+newpath 37000 49670 160 0 360 arc fill stroke
+newpath 36000 49670 160 0 360 arc fill stroke
+newpath 35000 49670 160 0 360 arc fill stroke
+newpath 34000 49670 160 0 360 arc fill stroke
+newpath 33000 49670 160 0 360 arc fill stroke
+newpath 32000 49670 160 0 360 arc fill stroke
+newpath 32000 43670 160 0 360 arc fill stroke
+newpath 33000 43670 160 0 360 arc fill stroke
+newpath 34000 43670 160 0 360 arc fill stroke
+newpath 35000 43670 160 0 360 arc fill stroke
+newpath 36000 43670 160 0 360 arc fill stroke
+newpath 37000 43670 160 0 360 arc fill stroke
+newpath 38000 43670 160 0 360 arc fill stroke
+newpath 39000 43670 160 0 360 arc fill stroke
+newpath 40000 43670 160 0 360 arc fill stroke
+newpath 41000 43670 160 0 360 arc fill stroke
+newpath 42000 43670 160 0 360 arc fill stroke
+newpath 43000 43670 160 0 360 arc fill stroke
+newpath 44000 43670 160 0 360 arc fill stroke
+newpath 45000 43670 160 0 360 arc fill stroke
+newpath 46000 43670 160 0 360 arc fill stroke
+newpath 47000 43670 160 0 360 arc fill stroke
+newpath 48000 43670 160 0 360 arc fill stroke
+newpath 49000 43670 160 0 360 arc fill stroke
+newpath 50000 43670 160 0 360 arc fill stroke
+newpath 51000 43670 160 0 360 arc fill stroke
+newpath 19370 62631 600 0 360 arc fill stroke
+newpath 19370 30741 600 0 360 arc fill stroke
+newpath 78425 62631 600 0 360 arc fill stroke
+newpath 78425 30741 600 0 360 arc fill stroke
+newpath 51000 42170 160 0 360 arc fill stroke
+newpath 51000 41170 160 0 360 arc fill stroke
+newpath 63000 49170 160 0 360 arc fill stroke
+newpath 63000 50170 160 0 360 arc fill stroke
+newpath 65500 58170 160 0 360 arc fill stroke
+newpath 64500 58170 160 0 360 arc fill stroke
+newpath 68750 35670 160 0 360 arc fill stroke
+newpath 68750 36670 160 0 360 arc fill stroke
+newpath 63250 37670 200 0 360 arc fill stroke
+newpath 59250 37670 200 0 360 arc fill stroke
+newpath 71250 47670 200 0 360 arc fill stroke
+newpath 67250 47670 200 0 360 arc fill stroke
+newpath 71250 46170 200 0 360 arc fill stroke
+newpath 67250 46170 200 0 360 arc fill stroke
+newpath 55500 53170 160 0 360 arc fill stroke
+newpath 55500 57170 160 0 360 arc fill stroke
+newpath 55500 43920 160 0 360 arc fill stroke
+newpath 55500 39920 160 0 360 arc fill stroke
+newpath 57750 41170 160 0 360 arc fill stroke
+newpath 57750 37170 160 0 360 arc fill stroke
+newpath 68000 38920 160 0 360 arc fill stroke
+newpath 64000 38920 160 0 360 arc fill stroke
+newpath 63250 36170 160 0 360 arc fill stroke
+newpath 59250 36170 160 0 360 arc fill stroke
+newpath 53250 45670 160 0 360 arc fill stroke
+newpath 53250 49670 160 0 360 arc fill stroke
+newpath 66000 44670 160 0 360 arc fill stroke
+newpath 62000 44670 160 0 360 arc fill stroke
+newpath 66000 46170 160 0 360 arc fill stroke
+newpath 62000 46170 160 0 360 arc fill stroke
+newpath 66000 47670 160 0 360 arc fill stroke
+newpath 62000 47670 160 0 360 arc fill stroke
+newpath 54500 49670 160 0 360 arc fill stroke
+newpath 54500 45670 160 0 360 arc fill stroke
+newpath 60500 44170 160 0 360 arc fill stroke
+newpath 60500 45170 160 0 360 arc fill stroke
+newpath 60500 46170 160 0 360 arc fill stroke
+newpath 60500 47170 160 0 360 arc fill stroke
+newpath 60500 48170 160 0 360 arc fill stroke
+newpath 60500 49170 160 0 360 arc fill stroke
+newpath 60500 50170 160 0 360 arc fill stroke
+newpath 60500 51170 160 0 360 arc fill stroke
+newpath 60500 52170 160 0 360 arc fill stroke
+newpath 60500 53170 160 0 360 arc fill stroke
+newpath 60500 54170 160 0 360 arc fill stroke
+newpath 60500 55170 160 0 360 arc fill stroke
+newpath 60500 56170 160 0 360 arc fill stroke
+newpath 60500 43170 160 0 360 arc fill stroke
+newpath 57500 56170 160 0 360 arc fill stroke
+newpath 57500 55170 160 0 360 arc fill stroke
+newpath 57500 54170 160 0 360 arc fill stroke
+newpath 57500 53170 160 0 360 arc fill stroke
+newpath 57500 52170 160 0 360 arc fill stroke
+newpath 57500 51170 160 0 360 arc fill stroke
+newpath 57500 50170 160 0 360 arc fill stroke
+newpath 57500 49170 160 0 360 arc fill stroke
+newpath 57500 48170 160 0 360 arc fill stroke
+newpath 57500 47170 160 0 360 arc fill stroke
+newpath 57500 46170 160 0 360 arc fill stroke
+newpath 57500 45170 160 0 360 arc fill stroke
+newpath 57500 44170 160 0 360 arc fill stroke
+newpath 57500 43170 160 0 360 arc fill stroke
+newpath 61500 57920 200 0 360 arc fill stroke
+newpath 61500 58920 200 0 360 arc fill stroke
+newpath 70500 56170 160 0 360 arc fill stroke
+newpath 65500 56170 160 0 360 arc fill stroke
+ 0 setgray
+showpage
+grestore
+%%EOF
diff --git a/kicad/10ch_pwm_ctrl.brd b/kicad/10ch_pwm_ctrl.brd
new file mode 100644
index 0000000..c7e6f91
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.brd
@@ -0,0 +1,9112 @@
+PCBNEW-BOARD Version 1 date 09/02/2010 13:07:24
+
+$GENERAL
+LayerCount 2
+Ly 1FFF8001
+Links 169
+NoConn 0
+Di 17326 15325 80470 55745
+Ndraw 6
+Ntrack 578
+Nzone 857
+Nmodule 58
+Nnets 89
+$EndGENERAL
+
+$SHEETDESCR
+Sheet A4 11700 8267
+Title "DF10CH Atmolight Controller"
+Date "9 feb 2010"
+Rev "3"
+Comp "Copyright Andreas Auras"
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndSHEETDESCR
+
+$SETUP
+InternalUnit 0.000100 INCH
+ZoneGridSize 39
+Layers 2
+Layer[0] Lötseite signal
+Layer[15] Bestückungsseite signal
+TrackWidth 500
+TrackWidthHistory 500
+TrackClearence 100
+ZoneClearence 500
+DrawSegmWidth 150
+EdgeSegmWidth 150
+ViaSize 1000
+ViaDrill 319
+ViaAltDrill 250
+ViaSizeHistory 1000
+MicroViaSize 200
+MicroViaDrill 80
+MicroViasAllowed 0
+TextPcbWidth 120
+TextPcbSize 600 800
+EdgeModWidth 150
+TextModSize 600 600
+TextModWidth 120
+PadSize 1890 1890
+PadDrill 1181
+AuxiliaryAxisOrg 17402 16299
+$EndSETUP
+
+$EQUIPOT
+Na 0 ""
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 1 "GND"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 2 "VDD"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 3 "N-000017"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 4 "/RGB_COMMON"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 5 "N-000016"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 6 "N-000018"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 7 "N-000076"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 8 "N-000078"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 9 "N-000015"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 10 "N-000014"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 11 "N-000075"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 12 "N-000013"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 13 "N-000019"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 14 "N-000012"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 15 "N-000079"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 16 "N-000010"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 17 "N-000080"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 18 "N-000011"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 19 "N-000047"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 20 "N-000046"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 21 "N-000020"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 22 "N-000021"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 23 "N-000043"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 24 "N-000074"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 25 "N-000022"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 26 "N-000073"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 27 "N-000023"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 28 "N-000072"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 29 "N-000045"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 30 "N-000024"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 31 "N-000025"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 32 "N-000044"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 33 "N-000026"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 34 "N-000086"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 35 "N-000085"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 36 "N-000082"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 37 "N-000034"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 38 "N-000038"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 39 "N-000039"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 40 "/PC0"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 41 "/PD7"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 42 "/PD6"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 43 "/PD5"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 44 "/PD4"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 45 "/PD3"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 46 "/PD2"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 47 "N-000041"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 48 "N-000042"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 49 "/PC7"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 50 "/PC6"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 51 "/PC5"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 52 "/PC4"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 53 "/PC3"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 54 "/PC2"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 55 "/PC1"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 56 "/PA0"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 57 "/PA1"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 58 "/PA2"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 59 "/PA3"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 60 "/PA4"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 61 "/PA5"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 62 "/PA6"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 63 "/PA7"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 64 "/PB7"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 65 "/PB6"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 66 "/PB5"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 67 "/PB4"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 68 "/PB3"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 69 "/PB2"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 70 "/PB1"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 71 "/PB0"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 72 "N-000040"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 73 "+5V"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 74 "N-000048"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 75 "N-000035"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 76 "N-000049"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 77 "N-000004"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 78 "N-000084"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 79 "N-000005"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 80 "N-000006"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 81 "N-000003"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 82 "N-000087"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 83 "N-000036"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 84 "N-000083"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 85 "N-000008"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 86 "N-000037"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 87 "N-000002"
+St ~
+$EndEQUIPOT
+$EQUIPOT
+Na 88 "N-000088"
+St ~
+$EndEQUIPOT
+$MODULE JACK_ALIM
+Po 72000 52500 900 15 4B6C05CB 4B23442B ~~
+Li JACK_ALIM
+Cd module 1 pin (ou trou mecanique de percage)
+Kw CONN JACK
+Sc 4B23442B
+AR /4B23442B
+Op 0 0 0
+T0 100 -2200 400 400 900 120 N V 21 N"J2"
+T1 -2000 2200 400 400 900 120 N V 21 N"PWR/OUT"
+DS -2800 -1700 -3100 -1700 150 21
+DS -3100 -1700 -3100 1700 150 21
+DS -3100 1700 -2800 1700 150 21
+DS -1600 -1700 -1600 1700 150 21
+DS 2200 -1700 2200 1700 150 21
+DS -2800 1700 2200 1700 150 21
+DS -2800 -1700 2200 -1700 150 21
+$PAD
+Sh "3" C 1890 1890 0 0 900
+Dr 400 0 0 O 400 1181
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 0 0
+$EndPAD
+$PAD
+Sh "1" R 1890 1890 0 0 900
+Dr 400 0 0 O 400 1181
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po 2400 0
+$EndPAD
+$PAD
+Sh "2" C 1890 1890 0 0 900
+Dr 1181 0 0 O 1181 400
+At STD N 00E0FFFF
+Ne 0 ""
+Po 900 2000
+$EndPAD
+$SHAPE3D
+Na "connectors/POWER_21.wrl"
+Sc 0.800000 0.800000 0.800000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE JACK_ALIM
+$MODULE JACK_ALIM
+Po 66000 52500 900 15 4B6C05A9 4B2344C0 ~~
+Li JACK_ALIM
+Cd module 1 pin (ou trou mecanique de percage)
+Kw CONN JACK
+Sc 4B2344C0
+AR /4B2344C0
+Op 0 0 0
+T0 100 -2200 400 400 900 120 N V 21 N"J1"
+T1 -2000 2200 400 400 900 120 N V 21 N"PWR/IN"
+DS -2800 -1700 -3100 -1700 150 21
+DS -3100 -1700 -3100 1700 150 21
+DS -3100 1700 -2800 1700 150 21
+DS -1600 -1700 -1600 1700 150 21
+DS 2200 -1700 2200 1700 150 21
+DS -2800 1700 2200 1700 150 21
+DS -2800 -1700 2200 -1700 150 21
+$PAD
+Sh "3" C 1890 1890 0 0 900
+Dr 400 0 0 O 400 1181
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 0 0
+$EndPAD
+$PAD
+Sh "1" R 1890 1890 0 0 900
+Dr 400 0 0 O 400 1181
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po 2400 0
+$EndPAD
+$PAD
+Sh "2" C 1890 1890 0 0 900
+Dr 1181 0 0 O 1181 400
+At STD N 00E0FFFF
+Ne 0 ""
+Po 900 2000
+$EndPAD
+$SHAPE3D
+Na "connectors/POWER_21.wrl"
+Sc 0.800000 0.800000 0.800000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE JACK_ALIM
+$MODULE MEBP6-4
+Po 58750 18750 1800 15 4B6BF12B 4B232EF3 ~~
+Li MEBP6-4
+Sc 4B232EF3
+AR /4B232EF3
+Op 0 0 0
+T0 -1250 -2000 600 600 1800 120 N V 21 N"J12"
+T1 100 850 600 600 1800 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 3 "N-000017"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 3 "N-000017"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 5 "N-000016"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 6 "N-000018"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 50500 18750 1800 15 4B6BF114 4B232EF2 ~~
+Li MEBP6-4
+Sc 4B232EF2
+AR /4B232EF2
+Op 0 0 0
+T0 -1250 -2000 600 600 1800 120 N V 21 N"J11"
+T1 100 850 600 600 1800 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 7 "N-000076"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 7 "N-000076"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 8 "N-000078"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 9 "N-000015"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 42250 18750 1800 15 4B6BF0FD 4B232EF1 ~~
+Li MEBP6-4
+Sc 4B232EF1
+AR /4B232EF1
+Op 0 0 0
+T0 -1250 -2000 600 600 1800 120 N V 21 N"J10"
+T1 100 850 600 600 1800 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 10 "N-000014"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 10 "N-000014"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 11 "N-000075"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 12 "N-000013"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 34000 18750 1800 15 4B6BF0E2 4B232EF0 ~~
+Li MEBP6-4
+Sc 4B232EF0
+AR /4B232EF0
+Op 0 0 0
+T0 -1500 -2000 600 600 1800 120 N V 21 N"J9"
+T1 100 850 600 600 1800 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 13 "N-000019"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 13 "N-000019"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 14 "N-000012"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 15 "N-000079"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 25750 18750 1800 15 4B6BF0CC 4B232EEF ~~
+Li MEBP6-4
+Sc 4B232EEF
+AR /4B232EEF
+Op 0 0 0
+T0 -1500 -2000 600 600 1800 120 N V 21 N"J8"
+T1 100 850 600 600 1800 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 1800
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 16 "N-000010"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 16 "N-000010"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 17 "N-000080"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00000001
+Ne 18 "N-000011"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 25750 53250 0 15 4B6BF0B7 4B232860 ~~
+Li MEBP6-4
+Sc 4B232860
+AR /4B232860
+Op 0 0 0
+T0 1500 -2000 600 600 0 120 N V 21 N"J7"
+T1 100 850 600 600 0 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 19 "N-000047"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 19 "N-000047"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 20 "N-000046"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 21 "N-000020"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 34000 53250 0 15 4B6BF09E 4B232858 ~~
+Li MEBP6-4
+Sc 4B232858
+AR /4B232858
+Op 0 0 0
+T0 1500 -2000 600 600 0 120 N V 21 N"J6"
+T1 100 850 600 600 0 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 22 "N-000021"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 22 "N-000021"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 23 "N-000043"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 24 "N-000074"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE MEBP6-4
+Po 42250 53250 0 15 4B6BF082 4B232850 ~~
+Li MEBP6-4
+Sc 4B232850
+AR /4B232850
+Op 0 0 0
+T0 1500 -2000 600 600 0 120 N V 21 N"J5"
+T1 100 850 600 600 0 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 25 "N-000022"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 25 "N-000022"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 26 "N-000073"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 27 "N-000023"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE J4
+Po 50500 53250 0 15 4B6BF066 4B232846 ~~
+Li J4
+Sc 4B232846
+AR /4B232846
+Op 0 0 0
+T0 1500 -2000 600 600 0 120 N V 21 N"J4"
+T1 100 850 600 600 0 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 28 "N-000072"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 28 "N-000072"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 29 "N-000045"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 30 "N-000024"
+Po -600 -1240
+$EndPAD
+$EndMODULE J4
+$MODULE MEBP6-4
+Po 58750 53250 0 15 4B6BF01C 4B232825 ~~
+Li MEBP6-4
+Sc 4B232825
+AR /4B232825
+Op 0 0 0
+T0 1500 -2000 600 600 0 120 N V 21 N"J3"
+T1 100 850 600 600 0 120 N V 21 N"RJ11"
+DS -200 -2550 -200 -3350 150 21
+DS -200 -3350 200 -3350 150 21
+DS 200 -3350 200 -2550 150 21
+DS -2000 2250 -2000 1400 150 21
+DS -2000 1400 2000 1400 150 21
+DS 2000 1400 2000 2250 150 21
+DS 0 2250 2400 2250 150 21
+DS 2400 2250 2400 -2550 150 21
+DS 2400 -2550 -2400 -2550 150 21
+DS -2400 -2550 -2400 2250 150 21
+DS -2400 2250 0 2250 150 21
+$PAD
+Sh "7" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3100 0
+$EndPAD
+$PAD
+Sh "8" C 1000 1000 0 0 0
+Dr 945 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3100 0
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 31 "N-000025"
+Po -200 -240
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 600 -240
+$EndPAD
+$PAD
+Sh "1" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 31 "N-000025"
+Po -1000 -240
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 32 "N-000044"
+Po 200 -1240
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 4 "/RGB_COMMON"
+Po 1000 -1240
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00000001
+Ne 33 "N-000026"
+Po -600 -1240
+$EndPAD
+$EndMODULE MEBP6-4
+$MODULE C1
+Po 66000 31500 1800 15 3F92C496 4B234854 ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B234854
+AR /4B234854
+Op 0 0 0
+T0 100 -900 400 400 1800 80 N V 21 N"C1"
+T1 0 -900 400 400 1800 80 N I 21 N"47p"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 34 "N-000086"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE C1
+Po 66000 29500 1800 15 3F92C496 4B2347F4 ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2347F4
+AR /4B2347F4
+Op 0 0 0
+T0 100 -900 400 400 1800 80 N V 21 N"C2"
+T1 0 -900 400 400 1800 80 N I 21 N"47p"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 35 "N-000085"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE HC-18UV
+Po 63000 28500 900 15 42899E71 4B2347D4 ~~
+Li HC-18UV
+Cd Quartz boitier HC-18U vertical
+Kw QUARTZ DEV
+Sc 4B2347D4
+AR /4B2347D4
+Op 0 A 0
+T0 -50 -700 450 500 900 60 N V 21 N"X1"
+T1 0 650 450 500 900 60 N V 21 N"16Mhz"
+DS -2750 -500 -2250 -1000 60 21
+DS 2250 -1000 2750 -500 60 21
+DS 2750 500 2250 1000 60 21
+DS -2750 500 -2250 1000 60 21
+DS -2250 -1000 2250 -1000 60 21
+DS -2750 -500 -2750 500 60 21
+DS -2250 1000 2250 1000 60 21
+DS 2750 500 2750 -500 60 21
+$PAD
+Sh "1" C 700 700 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 34 "N-000086"
+Po -1000 0
+$EndPAD
+$PAD
+Sh "2" C 700 700 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 35 "N-000085"
+Po 1000 0
+$EndPAD
+$SHAPE3D
+Na "discret/crystal_hc18u_vertical.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE HC-18UV
+$MODULE LED-3MM
+Po 72000 18250 0 15 49BFA23B 4B233E78 ~~
+Li LED-3MM
+Cd LED 3mm - Lead pitch 100mil (2,54mm)
+Kw LED led 3mm 3MM 100mil 2,54mm
+Sc 4B233E78
+AR /4B233E78
+Op 0 0 0
+At VIRTUAL
+T0 700 -1100 300 300 0 35 N V 21 N"D2"
+T1 0 1000 300 300 0 35 N V 21 N"LED/2mA"
+DS 720 500 720 -500 100 21
+DA 100 0 -500 0 3998 60 21
+DA 100 0 -348 398 4016 60 21
+DA 100 0 555 -390 4006 60 21
+DA 100 0 700 0 3998 60 21
+DA 100 0 100 -600 4144 60 21
+DA 100 0 -380 -360 4131 60 21
+DA 100 0 573 368 4121 60 21
+DA 100 0 100 600 4121 60 21
+DA 100 0 -150 0 4500 60 21
+DA 100 0 -300 0 4500 60 21
+DA 100 0 350 0 4500 60 21
+DA 100 0 500 0 4500 60 21
+DA 100 0 100 -800 4101 100 21
+DA 100 0 -605 -376 4219 100 21
+DA 100 0 710 516 4097 100 21
+DA 100 0 100 800 4202 100 21
+DA 100 0 -700 0 3883 100 21
+DA 100 0 -581 419 3916 100 21
+$PAD
+Sh "1" C 660 660 0 0 0
+Dr 320 0 0
+At STD N 00A8FFFF
+Ne 36 "N-000082"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 660 660 0 0 0
+Dr 320 0 0
+At STD N 00A8FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/leds/led3_vertical_verde.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE LED-3MM
+$MODULE USB_B
+Po 66000 20500 1800 15 48A935FA 4B233F56 ~~
+Li USB_B
+Kw USB
+Sc 4B233F56
+AR /4B233F56
+Op 0 0 0
+T0 0 2500 600 600 1800 120 N V 21 N"J13"
+T1 0 0 600 600 1800 120 N V 21 N"USB"
+DS -2400 4050 2400 4050 50 21
+DS 2400 4050 2400 -2650 50 21
+DS 2400 -2650 -2400 -2650 50 21
+DS -2400 -2650 -2400 4050 50 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 37 "N-000034"
+Po 500 -1850
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 38 "N-000038"
+Po -500 -1850
+$EndPAD
+$PAD
+Sh "3" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 39 "N-000039"
+Po -500 -1063
+$EndPAD
+$PAD
+Sh "4" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 -1063
+$EndPAD
+$PAD
+Sh "5" C 1063 1063 0 0 1800
+Dr 906 0 0
+At HOLE N 00F0FFFF
+Ne 1 "GND"
+Po 2362 0
+$EndPAD
+$PAD
+Sh "6" C 1063 1063 0 0 1800
+Dr 906 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -2362 0
+$EndPAD
+$SHAPE3D
+Na "connectors/USB_type_B.wrl"
+Sc 0.393700 0.393700 0.393700
+Of 0.000000 0.000000 0.001000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE USB_B
+$MODULE DIP-18__300_ELL
+Po 37000 27250 0 15 00200000 4B232EED ~~
+Li DIP-18__300_ELL
+Cd 18 pins DIL package, elliptical pads
+Sc 4B232EED
+AR /4B232EED
+Op 0 0 0
+T0 -3000 -500 700 450 0 120 N V 21 N"IC4"
+T1 600 400 700 450 0 120 N V 21 N"ULN2803/UDN2981"
+DS -5000 -500 -4500 -500 150 21
+DS -4500 -500 -4500 500 150 21
+DS -4500 500 -5000 500 150 21
+DS -5000 -1000 5000 -1000 150 21
+DS 5000 -1000 5000 1000 150 21
+DS 5000 1000 -5000 1000 150 21
+DS -5000 1000 -5000 -1000 150 21
+$PAD
+Sh "1" R 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 40 "/PC0"
+Po -4000 1500
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 40 "/PC0"
+Po -3000 1500
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 41 "/PD7"
+Po -2000 1500
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 42 "/PD6"
+Po -1000 1500
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 43 "/PD5"
+Po 0 1500
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 44 "/PD4"
+Po 1000 1500
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 45 "/PD3"
+Po 2000 1500
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 46 "/PD2"
+Po 3000 1500
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 47 "N-000041"
+Po 4000 1500
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 48 "N-000042"
+Po 4000 -1500
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 11 "N-000075"
+Po 3000 -1500
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 13 "N-000019"
+Po 2000 -1500
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 15 "N-000079"
+Po 1000 -1500
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 14 "N-000012"
+Po 0 -1500
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 16 "N-000010"
+Po -1000 -1500
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 18 "N-000011"
+Po -2000 -1500
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 17 "N-000080"
+Po -3000 -1500
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -4000 -1500
+$EndPAD
+$SHAPE3D
+Na "dil/dil_18.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-18__300_ELL
+$MODULE DIP-18__300_ELL
+Po 35000 44750 1800 15 00200000 4769865A ~~
+Li DIP-18__300_ELL
+Cd 18 pins DIL package, elliptical pads
+Sc 4769865A
+AR /4769865A
+Op 0 0 0
+T0 -3000 -500 700 450 1800 120 N V 21 N"IC3"
+T1 600 400 700 450 1800 120 N V 21 N"ULN2803/UDN2981"
+DS -5000 -500 -4500 -500 150 21
+DS -4500 -500 -4500 500 150 21
+DS -4500 500 -5000 500 150 21
+DS -5000 -1000 5000 -1000 150 21
+DS 5000 -1000 5000 1000 150 21
+DS 5000 1000 -5000 1000 150 21
+DS -5000 1000 -5000 -1000 150 21
+$PAD
+Sh "1" R 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 49 "/PC7"
+Po -4000 1500
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 50 "/PC6"
+Po -3000 1500
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 51 "/PC5"
+Po -2000 1500
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 52 "/PC4"
+Po -1000 1500
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 53 "/PC3"
+Po 0 1500
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 54 "/PC2"
+Po 1000 1500
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 55 "/PC1"
+Po 2000 1500
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 55 "/PC1"
+Po 3000 1500
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 47 "N-000041"
+Po 4000 1500
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 48 "N-000042"
+Po 4000 -1500
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3000 -1500
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 19 "N-000047"
+Po 2000 -1500
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 21 "N-000020"
+Po 1000 -1500
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 20 "N-000046"
+Po 0 -1500
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 22 "N-000021"
+Po -1000 -1500
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 24 "N-000074"
+Po -2000 -1500
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 23 "N-000043"
+Po -3000 -1500
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 25 "N-000022"
+Po -4000 -1500
+$EndPAD
+$SHAPE3D
+Na "dil/dil_18.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-18__300_ELL
+$MODULE DIP-18__300_ELL
+Po 46000 44750 1800 15 00200000 4769864D ~~
+Li DIP-18__300_ELL
+Cd 18 pins DIL package, elliptical pads
+Sc 4769864D
+AR /4769864D
+Op 0 0 0
+T0 -3000 -500 700 450 1800 120 N V 21 N"IC2"
+T1 600 400 700 450 1800 120 N V 21 N"ULN2803/UDN2981"
+DS -5000 -500 -4500 -500 150 21
+DS -4500 -500 -4500 500 150 21
+DS -4500 500 -5000 500 150 21
+DS -5000 -1000 5000 -1000 150 21
+DS 5000 -1000 5000 1000 150 21
+DS 5000 1000 -5000 1000 150 21
+DS -5000 1000 -5000 -1000 150 21
+$PAD
+Sh "1" R 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 56 "/PA0"
+Po -4000 1500
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 57 "/PA1"
+Po -3000 1500
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 58 "/PA2"
+Po -2000 1500
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 59 "/PA3"
+Po -1000 1500
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 60 "/PA4"
+Po 0 1500
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 61 "/PA5"
+Po 1000 1500
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 62 "/PA6"
+Po 2000 1500
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 63 "/PA7"
+Po 3000 1500
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 47 "N-000041"
+Po 4000 1500
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 48 "N-000042"
+Po 4000 -1500
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 27 "N-000023"
+Po 3000 -1500
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 26 "N-000073"
+Po 2000 -1500
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 28 "N-000072"
+Po 1000 -1500
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 30 "N-000024"
+Po 0 -1500
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 29 "N-000045"
+Po -1000 -1500
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 31 "N-000025"
+Po -2000 -1500
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 33 "N-000026"
+Po -3000 -1500
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 32 "N-000044"
+Po -4000 -1500
+$EndPAD
+$SHAPE3D
+Na "dil/dil_18.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-18__300_ELL
+$MODULE DIP-18__300_ELL
+Po 48000 27250 0 15 00200000 4B232EEE ~~
+Li DIP-18__300_ELL
+Cd 18 pins DIL package, elliptical pads
+Sc 4B232EEE
+AR /4B232EEE
+Op 0 0 0
+T0 -3000 -500 700 450 0 120 N V 21 N"IC5"
+T1 600 400 700 450 0 120 N V 21 N"ULN2803/UDN2981"
+DS -5000 -500 -4500 -500 150 21
+DS -4500 -500 -4500 500 150 21
+DS -4500 500 -5000 500 150 21
+DS -5000 -1000 5000 -1000 150 21
+DS 5000 -1000 5000 1000 150 21
+DS 5000 1000 -5000 1000 150 21
+DS -5000 1000 -5000 -1000 150 21
+$PAD
+Sh "1" R 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 64 "/PB7"
+Po -4000 1500
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 65 "/PB6"
+Po -3000 1500
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 66 "/PB5"
+Po -2000 1500
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 67 "/PB4"
+Po -1000 1500
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 68 "/PB3"
+Po 0 1500
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 69 "/PB2"
+Po 1000 1500
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 70 "/PB1"
+Po 2000 1500
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 71 "/PB0"
+Po 3000 1500
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 47 "N-000041"
+Po 4000 1500
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 48 "N-000042"
+Po 4000 -1500
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 3 "N-000017"
+Po 3000 -1500
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 6 "N-000018"
+Po 2000 -1500
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 5 "N-000016"
+Po 1000 -1500
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 7 "N-000076"
+Po 0 -1500
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 9 "N-000015"
+Po -1000 -1500
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 8 "N-000078"
+Po -2000 -1500
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 10 "N-000014"
+Po -3000 -1500
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 12 "N-000013"
+Po -4000 -1500
+$EndPAD
+$SHAPE3D
+Na "dil/dil_18.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-18__300_ELL
+$MODULE PINTST
+Po 62500 50000 0 15 4B243640 4B23DD8F ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD8F
+AR /4B23DD8F
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P7"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 4 "/RGB_COMMON"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 62500 49000 0 15 4B243655 4B23DD8D ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD8D
+AR /4B23DD8D
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P6"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 53000 45250 0 15 4B24368B 4B23DD8B ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD8B
+AR /4B23DD8B
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P5"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 48 "N-000042"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 54000 45250 0 15 4B24367E 4B23DD89 ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD89
+AR /4B23DD89
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P4"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 55000 44250 0 15 4B243671 4B23DD87 ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD87
+AR /4B23DD87
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P3"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 72 "N-000040"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 53000 44250 0 15 4B243683 4B23DD80 ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD80
+AR /4B23DD80
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P2"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 47 "N-000041"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE PINTST
+Po 62500 48000 0 15 4B24365A 4B23DD91 ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD91
+AR /4B23DD91
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P8"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 72 "N-000040"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE C1V5
+Po 70750 29500 0 15 3E070CF4 4B2346D7 ~~
+Li C1V5
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2346D7
+AR /4B2346D7
+Op 0 0 0
+T0 0 -499 300 300 0 50 N V 21 N"C5"
+T1 0 500 300 250 0 50 N V 21 N"10uF"
+T2 -900 0 300 300 0 80 N V 21 N"+"
+DC 0 0 50 -1000 50 21
+$PAD
+Sh "1" R 550 550 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/c_vert_c1v5.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1V5
+$MODULE PINTST
+Po 54000 44250 0 15 4B243676 4B23DD52 ~~
+Li PINTST
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B23DD52
+AR /4B23DD52
+Op 0 0 0
+T0 0 -499 200 200 0 50 N V 21 N"P1"
+T1 0 500 200 200 0 50 N I 21 N"CONN_1"
+DC 0 0 -100 -300 50 21
+$PAD
+Sh "1" C 700 700 0 0 0
+Dr 319 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 0 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pin_array_1x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PINTST
+$MODULE TO92SGD
+Po 62000 42000 900 15 4B23DB36 4B2338BA ~~
+Li TO92SGD
+Cd Transistor TO92 brochage type BC237
+Kw TR TO92
+Sc 4B2338BA
+AR /4B2338BA
+Op 0 0 0
+T0 -500 1500 400 400 900 80 N V 21 N"Q1"
+T1 -500 -2000 400 400 900 80 N V 21 N"BS170"
+DS -500 1000 1000 -500 120 21
+DS 1000 -500 1000 -1000 120 21
+DS 1000 -1000 500 -1500 120 21
+DS 500 -1500 -500 -1500 120 21
+DS -500 -1500 -1500 -500 120 21
+DS -1500 -500 -1500 500 120 21
+DS -1500 500 -1000 1000 120 21
+DS -1000 1000 -500 1000 120 21
+$PAD
+Sh "S" R 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 -500
+$EndPAD
+$PAD
+Sh "G" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 74 "N-000048"
+Po -500 -500
+$EndPAD
+$PAD
+Sh "D" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 75 "N-000035"
+Po -500 500
+$EndPAD
+$SHAPE3D
+Na "discret/to98.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE TO92SGD
+$MODULE C1V5
+Po 72500 47000 0 15 3E070CF4 4B2447D9 ~~
+Li C1V5
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2447D9
+AR /4B2447D9
+Op 0 0 0
+T0 0 -499 300 300 0 50 N V 21 N"C8"
+T1 0 500 300 250 0 50 N V 21 N"100uF"
+T2 -900 0 300 300 0 80 N V 21 N"+"
+DC 0 0 50 -1000 50 21
+$PAD
+Sh "1" R 550 550 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 0
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/c_vert_c1v5.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1V5
+$MODULE TO220GDS
+Po 69000 41500 0 15 4469D051 4B23346A ~~
+Li TO220GDS
+Cd Transistor VMOS Irf530, TO220
+Kw TR TO220 DEV
+Sc 4B23346A
+AR /4B23346A
+Op 0 0 0
+T0 2750 0 600 400 900 80 N V 21 N"Q2"
+T1 4250 0 600 400 900 80 N V 21 N"IRF9540N"
+DS 0 -1000 2000 -1000 120 21
+DS 0 0 2000 0 120 21
+DS 0 1000 2000 1000 120 21
+DS 2000 -2000 8000 -2000 120 21
+DS 8000 -2000 8000 2000 120 21
+DS 8000 2000 2000 2000 120 21
+DS 2000 2000 2000 -2000 120 21
+DS 5000 2000 5000 -2000 120 21
+$PAD
+Sh "4" R 3500 3500 0 0 0
+Dr 1200 0 0
+At STD N 00F0FFFF
+Ne 0 ""
+Po 6500 0
+$EndPAD
+$PAD
+Sh "G" C 700 700 0 0 0
+Dr 450 0 0
+At STD N 00E0FFFF
+Ne 76 "N-000049"
+Po 0 -1000
+$EndPAD
+$PAD
+Sh "D" C 700 700 0 0 0
+Dr 450 0 0
+At STD N 00E0FFFF
+Ne 72 "N-000040"
+Po 0 0
+$EndPAD
+$PAD
+Sh "S" R 700 700 0 0 0
+Dr 450 0 0
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po 0 1000
+$EndPAD
+$SHAPE3D
+Na "discret/to220_horiz.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE TO220GDS
+$MODULE DIP-40__600_ELL
+Po 41500 36000 1800 15 00200000 47698597 ~~
+Li DIP-40__600_ELL
+Cd Module Dil 40 pins, pads elliptiques, e=600 mils
+Kw DIL
+Sc 47698597
+AR /47698597
+Op 0 0 0
+T0 -7500 -1500 700 450 1800 120 N V 21 N"IC1"
+T1 0 1000 700 700 1800 120 N V 21 N"ATmega162"
+DS -10500 -500 -10000 -500 150 21
+DS -10000 -500 -10000 500 150 21
+DS -10000 500 -10500 500 150 21
+DS -10500 -2500 10500 -2500 150 21
+DS 10500 -2500 10500 2500 150 21
+DS 10500 2500 -10500 2500 150 21
+DS -10500 2500 -10500 -2500 150 21
+$PAD
+Sh "1" R 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 71 "/PB0"
+Po -9500 3000
+$EndPAD
+$PAD
+Sh "2" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 70 "/PB1"
+Po -8500 3000
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 69 "/PB2"
+Po -7500 3000
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 68 "/PB3"
+Po -6500 3000
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 67 "/PB4"
+Po -5500 3000
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 66 "/PB5"
+Po -4500 3000
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 65 "/PB6"
+Po -3500 3000
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 64 "/PB7"
+Po -2500 3000
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 77 "N-000004"
+Po -1500 3000
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 78 "N-000084"
+Po -500 3000
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 79 "N-000005"
+Po 500 3000
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 46 "/PD2"
+Po 1500 3000
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 45 "/PD3"
+Po 2500 3000
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 44 "/PD4"
+Po 3500 3000
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 43 "/PD5"
+Po 4500 3000
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 42 "/PD6"
+Po 5500 3000
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 41 "/PD7"
+Po 6500 3000
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 7500 3000
+$EndPAD
+$PAD
+Sh "19" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 35 "N-000085"
+Po 8500 3000
+$EndPAD
+$PAD
+Sh "20" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 9500 3000
+$EndPAD
+$PAD
+Sh "21" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 40 "/PC0"
+Po 9500 -3000
+$EndPAD
+$PAD
+Sh "22" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 55 "/PC1"
+Po 8500 -3000
+$EndPAD
+$PAD
+Sh "23" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 54 "/PC2"
+Po 7500 -3000
+$EndPAD
+$PAD
+Sh "24" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 53 "/PC3"
+Po 6500 -3000
+$EndPAD
+$PAD
+Sh "25" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 52 "/PC4"
+Po 5500 -3000
+$EndPAD
+$PAD
+Sh "26" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 51 "/PC5"
+Po 4500 -3000
+$EndPAD
+$PAD
+Sh "27" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 50 "/PC6"
+Po 3500 -3000
+$EndPAD
+$PAD
+Sh "28" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 49 "/PC7"
+Po 2500 -3000
+$EndPAD
+$PAD
+Sh "29" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 80 "N-000006"
+Po 1500 -3000
+$EndPAD
+$PAD
+Sh "30" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 81 "N-000003"
+Po 500 -3000
+$EndPAD
+$PAD
+Sh "31" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 82 "N-000087"
+Po -500 -3000
+$EndPAD
+$PAD
+Sh "32" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 63 "/PA7"
+Po -1500 -3000
+$EndPAD
+$PAD
+Sh "33" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 62 "/PA6"
+Po -2500 -3000
+$EndPAD
+$PAD
+Sh "34" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 61 "/PA5"
+Po -3500 -3000
+$EndPAD
+$PAD
+Sh "35" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 60 "/PA4"
+Po -4500 -3000
+$EndPAD
+$PAD
+Sh "36" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 59 "/PA3"
+Po -5500 -3000
+$EndPAD
+$PAD
+Sh "37" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 58 "/PA2"
+Po -6500 -3000
+$EndPAD
+$PAD
+Sh "38" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 57 "/PA1"
+Po -7500 -3000
+$EndPAD
+$PAD
+Sh "39" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 56 "/PA0"
+Po -8500 -3000
+$EndPAD
+$PAD
+Sh "40" O 620 900 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -9500 -3000
+$EndPAD
+$SHAPE3D
+Na "dil\dil_40-w600.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-40__600_ELL
+$MODULE 1pin
+Po 19370 20039 0 15 00200000 4B2500E8 ~~
+Li 1pin
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B2500E8
+AR
+Op 0 0 0
+T0 0 -1200 400 400 0 120 N V 21 N"1PIN"
+T1 0 1100 400 400 0 120 N I 21 N"P***"
+DC 0 0 0 -900 150 21
+$PAD
+Sh "1" C 1600 1600 0 0 0
+Dr 1200 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 0 0
+$EndPAD
+$EndMODULE 1pin
+$MODULE 1pin
+Po 19370 51929 0 15 00200000 4B25013B ~~
+Li 1pin
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B25013B
+AR
+Op 0 0 0
+T0 0 -1200 400 400 0 120 N V 21 N"1PIN"
+T1 0 1100 400 400 0 120 N I 21 N"P***"
+DC 0 0 0 -900 150 21
+$PAD
+Sh "1" C 1600 1600 0 0 0
+Dr 1200 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 0 0
+$EndPAD
+$EndMODULE 1pin
+$MODULE 1pin
+Po 78425 20039 0 15 00200000 4B250199 ~~
+Li 1pin
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B250199
+AR
+Op 0 0 0
+T0 0 -1200 400 400 0 120 N V 21 N"1PIN"
+T1 0 1100 400 400 0 120 N I 21 N"P***"
+DC 0 0 0 -900 150 21
+$PAD
+Sh "1" C 1600 1600 0 0 0
+Dr 1200 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 0 0
+$EndPAD
+$EndMODULE 1pin
+$MODULE 1pin
+Po 78425 51929 0 15 00200000 4B2501DE ~~
+Li 1pin
+Cd module 1 pin (ou trou mecanique de percage)
+Kw DEV
+Sc 4B2501DE
+AR
+Op 0 0 0
+T0 0 -1200 400 400 0 120 N V 21 N"1PIN"
+T1 0 1100 400 400 0 120 N I 21 N"P***"
+DC 0 0 0 -900 150 21
+$PAD
+Sh "1" C 1600 1600 0 0 0
+Dr 1200 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 0 0
+$EndPAD
+$EndMODULE 1pin
+$MODULE C1
+Po 51000 41000 2700 15 3F92C496 4B2346F2 ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2346F2
+AR /4B2346F2
+Op 0 0 0
+T0 100 -900 400 400 2700 80 N V 21 N"C3"
+T1 0 -900 400 400 2700 80 N I 21 N"100nf"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE C1
+Po 63000 33000 900 15 3F92C496 4B2346EC ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2346EC
+AR /4B2346EC
+Op 0 0 0
+T0 100 -900 400 400 900 80 N V 21 N"C4"
+T1 0 -900 400 400 900 80 N I 21 N"100nf"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE C1
+Po 65000 24500 1800 15 3F92C496 4B2343E9 ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2343E9
+AR /4B2343E9
+Op 0 0 0
+T0 100 -900 400 400 1800 80 N V 21 N"C6"
+T1 0 -900 400 400 1800 80 N I 21 N"100nF"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 37 "N-000034"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE C1
+Po 68750 46500 900 15 3F92C496 4B2447DA ~~
+Li C1
+Cd Condensateur e = 1 pas
+Kw C
+Sc 4B2447DA
+AR /4B2447DA
+Op 0 0 0
+T0 100 -900 400 400 900 80 N V 21 N"C7"
+T1 0 -900 400 400 900 80 N I 21 N"100nf"
+DS -980 -500 1000 -500 120 21
+DS 1000 -500 1000 500 120 21
+DS 1000 500 -1000 500 120 21
+DS -1000 500 -1000 -500 120 21
+DS -1000 -250 -750 -500 120 21
+$PAD
+Sh "1" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 550 550 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "discret/capa_1_pas.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE C1
+$MODULE D4
+Po 61250 45000 1800 15 00200000 4B233832 ~~
+Li D4
+Cd Diode 4 pas
+Kw DIODE DEV
+Sc 4B233832
+AR /4B233832
+Op 0 0 0
+T0 0 0 500 400 1800 80 N V 21 N"D1"
+T1 0 0 500 400 1800 80 N I 21 N"ZENER"
+DS -1500 -500 1500 -500 120 21
+DS 1500 -500 1500 500 120 21
+DS 1500 500 -1500 500 120 21
+DS -1500 500 -1500 -500 120 21
+DS 1250 -500 1250 500 120 21
+DS 1000 500 1000 -500 120 21
+DS -1500 0 -2000 0 120 21
+DS 1500 0 2000 0 120 21
+$PAD
+Sh "1" C 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 75 "N-000035"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" R 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 83 "N-000036"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/diode.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE D4
+$MODULE D4
+Po 69250 35000 1800 15 00200000 4B233F31 ~~
+Li D4
+Cd Diode 4 pas
+Kw DIODE DEV
+Sc 4B233F31
+AR /4B233F31
+Op 0 0 0
+T0 0 0 500 400 1800 80 N V 21 N"D3"
+T1 0 0 500 400 1800 80 N I 21 N"3V6"
+DS -1500 -500 1500 -500 120 21
+DS 1500 -500 1500 500 120 21
+DS 1500 500 -1500 500 120 21
+DS -1500 500 -1500 -500 120 21
+DS 1250 -500 1250 500 120 21
+DS 1000 500 1000 -500 120 21
+DS -1500 0 -2000 0 120 21
+DS 1500 0 2000 0 120 21
+$PAD
+Sh "1" C 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" R 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 38 "N-000038"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/diode.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE D4
+$MODULE D4
+Po 69250 36500 1800 15 00200000 4B233F3B ~~
+Li D4
+Cd Diode 4 pas
+Kw DIODE DEV
+Sc 4B233F3B
+AR /4B233F3B
+Op 0 0 0
+T0 0 0 500 400 1800 80 N V 21 N"D4"
+T1 0 0 500 400 1800 80 N I 21 N"3V6"
+DS -1500 -500 1500 -500 120 21
+DS 1500 -500 1500 500 120 21
+DS 1500 500 -1500 500 120 21
+DS -1500 500 -1500 -500 120 21
+DS 1250 -500 1250 500 120 21
+DS 1000 500 1000 -500 120 21
+DS -1500 0 -2000 0 120 21
+DS 1500 0 2000 0 120 21
+$PAD
+Sh "1" C 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" R 700 700 0 0 1800
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 39 "N-000039"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/diode.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE D4
+$MODULE R4
+Po 55500 27500 900 15 00200000 4B234A65 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B234A65
+AR /4B234A65
+Op 0 A 0
+T0 0 0 550 500 900 80 N V 21 N"R1"
+T1 0 0 550 500 900 80 N I 21 N"5K6"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 77 "N-000004"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 55500 40750 2700 15 00200000 4B233954 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233954
+AR /4B233954
+Op 0 A 0
+T0 0 0 550 500 2700 80 N V 21 N"R2"
+T1 0 0 550 500 2700 80 N I 21 N"1K5"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 80 "N-000006"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 74 "N-000048"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 57750 43500 2700 15 00200000 4B2338D9 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B2338D9
+AR /4B2338D9
+Op 0 A 0
+T0 0 0 550 500 2700 80 N V 21 N"R3"
+T1 0 0 550 500 2700 80 N I 21 N"47K"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 74 "N-000048"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 66000 43750 1800 15 00200000 4B2337C6 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B2337C6
+AR /4B2337C6
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"R4"
+T1 0 0 550 500 1800 80 N I 21 N"1K5"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 2 "VDD"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 83 "N-000036"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 61250 46500 1800 15 00200000 4B233808 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233808
+AR /4B233808
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"R5"
+T1 0 0 550 500 1800 80 N I 21 N"100"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 76 "N-000049"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 83 "N-000036"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 53250 35000 900 15 00200000 4B233E03 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233E03
+AR /4B233E03
+Op 0 A 0
+T0 0 0 550 500 900 80 N V 21 N"R6"
+T1 0 0 550 500 900 80 N I 21 N"1K2"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 81 "N-000003"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 36 "N-000082"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 64000 38000 1800 15 00200000 4B233EFA ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233EFA
+AR /4B233EFA
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"R7"
+T1 0 0 550 500 1800 80 N I 21 N"68"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 39 "N-000039"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 84 "N-000083"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 64000 36500 1800 15 00200000 4B233EC8 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233EC8
+AR /4B233EC8
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"R8"
+T1 0 0 550 500 1800 80 N I 21 N"68"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 38 "N-000038"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 85 "N-000008"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 64000 35000 1800 15 00200000 4B233F05 ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B233F05
+AR /4B233F05
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"R9"
+T1 0 0 550 500 1800 80 N I 21 N"2K2"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 38 "N-000038"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 86 "N-000037"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE R4
+Po 54500 35000 2700 15 00200000 4B27466D ~~
+Li R4
+Cd Resitance 4 pas
+Kw R
+Sc 4B27466D
+AR /4B27466D
+Op 0 A 0
+T0 0 0 550 500 2700 80 N V 21 N"R10"
+T1 0 0 550 500 2700 80 N I 21 N"1K"
+DS -2000 0 -1600 0 120 21
+DS -1600 0 -1600 -400 120 21
+DS -1600 -400 1600 -400 120 21
+DS 1600 -400 1600 400 120 21
+DS 1600 400 -1600 400 120 21
+DS -1600 400 -1600 0 120 21
+DS -1600 -200 -1400 -400 120 21
+DS 2000 0 1600 0 120 21
+$PAD
+Sh "1" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 87 "N-000002"
+Po -2000 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 2700
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 82 "N-000087"
+Po 2000 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.400000 0.400000 0.400000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R4
+$MODULE DIP-28__300_ELL
+Po 59000 33000 900 15 00200000 4B28A789 ~~
+Li DIP-28__300_ELL
+Cd 28 pins DIL package, elliptical pads, width 300mil
+Kw DIL
+Sc 4B28A789
+AR /4B28A789
+Op 0 0 0
+T0 -4500 0 600 450 900 120 N V 21 N"IC6"
+T1 2750 0 600 450 900 120 N V 21 N"ATMEGA8-P"
+DS -7500 -1000 7500 -1000 150 21
+DS 7500 -1000 7500 1000 150 21
+DS 7500 1000 -7500 1000 150 21
+DS -7500 1000 -7500 -1000 150 21
+DS -7500 -500 -7000 -500 150 21
+DS -7000 -500 -7000 500 150 21
+DS -7000 500 -7500 500 150 21
+$PAD
+Sh "2" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 79 "N-000005"
+Po -5500 1500
+$EndPAD
+$PAD
+Sh "3" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 78 "N-000084"
+Po -4500 1500
+$EndPAD
+$PAD
+Sh "4" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 84 "N-000083"
+Po -3500 1500
+$EndPAD
+$PAD
+Sh "5" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 85 "N-000008"
+Po -2500 1500
+$EndPAD
+$PAD
+Sh "6" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 86 "N-000037"
+Po -1500 1500
+$EndPAD
+$PAD
+Sh "7" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -500 1500
+$EndPAD
+$PAD
+Sh "8" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 1500
+$EndPAD
+$PAD
+Sh "9" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 34 "N-000086"
+Po 1500 1500
+$EndPAD
+$PAD
+Sh "10" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 35 "N-000085"
+Po 2500 1500
+$EndPAD
+$PAD
+Sh "11" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 3500 1500
+$EndPAD
+$PAD
+Sh "12" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 4500 1500
+$EndPAD
+$PAD
+Sh "13" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 5500 1500
+$EndPAD
+$PAD
+Sh "14" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 88 "N-000088"
+Po 6500 1500
+$EndPAD
+$PAD
+Sh "1" R 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -6500 1500
+$EndPAD
+$PAD
+Sh "15" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 6500 -1500
+$EndPAD
+$PAD
+Sh "16" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 5500 -1500
+$EndPAD
+$PAD
+Sh "17" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 87 "N-000002"
+Po 4500 -1500
+$EndPAD
+$PAD
+Sh "18" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 77 "N-000004"
+Po 3500 -1500
+$EndPAD
+$PAD
+Sh "19" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 2500 -1500
+$EndPAD
+$PAD
+Sh "20" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po 1500 -1500
+$EndPAD
+$PAD
+Sh "21" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po 500 -1500
+$EndPAD
+$PAD
+Sh "22" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po -500 -1500
+$EndPAD
+$PAD
+Sh "23" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -1500 -1500
+$EndPAD
+$PAD
+Sh "24" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -2500 -1500
+$EndPAD
+$PAD
+Sh "25" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -3500 -1500
+$EndPAD
+$PAD
+Sh "26" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -4500 -1500
+$EndPAD
+$PAD
+Sh "27" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -5500 -1500
+$EndPAD
+$PAD
+Sh "28" O 620 900 0 0 900
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 0 ""
+Po -6500 -1500
+$EndPAD
+$SHAPE3D
+Na "dil/dil_28-w300.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE DIP-28__300_ELL
+$MODULE PIN_ARRAY_2X1
+Po 61500 24250 900 15 4565C520 4B28D598 ~~
+Li PIN_ARRAY_2X1
+Cd Connecteurs 2 pins
+Kw CONN DEV
+Sc 4B28D598
+AR /4B28D598
+Op 0 0 0
+T0 0 -750 300 300 900 60 N V 21 N"JP1"
+T1 0 -750 300 300 900 60 N I 21 N"JUMPER"
+DS -1000 500 -1000 -500 60 21
+DS -1000 -500 1000 -500 60 21
+DS 1000 -500 1000 500 60 21
+DS 1000 500 -1000 500 60 21
+$PAD
+Sh "1" R 600 600 0 0 900
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 88 "N-000088"
+Po -500 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 900
+Dr 400 0 0
+At STD N 00E0FFFF
+Ne 1 "GND"
+Po 500 0
+$EndPAD
+$SHAPE3D
+Na "pin_array/pins_array_2x1.wrl"
+Sc 1.000000 1.000000 1.000000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE PIN_ARRAY_2X1
+$MODULE R5
+Po 68000 26500 1800 15 00200000 4B234662 ~~
+Li R5
+Cd Resistance 5 pas
+Kw R
+Sc 4B234662
+AR /4B234662
+Op 0 A 0
+T0 0 0 550 500 1800 80 N V 21 N"FB1"
+T1 0 0 550 500 1800 80 N I 21 N"10uH"
+DS -2500 0 -2100 0 120 21
+DS 2500 0 2100 0 120 21
+DS 2100 -500 2100 500 120 21
+DS 2100 500 -2100 500 120 21
+DS -2100 500 -2100 -500 120 21
+DS -2100 -500 2100 -500 120 21
+DS -2100 -300 -1900 -500 120 21
+$PAD
+Sh "1" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 73 "+5V"
+Po -2500 0
+$EndPAD
+$PAD
+Sh "2" C 600 600 0 0 1800
+Dr 320 0 0
+At STD N 00E0FFFF
+Ne 37 "N-000034"
+Po 2500 0
+$EndPAD
+$SHAPE3D
+Na "discret/resistor.wrl"
+Sc 0.500000 0.500000 0.500000
+Of 0.000000 0.000000 0.000000
+Ro 0.000000 0.000000 0.000000
+$EndSHAPE3D
+$EndMODULE R5
+$TEXTPCB
+Te "DF10CH V3 (C) Andreas Auras (copper side)"
+Po 19409 35551 480 640 120 2700
+De 0 0 0 Normal
+$EndTEXTPCB
+$DRAWSEGMENT
+Po 0 17402 16299 17402 35984 150
+De 28 0 900 0 0
+$EndDRAWSEGMENT
+$DRAWSEGMENT
+Po 0 80394 16299 17402 16299 150
+De 28 0 900 0 0
+$EndDRAWSEGMENT
+$DRAWSEGMENT
+Po 0 80394 55669 80394 16299 150
+De 28 0 900 0 0
+$EndDRAWSEGMENT
+$DRAWSEGMENT
+Po 0 17402 55669 80394 55669 150
+De 28 0 900 0 0
+$EndDRAWSEGMENT
+$DRAWSEGMENT
+Po 0 17402 35984 17402 55669 150
+De 28 0 900 0 0
+$EndDRAWSEGMENT
+$TRACK
+Po 0 71250 29500 71250 28750 500 -1
+De 0 0 1 0 800
+Po 0 66500 31500 66500 29500 500 -1
+De 0 0 1 0 C00
+Po 0 63000 32500 66250 32500 500 -1
+De 0 0 1 0 800
+Po 0 66500 32250 66500 31500 500 -1
+De 0 0 1 0 400
+Po 0 66250 32500 66500 32250 500 -1
+De 0 0 1 0 0
+Po 0 71250 19250 71500 19250 500 -1
+De 0 0 1 0 0
+Po 0 68250 19250 71250 19250 500 -1
+De 0 0 1 0 0
+Po 0 71500 19250 72250 19250 500 -1
+De 0 0 1 0 0
+Po 0 72250 19250 72500 19000 500 -1
+De 0 0 1 0 0
+Po 0 72500 19000 72500 18250 500 -1
+De 0 0 1 0 400
+Po 0 71250 29500 71250 35000 500 -1
+De 0 0 1 0 C00
+Po 0 71250 35000 71250 36500 500 -1
+De 0 0 1 0 C00
+Po 0 71250 36500 71250 46000 500 -1
+De 0 0 1 0 800
+Po 0 54000 41500 51000 41500 500 -1
+De 0 0 1 0 400
+Po 0 63750 54250 63750 53000 500 -1
+De 0 0 1 0 0
+Po 0 63750 53000 63750 49500 500 -1
+De 0 0 1 0 0
+Po 0 63750 49500 63250 49000 500 -1
+De 0 0 1 0 0
+Po 0 63250 49000 62500 49000 500 -1
+De 0 0 1 0 400
+Po 0 57750 41500 54000 41500 500 -1
+De 0 0 1 0 800
+Po 0 63750 54250 62500 54250 500 -1
+De 0 0 1 0 0
+Po 0 32000 31500 32000 33000 500 -1
+De 0 0 1 0 400
+Po 3 32000 31500 32000 31500 1000 -1
+De 15 1 1 0 0
+Po 0 54000 44250 54000 41500 500 -1
+De 0 0 1 0 800
+Po 0 71500 28500 71500 19250 500 -1
+De 0 0 1 0 0
+Po 0 71250 28750 71500 28500 500 -1
+De 0 0 1 0 0
+Po 0 66000 54250 66000 52500 500 -1
+De 0 0 1 0 400
+Po 0 72000 54250 72000 52500 500 -1
+De 0 0 1 0 400
+Po 0 63750 54250 66000 54250 500 -1
+De 0 0 1 0 0
+Po 0 66000 54250 72000 54250 500 -1
+De 0 0 1 0 0
+Po 0 72000 54250 74500 54250 500 -1
+De 0 0 1 0 0
+Po 0 73500 47000 73000 47000 500 -1
+De 0 0 1 0 400
+Po 0 54000 44250 54000 45250 500 -1
+De 0 0 1 0 C00
+Po 0 68362 19250 68250 19250 500 -1
+De 0 0 1 0 0
+Po 0 74500 48000 73500 47000 500 -1
+De 0 0 1 0 0
+Po 0 24000 31500 26000 31500 500 -1
+De 0 0 1 0 0
+Po 0 74500 49000 74500 48000 500 -1
+De 0 0 1 0 0
+Po 0 75750 50250 74500 49000 500 -1
+De 0 0 1 0 0
+Po 0 75750 53000 75750 50250 500 -1
+De 0 0 1 0 0
+Po 0 74500 54250 75750 53000 500 -1
+De 0 0 1 0 0
+Po 0 61500 41500 64500 41500 500 -1
+De 0 0 1 0 800
+Po 0 64500 25500 64500 25250 500 -1
+De 0 0 1 0 0
+Po 0 61250 48500 56250 48500 500 -1
+De 0 0 1 0 0
+Po 0 64500 24500 64500 23750 500 -1
+De 0 0 1 0 800
+Po 0 64500 23750 64500 22000 500 -1
+De 0 0 1 0 0
+Po 0 64500 22000 64937 21563 500 -1
+De 0 0 1 0 0
+Po 0 64937 21563 65500 21563 500 -1
+De 0 0 1 0 400
+Po 0 66500 29500 66500 29250 500 -1
+De 0 0 1 0 800
+Po 0 64500 27250 64500 25250 500 -1
+De 0 0 1 0 0
+Po 0 61500 23750 64500 23750 315 -1
+De 0 0 1 0 800
+Po 0 55500 25500 55500 25250 315 -1
+De 0 0 1 0 800
+Po 0 61000 23750 61500 23750 315 -1
+De 0 0 1 0 400
+Po 0 60000 24750 61000 23750 315 -1
+De 0 0 1 0 0
+Po 0 56000 24750 60000 24750 315 -1
+De 0 0 1 0 0
+Po 0 55500 25250 56000 24750 315 -1
+De 0 0 1 0 0
+Po 0 58750 31000 58500 31000 315 -1
+De 0 0 1 0 0
+Po 0 59500 32250 59750 32500 315 -1
+De 0 0 1 0 0
+Po 0 59750 32500 60500 32500 315 -1
+De 0 0 1 0 400
+Po 0 58750 31000 59500 31750 315 -1
+De 0 0 1 0 0
+Po 0 56650 33400 56650 31100 315 -1
+De 0 0 1 0 0
+Po 0 56650 31100 56750 31000 315 -1
+De 0 0 1 0 0
+Po 0 56750 31000 58500 31000 157 -1
+De 0 0 1 0 0
+Po 0 57500 33500 56750 33500 315 -1
+De 0 0 1 0 800
+Po 0 56750 33500 56650 33400 315 -1
+De 0 0 1 0 0
+Po 0 59500 31750 59500 32250 315 -1
+De 0 0 1 0 0
+Po 0 65500 21563 65500 20500 500 -1
+De 0 0 1 0 800
+Po 0 68362 20500 68362 19250 500 -1
+De 0 0 1 0 800
+Po 0 32000 33000 32000 35000 500 -1
+De 0 0 1 0 800
+Po 0 54000 45250 54000 46250 500 -1
+De 0 0 1 0 800
+Po 0 26000 31500 32000 31500 500 -1
+De 15 0 1 0 0
+Po 0 54000 46250 54000 46250 500 -1
+De 0 0 1 0 0
+Po 0 68750 46000 71500 46000 500 -1
+De 0 0 1 0 800
+Po 0 71500 46000 71250 46000 500 -1
+De 0 0 1 0 0
+Po 0 71250 46000 72000 46000 500 -1
+De 0 0 1 0 0
+Po 0 72000 46000 73000 46000 500 -1
+De 0 0 1 0 0
+Po 0 73000 46000 73000 47000 500 -1
+De 0 0 1 0 400
+Po 0 63638 20500 65500 20500 500 -1
+De 0 0 1 0 800
+Po 0 65500 19750 66000 19250 500 -1
+De 0 0 1 0 0
+Po 0 66000 19250 68250 19250 500 -1
+De 0 0 1 0 0
+Po 0 65500 20500 65500 19750 500 -1
+De 0 0 1 0 0
+Po 0 57750 41500 61500 41500 500 -1
+De 0 0 1 0 C00
+Po 0 61750 49000 61250 48500 500 -1
+De 0 0 1 0 0
+Po 0 64500 25250 64500 24500 500 -1
+De 0 0 1 0 400
+Po 0 56250 48500 54000 46250 500 -1
+De 0 0 1 0 0
+Po 0 62500 49000 61750 49000 500 -1
+De 0 0 1 0 800
+Po 0 62500 54250 61750 55000 500 -1
+De 0 0 1 0 0
+Po 0 61750 55000 22500 55000 500 -1
+De 0 0 1 0 0
+Po 0 22500 55000 21500 54000 500 -1
+De 0 0 1 0 0
+Po 0 21500 54000 21500 34000 500 -1
+De 0 0 1 0 0
+Po 0 21500 34000 24000 31500 500 -1
+De 0 0 1 0 0
+Po 0 60500 32500 63000 32500 500 -1
+De 0 0 1 0 C00
+Po 3 26000 31500 26000 31500 1000 -1
+De 15 1 1 0 0
+Po 0 66500 29250 64500 27250 500 -1
+De 0 0 1 0 0
+Po 0 72000 48500 72000 50100 500 -1
+De 0 0 2 0 400
+Po 0 69000 43250 69000 42500 500 -1
+De 0 0 2 0 400
+Po 0 68500 43750 69000 43250 500 -1
+De 0 0 2 0 0
+Po 0 66150 50100 67750 48500 500 -1
+De 0 0 2 0 0
+Po 0 72000 47000 72000 48500 500 -1
+De 0 0 2 0 800
+Po 0 67250 44500 68000 43750 500 -1
+De 0 0 2 0 400
+Po 0 68750 47000 67750 47000 500 -1
+De 0 0 2 0 800
+Po 0 67750 48500 72000 48500 500 -1
+De 0 0 2 0 0
+Po 0 66000 50100 66150 50100 500 -1
+De 0 0 2 0 800
+Po 0 72000 47000 68750 47000 665 -1
+De 0 0 2 0 C00
+Po 0 67750 47000 67250 46500 500 -1
+De 0 0 2 0 0
+Po 0 68000 43750 68500 43750 500 -1
+De 0 0 2 0 800
+Po 0 67250 46500 67250 44500 500 -1
+De 0 0 2 0 0
+Po 0 60250 21500 60250 19490 315 -1
+De 0 0 3 0 0
+Po 0 60250 19490 59750 18990 315 -1
+De 0 0 3 0 400
+Po 0 51000 25750 51000 25250 315 -1
+De 0 0 3 0 800
+Po 0 55000 22750 59000 22750 315 -1
+De 0 0 3 0 0
+Po 0 53000 24750 55000 22750 315 -1
+De 0 0 3 0 0
+Po 0 51000 25250 51500 24750 315 -1
+De 0 0 3 0 0
+Po 0 51500 24750 53000 24750 315 -1
+De 0 0 3 0 0
+Po 0 59750 18990 58950 18990 315 -1
+De 0 0 3 0 C00
+Po 0 59000 22750 60250 21500 315 -1
+De 0 0 3 0 0
+Po 0 51500 52610 51100 53010 500 -1
+De 0 0 4 0 400
+Po 0 27500 45500 23500 49500 500 -1
+De 0 0 4 0 0
+Po 0 51100 53650 51100 53010 500 -1
+De 0 0 4 0 400
+Po 0 24750 19990 24750 19390 500 -1
+De 0 0 4 0 800
+Po 0 51500 52010 51500 52610 500 -1
+De 0 0 4 0 800
+Po 0 59750 52010 59750 52610 500 -1
+De 0 0 4 0 800
+Po 0 41250 19990 41250 19390 500 -1
+De 0 0 4 0 800
+Po 0 35000 52610 34600 53010 500 -1
+De 0 0 4 0 400
+Po 0 35000 52010 35000 52610 500 -1
+De 0 0 4 0 800
+Po 0 26750 52010 26750 52610 500 -1
+De 0 0 4 0 800
+Po 0 33000 19390 33400 18990 500 -1
+De 0 0 4 0 400
+Po 0 43250 52610 42850 53010 500 -1
+De 0 0 4 0 400
+Po 0 43250 52010 43250 52610 500 -1
+De 0 0 4 0 800
+Po 0 59750 52610 59350 53010 500 -1
+De 0 0 4 0 400
+Po 0 35000 52010 39510 52010 500 -1
+De 0 0 4 0 800
+Po 0 40000 53000 41000 54000 500 -1
+De 0 0 4 0 0
+Po 0 40000 52500 40000 53000 500 -1
+De 0 0 4 0 0
+Po 0 42850 53650 42850 53010 500 -1
+De 0 0 4 0 400
+Po 0 39510 52010 40000 52500 500 -1
+De 0 0 4 0 0
+Po 0 49250 54000 50750 54000 500 -1
+De 0 0 4 0 0
+Po 0 26750 52010 31490 52010 500 -1
+De 0 0 4 0 800
+Po 0 24500 54000 26000 54000 500 -1
+De 0 0 4 0 0
+Po 0 43250 52010 47760 52010 500 -1
+De 0 0 4 0 800
+Po 0 26350 53650 26350 53010 500 -1
+De 0 0 4 0 400
+Po 0 24750 19990 24750 23000 500 -1
+De 0 0 4 0 800
+Po 0 33000 19990 33000 19390 500 -1
+De 0 0 4 0 800
+Po 0 57750 19990 57750 19390 500 -1
+De 0 0 4 0 800
+Po 0 24750 19390 25150 18990 500 -1
+De 0 0 4 0 400
+Po 0 34250 54000 34600 53650 500 -1
+De 0 0 4 0 0
+Po 0 49500 19390 49900 18990 500 -1
+De 0 0 4 0 400
+Po 0 47760 52010 48250 52500 500 -1
+De 0 0 4 0 0
+Po 0 26750 52610 26350 53010 500 -1
+De 0 0 4 0 400
+Po 0 41000 54000 42500 54000 500 -1
+De 0 0 4 0 0
+Po 0 26000 54000 26350 53650 500 -1
+De 0 0 4 0 0
+Po 0 48250 53000 49250 54000 500 -1
+De 0 0 4 0 0
+Po 0 48250 52500 48250 53000 500 -1
+De 0 0 4 0 0
+Po 0 42500 54000 42850 53650 500 -1
+De 0 0 4 0 0
+Po 0 23500 49500 23500 53000 500 -1
+De 0 0 4 0 0
+Po 0 31750 53000 32750 54000 500 -1
+De 0 0 4 0 0
+Po 0 33000 19990 28740 19990 500 -1
+De 0 0 4 0 800
+Po 0 25150 18350 25150 18990 500 -1
+De 0 0 4 0 400
+Po 0 25500 18000 25150 18350 500 -1
+De 0 0 4 0 0
+Po 0 27250 18000 25500 18000 500 -1
+De 0 0 4 0 0
+Po 0 27750 18500 27250 18000 500 -1
+De 0 0 4 0 0
+Po 0 27750 19000 27750 18500 500 -1
+De 0 0 4 0 0
+Po 0 28740 19990 27750 19000 500 -1
+De 0 0 4 0 0
+Po 0 41250 19990 36990 19990 500 -1
+De 0 0 4 0 800
+Po 0 33400 18350 33400 18990 500 -1
+De 0 0 4 0 400
+Po 0 33750 18000 33400 18350 500 -1
+De 0 0 4 0 0
+Po 0 35500 18000 33750 18000 500 -1
+De 0 0 4 0 0
+Po 0 36000 18500 35500 18000 500 -1
+De 0 0 4 0 0
+Po 0 36000 19000 36000 18500 500 -1
+De 0 0 4 0 0
+Po 0 36990 19990 36000 19000 500 -1
+De 0 0 4 0 0
+Po 0 49500 19990 45240 19990 500 -1
+De 0 0 4 0 800
+Po 0 41650 18350 41650 18990 500 -1
+De 0 0 4 0 400
+Po 0 42000 18000 41650 18350 500 -1
+De 0 0 4 0 0
+Po 0 44000 18000 42000 18000 500 -1
+De 0 0 4 0 0
+Po 0 44250 18250 44000 18000 500 -1
+De 0 0 4 0 0
+Po 0 44250 19000 44250 18250 500 -1
+De 0 0 4 0 0
+Po 0 45240 19990 44250 19000 500 -1
+De 0 0 4 0 0
+Po 0 57750 19990 53490 19990 500 -1
+De 0 0 4 0 800
+Po 0 49900 18350 49900 18990 500 -1
+De 0 0 4 0 400
+Po 0 50250 18000 49900 18350 500 -1
+De 0 0 4 0 0
+Po 0 52000 18000 50250 18000 500 -1
+De 0 0 4 0 0
+Po 0 52500 18500 52000 18000 500 -1
+De 0 0 4 0 0
+Po 0 52500 19000 52500 18500 500 -1
+De 0 0 4 0 0
+Po 0 53490 19990 52500 19000 500 -1
+De 0 0 4 0 0
+Po 0 51500 52010 56260 52010 500 -1
+De 0 0 4 0 800
+Po 0 59350 53650 59350 53010 500 -1
+De 0 0 4 0 400
+Po 0 59000 54000 59350 53650 500 -1
+De 0 0 4 0 0
+Po 0 57500 54000 59000 54000 500 -1
+De 0 0 4 0 0
+Po 0 56500 53000 57500 54000 500 -1
+De 0 0 4 0 0
+Po 0 56500 52250 56500 53000 500 -1
+De 0 0 4 0 0
+Po 0 56260 52010 56500 52250 500 -1
+De 0 0 4 0 0
+Po 0 59750 52010 61740 52010 500 -1
+De 0 0 4 0 800
+Po 0 62500 51250 62500 50000 500 -1
+De 0 0 4 0 400
+Po 0 61740 52010 62500 51250 500 -1
+De 0 0 4 0 0
+Po 0 50750 54000 51100 53650 500 -1
+De 0 0 4 0 0
+Po 0 34600 53650 34600 53010 500 -1
+De 0 0 4 0 400
+Po 0 49500 19990 49500 19390 500 -1
+De 0 0 4 0 800
+Po 0 32750 54000 34250 54000 500 -1
+De 0 0 4 0 0
+Po 0 57750 19390 58150 18990 500 -1
+De 0 0 4 0 400
+Po 0 31750 52270 31750 53000 500 -1
+De 0 0 4 0 0
+Po 0 31490 52010 31750 52270 500 -1
+De 0 0 4 0 0
+Po 0 23500 53000 24500 54000 500 -1
+De 0 0 4 0 0
+Po 0 24750 23000 27500 25750 500 -1
+De 0 0 4 0 0
+Po 0 27500 25750 27500 45500 500 -1
+De 0 0 4 0 0
+Po 0 41250 19390 41650 18990 500 -1
+De 0 0 4 0 400
+Po 0 49000 25750 49000 24500 315 -1
+De 0 0 5 0 800
+Po 0 58250 21250 58550 20950 315 -1
+De 0 0 5 0 0
+Po 0 49000 24500 50250 23250 315 -1
+De 0 0 5 0 0
+Po 0 50250 23250 51500 23250 315 -1
+De 0 0 5 0 0
+Po 0 51500 23250 53500 21250 315 -1
+De 0 0 5 0 0
+Po 0 58550 20950 58550 19990 315 -1
+De 0 0 5 0 400
+Po 0 53500 21250 58250 21250 315 -1
+De 0 0 5 0 0
+Po 0 52250 24000 54250 22000 315 -1
+De 0 0 6 0 0
+Po 0 50000 25000 51000 24000 315 -1
+De 0 0 6 0 0
+Po 0 58750 22000 59350 21400 315 -1
+De 0 0 6 0 0
+Po 0 59350 21400 59350 19990 315 -1
+De 0 0 6 0 400
+Po 0 50000 25750 50000 25000 315 -1
+De 0 0 6 0 800
+Po 0 54250 22000 58750 22000 315 -1
+De 0 0 6 0 0
+Po 0 51000 24000 52250 24000 315 -1
+De 0 0 6 0 0
+Po 0 48000 24250 49750 22500 315 -1
+De 0 0 7 0 0
+Po 0 52000 21250 52000 19490 315 -1
+De 0 0 7 0 0
+Po 0 48000 25750 48000 24250 315 -1
+De 0 0 7 0 800
+Po 0 50750 22500 52000 21250 315 -1
+De 0 0 7 0 0
+Po 0 51500 18990 50700 18990 315 -1
+De 0 0 7 0 C00
+Po 0 49750 22500 50750 22500 315 -1
+De 0 0 7 0 0
+Po 0 52000 19490 51500 18990 315 -1
+De 0 0 7 0 400
+Po 0 49750 21000 50300 20450 315 -1
+De 0 0 8 0 0
+Po 0 46000 25750 46000 23250 315 -1
+De 0 0 8 0 800
+Po 0 48250 21000 49750 21000 315 -1
+De 0 0 8 0 0
+Po 0 46000 23250 48250 21000 315 -1
+De 0 0 8 0 0
+Po 0 50300 20450 50300 19990 315 -1
+De 0 0 8 0 400
+Po 0 47000 23750 49000 21750 315 -1
+De 0 0 9 0 0
+Po 0 47000 25750 47000 23750 315 -1
+De 0 0 9 0 800
+Po 0 51100 20900 51100 19990 315 -1
+De 0 0 9 0 400
+Po 0 50250 21750 51100 20900 315 -1
+De 0 0 9 0 0
+Po 0 49000 21750 50250 21750 315 -1
+De 0 0 9 0 0
+Po 0 45000 25750 45000 24500 315 -1
+De 0 0 10 0 800
+Po 0 43250 18990 42450 18990 315 -1
+De 0 0 10 0 C00
+Po 0 43750 19490 43250 18990 315 -1
+De 0 0 10 0 400
+Po 0 43750 23250 43750 19490 315 -1
+De 0 0 10 0 0
+Po 0 45000 24500 43750 23250 315 -1
+De 0 0 10 0 0
+Po 0 40000 25750 40000 23250 315 -1
+De 0 0 11 0 800
+Po 0 42050 21200 42050 19990 315 -1
+De 0 0 11 0 400
+Po 0 40000 23250 42050 21200 315 -1
+De 0 0 11 0 0
+Po 0 44000 25250 42850 24100 315 -1
+De 0 0 12 0 0
+Po 0 42850 24100 42850 19990 315 -1
+De 0 0 12 0 400
+Po 0 44000 25750 44000 25250 315 -1
+De 0 0 12 0 800
+Po 0 35000 18990 34200 18990 315 -1
+De 0 0 13 0 C00
+Po 0 35500 19490 35000 18990 315 -1
+De 0 0 13 0 400
+Po 0 39000 24250 35500 20750 315 -1
+De 0 0 13 0 0
+Po 0 35500 20750 35500 19490 315 -1
+De 0 0 13 0 0
+Po 0 39000 25750 39000 24250 315 -1
+De 0 0 13 0 800
+Po 0 37000 24750 33800 21550 315 -1
+De 0 0 14 0 0
+Po 0 37000 25750 37000 24750 315 -1
+De 0 0 14 0 800
+Po 0 33800 21550 33800 19990 315 -1
+De 0 0 14 0 400
+Po 0 38000 24500 34600 21100 315 -1
+De 0 0 15 0 0
+Po 0 34600 21100 34600 19990 315 -1
+De 0 0 15 0 400
+Po 0 38000 25750 38000 24500 315 -1
+De 0 0 15 0 800
+Po 0 36000 25000 33500 22500 315 -1
+De 0 0 16 0 0
+Po 0 36000 25750 36000 25000 315 -1
+De 0 0 16 0 800
+Po 0 27250 19490 26750 18990 315 -1
+De 0 0 16 0 400
+Po 0 26750 18990 25950 18990 315 -1
+De 0 0 16 0 C00
+Po 0 28250 22500 27250 21500 315 -1
+De 0 0 16 0 0
+Po 0 33500 22500 28250 22500 315 -1
+De 0 0 16 0 0
+Po 0 27250 21500 27250 19490 315 -1
+De 0 0 16 0 0
+Po 0 34000 25750 34000 25500 315 -1
+De 0 0 17 0 800
+Po 0 32500 24000 27250 24000 315 -1
+De 0 0 17 0 0
+Po 0 34000 25500 32500 24000 315 -1
+De 0 0 17 0 0
+Po 0 27250 24000 25550 22300 315 -1
+De 0 0 17 0 0
+Po 0 25550 22300 25550 19990 315 -1
+De 0 0 17 0 400
+Po 0 26350 21850 26350 19990 315 -1
+De 0 0 18 0 400
+Po 0 35000 25250 33000 23250 315 -1
+De 0 0 18 0 0
+Po 0 27750 23250 26350 21850 315 -1
+De 0 0 18 0 0
+Po 0 33000 23250 27750 23250 315 -1
+De 0 0 18 0 0
+Po 0 35000 25750 35000 25250 315 -1
+De 0 0 18 0 800
+Po 0 26250 48250 24250 50250 315 -1
+De 0 0 19 0 0
+Po 0 24750 53010 25550 53010 315 -1
+De 0 0 19 0 C00
+Po 0 33000 46250 33000 46500 315 -1
+De 0 0 19 0 800
+Po 0 33000 46500 33000 46250 315 -1
+De 0 0 19 0 400
+Po 0 24750 53010 24250 52510 315 -1
+De 0 0 19 0 800
+Po 0 31250 48250 26250 48250 315 -1
+De 0 0 19 0 0
+Po 0 31250 48250 31250 48250 315 -1
+De 0 0 19 0 0
+Po 0 24250 50250 24250 52510 315 -1
+De 0 0 19 0 0
+Po 0 31250 48250 33000 46500 315 -1
+De 0 0 19 0 0
+Po 0 25950 51300 27000 50250 315 -1
+De 0 0 20 0 0
+Po 0 35000 47000 35000 46250 315 -1
+De 0 0 20 0 400
+Po 0 27000 50250 31750 50250 315 -1
+De 0 0 20 0 0
+Po 0 25950 52010 25950 51300 315 -1
+De 0 0 20 0 800
+Po 0 31750 50250 35000 47000 315 -1
+De 0 0 20 0 0
+Po 0 34000 46750 34000 46250 315 -1
+De 0 0 21 0 400
+Po 0 25150 50850 26750 49250 315 -1
+De 0 0 21 0 0
+Po 0 31500 49250 34000 46750 315 -1
+De 0 0 21 0 0
+Po 0 25150 52010 25150 50850 315 -1
+De 0 0 21 0 800
+Po 0 26750 49250 31500 49250 315 -1
+De 0 0 21 0 0
+Po 0 32500 50750 32500 52510 315 -1
+De 0 0 22 0 0
+Po 0 36000 46250 36000 47250 315 -1
+De 0 0 22 0 800
+Po 0 36000 47250 32500 50750 315 -1
+De 0 0 22 0 0
+Po 0 33000 53010 33800 53010 315 -1
+De 0 0 22 0 C00
+Po 0 32500 52510 33000 53010 315 -1
+De 0 0 22 0 400
+Po 0 38000 47750 34200 51550 315 -1
+De 0 0 23 0 0
+Po 0 34200 51550 34200 52010 315 -1
+De 0 0 23 0 400
+Po 0 38000 46250 38000 47750 315 -1
+De 0 0 23 0 800
+Po 0 37000 46250 37000 47500 315 -1
+De 0 0 24 0 800
+Po 0 33400 51100 33400 52010 315 -1
+De 0 0 24 0 400
+Po 0 37000 47500 33400 51100 315 -1
+De 0 0 24 0 0
+Po 0 41250 53010 42050 53010 315 -1
+De 0 0 25 0 C00
+Po 0 40750 49500 40750 52510 315 -1
+De 0 0 25 0 0
+Po 0 39000 47750 40750 49500 315 -1
+De 0 0 25 0 0
+Po 0 40750 52510 41250 53010 315 -1
+De 0 0 25 0 400
+Po 0 39000 46250 39000 47750 315 -1
+De 0 0 25 0 800
+Po 0 42450 50050 42450 52010 315 -1
+De 0 0 26 0 400
+Po 0 44000 46250 44000 48500 315 -1
+De 0 0 26 0 800
+Po 0 44000 48500 42450 50050 315 -1
+De 0 0 26 0 0
+Po 0 43000 46250 43000 47750 315 -1
+De 0 0 27 0 800
+Po 0 43000 47750 41650 49100 315 -1
+De 0 0 27 0 0
+Po 0 41650 49100 41650 52010 315 -1
+De 0 0 27 0 400
+Po 0 49000 51500 49000 52510 315 -1
+De 0 0 28 0 0
+Po 0 49000 52510 49500 53010 315 -1
+De 0 0 28 0 400
+Po 0 49500 53010 50300 53010 315 -1
+De 0 0 28 0 C00
+Po 0 45000 47500 49000 51500 315 -1
+De 0 0 28 0 0
+Po 0 45000 46250 45000 47500 315 -1
+De 0 0 28 0 800
+Po 0 47000 46250 47000 46750 315 -1
+De 0 0 29 0 800
+Po 0 50700 50450 50700 52010 315 -1
+De 0 0 29 0 400
+Po 0 47000 46750 50700 50450 315 -1
+De 0 0 29 0 0
+Po 0 46000 46250 46000 47000 315 -1
+De 0 0 30 0 800
+Po 0 46000 47000 49900 50900 315 -1
+De 0 0 30 0 0
+Po 0 49900 50900 49900 52010 315 -1
+De 0 0 30 0 400
+Po 0 48000 46500 50750 49250 315 -1
+De 0 0 31 0 0
+Po 0 50750 49250 53000 49250 315 -1
+De 0 0 31 0 0
+Po 0 56750 51000 57250 51500 315 -1
+De 0 0 31 0 0
+Po 0 57750 53010 58550 53010 315 -1
+De 0 0 31 0 C00
+Po 0 48000 46250 48000 46500 315 -1
+De 0 0 31 0 800
+Po 0 57250 51500 57250 52510 315 -1
+De 0 0 31 0 0
+Po 0 53250 49250 55000 51000 315 -1
+De 0 0 31 0 0
+Po 0 57250 52510 57750 53010 315 -1
+De 0 0 31 0 400
+Po 0 55000 51000 56750 51000 315 -1
+De 0 0 31 0 0
+Po 0 53000 49250 53250 49250 315 -1
+De 0 0 31 0 0
+Po 0 55750 49500 57750 49500 315 -1
+De 0 0 32 0 0
+Po 0 51250 47500 53750 47500 315 -1
+De 0 0 32 0 0
+Po 0 50000 46250 50000 46500 315 -1
+De 0 0 32 0 800
+Po 0 50000 46250 51250 47500 315 -1
+De 0 0 32 0 800
+Po 0 53750 47500 55750 49500 315 -1
+De 0 0 32 0 0
+Po 0 57750 49500 58950 50700 315 -1
+De 0 0 32 0 0
+Po 0 58950 50700 58950 52010 315 -1
+De 0 0 32 0 400
+Po 0 49000 46250 49000 46500 315 -1
+De 0 0 33 0 800
+Po 0 57250 50250 58150 51150 315 -1
+De 0 0 33 0 0
+Po 0 53500 48250 55500 50250 315 -1
+De 0 0 33 0 0
+Po 0 55500 50250 57250 50250 315 -1
+De 0 0 33 0 0
+Po 0 49000 46500 50750 48250 315 -1
+De 0 0 33 0 0
+Po 0 53250 48250 53500 48250 315 -1
+De 0 0 33 0 0
+Po 0 58150 51150 58150 52010 315 -1
+De 0 0 33 0 400
+Po 0 50750 48250 53250 48250 315 -1
+De 0 0 33 0 0
+Po 0 60500 31500 63000 31500 315 -1
+De 0 0 34 0 800
+Po 0 63000 31500 65500 31500 315 -1
+De 0 0 34 0 400
+Po 0 63000 29500 63000 31500 315 -1
+De 0 0 34 0 800
+Po 0 55000 34650 55350 34650 315 -1
+De 0 0 35 0 0
+Po 0 63500 27500 65500 29500 315 -1
+De 0 0 35 0 400
+Po 0 33000 33000 33000 33750 315 -1
+De 0 0 35 0 800
+Po 0 42900 34650 55000 34650 315 -1
+De 0 0 35 0 0
+Po 0 55000 34650 55100 34650 315 -1
+De 0 0 35 0 0
+Po 0 42500 34250 42900 34650 315 -1
+De 0 0 35 0 0
+Po 0 63000 27500 63500 27500 315 -1
+De 0 0 35 0 800
+Po 0 42250 32000 42500 32250 315 -1
+De 0 0 35 0 0
+Po 0 40750 32000 42250 32000 315 -1
+De 0 0 35 0 0
+Po 0 40500 32250 40750 32000 315 -1
+De 0 0 35 0 0
+Po 0 40500 33750 40500 32250 157 -1
+De 0 0 35 0 0
+Po 0 40250 34000 40500 33750 315 -1
+De 0 0 35 0 0
+Po 0 33250 34000 40250 34000 315 -1
+De 0 0 35 0 0
+Po 0 33000 33750 33250 34000 315 -1
+De 0 0 35 0 0
+Po 0 59250 30000 59750 30500 315 -1
+De 0 0 35 0 0
+Po 0 59750 30500 60500 30500 315 -1
+De 0 0 35 0 400
+Po 0 56500 30000 58500 30000 157 -1
+De 0 0 35 0 0
+Po 0 56000 30500 56500 30000 315 -1
+De 0 0 35 0 0
+Po 0 56000 34000 56000 30500 315 -1
+De 0 0 35 0 0
+Po 0 55350 34650 56000 34000 315 -1
+De 0 0 35 0 0
+Po 0 42500 32250 42500 34250 157 -1
+De 0 0 35 0 0
+Po 0 61750 28750 63000 27500 315 -1
+De 0 0 35 0 400
+Po 0 61750 29750 61750 28750 315 -1
+De 0 0 35 0 0
+Po 0 61000 30500 61750 29750 315 -1
+De 0 0 35 0 0
+Po 0 60500 30500 61000 30500 315 -1
+De 0 0 35 0 800
+Po 0 59250 30000 58500 30000 315 -1
+De 0 0 35 0 0
+Po 0 53250 26000 55500 23750 315 -1
+De 0 0 36 0 0
+Po 0 61750 20500 64000 18250 315 -1
+De 0 0 36 0 0
+Po 0 61750 21500 61750 20500 315 -1
+De 0 0 36 0 0
+Po 0 59500 23750 61750 21500 315 -1
+De 0 0 36 0 0
+Po 0 55500 23750 59500 23750 315 -1
+De 0 0 36 0 0
+Po 0 64000 18250 71500 18250 315 -1
+De 0 0 36 0 400
+Po 0 53250 33000 53250 26000 315 -1
+De 0 0 36 0 800
+Po 0 65500 26500 65500 24500 500 -1
+De 0 0 37 0 C00
+Po 0 65500 22350 65500 24500 500 -1
+De 0 0 37 0 C00
+Po 0 66000 35000 67250 35000 315 -1
+De 0 0 38 0 C00
+Po 0 66500 22350 66850 22350 315 -1
+De 0 0 38 0 800
+Po 0 67750 35000 67250 35000 315 -1
+De 0 0 38 0 400
+Po 0 68250 34500 67750 35000 315 -1
+De 0 0 38 0 0
+Po 0 68250 23750 68250 26000 315 -1
+De 0 0 38 0 0
+Po 0 68250 26000 68250 34500 315 -1
+De 0 0 38 0 0
+Po 0 66850 22350 68250 23750 315 -1
+De 0 0 38 0 0
+Po 0 66000 36500 66000 35000 315 -1
+De 0 0 38 0 C00
+Po 0 69000 25250 69000 26750 315 -1
+De 0 0 39 0 0
+Po 0 67250 37000 67250 36500 315 -1
+De 0 0 39 0 400
+Po 0 67313 21563 69000 23250 315 -1
+De 0 0 39 0 0
+Po 0 69000 23250 69000 25250 315 -1
+De 0 0 39 0 0
+Po 0 69000 26750 69000 35250 315 -1
+De 0 0 39 0 0
+Po 0 66000 38000 66250 38000 315 -1
+De 0 0 39 0 800
+Po 0 66250 38000 67250 37000 315 -1
+De 0 0 39 0 0
+Po 0 69000 35250 67750 36500 315 -1
+De 0 0 39 0 0
+Po 0 67313 21563 66500 21563 315 -1
+De 0 0 39 0 400
+Po 0 67250 36500 67750 36500 315 -1
+De 0 0 39 0 800
+Po 0 31000 38750 31250 39000 315 -1
+De 0 0 40 0 0
+Po 0 31250 39000 32000 39000 315 -1
+De 0 0 40 0 400
+Po 0 33000 28750 34000 28750 315 -1
+De 0 0 40 0 C00
+Po 0 31000 37000 31000 30250 315 -1
+De 0 0 40 0 0
+Po 0 31000 30250 32500 28750 315 -1
+De 0 0 40 0 0
+Po 0 33000 28750 32500 28750 315 -1
+De 0 0 40 0 800
+Po 0 31000 37000 31000 38750 315 -1
+De 0 0 40 0 0
+Po 0 35000 33000 35000 28750 315 -1
+De 0 0 41 0 C00
+Po 0 36000 33000 36000 28750 315 -1
+De 0 0 42 0 C00
+Po 0 37000 33000 37000 28750 315 -1
+De 0 0 43 0 C00
+Po 0 38000 33000 38000 28750 315 -1
+De 0 0 44 0 C00
+Po 0 39000 33000 39000 28750 315 -1
+De 0 0 45 0 C00
+Po 0 40000 33000 40000 28750 315 -1
+De 0 0 46 0 C00
+Po 0 53000 44250 52000 44250 500 -1
+De 0 0 47 0 800
+Po 0 30000 29500 31750 27750 500 -1
+De 0 0 47 0 0
+Po 0 30000 39500 30000 29500 500 -1
+De 0 0 47 0 0
+Po 0 31000 40500 30000 39500 500 -1
+De 0 0 47 0 0
+Po 0 31000 43250 31000 40500 500 -1
+De 0 0 47 0 800
+Po 0 52000 44250 42000 44250 500 -1
+De 0 0 47 0 0
+Po 0 41000 28750 41000 27750 500 -1
+De 0 0 47 0 800
+Po 0 42000 43250 42000 44250 500 -1
+De 0 0 47 0 800
+Po 0 31000 43250 31000 44250 500 -1
+De 0 0 47 0 800
+Po 0 52000 27750 41000 27750 500 -1
+De 0 0 47 0 0
+Po 0 52000 28750 52000 27750 500 -1
+De 0 0 47 0 800
+Po 0 31000 44250 42000 44250 500 -1
+De 0 0 47 0 0
+Po 0 31750 27750 41000 27750 500 -1
+De 0 0 47 0 0
+Po 0 30750 26750 41000 26750 500 -1
+De 0 0 48 0 0
+Po 0 53000 45250 51000 45250 500 -1
+De 0 0 48 0 800
+Po 0 51000 45250 42250 45250 500 -1
+De 0 0 48 0 0
+Po 0 41000 25750 41000 26750 500 -1
+De 0 0 48 0 800
+Po 0 42000 46250 42000 45250 500 -1
+De 0 0 48 0 800
+Po 0 31000 45250 30000 45250 500 -1
+De 0 0 48 0 0
+Po 0 31000 46250 31000 45250 500 -1
+De 0 0 48 0 800
+Po 0 31000 45250 42250 45250 500 -1
+De 0 0 48 0 0
+Po 0 28750 44000 28750 28750 500 -1
+De 0 0 48 0 0
+Po 0 52000 26750 41000 26750 500 -1
+De 0 0 48 0 0
+Po 0 52000 25750 52000 26750 500 -1
+De 0 0 48 0 800
+Po 0 42000 45250 42250 45250 500 -1
+De 0 0 48 0 0
+Po 0 30000 45250 28750 44000 500 -1
+De 0 0 48 0 0
+Po 0 28750 28750 30750 26750 500 -1
+De 0 0 48 0 0
+Po 0 39000 39000 39000 43250 315 -1
+De 0 0 49 0 C00
+Po 0 38000 39000 38000 43250 315 -1
+De 0 0 50 0 C00
+Po 0 37000 39000 37000 43250 315 -1
+De 0 0 51 0 C00
+Po 0 36000 39000 36000 43250 315 -1
+De 0 0 52 0 C00
+Po 0 35000 39000 35000 43250 315 -1
+De 0 0 53 0 C00
+Po 0 34000 39000 34000 43250 315 -1
+De 0 0 54 0 C00
+Po 0 33000 43250 32000 43250 315 -1
+De 0 0 55 0 C00
+Po 0 33000 39000 33000 43250 315 -1
+De 0 0 55 0 C00
+Po 0 50000 39000 50000 43250 315 -1
+De 0 0 56 0 C00
+Po 0 49000 39000 49000 43250 315 -1
+De 0 0 57 0 C00
+Po 0 48000 39000 48000 43250 315 -1
+De 0 0 58 0 C00
+Po 0 47000 39000 47000 43250 315 -1
+De 0 0 59 0 C00
+Po 0 46000 39000 46000 43250 315 -1
+De 0 0 60 0 C00
+Po 0 45000 39000 45000 43250 315 -1
+De 0 0 61 0 C00
+Po 0 44000 39000 44000 43250 315 -1
+De 0 0 62 0 C00
+Po 0 43000 39000 43000 43250 315 -1
+De 0 0 63 0 C00
+Po 0 44000 33000 44000 28750 315 -1
+De 0 0 64 0 C00
+Po 0 45000 33000 45000 28750 315 -1
+De 0 0 65 0 C00
+Po 0 46000 33000 46000 28750 315 -1
+De 0 0 66 0 C00
+Po 0 47000 33000 47000 28750 315 -1
+De 0 0 67 0 C00
+Po 0 48000 33000 48000 28750 315 -1
+De 0 0 68 0 C00
+Po 0 49000 33000 49000 28750 315 -1
+De 0 0 69 0 C00
+Po 0 50000 33000 50000 28750 315 -1
+De 0 0 70 0 C00
+Po 0 51000 33000 51000 28750 315 -1
+De 0 0 71 0 C00
+Po 0 66000 46750 66000 43750 500 -1
+De 0 0 72 0 0
+Po 0 62500 48000 64750 48000 500 -1
+De 0 0 72 0 800
+Po 0 66000 46750 64750 48000 500 -1
+De 0 0 72 0 0
+Po 0 68250 41500 69000 41500 500 -1
+De 0 0 72 0 400
+Po 0 66000 43750 68250 41500 500 -1
+De 0 0 72 0 0
+Po 0 57250 47500 55000 45250 500 -1
+De 0 0 72 0 0
+Po 0 62000 47500 62500 48000 500 -1
+De 0 0 72 0 400
+Po 0 55000 44250 55000 45250 500 -1
+De 0 0 72 0 800
+Po 0 62000 47500 57250 47500 500 -1
+De 0 0 72 0 0
+Po 0 70250 29500 70250 26750 500 -1
+De 0 0 73 0 800
+Po 0 70250 26750 70500 26500 500 -1
+De 0 0 73 0 400
+Po 0 57500 31500 58000 31500 315 -1
+De 0 0 73 0 800
+Po 0 59500 33500 60500 33500 315 -1
+De 0 0 73 0 400
+Po 0 58500 32500 59500 33500 315 -1
+De 0 0 73 0 0
+Po 0 58500 32000 58500 32500 315 -1
+De 0 0 73 0 0
+Po 0 58000 31500 58500 32000 315 -1
+De 0 0 73 0 0
+Po 0 60500 33500 63000 33500 500 -1
+De 0 0 73 0 C00
+Po 0 63000 33500 63000 40500 500 -1
+De 0 0 73 0 800
+Po 0 51000 40500 63000 40500 500 -1
+De 0 0 73 0 800
+Po 0 63000 40500 65250 40500 500 -1
+De 0 0 73 0 0
+Po 0 65250 40500 70000 35750 500 -1
+De 0 0 73 0 0
+Po 0 70000 35750 70000 33250 500 -1
+De 0 0 73 0 0
+Po 0 70000 33250 70000 30000 500 -1
+De 0 0 73 0 0
+Po 0 70000 30000 70250 29750 500 -1
+De 0 0 73 0 0
+Po 0 70250 29750 70250 29500 500 -1
+De 0 0 73 0 400
+Po 0 51000 39000 51000 40500 500 -1
+De 0 0 73 0 C00
+Po 0 55500 42750 56250 43500 315 -1
+De 0 0 74 0 800
+Po 0 60500 43500 61500 42500 315 -1
+De 0 0 74 0 400
+Po 0 56250 43500 57750 43500 315 -1
+De 0 0 74 0 0
+Po 0 57750 43500 60500 43500 315 -1
+De 0 0 74 0 0
+Po 0 57750 45500 57750 43500 315 -1
+De 0 0 74 0 800
+Po 0 62500 44250 63250 45000 315 -1
+De 0 0 75 0 400
+Po 0 62500 42500 62500 44250 315 -1
+De 0 0 75 0 800
+Po 0 65000 46000 65000 43500 315 -1
+De 0 0 76 0 0
+Po 0 64500 46500 65000 46000 315 -1
+De 0 0 76 0 0
+Po 0 63250 46500 64500 46500 315 -1
+De 0 0 76 0 800
+Po 0 68000 40500 69000 40500 315 -1
+De 0 0 76 0 400
+Po 0 65000 43500 68000 40500 315 -1
+De 0 0 76 0 0
+Po 0 54750 34000 55250 33500 315 -1
+De 0 0 77 0 0
+Po 0 55250 29750 55500 29500 315 -1
+De 0 0 77 0 400
+Po 0 55250 33500 55250 29750 315 -1
+De 0 0 77 0 0
+Po 0 55500 29500 57500 29500 315 -1
+De 0 0 77 0 C00
+Po 0 43000 33750 43250 34000 315 -1
+De 0 0 77 0 0
+Po 0 43000 33000 43000 33750 315 -1
+De 0 0 77 0 800
+Po 0 43250 34000 54750 34000 315 -1
+De 0 0 77 0 0
+Po 0 60500 37500 59000 37500 315 -1
+De 0 0 78 0 800
+Po 0 56250 36750 56250 35750 315 -1
+De 0 0 78 0 0
+Po 0 56250 35750 55750 35250 315 -1
+De 0 0 78 0 0
+Po 0 55750 35250 54750 35250 315 -1
+De 0 0 78 0 0
+Po 0 58500 37000 59000 37500 315 -1
+De 0 0 78 0 0
+Po 0 56500 37000 58500 37000 157 -1
+De 0 0 78 0 0
+Po 0 42250 35250 54750 35250 315 -1
+De 0 0 78 0 0
+Po 0 42000 35000 42250 35250 315 -1
+De 0 0 78 0 0
+Po 0 42000 34750 42000 35000 315 -1
+De 0 0 78 0 0
+Po 0 42000 34750 42000 33000 315 -1
+De 0 0 78 0 400
+Po 0 56500 37000 56250 36750 315 -1
+De 0 0 78 0 0
+Po 0 60500 38500 58750 38500 315 -1
+De 0 0 79 0 800
+Po 0 55500 36000 55500 37250 315 -1
+De 0 0 79 0 0
+Po 0 55500 37250 56250 38000 315 -1
+De 0 0 79 0 0
+Po 0 56250 38000 56500 38000 315 -1
+De 0 0 79 0 0
+Po 0 58250 38000 58750 38500 315 -1
+De 0 0 79 0 0
+Po 0 56500 38000 58250 38000 157 -1
+De 0 0 79 0 0
+Po 0 55500 36000 54250 36000 315 -1
+De 0 0 79 0 0
+Po 0 41000 33000 41000 35100 315 -1
+De 0 0 79 0 800
+Po 0 41000 35100 41900 36000 315 -1
+De 0 0 79 0 0
+Po 0 41900 36000 54250 36000 315 -1
+De 0 0 79 0 0
+Po 0 54250 36000 54300 36000 315 -1
+De 0 0 79 0 0
+Po 0 42500 38500 42500 39750 157 -1
+De 0 0 80 0 0
+Po 0 42500 39750 42250 40000 315 -1
+De 0 0 80 0 0
+Po 0 42250 40000 40250 40000 315 -1
+De 0 0 80 0 0
+Po 0 40250 40000 40000 39750 315 -1
+De 0 0 80 0 0
+Po 0 40000 39750 40000 39000 315 -1
+De 0 0 80 0 400
+Po 0 51500 38000 52250 38750 315 -1
+De 0 0 80 0 0
+Po 0 55500 38750 52250 38750 315 -1
+De 0 0 80 0 800
+Po 0 43000 38000 50250 38000 315 -1
+De 0 0 80 0 0
+Po 0 42500 38500 43000 38000 315 -1
+De 0 0 80 0 0
+Po 0 50250 38000 51500 38000 315 -1
+De 0 0 80 0 0
+Po 0 52150 36650 52900 36650 315 -1
+De 0 0 81 0 0
+Po 0 41450 36650 52150 36650 315 -1
+De 0 0 81 0 0
+Po 0 41000 37100 41450 36650 315 -1
+De 0 0 81 0 0
+Po 0 41000 39000 41000 37100 315 -1
+De 0 0 81 0 800
+Po 0 52900 36650 53250 37000 315 -1
+De 0 0 81 0 400
+Po 0 54000 37750 54250 37750 315 -1
+De 0 0 82 0 0
+Po 0 52050 37300 52500 37750 315 -1
+De 0 0 82 0 0
+Po 0 52500 37750 54000 37750 315 -1
+De 0 0 82 0 0
+Po 0 51250 37300 52050 37300 315 -1
+De 0 0 82 0 0
+Po 0 54500 37500 54500 37000 315 -1
+De 0 0 82 0 400
+Po 0 54250 37750 54500 37500 315 -1
+De 0 0 82 0 0
+Po 0 42100 37300 51250 37300 315 -1
+De 0 0 82 0 0
+Po 0 51250 37300 51300 37300 315 -1
+De 0 0 82 0 0
+Po 0 42000 39000 42000 37400 315 -1
+De 0 0 82 0 800
+Po 0 42000 37400 42100 37300 315 -1
+De 0 0 82 0 0
+Po 0 64000 45750 64000 43750 315 -1
+De 0 0 83 0 400
+Po 0 59250 45000 59250 45750 315 -1
+De 0 0 83 0 800
+Po 0 59250 45750 59250 46500 315 -1
+De 0 0 83 0 400
+Po 0 59250 45750 64000 45750 315 -1
+De 0 0 83 0 0
+Po 0 62000 37750 62000 38000 315 -1
+De 0 0 84 0 400
+Po 0 60750 36500 62000 37750 315 -1
+De 0 0 84 0 0
+Po 0 60250 36500 60500 36500 315 -1
+De 0 0 84 0 400
+Po 0 60500 36500 60750 36500 315 -1
+De 0 0 84 0 800
+Po 0 61000 35500 62000 36500 315 -1
+De 0 0 85 0 400
+Po 0 60500 35500 61000 35500 315 -1
+De 0 0 85 0 800
+Po 0 60500 34500 61500 34500 315 -1
+De 0 0 86 0 800
+Po 0 61500 34500 62000 35000 315 -1
+De 0 0 86 0 400
+Po 0 54500 33000 54500 29000 315 -1
+De 0 0 87 0 800
+Po 0 55000 28500 57500 28500 315 -1
+De 0 0 87 0 400
+Po 0 54500 29000 55000 28500 315 -1
+De 0 0 87 0 0
+Po 0 60500 25750 61500 24750 315 -1
+De 0 0 88 0 400
+Po 0 60500 26500 60500 25750 315 -1
+De 0 0 88 0 800
+$EndTRACK
+$ZONE
+Po 0 58484 28978 59516 28978 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58583 28722 59415 28722 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58609 28466 59392 28466 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58568 28210 59432 28210 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 28210 54136 28210 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58499 27954 59500 27954 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 27954 54392 27954 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58588 27698 59411 27698 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 27698 54850 27698 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58609 27442 59392 27442 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 27442 56392 27442 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58558 27186 59442 27186 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 27186 56442 27186 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58509 26930 59489 26930 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 26930 56489 26930 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58593 26674 59406 26674 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 26674 56406 26674 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58609 26418 59392 26418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55782 26418 56392 26418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54066 26418 55212 26418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58549 26162 59452 26162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56194 26162 56452 26162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54241 26162 54807 26162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58409 25906 59593 25906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56367 25906 56593 25906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54497 25906 54630 25906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58109 25650 59694 25650 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56448 25650 56893 25650 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56456 25394 59769 25394 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56387 25138 59958 25138 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56237 24882 60214 24882 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55895 24626 60470 24626 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60024 24370 60544 24370 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60289 24114 60613 24114 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60545 23858 60545 23858 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 31830 34184 31830 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 31574 34184 31574 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 31318 34184 31318 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 31062 34184 31062 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 30806 34184 30806 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31854 30550 34184 30550 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32110 30294 34184 30294 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32366 30038 34184 30038 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 33624 29782 33624 29782 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59316 32096 59480 32096 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59300 31840 59452 31840 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59199 31584 59391 31584 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58982 31328 59407 31328 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58726 31072 59168 31072 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58557 30816 58912 30816 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 39223 37917 39773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 38223 37917 38773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 37223 37917 37773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 36223 37917 36773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35223 37917 35773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 34223 37917 34773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 33223 37917 33773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32223 37917 32773 37917 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 37661 40184 37661 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 37405 40184 37405 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 37149 40184 37149 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 36893 40214 36893 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 36637 40329 36637 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 36381 40565 36381 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 36125 40821 36125 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 35869 40615 35869 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 35613 40369 35613 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 35357 40229 35357 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 35101 40184 35101 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 34845 40184 34845 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 34589 32687 34589 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31816 34333 32429 34333 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32254 34077 32254 34077 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 39452 65011 39452 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 39196 65267 39196 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 38940 65523 38940 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 38684 65328 38684 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 38428 65139 38428 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 38172 65057 38172 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 37916 65043 37916 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 37660 65103 37660 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 37404 65248 37404 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 37148 65294 37148 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 36892 65125 36892 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 36636 65051 36636 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 36380 65046 36380 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 36124 65119 36124 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 35868 65184 35868 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 35612 65184 35612 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 35356 65110 35356 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 35100 65044 35100 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 34844 65054 34844 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 34588 65134 34588 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 34332 65314 34332 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66266 34076 66573 34076 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 34076 65734 34076 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63909 33820 67434 33820 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63931 33564 67434 33564 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63914 33308 67434 33308 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63824 33052 67434 33052 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63891 32796 67434 32796 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63932 32540 67434 32540 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67008 32284 67434 32284 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67270 32028 67434 32028 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67396 31772 67434 31772 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67432 31516 67434 31516 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67405 31260 67434 31260 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67292 31004 67434 31004 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67056 30748 67434 30748 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63816 30492 67434 30492 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67081 30236 67434 30236 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63816 30236 64922 30236 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67304 29980 67434 29980 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63889 29980 64698 29980 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67407 29724 67434 29724 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63982 29724 64570 29724 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67433 29468 67434 29468 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64007 29468 64314 29468 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67392 29212 67434 29212 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63971 29212 64058 29212 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67260 28956 67434 28956 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66985 28700 67434 28700 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65985 28700 66016 28700 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65598 28444 67434 28444 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65342 28188 67434 28188 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65086 27932 67434 27932 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64830 27676 67434 27676 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61592 27676 61669 27676 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65777 27420 67434 27420 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64574 27420 65221 27420 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61609 27420 61925 27420 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66192 27164 67434 27164 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64318 27164 64809 27164 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61549 27164 62048 27164 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66366 26908 67434 26908 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64059 26908 64631 26908 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61518 26908 62184 26908 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66447 26652 67434 26652 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63547 26652 64554 26652 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61597 26652 62455 26652 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66456 26396 67434 26396 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61607 26396 64543 26396 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 26140 67434 26140 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61540 26140 64591 26140 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 25884 67434 25884 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61519 25884 64591 25884 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 25628 67434 25628 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62121 25628 64591 25628 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 25372 67434 25372 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62378 25372 64162 25372 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 25116 67434 25116 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62459 25116 63796 25116 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 24860 67434 24860 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62459 24860 63637 24860 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66431 24604 67434 24604 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62459 24604 63569 24604 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66422 24348 67434 24348 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62452 24348 63578 24348 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 24092 67434 24092 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62396 24092 63659 24092 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 23836 67182 23836 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62455 23836 63844 23836 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 23580 66926 23580 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62443 23580 64338 23580 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66409 23324 66670 23324 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62361 23324 64591 23324 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62174 23068 64591 23068 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61697 22812 64591 22812 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 61847 22556 64564 22556 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62103 22300 64543 22300 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62353 22044 64589 22044 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62510 21788 64567 21788 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64230 21532 64543 21532 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62563 21532 63039 21532 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64545 21276 64582 21276 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62566 21276 62734 21276 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62566 21020 62566 21020 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 50969 43201 54651 43201 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 50969 42945 54562 42945 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 50960 42689 54543 42689 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 57975 42433 60413 42433 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56406 42433 57530 42433 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51088 42433 54594 42433 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 50858 42433 50934 42433 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58428 42177 60622 42177 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56270 42177 57072 42177 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51643 42177 54732 42177 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58611 41921 60581 41921 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55985 41921 56886 41921 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51834 41921 55018 41921 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58694 41665 60566 41665 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51920 41665 56806 41665 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58707 41409 60566 41409 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51933 41409 56792 41409 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60072 50955 61509 50955 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59766 50699 61591 50699 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59721 50443 61591 50443 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59581 50187 61509 50187 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59335 49931 61493 49931 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59079 49675 61544 49675 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58823 49419 61581 49419 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58567 49163 61505 49163 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58308 48907 61493 48907 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56055 48651 61554 48651 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55799 48395 57113 48395 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55543 48139 56603 48139 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55287 47883 56347 47883 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 55031 47627 56091 47627 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54775 47371 55835 47371 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54519 47115 55579 47115 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54250 46859 55323 46859 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51506 46603 55067 46603 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51250 46347 54811 46347 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54555 46091 54555 46091 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 55018 79819 55018 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59495 54762 79819 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51245 54762 57005 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 42995 54762 48755 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 34745 54762 40505 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 26495 54762 32255 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 54762 24005 54762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59779 54506 79819 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51529 54506 56720 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43279 54506 48470 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35029 54506 40220 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 26779 54506 31970 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 54506 23720 54506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62435 54250 79819 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60026 54250 61259 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56235 54250 56464 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54185 54250 55059 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51776 54250 53009 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 47985 54250 48214 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 45935 54250 46809 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43526 54250 44759 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 39735 54250 39964 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 37685 54250 38559 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35276 54250 36509 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31485 54250 31714 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 29435 54250 30309 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27026 54250 28259 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23235 54250 23464 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 54250 22059 54250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72580 53994 79819 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66580 53994 71415 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62742 53994 65415 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60189 53994 60958 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54492 53994 54758 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 51939 53994 52708 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 46242 53994 46508 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43689 53994 44458 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 37992 53994 38258 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35439 53994 36208 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 29742 53994 30008 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27189 53994 27958 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 53994 21758 53994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73023 53738 79819 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67023 53738 70973 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62900 53738 64973 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60250 53738 60797 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52000 53738 52547 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43750 53738 44297 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35500 53738 36047 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27250 53738 27797 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 53738 21597 53738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73269 53482 79819 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67269 53482 70726 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62984 53482 64726 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60259 53482 60715 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52009 53482 52465 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43759 53482 44215 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35509 53482 35965 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27259 53482 27715 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 53482 21515 53482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79104 53226 79819 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73430 53226 77749 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67430 53226 70563 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63006 53226 64563 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60413 53226 60693 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52163 53226 52443 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 43913 53226 44193 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35663 53226 35943 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27413 53226 27693 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20049 53226 21493 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 53226 18694 53226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79447 52970 79819 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 74832 52970 77402 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68832 52970 70462 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62976 52970 64462 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60583 52970 60726 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52333 52970 52476 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 44083 52970 44226 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35833 52970 35976 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27583 52970 27726 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20392 52970 21526 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 52970 18347 52970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79656 52714 79819 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75154 52714 77194 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69154 52714 70409 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62882 52714 64409 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20601 52714 21620 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 52714 18139 52714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79786 52458 79819 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75356 52458 77065 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69356 52458 70398 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62696 52458 64398 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20731 52458 21804 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 52458 18010 52458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75486 52202 76991 52202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69486 52202 70425 52202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62832 52202 64425 52202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20803 52202 22153 52202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75565 51946 76966 51946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69565 51946 70494 51946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63088 51946 64494 51946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20826 51946 22591 51946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75599 51690 76985 51690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69599 51690 70612 51690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63289 51690 64612 51690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20810 51690 22591 51690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79799 51434 79819 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75602 51434 77051 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69602 51434 70522 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63389 51434 64522 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20744 51434 22591 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 51434 17995 51434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79678 51178 79819 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75551 51178 77171 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69551 51178 70409 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63409 51178 64409 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20623 51178 22591 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 51178 18116 51178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79482 50922 79819 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75455 50922 77368 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69455 50922 70396 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63409 50922 64396 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20427 50922 22591 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 50922 18313 50922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79163 50666 79819 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75304 50666 77691 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69304 50666 70396 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63409 50666 64396 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20108 50666 22591 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 50666 18636 50666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 75078 50410 79819 50410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69078 50410 70396 50410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63421 50410 64396 50410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 50410 22591 50410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 74698 50154 79819 50154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68698 50154 70396 50154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63498 50154 64396 50154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 50154 22591 50154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73604 49898 79819 49898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67637 49898 70396 49898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63508 49898 64396 49898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 49898 22591 49898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73604 49642 79819 49642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67893 49642 70396 49642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63444 49642 64396 49642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 49642 22591 49642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 49642 18529 49642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73604 49386 79819 49386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63431 49386 64396 49386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 49386 22602 49386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 49386 18529 49386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73604 49130 79819 49130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63504 49130 64396 49130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 49130 22672 49130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 49130 18529 49130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73543 48874 79819 48874 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 48874 22843 48874 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 48874 18529 48874 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73328 48618 79819 48618 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 48618 23096 48618 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 48618 18529 48618 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72909 48362 79819 48362 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 48362 23352 48362 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 48362 18529 48362 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72909 48106 79819 48106 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 48106 23608 48106 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 48106 18529 48106 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73392 47850 79819 47850 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 47850 23864 47850 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 47850 18529 47850 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73724 47594 79819 47594 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 47594 24120 47594 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 47594 18529 47594 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73872 47338 79819 47338 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 47338 24376 47338 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 47338 18529 47338 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73931 47082 79819 47082 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 47082 24632 47082 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 47082 18529 47082 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73918 46826 79819 46826 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 46826 24888 46826 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 46826 18529 46826 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73833 46570 79819 46570 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 46570 25144 46570 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 46570 18529 46570 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73635 46314 79819 46314 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 46314 25400 46314 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 46314 18529 46314 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72292 46058 79819 46058 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 46058 25656 46058 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 46058 18529 46058 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69663 45802 79819 45802 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 45802 25912 45802 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 45802 18529 45802 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69570 45546 79819 45546 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 45546 26168 45546 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 45546 18529 45546 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69361 45290 79819 45290 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 45290 26424 45290 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 45290 18529 45290 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68159 45034 79819 45034 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 45034 26591 45034 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 45034 18529 45034 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68256 44778 79819 44778 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 44778 26591 44778 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 44778 18529 44778 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68975 44522 79819 44522 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 44522 26591 44522 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 44522 18529 44522 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69270 44266 79819 44266 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 44266 26591 44266 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 44266 18529 44266 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69526 44010 79819 44010 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 44010 26591 44010 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 44010 18529 44010 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77678 43754 79819 43754 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69757 43754 73322 43754 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 43754 26591 43754 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 43754 18529 43754 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77860 43498 79819 43498 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69869 43498 73139 43498 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 43498 26591 43498 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 43498 18529 43498 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 43242 79819 43242 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69909 43242 73091 43242 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 43242 26591 43242 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 43242 18529 43242 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 42986 79819 42986 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69995 42986 73091 42986 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63316 42986 63419 42986 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 42986 26591 42986 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 42986 18529 42986 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 42730 79819 42730 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70009 42730 73091 42730 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63405 42730 64616 42730 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 42730 26591 42730 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 42730 18529 42730 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 42474 79819 42474 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70009 42474 73091 42474 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63433 42474 64872 42474 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 42474 26591 42474 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 42474 18529 42474 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 42218 79819 42218 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70009 42218 73091 42218 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63394 42218 65128 42218 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 42218 26591 42218 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 42218 18529 42218 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 41962 79819 41962 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69985 41962 73091 41962 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 63264 41962 65384 41962 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 41962 26591 41962 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 41962 18529 41962 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 41706 79819 41706 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69986 41706 73091 41706 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62994 41706 65640 41706 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 41706 26591 41706 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 41706 18529 41706 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 41450 79819 41450 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70007 41450 73091 41450 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62434 41450 65896 41450 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 41450 26591 41450 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 41450 18529 41450 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 41194 79819 41194 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69965 41194 73091 41194 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65829 41194 66152 41194 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 41194 26591 41194 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 41194 18529 41194 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 40938 79819 40938 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69908 40938 73091 40938 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66096 40938 66408 40938 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 40938 26591 40938 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 40938 18529 40938 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 40682 79819 40682 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69992 40682 73091 40682 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66352 40682 66664 40682 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 40682 26591 40682 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 40682 18529 40682 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 40426 79819 40426 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70007 40426 73091 40426 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66608 40426 66920 40426 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 40426 26591 40426 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 40426 18529 40426 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 40170 79819 40170 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69955 40170 73091 40170 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66864 40170 67176 40170 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 40170 26591 40170 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 40170 18529 40170 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77909 39914 79819 39914 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69821 39914 73091 39914 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67120 39914 67433 39914 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 39914 26591 39914 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 39914 18529 39914 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77904 39658 79819 39658 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69555 39658 73096 39658 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67376 39658 68446 39658 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 39658 26591 39658 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 39658 18529 39658 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77811 39402 79819 39402 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67632 39402 73190 39402 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 39402 26591 39402 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 39402 18529 39402 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 77515 39146 79819 39146 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 67888 39146 73486 39146 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 39146 26591 39146 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 39146 18529 39146 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68144 38890 79819 38890 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 38890 26591 38890 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 38890 18529 38890 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68400 38634 79819 38634 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 38634 26591 38634 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 38634 18529 38634 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68656 38378 79819 38378 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 38378 26591 38378 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 38378 18529 38378 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68912 38122 79819 38122 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 38122 26591 38122 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 38122 18529 38122 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69168 37866 79819 37866 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 37866 26591 37866 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 37866 18529 37866 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69424 37610 79819 37610 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 37610 26591 37610 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 37610 18529 37610 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71785 37354 79819 37354 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69680 37354 70712 37354 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 37354 26591 37354 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 37354 18529 37354 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72062 37098 79819 37098 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69936 37098 70436 37098 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 37098 26591 37098 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 37098 18529 37098 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72201 36842 79819 36842 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70192 36842 70300 36842 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 36842 26591 36842 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 36842 18529 36842 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72255 36586 79819 36586 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 36586 26591 36586 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 36586 18529 36586 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72245 36330 79819 36330 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 36330 26591 36330 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 36330 18529 36330 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72165 36074 79819 36074 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 36074 26591 36074 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 36074 18529 36074 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71994 35818 79819 35818 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 35818 26591 35818 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 35818 18529 35818 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72087 35562 79819 35562 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 35562 26591 35562 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 35562 18529 35562 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72214 35306 79819 35306 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 35306 26591 35306 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 35306 18529 35306 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72256 35050 79819 35050 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 35050 26591 35050 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 35050 18529 35050 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72238 34794 79819 34794 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 34794 26591 34794 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 34794 18529 34794 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72150 34538 79819 34538 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 34538 26591 34538 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 34538 18529 34538 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71958 34282 79819 34282 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 34282 26591 34282 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 34282 18529 34282 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71520 34026 79819 34026 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 34026 70975 34026 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 34026 26591 34026 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 34026 18529 34026 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 33770 79819 33770 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 33770 26591 33770 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 33770 18529 33770 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 33514 79819 33514 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 33514 26591 33514 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 33514 18529 33514 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 33258 79819 33258 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 33258 26591 33258 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 33258 18529 33258 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 33002 79819 33002 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 33002 26591 33002 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 33002 18529 33002 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 32746 79819 32746 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 32746 26591 32746 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 32746 18529 32746 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 32490 79819 32490 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 32490 26591 32490 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 32490 18529 32490 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 32234 79819 32234 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 32234 26591 32234 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 32234 18529 32234 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 31978 79819 31978 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 31978 26591 31978 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 31978 18529 31978 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 31722 79819 31722 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 31722 26591 31722 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 31722 18529 31722 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 31466 79819 31466 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 31466 26591 31466 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 31466 18529 31466 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 31210 79819 31210 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 31210 26591 31210 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 31210 18529 31210 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 30954 79819 30954 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 30954 26591 30954 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 30954 18529 30954 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 30698 79819 30698 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 30698 26591 30698 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 30698 18529 30698 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70909 30442 79819 30442 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 30442 26591 30442 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 30442 18529 30442 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71883 30186 79819 30186 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 30186 26591 30186 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 30186 18529 30186 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72080 29930 79819 29930 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 29930 26591 29930 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 29930 18529 29930 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72168 29674 79819 29674 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 29674 26591 29674 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 29674 18529 29674 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72183 29418 79819 29418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 29418 26591 29418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 29418 18529 29418 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72121 29162 79819 29162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 29162 26591 29162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 29162 18529 29162 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71977 28906 79819 28906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 28906 26591 28906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 28906 18529 28906 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71639 28650 79819 28650 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 28650 26591 28650 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 28650 18529 28650 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71159 28394 79819 28394 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 28394 26591 28394 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 28394 18529 28394 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71159 28138 79819 28138 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 28138 26591 28138 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 28138 18529 28138 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71159 27882 79819 27882 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 27882 26591 27882 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 27882 18529 27882 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71159 27626 79819 27626 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 27626 26591 27626 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 27626 18529 27626 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71159 27370 79819 27370 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 27370 26591 27370 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 27370 18529 27370 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71239 27114 79819 27114 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 27114 26591 27114 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 27114 18529 27114 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71389 26858 79819 26858 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 26858 26591 26858 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 26858 18529 26858 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71455 26602 79819 26602 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 26602 26591 26602 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 26602 18529 26602 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71446 26346 79819 26346 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 26346 26591 26346 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 26346 18529 26346 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71368 26090 79819 26090 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 26090 26554 26090 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 26090 18529 26090 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71189 25834 79819 25834 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 25834 26298 25834 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 25834 18529 25834 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 70776 25578 79819 25578 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 25578 70226 25578 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 25578 26042 25578 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 25578 18529 25578 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 25322 79819 25322 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 25322 25786 25322 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 25322 18529 25322 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 25066 79819 25066 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 25066 25530 25066 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 25066 18529 25066 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 24810 79819 24810 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 24810 25274 24810 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 24810 18529 24810 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 24554 79819 24554 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 24554 25018 24554 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 24554 18529 24554 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 24298 79819 24298 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 24298 24762 24298 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 24298 18529 24298 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 24042 79819 24042 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 24042 24506 24042 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 24042 18529 24042 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 23786 79819 23786 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 23786 24250 23786 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 23786 18529 23786 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 23530 79819 23530 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 23530 24015 23530 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 23530 18529 23530 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69816 23274 79819 23274 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 23274 23887 23274 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 23274 18529 23274 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69778 23018 79819 23018 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 23018 23842 23018 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 23018 18529 23018 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69651 22762 79819 22762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 22762 23841 22762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 22762 18529 22762 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69410 22506 79819 22506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 22506 23841 22506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 22506 18529 22506 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69154 22250 79819 22250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 22250 23841 22250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 22250 18529 22250 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68898 21994 79819 21994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 21994 23841 21994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 21994 18529 21994 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68642 21738 79819 21738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 21738 23841 21738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 21738 18529 21738 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 78644 21482 79819 21482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69033 21482 78192 21482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20289 21482 23841 21482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 21482 18529 21482 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79277 21226 79819 21226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69305 21226 77576 21226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20222 21226 23841 21226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 21226 18521 21226 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79554 20970 79819 20970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69454 20970 77295 20970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64729 20970 64745 20970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20499 20970 23841 20970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 20970 18240 20970 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79721 20714 79819 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69532 20714 77124 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 66954 20714 67191 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 65954 20714 66048 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64808 20714 65048 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20666 20714 23841 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 20714 18069 20714 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69549 20458 77021 20458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64825 20458 67174 20458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20770 20458 23841 20458 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69516 20202 76971 20202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64792 20202 67210 20202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20824 20202 23785 20202 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69420 19946 76968 19946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64696 19946 67306 19946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20828 19946 23785 19946 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 69234 19690 77008 19690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64510 19690 67490 19690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23330 19690 23798 19690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20788 19690 21973 19690 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79754 19434 79819 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 68895 19434 77097 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64171 19434 67826 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23584 19434 23841 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20699 19434 21712 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 19434 18042 19434 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79605 19178 79819 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72839 19178 77247 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71839 19178 72156 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 64225 19178 71156 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23726 19178 23868 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20550 19178 21574 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 19178 18192 19178 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 79373 18922 79819 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73227 18922 77480 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56797 18922 56974 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 48547 18922 48724 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 40297 18922 40474 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32047 18922 32224 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23797 18922 23974 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 20318 18922 21504 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 18922 18425 18922 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 78924 18666 79819 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73396 18666 77930 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56807 18666 57188 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 48557 18666 48938 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 40307 18666 40688 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32057 18666 32438 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23807 18666 24188 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 19869 18666 21494 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 18666 18875 18666 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73476 18410 79819 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60614 18410 60739 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56763 18410 57288 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 48513 18410 48991 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 40263 18410 40741 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 32013 18410 32491 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23763 18410 24241 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 18410 21539 18410 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73487 18154 79819 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62845 18154 62941 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 60423 18154 60855 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56645 18154 57479 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54595 18154 54655 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 48395 18154 49014 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 46345 18154 46405 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 40145 18154 40764 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 38095 18154 38155 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31895 18154 32514 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 29845 18154 29905 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23645 18154 24264 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 18154 21655 18154 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73424 17898 79819 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62636 17898 63197 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59929 17898 61065 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 59129 17898 59569 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 58329 17898 58769 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56436 17898 57969 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 54386 17898 54865 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 48186 17898 49116 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 46136 17898 46615 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 39936 17898 40866 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 37886 17898 38365 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31686 17898 32616 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 29636 17898 30115 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23436 17898 24366 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 17898 21865 17898 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 73283 17642 79819 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 62204 17642 63460 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 56004 17642 61502 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 53954 17642 55302 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52928 17642 53252 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 47754 17642 49322 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 45704 17642 47052 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 44923 17642 45001 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 39504 17642 41072 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 37454 17642 38802 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 36428 17642 36752 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 31254 17642 32822 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 29204 17642 30552 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 28178 17642 28502 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 23004 17642 24572 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 17642 22302 17642 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 72986 17386 79819 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 71986 17386 72015 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52672 17386 71016 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 44672 17386 49578 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 36172 17386 41328 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27922 17386 33078 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 17386 24828 17386 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 52251 17130 79819 17130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 44251 17130 50001 17130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 35751 17130 41751 17130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 27500 17130 33501 17130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 17130 25251 17130 319 -1
+De 0 0 1 4B261FE2 0
+Po 0 17977 16874 79819 16874 319 -1
+De 0 0 1 4B261FE2 0
+$EndZONE
+$CZONE_OUTLINE
+ZInfo 4B261FE2 1 "GND"
+ZLayer 0
+ZAux 4 E
+ZClearance 500 X
+ZMinThickness 319
+ZOptions 1 32 F 200 512
+ZCorner 80394 55669 0
+ZCorner 80394 16299 0
+ZCorner 17402 16299 0
+ZCorner 17402 55669 1
+$POLYSCORNERS
+79819 55094 0 0
+79819 52378 0 0
+79816 52392 0 0
+79700 52653 0 0
+79535 52887 0 0
+79328 53084 0 0
+79086 53238 0 0
+78819 53341 0 0
+78537 53391 0 0
+78251 53385 0 0
+77972 53323 0 0
+77710 53209 0 0
+77475 53045 0 0
+77276 52840 0 0
+77121 52599 0 0
+77016 52333 0 0
+76964 52052 0 0
+76968 51766 0 0
+77028 51486 0 0
+77140 51223 0 0
+77302 50987 0 0
+77506 50786 0 0
+77746 50630 0 0
+78011 50523 0 0
+78292 50469 0 0
+78578 50471 0 0
+78859 50529 0 0
+79122 50639 0 0
+79360 50799 0 0
+79561 51002 0 0
+79719 51241 0 0
+79819 51483 0 0
+79819 20488 0 0
+79816 20502 0 0
+79700 20763 0 0
+79535 20997 0 0
+79328 21194 0 0
+79086 21348 0 0
+78819 21451 0 0
+78537 21501 0 0
+78251 21495 0 0
+77972 21433 0 0
+77710 21319 0 0
+77475 21155 0 0
+77276 20950 0 0
+77121 20709 0 0
+77016 20443 0 0
+76964 20162 0 0
+76968 19876 0 0
+77028 19596 0 0
+77140 19333 0 0
+77302 19097 0 0
+77506 18896 0 0
+77746 18740 0 0
+78011 18633 0 0
+78292 18579 0 0
+78578 18581 0 0
+78859 18639 0 0
+79122 18749 0 0
+79360 18909 0 0
+79561 19112 0 0
+79719 19351 0 0
+79819 19593 0 0
+79819 16874 0 0
+17977 16874 0 0
+17977 19586 0 0
+18085 19333 0 0
+18247 19097 0 0
+18451 18896 0 0
+18691 18740 0 0
+18956 18633 0 0
+19237 18579 0 0
+19523 18581 0 0
+19804 18639 0 0
+20067 18749 0 0
+20305 18909 0 0
+20506 19112 0 0
+20664 19351 0 0
+20773 19615 0 0
+20829 19896 0 0
+20824 20223 0 0
+20761 20502 0 0
+20645 20763 0 0
+20480 20997 0 0
+20273 21194 0 0
+20046 21338 0 0
+20289 21338 0 0
+20289 49764 0 0
+18529 49764 0 0
+18529 21338 0 0
+18698 21338 0 0
+18655 21319 0 0
+18420 21155 0 0
+18221 20950 0 0
+18066 20709 0 0
+17977 20483 0 0
+17977 35984 0 0
+17977 51476 0 0
+18085 51223 0 0
+18247 50987 0 0
+18451 50786 0 0
+18691 50630 0 0
+18956 50523 0 0
+19237 50469 0 0
+19523 50471 0 0
+19804 50529 0 0
+20067 50639 0 0
+20305 50799 0 0
+20506 51002 0 0
+20664 51241 0 0
+20773 51505 0 0
+20829 51786 0 0
+20824 52113 0 0
+20761 52392 0 0
+20645 52653 0 0
+20480 52887 0 0
+20273 53084 0 0
+20031 53238 0 0
+19764 53341 0 0
+19482 53391 0 0
+19196 53385 0 0
+18917 53323 0 0
+18655 53209 0 0
+18420 53045 0 0
+18221 52840 0 0
+18066 52599 0 0
+17977 52373 0 0
+17977 55094 0 0
+58991 55094 0 1
+58991 54909 0 0
+57497 54909 0 0
+57487 54909 0 0
+57401 54899 0 0
+57320 54891 0 0
+57315 54889 0 0
+57311 54889 0 0
+57171 54844 0 0
+57151 54838 0 0
+57150 54837 0 0
+57142 54835 0 0
+57066 54793 0 0
+56994 54756 0 0
+56988 54751 0 0
+56986 54750 0 0
+56955 54724 0 0
+56857 54643 0 0
+56374 54160 0 0
+56367 54167 0 0
+56175 54288 0 0
+55963 54371 0 0
+55740 54410 0 0
+55513 54405 0 0
+55291 54357 0 0
+55083 54266 0 0
+54896 54136 0 0
+54738 53973 0 0
+54624 53796 0 0
+54612 53824 0 0
+54481 54010 0 0
+54317 54167 0 0
+54125 54288 0 0
+53913 54371 0 0
+53690 54410 0 0
+53463 54405 0 0
+53241 54357 0 0
+53033 54266 0 0
+52846 54136 0 0
+52688 53973 0 0
+52565 53782 0 0
+52482 53571 0 0
+52441 53348 0 0
+52444 53121 0 0
+52486 52919 0 0
+52350 52919 0 0
+52347 52927 0 0
+52338 52960 0 0
+52336 52962 0 0
+52335 52968 0 0
+52281 53065 0 0
+52255 53116 0 0
+52253 53118 0 0
+52250 53124 0 0
+52181 53205 0 0
+52142 53253 0 0
+52043 53351 0 0
+52023 53447 0 0
+52009 53479 0 0
+52009 53654 0 0
+52009 53663 0 0
+51989 53839 0 0
+51947 53967 0 0
+51938 54000 0 0
+51936 54002 0 0
+51935 54008 0 0
+51881 54105 0 0
+51855 54156 0 0
+51853 54158 0 0
+51850 54164 0 0
+51781 54245 0 0
+51742 54293 0 0
+51391 54644 0 0
+51391 54645 0 0
+51390 54645 0 0
+51384 54652 0 0
+51318 54703 0 0
+51253 54757 0 0
+51247 54759 0 0
+51245 54762 0 0
+51165 54803 0 0
+51096 54840 0 0
+51092 54840 0 0
+51087 54844 0 0
+50996 54870 0 0
+50927 54892 0 0
+50922 54892 0 0
+50917 54894 0 0
+50820 54902 0 0
+50750 54909 0 0
+50741 54909 0 0
+49247 54909 0 0
+49237 54909 0 0
+49151 54899 0 0
+49070 54891 0 0
+49065 54889 0 0
+49061 54889 0 0
+48921 54844 0 0
+48901 54838 0 0
+48900 54837 0 0
+48892 54835 0 0
+48816 54793 0 0
+48744 54756 0 0
+48738 54751 0 0
+48736 54750 0 0
+48705 54724 0 0
+48607 54643 0 0
+48124 54160 0 0
+48117 54167 0 0
+47925 54288 0 0
+47713 54371 0 0
+47490 54410 0 0
+47263 54405 0 0
+47041 54357 0 0
+46833 54266 0 0
+46646 54136 0 0
+46488 53973 0 0
+46374 53796 0 0
+46362 53824 0 0
+46231 54010 0 0
+46067 54167 0 0
+45875 54288 0 0
+45663 54371 0 0
+45440 54410 0 0
+45213 54405 0 0
+44991 54357 0 0
+44783 54266 0 0
+44596 54136 0 0
+44438 53973 0 0
+44315 53782 0 0
+44232 53571 0 0
+44191 53348 0 0
+44194 53121 0 0
+44236 52919 0 0
+44100 52919 0 0
+44097 52927 0 0
+44088 52960 0 0
+44086 52962 0 0
+44085 52968 0 0
+44031 53065 0 0
+44005 53116 0 0
+44003 53118 0 0
+44000 53124 0 0
+43931 53205 0 0
+43892 53253 0 0
+43793 53351 0 0
+43773 53447 0 0
+43759 53479 0 0
+43759 53654 0 0
+43759 53663 0 0
+43739 53839 0 0
+43697 53967 0 0
+43688 54000 0 0
+43686 54002 0 0
+43685 54008 0 0
+43631 54106 0 0
+43605 54156 0 0
+43603 54158 0 0
+43600 54164 0 0
+43531 54245 0 0
+43492 54293 0 0
+43141 54644 0 0
+43141 54645 0 0
+43140 54645 0 0
+43134 54652 0 0
+43068 54703 0 0
+43003 54757 0 0
+42997 54759 0 0
+42995 54762 0 0
+42915 54803 0 0
+42846 54840 0 0
+42842 54840 0 0
+42837 54844 0 0
+42746 54870 0 0
+42677 54892 0 0
+42672 54892 0 0
+42667 54894 0 0
+42570 54902 0 0
+42500 54909 0 0
+42491 54909 0 0
+40997 54909 0 0
+40987 54909 0 0
+40901 54899 0 0
+40820 54891 0 0
+40815 54889 0 0
+40811 54889 0 0
+40672 54844 0 0
+40651 54838 0 0
+40650 54837 0 0
+40642 54835 0 0
+40566 54793 0 0
+40494 54756 0 0
+40488 54751 0 0
+40486 54750 0 0
+40455 54724 0 0
+40357 54643 0 0
+39874 54160 0 0
+39867 54167 0 0
+39675 54288 0 0
+39463 54371 0 0
+39240 54410 0 0
+39013 54405 0 0
+38791 54357 0 0
+38583 54266 0 0
+38396 54136 0 0
+38238 53973 0 0
+38124 53796 0 0
+38112 53824 0 0
+37981 54010 0 0
+37817 54167 0 0
+37625 54288 0 0
+37413 54371 0 0
+37190 54410 0 0
+36963 54405 0 0
+36741 54357 0 0
+36533 54266 0 0
+36346 54136 0 0
+36188 53973 0 0
+36065 53782 0 0
+35982 53571 0 0
+35941 53348 0 0
+35944 53121 0 0
+35986 52919 0 0
+35850 52919 0 0
+35847 52927 0 0
+35838 52960 0 0
+35836 52962 0 0
+35835 52968 0 0
+35781 53066 0 0
+35755 53116 0 0
+35753 53118 0 0
+35750 53124 0 0
+35681 53205 0 0
+35642 53253 0 0
+35543 53351 0 0
+35523 53447 0 0
+35509 53479 0 0
+35509 53654 0 0
+35509 53663 0 0
+35489 53839 0 0
+35447 53967 0 0
+35438 54000 0 0
+35436 54002 0 0
+35435 54008 0 0
+35381 54106 0 0
+35355 54156 0 0
+35353 54158 0 0
+35350 54164 0 0
+35281 54245 0 0
+35242 54293 0 0
+34891 54644 0 0
+34891 54645 0 0
+34890 54645 0 0
+34884 54652 0 0
+34818 54703 0 0
+34753 54757 0 0
+34747 54759 0 0
+34745 54762 0 0
+34665 54803 0 0
+34596 54840 0 0
+34592 54840 0 0
+34587 54844 0 0
+34496 54870 0 0
+34427 54892 0 0
+34422 54892 0 0
+34417 54894 0 0
+34320 54902 0 0
+34250 54909 0 0
+34241 54909 0 0
+32747 54909 0 0
+32737 54909 0 0
+32651 54899 0 0
+32570 54891 0 0
+32565 54889 0 0
+32561 54889 0 0
+32422 54844 0 0
+32401 54838 0 0
+32400 54837 0 0
+32392 54835 0 0
+32316 54793 0 0
+32244 54756 0 0
+32238 54751 0 0
+32236 54750 0 0
+32205 54724 0 0
+32107 54643 0 0
+31624 54160 0 0
+31617 54167 0 0
+31425 54288 0 0
+31213 54371 0 0
+30990 54410 0 0
+30763 54405 0 0
+30541 54357 0 0
+30333 54266 0 0
+30146 54136 0 0
+29988 53973 0 0
+29874 53796 0 0
+29862 53824 0 0
+29731 54010 0 0
+29567 54167 0 0
+29375 54288 0 0
+29163 54371 0 0
+28940 54410 0 0
+28713 54405 0 0
+28491 54357 0 0
+28283 54266 0 0
+28096 54136 0 0
+27938 53973 0 0
+27815 53782 0 0
+27732 53571 0 0
+27691 53348 0 0
+27694 53121 0 0
+27736 52919 0 0
+27600 52919 0 0
+27597 52927 0 0
+27588 52960 0 0
+27586 52962 0 0
+27585 52968 0 0
+27531 53065 0 0
+27505 53116 0 0
+27503 53118 0 0
+27500 53124 0 0
+27431 53205 0 0
+27392 53253 0 0
+27293 53351 0 0
+27273 53447 0 0
+27259 53479 0 0
+27259 53654 0 0
+27259 53663 0 0
+27239 53839 0 0
+27197 53967 0 0
+27188 54000 0 0
+27186 54002 0 0
+27185 54008 0 0
+27131 54105 0 0
+27105 54156 0 0
+27103 54158 0 0
+27100 54164 0 0
+27031 54245 0 0
+26992 54293 0 0
+26641 54644 0 0
+26641 54645 0 0
+26640 54645 0 0
+26634 54652 0 0
+26568 54703 0 0
+26503 54757 0 0
+26497 54759 0 0
+26495 54762 0 0
+26415 54803 0 0
+26346 54840 0 0
+26342 54840 0 0
+26337 54844 0 0
+26246 54870 0 0
+26177 54892 0 0
+26172 54892 0 0
+26167 54894 0 0
+26070 54902 0 0
+26000 54909 0 0
+25991 54909 0 0
+24497 54909 0 0
+24487 54909 0 0
+24401 54899 0 0
+24320 54891 0 0
+24315 54889 0 0
+24311 54889 0 0
+24172 54844 0 0
+24151 54838 0 0
+24150 54837 0 0
+24142 54835 0 0
+24066 54793 0 0
+23994 54756 0 0
+23988 54751 0 0
+23986 54750 0 0
+23955 54724 0 0
+23857 54643 0 0
+23374 54160 0 0
+23367 54167 0 0
+23175 54288 0 0
+22963 54371 0 0
+22740 54410 0 0
+22513 54405 0 0
+22291 54357 0 0
+22083 54266 0 0
+21896 54136 0 0
+21738 53973 0 0
+21615 53782 0 0
+21532 53571 0 0
+21491 53348 0 0
+21494 53121 0 0
+21541 52899 0 0
+21630 52690 0 0
+21758 52502 0 0
+21921 52343 0 0
+22111 52219 0 0
+22321 52134 0 0
+22544 52091 0 0
+22591 52091 0 0
+22591 49497 0 0
+22591 49487 0 0
+22600 49401 0 0
+22609 49320 0 0
+22610 49314 0 0
+22611 49311 0 0
+22631 49246 0 0
+22661 49151 0 0
+22663 49145 0 0
+22665 49142 0 0
+22690 49095 0 0
+22740 49001 0 1
+22740 19910 0 0
+22513 19905 0 0
+22291 19857 0 0
+22083 19766 0 0
+21896 19636 0 0
+21738 19473 0 0
+21615 19282 0 0
+21532 19071 0 0
+21491 18848 0 0
+21494 18621 0 0
+21541 18399 0 0
+21630 18190 0 0
+21758 18002 0 0
+21921 17843 0 0
+22111 17719 0 0
+22321 17634 0 0
+22544 17591 0 0
+22771 17593 0 0
+22994 17638 0 0
+23203 17726 0 0
+23391 17853 0 0
+23551 18014 0 0
+23677 18203 0 0
+23764 18413 0 0
+23808 18636 0 0
+23804 18895 0 0
+23754 19117 0 0
+23662 19324 0 0
+23531 19510 0 0
+23367 19667 0 0
+23175 19788 0 0
+22963 19871 0 0
+22740 19910 0 1
+22740 49001 0 0
+22744 48994 0 0
+22748 48988 0 0
+22750 48986 0 0
+22775 48955 0 0
+22857 48857 0 0
+26591 45123 0 0
+26591 26127 0 0
+24105 23641 0 0
+24098 23634 0 0
+24046 23568 0 0
+23993 23503 0 0
+23990 23497 0 0
+23988 23495 0 0
+23946 23415 0 0
+23910 23346 0 0
+23909 23342 0 0
+23906 23337 0 0
+23879 23246 0 0
+23858 23177 0 0
+23857 23172 0 0
+23856 23167 0 0
+23847 23070 0 0
+23841 23000 0 0
+23841 22991 0 0
+23841 20458 0 0
+23823 20415 0 0
+23786 20230 0 0
+23785 19927 0 0
+23787 19737 0 0
+23827 19553 0 0
+23841 19520 0 0
+23841 19387 0 0
+23841 19377 0 0
+23850 19291 0 0
+23859 19210 0 0
+23860 19204 0 0
+23861 19201 0 0
+23881 19135 0 0
+23911 19041 0 0
+23913 19035 0 0
+23915 19032 0 0
+23940 18985 0 0
+23994 18884 0 0
+23998 18878 0 0
+24000 18876 0 0
+24025 18845 0 0
+24107 18747 0 0
+24206 18647 0 0
+24227 18553 0 0
+24241 18520 0 0
+24241 18347 0 0
+24241 18337 0 0
+24250 18251 0 0
+24259 18170 0 0
+24260 18164 0 0
+24261 18161 0 0
+24281 18096 0 0
+24311 18001 0 0
+24313 17995 0 0
+24315 17992 0 0
+24340 17945 0 0
+24394 17844 0 0
+24398 17838 0 0
+24400 17836 0 0
+24425 17805 0 0
+24507 17707 0 0
+24854 17360 0 0
+24859 17355 0 0
+24864 17350 0 0
+24866 17349 0 0
+24909 17313 0 0
+24997 17243 0 0
+24999 17241 0 0
+25004 17238 0 0
+25085 17196 0 0
+25154 17160 0 0
+25159 17158 0 0
+25162 17157 0 0
+25201 17145 0 0
+25323 17108 0 0
+25331 17107 0 0
+25332 17107 0 0
+25343 17105 0 0
+25500 17091 0 0
+27253 17091 0 0
+27263 17091 0 0
+27348 17100 0 0
+27430 17109 0 0
+27435 17110 0 0
+27439 17111 0 0
+27503 17131 0 0
+27599 17161 0 0
+27604 17163 0 0
+27608 17165 0 0
+27654 17190 0 0
+27756 17244 0 0
+27761 17248 0 0
+27764 17250 0 0
+27794 17275 0 0
+27893 17357 0 0
+28277 17741 0 0
+28311 17719 0 0
+28521 17634 0 0
+28744 17591 0 0
+28971 17593 0 0
+29194 17638 0 0
+29403 17726 0 0
+29591 17853 0 0
+29751 18014 0 0
+29875 18200 0 0
+29880 18190 0 0
+30008 18002 0 0
+30171 17843 0 0
+30361 17719 0 0
+30571 17634 0 0
+30794 17591 0 0
+31021 17593 0 0
+31244 17638 0 0
+31453 17726 0 0
+31641 17853 0 0
+31801 18014 0 0
+31927 18203 0 0
+32014 18413 0 0
+32058 18636 0 0
+32054 18895 0 0
+32012 19081 0 0
+32148 19081 0 0
+32161 19041 0 0
+32163 19035 0 0
+32165 19032 0 0
+32190 18985 0 0
+32244 18884 0 0
+32248 18878 0 0
+32250 18876 0 0
+32275 18845 0 0
+32357 18747 0 0
+32456 18647 0 0
+32477 18553 0 0
+32491 18520 0 0
+32491 18347 0 0
+32491 18337 0 0
+32500 18251 0 0
+32509 18170 0 0
+32510 18164 0 0
+32511 18161 0 0
+32531 18095 0 0
+32561 18001 0 0
+32563 17995 0 0
+32565 17992 0 0
+32590 17945 0 0
+32644 17844 0 0
+32648 17838 0 0
+32650 17836 0 0
+32675 17805 0 0
+32757 17707 0 0
+33104 17360 0 0
+33109 17355 0 0
+33114 17350 0 0
+33116 17349 0 0
+33159 17313 0 0
+33247 17243 0 0
+33249 17241 0 0
+33254 17238 0 0
+33335 17196 0 0
+33404 17160 0 0
+33409 17158 0 0
+33412 17157 0 0
+33451 17145 0 0
+33573 17108 0 0
+33581 17107 0 0
+33582 17107 0 0
+33593 17105 0 0
+33750 17091 0 0
+35503 17091 0 0
+35513 17091 0 0
+35598 17100 0 0
+35680 17109 0 0
+35685 17110 0 0
+35689 17111 0 0
+35754 17131 0 0
+35849 17161 0 0
+35854 17163 0 0
+35858 17165 0 0
+35904 17190 0 0
+36006 17244 0 0
+36011 17248 0 0
+36014 17250 0 0
+36044 17275 0 0
+36143 17357 0 0
+36527 17741 0 0
+36561 17719 0 0
+36771 17634 0 0
+36994 17591 0 0
+37221 17593 0 0
+37444 17638 0 0
+37653 17726 0 0
+37841 17853 0 0
+38001 18014 0 0
+38125 18200 0 0
+38130 18190 0 0
+38258 18002 0 0
+38421 17843 0 0
+38611 17719 0 0
+38821 17634 0 0
+39044 17591 0 0
+39271 17593 0 0
+39494 17638 0 0
+39703 17726 0 0
+39891 17853 0 0
+40051 18014 0 0
+40177 18203 0 0
+40264 18413 0 0
+40308 18636 0 0
+40304 18895 0 0
+40262 19081 0 0
+40398 19081 0 0
+40411 19041 0 0
+40413 19035 0 0
+40415 19032 0 0
+40440 18985 0 0
+40494 18884 0 0
+40498 18878 0 0
+40500 18876 0 0
+40525 18845 0 0
+40607 18747 0 0
+40706 18647 0 0
+40727 18553 0 0
+40741 18520 0 0
+40741 18347 0 0
+40741 18337 0 0
+40750 18251 0 0
+40759 18170 0 0
+40760 18164 0 0
+40761 18161 0 0
+40781 18096 0 0
+40811 18001 0 0
+40813 17995 0 0
+40815 17992 0 0
+40840 17945 0 0
+40894 17844 0 0
+40898 17838 0 0
+40900 17836 0 0
+40925 17805 0 0
+41007 17707 0 0
+41354 17360 0 0
+41359 17355 0 0
+41364 17350 0 0
+41366 17349 0 0
+41409 17313 0 0
+41497 17243 0 0
+41499 17241 0 0
+41504 17238 0 0
+41585 17196 0 0
+41654 17160 0 0
+41659 17158 0 0
+41662 17157 0 0
+41701 17145 0 0
+41823 17108 0 0
+41831 17107 0 0
+41832 17107 0 0
+41843 17105 0 0
+42000 17091 0 0
+44003 17091 0 0
+44013 17091 0 0
+44098 17100 0 0
+44180 17109 0 0
+44185 17110 0 0
+44189 17111 0 0
+44254 17131 0 0
+44349 17161 0 0
+44354 17163 0 0
+44358 17165 0 0
+44404 17190 0 0
+44506 17244 0 0
+44511 17248 0 0
+44514 17250 0 0
+44544 17275 0 0
+44643 17357 0 0
+44895 17609 0 0
+44902 17616 0 0
+44941 17666 0 0
+45021 17634 0 0
+45244 17591 0 0
+45471 17593 0 0
+45694 17638 0 0
+45903 17726 0 0
+46091 17853 0 0
+46251 18014 0 0
+46375 18200 0 0
+46380 18190 0 0
+46508 18002 0 0
+46671 17843 0 0
+46861 17719 0 0
+47071 17634 0 0
+47294 17591 0 0
+47521 17593 0 0
+47744 17638 0 0
+47953 17726 0 0
+48141 17853 0 0
+48301 18014 0 0
+48427 18203 0 0
+48514 18413 0 0
+48558 18636 0 0
+48554 18895 0 0
+48512 19081 0 0
+48648 19081 0 0
+48661 19041 0 0
+48663 19035 0 0
+48665 19032 0 0
+48690 18985 0 0
+48744 18884 0 0
+48748 18878 0 0
+48750 18876 0 0
+48775 18845 0 0
+48857 18747 0 0
+48956 18647 0 0
+48977 18553 0 0
+48991 18520 0 0
+48991 18347 0 0
+48991 18337 0 0
+49000 18251 0 0
+49009 18170 0 0
+49010 18164 0 0
+49011 18161 0 0
+49031 18096 0 0
+49061 18001 0 0
+49063 17995 0 0
+49065 17992 0 0
+49090 17945 0 0
+49144 17844 0 0
+49148 17838 0 0
+49150 17836 0 0
+49175 17805 0 0
+49257 17707 0 0
+49604 17360 0 0
+49609 17355 0 0
+49614 17350 0 0
+49616 17349 0 0
+49659 17313 0 0
+49747 17243 0 0
+49749 17241 0 0
+49754 17238 0 0
+49835 17196 0 0
+49904 17160 0 0
+49909 17158 0 0
+49912 17157 0 0
+49951 17145 0 0
+50073 17108 0 0
+50081 17107 0 0
+50082 17107 0 0
+50094 17105 0 0
+50250 17091 0 0
+52003 17091 0 0
+52013 17091 0 0
+52098 17100 0 0
+52180 17109 0 0
+52185 17110 0 0
+52189 17111 0 0
+52254 17131 0 0
+52349 17161 0 0
+52354 17163 0 0
+52358 17165 0 0
+52404 17190 0 0
+52506 17244 0 0
+52511 17248 0 0
+52514 17250 0 0
+52544 17275 0 0
+52643 17357 0 0
+53027 17741 0 0
+53061 17719 0 0
+53271 17634 0 0
+53494 17591 0 0
+53721 17593 0 0
+53944 17638 0 0
+54153 17726 0 0
+54341 17853 0 0
+54501 18014 0 0
+54625 18200 0 0
+54630 18190 0 0
+54758 18002 0 0
+54921 17843 0 0
+55111 17719 0 0
+55321 17634 0 0
+55544 17591 0 0
+55771 17593 0 0
+55994 17638 0 0
+56203 17726 0 0
+56391 17853 0 0
+56551 18014 0 0
+56677 18203 0 0
+56764 18413 0 0
+56808 18636 0 0
+56804 18895 0 0
+56762 19081 0 0
+56898 19081 0 0
+56911 19041 0 0
+56913 19035 0 0
+56915 19032 0 0
+56940 18985 0 0
+56994 18884 0 0
+56998 18878 0 0
+57000 18876 0 0
+57025 18845 0 0
+57107 18747 0 0
+57206 18647 0 0
+57227 18553 0 0
+57301 18379 0 0
+57408 18223 0 0
+57543 18090 0 0
+57701 17987 0 0
+57876 17916 0 0
+58062 17880 0 0
+58251 17882 0 0
+58436 17920 0 0
+58549 17967 0 0
+58676 17916 0 0
+58862 17880 0 0
+59051 17882 0 0
+59236 17920 0 0
+59349 17967 0 0
+59476 17916 0 0
+59662 17880 0 0
+59851 17882 0 0
+60036 17920 0 0
+60210 17993 0 0
+60367 18098 0 0
+60500 18232 0 0
+60605 18390 0 0
+60677 18565 0 0
+60693 18648 0 0
+60694 18621 0 0
+60741 18399 0 0
+60830 18190 0 0
+60958 18002 0 0
+61121 17843 0 0
+61311 17719 0 0
+61521 17634 0 0
+61744 17591 0 0
+61971 17593 0 0
+62194 17638 0 0
+62403 17726 0 0
+62591 17853 0 0
+62751 18014 0 0
+62877 18203 0 0
+62881 18214 0 0
+63424 17671 0 0
+63430 17666 0 0
+63472 17632 0 0
+63548 17570 0 0
+63553 17566 0 0
+63555 17566 0 0
+63601 17542 0 0
+63689 17496 0 0
+63691 17495 0 0
+63696 17493 0 0
+63764 17473 0 0
+63842 17450 0 0
+63847 17449 0 0
+63849 17449 0 0
+63871 17447 0 0
+64000 17434 0 0
+70942 17434 0 0
+71040 17370 0 0
+71220 17298 0 0
+71410 17261 0 0
+71604 17263 0 0
+71793 17302 0 0
+71972 17377 0 0
+72000 17395 0 0
+72040 17370 0 0
+72220 17298 0 0
+72410 17261 0 0
+72604 17263 0 0
+72793 17302 0 0
+72972 17377 0 0
+73133 17485 0 0
+73269 17622 0 0
+73376 17784 0 0
+73450 17963 0 0
+73488 18153 0 0
+73485 18374 0 0
+73442 18563 0 0
+73363 18740 0 0
+73252 18899 0 0
+73111 19032 0 0
+72948 19136 0 0
+72767 19206 0 0
+72576 19240 0 0
+72383 19236 0 0
+72193 19194 0 0
+72016 19117 0 0
+71997 19104 0 0
+71948 19136 0 0
+71767 19206 0 0
+71576 19240 0 0
+71383 19236 0 0
+71193 19194 0 0
+71016 19117 0 0
+70942 19066 0 0
+64337 19066 0 0
+64029 19374 0 0
+64206 19449 0 0
+64399 19579 0 0
+64564 19745 0 0
+64693 19939 0 0
+64782 20154 0 0
+64827 20383 0 0
+64823 20649 0 0
+64772 20877 0 0
+64703 21029 0 0
+64763 20944 0 0
+64897 20813 0 0
+65054 20710 0 0
+65228 20640 0 0
+65413 20604 0 0
+65601 20606 0 0
+65785 20643 0 0
+65958 20716 0 0
+66000 20744 0 0
+66054 20710 0 0
+66228 20640 0 0
+66413 20604 0 0
+66601 20606 0 0
+66785 20643 0 0
+66958 20716 0 0
+67004 20747 0 0
+67198 20747 0 0
+67171 20600 0 0
+67175 20367 0 0
+67223 20139 0 0
+67315 19925 0 0
+67447 19732 0 0
+67613 19569 0 0
+67808 19441 0 0
+68024 19354 0 0
+68253 19310 0 0
+68486 19312 0 0
+68715 19359 0 0
+68930 19449 0 0
+69123 19579 0 0
+69288 19745 0 0
+69417 19939 0 0
+69506 20154 0 0
+69551 20383 0 0
+69547 20649 0 0
+69496 20877 0 0
+69401 21090 0 0
+69267 21280 0 0
+69098 21441 0 0
+68901 21566 0 0
+68684 21651 0 0
+68574 21670 0 0
+69579 22675 0 0
+69584 22680 0 0
+69617 22722 0 0
+69680 22798 0 0
+69683 22803 0 0
+69684 22805 0 0
+69707 22851 0 0
+69754 22939 0 0
+69754 22941 0 0
+69757 22946 0 0
+69774 23005 0 0
+69800 23092 0 0
+69800 23098 0 0
+69801 23100 0 0
+69802 23114 0 0
+69816 23250 0 0
+69816 25250 0 0
+69816 25261 0 0
+69816 25829 0 0
+69897 25750 0 0
+70054 25647 0 0
+70228 25577 0 0
+70413 25541 0 0
+70601 25543 0 0
+70785 25580 0 0
+70958 25653 0 0
+71114 25758 0 0
+71246 25892 0 0
+71350 26048 0 0
+71421 26222 0 0
+71458 26406 0 0
+71455 26621 0 0
+71413 26804 0 0
+71337 26975 0 0
+71229 27129 0 0
+71159 27195 0 0
+71159 28566 0 0
+71165 28565 0 0
+71348 28567 0 0
+71527 28603 0 0
+71696 28674 0 0
+71848 28777 0 0
+71977 28907 0 0
+72078 29059 0 0
+72148 29228 0 0
+72184 29408 0 0
+72181 29617 0 0
+72141 29796 0 0
+72066 29963 0 0
+71961 30113 0 0
+71828 30239 0 0
+71674 30338 0 0
+71503 30404 0 0
+71322 30436 0 0
+71139 30432 0 0
+70960 30393 0 0
+70910 30371 0 0
+70909 30372 0 0
+70909 33250 0 0
+70909 33263 0 0
+70909 34050 0 0
+70964 34028 0 0
+71158 33991 0 0
+71356 33993 0 0
+71549 34032 0 0
+71732 34109 0 0
+71895 34219 0 0
+72035 34360 0 0
+72144 34524 0 0
+72220 34707 0 0
+72258 34901 0 0
+72255 35127 0 0
+72211 35320 0 0
+72131 35500 0 0
+72017 35662 0 0
+71925 35749 0 0
+72035 35860 0 0
+72144 36024 0 0
+72220 36207 0 0
+72258 36401 0 0
+72255 36627 0 0
+72211 36820 0 0
+72131 37000 0 0
+72017 37162 0 0
+71874 37298 0 0
+71707 37404 0 0
+71523 37475 0 0
+71328 37510 0 0
+71130 37506 0 0
+70937 37463 0 0
+70756 37384 0 0
+70594 37271 0 0
+70456 37129 0 0
+70349 36963 0 0
+70276 36779 0 0
+70272 36762 0 0
+65891 41144 0 0
+65891 41145 0 0
+65890 41145 0 0
+65884 41152 0 0
+65818 41203 0 0
+65753 41257 0 0
+65747 41259 0 0
+65745 41262 0 0
+65665 41303 0 0
+65596 41340 0 0
+65592 41340 0 0
+65587 41344 0 0
+65496 41370 0 0
+65427 41392 0 0
+65422 41392 0 0
+65417 41394 0 0
+65320 41402 0 0
+65250 41409 0 0
+65241 41409 0 0
+63000 41409 0 0
+62994 41409 0 0
+62987 41409 0 0
+62434 41409 0 0
+62434 41565 0 0
+62598 41567 0 0
+62777 41603 0 0
+62946 41674 0 0
+63098 41777 0 0
+63227 41907 0 0
+63328 42059 0 0
+63398 42228 0 0
+63434 42408 0 0
+63431 42617 0 0
+63391 42796 0 0
+63316 42963 0 0
+63316 43079 0 0
+63397 43000 0 0
+63554 42897 0 0
+63728 42827 0 0
+63913 42791 0 0
+64101 42793 0 0
+64285 42830 0 0
+64447 42898 0 0
+67425 39921 0 0
+67430 39916 0 0
+67472 39882 0 0
+67548 39820 0 0
+67553 39816 0 0
+67555 39816 0 0
+67601 39792 0 0
+67689 39746 0 0
+67691 39745 0 0
+67696 39743 0 0
+67755 39725 0 0
+67842 39700 0 0
+67848 39699 0 0
+67850 39699 0 0
+67880 39696 0 0
+68000 39684 0 0
+68008 39684 0 0
+68406 39684 0 0
+68531 39602 0 0
+68714 39528 0 0
+68908 39491 0 0
+69106 39493 0 0
+69299 39532 0 0
+69482 39609 0 0
+69645 39719 0 0
+69785 39860 0 0
+69894 40024 0 0
+69970 40207 0 0
+70008 40401 0 0
+70005 40627 0 0
+69961 40820 0 0
+69881 41000 0 0
+69879 41002 0 0
+69894 41024 0 0
+69970 41207 0 0
+70008 41401 0 0
+70005 41627 0 0
+69961 41820 0 0
+69943 41859 0 0
+69984 41958 0 0
+70009 42085 0 0
+70009 42919 0 0
+69983 43045 0 0
+69933 43165 0 0
+69909 43200 0 0
+69909 43253 0 0
+69909 43263 0 0
+69899 43348 0 0
+69891 43430 0 0
+69889 43435 0 0
+69889 43439 0 0
+69868 43504 0 0
+69839 43599 0 0
+69836 43604 0 0
+69835 43608 0 0
+69809 43654 0 0
+69756 43756 0 0
+69751 43761 0 0
+69750 43764 0 0
+69724 43794 0 0
+69643 43893 0 0
+69141 44395 0 0
+69134 44402 0 0
+69068 44453 0 0
+69003 44507 0 0
+68997 44509 0 0
+68995 44512 0 0
+68915 44553 0 0
+68846 44590 0 0
+68842 44590 0 0
+68837 44594 0 0
+68746 44620 0 0
+68677 44642 0 0
+68672 44642 0 0
+68667 44644 0 0
+68570 44652 0 0
+68500 44659 0 0
+68491 44659 0 0
+68376 44658 0 0
+68159 44876 0 0
+68159 45271 0 0
+68162 45269 0 0
+68315 45168 0 0
+68485 45100 0 0
+68665 45065 0 0
+68848 45067 0 0
+69027 45103 0 0
+69196 45174 0 0
+69348 45277 0 0
+69477 45407 0 0
+69578 45559 0 0
+69648 45728 0 0
+69684 45908 0 0
+69682 46009 0 0
+72014 46009 0 0
+72206 46031 0 0
+72317 46066 0 0
+72344 46066 0 0
+72470 46092 0 0
+72590 46142 0 0
+72604 46152 0 0
+72735 46100 0 0
+72915 46065 0 0
+73098 46067 0 0
+73277 46103 0 0
+73446 46174 0 0
+73598 46277 0 0
+73681 46360 0 1
+73681 43909 0 0
+73555 43883 0 0
+73435 43833 0 0
+73328 43760 0 0
+73237 43669 0 0
+73165 43561 0 0
+73116 43442 0 0
+73091 43315 0 0
+73091 39681 0 0
+73117 39555 0 0
+73167 39435 0 0
+73240 39328 0 0
+73331 39237 0 0
+73439 39165 0 0
+73558 39116 0 0
+73685 39091 0 0
+77319 39091 0 0
+77445 39117 0 0
+77565 39167 0 0
+77672 39240 0 0
+77763 39331 0 0
+77835 39439 0 0
+77884 39558 0 0
+77909 39685 0 0
+77909 43319 0 0
+77883 43445 0 0
+77833 43565 0 0
+77760 43672 0 0
+77669 43763 0 0
+77561 43835 0 0
+77442 43884 0 0
+77315 43909 0 0
+73681 43909 0 1
+73681 46360 0 0
+73727 46407 0 0
+73828 46559 0 0
+73898 46728 0 0
+73934 46908 0 0
+73931 47117 0 0
+73891 47296 0 0
+73816 47463 0 0
+73711 47613 0 0
+73578 47739 0 0
+73424 47838 0 0
+73253 47904 0 0
+73072 47936 0 0
+72909 47932 0 0
+72909 48496 0 0
+73014 48496 0 0
+73140 48522 0 0
+73260 48572 0 0
+73367 48645 0 0
+73458 48736 0 0
+73530 48844 0 0
+73579 48963 0 0
+73604 49090 0 0
+73604 50043 0 0
+73854 49996 0 0
+74169 49998 0 0
+74476 50061 0 0
+74766 50183 0 0
+75027 50359 0 0
+75248 50582 0 0
+75422 50844 0 0
+75542 51135 0 0
+75603 51443 0 0
+75598 51802 0 0
+75528 52109 0 0
+75400 52396 0 0
+75219 52653 0 0
+74991 52869 0 0
+74726 53038 0 0
+74433 53151 0 0
+74123 53206 0 0
+73809 53199 0 0
+73502 53132 0 0
+73477 53121 0 0
+73400 53296 0 0
+73219 53553 0 0
+72991 53769 0 0
+72726 53938 0 0
+72433 54051 0 0
+72123 54106 0 0
+71809 54099 0 0
+71502 54032 0 0
+71214 53906 0 0
+70956 53726 0 0
+70738 53500 0 0
+70567 53236 0 0
+70452 52944 0 0
+70395 52635 0 0
+70399 52320 0 0
+70465 52013 0 0
+70589 51724 0 0
+70681 51588 0 0
+70633 51555 0 0
+70542 51464 0 0
+70470 51356 0 0
+70421 51237 0 0
+70396 51110 0 0
+70396 49409 0 0
+68126 49409 0 0
+67604 49931 0 0
+67604 50043 0 0
+67854 49996 0 0
+68169 49998 0 0
+68476 50061 0 0
+68766 50183 0 0
+69027 50359 0 0
+69248 50582 0 0
+69422 50844 0 0
+69542 51135 0 0
+69603 51443 0 0
+69598 51802 0 0
+69528 52109 0 0
+69400 52396 0 0
+69219 52653 0 0
+68991 52869 0 0
+68726 53038 0 0
+68433 53151 0 0
+68123 53206 0 0
+67809 53199 0 0
+67502 53132 0 0
+67477 53121 0 0
+67400 53296 0 0
+67219 53553 0 0
+66991 53769 0 0
+66726 53938 0 0
+66433 54051 0 0
+66123 54106 0 0
+65809 54099 0 0
+65502 54032 0 0
+65214 53906 0 0
+64956 53726 0 0
+64738 53500 0 0
+64567 53236 0 0
+64452 52944 0 0
+64395 52635 0 0
+64399 52320 0 0
+64465 52013 0 0
+64589 51724 0 0
+64681 51588 0 0
+64633 51555 0 0
+64542 51464 0 0
+64470 51356 0 0
+64421 51237 0 0
+64396 51110 0 0
+64396 49086 0 0
+64422 48960 0 0
+64443 48909 0 0
+63507 48909 0 0
+63505 49127 0 0
+63461 49320 0 0
+63381 49500 0 0
+63379 49502 0 0
+63394 49524 0 0
+63470 49707 0 0
+63508 49901 0 0
+63505 50127 0 0
+63461 50320 0 0
+63409 50437 0 0
+63409 51253 0 0
+63409 51263 0 0
+63389 51439 0 0
+63347 51567 0 0
+63338 51600 0 0
+63336 51602 0 0
+63335 51608 0 0
+63281 51705 0 0
+63255 51756 0 0
+63253 51758 0 0
+63250 51764 0 0
+63181 51845 0 0
+63142 51893 0 0
+62636 52398 0 0
+62751 52514 0 0
+62877 52703 0 0
+62964 52913 0 0
+63008 53136 0 0
+63004 53395 0 0
+62954 53617 0 0
+62862 53824 0 0
+62731 54010 0 0
+62567 54167 0 0
+62375 54288 0 0
+62163 54371 0 0
+61940 54410 0 0
+61713 54405 0 0
+61491 54357 0 0
+61283 54266 0 0
+61096 54136 0 0
+60938 53973 0 0
+60815 53782 0 0
+60732 53571 0 0
+60691 53348 0 0
+60694 53121 0 0
+60736 52919 0 0
+60600 52919 0 0
+60597 52927 0 0
+60588 52960 0 0
+60586 52962 0 0
+60585 52968 0 0
+60531 53065 0 0
+60505 53116 0 0
+60503 53118 0 0
+60500 53124 0 0
+60431 53205 0 0
+60392 53253 0 0
+60293 53351 0 0
+60273 53447 0 0
+60259 53479 0 0
+60259 53654 0 0
+60259 53663 0 0
+60239 53839 0 0
+60197 53967 0 0
+60188 54000 0 0
+60186 54002 0 0
+60185 54008 0 0
+60131 54105 0 0
+60105 54156 0 0
+60103 54158 0 0
+60100 54164 0 0
+60031 54245 0 0
+59992 54293 0 0
+59641 54644 0 0
+59641 54645 0 0
+59640 54645 0 0
+59634 54652 0 0
+59568 54703 0 0
+59503 54757 0 0
+59497 54759 0 0
+59495 54762 0 0
+59415 54803 0 0
+59346 54840 0 0
+59342 54840 0 0
+59337 54844 0 0
+59246 54870 0 0
+59177 54892 0 0
+59172 54892 0 0
+59167 54894 0 0
+59070 54902 0 0
+59000 54909 0 0
+58991 54909 0 1
+58991 55094 1 0
+61363 51101 0 0
+61591 50873 0 0
+61591 50442 0 0
+61526 50279 0 0
+61491 50085 0 0
+61493 49887 0 0
+61535 49694 0 0
+61612 49512 0 0
+61621 49498 0 0
+61599 49463 0 0
+61526 49279 0 0
+61491 49085 0 0
+61493 48887 0 0
+61535 48694 0 0
+61612 48512 0 0
+61621 48498 0 0
+61599 48463 0 0
+61577 48409 0 0
+57246 48409 0 0
+57237 48409 0 0
+57061 48389 0 0
+56932 48347 0 0
+56900 48338 0 0
+56897 48336 0 0
+56892 48335 0 0
+56793 48281 0 0
+56744 48255 0 0
+56741 48253 0 0
+56736 48250 0 0
+56654 48181 0 0
+56607 48142 0 0
+54555 46091 0 0
+54457 46154 0 0
+54273 46225 0 0
+54078 46260 0 0
+53880 46256 0 0
+53687 46213 0 0
+53506 46134 0 0
+53497 46128 0 0
+53457 46154 0 0
+53273 46225 0 0
+53078 46260 0 0
+52880 46256 0 0
+52687 46213 0 0
+52563 46159 0 0
+51062 46159 0 0
+51587 46684 0 0
+53753 46684 0 0
+53761 46684 0 0
+53828 46691 0 0
+53911 46700 0 0
+53916 46701 0 0
+53920 46702 0 0
+54010 46730 0 0
+54063 46747 0 0
+54065 46748 0 0
+54071 46750 0 0
+54190 46815 0 0
+54204 46823 0 0
+54204 46823 0 0
+54211 46827 0 0
+54284 46888 0 0
+54327 46923 0 0
+54332 46928 0 0
+56087 48684 0 0
+57753 48684 0 0
+57761 48684 0 0
+57828 48691 0 0
+57911 48700 0 0
+57916 48701 0 0
+57920 48702 0 0
+58010 48730 0 0
+58063 48747 0 0
+58065 48748 0 0
+58071 48750 0 0
+58190 48815 0 0
+58204 48823 0 0
+58204 48823 0 0
+58211 48827 0 0
+58284 48888 0 0
+58327 48923 0 0
+58333 48929 0 0
+59529 50125 0 0
+59535 50131 0 0
+59564 50167 0 0
+59630 50248 0 0
+59704 50389 0 0
+59705 50394 0 0
+59707 50397 0 0
+59733 50488 0 0
+59750 50542 0 0
+59750 50543 0 0
+59752 50550 0 0
+59760 50643 0 0
+59766 50700 0 0
+59766 50708 0 0
+59766 50901 0 0
+59851 50902 0 0
+60036 50940 0 0
+60210 51013 0 0
+60341 51101 1 0
+54500 43371 0 0
+54531 43352 0 0
+54703 43282 0 0
+54644 43190 0 0
+54575 43015 0 0
+54541 42831 0 0
+54543 42643 0 0
+54582 42459 0 0
+54656 42286 0 0
+54763 42131 0 0
+54897 42000 0 0
+55054 41897 0 0
+55228 41827 0 0
+55413 41791 0 0
+55601 41793 0 0
+55785 41830 0 0
+55958 41903 0 0
+56114 42008 0 0
+56246 42142 0 0
+56350 42298 0 0
+56421 42472 0 0
+56432 42528 0 0
+56587 42684 0 0
+57750 42684 0 0
+57756 42684 0 0
+57761 42684 0 0
+60162 42684 0 0
+60598 42247 0 0
+60605 42217 0 0
+60652 42105 0 0
+60640 42086 0 0
+60591 41967 0 0
+60566 41840 0 0
+60566 41409 0 0
+58707 41409 0 0
+58705 41621 0 0
+58663 41804 0 0
+58587 41975 0 0
+58479 42129 0 0
+58343 42258 0 0
+58184 42359 0 0
+58009 42427 0 0
+57824 42460 0 0
+57636 42456 0 0
+57453 42416 0 0
+57280 42340 0 0
+57126 42233 0 0
+56996 42098 0 0
+56894 41940 0 0
+56825 41765 0 0
+56791 41581 0 0
+56792 41409 0 0
+51933 41409 0 0
+51931 41617 0 0
+51891 41796 0 0
+51816 41963 0 0
+51711 42113 0 0
+51578 42239 0 0
+51424 42338 0 0
+51253 42404 0 0
+51072 42436 0 0
+50889 42432 0 0
+50851 42423 0 0
+50895 42489 0 0
+50944 42608 0 0
+50969 42735 0 0
+50969 43341 0 0
+52000 43341 0 0
+52013 43341 0 0
+52558 43341 0 0
+52714 43278 0 0
+52908 43241 0 0
+53106 43243 0 0
+53299 43282 0 0
+53482 43359 0 0
+53500 43371 0 0
+53531 43352 0 0
+53714 43278 0 0
+53908 43241 0 0
+54106 43243 0 0
+54299 43282 0 0
+54482 43359 1 0
+63909 39591 0 0
+64872 39590 0 0
+65595 38868 0 0
+65530 38840 0 0
+65376 38733 0 0
+65246 38598 0 0
+65144 38440 0 0
+65075 38265 0 0
+65041 38081 0 0
+65043 37893 0 0
+65082 37709 0 0
+65156 37536 0 0
+65263 37381 0 0
+65397 37250 0 0
+65398 37248 0 0
+65376 37233 0 0
+65246 37098 0 0
+65144 36940 0 0
+65075 36765 0 0
+65041 36581 0 0
+65043 36393 0 0
+65082 36209 0 0
+65156 36036 0 0
+65184 35995 0 0
+65184 35501 0 0
+65144 35440 0 0
+65075 35265 0 0
+65041 35081 0 0
+65043 34893 0 0
+65082 34709 0 0
+65156 34536 0 0
+65263 34381 0 0
+65397 34250 0 0
+65554 34147 0 0
+65728 34077 0 0
+65913 34041 0 0
+66101 34043 0 0
+66285 34080 0 0
+66458 34153 0 0
+66462 34155 0 0
+66481 34137 0 0
+66589 34065 0 0
+66708 34016 0 0
+66835 33991 0 0
+67434 33991 0 0
+67434 31408 0 0
+67434 29408 0 0
+67434 26000 0 0
+67434 25989 0 0
+67434 24088 0 0
+66643 23297 0 0
+66574 23310 0 0
+66409 23306 0 0
+66409 24283 0 0
+66434 24408 0 0
+66431 24617 0 0
+66409 24715 0 0
+66409 26192 0 0
+66421 26222 0 0
+66458 26406 0 0
+66455 26621 0 0
+66413 26804 0 0
+66337 26975 0 0
+66229 27129 0 0
+66093 27258 0 0
+65934 27359 0 0
+65759 27427 0 0
+65574 27460 0 0
+65386 27456 0 0
+65203 27416 0 0
+65030 27340 0 0
+64876 27233 0 0
+64746 27098 0 0
+64644 26940 0 0
+64575 26765 0 0
+64541 26581 0 0
+64543 26393 0 0
+64582 26209 0 0
+64591 26187 0 0
+64591 25432 0 0
+64572 25436 0 0
+64389 25432 0 0
+64210 25393 0 0
+64042 25319 0 0
+63892 25215 0 0
+63765 25083 0 0
+63665 24929 0 0
+63598 24759 0 0
+63565 24579 0 0
+63567 24396 0 0
+63605 24217 0 0
+63677 24048 0 0
+63781 23897 0 0
+63912 23769 0 0
+64065 23668 0 0
+64235 23600 0 0
+64415 23565 0 0
+64591 23566 0 0
+64591 22655 0 0
+64575 22615 0 0
+64541 22431 0 0
+64543 22243 0 0
+64582 22059 0 0
+64625 21956 0 0
+64575 21828 0 0
+64541 21644 0 0
+64543 21456 0 0
+64582 21272 0 0
+64633 21151 0 0
+64543 21280 0 0
+64374 21441 0 0
+64177 21566 0 0
+63960 21651 0 0
+63730 21691 0 0
+63497 21686 0 0
+63269 21636 0 0
+63055 21543 0 0
+62864 21410 0 0
+62702 21242 0 0
+62576 21046 0 0
+62566 21020 0 0
+62566 21511 0 0
+62555 21602 0 0
+62550 21662 0 0
+62548 21667 0 0
+62548 21670 0 0
+62500 21821 0 0
+62447 21916 0 0
+62427 21955 0 0
+62424 21957 0 0
+62423 21961 0 0
+62371 22023 0 0
+62326 22078 0 0
+62321 22083 0 0
+61609 22794 0 0
+61785 22830 0 0
+61958 22903 0 0
+62114 23008 0 0
+62246 23142 0 0
+62350 23298 0 0
+62421 23472 0 0
+62458 23656 0 0
+62455 23871 0 0
+62413 24054 0 0
+62379 24130 0 0
+62385 24139 0 0
+62434 24258 0 0
+62459 24385 0 0
+62459 25119 0 0
+62433 25245 0 0
+62383 25365 0 0
+62310 25472 0 0
+62219 25563 0 0
+62111 25635 0 0
+61992 25684 0 0
+61865 25709 0 0
+61694 25709 0 0
+61443 25960 0 0
+61503 26051 0 0
+61574 26226 0 0
+61610 26412 0 0
+61608 26601 0 0
+61570 26786 0 0
+61497 26960 0 0
+61469 27000 0 0
+61503 27051 0 0
+61574 27226 0 0
+61610 27412 0 0
+61608 27601 0 0
+61572 27773 0 0
+62002 27343 0 0
+62035 27194 0 0
+62112 27012 0 0
+62224 26849 0 0
+62365 26711 0 0
+62531 26602 0 0
+62714 26528 0 0
+62908 26491 0 0
+63106 26493 0 0
+63299 26532 0 0
+63482 26609 0 0
+63609 26694 0 0
+63661 26700 0 0
+63666 26701 0 0
+63670 26702 0 0
+63760 26730 0 0
+63813 26747 0 0
+63815 26748 0 0
+63821 26750 0 0
+63940 26815 0 0
+63954 26823 0 0
+63954 26823 0 0
+63961 26827 0 0
+64034 26888 0 0
+64077 26923 0 0
+64082 26928 0 0
+65751 28597 0 0
+65777 28603 0 0
+65946 28674 0 0
+66000 28710 0 0
+66065 28668 0 0
+66235 28600 0 0
+66415 28565 0 0
+66598 28567 0 0
+66777 28603 0 0
+66946 28674 0 0
+67098 28777 0 0
+67227 28907 0 0
+67328 29059 0 0
+67398 29228 0 0
+67434 29408 0 0
+67431 29617 0 0
+67391 29796 0 0
+67316 29963 0 0
+67211 30113 0 0
+67078 30239 0 0
+66924 30338 0 0
+66753 30404 0 0
+66572 30436 0 0
+66389 30432 0 0
+66210 30393 0 0
+66042 30319 0 0
+65999 30289 0 0
+65924 30338 0 0
+65753 30404 0 0
+65572 30436 0 0
+65389 30432 0 0
+65210 30393 0 0
+65042 30319 0 0
+64892 30215 0 0
+64765 30083 0 0
+64665 29929 0 0
+64598 29759 0 0
+64596 29750 0 0
+63911 29065 0 0
+63970 29207 0 0
+64008 29401 0 0
+64005 29627 0 0
+63961 29820 0 0
+63881 30000 0 0
+63816 30092 0 0
+63816 30684 0 0
+65040 30684 0 0
+65065 30668 0 0
+65235 30600 0 0
+65415 30565 0 0
+65598 30567 0 0
+65777 30603 0 0
+65946 30674 0 0
+66000 30710 0 0
+66065 30668 0 0
+66235 30600 0 0
+66415 30565 0 0
+66598 30567 0 0
+66777 30603 0 0
+66946 30674 0 0
+67098 30777 0 0
+67227 30907 0 0
+67328 31059 0 0
+67398 31228 0 0
+67434 31408 0 0
+67431 31617 0 0
+67391 31796 0 0
+67316 31963 0 0
+67211 32113 0 0
+67078 32239 0 0
+66924 32338 0 0
+66753 32404 0 0
+66572 32436 0 0
+66389 32432 0 0
+66210 32393 0 0
+66042 32319 0 0
+65999 32289 0 0
+65924 32338 0 0
+65753 32404 0 0
+65572 32436 0 0
+65389 32432 0 0
+65210 32393 0 0
+65042 32319 0 0
+65037 32316 0 0
+63915 32316 0 0
+63934 32408 0 0
+63931 32617 0 0
+63891 32796 0 0
+63816 32963 0 0
+63789 33000 0 0
+63828 33059 0 0
+63898 33228 0 0
+63934 33408 0 0
+63931 33617 0 0
+63909 33715 1 0
+39500 38030 0 0
+39551 37997 0 0
+39726 37926 0 0
+39912 37890 0 0
+40101 37892 0 0
+40184 37909 0 0
+40184 37097 0 0
+40184 37089 0 0
+40191 37021 0 0
+40200 36939 0 0
+40201 36933 0 0
+40202 36930 0 0
+40230 36839 0 0
+40247 36787 0 0
+40248 36784 0 0
+40250 36779 0 0
+40315 36659 0 0
+40323 36646 0 0
+40323 36645 0 0
+40327 36639 0 0
+40388 36565 0 0
+40423 36523 0 0
+40429 36517 0 0
+40846 36100 0 0
+40421 35675 0 0
+40415 35669 0 0
+40385 35632 0 0
+40320 35552 0 0
+40246 35411 0 0
+40244 35405 0 0
+40243 35403 0 0
+40216 35312 0 0
+40200 35258 0 0
+40199 35256 0 0
+40198 35250 0 0
+40189 35155 0 0
+40184 35100 0 0
+40184 35092 0 0
+40184 34816 0 0
+33247 34816 0 0
+33239 34816 0 0
+33174 34808 0 0
+33088 34800 0 0
+33082 34798 0 0
+33080 34798 0 0
+33025 34780 0 0
+32936 34753 0 0
+32932 34751 0 0
+32929 34750 0 0
+32817 34688 0 0
+32796 34677 0 0
+32795 34676 0 0
+32789 34673 0 0
+32715 34611 0 0
+32673 34577 0 0
+32667 34571 0 0
+32421 34325 0 0
+32415 34319 0 0
+32385 34282 0 0
+32320 34202 0 0
+32254 34077 0 0
+32088 34110 0 0
+31899 34108 0 0
+31816 34090 0 0
+31816 37000 0 0
+31816 37011 0 0
+31816 37908 0 0
+31912 37890 0 0
+32101 37892 0 0
+32286 37930 0 0
+32460 38003 0 0
+32500 38030 0 0
+32551 37997 0 0
+32726 37926 0 0
+32912 37890 0 0
+33101 37892 0 0
+33286 37930 0 0
+33460 38003 0 0
+33500 38030 0 0
+33551 37997 0 0
+33726 37926 0 0
+33912 37890 0 0
+34101 37892 0 0
+34286 37930 0 0
+34460 38003 0 0
+34500 38030 0 0
+34551 37997 0 0
+34726 37926 0 0
+34912 37890 0 0
+35101 37892 0 0
+35286 37930 0 0
+35460 38003 0 0
+35500 38030 0 0
+35551 37997 0 0
+35726 37926 0 0
+35912 37890 0 0
+36101 37892 0 0
+36286 37930 0 0
+36460 38003 0 0
+36500 38030 0 0
+36551 37997 0 0
+36726 37926 0 0
+36912 37890 0 0
+37101 37892 0 0
+37286 37930 0 0
+37460 38003 0 0
+37500 38030 0 0
+37551 37997 0 0
+37726 37926 0 0
+37912 37890 0 0
+38101 37892 0 0
+38286 37930 0 0
+38460 38003 0 0
+38500 38030 0 0
+38551 37997 0 0
+38726 37926 0 0
+38912 37890 0 0
+39101 37892 0 0
+39286 37930 0 0
+39460 38003 1 0
+59419 32265 0 0
+59430 32214 0 0
+59503 32040 0 0
+59530 31999 0 0
+59497 31949 0 0
+59426 31774 0 0
+59390 31588 0 0
+59392 31399 0 0
+59423 31246 0 0
+59309 31184 0 0
+59296 31177 0 0
+59295 31176 0 0
+59289 31173 0 0
+59215 31111 0 0
+59173 31077 0 0
+59166 31070 0 0
+58912 30816 0 0
+58557 30816 0 0
+58528 30883 0 0
+58534 30888 0 0
+58577 30923 0 0
+58583 30929 0 0
+59079 31425 0 0
+59085 31431 0 0
+59114 31467 0 0
+59180 31548 0 0
+59254 31689 0 0
+59255 31694 0 0
+59257 31697 0 0
+59283 31788 0 0
+59300 31842 0 0
+59300 31843 0 0
+59302 31850 0 0
+59310 31944 0 0
+59316 32000 0 0
+59316 32008 0 0
+59316 32162 1 0
+33500 32030 0 0
+33551 31997 0 0
+33726 31926 0 0
+33912 31890 0 0
+34101 31892 0 0
+34184 31909 0 0
+34184 29841 0 0
+34088 29860 0 0
+33899 29858 0 0
+33714 29820 0 0
+33624 29782 0 0
+33621 29785 0 0
+33502 29834 0 0
+33375 29859 0 0
+32621 29859 0 0
+32558 29846 0 0
+31816 30588 0 0
+31816 31908 0 0
+31912 31890 0 0
+32101 31892 0 0
+32286 31930 0 0
+32460 32003 0 0
+32500 32030 0 0
+32551 31997 0 0
+32726 31926 0 0
+32912 31890 0 0
+33101 31892 0 0
+33286 31930 0 0
+33460 32003 1 0
+59433 29206 0 0
+59503 29040 0 0
+59530 28999 0 0
+59497 28949 0 0
+59426 28774 0 0
+59390 28588 0 0
+59392 28399 0 0
+59430 28214 0 0
+59503 28040 0 0
+59530 27999 0 0
+59497 27949 0 0
+59426 27774 0 0
+59390 27588 0 0
+59392 27399 0 0
+59430 27214 0 0
+59503 27040 0 0
+59530 26999 0 0
+59497 26949 0 0
+59426 26774 0 0
+59390 26588 0 0
+59392 26399 0 0
+59430 26214 0 0
+59503 26040 0 0
+59608 25883 0 0
+59684 25807 0 0
+59684 25747 0 0
+59684 25739 0 0
+59691 25671 0 0
+59700 25589 0 0
+59701 25583 0 0
+59702 25580 0 0
+59730 25489 0 0
+59747 25437 0 0
+59748 25434 0 0
+59750 25429 0 0
+59815 25309 0 0
+59823 25296 0 0
+59823 25295 0 0
+59827 25289 0 0
+59888 25215 0 0
+59923 25173 0 0
+59929 25167 0 0
+60541 24555 0 0
+60541 24381 0 0
+60567 24255 0 0
+60617 24135 0 0
+60620 24130 0 0
+60575 24015 0 0
+60545 23858 0 0
+60075 24329 0 0
+60069 24335 0 0
+60032 24364 0 0
+59952 24430 0 0
+59811 24504 0 0
+59805 24505 0 0
+59803 24507 0 0
+59712 24533 0 0
+59658 24550 0 0
+59656 24550 0 0
+59650 24552 0 0
+59555 24560 0 0
+59500 24566 0 0
+59492 24566 0 0
+55837 24566 0 0
+55812 24591 0 0
+55958 24653 0 0
+56114 24758 0 0
+56246 24892 0 0
+56350 25048 0 0
+56421 25222 0 0
+56458 25406 0 0
+56455 25621 0 0
+56413 25804 0 0
+56337 25975 0 0
+56229 26129 0 0
+56093 26258 0 0
+55934 26359 0 0
+55759 26427 0 0
+55574 26460 0 0
+55386 26456 0 0
+55203 26416 0 0
+55030 26340 0 0
+54876 26233 0 0
+54746 26098 0 0
+54644 25940 0 0
+54593 25810 0 0
+54066 26338 0 0
+54066 28280 0 0
+54425 27921 0 0
+54431 27915 0 0
+54467 27885 0 0
+54548 27820 0 0
+54689 27746 0 0
+54694 27744 0 0
+54697 27743 0 0
+54787 27716 0 0
+54842 27700 0 0
+54843 27699 0 0
+54850 27698 0 0
+54943 27689 0 0
+55000 27684 0 0
+55008 27684 0 0
+56408 27684 0 0
+56390 27588 0 0
+56392 27399 0 0
+56430 27214 0 0
+56503 27040 0 0
+56530 26999 0 0
+56497 26949 0 0
+56426 26774 0 0
+56390 26588 0 0
+56392 26399 0 0
+56430 26214 0 0
+56503 26040 0 0
+56608 25883 0 0
+56742 25750 0 0
+56900 25645 0 0
+57075 25573 0 0
+57260 25536 0 0
+57563 25535 0 0
+57753 25537 0 0
+57937 25577 0 0
+58111 25651 0 0
+58267 25758 0 0
+58400 25893 0 0
+58503 26051 0 0
+58574 26226 0 0
+58610 26412 0 0
+58608 26601 0 0
+58570 26786 0 0
+58497 26960 0 0
+58469 27000 0 0
+58503 27051 0 0
+58574 27226 0 0
+58610 27412 0 0
+58608 27601 0 0
+58570 27786 0 0
+58497 27960 0 0
+58469 28000 0 0
+58503 28051 0 0
+58574 28226 0 0
+58610 28412 0 0
+58608 28601 0 0
+58570 28786 0 0
+58497 28960 0 0
+58469 29000 0 0
+58503 29051 0 0
+58556 29184 0 0
+59253 29184 0 0
+59261 29184 0 0
+59328 29191 0 0
+59411 29200 0 0
+59416 29201 0 0
+59420 29202 1 0
+$endPOLYSCORNERS
+$endCZONE_OUTLINE
+$EndBOARD
diff --git a/kicad/10ch_pwm_ctrl.cache.bck b/kicad/10ch_pwm_ctrl.cache.bck
new file mode 100644
index 0000000..620e938
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.cache.bck
@@ -0,0 +1,16 @@
+EESchema-DOCLIB Version 2.0 19/12/2007-21:44:37
+#
+$CMP C
+D Condensateur non polarise
+$ENDCMP
+#
+$CMP CP
+D Condensateur polarise
+$ENDCMP
+#
+$CMP R
+D Resistance
+K R DEV
+$ENDCMP
+#
+#End Doc Library
diff --git a/kicad/10ch_pwm_ctrl.cache.dcm b/kicad/10ch_pwm_ctrl.cache.dcm
new file mode 100644
index 0000000..320be9d
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.cache.dcm
@@ -0,0 +1,48 @@
+EESchema-DOCLIB Version 2.0 09/02/2010 13:09:32
+#
+$CMP ATMEGA8-P
+D 8 Bit AVR Microcontroller, 8kB Flash, 1024B SRAM, 512B EEPROM
+K AVR avr ATMEL atmel MICROCONTROLLER microcontroller 8bit ATMEGA atmega ATMEGA8 atmega8
+$ENDCMP
+#
+$CMP C
+D Condensateur non polarise
+$ENDCMP
+#
+$CMP CONN_1
+D 1 pin
+K CONN
+$ENDCMP
+#
+$CMP CP
+D Condensateur polarise
+$ENDCMP
+#
+$CMP FILTER
+D Filtre EMI
+K EMI
+$ENDCMP
+#
+$CMP LED
+K LED
+$ENDCMP
+#
+$CMP MOS_N
+F transistors/mos/*.*
+$ENDCMP
+#
+$CMP MOS_P
+F transistors/mos/*.*
+$ENDCMP
+#
+$CMP R
+D Resistance
+K R DEV
+$ENDCMP
+#
+$CMP ZENER
+D Diode zener
+K DEV DIODE
+$ENDCMP
+#
+#End Doc Library
diff --git a/kicad/10ch_pwm_ctrl.cache.lib b/kicad/10ch_pwm_ctrl.cache.lib
new file mode 100644
index 0000000..7b3297d
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.cache.lib
@@ -0,0 +1,445 @@
+EESchema-LIBRARY Version 09/02/2010 13:09:32
+#
+#
+# +5V
+#
+DEF +5V #PWR 0 40 Y Y 1 F P
+F0 "#PWR" 0 90 20 H I C CNN
+F1 "+5V" 0 90 30 H V C CNN
+DRAW
+P 4 0 1 0 0 0 0 30 0 30 0 30 N
+C 0 50 20 0 1 0 N
+X +5V 1 0 0 0 U 20 20 0 0 W N
+ENDDRAW
+ENDDEF
+#
+# ATMEGA8-P
+#
+DEF ATMEGA8-P IC 0 40 Y Y 1 F N
+F0 "IC" -650 1250 50 H V L BNN
+F1 "ATMEGA8-P" 250 -1200 50 H V L BNN
+F2 "DIL28" 0 400 50 H I C CNN
+$FPLIST
+ 28DIP-ELL600
+ 28dip600
+$ENDFPLIST
+DRAW
+P 3 0 1 0 -700 1200 -700 -1100 -700 -1100 N
+P 3 0 1 0 800 1200 800 -1100 800 -1100 N
+P 2 1 0 0 -700 1200 800 1200 N
+P 2 1 0 0 800 -1100 -700 -1100 N
+X PD7(AIN1) 13 1000 -1000 200 L 40 40 1 1 B
+X PD6(AIN0) 12 1000 -900 200 L 40 40 1 1 B
+X PD5(T1) 11 1000 -800 200 L 40 40 1 1 B
+X PD4(XCK/T0) 6 1000 -700 200 L 40 40 1 1 B
+X PD3(INT1) 5 1000 -600 200 L 40 40 1 1 B
+X PD2(INT0) 4 1000 -500 200 L 40 40 1 1 B
+X PD1(TXD) 3 1000 -400 200 L 40 40 1 1 B
+X PD0(RXD) 2 1000 -300 200 L 40 40 1 1 B
+X PC5(ADC5/SCL) 28 1000 -100 200 L 40 40 1 1 B
+X PC4(ADC4/SDA) 27 1000 0 200 L 40 40 1 1 B
+X PC3(ADC3) 26 1000 100 200 L 40 40 1 1 B
+X PC2(ADC2) 25 1000 200 200 L 40 40 1 1 B
+X PC1(ADC1) 24 1000 300 200 L 40 40 1 1 B
+X PC0(ADC0) 23 1000 400 200 L 40 40 1 1 B
+X PB5(SCK) 19 1000 600 200 L 40 40 1 1 B
+X PB4(MISO) 18 1000 700 200 L 40 40 1 1 B
+X PB3(MOSI/OC2) 17 1000 800 200 L 40 40 1 1 B
+X PB2(SS/OC1B) 16 1000 900 200 L 40 40 1 1 B
+X PB1(OC1A) 15 1000 1000 200 L 40 40 1 1 B
+X PB0(ICP) 14 1000 1100 200 L 40 40 1 1 B
+X GND 8 -900 -900 200 R 40 40 1 1 B
+X VCC 7 -900 -800 200 R 40 40 1 1 B
+X AVCC 20 -900 -500 200 R 40 40 1 1 B
+X AREF 21 -900 -400 200 R 40 40 1 1 B
+X AGND 22 -900 -300 200 R 40 40 1 1 B
+X PC6(/RESET) 1 -900 400 200 R 40 40 1 1 B I
+X PB7(XTAL2/TOSC2) 10 -900 1000 200 R 40 40 1 1 B
+X PB6(XTAL1/TOSC1) 9 -900 1100 200 R 40 40 1 1 B
+ENDDRAW
+ENDDEF
+#
+# C
+#
+DEF C C 0 10 N Y 1 F N
+F0 "C" 50 100 50 H V L CNN
+F1 "C" 50 -100 50 H V L CNN
+$FPLIST
+ SM*
+ C?
+ C1-1
+$ENDFPLIST
+DRAW
+P 2 0 1 10 -100 30 100 30 N
+P 2 0 1 10 -100 -30 100 -30 N
+X ~ 1 0 200 170 D 40 40 1 1 P
+X ~ 2 0 -200 170 U 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# CONN_1
+#
+DEF ~CONN_1 P 0 30 N N 1 F N
+F0 "P" 80 0 40 H V L CNN
+F1 "CONN_1" 0 55 30 H I C CNN
+DRAW
+P 2 0 1 0 -30 0 -50 0 N
+C 0 0 31 0 1 0 N
+X 1 1 -150 0 100 R 60 60 1 1 P
+ENDDRAW
+ENDDEF
+#
+# CP
+#
+DEF CP C 0 10 N N 1 F N
+F0 "C" 50 100 50 H V L CNN
+F1 "CP" 50 -100 50 H V L CNN
+ALIAS CAPAPOL
+$FPLIST
+ CP*
+ SM*
+$ENDFPLIST
+DRAW
+P 4 0 1 0 -50 50 -50 -20 50 -20 50 50 F
+P 4 0 1 8 -100 50 -100 -50 100 -50 100 50 N
+X ~ 1 0 200 150 D 40 40 1 1 P
+X ~ 2 0 -200 150 U 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# CRYSTAL
+#
+DEF CRYSTAL X 0 40 N N 0 F N
+F0 "X" 0 150 60 H V C CNN
+F1 "CRYSTAL" 0 -150 60 H V C CNN
+DRAW
+P 5 0 1 12 -50 50 50 50 50 -50 -50 -50 -50 50 f
+P 2 0 1 16 100 100 100 -100 N
+P 2 0 1 16 -100 100 -100 -100 N
+X 2 2 300 0 200 L 40 40 1 1 P
+X 1 1 -300 0 200 R 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# FILTER
+#
+DEF FILTER FB 0 40 Y N 1 F N
+F0 "FB" 0 150 60 H V C CNN
+F1 "FILTER" 0 -100 60 H V C CNN
+DRAW
+S -225 75 225 -50 0 1 0 N
+A 150 0 50 1 1799 0 1 0 N 200 0 100 0
+A 0 0 0 0 0 0 1 0 N 0 0 0 0
+A 50 0 50 1 1799 0 1 0 N 100 0 0 0
+A -50 0 50 1 1799 0 1 0 N 0 0 -100 0
+A -150 0 50 1 1799 0 1 0 N -100 0 -200 0
+X 2 2 350 0 150 L 40 40 1 1 P
+X 1 1 -350 0 150 R 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# GND
+#
+DEF ~GND #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 0 30 H I C CNN
+F1 "GND" 0 -70 30 H I C CNN
+DRAW
+P 4 0 1 4 -50 0 0 -50 50 0 -50 0 N
+X GND 1 0 0 0 U 30 30 1 1 W N
+ENDDRAW
+ENDDEF
+#
+# JACK_2P
+#
+DEF JACK_2P J 0 40 Y Y 1 F N
+F0 "J" -350 -200 60 H V C CNN
+F1 "JACK_2P" -150 250 60 H V C CNN
+DRAW
+S -450 150 -400 -100 0 1 0 F
+P 4 0 1 0 0 -100 -50 -50 -100 -100 -100 -100 N
+S 300 -150 -400 200 0 1 0 N
+P 4 0 1 0 50 -50 100 -100 150 -50 150 -50 N
+P 3 0 1 0 150 0 300 0 300 0 N
+P 4 0 1 0 150 0 100 0 100 -100 100 -100 N
+P 5 0 1 0 300 150 -250 150 -300 100 -350 150 -350 150 N
+P 4 0 1 0 0 -100 300 -100 300 -100 300 -100 N
+X ~ 1 450 -100 150 L 50 50 1 1 P
+X ~ 2 450 0 150 L 50 50 1 1 P
+X ~ 3 450 150 150 L 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# JUMPER
+#
+DEF JUMPER JP 0 30 Y N 1 F N
+F0 "JP" 0 150 60 H V C CNN
+F1 "JUMPER" 0 -80 40 H V C CNN
+DRAW
+C 100 0 35 0 1 0 N
+C -100 0 35 0 1 0 N
+A 0 -26 125 1426 373 0 1 0 N -98 50 99 50
+X 2 2 300 0 165 L 60 60 0 1 P
+X 1 1 -300 0 165 R 60 60 0 1 P
+ENDDRAW
+ENDDEF
+#
+# LED
+#
+DEF LED D 0 40 Y N 1 F N
+F0 "D" 0 100 50 H V C CNN
+F1 "LED" 0 -100 50 H V C CNN
+$FPLIST
+ LED-3MM
+ LED-5MM
+ LED-10MM
+ LED-0603
+ LED-0805
+ LED-1206
+ LEDV
+$ENDFPLIST
+DRAW
+P 3 0 1 0 -50 50 50 0 -50 -50 F
+P 3 0 1 0 65 -40 110 -80 105 -55 N
+P 3 0 1 0 80 -25 125 -65 120 -40 N
+P 2 0 1 0 50 50 50 -50 N
+X K 2 200 0 150 L 40 40 1 1 P
+X A 1 -200 0 150 R 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# MEGA161P
+#
+DEF MEGA161P IC 0 40 Y Y 1 L N
+F0 "IC" -650 1450 50 H V L BNN
+F1 "MEGA161P" 250 -1400 50 H V L BNN
+F2 "atmel-DIL40" 0 1200 50 H I C CNN
+DRAW
+P 2 0 1 0 -750 1400 -750 -1300 N
+P 3 0 1 0 750 1400 750 -1300 750 -1300 N
+P 2 1 0 0 750 -1300 -750 -1300 N
+P 2 1 0 0 -750 1400 750 1400 N
+X (INT2)PE0 31 950 -1200 200 L 40 40 1 1 B
+X (ALE)PE1 30 950 -1100 200 L 40 40 1 1 B
+X (OC1B)PE2 29 950 -1000 200 L 40 40 1 1 B
+X (RXD0)PD0 10 950 -800 200 L 40 40 1 1 B
+X (TXD0)PD1 11 950 -700 200 L 40 40 1 1 B
+X (INT0)PD2 12 950 -600 200 L 40 40 1 1 B
+X (INT1)PD3 13 950 -500 200 L 40 40 1 1 B
+X (TOSC1)PD4 14 950 -400 200 L 40 40 1 1 B
+X (TOSC2)PD5 15 950 -300 200 L 40 40 1 1 B
+X (WR)PD6 16 950 -200 200 L 40 40 1 1 B
+X (RD)PD7 17 950 -100 200 L 40 40 1 1 B
+X (T0)PB0 1 950 100 200 L 40 40 1 1 B
+X (T1)PB1 2 950 200 200 L 40 40 1 1 B
+X (RXD1)PB2 3 950 300 200 L 40 40 1 1 B
+X (TXD1)PB3 4 950 400 200 L 40 40 1 1 B
+X (SS)PB4 5 950 500 200 L 40 40 1 1 B
+X (MOSI)PB5 6 950 600 200 L 40 40 1 1 B
+X (MISO)PB6 7 950 700 200 L 40 40 1 1 B
+X (SCK)PB7 8 950 800 200 L 40 40 1 1 B
+X GND 20 -950 -1200 200 R 40 40 1 1 W
+X VCC 40 -950 -1000 200 R 40 40 1 1 W
+X (A8)PC0 21 -950 -800 200 R 40 40 1 1 B
+X (A9)PC1 22 -950 -700 200 R 40 40 1 1 B
+X (A10)PC2 23 -950 -600 200 R 40 40 1 1 B
+X (A11)PC3 24 -950 -500 200 R 40 40 1 1 B
+X (A12)PC4 25 -950 -400 200 R 40 40 1 1 B
+X (A13)PC5 26 -950 -300 200 R 40 40 1 1 B
+X (A14)PC6 27 -950 -200 200 R 40 40 1 1 B
+X (A15)PC7 28 -950 -100 200 R 40 40 1 1 B
+X (AD0)PA0 39 -950 100 200 R 40 40 1 1 B
+X (AD1)PA1 38 -950 200 200 R 40 40 1 1 B
+X (AD2)PA2 37 -950 300 200 R 40 40 1 1 B
+X (AD3)PA3 36 -950 400 200 R 40 40 1 1 B
+X (AD4)PA4 35 -950 500 200 R 40 40 1 1 B
+X (AD5)PA5 34 -950 600 200 R 40 40 1 1 B
+X (AD6)PA6 33 -950 700 200 R 40 40 1 1 B
+X (AD7)PA7 32 -950 800 200 R 40 40 1 1 B
+X XTAL1 19 -950 1000 200 R 40 40 1 1 I
+X XTAL2 18 -950 1100 200 R 40 40 1 1 I
+X RESET 9 -950 1300 200 R 40 40 1 1 I I
+ENDDRAW
+ENDDEF
+#
+# MOS_N
+#
+DEF MOS_N Q 0 0 N Y 0 F N
+F0 "Q" 10 170 60 H V R CNN
+F1 "MOS_N" 10 -150 60 H V R CNN
+ALIAS MOSFET_N
+DRAW
+P 5 0 1 8 50 30 50 -30 0 0 50 30 50 30 N
+P 3 0 1 8 100 -100 100 0 50 0 N
+P 2 0 1 0 100 -100 0 -100 N
+P 2 0 1 0 100 100 0 100 N
+P 2 0 1 8 -50 -100 -50 100 N
+P 2 0 1 10 0 -150 0 150 N
+X D D 100 200 100 D 40 40 1 1 P
+X G G -200 0 150 R 40 40 1 1 I
+X S S 100 -200 100 U 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# MOS_P
+#
+DEF MOS_P Q 0 40 Y N 0 F N
+F0 "Q" 0 190 60 H V R CNN
+F1 "MOS_P" 0 -180 60 H V R CNN
+ALIAS MOSFET_P
+DRAW
+P 3 0 1 0 80 0 100 0 100 -100 N
+P 2 0 1 8 -50 -100 -50 100 N
+P 2 0 1 8 30 0 0 0 N
+P 2 0 1 0 100 -100 0 -100 N
+P 2 0 1 0 100 100 0 100 N
+P 5 0 1 8 30 40 30 -30 80 0 30 40 30 40 N
+P 2 0 1 10 0 -150 0 150 N
+X D D 100 200 100 D 40 40 1 1 P
+X G G -200 0 150 R 40 40 1 1 I
+X S S 100 -200 100 U 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+# PWR_FLAG
+#
+DEF PWR_FLAG #FLG 0 0 N N 1 F P
+F0 "#FLG" 0 270 30 H I C CNN
+F1 "PWR_FLAG" 0 230 30 H V C CNN
+DRAW
+P 3 0 1 0 0 0 0 100 0 100 N
+P 5 0 1 0 0 100 -100 150 0 200 100 150 0 100 N
+X pwr 1 0 0 0 U 20 20 0 0 w
+ENDDRAW
+ENDDEF
+#
+# R
+#
+DEF R R 0 0 N Y 1 F N
+F0 "R" 80 0 50 V V C CNN
+F1 "R" 0 0 50 V V C CNN
+$FPLIST
+ R?
+ SM0603
+ SM0805
+$ENDFPLIST
+DRAW
+S -40 150 40 -150 0 1 8 N
+X ~ 1 0 250 100 D 60 60 1 1 P
+X ~ 2 0 -250 100 U 60 60 1 1 P
+ENDDRAW
+ENDDEF
+#
+# RJ11
+#
+DEF RJ11 J 0 40 Y Y 1 F N
+F0 "J" 200 500 60 H V C CNN
+F1 "RJ11" -150 500 60 H V C CNN
+DRAW
+P 3 0 1 0 -50 250 -50 200 -50 200 N
+P 3 0 1 0 50 250 50 200 50 200 N
+P 3 0 1 0 0 250 0 200 0 200 N
+P 3 0 1 0 150 200 150 250 150 250 N
+P 14 0 1 0 -200 250 250 250 250 -150 150 -150 150 -200 100 -200 100 -250 -50 -250 -50 -200 -100 -200 -100 -150 -200 -150 -200 250 -200 250 N
+P 3 0 1 0 -100 250 -100 200 -100 200 N
+S 350 -300 -300 450 0 1 0 N
+P 3 0 1 0 100 250 100 200 100 200 N
+X ~ 1 -200 -450 150 U 50 50 1 1 P
+X ~ 2 -100 -450 150 U 50 50 1 1 P
+X ~ 3 0 -450 150 U 50 50 1 1 P
+X ~ 4 100 -450 150 U 50 50 1 1 P
+X ~ 5 200 -450 150 U 50 50 1 1 P
+X ~ 6 300 -450 150 U 50 50 1 1 P
+ENDDRAW
+ENDDEF
+#
+# ULN2803A
+#
+DEF ULN2803A IC 0 40 Y Y 1 L N
+F0 "IC" -300 530 50 H V L BNN
+F1 "ULN2803A" -300 -600 50 H V L BNN
+F2 "uln-udn-DIL18" 0 150 50 H I C CNN
+DRAW
+P 2 1 0 0 -300 500 -300 -500 N
+P 2 1 0 0 300 -500 -300 -500 N
+P 2 1 0 0 300 -500 300 500 N
+P 2 1 0 0 -300 500 300 500 N
+X CD+ 10 500 -400 200 L 40 40 1 1 P
+X O8 11 500 -300 200 L 40 40 1 1 C
+X O7 12 500 -200 200 L 40 40 1 1 C
+X O6 13 500 -100 200 L 40 40 1 1 C
+X O5 14 500 0 200 L 40 40 1 1 C
+X O4 15 500 100 200 L 40 40 1 1 C
+X O3 16 500 200 200 L 40 40 1 1 C
+X O2 17 500 300 200 L 40 40 1 1 C
+X O1 18 500 400 200 L 40 40 1 1 C
+X GND 9 -500 -400 200 R 40 40 1 1 W
+X I8 8 -500 -300 200 R 40 40 1 1 I
+X I7 7 -500 -200 200 R 40 40 1 1 I
+X I6 6 -500 -100 200 R 40 40 1 1 I
+X I5 5 -500 0 200 R 40 40 1 1 I
+X I4 4 -500 100 200 R 40 40 1 1 I
+X I3 3 -500 200 200 R 40 40 1 1 I
+X I2 2 -500 300 200 R 40 40 1 1 I
+X I1 1 -500 400 200 R 40 40 1 1 I
+ENDDRAW
+ENDDEF
+#
+# USB
+#
+DEF USB J 0 0 Y Y 1 F N
+F0 "J" -50 400 60 H V C CNN
+F1 "USB" -250 150 60 V V C CNN
+DRAW
+P 4 0 1 0 -100 -450 -50 -400 -50 -50 -50 -50 N
+P 4 0 1 0 50 -50 50 -250 200 -350 200 -350 N
+S 50 100 -100 100 0 1 0 N
+P 6 0 1 0 -200 -50 150 -50 150 350 -200 350 -200 -50 -200 -50 N
+P 4 0 1 0 0 -50 0 -400 50 -450 50 -450 N
+P 9 0 1 0 -150 0 100 0 100 250 50 300 -100 300 -150 250 -150 0 -150 0 -150 0 N
+S -100 200 50 200 0 1 0 N
+S -100 200 -100 100 0 1 0 N
+S -100 200 -100 200 0 1 0 N
+P 3 0 1 0 -150 -50 -250 -200 -250 -200 N
+P 4 0 1 0 -100 -50 -100 -250 -250 -350 -250 -350 N
+P 3 0 1 0 100 -50 200 -200 200 -200 N
+S 50 100 50 200 0 1 0 N
+X Shield_1 5 350 -450 300 L 40 30 1 1 P
+X D- 2 350 -350 150 L 40 30 1 1 B
+X D+ 3 350 -200 150 L 40 30 1 1 B
+X Shield_2 6 -400 -450 300 R 40 30 1 1 P
+X GND 4 -400 -350 150 R 40 30 1 1 w
+X Vbus 1 -400 -200 150 R 40 30 1 1 w
+ENDDRAW
+ENDDEF
+#
+# VDD
+#
+DEF VDD #PWR 0 0 Y Y 1 F P
+F0 "#PWR" 0 100 30 H I C CNN
+F1 "VDD" 0 110 30 H V C CNN
+DRAW
+P 3 0 1 0 0 0 0 40 0 40 N
+C 0 60 20 0 1 0 N
+X VDD 1 0 0 0 U 40 40 0 0 W N
+ENDDRAW
+ENDDEF
+#
+# ZENER
+#
+DEF ZENER D 0 40 N N 1 F N
+F0 "D" 0 100 50 H V C CNN
+F1 "ZENER" 0 -100 40 H V C CNN
+$FPLIST
+ D?
+ SO*
+ SM*
+$ENDFPLIST
+DRAW
+P 5 0 1 0 50 0 -50 50 -50 -50 50 0 50 0 F
+P 5 0 1 8 70 50 50 30 50 -30 30 -50 30 -50 N
+X K 2 200 0 150 L 40 40 1 1 P
+X A 1 -200 0 150 R 40 40 1 1 P
+ENDDRAW
+ENDDEF
+#
+#EndLibrary
diff --git a/kicad/10ch_pwm_ctrl.cmp b/kicad/10ch_pwm_ctrl.cmp
new file mode 100644
index 0000000..9629e25
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.cmp
@@ -0,0 +1,381 @@
+Cmp-Mod V01 Created by CVpcb (20090216-final) date = 03.01.2010 21:45:21
+
+BeginCmp
+TimeStamp = /4B234854;
+Reference = C1;
+ValeurCmp = 47p;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2347F4;
+Reference = C2;
+ValeurCmp = 47p;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2346F2;
+Reference = C3;
+ValeurCmp = 100nf;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2346EC;
+Reference = C4;
+ValeurCmp = 100nf;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2346D7;
+Reference = C5;
+ValeurCmp = 10uF;
+IdModule = C1V5;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2343E9;
+Reference = C6;
+ValeurCmp = 100nF;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2447DA;
+Reference = C7;
+ValeurCmp = 100nf;
+IdModule = C1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2447D9;
+Reference = C8;
+ValeurCmp = 100uF;
+IdModule = C1V5;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233832;
+Reference = D1;
+ValeurCmp = ZENER;
+IdModule = D4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233E78;
+Reference = D2;
+ValeurCmp = LED/2mA;
+IdModule = LED-3MM;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233F31;
+Reference = D3;
+ValeurCmp = 3V6;
+IdModule = D4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233F3B;
+Reference = D4;
+ValeurCmp = 3V6;
+IdModule = D4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B234662;
+Reference = FB1;
+ValeurCmp = 10uH;
+IdModule = R5;
+EndCmp
+
+BeginCmp
+TimeStamp = /47698597;
+Reference = IC1;
+ValeurCmp = ATmega162;
+IdModule = DIP-40__600_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4769864D;
+Reference = IC2;
+ValeurCmp = ULN2803/UDN2981;
+IdModule = DIP-18__300_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4769865A;
+Reference = IC3;
+ValeurCmp = ULN2803/UDN2981;
+IdModule = DIP-18__300_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EED;
+Reference = IC4;
+ValeurCmp = ULN2803/UDN2981;
+IdModule = DIP-18__300_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EEE;
+Reference = IC5;
+ValeurCmp = ULN2803/UDN2981;
+IdModule = DIP-18__300_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B28A789;
+Reference = IC6;
+ValeurCmp = ATMEGA8-P;
+IdModule = DIP-28__300_ELL;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2344C0;
+Reference = J1;
+ValeurCmp = PWR/IN;
+IdModule = JACK_ALIM;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23442B;
+Reference = J2;
+ValeurCmp = PWR/OUT;
+IdModule = JACK_ALIM;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232825;
+Reference = J3;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232846;
+Reference = J4;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232850;
+Reference = J5;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232858;
+Reference = J6;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232860;
+Reference = J7;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EEF;
+Reference = J8;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EF0;
+Reference = J9;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EF1;
+Reference = J10;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EF2;
+Reference = J11;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B232EF3;
+Reference = J12;
+ValeurCmp = RJ11;
+IdModule = MEBP6-4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233F56;
+Reference = J13;
+ValeurCmp = USB;
+IdModule = USB_B;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B28D598;
+Reference = JP1;
+ValeurCmp = JUMPER;
+IdModule = PIN_ARRAY_2X1;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD52;
+Reference = P1;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD80;
+Reference = P2;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD87;
+Reference = P3;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD89;
+Reference = P4;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD8B;
+Reference = P5;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD8D;
+Reference = P6;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD8F;
+Reference = P7;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23DD91;
+Reference = P8;
+ValeurCmp = CONN_1;
+IdModule = PINTST;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2338BA;
+Reference = Q1;
+ValeurCmp = BS170;
+IdModule = TO92SGD;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B23346A;
+Reference = Q2;
+ValeurCmp = IRF9540N;
+IdModule = TO220GDS;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B234A65;
+Reference = R1;
+ValeurCmp = 5K6;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233954;
+Reference = R2;
+ValeurCmp = 1K5;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2338D9;
+Reference = R3;
+ValeurCmp = 47K;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2337C6;
+Reference = R4;
+ValeurCmp = 1K5;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233808;
+Reference = R5;
+ValeurCmp = 100;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233E03;
+Reference = R6;
+ValeurCmp = 1K2;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233EFA;
+Reference = R7;
+ValeurCmp = 68;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233EC8;
+Reference = R8;
+ValeurCmp = 68;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B233F05;
+Reference = R9;
+ValeurCmp = 2K2;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B27466D;
+Reference = R10;
+ValeurCmp = 1K;
+IdModule = R4;
+EndCmp
+
+BeginCmp
+TimeStamp = /4B2347D4;
+Reference = X1;
+ValeurCmp = 16Mhz;
+IdModule = HC-18UV;
+EndCmp
+
+EndListe
diff --git a/kicad/10ch_pwm_ctrl.lst b/kicad/10ch_pwm_ctrl.lst
new file mode 100644
index 0000000..840da63
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.lst
@@ -0,0 +1,117 @@
+EESchema (20090216-final) >> Creation date: 09/02/2010 13:09:24
+
+#Cmp ( order = Reference )
+| C1 47p
+| C2 47p
+| C3 100nf
+| C4 100nf
+| C5 10uF
+| C6 100nF
+| C7 100nf
+| C8 4,7uF
+| D1 Z<=(VDD - 5,5V) 1,3W
+| D2 LED/2mA
+| D3 3V6 0,5W
+| D4 3V6 0,5W
+| FB1 10uH
+| IC1 ATmega162
+| IC2 ULN2803/UDN2981
+| IC3 ULN2803/UDN2981
+| IC4 ULN2803/UDN2981
+| IC5 ULN2803/UDN2981
+| IC6 ATMEGA8-P
+| J1 PWR/IN
+| J2 PWR/OUT
+| J3 RJ11
+| J4 RJ11
+| J5 RJ11
+| J6 RJ11
+| J7 RJ11
+| J8 RJ11
+| J9 RJ11
+| J10 RJ11
+| J11 RJ11
+| J12 RJ11
+| J13 USB
+| JP1 Bootloader
+| P1 CONN_1
+| P2 CONN_1
+| P3 CONN_1
+| P4 CONN_1
+| P5 CONN_1
+| P6 CONN_1
+| P7 CONN_1
+| P8 CONN_1
+| Q1 BS170
+| Q2 IRF9540N
+| R1 5K6
+| R2 1K5
+| R3 47K
+| R4 270
+| R5 100
+| R6 1K2
+| R7 68
+| R8 68
+| R9 2K2
+| R10 1K
+| X1 16Mhz
+#End Cmp
+
+#Cmp ( order = Value )
+| 100 R5
+| 100nf C3
+| 100nf C4
+| 100nF C6
+| 100nf C7
+| 10uF C5
+| 10uH FB1
+| 16Mhz X1
+| 1K R10
+| 1K2 R6
+| 1K5 R2
+| 270 R4
+| 2K2 R9
+| 3V6 0,5W D3
+| 3V6 0,5W D4
+| 4,7uF C8
+| 47K R3
+| 47p C1
+| 47p C2
+| 5K6 R1
+| 68 R7
+| 68 R8
+| ATmega162 IC1
+| ATMEGA8-P IC6
+| Bootloader JP1
+| BS170 Q1
+| CONN_1 P1
+| CONN_1 P2
+| CONN_1 P3
+| CONN_1 P4
+| CONN_1 P5
+| CONN_1 P6
+| CONN_1 P7
+| CONN_1 P8
+| IRF9540N Q2
+| LED/2mA D2
+| PWR/IN J1
+| PWR/OUT J2
+| RJ11 J3
+| RJ11 J4
+| RJ11 J5
+| RJ11 J6
+| RJ11 J7
+| RJ11 J8
+| RJ11 J9
+| RJ11 J10
+| RJ11 J11
+| RJ11 J12
+| ULN2803/UDN2981 IC2
+| ULN2803/UDN2981 IC3
+| ULN2803/UDN2981 IC4
+| ULN2803/UDN2981 IC5
+| USB J13
+| Z<=(VDD - 5,5V) 1,3W D1
+#End Cmp
+
+#End List
diff --git a/kicad/10ch_pwm_ctrl.net b/kicad/10ch_pwm_ctrl.net
new file mode 100644
index 0000000..1652c40
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.net
@@ -0,0 +1,855 @@
+# EESchema Netlist Version 1.1 created 09/02/2010 13:09:16
+(
+ ( /4B28D598 $noname JP1 Bootloader {Lib=JUMPER}
+ ( 1 N-000088 )
+ ( 2 GND )
+ )
+ ( /4B28A789 DIL28 IC6 ATMEGA8-P {Lib=ATMEGA8-P}
+ ( 1 ? )
+ ( 2 N-000005 )
+ ( 3 N-000084 )
+ ( 4 N-000083 )
+ ( 5 N-000008 )
+ ( 6 N-000037 )
+ ( 7 +5V )
+ ( 8 GND )
+ ( 9 N-000086 )
+ ( 10 N-000085 )
+ ( 11 ? )
+ ( 12 ? )
+ ( 13 ? )
+ ( 14 N-000088 )
+ ( 15 ? )
+ ( 16 ? )
+ ( 17 N-000002 )
+ ( 18 N-000004 )
+ ( 19 ? )
+ ( 20 +5V )
+ ( 21 ? )
+ ( 22 GND )
+ ( 23 ? )
+ ( 24 ? )
+ ( 25 ? )
+ ( 26 ? )
+ ( 27 ? )
+ ( 28 ? )
+ )
+ ( /4B27466D $noname R10 1K {Lib=R}
+ ( 1 N-000002 )
+ ( 2 N-000087 )
+ )
+ ( /4B2447DA $noname C7 100nf {Lib=C}
+ ( 1 VDD )
+ ( 2 GND )
+ )
+ ( /4B2447D9 $noname C8 4,7uF {Lib=CAPAPOL}
+ ( 1 VDD )
+ ( 2 GND )
+ )
+ ( /4B23DD91 $noname P8 CONN_1 {Lib=CONN_1}
+ ( 1 N-000040 )
+ )
+ ( /4B23DD8F $noname P7 CONN_1 {Lib=CONN_1}
+ ( 1 /RGB_COMMON )
+ )
+ ( /4B23DD8D $noname P6 CONN_1 {Lib=CONN_1}
+ ( 1 GND )
+ )
+ ( /4B23DD8B $noname P5 CONN_1 {Lib=CONN_1}
+ ( 1 N-000042 )
+ )
+ ( /4B23DD89 $noname P4 CONN_1 {Lib=CONN_1}
+ ( 1 GND )
+ )
+ ( /4B23DD87 $noname P3 CONN_1 {Lib=CONN_1}
+ ( 1 N-000040 )
+ )
+ ( /4B23DD80 $noname P2 CONN_1 {Lib=CONN_1}
+ ( 1 N-000041 )
+ )
+ ( /4B23DD52 $noname P1 CONN_1 {Lib=CONN_1}
+ ( 1 GND )
+ )
+ ( /4B234A65 $noname R1 5K6 {Lib=R}
+ ( 1 N-000004 )
+ ( 2 GND )
+ )
+ ( /4B234854 $noname C1 47p {Lib=C}
+ ( 1 GND )
+ ( 2 N-000086 )
+ )
+ ( /4B2347F4 $noname C2 47p {Lib=C}
+ ( 1 GND )
+ ( 2 N-000085 )
+ )
+ ( /4B2347D4 $noname X1 16Mhz {Lib=CRYSTAL}
+ ( 1 N-000086 )
+ ( 2 N-000085 )
+ )
+ ( /4B2346F2 $noname C3 100nf {Lib=C}
+ ( 1 +5V )
+ ( 2 GND )
+ )
+ ( /4B2346EC $noname C4 100nf {Lib=C}
+ ( 1 +5V )
+ ( 2 GND )
+ )
+ ( /4B2346D7 $noname C5 10uF {Lib=CAPAPOL}
+ ( 1 +5V )
+ ( 2 GND )
+ )
+ ( /4B234662 $noname FB1 10uH {Lib=FILTER}
+ ( 1 +5V )
+ ( 2 N-000034 )
+ )
+ ( /4B2344C0 $noname J1 PWR/IN {Lib=JACK_2P}
+ ( 1 VDD )
+ ( 2 ? )
+ ( 3 GND )
+ )
+ ( /4B23442B $noname J2 PWR/OUT {Lib=JACK_2P}
+ ( 1 VDD )
+ ( 2 ? )
+ ( 3 GND )
+ )
+ ( /4B2343E9 $noname C6 100nF {Lib=C}
+ ( 1 N-000034 )
+ ( 2 GND )
+ )
+ ( /4B233F56 $noname J13 USB {Lib=USB}
+ ( 1 N-000034 )
+ ( 2 N-000038 )
+ ( 3 N-000039 )
+ ( 4 GND )
+ ( 5 GND )
+ ( 6 GND )
+ )
+ ( /4B233F3B $noname D4 3V6_0,5W {Lib=ZENER}
+ ( 1 GND )
+ ( 2 N-000039 )
+ )
+ ( /4B233F31 $noname D3 3V6_0,5W {Lib=ZENER}
+ ( 1 GND )
+ ( 2 N-000038 )
+ )
+ ( /4B233F05 $noname R9 2K2 {Lib=R}
+ ( 1 N-000038 )
+ ( 2 N-000037 )
+ )
+ ( /4B233EFA $noname R7 68 {Lib=R}
+ ( 1 N-000039 )
+ ( 2 N-000083 )
+ )
+ ( /4B233EC8 $noname R8 68 {Lib=R}
+ ( 1 N-000038 )
+ ( 2 N-000008 )
+ )
+ ( /4B233E78 $noname D2 LED/2mA {Lib=LED}
+ ( 1 N-000082 )
+ ( 2 GND )
+ )
+ ( /4B233E03 $noname R6 1K2 {Lib=R}
+ ( 1 N-000003 )
+ ( 2 N-000082 )
+ )
+ ( /4B233954 $noname R2 1K5 {Lib=R}
+ ( 1 N-000006 )
+ ( 2 N-000048 )
+ )
+ ( /4B2338D9 $noname R3 47K {Lib=R}
+ ( 1 GND )
+ ( 2 N-000048 )
+ )
+ ( /4B2338BA $noname Q1 BS170 {Lib=MOSFET_N}
+ ( G N-000048 )
+ ( S GND )
+ ( D N-000035 )
+ )
+ ( /4B233832 $noname D1 Z<=(VDD_-_5,5V)__1,3W {Lib=ZENER}
+ ( 1 N-000035 )
+ ( 2 N-000036 )
+ )
+ ( /4B233808 $noname R5 100 {Lib=R}
+ ( 1 N-000049 )
+ ( 2 N-000036 )
+ )
+ ( /4B2337C6 $noname R4 270 {Lib=R}
+ ( 1 VDD )
+ ( 2 N-000036 )
+ )
+ ( /4B23346A $noname Q2 IRF9540N {Lib=MOSFET_P}
+ ( G N-000049 )
+ ( S VDD )
+ ( D N-000040 )
+ )
+ ( /4B232EF3 $noname J12 RJ11 {Lib=RJ11}
+ ( 1 N-000017 )
+ ( 2 N-000018 )
+ ( 3 N-000017 )
+ ( 4 N-000016 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232EF2 $noname J11 RJ11 {Lib=RJ11}
+ ( 1 N-000076 )
+ ( 2 N-000015 )
+ ( 3 N-000076 )
+ ( 4 N-000078 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232EF1 $noname J10 RJ11 {Lib=RJ11}
+ ( 1 N-000014 )
+ ( 2 N-000013 )
+ ( 3 N-000014 )
+ ( 4 N-000075 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232EF0 $noname J9 RJ11 {Lib=RJ11}
+ ( 1 N-000019 )
+ ( 2 N-000079 )
+ ( 3 N-000019 )
+ ( 4 N-000012 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232EEF $noname J8 RJ11 {Lib=RJ11}
+ ( 1 N-000010 )
+ ( 2 N-000011 )
+ ( 3 N-000010 )
+ ( 4 N-000080 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232EEE uln-udn-DIL18 IC5 ULN2803/UDN2981 {Lib=ULN2803A}
+ ( 1 /PB7 )
+ ( 2 /PB6 )
+ ( 3 /PB5 )
+ ( 4 /PB4 )
+ ( 5 /PB3 )
+ ( 6 /PB2 )
+ ( 7 /PB1 )
+ ( 8 /PB0 )
+ ( 9 N-000041 )
+ ( 10 N-000042 )
+ ( 11 N-000017 )
+ ( 12 N-000018 )
+ ( 13 N-000016 )
+ ( 14 N-000076 )
+ ( 15 N-000015 )
+ ( 16 N-000078 )
+ ( 17 N-000014 )
+ ( 18 N-000013 )
+ )
+ ( /4B232EED uln-udn-DIL18 IC4 ULN2803/UDN2981 {Lib=ULN2803A}
+ ( 1 /PC0 )
+ ( 2 /PC0 )
+ ( 3 /PD7 )
+ ( 4 /PD6 )
+ ( 5 /PD5 )
+ ( 6 /PD4 )
+ ( 7 /PD3 )
+ ( 8 /PD2 )
+ ( 9 N-000041 )
+ ( 10 N-000042 )
+ ( 11 N-000075 )
+ ( 12 N-000019 )
+ ( 13 N-000079 )
+ ( 14 N-000012 )
+ ( 15 N-000010 )
+ ( 16 N-000011 )
+ ( 17 N-000080 )
+ ( 18 ? )
+ )
+ ( /4B232860 $noname J7 RJ11 {Lib=RJ11}
+ ( 1 N-000047 )
+ ( 2 N-000020 )
+ ( 3 N-000047 )
+ ( 4 N-000046 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232858 $noname J6 RJ11 {Lib=RJ11}
+ ( 1 N-000021 )
+ ( 2 N-000074 )
+ ( 3 N-000021 )
+ ( 4 N-000043 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232850 $noname J5 RJ11 {Lib=RJ11}
+ ( 1 N-000022 )
+ ( 2 N-000023 )
+ ( 3 N-000022 )
+ ( 4 N-000073 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232846 $noname J4 RJ11 {Lib=RJ11}
+ ( 1 N-000072 )
+ ( 2 N-000024 )
+ ( 3 N-000072 )
+ ( 4 N-000045 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4B232825 $noname J3 RJ11 {Lib=RJ11}
+ ( 1 N-000025 )
+ ( 2 N-000026 )
+ ( 3 N-000025 )
+ ( 4 N-000044 )
+ ( 5 /RGB_COMMON )
+ ( 6 /RGB_COMMON )
+ )
+ ( /4769865A uln-udn-DIL18 IC3 ULN2803/UDN2981 {Lib=ULN2803A}
+ ( 1 /PC7 )
+ ( 2 /PC6 )
+ ( 3 /PC5 )
+ ( 4 /PC4 )
+ ( 5 /PC3 )
+ ( 6 /PC2 )
+ ( 7 /PC1 )
+ ( 8 /PC1 )
+ ( 9 N-000041 )
+ ( 10 N-000042 )
+ ( 11 ? )
+ ( 12 N-000047 )
+ ( 13 N-000020 )
+ ( 14 N-000046 )
+ ( 15 N-000021 )
+ ( 16 N-000074 )
+ ( 17 N-000043 )
+ ( 18 N-000022 )
+ )
+ ( /4769864D uln-udn-DIL18 IC2 ULN2803/UDN2981 {Lib=ULN2803A}
+ ( 1 /PA0 )
+ ( 2 /PA1 )
+ ( 3 /PA2 )
+ ( 4 /PA3 )
+ ( 5 /PA4 )
+ ( 6 /PA5 )
+ ( 7 /PA6 )
+ ( 8 /PA7 )
+ ( 9 N-000041 )
+ ( 10 N-000042 )
+ ( 11 N-000023 )
+ ( 12 N-000073 )
+ ( 13 N-000072 )
+ ( 14 N-000024 )
+ ( 15 N-000045 )
+ ( 16 N-000025 )
+ ( 17 N-000026 )
+ ( 18 N-000044 )
+ )
+ ( /47698597 $noname IC1 ATmega162 {Lib=MEGA161P}
+ ( 1 /PB0 )
+ ( 2 /PB1 )
+ ( 3 /PB2 )
+ ( 4 /PB3 )
+ ( 5 /PB4 )
+ ( 6 /PB5 )
+ ( 7 /PB6 )
+ ( 8 /PB7 )
+ ( 9 N-000004 )
+ ( 10 N-000084 )
+ ( 11 N-000005 )
+ ( 12 /PD2 )
+ ( 13 /PD3 )
+ ( 14 /PD4 )
+ ( 15 /PD5 )
+ ( 16 /PD6 )
+ ( 17 /PD7 )
+ ( 18 ? )
+ ( 19 N-000085 )
+ ( 20 GND )
+ ( 21 /PC0 )
+ ( 22 /PC1 )
+ ( 23 /PC2 )
+ ( 24 /PC3 )
+ ( 25 /PC4 )
+ ( 26 /PC5 )
+ ( 27 /PC6 )
+ ( 28 /PC7 )
+ ( 29 N-000006 )
+ ( 30 N-000003 )
+ ( 31 N-000087 )
+ ( 32 /PA7 )
+ ( 33 /PA6 )
+ ( 34 /PA5 )
+ ( 35 /PA4 )
+ ( 36 /PA3 )
+ ( 37 /PA2 )
+ ( 38 /PA1 )
+ ( 39 /PA0 )
+ ( 40 +5V )
+ )
+)
+*
+{ Allowed footprints by component:
+$component IC6
+ 28DIP-ELL600
+ 28dip600
+$endlist
+$component R10
+ R?
+ SM0603
+ SM0805
+$endlist
+$component C7
+ SM*
+ C?
+ C1-1
+$endlist
+$component C8
+ CP*
+ SM*
+$endlist
+$component R1
+ R?
+ SM0603
+ SM0805
+$endlist
+$component C1
+ SM*
+ C?
+ C1-1
+$endlist
+$component C2
+ SM*
+ C?
+ C1-1
+$endlist
+$component C3
+ SM*
+ C?
+ C1-1
+$endlist
+$component C4
+ SM*
+ C?
+ C1-1
+$endlist
+$component C5
+ CP*
+ SM*
+$endlist
+$component C6
+ SM*
+ C?
+ C1-1
+$endlist
+$component D4
+ D?
+ SO*
+ SM*
+$endlist
+$component D3
+ D?
+ SO*
+ SM*
+$endlist
+$component R9
+ R?
+ SM0603
+ SM0805
+$endlist
+$component R7
+ R?
+ SM0603
+ SM0805
+$endlist
+$component R8
+ R?
+ SM0603
+ SM0805
+$endlist
+$component D2
+ LED-3MM
+ LED-5MM
+ LED-10MM
+ LED-0603
+ LED-0805
+ LED-1206
+ LEDV
+$endlist
+$component R6
+ R?
+ SM0603
+ SM0805
+$endlist
+$component R2
+ R?
+ SM0603
+ SM0805
+$endlist
+$component R3
+ R?
+ SM0603
+ SM0805
+$endlist
+$component D1
+ D?
+ SO*
+ SM*
+$endlist
+$component R5
+ R?
+ SM0603
+ SM0805
+$endlist
+$component R4
+ R?
+ SM0603
+ SM0805
+$endlist
+$endfootprintlist
+}
+{ Pin List by Nets
+Net 1 "GND" "GND"
+ IC1 20
+ Q1 S
+ R3 1
+ D2 2
+ D3 1
+ D4 1
+ J13 4
+ J13 6
+ J13 5
+ C6 2
+ J2 3
+ J1 3
+ C5 2
+ C4 2
+ C3 2
+ C2 1
+ C1 1
+ R1 2
+ P1 1
+ P4 1
+ P6 1
+ C8 2
+ C7 2
+ IC6 22
+ IC6 8
+ JP1 2
+Net 2 "" ""
+ R10 1
+ IC6 17
+Net 3 "" ""
+ IC1 30
+ R6 1
+Net 4 "" ""
+ IC1 9
+ R1 1
+ IC6 18
+Net 5 "" ""
+ IC6 2
+ IC1 11
+Net 6 "" ""
+ IC1 29
+ R2 1
+Net 7 "+5V" "+5V"
+ IC1 40
+ IC6 7
+ IC6 20
+ C3 1
+ C4 1
+ C5 1
+ FB1 1
+Net 8 "" ""
+ R8 2
+ IC6 5
+Net 9 "/PC1" "PC1"
+ IC3 7
+ IC1 22
+ IC3 8
+Net 10 "" ""
+ J8 1
+ J8 3
+ IC4 15
+Net 11 "" ""
+ J8 2
+ IC4 16
+Net 12 "" ""
+ J9 4
+ IC4 14
+Net 13 "" ""
+ IC5 18
+ J10 2
+Net 14 "" ""
+ J10 1
+ IC5 17
+ J10 3
+Net 15 "" ""
+ IC5 15
+ J11 2
+Net 16 "" ""
+ IC5 13
+ J12 4
+Net 17 "" ""
+ IC5 11
+ J12 1
+ J12 3
+Net 18 "" ""
+ IC5 12
+ J12 2
+Net 19 "" ""
+ J9 3
+ J9 1
+ IC4 12
+Net 20 "" ""
+ IC3 13
+ J7 2
+Net 21 "" ""
+ J6 3
+ IC3 15
+ J6 1
+Net 22 "" ""
+ J5 3
+ IC3 18
+ J5 1
+Net 23 "" ""
+ J5 2
+ IC2 11
+Net 24 "" ""
+ J4 2
+ IC2 14
+Net 25 "" ""
+ J3 1
+ IC2 16
+ J3 3
+Net 26 "" ""
+ J3 2
+ IC2 17
+Net 27 "/PC2" "PC2"
+ IC3 6
+ IC1 23
+Net 28 "/PC4" "PC4"
+ IC1 25
+ IC3 4
+Net 29 "/PC6" "PC6"
+ IC3 2
+ IC1 27
+Net 30 "/PA7" "PA7"
+ IC2 8
+ IC1 32
+Net 31 "/PA5" "PA5"
+ IC2 6
+ IC1 34
+Net 32 "/PA3" "PA3"
+ IC2 4
+ IC1 36
+Net 33 "/PA1" "PA1"
+ IC2 2
+ IC1 38
+Net 34 "" ""
+ FB1 2
+ J13 1
+ C6 1
+Net 35 "" ""
+ D1 1
+ Q1 D
+Net 36 "" ""
+ R4 2
+ R5 2
+ D1 2
+Net 37 "" ""
+ IC6 6
+ R9 2
+Net 38 "" ""
+ R8 1
+ D3 2
+ R9 1
+ J13 2
+Net 39 "" ""
+ R7 1
+ J13 3
+ D4 2
+Net 40 "" ""
+ P3 1
+ P8 1
+ Q2 D
+Net 41 "" ""
+ IC2 9
+ P2 1
+ IC4 9
+ IC5 9
+ IC3 9
+Net 42 "" ""
+ IC4 10
+ IC2 10
+ IC5 10
+ P5 1
+ IC3 10
+Net 43 "" ""
+ IC3 17
+ J6 4
+Net 44 "" ""
+ IC2 18
+ J3 4
+Net 45 "" ""
+ IC2 15
+ J4 4
+Net 46 "" ""
+ J7 4
+ IC3 14
+Net 47 "" ""
+ J7 3
+ J7 1
+ IC3 12
+Net 48 "" ""
+ R2 2
+ R3 2
+ Q1 G
+Net 49 "" ""
+ R5 1
+ Q2 G
+Net 50 "/PA0" "PA0"
+ IC1 39
+ IC2 1
+Net 51 "/PA2" "PA2"
+ IC2 3
+ IC1 37
+Net 52 "/PA4" "PA4"
+ IC1 35
+ IC2 5
+Net 53 "/PA6" "PA6"
+ IC1 33
+ IC2 7
+Net 54 "/PC7" "PC7"
+ IC3 1
+ IC1 28
+Net 55 "/PC5" "PC5"
+ IC1 26
+ IC3 3
+Net 56 "/PC3" "PC3"
+ IC3 5
+ IC1 24
+Net 57 "/PD7" "PD7"
+ IC1 17
+ IC4 3
+Net 58 "/PD6" "PD6"
+ IC4 4
+ IC1 16
+Net 59 "/PD5" "PD5"
+ IC1 15
+ IC4 5
+Net 60 "/PD4" "PD4"
+ IC4 6
+ IC1 14
+Net 61 "/PD3" "PD3"
+ IC1 13
+ IC4 7
+Net 62 "/PD2" "PD2"
+ IC1 12
+ IC4 8
+Net 63 "/PB7" "PB7"
+ IC1 8
+ IC5 1
+Net 64 "/PB6" "PB6"
+ IC1 7
+ IC5 2
+Net 65 "/PB5" "PB5"
+ IC5 3
+ IC1 6
+Net 66 "/PB4" "PB4"
+ IC5 4
+ IC1 5
+Net 67 "/PB3" "PB3"
+ IC1 4
+ IC5 5
+Net 68 "/PB2" "PB2"
+ IC5 6
+ IC1 3
+Net 69 "/PB1" "PB1"
+ IC5 7
+ IC1 2
+Net 70 "/PB0" "PB0"
+ IC5 8
+ IC1 1
+Net 71 "/RGB COMMON" "RGB COMMON"
+ J3 6
+ J3 5
+ P7 1
+ J4 6
+ J4 5
+ J5 6
+ J5 5
+ J12 5
+ J12 6
+ J8 6
+ J6 6
+ J6 5
+ J8 5
+ J11 5
+ J11 6
+ J9 6
+ J9 5
+ J10 5
+ J10 6
+ J7 5
+ J7 6
+Net 72 "" ""
+ IC2 13
+ J4 3
+ J4 1
+Net 73 "" ""
+ J5 4
+ IC2 12
+Net 74 "" ""
+ IC3 16
+ J6 2
+Net 75 "" ""
+ J10 4
+ IC4 11
+Net 76 "" ""
+ J11 3
+ IC5 14
+ J11 1
+Net 77 "VDD" "VDD"
+ C8 1
+ J1 1
+ Q2 S
+ C7 1
+ R4 1
+ J2 1
+Net 78 "" ""
+ IC5 16
+ J11 4
+Net 79 "" ""
+ IC4 13
+ J9 2
+Net 80 "" ""
+ J8 4
+ IC4 17
+Net 81 "/PC0" "PC0"
+ IC4 1
+ IC1 21
+ IC4 2
+Net 82 "" ""
+ D2 1
+ R6 2
+Net 83 "" ""
+ R7 2
+ IC6 4
+Net 84 "" ""
+ IC1 10
+ IC6 3
+Net 85 "" ""
+ X1 2
+ IC1 19
+ IC6 10
+ C2 2
+Net 86 "" ""
+ X1 1
+ C1 2
+ IC6 9
+Net 87 "" ""
+ IC1 31
+ R10 2
+Net 88 "" ""
+ JP1 1
+ IC6 14
+}
+#End
diff --git a/kicad/10ch_pwm_ctrl.pro b/kicad/10ch_pwm_ctrl.pro
new file mode 100644
index 0000000..1ceeca5
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.pro
@@ -0,0 +1,121 @@
+update=09.02.2010 12:52:43
+last_client=pcbnew
+[general]
+version=1
+RootSch=10ch_pwm_ctrl.sch
+BoardNm=10ch_pwm_ctrl.brd
+[cvpcb]
+version=1
+NetIExt=.net
+[cvpcb/libraries]
+EquName1=devcms
+[common]
+NetDir=
+[eeschema]
+version=1
+LibDir=
+NetFmt=1
+HPGLSpd=20
+HPGLDm=15
+HPGLNum=1
+offX_A4=0
+offY_A4=0
+offX_A3=0
+offY_A3=0
+offX_A2=0
+offY_A2=0
+offX_A1=0
+offY_A1=0
+offX_A0=0
+offY_A0=0
+offX_A=0
+offY_A=0
+offX_B=0
+offY_B=0
+offX_C=0
+offY_C=0
+offX_D=0
+offY_D=0
+offX_E=0
+offY_E=0
+RptD_X=0
+RptD_Y=100
+RptLab=1
+SimCmd=
+UseNetN=0
+LabSize=60
+[eeschema/libraries]
+LibName1=power
+LibName2=device
+LibName3=conn
+LibName4=linear
+LibName5=regul
+LibName6=74xx
+LibName7=cmos4000
+LibName8=adc-dac
+LibName9=memory
+LibName10=xilinx
+LibName11=special
+LibName12=microcontrollers
+LibName13=dsp
+LibName14=microchip
+LibName15=analog_switches
+LibName16=motorola
+LibName17=texas
+LibName18=intel
+LibName19=audio
+LibName20=interface
+LibName21=digital-audio
+LibName22=philips
+LibName23=display
+LibName24=cypress
+LibName25=siliconi
+LibName26=contrib
+LibName27=valves
+[pcbnew]
+version=1
+PadDrlX=1181
+PadDimH=1890
+PadDimV=1890
+ViaDiam=1000
+ViaDril=319
+ViaAltD=250
+MViaDia=200
+MViaDrl=80
+Isol=100
+Countlayer=2
+Lpiste=500
+RouteTo=15
+RouteBo=0
+TypeVia=3
+Segm45=1
+Racc45=1
+SgPcb45=1
+TxtPcbV=800
+TxtPcbH=600
+TxtModV=600
+TxtModH=600
+TxtModW=120
+HPGLnum=1
+HPGdiam=15
+HPGLSpd=20
+HPGLrec=2
+HPGLorg=0
+VEgarde=100
+DrawLar=150
+EdgeLar=150
+TxtLar=120
+MSegLar=150
+WpenSer=10
+[pcbnew/libraries]
+LibDir=
+LibName1=sockets
+LibName2=connect
+LibName3=discret
+LibName4=pin_array
+LibName5=divers
+LibName6=libcms
+LibName7=display
+LibName8=valves
+LibName9=led
+LibName10=dip_sockets
diff --git a/kicad/10ch_pwm_ctrl.sch b/kicad/10ch_pwm_ctrl.sch
new file mode 100644
index 0000000..780676d
--- /dev/null
+++ b/kicad/10ch_pwm_ctrl.sch
@@ -0,0 +1,1585 @@
+EESchema Schematic File Version 2 date 09/02/2010 13:09:32
+LIBS:power,device,conn,linear,regul,74xx,cmos4000,adc-dac,memory,xilinx,special,microcontrollers,dsp,microchip,analog_switches,motorola,texas,intel,audio,interface,digital-audio,philips,display,cypress,siliconi,contrib,valves,.\10ch_pwm_ctrl.cache
+EELAYER 23 0
+EELAYER END
+$Descr User 8265 11692
+Sheet 1 1
+Title "DF10CH Atmolight Controller"
+Date "16 dec 2009"
+Rev "3"
+Comp "Copyright Andreas Auras"
+Comment1 ""
+Comment2 ""
+Comment3 ""
+Comment4 ""
+$EndDescr
+Wire Wire Line
+ 4150 7950 4150 8050
+Wire Wire Line
+ 4350 6700 4350 7200
+Wire Wire Line
+ 4350 7200 3700 7200
+Wire Wire Line
+ 3700 5950 4600 5950
+Wire Wire Line
+ 3700 7300 3750 7300
+Wire Wire Line
+ 3750 7300 3750 6400
+Wire Wire Line
+ 900 10200 900 10350
+Wire Wire Line
+ 900 7450 900 6900
+Wire Wire Line
+ 900 6900 1800 6900
+Connection ~ 1600 7200
+Wire Wire Line
+ 1550 7200 1600 7200
+Connection ~ 1400 3550
+Wire Wire Line
+ 1800 3550 1000 3550
+Wire Wire Line
+ 4600 5950 4600 6200
+Wire Wire Line
+ 3700 8300 3950 8300
+Wire Wire Line
+ 3950 8300 3950 5550
+Wire Wire Line
+ 3950 5550 3700 5550
+Wire Wire Line
+ 4300 5850 4300 2850
+Wire Wire Line
+ 4300 5850 3700 5850
+Connection ~ 700 8500
+Wire Wire Line
+ 700 8500 1800 8500
+Wire Wire Line
+ 1700 8900 1800 8900
+Wire Wire Line
+ 700 8800 1800 8800
+Wire Wire Line
+ 2350 10200 700 10200
+Wire Wire Line
+ 1600 7850 1600 7900
+Wire Wire Line
+ 3700 8600 5350 8600
+Connection ~ 5200 4150
+Wire Wire Line
+ 5200 4150 5200 4250
+Wire Wire Line
+ 5200 4250 5250 4250
+Wire Wire Line
+ 6250 5850 6450 5850
+Wire Wire Line
+ 6450 5450 6650 5450
+Wire Wire Line
+ 6650 5250 6450 5250
+Wire Wire Line
+ 6250 5750 6400 5750
+Wire Wire Line
+ 6400 5750 6400 5350
+Wire Wire Line
+ 6400 5350 6650 5350
+Wire Wire Line
+ 6250 5950 6500 5950
+Wire Wire Line
+ 6500 5950 6500 5850
+Wire Wire Line
+ 6500 5850 6650 5850
+Wire Wire Line
+ 6250 6150 6650 6150
+Wire Wire Line
+ 6250 7150 6400 7150
+Wire Wire Line
+ 6400 7150 6400 6750
+Wire Wire Line
+ 6400 6750 6650 6750
+Wire Wire Line
+ 6450 6850 6650 6850
+Wire Wire Line
+ 6650 6650 6450 6650
+Wire Wire Line
+ 6250 7450 6650 7450
+Wire Wire Line
+ 6250 7650 6500 7650
+Wire Wire Line
+ 6500 7650 6500 7950
+Wire Wire Line
+ 6250 7850 6400 7850
+Wire Wire Line
+ 6400 7850 6400 8250
+Connection ~ 6550 1200
+Wire Wire Line
+ 6550 1200 6900 1200
+Wire Wire Line
+ 3850 1000 3850 1250
+Wire Wire Line
+ 5900 1050 5900 1250
+Connection ~ 2750 1150
+Wire Wire Line
+ 2750 1300 2750 1150
+Wire Wire Line
+ 6550 1050 6550 7850
+Connection ~ 6400 8050
+Wire Wire Line
+ 6400 8250 6650 8250
+Wire Wire Line
+ 6650 8150 6450 8150
+Connection ~ 6600 6150
+Wire Wire Line
+ 6650 5950 6600 5950
+Wire Wire Line
+ 6600 5950 6600 6150
+Connection ~ 6400 4450
+Wire Wire Line
+ 6650 4450 6400 4450
+Wire Wire Line
+ 6650 4550 6450 4550
+Wire Wire Line
+ 6450 4550 6450 4050
+Wire Wire Line
+ 6250 3850 6450 3850
+Wire Wire Line
+ 6450 3850 6450 3900
+Wire Wire Line
+ 6450 3900 6600 3900
+Wire Wire Line
+ 6650 3950 6600 3950
+Connection ~ 6400 3250
+Wire Wire Line
+ 6650 3050 6400 3050
+Wire Wire Line
+ 6400 3050 6400 3550
+Wire Wire Line
+ 6650 3150 6300 3150
+Wire Wire Line
+ 6300 3150 6300 2650
+Connection ~ 6600 2550
+Wire Wire Line
+ 6650 2350 6600 2350
+Wire Wire Line
+ 6600 2350 6600 2550
+Wire Wire Line
+ 6650 2450 6500 2450
+Wire Wire Line
+ 6500 2450 6500 2350
+Wire Wire Line
+ 6500 2350 6250 2350
+Connection ~ 6500 1850
+Wire Wire Line
+ 6650 1650 6500 1650
+Wire Wire Line
+ 6500 1650 6500 2150
+Wire Wire Line
+ 6650 1750 6450 1750
+Wire Wire Line
+ 6450 1750 6450 2050
+Wire Wire Line
+ 3050 10200 7000 10200
+Connection ~ 5150 1500
+Wire Wire Line
+ 5300 1500 5150 1500
+Connection ~ 6550 2150
+Wire Wire Line
+ 6550 2150 6650 2150
+Connection ~ 1200 10200
+Wire Wire Line
+ 1200 10200 1200 10450
+Wire Wire Line
+ 5250 4050 4900 4050
+Wire Wire Line
+ 5250 3850 4900 3850
+Wire Wire Line
+ 5250 3650 4900 3650
+Wire Wire Line
+ 5250 2650 4900 2650
+Wire Wire Line
+ 5250 2450 4900 2450
+Wire Wire Line
+ 5250 2250 4900 2250
+Wire Wire Line
+ 5250 2050 4900 2050
+Wire Wire Line
+ 3700 4950 3950 4950
+Wire Wire Line
+ 3700 5050 3950 5050
+Wire Wire Line
+ 3700 5150 3950 5150
+Wire Wire Line
+ 3700 5250 3950 5250
+Wire Wire Line
+ 3700 5350 3950 5350
+Wire Wire Line
+ 3700 5450 3950 5450
+Wire Wire Line
+ 1800 4950 1550 4950
+Wire Wire Line
+ 1800 5050 1550 5050
+Wire Wire Line
+ 1800 5150 1550 5150
+Wire Wire Line
+ 1800 5250 1550 5250
+Wire Wire Line
+ 1800 5350 1550 5350
+Wire Wire Line
+ 1800 5450 1550 5450
+Wire Wire Line
+ 1800 5550 1550 5550
+Wire Wire Line
+ 1800 5650 1550 5650
+Wire Wire Line
+ 3700 4050 3950 4050
+Wire Wire Line
+ 3700 4150 3950 4150
+Wire Wire Line
+ 3700 4250 3950 4250
+Wire Wire Line
+ 3700 4350 3950 4350
+Wire Wire Line
+ 3700 4450 3950 4450
+Wire Wire Line
+ 3700 4550 3950 4550
+Wire Wire Line
+ 3700 4650 3950 4650
+Wire Wire Line
+ 3700 4750 3950 4750
+Wire Wire Line
+ 1800 4050 1550 4050
+Wire Wire Line
+ 1800 4150 1550 4150
+Wire Wire Line
+ 1800 4250 1550 4250
+Wire Wire Line
+ 1800 4350 1550 4350
+Wire Wire Line
+ 1800 4450 1550 4450
+Wire Wire Line
+ 1800 4550 1550 4550
+Wire Wire Line
+ 1800 4650 1550 4650
+Wire Wire Line
+ 1800 4750 1550 4750
+Wire Wire Line
+ 4300 2850 2150 2850
+Wire Wire Line
+ 3950 1850 3750 1850
+Wire Wire Line
+ 1000 3550 1000 3750
+Wire Wire Line
+ 1450 10200 1450 10350
+Connection ~ 1450 10200
+Wire Wire Line
+ 1800 10750 1800 10850
+Wire Wire Line
+ 3200 10750 3200 10850
+Connection ~ 2200 10200
+Wire Wire Line
+ 1800 10200 1800 10350
+Connection ~ 3200 10200
+Wire Wire Line
+ 3200 10200 3200 10350
+Wire Wire Line
+ 3350 1850 3250 1850
+Connection ~ 2000 1550
+Wire Wire Line
+ 1900 1300 2150 1300
+Wire Wire Line
+ 2150 1300 2150 750
+Wire Wire Line
+ 3850 1850 3850 1750
+Connection ~ 3850 1150
+Wire Wire Line
+ 6100 9650 6100 9800
+Wire Wire Line
+ 6400 9250 6400 8500
+Wire Wire Line
+ 5450 8900 5250 8900
+Wire Wire Line
+ 5250 8900 5250 8700
+Connection ~ 6100 8900
+Connection ~ 6100 8700
+Connection ~ 6400 8500
+Wire Wire Line
+ 6850 8850 6850 8700
+Wire Wire Line
+ 6850 8700 5950 8700
+Wire Wire Line
+ 7000 8850 7000 8500
+Wire Wire Line
+ 7000 8500 5950 8500
+Connection ~ 6750 9700
+Wire Wire Line
+ 6850 9700 6650 9700
+Wire Wire Line
+ 3250 2300 3250 2750
+Wire Wire Line
+ 2750 2100 2950 2100
+Connection ~ 5250 1150
+Wire Wire Line
+ 4750 1150 6650 1150
+Wire Wire Line
+ 6350 1450 6350 7950
+Wire Wire Line
+ 6350 1450 6000 1450
+Wire Wire Line
+ 6000 1450 6000 1050
+Wire Wire Line
+ 5050 1050 5050 1250
+Wire Wire Line
+ 6450 1050 6450 1250
+Connection ~ 6550 1350
+Connection ~ 5150 6350
+Wire Wire Line
+ 5250 7950 5150 7950
+Wire Wire Line
+ 5150 4350 5250 4350
+Wire Wire Line
+ 5150 2750 5250 2750
+Connection ~ 6550 7750
+Wire Wire Line
+ 6550 7850 6650 7850
+Connection ~ 6550 7150
+Wire Wire Line
+ 6550 7050 6650 7050
+Connection ~ 6550 6350
+Wire Wire Line
+ 6550 6450 6650 6450
+Connection ~ 6550 5750
+Wire Wire Line
+ 6550 5650 6650 5650
+Connection ~ 6550 4950
+Wire Wire Line
+ 6550 5050 6650 5050
+Connection ~ 6550 4250
+Wire Wire Line
+ 6550 4150 6650 4150
+Connection ~ 6550 3450
+Wire Wire Line
+ 6550 3550 6650 3550
+Connection ~ 6550 2850
+Wire Wire Line
+ 6550 2750 6650 2750
+Connection ~ 6350 6350
+Wire Wire Line
+ 6350 7950 6250 7950
+Wire Wire Line
+ 6350 4350 6250 4350
+Wire Wire Line
+ 6350 2750 6250 2750
+Wire Wire Line
+ 6450 4050 6250 4050
+Wire Wire Line
+ 6250 3650 6650 3650
+Wire Wire Line
+ 6500 2150 6250 2150
+Wire Wire Line
+ 6650 1550 6400 1550
+Wire Wire Line
+ 6400 1550 6400 1950
+Wire Wire Line
+ 6400 1950 6250 1950
+Wire Wire Line
+ 6450 2050 6250 2050
+Wire Wire Line
+ 6250 2250 6650 2250
+Wire Wire Line
+ 6400 3550 6250 3550
+Wire Wire Line
+ 6250 3950 6500 3950
+Wire Wire Line
+ 6500 3950 6500 4350
+Wire Wire Line
+ 6500 4350 6650 4350
+Wire Wire Line
+ 6250 4150 6400 4150
+Wire Wire Line
+ 6500 7950 6650 7950
+Wire Wire Line
+ 6350 6350 6250 6350
+Connection ~ 6350 4350
+Wire Wire Line
+ 6550 1350 6650 1350
+Wire Wire Line
+ 6550 1450 6650 1450
+Connection ~ 6550 1450
+Wire Wire Line
+ 6550 2850 6650 2850
+Connection ~ 6550 2750
+Wire Wire Line
+ 6550 3450 6650 3450
+Connection ~ 6550 3550
+Wire Wire Line
+ 6550 4250 6650 4250
+Connection ~ 6550 4150
+Wire Wire Line
+ 6550 4950 6650 4950
+Connection ~ 6550 5050
+Wire Wire Line
+ 6550 5750 6650 5750
+Connection ~ 6550 5650
+Wire Wire Line
+ 6550 6350 6650 6350
+Connection ~ 6550 6450
+Wire Wire Line
+ 6550 7150 6650 7150
+Connection ~ 6550 7050
+Wire Wire Line
+ 6550 7750 6650 7750
+Wire Wire Line
+ 5150 6350 5250 6350
+Connection ~ 5150 4350
+Wire Wire Line
+ 5150 7950 5150 1050
+Connection ~ 5150 2750
+Connection ~ 6350 2750
+Wire Wire Line
+ 6650 1150 6650 1050
+Wire Wire Line
+ 5250 1150 5250 1050
+Wire Wire Line
+ 3250 1850 3250 1900
+Wire Wire Line
+ 2850 2150 2850 2100
+Connection ~ 2850 2100
+Wire Wire Line
+ 2850 2650 2850 2750
+Wire Wire Line
+ 6750 8850 6750 8800
+Wire Wire Line
+ 6750 8800 6650 8800
+Wire Wire Line
+ 6650 8800 6650 9700
+Wire Wire Line
+ 6750 9700 6750 9600
+Wire Wire Line
+ 6850 9800 6850 9600
+Connection ~ 6850 9700
+Wire Wire Line
+ 6100 8900 5950 8900
+Wire Wire Line
+ 5350 8600 5350 8700
+Wire Wire Line
+ 5350 8700 5450 8700
+Wire Wire Line
+ 6100 9250 6100 8700
+Wire Wire Line
+ 4600 7150 4600 7300
+Wire Wire Line
+ 6400 9650 6400 9800
+Wire Wire Line
+ 4450 1850 4550 1850
+Wire Wire Line
+ 4550 1850 4550 1450
+Connection ~ 2150 1150
+Wire Wire Line
+ 2150 750 1900 750
+Wire Wire Line
+ 1900 1000 2000 1000
+Wire Wire Line
+ 2000 1000 2000 1650
+Connection ~ 3850 1850
+Wire Wire Line
+ 7000 10200 7000 9600
+Wire Wire Line
+ 2200 10200 2200 10350
+Connection ~ 1800 10200
+Wire Wire Line
+ 2200 10750 2200 10850
+Wire Wire Line
+ 1450 10750 1450 10850
+Wire Wire Line
+ 1000 4250 1000 4400
+Wire Wire Line
+ 2150 2850 2150 2100
+Wire Wire Line
+ 2150 2100 2250 2100
+Wire Wire Line
+ 4900 1950 5250 1950
+Wire Wire Line
+ 5250 2150 4900 2150
+Wire Wire Line
+ 5250 2350 4900 2350
+Wire Wire Line
+ 5250 2550 4900 2550
+Wire Wire Line
+ 5250 3550 4900 3550
+Wire Wire Line
+ 5250 3750 4900 3750
+Wire Wire Line
+ 5250 3950 4900 3950
+Wire Wire Line
+ 5250 4150 4900 4150
+Wire Wire Line
+ 5250 5650 4900 5650
+Wire Wire Line
+ 5250 5750 4900 5750
+Wire Wire Line
+ 5250 5850 4900 5850
+Wire Wire Line
+ 5250 5950 4900 5950
+Wire Wire Line
+ 5250 6050 4900 6050
+Wire Wire Line
+ 5250 6150 4900 6150
+Wire Wire Line
+ 5250 6250 4900 6250
+Wire Wire Line
+ 5250 7150 4900 7150
+Wire Wire Line
+ 5250 7250 4900 7250
+Wire Wire Line
+ 5250 7350 4900 7350
+Wire Wire Line
+ 5250 7450 4900 7450
+Wire Wire Line
+ 5250 7550 4900 7550
+Wire Wire Line
+ 5250 7650 4900 7650
+Wire Wire Line
+ 5250 7750 4900 7750
+Wire Wire Line
+ 5250 7850 4900 7850
+Wire Wire Line
+ 3250 900 3250 1150
+Connection ~ 3250 1150
+Wire Wire Line
+ 6550 2050 6650 2050
+Connection ~ 6550 2050
+Wire Wire Line
+ 1900 1550 2000 1550
+Connection ~ 900 10200
+Wire Wire Line
+ 6500 1850 6650 1850
+Wire Wire Line
+ 6250 2450 6450 2450
+Wire Wire Line
+ 6450 2450 6450 2550
+Wire Wire Line
+ 6450 2550 6650 2550
+Wire Wire Line
+ 6250 2550 6400 2550
+Wire Wire Line
+ 6400 2550 6400 2950
+Wire Wire Line
+ 6400 2950 6650 2950
+Wire Wire Line
+ 6300 2650 6250 2650
+Wire Wire Line
+ 6400 3250 6650 3250
+Wire Wire Line
+ 6250 3750 6500 3750
+Wire Wire Line
+ 6500 3750 6500 3850
+Wire Wire Line
+ 6500 3850 6650 3850
+Wire Wire Line
+ 6600 3950 6600 3750
+Wire Wire Line
+ 6600 3750 6650 3750
+Connection ~ 6600 3900
+Wire Wire Line
+ 6400 4150 6400 4650
+Wire Wire Line
+ 6400 4650 6650 4650
+Wire Wire Line
+ 6650 6550 6400 6550
+Wire Wire Line
+ 6600 7550 6600 7350
+Wire Wire Line
+ 6600 7350 6650 7350
+Wire Wire Line
+ 6400 8050 6650 8050
+Wire Wire Line
+ 4350 1150 2150 1150
+Wire Wire Line
+ 2350 1700 2350 1800
+Wire Wire Line
+ 2750 1700 2750 1800
+Wire Wire Line
+ 2350 1300 2350 1150
+Connection ~ 2350 1150
+Wire Wire Line
+ 6450 8150 6450 7750
+Wire Wire Line
+ 6450 7750 6250 7750
+Wire Wire Line
+ 6250 7550 6650 7550
+Connection ~ 6600 7550
+Wire Wire Line
+ 6650 7250 6500 7250
+Wire Wire Line
+ 6500 7250 6500 7350
+Wire Wire Line
+ 6500 7350 6250 7350
+Wire Wire Line
+ 6450 6650 6450 7250
+Wire Wire Line
+ 6450 7250 6250 7250
+Connection ~ 6450 6850
+Wire Wire Line
+ 6400 6550 6400 6250
+Wire Wire Line
+ 6400 6250 6250 6250
+Wire Wire Line
+ 6250 6050 6650 6050
+Wire Wire Line
+ 6650 5150 6300 5150
+Wire Wire Line
+ 6300 5150 6300 5650
+Wire Wire Line
+ 6300 5650 6250 5650
+Wire Wire Line
+ 6450 5250 6450 5850
+Connection ~ 6450 5450
+Wire Wire Line
+ 5250 5550 5200 5550
+Wire Wire Line
+ 5200 5550 5200 5650
+Connection ~ 5200 5650
+Wire Wire Line
+ 4600 6700 4600 6750
+Wire Wire Line
+ 3700 8500 5450 8500
+Wire Wire Line
+ 5250 8700 3700 8700
+Wire Wire Line
+ 900 7850 900 7900
+Wire Wire Line
+ 700 10200 700 5850
+Wire Wire Line
+ 700 5850 1800 5850
+Connection ~ 700 8800
+Wire Wire Line
+ 1800 6050 1700 6050
+Wire Wire Line
+ 1700 6050 1700 6200
+Wire Wire Line
+ 1800 8300 1700 8300
+Wire Wire Line
+ 1700 8300 1700 9050
+Connection ~ 1700 8900
+Wire Wire Line
+ 3700 5650 3850 5650
+Wire Wire Line
+ 3850 5650 3850 8400
+Wire Wire Line
+ 3850 8400 3700 8400
+Wire Wire Line
+ 3750 6400 1400 6400
+Wire Wire Line
+ 1400 6400 1400 3550
+Wire Wire Line
+ 1250 3850 1250 6600
+Wire Wire Line
+ 1250 3850 1800 3850
+Wire Wire Line
+ 1600 7000 1800 7000
+Wire Wire Line
+ 1250 6600 1600 6600
+Wire Wire Line
+ 1600 6600 1600 7450
+Connection ~ 1600 7000
+Wire Wire Line
+ 950 7200 900 7200
+Connection ~ 900 7200
+Wire Wire Line
+ 3700 6050 4350 6050
+Wire Wire Line
+ 4350 6050 4350 6200
+Wire Wire Line
+ 3700 6900 4150 6900
+Wire Wire Line
+ 4150 6900 4150 7350
+$Comp
+L GND #PWR01
+U 1 1 4B28D5EE
+P 4150 8050
+F 0 "#PWR01" H 4150 8050 30 0001 C CNN
+F 1 "GND" H 4150 7980 30 0001 C CNN
+ 1 4150 8050
+ 1 0 0 -1
+$EndComp
+$Comp
+L JUMPER JP1
+U 1 1 4B28D598
+P 4150 7650
+F 0 "JP1" H 4150 7800 60 0000 C CNN
+F 1 "Bootloader" H 4150 7570 40 0000 C CNN
+ 1 4150 7650
+ 0 1 1 0
+$EndComp
+NoConn ~ 3700 7100
+NoConn ~ 3700 7400
+Kmarq B 6850 9600 "Warnung: Pin power_out verbunden mit Pin BiDi (Netz 75)" F=1
+Kmarq B 900 10350 "Warnung: Pin power_out verbunden mit Pin BiDi (Netz 5)" F=1
+NoConn ~ 1800 8400
+NoConn ~ 3700 9000
+NoConn ~ 3700 8900
+NoConn ~ 3700 8800
+NoConn ~ 3700 8100
+NoConn ~ 3700 8000
+NoConn ~ 3700 7900
+NoConn ~ 3700 7800
+NoConn ~ 3700 7700
+NoConn ~ 3700 7600
+NoConn ~ 3700 7000
+NoConn ~ 1800 7600
+NoConn ~ 1800 3750
+$Comp
+L ATMEGA8-P IC6
+U 1 1 4B28A789
+P 2700 8000
+F 0 "IC6" H 2050 9250 50 0000 L BNN
+F 1 "ATMEGA8-P" H 2950 6800 50 0000 L BNN
+F 2 "DIL28" H 2700 8400 50 0001 C CNN
+ 1 2700 8000
+ 1 0 0 -1
+$EndComp
+$Comp
+L R R10
+U 1 1 4B27466D
+P 4350 6450
+F 0 "R10" V 4430 6450 50 0000 C CNN
+F 1 "1K" V 4350 6450 50 0000 C CNN
+ 1 4350 6450
+ -1 0 0 1
+$EndComp
+NoConn ~ 6250 5550
+Text Label 6900 1200 0 60 ~ 0
+RGB COMMON
+$Comp
+L GND #PWR02
+U 1 1 4B2447DC
+P 2350 1800
+F 0 "#PWR02" H 2350 1800 30 0001 C CNN
+F 1 "GND" H 2350 1730 30 0001 C CNN
+ 1 2350 1800
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR03
+U 1 1 4B2447DB
+P 2750 1800
+F 0 "#PWR03" H 2750 1800 30 0001 C CNN
+F 1 "GND" H 2750 1730 30 0001 C CNN
+ 1 2750 1800
+ 1 0 0 -1
+$EndComp
+$Comp
+L C C7
+U 1 1 4B2447DA
+P 2350 1500
+F 0 "C7" H 2400 1600 50 0000 L CNN
+F 1 "100nf" H 2400 1400 50 0000 L CNN
+ 1 2350 1500
+ 1 0 0 -1
+$EndComp
+$Comp
+L CAPAPOL C8
+U 1 1 4B2447D9
+P 2750 1500
+F 0 "C8" H 2800 1600 50 0000 L CNN
+F 1 "4,7uF" H 2800 1400 50 0000 L CNN
+ 1 2750 1500
+ 1 0 0 -1
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD91
+P 6650 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD91" Ref="P8" Part="1"
+F 0 "P8" H 6730 900 40 0000 L CNN
+F 1 "CONN_1" H 6650 955 30 0001 C CNN
+ 1 6650 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD8F
+P 6550 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD8F" Ref="P7" Part="1"
+F 0 "P7" H 6630 900 40 0000 L CNN
+F 1 "CONN_1" H 6550 955 30 0001 C CNN
+ 1 6550 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD8D
+P 6450 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD8D" Ref="P6" Part="1"
+F 0 "P6" H 6530 900 40 0000 L CNN
+F 1 "CONN_1" H 6450 955 30 0001 C CNN
+ 1 6450 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD8B
+P 6000 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD8B" Ref="P5" Part="1"
+F 0 "P5" H 6080 900 40 0000 L CNN
+F 1 "CONN_1" H 6000 955 30 0001 C CNN
+ 1 6000 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD89
+P 5900 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD89" Ref="P4" Part="1"
+F 0 "P4" H 5980 900 40 0000 L CNN
+F 1 "CONN_1" H 5900 955 30 0001 C CNN
+ 1 5900 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P?
+U 1 1 4B23DD87
+P 5250 900
+AR Path="/4B23DD80" Ref="P?" Part="1"
+AR Path="/4B23DD87" Ref="P3" Part="1"
+F 0 "P3" H 5330 900 40 0000 L CNN
+F 1 "CONN_1" H 5250 955 30 0001 C CNN
+ 1 5250 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P2
+U 1 1 4B23DD80
+P 5150 900
+F 0 "P2" H 5230 900 40 0000 L CNN
+F 1 "CONN_1" H 5150 955 30 0001 C CNN
+ 1 5150 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L CONN_1 P1
+U 1 1 4B23DD52
+P 5050 900
+F 0 "P1" H 5130 900 40 0000 L CNN
+F 1 "CONN_1" H 5050 955 30 0001 C CNN
+ 1 5050 900
+ 0 -1 -1 0
+$EndComp
+$Comp
+L PWR_FLAG #FLG04
+U 1 1 4B235A79
+P 900 10350
+F 0 "#FLG04" H 900 10620 30 0001 C CNN
+F 1 "PWR_FLAG" H 900 10580 30 0000 C CNN
+ 1 900 10350
+ -1 0 0 1
+$EndComp
+NoConn ~ 1900 1400
+NoConn ~ 1900 850
+$Comp
+L PWR_FLAG #FLG05
+U 1 1 4B235940
+P 5300 1500
+F 0 "#FLG05" H 5300 1770 30 0001 C CNN
+F 1 "PWR_FLAG" H 5300 1730 30 0000 C CNN
+ 1 5300 1500
+ 0 1 1 0
+$EndComp
+$Comp
+L +5V #PWR06
+U 1 1 4B2356B1
+P 1200 10450
+F 0 "#PWR06" H 1200 10540 20 0001 C CNN
+F 1 "+5V" H 1200 10540 30 0000 C CNN
+ 1 1200 10450
+ -1 0 0 1
+$EndComp
+$Comp
+L VDD #PWR07
+U 1 1 4B23567B
+P 3250 900
+F 0 "#PWR07" H 3250 1000 30 0001 C CNN
+F 1 "VDD" H 3250 1010 30 0000 C CNN
+ 1 3250 900
+ 1 0 0 -1
+$EndComp
+$Comp
+L PWR_FLAG #FLG08
+U 1 1 4B235626
+P 3850 1000
+F 0 "#FLG08" H 3850 1270 30 0001 C CNN
+F 1 "PWR_FLAG" H 3850 1230 30 0000 C CNN
+ 1 3850 1000
+ 1 0 0 -1
+$EndComp
+Text Label 4900 5750 0 60 ~ 0
+PD7
+Text Label 4900 5850 0 60 ~ 0
+PD6
+Text Label 4900 5950 0 60 ~ 0
+PD5
+Text Label 4900 6050 0 60 ~ 0
+PD4
+Text Label 4900 6150 0 60 ~ 0
+PD3
+Text Label 4900 6250 0 60 ~ 0
+PD2
+Text Label 4900 7150 0 60 ~ 0
+PB7
+Text Label 4900 7250 0 60 ~ 0
+PB6
+Text Label 4900 7350 0 60 ~ 0
+PB5
+Text Label 4900 7450 0 60 ~ 0
+PB4
+Text Label 4900 7550 0 60 ~ 0
+PB3
+Text Label 4900 7650 0 60 ~ 0
+PB2
+Text Label 4900 7750 0 60 ~ 0
+PB1
+Text Label 4900 7850 0 60 ~ 0
+PB0
+Text Label 4900 3550 0 60 ~ 0
+PC7
+Text Label 4900 3650 0 60 ~ 0
+PC6
+Text Label 4900 3750 0 60 ~ 0
+PC5
+Text Label 4900 3850 0 60 ~ 0
+PC4
+Text Label 4900 3950 0 60 ~ 0
+PC3
+Text Label 4900 4050 0 60 ~ 0
+PC2
+Text Label 4900 4150 0 60 ~ 0
+PC1
+Text Label 4900 5650 0 60 ~ 0
+PC0
+Text Label 4900 2650 0 60 ~ 0
+PA7
+Text Label 4900 2550 0 60 ~ 0
+PA6
+Text Label 4900 2450 0 60 ~ 0
+PA5
+Text Label 4900 2350 0 60 ~ 0
+PA4
+Text Label 4900 2250 0 60 ~ 0
+PA3
+Text Label 4900 2150 0 60 ~ 0
+PA2
+Text Label 4900 2050 0 60 ~ 0
+PA1
+Text Label 4900 1950 0 60 ~ 0
+PA0
+Text Label 3950 4950 2 60 ~ 0
+PD7
+Text Label 3950 5050 2 60 ~ 0
+PD6
+Text Label 3950 5150 2 60 ~ 0
+PD5
+Text Label 3950 5250 2 60 ~ 0
+PD4
+Text Label 3950 5350 2 60 ~ 0
+PD3
+Text Label 3950 5450 2 60 ~ 0
+PD2
+Text Label 1750 4950 2 60 ~ 0
+PC7
+Text Label 1750 5050 2 60 ~ 0
+PC6
+Text Label 1750 5150 2 60 ~ 0
+PC5
+Text Label 1750 5250 2 60 ~ 0
+PC4
+Text Label 1750 5350 2 60 ~ 0
+PC3
+Text Label 1750 5450 2 60 ~ 0
+PC2
+Text Label 1750 5550 2 60 ~ 0
+PC1
+Text Label 1750 5650 2 60 ~ 0
+PC0
+Text Label 3950 4050 2 60 ~ 0
+PB7
+Text Label 3950 4150 2 60 ~ 0
+PB6
+Text Label 3950 4250 2 60 ~ 0
+PB5
+Text Label 3950 4350 2 60 ~ 0
+PB4
+Text Label 3950 4450 2 60 ~ 0
+PB3
+Text Label 3950 4550 2 60 ~ 0
+PB2
+Text Label 3950 4650 2 60 ~ 0
+PB1
+Text Label 3950 4750 2 60 ~ 0
+PB0
+Text Label 1750 4050 2 60 ~ 0
+PA7
+Text Label 1750 4150 2 60 ~ 0
+PA6
+Text Label 1750 4250 2 60 ~ 0
+PA5
+Text Label 1750 4350 2 60 ~ 0
+PA4
+Text Label 1750 4450 2 60 ~ 0
+PA3
+Text Label 1750 4550 2 60 ~ 0
+PA2
+Text Label 1750 4650 2 60 ~ 0
+PA1
+Text Label 1750 4750 2 60 ~ 0
+PA0
+$Comp
+L GND #PWR09
+U 1 1 4B234A76
+P 1000 4400
+F 0 "#PWR09" H 1000 4400 30 0001 C CNN
+F 1 "GND" H 1000 4330 30 0001 C CNN
+ 1 1000 4400
+ 1 0 0 -1
+$EndComp
+$Comp
+L R R1
+U 1 1 4B234A65
+P 1000 4000
+F 0 "R1" V 1080 4000 50 0000 C CNN
+F 1 "5K6" V 1000 4000 50 0000 C CNN
+ 1 1000 4000
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR010
+U 1 1 4B2348D2
+P 1700 6200
+F 0 "#PWR010" H 1700 6200 30 0001 C CNN
+F 1 "GND" H 1700 6130 30 0001 C CNN
+ 1 1700 6200
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR011
+U 1 1 4B2348CA
+P 1700 9050
+F 0 "#PWR011" H 1700 9050 30 0001 C CNN
+F 1 "GND" H 1700 8980 30 0001 C CNN
+ 1 1700 9050
+ 1 0 0 -1
+$EndComp
+$Comp
+L C C1
+U 1 1 4B234854
+P 900 7650
+F 0 "C1" H 950 7750 50 0000 L CNN
+F 1 "47p" H 950 7550 50 0000 L CNN
+ 1 900 7650
+ -1 0 0 1
+$EndComp
+$Comp
+L C C2
+U 1 1 4B2347F4
+P 1600 7650
+F 0 "C2" H 1650 7750 50 0000 L CNN
+F 1 "47p" H 1650 7550 50 0000 L CNN
+ 1 1600 7650
+ -1 0 0 1
+$EndComp
+$Comp
+L CRYSTAL X1
+U 1 1 4B2347D4
+P 1250 7200
+F 0 "X1" H 1250 7350 60 0000 C CNN
+F 1 "16Mhz" H 1250 7050 60 0000 C CNN
+ 1 1250 7200
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR012
+U 1 1 4B2347B6
+P 900 7900
+F 0 "#PWR012" H 900 7900 30 0001 C CNN
+F 1 "GND" H 900 7830 30 0001 C CNN
+ 1 900 7900
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR013
+U 1 1 4B2347A0
+P 1600 7900
+F 0 "#PWR013" H 1600 7900 30 0001 C CNN
+F 1 "GND" H 1600 7830 30 0001 C CNN
+ 1 1600 7900
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR014
+U 1 1 4B234738
+P 1450 10850
+F 0 "#PWR014" H 1450 10850 30 0001 C CNN
+F 1 "GND" H 1450 10780 30 0001 C CNN
+ 1 1450 10850
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR015
+U 1 1 4B234734
+P 1800 10850
+F 0 "#PWR015" H 1800 10850 30 0001 C CNN
+F 1 "GND" H 1800 10780 30 0001 C CNN
+ 1 1800 10850
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR016
+U 1 1 4B23472D
+P 2200 10850
+F 0 "#PWR016" H 2200 10850 30 0001 C CNN
+F 1 "GND" H 2200 10780 30 0001 C CNN
+ 1 2200 10850
+ 1 0 0 -1
+$EndComp
+$Comp
+L C C3
+U 1 1 4B2346F2
+P 1450 10550
+F 0 "C3" H 1500 10650 50 0000 L CNN
+F 1 "100nf" H 1500 10450 50 0000 L CNN
+ 1 1450 10550
+ 1 0 0 -1
+$EndComp
+$Comp
+L C C4
+U 1 1 4B2346EC
+P 1800 10550
+F 0 "C4" H 1850 10650 50 0000 L CNN
+F 1 "100nf" H 1850 10450 50 0000 L CNN
+ 1 1800 10550
+ 1 0 0 -1
+$EndComp
+$Comp
+L CAPAPOL C5
+U 1 1 4B2346D7
+P 2200 10550
+F 0 "C5" H 2250 10650 50 0000 L CNN
+F 1 "10uF" H 2250 10450 50 0000 L CNN
+ 1 2200 10550
+ 1 0 0 -1
+$EndComp
+$Comp
+L FILTER FB1
+U 1 1 4B234662
+P 2700 10200
+F 0 "FB1" H 2700 10350 60 0000 C CNN
+F 1 "10uH" H 2700 10100 60 0000 C CNN
+ 1 2700 10200
+ 1 0 0 -1
+$EndComp
+$Comp
+L JACK_2P J1
+U 1 1 4B2344C0
+P 1450 850
+F 0 "J1" H 1100 650 60 0000 C CNN
+F 1 "PWR/IN" H 1300 1100 60 0000 C CNN
+ 1 1450 850
+ 1 0 0 1
+$EndComp
+$Comp
+L JACK_2P J2
+U 1 1 4B23442B
+P 1450 1400
+F 0 "J2" H 1100 1200 60 0000 C CNN
+F 1 "PWR/OUT" H 1300 1650 60 0000 C CNN
+ 1 1450 1400
+ 1 0 0 1
+$EndComp
+$Comp
+L C C6
+U 1 1 4B2343E9
+P 3200 10550
+F 0 "C6" H 3250 10650 50 0000 L CNN
+F 1 "100nF" H 3250 10450 50 0000 L CNN
+ 1 3200 10550
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR017
+U 1 1 4B23431D
+P 4600 7300
+F 0 "#PWR017" H 4600 7300 30 0001 C CNN
+F 1 "GND" H 4600 7230 30 0001 C CNN
+ 1 4600 7300
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR018
+U 1 1 4B2340E9
+P 6100 9800
+F 0 "#PWR018" H 6100 9800 30 0001 C CNN
+F 1 "GND" H 6100 9730 30 0001 C CNN
+ 1 6100 9800
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR019
+U 1 1 4B2340E3
+P 6400 9800
+F 0 "#PWR019" H 6400 9800 30 0001 C CNN
+F 1 "GND" H 6400 9730 30 0001 C CNN
+ 1 6400 9800
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR020
+U 1 1 4B2340D6
+P 6850 9800
+F 0 "#PWR020" H 6850 9800 30 0001 C CNN
+F 1 "GND" H 6850 9730 30 0001 C CNN
+ 1 6850 9800
+ 1 0 0 -1
+$EndComp
+$Comp
+L USB J13
+U 1 1 4B233F56
+P 7200 9200
+F 0 "J13" H 7150 9600 60 0000 C CNN
+F 1 "USB" V 6950 9350 60 0000 C CNN
+ 1 7200 9200
+ 0 1 -1 0
+$EndComp
+$Comp
+L ZENER D4
+U 1 1 4B233F3B
+P 6400 9450
+F 0 "D4" H 6400 9550 50 0000 C CNN
+F 1 "3V6 0,5W" H 6400 9350 40 0000 C CNN
+ 1 6400 9450
+ 0 -1 -1 0
+$EndComp
+$Comp
+L ZENER D3
+U 1 1 4B233F31
+P 6100 9450
+F 0 "D3" H 6100 9550 50 0000 C CNN
+F 1 "3V6 0,5W" H 6100 9350 40 0000 C CNN
+ 1 6100 9450
+ 0 -1 -1 0
+$EndComp
+$Comp
+L R R9
+U 1 1 4B233F05
+P 5700 8900
+F 0 "R9" V 5780 8900 50 0000 C CNN
+F 1 "2K2" V 5700 8900 50 0000 C CNN
+ 1 5700 8900
+ 0 1 1 0
+$EndComp
+$Comp
+L R R7
+U 1 1 4B233EFA
+P 5700 8500
+F 0 "R7" V 5780 8500 50 0000 C CNN
+F 1 "68" V 5700 8500 50 0000 C CNN
+ 1 5700 8500
+ 0 1 1 0
+$EndComp
+$Comp
+L R R8
+U 1 1 4B233EC8
+P 5700 8700
+F 0 "R8" V 5780 8700 50 0000 C CNN
+F 1 "68" V 5700 8700 50 0000 C CNN
+ 1 5700 8700
+ 0 1 1 0
+$EndComp
+$Comp
+L LED D2
+U 1 1 4B233E78
+P 4600 6950
+F 0 "D2" H 4600 7050 50 0000 C CNN
+F 1 "LED/2mA" H 4600 6850 50 0000 C CNN
+ 1 4600 6950
+ 0 1 1 0
+$EndComp
+$Comp
+L R R6
+U 1 1 4B233E03
+P 4600 6450
+F 0 "R6" V 4680 6450 50 0000 C CNN
+F 1 "1K2" V 4600 6450 50 0000 C CNN
+ 1 4600 6450
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR021
+U 1 1 4B233AA8
+P 2000 1650
+F 0 "#PWR021" H 2000 1650 30 0001 C CNN
+F 1 "GND" H 2000 1580 30 0001 C CNN
+ 1 2000 1650
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR022
+U 1 1 4B2339C5
+P 3200 10850
+F 0 "#PWR022" H 3200 10850 30 0001 C CNN
+F 1 "GND" H 3200 10780 30 0001 C CNN
+ 1 3200 10850
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR023
+U 1 1 4B23399E
+P 3250 2750
+F 0 "#PWR023" H 3250 2750 30 0001 C CNN
+F 1 "GND" H 3250 2680 30 0001 C CNN
+ 1 3250 2750
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR024
+U 1 1 4B233996
+P 2850 2750
+F 0 "#PWR024" H 2850 2750 30 0001 C CNN
+F 1 "GND" H 2850 2680 30 0001 C CNN
+ 1 2850 2750
+ 1 0 0 -1
+$EndComp
+$Comp
+L R R2
+U 1 1 4B233954
+P 2500 2100
+F 0 "R2" V 2580 2100 50 0000 C CNN
+F 1 "1K5" V 2500 2100 50 0000 C CNN
+ 1 2500 2100
+ 0 -1 -1 0
+$EndComp
+$Comp
+L R R3
+U 1 1 4B2338D9
+P 2850 2400
+F 0 "R3" V 2930 2400 50 0000 C CNN
+F 1 "47K" V 2850 2400 50 0000 C CNN
+ 1 2850 2400
+ -1 0 0 1
+$EndComp
+$Comp
+L MOSFET_N Q1
+U 1 1 4B2338BA
+P 3150 2100
+F 0 "Q1" H 3450 2100 60 0000 R CNN
+F 1 "BS170" H 3300 2450 60 0000 R CNN
+ 1 3150 2100
+ 1 0 0 -1
+$EndComp
+$Comp
+L ZENER D1
+U 1 1 4B233832
+P 3550 1850
+F 0 "D1" H 3550 1950 50 0000 C CNN
+F 1 "Z<=(VDD - 5,5V) 1,3W" H 3950 1650 40 0000 C CNN
+ 1 3550 1850
+ 1 0 0 -1
+$EndComp
+$Comp
+L R R5
+U 1 1 4B233808
+P 4200 1850
+F 0 "R5" V 4280 1850 50 0000 C CNN
+F 1 "100" V 4200 1850 50 0000 C CNN
+ 1 4200 1850
+ 0 1 1 0
+$EndComp
+$Comp
+L R R4
+U 1 1 4B2337C6
+P 3850 1500
+F 0 "R4" V 3930 1500 50 0000 C CNN
+F 1 "270" V 3850 1500 50 0000 C CNN
+ 1 3850 1500
+ 1 0 0 -1
+$EndComp
+$Comp
+L MOSFET_P Q2
+U 1 1 4B23346A
+P 4550 1250
+F 0 "Q2" V 4450 1400 60 0000 R CNN
+F 1 "IRF9540N" V 4850 1250 60 0000 R CNN
+ 1 4550 1250
+ 0 1 -1 0
+$EndComp
+$Comp
+L GND #PWR025
+U 1 1 4B23336E
+P 5050 1250
+F 0 "#PWR025" H 5050 1250 30 0001 C CNN
+F 1 "GND" H 5050 1180 30 0001 C CNN
+ 1 5050 1250
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR026
+U 1 1 4B233368
+P 5900 1250
+F 0 "#PWR026" H 5900 1250 30 0001 C CNN
+F 1 "GND" H 5900 1180 30 0001 C CNN
+ 1 5900 1250
+ 1 0 0 -1
+$EndComp
+$Comp
+L GND #PWR027
+U 1 1 4B23333F
+P 6450 1250
+F 0 "#PWR027" H 6450 1250 30 0001 C CNN
+F 1 "GND" H 6450 1180 30 0001 C CNN
+ 1 6450 1250
+ 1 0 0 -1
+$EndComp
+NoConn ~ 6250 4250
+$Comp
+L RJ11 J12
+U 1 1 4B232EF3
+P 7100 8050
+F 0 "J12" H 7300 8550 60 0000 C CNN
+F 1 "RJ11" H 6950 8550 60 0000 C CNN
+ 1 7100 8050
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J11
+U 1 1 4B232EF2
+P 7100 7350
+F 0 "J11" H 7300 7850 60 0000 C CNN
+F 1 "RJ11" H 6950 7850 60 0000 C CNN
+ 1 7100 7350
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J10
+U 1 1 4B232EF1
+P 7100 6650
+F 0 "J10" H 7300 7150 60 0000 C CNN
+F 1 "RJ11" H 6950 7150 60 0000 C CNN
+ 1 7100 6650
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J9
+U 1 1 4B232EF0
+P 7100 5950
+F 0 "J9" H 7300 6450 60 0000 C CNN
+F 1 "RJ11" H 6950 6450 60 0000 C CNN
+ 1 7100 5950
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J8
+U 1 1 4B232EEF
+P 7100 5250
+F 0 "J8" H 7300 5750 60 0000 C CNN
+F 1 "RJ11" H 6950 5750 60 0000 C CNN
+ 1 7100 5250
+ 0 1 -1 0
+$EndComp
+$Comp
+L ULN2803A IC?
+U 1 1 4B232EEE
+P 5750 7550
+AR Path="/4769865A" Ref="IC?" Part="1"
+AR Path="/4B232EEE" Ref="IC5" Part="1"
+F 0 "IC5" H 5450 8080 50 0000 L BNN
+F 1 "ULN2803/UDN2981" H 5350 6950 50 0000 L BNN
+F 2 "uln-udn-DIL18" H 5750 7700 50 0001 C CNN
+ 1 5750 7550
+ 1 0 0 -1
+$EndComp
+$Comp
+L ULN2803A IC?
+U 1 1 4B232EED
+P 5750 5950
+AR Path="/4769864D" Ref="IC?" Part="1"
+AR Path="/4B232EED" Ref="IC4" Part="1"
+F 0 "IC4" H 5450 6480 50 0000 L BNN
+F 1 "ULN2803/UDN2981" H 5350 5350 50 0000 L BNN
+F 2 "uln-udn-DIL18" H 5750 6100 50 0001 C CNN
+ 1 5750 5950
+ 1 0 0 -1
+$EndComp
+$Comp
+L RJ11 J7
+U 1 1 4B232860
+P 7100 4450
+F 0 "J7" H 7300 4950 60 0000 C CNN
+F 1 "RJ11" H 6950 4950 60 0000 C CNN
+ 1 7100 4450
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J6
+U 1 1 4B232858
+P 7100 3750
+F 0 "J6" H 7300 4250 60 0000 C CNN
+F 1 "RJ11" H 6950 4250 60 0000 C CNN
+ 1 7100 3750
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J5
+U 1 1 4B232850
+P 7100 3050
+F 0 "J5" H 7300 3550 60 0000 C CNN
+F 1 "RJ11" H 6950 3550 60 0000 C CNN
+ 1 7100 3050
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J4
+U 1 1 4B232846
+P 7100 2350
+F 0 "J4" H 7300 2850 60 0000 C CNN
+F 1 "RJ11" H 6950 2850 60 0000 C CNN
+ 1 7100 2350
+ 0 1 -1 0
+$EndComp
+$Comp
+L RJ11 J3
+U 1 1 4B232825
+P 7100 1650
+F 0 "J3" H 7300 2150 60 0000 C CNN
+F 1 "RJ11" H 6950 2150 60 0000 C CNN
+ 1 7100 1650
+ 0 1 -1 0
+$EndComp
+$Comp
+L ULN2803A IC3
+U 1 1 4769865A
+P 5750 3950
+F 0 "IC3" H 5450 4480 50 0000 L BNN
+F 1 "ULN2803/UDN2981" H 5350 3350 50 0000 L BNN
+F 2 "uln-udn-DIL18" H 5750 4100 50 0001 C CNN
+ 1 5750 3950
+ 1 0 0 -1
+$EndComp
+$Comp
+L ULN2803A IC2
+U 1 1 4769864D
+P 5750 2350
+F 0 "IC2" H 5450 2880 50 0000 L BNN
+F 1 "ULN2803/UDN2981" H 5350 1750 50 0000 L BNN
+F 2 "uln-udn-DIL18" H 5750 2500 50 0001 C CNN
+ 1 5750 2350
+ 1 0 0 -1
+$EndComp
+$Comp
+L MEGA161P IC1
+U 1 1 47698597
+P 2750 4850
+F 0 "IC1" H 2050 6300 50 0000 L BNN
+F 1 "ATmega162" H 2950 3450 50 0000 L BNN
+ 1 2750 4850
+ 1 0 0 -1
+$EndComp
+$EndSCHEMATC
diff --git a/pwm_appl/10ch_pwm_appl.c b/pwm_appl/10ch_pwm_appl.c
new file mode 100644
index 0000000..0aa7ea4
--- /dev/null
+++ b/pwm_appl/10ch_pwm_appl.c
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+// ======================================================================
+// Application firmware for PWM processor.
+//
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+
+#include "../df10ch_common.h"
+#include "../df10ch_usb_proto.h"
+
+
+// ---
+// Fuse-Bit settings for the flash programmer (ATmega 162):
+//
+// M161C=1
+// BODLEVEL2=1
+// BODLEVEL1=0
+// BODLEVEL0=0
+//
+// OCDEN=1
+// JTAGEN=1
+// SPIEN=0
+// WDTON=0
+// EESAVE=1
+// BOOTSZ1=0
+// BOOTSZ0=0
+// BOOTRST=1
+//
+// CKDIV8=1
+// CKOUT=1
+// SUT1=0
+// SUT0=1
+// CKSEL3=1
+// CKSEL2=1
+// CKSEL1=1
+// CKSEL0=1
+//
+// Memory-Lock Bits:
+// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1
+//
+FUSES =
+{
+ .low = (FUSE_SUT1),
+ .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0),
+ .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0),
+};
+LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2);
+SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ;
+
+
+// ---
+// System clock related.
+// System clock is implemented with hardware timer 0
+//
+#define SYS_HWPRESCALE 64 // Hardware Prescaler
+#define SYS_PRESCALER 256 // Timer Prescaler
+
+ // useconds <-> timer ticks conversation
+#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5))
+#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER))))
+
+static uint16_t sys_clock;
+
+
+// ---
+// Keep alive reply related
+//
+#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000)
+
+static uint16_t last_keep_alive;
+
+
+// ---
+// Request parser related variables
+//
+typedef union
+{
+ uint8_t bytes[REQ_HEADER_SIZE];
+ struct
+ {
+ uint8_t request_type;
+ uint8_t request;
+ bytes_word_t value;
+ bytes_word_t index;
+ bytes_word_t length;
+ };
+} pwm_request_t;
+
+static pwm_request_t actual_req;
+static uint8_t header_pos;
+static uint8_t payload_pos;
+static uint8_t payload_count;
+
+
+// ---
+// PWM generation related
+//
+#define DEF_F_PWM 100UL // Default PWM cycle frequency in Hz
+#define PWM_HWPRESCALE 16 // Hardware timer prescale
+#define PWM_PRESCALE 9 // require: (PWM_PRESCALE * PWM_HWPRESCALE) > (size of ISR for timer )
+
+#define DEF_MAX_PWM (F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * DEF_F_PWM) - 1) // Maximum internal resolution for pwm
+
+#define PWM_STEP_PAGE_SIZE (NCHANNELS + 2) // possible maximum steps: NCHANNELS + Pause + End of Table
+
+typedef struct pwm_step_s {
+ uint8_t port_val[NPORTS]; // Values for Port A,B,C,D
+ uint16_t timer_val; // Timer compare value
+ struct pwm_step_s *next_step; // Pointer to next list entry
+ } pwm_step_t;
+
+ // One actual and one shadow page
+static pwm_step_t pwm_step_page1[PWM_STEP_PAGE_SIZE] NOMEMINIT;
+static pwm_step_t pwm_step_page2[PWM_STEP_PAGE_SIZE] NOMEMINIT;
+static pwm_step_t *shadow_pwm_page NOMEMINIT;
+static pwm_step_t *active_pwm_page NOMEMINIT;
+static pwm_step_t * volatile actual_pwm_step NOMEMINIT;
+static uint8_t update_pwm_page NOMEMINIT;
+
+
+// ---
+// RX buffer related variables
+//
+#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1)
+#if RXBUF_SIZE == 256
+#define CHECK_RXBUF_END(pos)
+#else
+#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0
+#endif
+
+static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status;
+static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT;
+
+
+// ---
+// Actual brightness values for each channel
+//
+static uint16_t bright_vals[NCHANNELS];
+
+
+// ---
+// Port channel mapping related variables
+//
+typedef struct { uint8_t code, port_bits; } channel_map_t;
+
+static channel_map_t default_channel_map[NCHANNELS] PROGMEM = {
+ // J3
+ { CM_CODE(PA_IDX, 0), _BV(2) },
+ { CM_CODE(PA_IDX, 1), _BV(1) },
+ { CM_CODE(PA_IDX, 2), _BV(0) },
+
+ // J4
+ { CM_CODE(PA_IDX, 3), _BV(5) },
+ { CM_CODE(PA_IDX, 4), _BV(4) },
+ { CM_CODE(PA_IDX, 5), _BV(3) },
+
+ // J5
+ { CM_CODE(PC_IDX, 6), _BV(7) },
+ { CM_CODE(PA_IDX, 7), _BV(7) },
+ { CM_CODE(PA_IDX, 8), _BV(6) },
+
+ // J6
+ { CM_CODE(PC_IDX, 9), _BV(4) },
+ { CM_CODE(PC_IDX, 10), _BV(5) },
+ { CM_CODE(PC_IDX, 11), _BV(6) },
+
+ // J7
+ { CM_CODE(PC_IDX, 12), _BV(1) },
+ { CM_CODE(PC_IDX, 13), _BV(2) },
+ { CM_CODE(PC_IDX, 14), _BV(3) },
+
+ // J8
+ { CM_CODE(PD_IDX, 15), _BV(6) },
+ { CM_CODE(PD_IDX, 16), _BV(7) },
+ { CM_CODE(PC_IDX, 17), _BV(0) },
+
+ // J9
+ { CM_CODE(PD_IDX, 18), _BV(3) },
+ { CM_CODE(PD_IDX, 19), _BV(4) },
+ { CM_CODE(PD_IDX, 20), _BV(5) },
+
+ // J10
+ { CM_CODE(PB_IDX, 21), _BV(6) },
+ { CM_CODE(PB_IDX, 22), _BV(7) },
+ { CM_CODE(PD_IDX, 23), _BV(2) },
+
+ // J11
+ { CM_CODE(PB_IDX, 24), _BV(3) },
+ { CM_CODE(PB_IDX, 25), _BV(4) },
+ { CM_CODE(PB_IDX, 26), _BV(5) },
+
+ // J12
+ { CM_CODE(PB_IDX, 27), _BV(0) },
+ { CM_CODE(PB_IDX, 28), _BV(1) },
+ { CM_CODE(PB_IDX, 29), _BV(2) }
+
+ };
+
+
+// ---
+// Setup values that will be stored to eeprom.
+//
+
+typedef struct {
+ uint16_t max_pwm;
+ uint8_t common_pwm;
+ channel_map_t channel_map[NCHANNELS];
+ } setup_t;
+
+setup_t setup NOMEMINIT;
+
+#define EE_VALID_MARK 0xA5
+static uint8_t ee_valid EEMEM; // If eeprom content is valid this byte is EE_VALID_MARK
+static setup_t ee_setup EEMEM;
+
+
+// Status LED related
+#define STATUS_LED_PORT PORTE
+#define STATUS_LED_BIT 1
+
+// Common PWM channel related
+#define MAX_COMMON_PWM 255
+#define DEF_COMMON_PWM 255 // Default common pwm value
+
+#define COMMON_PWM_PORT PORTE
+#define COMMON_PWM_BIT 2
+
+
+// Input pin for enable/disable of bootloader
+#define BL_SENSE_PIN PINE
+#define BL_SENSE_BIT 0
+
+
+// ---
+// Definition of port direction and initial values.
+//
+#define PA_DDR 0xFF
+#define PA_INIT 0x00
+
+#define PB_DDR 0xFF
+#define PB_INIT 0x00
+
+#define PC_DDR 0xFF
+#define PC_INIT 0x00
+
+#define PD_DDR (_BV(1) | _BV(2) | _BV(3) | _BV(4) | _BV(5) | _BV(6) | _BV(7))
+#define PD_INIT _BV(1)
+
+#define PE_DDR (_BV(STATUS_LED_BIT) | _BV(COMMON_PWM_BIT))
+#define PE_INIT _BV(BL_SENSE_BIT)
+
+
+// ---
+// Catchup all unused interrupts and wait until watchdog resets device.
+// This ISR is only for unexpected interrupts.
+//
+ISR(BADISR_vect)
+{
+ for (;;);
+}
+
+
+// ---
+// ISR for PWM generation.
+//
+ISR(TIMER3_COMPA_vect)
+{
+ pwm_step_t *p = actual_pwm_step;
+
+ // Optimized OCR3A = p->timer_val
+ OCR3AH = ((uint8_t *)&(p->timer_val))[1];
+ OCR3AL = ((uint8_t *)&(p->timer_val))[0];
+
+ PORTA = p->port_val[PA_IDX];
+ PORTB = p->port_val[PB_IDX];
+ PORTC = p->port_val[PC_IDX];
+ PORTD = p->port_val[PD_IDX];
+
+ // Optimized actual_pwm_step = p->next_step
+ ((uint8_t *)&(actual_pwm_step))[0] = ((uint8_t *)&(p->next_step))[0];
+ ((uint8_t *)&(actual_pwm_step))[1] = ((uint8_t *)&(p->next_step))[1];
+}
+
+
+// ---
+// ISR for receiving data.
+//
+ISR(USART0_RXC_vect)
+{
+ clear_bit(UCSR0B, RXCIE0);
+ sei();
+
+ do
+ {
+ uint8_t i = rxwpos;
+ uint8_t p = i + 1;
+ CHECK_RXBUF_END(p);
+
+ if (bit_is_set(UCSR0A, FE0))
+ set_bit(rx_err_status, COMM_ERR_FRAME);
+ else if (bit_is_set(UCSR0A, DOR0))
+ set_bit(rx_err_status, COMM_ERR_OVERRUN);
+ else if (p == rxrpos)
+ set_bit(rx_err_status, COMM_ERR_OVERFLOW);
+ else
+ {
+ if (bit_is_set(UCSR0B, RXB80))
+ rxspos = i; // save start of request message
+ rxwpos = p; // set data valid
+ }
+ rxbuf[i] = UDR0; // read data
+ }
+ while (bit_is_set(UCSR0A, RXC0));
+
+ cli();
+ set_bit(UCSR0B, RXCIE0);
+}
+
+
+// ---
+// Processing while waiting for a event.
+//
+static void background_processing(void)
+{
+ wdt_reset();
+
+ // count system clock
+ if (bit_is_set(TIFR, TOV0))
+ {
+ ++sys_clock;
+ TIFR = _BV(TOV0);
+ }
+}
+
+
+// ---
+// Put data into transmit buffer.
+//
+static void send_reply_data(uint8_t c)
+{
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ UDR0 = c;
+}
+
+
+// ---
+// Send reply start.
+//
+static void send_reply_start(uint8_t len)
+{
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ uint8_t id = actual_req.request_type & PWMRQ_ID_MASK;
+ if (len)
+ id |= PWMRP_HAS_PAYLOAD;
+
+ set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply
+ UDR0 = id; // Send reply id
+ clear_bit(UCSR0B, TXB80);
+
+ if (len)
+ send_reply_data(len); // Send reply length
+
+ last_keep_alive = sys_clock;
+}
+
+
+// ---
+// Send keep alive reply.
+//
+static void send_keep_alive_reply(void)
+{
+ background_processing();
+ if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE)
+ {
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply
+ UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID
+ clear_bit(UCSR0B, TXB80);
+
+ last_keep_alive = sys_clock;
+ }
+}
+
+
+// ---
+// Set on time 'v' for port bits 'pb' of port 'pi' in shadow pwm page.
+//
+static void set_channel(uint8_t pi, uint8_t pb, uint16_t v)
+{
+ pwm_step_t *p = shadow_pwm_page;
+ pwm_step_t *l, *n;
+
+ while (p->timer_val && v >= p->timer_val)
+ {
+ p->port_val[pi] |= pb;
+ if (p->timer_val == v)
+ return;
+ l = p;
+ p = l->next_step;
+ }
+
+ if (p->timer_val)
+ {
+ n = p;
+ do
+ {
+ l = n;
+ n = l->next_step;
+ }
+ while (n->timer_val);
+
+ l->next_step = n->next_step;
+ n[0] = p[0];
+ p->next_step = n;
+ }
+ else
+ {
+ p->port_val[PA_IDX] = PA_INIT;
+ p->port_val[PB_IDX] = PB_INIT;
+ p->port_val[PC_IDX] = PC_INIT;
+ p->port_val[PD_IDX] = PD_INIT;
+ }
+ p->timer_val = v;
+ p->port_val[pi] |= pb;
+}
+
+
+// ---
+// Init shadow pwm page.
+//
+static uint8_t init_pwm_page(uint8_t do_init)
+{
+ pwm_step_t *p = shadow_pwm_page;
+ pwm_step_t *e = p + PWM_STEP_PAGE_SIZE;
+
+ // Check if shadow page is deactivated
+ cli();
+ pwm_step_t *a = actual_pwm_step;
+ sei();
+ if (a >= p && a < e)
+ return(0); // Shadow page is still active
+
+ if (do_init)
+ {
+ while (p < e)
+ {
+ p->timer_val = 0;
+ a = p + 1;
+ p->next_step = a;
+ p = a;
+ }
+ }
+
+ return(1);
+}
+
+
+// ---
+// Finalize shadow pwm page and activate it.
+//
+static void activate_pwm_page(void)
+{
+ pwm_step_t *p = shadow_pwm_page;
+ pwm_step_t *l;
+ uint16_t t = 0;
+
+ // Calculate time steps
+ while (p->timer_val)
+ {
+ uint16_t ts = p->timer_val - t;
+ t = p->timer_val;
+ p->timer_val = ts * PWM_PRESCALE;
+ l = p;
+ p = l->next_step;
+ }
+
+ // Add pause entry to reach a full cycle
+ t = setup.max_pwm - t;
+ if (t)
+ {
+ p->port_val[PA_IDX] = PA_INIT;
+ p->port_val[PB_IDX] = PB_INIT;
+ p->port_val[PC_IDX] = PC_INIT;
+ p->port_val[PD_IDX] = PD_INIT;
+ p->timer_val = t * PWM_PRESCALE;
+ l = p;
+ }
+
+ // Make list cyclic
+ p = shadow_pwm_page;
+ l->next_step = p;
+
+ // Install Link to shadow page in active page
+ p = active_pwm_page;
+ active_pwm_page = l;
+ l = shadow_pwm_page;
+ cli();
+ p->next_step = l;
+ sei();
+
+ // Swap shadow page
+ if (l == pwm_step_page1)
+ p = pwm_step_page2;
+ else
+ p = pwm_step_page1;
+ shadow_pwm_page = p;
+
+ update_pwm_page = 0;
+}
+
+
+// ---
+// Calculate pwm page.
+//
+static void calc_pwm_page(void)
+{
+ uint8_t c;
+
+ c = NCHANNELS;
+ while (c--)
+ {
+ uint8_t port_bits = setup.channel_map[c].port_bits;
+ if (port_bits)
+ {
+ uint8_t code = setup.channel_map[c].code;
+ uint16_t v = bright_vals[CM_CHANNEL(code)];
+ if (v)
+ {
+ if (v > setup.max_pwm)
+ v = setup.max_pwm;
+ set_channel(CM_PORT(code), port_bits, v);
+ }
+ }
+ }
+}
+
+
+// ---
+// Initialize pwm step table and start pwm timer.
+//
+static void init_pwm_step_tab(void)
+{
+ // Set up pwm step table
+ shadow_pwm_page = pwm_step_page1;
+ active_pwm_page = pwm_step_page2;
+ actual_pwm_step = pwm_step_page2;
+ init_pwm_page(1);
+ calc_pwm_page();
+ activate_pwm_page();
+ actual_pwm_step = active_pwm_page->next_step;
+
+ TCNT3 = 0; // Reset timer counter
+ OCR3A = PWM_PRESCALE; // Initial startup step
+ TCCR3B = _BV(CS32) | _BV(CS31) | _BV(WGM32); // Start timer, Prescaler 16, CTC mode
+}
+
+
+// ---
+// Set default setup values.
+//
+static void init_setup_values(void)
+{
+ setup.max_pwm = DEF_MAX_PWM;
+ setup.common_pwm = DEF_COMMON_PWM;
+
+ memcpy_P(&setup.channel_map, &default_channel_map, sizeof(setup.channel_map));
+}
+
+
+// ---
+// Read setup values from eeprom.
+//
+static void read_setup_values(void)
+{
+ if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK)
+ eeprom_read_block(&setup, &ee_setup, sizeof(setup));
+ else
+ init_setup_values();
+}
+
+
+// ---
+// Store actual setup values into eeprom.
+//
+static void store_setup_values(void)
+{
+ uint8_t i = sizeof(setup);
+ uint8_t *src = (uint8_t *) (&setup);
+ uint8_t *dst = (uint8_t *) (&ee_setup);
+ while (i--)
+ {
+ if (eeprom_read_byte(dst) != *src)
+ {
+ eeprom_write_byte(dst, *src);
+ while (!eeprom_is_ready())
+ send_keep_alive_reply();
+ }
+ ++src;
+ ++dst;
+ }
+ if (eeprom_read_byte(&ee_valid) != EE_VALID_MARK)
+ {
+ eeprom_write_byte(&ee_valid, EE_VALID_MARK);
+ while (!eeprom_is_ready())
+ send_keep_alive_reply();
+ }
+}
+
+
+// ---
+// Set common pwm value.
+//
+static void set_common_pwm(void)
+{
+ uint8_t v = setup.common_pwm;
+
+ if (v == 0 || v == 255)
+ {
+ if (v)
+ set_bit(COMMON_PWM_PORT, COMMON_PWM_BIT);
+ else
+ clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT);
+ clear_bit(TCCR1A, COM1B1); // Normal port output
+ }
+ else
+ {
+ OCR1B = v;
+ clear_bit(COMMON_PWM_PORT, COMMON_PWM_BIT);
+ set_bit(TCCR1A, COM1B1); // pwm port output
+ }
+}
+
+
+// ---
+// Send reply packet from ram memory.
+//
+static void send_reply_mem(uint8_t *data, uint16_t len)
+{
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ uint16_t p = r->index.word << 1;
+ uint16_t n = r->length.word;
+ if (p >= len)
+ n = 0;
+ if (n && (p + n) > len)
+ n = len - p;
+ if (n > MAX_REPLY_PAYLOAD_SIZE)
+ n = 0; // Send nothing!
+
+ send_reply_start(n);
+
+ data += p;
+ while (n)
+ {
+ send_reply_data(*data++);
+ --n;
+ }
+}
+
+
+// ---
+// Process set brightness value.
+//
+static void req_set_brightness(void)
+{
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ uint8_t p = payload_pos;
+ uint16_t c = r->index.word;
+ uint16_t len = r->length.word >> 1;
+ while (len && c < NCHANNELS)
+ {
+ bytes_word_t v;
+ v.bytes[0] = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+ v.bytes[1] = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+
+ if (bright_vals[c] != v.word)
+ {
+ bright_vals[c] = v.word;
+ update_pwm_page = 1;
+ }
+
+ ++c;
+ --len;
+ }
+}
+
+
+// ---
+// Process set channel map request.
+//
+static void req_set_channel_map(void)
+{
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ uint8_t p = payload_pos;
+ uint16_t c = r->index.word;
+ uint16_t len = r->length.word >> 1;
+ while (len && c < NCHANNELS)
+ {
+ uint8_t v = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+
+ if (CM_CHANNEL(v) >= NCHANNELS)
+ v = NCHANNELS - 1;
+
+ if (setup.channel_map[c].code != v)
+ {
+ setup.channel_map[c].code = v;
+ update_pwm_page = 1;
+ }
+
+ v = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+
+ if (setup.channel_map[c].port_bits != v)
+ {
+ setup.channel_map[c].port_bits = v;
+ update_pwm_page = 1;
+ }
+
+ ++c;
+ --len;
+ }
+}
+
+
+// ---
+// Process received request.
+//
+static void process_request(void)
+{
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ uint8_t req = r->request;
+
+ if (req == PWM_REQ_SET_BRIGHTNESS)
+ req_set_brightness();
+ else if (req == PWM_REQ_SET_BRIGHTNESS_SYNCED)
+ {
+ req_set_brightness();
+ if (update_pwm_page)
+ {
+ while (!init_pwm_page(0))
+ background_processing();
+ }
+ }
+ else if (req == PWM_REQ_GET_BRIGHTNESS)
+ {
+ send_reply_mem((uint8_t *)bright_vals, sizeof(bright_vals));
+ return;
+ }
+ else if (req == PWM_REQ_SET_CHANNEL_MAP)
+ req_set_channel_map();
+ else if (req == PWM_REQ_GET_CHANNEL_MAP)
+ {
+ send_reply_mem((uint8_t *)&setup.channel_map, sizeof(setup.channel_map));
+ return;
+ }
+ else if (req == PWM_REQ_STORE_SETUP)
+ store_setup_values();
+ else if (req == PWM_REQ_RESET_SETUP)
+ {
+ init_setup_values();
+ update_pwm_page = 1;
+ if (eeprom_read_byte(&ee_valid) == EE_VALID_MARK)
+ eeprom_write_byte(&ee_valid, (uint8_t)(~EE_VALID_MARK)); // Invalidate eeprom values
+ }
+ else if (req == PWM_REQ_GET_REQUEST_ERR_STATUS)
+ {
+ send_reply_start(1);
+ send_reply_data(rx_err_status);
+ rx_err_status = 0;
+ return;
+ }
+ else if (req == PWM_REQ_SET_COMMON_PWM)
+ {
+ setup.common_pwm = (r->value.word <= MAX_COMMON_PWM) ? r->value.bytes[0]: MAX_COMMON_PWM;
+ set_common_pwm();
+ }
+ else if (req == PWM_REQ_GET_COMMON_PWM)
+ {
+ send_reply_start(2);
+ send_reply_data(setup.common_pwm);
+ send_reply_data(0);
+ return;
+ }
+ else if (req == PWM_REQ_GET_MAX_PWM)
+ {
+ send_reply_start(4);
+ send_reply_data((uint8_t)(setup.max_pwm & 0x00FF));
+ send_reply_data((uint8_t)(setup.max_pwm >> 8));
+ send_reply_data(MAX_COMMON_PWM);
+ send_reply_data(0);
+ return;
+ }
+ else if (req == PWM_REQ_SET_PWM_FREQ)
+ {
+ if (r->value.word >= MIN_PWM_FREQ && r->value.word <= MAX_PWM_FREQ)
+ {
+ setup.max_pwm = F_CPU / (PWM_HWPRESCALE * PWM_PRESCALE * (uint32_t)r->value.word) - 1;
+ update_pwm_page = 1;
+ }
+ }
+ else if (req == PWM_REQ_GET_PWM_FREQ)
+ {
+ uint16_t f = F_CPU / (((uint32_t)setup.max_pwm + 1) * PWM_HWPRESCALE * PWM_PRESCALE);
+ send_reply_start(2);
+ send_reply_data((uint8_t)(f & 0x00FF));
+ send_reply_data((uint8_t)(f >> 8));
+ return;
+ }
+ else if (req == PWM_REQ_GET_VERSION)
+ {
+ send_reply_start(2);
+ send_reply_data(PWM_VERS_APPL);
+ send_reply_data(FIRMWARE_VERSION);
+ return;
+ }
+ else if (req == PWM_REQ_ECHO_TEST)
+ {
+ send_reply_start(8);
+ send_reply_data(r->bytes[0]);
+ send_reply_data(r->bytes[1]);
+ send_reply_data(r->bytes[2]);
+ send_reply_data(r->bytes[3]);
+ send_reply_data(r->bytes[4]);
+ send_reply_data(r->bytes[5]);
+ send_reply_data(r->bytes[6]);
+ send_reply_data(r->bytes[7]);
+ return;
+ }
+
+ send_reply_start(0);
+}
+
+
+// ---
+// Decode data byte of received data.
+//
+static void read_data(void)
+{
+ uint8_t p, c, is_req_start;
+
+
+ // Read data from RX buffer
+ p = rxrpos;
+ is_req_start = (p == rxspos);
+ c = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+ rxrpos = p;
+
+ p = header_pos;
+ if (is_req_start)
+ {
+ if (p)
+ set_bit(rx_err_status, COMM_ERR_TIMEOUT);
+
+ p = 0;
+ }
+ else if (!p)
+ return; // Discard garbage
+
+ if (p < sizeof(pwm_request_t))
+ {
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ r->bytes[p++] = c;
+ header_pos = p;
+
+ if (p < sizeof(pwm_request_t))
+ return;
+
+ // Header complete
+ if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word)
+ {
+ payload_pos = rxrpos;
+ payload_count = r->length.word;
+ return;
+ }
+ }
+ else if (--payload_count)
+ return; // Payload not complete
+
+ last_keep_alive = sys_clock;
+ process_request();
+ header_pos = 0;
+}
+
+
+// ---
+// Device initialization and main program loop.
+//
+void main(void) NORETURN;
+void main(void)
+{
+ wdt_enable(WDTO_30MS); // Set watchdog timeout
+
+ // Port init, enable pull-up resistors for unused ports
+ PORTA = PA_INIT;
+ PORTB = PB_INIT;
+ PORTC = PC_INIT;
+ PORTD = PD_INIT;
+ PORTE = PE_INIT;
+ DDRA = PA_DDR;
+ DDRB = PB_DDR;
+ DDRC = PC_DDR;
+ DDRD = PD_DDR;
+ DDRE = PE_DDR;
+
+ // USART init
+ // 9 data bits, 1 stop bit, no parity, asynchron mode
+ // Enable TX, RX and RX Interrupts
+#include <util/setbaud.h>
+ UBRR0H = UBRRH_VALUE;
+ UBRR0L = UBRRL_VALUE;
+#if USE_2X
+ UCSR0A = _BV(U2X);
+#endif
+ UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00);
+ UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02);
+
+ read_setup_values();
+
+ // Timer 0 is used for system clock
+ // Normal mode, Prescaler 64
+ TCCR0 = _BV(CS01) | _BV(CS00);
+
+ // Timer 1 is used for common PWM generation
+ // Fast 8-Bit PWM mode, Prescaler 1, PWM output at OC1B Pin
+ TCCR1A = _BV(WGM10);
+ TCCR1B = _BV(WGM12) | _BV(CS10);
+ set_common_pwm();
+
+ // Timer 3 is used for PWM generation
+ ETIMSK = _BV(OCIE3A); // Enable timer 3 compare a interrupt
+ init_pwm_step_tab();
+
+ // Main loop
+ for (;;)
+ {
+ background_processing();
+
+ if (rxrpos != rxwpos)
+ read_data();
+
+ if (update_pwm_page && init_pwm_page(1))
+ {
+ calc_pwm_page();
+ activate_pwm_page();
+ }
+
+ if (update_pwm_page || header_pos)
+ clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request
+ else
+ set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request
+ }
+}
diff --git a/pwm_appl/Makefile b/pwm_appl/Makefile
new file mode 100644
index 0000000..d9faba8
--- /dev/null
+++ b/pwm_appl/Makefile
@@ -0,0 +1,106 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+#
+###############################################################################
+# Makefile for the application firmware of PWM processor
+###############################################################################
+
+## General Flags
+PROJECT = 10ch_pwm_appl
+MCU = atmega162
+TARGET = 10ch_pwm_appl.elf
+CC = avr-gcc
+AVRDUDE ?= avrdude -c stk500v2 -P avrdoper
+F_CPU ?= 16000000UL
+FIRMWARE_VERSION ?= 1
+
+## Options common to compile, link and assembly rules
+COMMON = -mmcu=$(MCU)
+
+## Compile options common for all C compilation units.
+CFLAGS = $(COMMON)
+CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION)
+
+## Assembly specific flags
+ASMFLAGS = $(COMMON)
+ASMFLAGS += $(CFLAGS)
+ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
+
+## Linker flags
+LDFLAGS = $(COMMON)
+LDFLAGS += -Wl,-Map=10ch_pwm_appl.map
+LDFLAGS += -Wl,-section-start=.eeprom=0x810001
+
+
+## Intel Hex file production flags
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
+
+HEX_EEPROM_FLAGS = -j .eeprom
+HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
+HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0x01 --no-change-warnings
+
+## Include Directories
+INCLUDES = -I. -I..
+
+## Objects that must be built in order to link
+OBJECTS = 10ch_pwm_appl.o
+
+## Objects explicitly added by the user
+LINKONLYOBJECTS =
+
+## Build
+all: $(TARGET) 10ch_pwm_appl.dff 10ch_pwm_appl.lss size
+
+10ch_pwm_appl.dff: 10ch_pwm_appl.hex
+ echo "@DF10CH-PWM" $(FIRMWARE_VERSION) > $@
+ cat 10ch_pwm_appl.hex >> $@
+
+prog: flash
+ $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc9:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m
+
+flash: 10ch_pwm_appl.hex
+ $(AVRDUDE) -p $(MCU) -U flash:w:10ch_pwm_appl.hex:i
+
+## Compile
+10ch_pwm_appl.o: 10ch_pwm_appl.c ../df10ch_usb_proto.h ../df10ch_common.h
+ $(CC) $(INCLUDES) $(CFLAGS) -c $<
+
+##Link
+$(TARGET): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
+
+%.hex: $(TARGET)
+ avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
+
+%.eep: $(TARGET)
+ -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
+
+%.lss: $(TARGET)
+ avr-objdump -h -S $< > $@
+
+size: ${TARGET}
+ @echo
+ @avr-size -C --mcu=${MCU} ${TARGET}
+
+## Clean target
+.PHONY: clean
+clean:
+ -rm -rf $(OBJECTS) 10ch_pwm_appl.elf 10ch_pwm_appl.dff 10ch_pwm_appl.hex 10ch_pwm_appl.eep 10ch_pwm_appl.lss 10ch_pwm_appl.map
diff --git a/pwm_boot/10ch_pwm_boot.c b/pwm_boot/10ch_pwm_boot.c
new file mode 100644
index 0000000..986b9da
--- /dev/null
+++ b/pwm_boot/10ch_pwm_boot.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+// ======================================================================
+// Bootloader firmware for PWM processor.
+//
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+#include <avr/boot.h>
+
+#include "../df10ch_common.h"
+#include "../df10ch_usb_proto.h"
+
+
+// ---
+// Fuse-Bit settings for the flash programmer (Atmega 162):
+//
+// M161C=1
+// BODLEVEL2=1
+// BODLEVEL1=0
+// BODLEVEL0=0
+//
+// OCDEN=1
+// JTAGEN=1
+// SPIEN=0
+// WDTON=0
+// EESAVE=1
+// BOOTSZ1=0
+// BOOTSZ0=0
+// BOOTRST=0
+//
+// CKDIV8=1
+// CKOUT=1
+// SUT1=0
+// SUT0=1
+// CKSEL3=1
+// CKSEL2=1
+// CKSEL1=1
+// CKSEL0=1
+//
+// Memory-Lock Bits:
+// BLB12=1, BLB11=0, BLB02=1, BLB01=1, LB2=1, LB1=1
+//
+FUSES =
+{
+ .low = (FUSE_SUT1),
+ .high = (FUSE_SPIEN & FUSE_WDTON & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST),
+ .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0),
+};
+LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2);
+SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ;
+
+
+// ---
+// System clock related.
+// System clock is implemented with hardware timer 0
+//
+#define SYS_HWPRESCALE 64 // Hardware Prescaler
+#define SYS_PRESCALER 256 // Timer Prescaler
+
+ // useconds <-> timer ticks conversation
+#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE * (double)SYS_PRESCALER) + 0.5))
+#define TICKS2US(t) (((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE * SYS_PRESCALER))))
+
+static uint16_t sys_clock;
+
+
+// ---
+// Keep alive reply related
+//
+#define MIN_KEEP_ALIVE_PAUSE US2TICKS(15000)
+
+static uint16_t last_keep_alive;
+
+
+// ---
+// Request parser related variables
+//
+typedef union
+{
+ uint8_t bytes[REQ_HEADER_SIZE];
+ struct
+ {
+ uint8_t request_type;
+ uint8_t request;
+ bytes_word_t value;
+ bytes_word_t index;
+ bytes_word_t length;
+ };
+} pwm_request_t;
+
+static pwm_request_t actual_req;
+static uint8_t header_pos;
+static uint8_t payload_pos;
+static uint8_t payload_count;
+
+
+// ---
+// RX buffer related variables
+//
+#define RXBUF_SIZE (REQ_HEADER_SIZE + MAX_REQ_PAYLOAD_SIZE + 1)
+#if RXBUF_SIZE == 256
+#define CHECK_RXBUF_END(pos)
+#else
+#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0
+#endif
+
+static uint8_t volatile rxrpos, rxwpos, rxspos, rx_err_status;
+static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT;
+
+
+// Status LED related
+#define STATUS_LED_PORT PORTE
+#define STATUS_LED_BIT 1
+
+// Input pin for enable/disable of bootloader
+#define BL_SENSE_PIN PINE
+#define BL_SENSE_BIT 0
+
+#define APPL_START_VECT 0x0000
+
+// ---
+// Definition of port direction and initial values.
+//
+#define PE_DDR _BV(STATUS_LED_BIT)
+#define PE_INIT _BV(BL_SENSE_BIT)
+
+
+// ---
+// ISR handler for IRQ's that do not have a dedicated handler.
+//
+EMPTY_INTERRUPT(BADISR_vect)
+
+
+// ---
+// ISR for receiving data.
+//
+ISR(USART0_RXC_vect)
+{
+ do
+ {
+ uint8_t i = rxwpos;
+ uint8_t p = i + 1;
+ CHECK_RXBUF_END(p);
+
+ if (bit_is_set(UCSR0A, FE0))
+ set_bit(rx_err_status, COMM_ERR_FRAME);
+ else if (bit_is_set(UCSR0A, DOR0))
+ set_bit(rx_err_status, COMM_ERR_OVERRUN);
+ else if (p == rxrpos)
+ set_bit(rx_err_status, COMM_ERR_OVERFLOW);
+ else
+ {
+ if (bit_is_set(UCSR0B, RXB80))
+ rxspos = i; // save start of request message
+ rxwpos = p; // set data valid
+ }
+ rxbuf[i] = UDR0; // read data
+ }
+ while (bit_is_set(UCSR0A, RXC0));
+}
+
+
+// ---
+// Processing while waiting for a event.
+//
+static void background_processing(void)
+{
+ wdt_reset();
+
+ // count system clock
+ if (bit_is_set(TIFR, TOV0))
+ {
+ ++sys_clock;
+ TIFR = _BV(TOV0);
+ }
+}
+
+
+// ---
+// Put data into transmit buffer.
+//
+static void send_reply_data(uint8_t c)
+{
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ UDR0 = c;
+}
+
+
+// ---
+// Send reply start.
+//
+static void send_reply_start(uint8_t len)
+{
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ uint8_t id = actual_req.request_type & PWMRQ_ID_MASK;
+ if (len)
+ id |= PWMRP_HAS_PAYLOAD;
+
+ set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply
+ UDR0 = id; // Send reply id
+ clear_bit(UCSR0B, TXB80);
+
+ if (len)
+ send_reply_data(len); // Send reply length
+
+ last_keep_alive = sys_clock;
+}
+
+
+// ---
+// Send keep alive reply.
+//
+static void send_keep_alive_reply(void)
+{
+ background_processing();
+ if ((sys_clock - last_keep_alive) > MIN_KEEP_ALIVE_PAUSE)
+ {
+ // Wait until transmit buffer free
+ while (bit_is_clear(UCSR0A, UDRE0))
+ background_processing();
+
+ set_bit(UCSR0B, TXB80); // Set 9th bit for start of reply
+ UDR0 = PWMRP_KEEP_ALIVE; // Send keep alive ID
+ clear_bit(UCSR0B, TXB80);
+
+ last_keep_alive = sys_clock;
+ }
+}
+
+
+// ---
+// Send reply packet from flash memory.
+//
+static void send_reply_read_flash(PGM_P p, uint16_t n)
+{
+ if (n > MAX_REPLY_PAYLOAD_SIZE)
+ n = 0; // Send nothing!
+
+ send_reply_start((uint8_t)n);
+
+ while (n)
+ {
+ send_reply_data(pgm_read_byte(p));
+ ++p;
+ --n;
+ }
+}
+
+
+// ---
+// Process write flash page request.
+//
+static void req_write_flash_page(uint16_t page_address, uint16_t len)
+{
+ while (!eeprom_is_ready())
+ send_keep_alive_reply();
+
+ cli();
+ boot_page_erase(page_address);
+ sei();
+
+ while (boot_spm_busy())
+ send_keep_alive_reply();
+
+ uint8_t page_offset = 0;
+ uint8_t p = payload_pos;
+ while (len > 1 && page_offset < SPM_PAGESIZE)
+ {
+ bytes_word_t v;
+ v.bytes[0] = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+ v.bytes[1] = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+
+ cli();
+ boot_page_fill(page_address + page_offset, v.word);
+ sei();
+
+ page_offset += 2;
+ len -= 2;
+ }
+
+ cli();
+ boot_page_write(page_address);
+ sei();
+
+ while (boot_spm_busy())
+ send_keep_alive_reply();
+
+ if (boot_rww_busy())
+ boot_rww_enable();
+}
+
+
+// ---
+// Process received request.
+//
+static void process_request(void)
+{
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ uint8_t req = r->request;
+
+ if (req == BL_PWM_REQ_WRITE_PAGE)
+ req_write_flash_page(r->index.word, r->length.word);
+ else if (req == BL_PWM_REQ_READ_FLASH)
+ {
+ send_reply_read_flash((PGM_P) r->index.word, r->length.word);
+ return;
+ }
+ else if (req == BL_PWM_REQ_GET_PAGE_SIZE)
+ {
+ send_reply_start(2);
+ send_reply_data(SPM_PAGESIZE & 0xFF);
+ send_reply_data(SPM_PAGESIZE >> 8);
+ return;
+ }
+ else if (req == BL_PWM_REQ_GET_REQUEST_ERR_STATUS)
+ {
+ send_reply_start(1);
+ send_reply_data(rx_err_status);
+ rx_err_status = 0;
+ return;
+ }
+ else if (req == PWM_REQ_GET_VERSION)
+ {
+ send_reply_start(2);
+ send_reply_data(PWM_VERS_BOOT);
+ send_reply_data(FIRMWARE_VERSION);
+ return;
+ }
+
+ send_reply_start(0);
+}
+
+
+// ---
+// Decode data byte of received data.
+//
+static void read_data(void)
+{
+ uint8_t p, c, is_req_start;
+
+ // Read data from RX buffer
+ p = rxrpos;
+ is_req_start = (p == rxspos);
+ c = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+ rxrpos = p;
+
+ p = header_pos;
+ if (is_req_start)
+ {
+ if (p)
+ set_bit(rx_err_status, COMM_ERR_TIMEOUT);
+
+ p = 0;
+ }
+ else if (!p)
+ return; // Discard garbage
+
+ if (p < sizeof(pwm_request_t))
+ {
+ pwm_request_t *r = &actual_req;
+ FIX_POINTER(r);
+
+ r->bytes[p++] = c;
+ header_pos = p;
+
+ if (p < sizeof(pwm_request_t))
+ return;
+
+ // Header complete
+ if (!(r->request_type & PWMRQ_DEVICE_TO_HOST) && r->length.word)
+ {
+ payload_pos = rxrpos;
+ payload_count = r->length.word;
+ return;
+ }
+ }
+ else if (--payload_count)
+ return; // Payload not complete
+
+ last_keep_alive = sys_clock;
+ process_request();
+ header_pos = 0;
+}
+
+
+// ---
+// Device initialization and main program loop.
+//
+void main(void) NORETURN;
+void main(void)
+{
+ wdt_enable(WDTO_30MS); // Set watchdog timeout
+
+ // Port init, enable pull-up resistors for unused ports
+ PORTE = PE_INIT;
+ DDRE = PE_DDR;
+
+ if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed?
+ bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT))
+ { // boot loader disabled -> start application
+ void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address!
+ jump_to_app();
+ }
+
+ GICR = _BV(IVCE); // enable change of interrupt vectors
+ GICR = _BV(IVSEL); // move interrupts to boot flash section
+
+ // USART init
+ // 9 data bits, 1 stop bit, no parity, asynchron mode
+ // Enable TX, RX and RX Interrupts
+#include <util/setbaud.h>
+ UBRR0H = UBRRH_VALUE;
+ UBRR0L = UBRRL_VALUE;
+#if USE_2X
+ UCSR0A = _BV(U2X);
+#endif
+ UCSR0C = _BV(URSEL0) | _BV(UCSZ01) | _BV(UCSZ00);
+ UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0) | _BV(UCSZ02);
+
+ // Timer 0 is used for system clock
+ // Normal mode, Prescaler 64
+ TCCR0 = _BV(CS01) | _BV(CS00);
+
+ sei();
+
+ // Main loop
+ for (;;)
+ {
+ background_processing();
+
+ if (rxrpos != rxwpos)
+ read_data();
+
+ if (header_pos)
+ clear_bit(STATUS_LED_PORT, STATUS_LED_BIT); // We are processing a request
+ else
+ set_bit(STATUS_LED_PORT, STATUS_LED_BIT); // No request
+ }
+}
diff --git a/pwm_boot/Makefile b/pwm_boot/Makefile
new file mode 100644
index 0000000..1a98f84
--- /dev/null
+++ b/pwm_boot/Makefile
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+#
+###############################################################################
+# Makefile for the bootloader firmware of PWM processor
+###############################################################################
+
+## General Flags
+PROJECT = 10ch_pwm_boot
+MCU = atmega162
+TARGET = 10ch_pwm_boot.elf
+CC = avr-gcc
+AVRDUDE ?= avrdude -c stk500v2 -P avrdoper
+F_CPU ?= 16000000UL
+FIRMWARE_VERSION ?= 1
+
+## Options common to compile, link and assembly rules
+COMMON = -mmcu=$(MCU)
+
+## Compile options common for all C compilation units.
+CFLAGS = $(COMMON)
+CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION)
+
+## Assembly specific flags
+ASMFLAGS = $(COMMON)
+ASMFLAGS += $(CFLAGS)
+ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
+
+## Linker flags
+LDFLAGS = $(COMMON)
+LDFLAGS += -Wl,-Map=10ch_pwm_boot.map
+LDFLAGS += -Wl,-section-start=.text=0x3800
+
+
+## Intel Hex file production flags
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
+
+HEX_EEPROM_FLAGS = -j .eeprom
+HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
+
+## Include Directories
+INCLUDES = -I. -I..
+
+## Objects that must be built in order to link
+OBJECTS = 10ch_pwm_boot.o
+
+## Objects explicitly added by the user
+LINKONLYOBJECTS =
+
+## Build
+all: $(TARGET) 10ch_pwm_boot.hex 10ch_pwm_boot.lss size
+
+prog: flash
+ $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0xc0:m -Uhfuse:w:0xc8:m -Uefuse:w:0xf9:m -Ulock:w:0xef:m
+
+flash: 10ch_pwm_boot.hex
+ $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_pwm_boot.hex:i
+
+
+## Compile
+10ch_pwm_boot.o: 10ch_pwm_boot.c ../df10ch_usb_proto.h ../df10ch_common.h
+ $(CC) $(INCLUDES) $(CFLAGS) -c $<
+
+##Link
+$(TARGET): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
+
+%.hex: $(TARGET)
+ avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
+
+%.eep: $(TARGET)
+ -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
+
+%.lss: $(TARGET)
+ avr-objdump -h -S $< > $@
+
+size: ${TARGET}
+ @echo
+ @avr-size -C --mcu=${MCU} ${TARGET}
+
+## Clean target
+.PHONY: clean
+clean:
+ -rm -rf $(OBJECTS) 10ch_pwm_boot.elf 10ch_pwm_boot.hex 10ch_pwm_boot.eep 10ch_pwm_boot.lss 10ch_pwm_boot.map
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..c81ca90
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+# Df10CH setup program installation script
+#
+
+from distutils.core import setup
+setup(name='df10ch_setup',
+ version='0.1',
+ description='DF10CH Setup program',
+ author='Andreas Auras',
+ author_email='yak54@gmx.net',
+ url='http://www.vdr-wiki.de/wiki/index.php/VDR_Wiki:DF10CH_Atmolight_Kontroller',
+ requires=[ 'usb', 'TKinter' ],
+ scripts=[ 'df10ch_setup.py' ],
+ packages = [ 'df10ch_setup_pkg' ],
+ )
+
diff --git a/usb_appl/10ch_usb_appl.c b/usb_appl/10ch_usb_appl.c
new file mode 100644
index 0000000..f5a1ce4
--- /dev/null
+++ b/usb_appl/10ch_usb_appl.c
@@ -0,0 +1,839 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+// ======================================================================
+// Application firmware for USB processor.
+//
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/eeprom.h>
+#include <avr/sleep.h>
+
+#include "../df10ch_common.h"
+#include "../df10ch_usb_proto.h"
+#include "usbconfig.h"
+
+
+// ---
+// Fuse-Bit settings for the flash programmer (ATmega8):
+// RSTDISBL=1
+// WDTON=1
+// SPIEN=0
+// CKOPT=0
+// EESAVE=1
+// BOOTSZ1=0
+// BOOTSZ0=0
+// BOOTRST=1
+//
+// BODLEVEL=0
+// BODEN=0
+// SUT1=0
+// SUT0=1
+// CKSEL3=1
+// CKSEL2=1
+// CKSEL1=1
+// CKSEL0=1
+//
+// Memory-Lock Bits:
+// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1
+//
+FUSES =
+{
+ .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1),
+ .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0)
+};
+LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2);
+
+SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ;
+
+
+#define EE_MEM_SIZE (E2END + 1)
+
+
+// ---
+// System clock related.
+// System clock ist implemented with hardware timer 1
+//
+#define SYS_HWPRESCALE 1024 // Hardware Prescaler
+
+ // useconds <-> timer ticks conversation
+#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5))
+#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE))))
+
+
+// ---
+// pwm controller reset related.
+//
+#define RESET_TIME US2TICKS(128UL)
+#define STARTUP_TIME US2TICKS(10000UL)
+
+ // Output pin for PWM controller reset
+#define RESET_PORT PORTB
+#define RESET_BIT 4
+
+ // Output pin for enabling PWM controller bootloader
+#define BOOTLOADER_PORT PORTB
+#define BOOTLOADER_BIT 3
+
+
+// ---
+// bootloader related.
+//
+#define BL_START_VECT 0x1800
+
+// Input/Output pin for bootloader startup
+#define BL_SENSE_DDR DDRB
+#define BL_SENSE_PORT PORTB
+#define BL_SENSE_PIN PINB
+#define BL_SENSE_BIT 0
+
+#define BL_START_DELAY_TIME US2TICKS(30000UL)
+
+static uint8_t bl_start;
+static uint16_t bl_time;
+
+
+// ---
+// USB related.
+//
+#define USB_SLEEP_TIMEOUT US2TICKS(5000UL)
+#define USB_DISCONNECT_TIME US2TICKS(500000UL)
+#define USB_INITIALIZE_TIMEOUT US2TICKS(1750000UL)
+#define USB_STALL_RC 0xFF
+
+volatile uint16_t usb_sof_time; // Time of last USB start of frame IRQ
+static uint8_t usb_is_resetting; // Is true while reset condition on USB bus happen
+static uint8_t usb_is_initialized; // Is true after USB address has been set
+static uint8_t usb_last_data_token; // Token PID of last usb packet received
+static uint8_t usb_last_rc; // Return status of last payload packet
+static uint8_t payload_req; // ID of actual proccessed USB request
+static uint16_t payload_pos; // Position of actual payload read/write
+static uint16_t payload_count; // Number of bytes left of actual payload read/write
+
+
+
+// ---
+// RX buffer related.
+//
+#define RXBUF_SIZE 256
+#if RXBUF_SIZE == 256
+#define CHECK_RXBUF_END(pos)
+#else
+#define CHECK_RXBUF_END(pos) if ((pos) == RXBUF_SIZE) (pos) = 0
+#endif
+
+static volatile uint8_t rxrpos, rxwpos;
+static volatile uint8_t rxspos; // Start position of reply
+static uint8_t rxbuf[RXBUF_SIZE] NOMEMINIT;
+
+
+// ---
+// TX buffer related.
+//
+#define TXBUF_SIZE 256
+#if TXBUF_SIZE == 256
+#define CHECK_TXBUF_END(pos)
+#else
+#define CHECK_TXBUF_END(pos) if ((pos) == TXBUF_SIZE) (pos) = 0
+#endif
+
+static uint8_t txrpos, txwpos;
+static uint8_t txbuf[TXBUF_SIZE] NOMEMINIT;
+
+
+// ---
+// PWM controller communication related.
+//
+#define REPLY_START_TIMEOUT US2TICKS(50000UL)
+#define REPLY_TIMEOUT US2TICKS(10000UL)
+
+static uint8_t actual_req_id;
+static uint8_t reply_start;
+static uint8_t reply_count;
+static volatile uint8_t reply_err_status;
+static uint16_t reply_start_timeout = REPLY_START_TIMEOUT;
+static uint16_t reply_timeout = REPLY_TIMEOUT;
+
+
+// ---
+// Port setup related.
+//
+#define PORTB_INIT (_BV(BL_SENSE_BIT) | _BV(BOOTLOADER_BIT) | _BV(1) | _BV(2) | _BV(5))
+#define DDRB_INIT (_BV(BOOTLOADER_BIT) | _BV(RESET_BIT))
+
+#define PORTC_INIT (0xFF)
+#define DDRC_INIT (0)
+
+#define PORTD_INIT (_BV(1) | _BV(5) | _BV(6) | _BV(7))
+#define DDRD_INIT (_BV(1))
+
+
+#include <usbdrv.c>
+
+
+// ---
+// ISR handler for IRQ's that do not have a dedicated handler.
+//
+ISR(BADISR_vect)
+{
+ for (;;); // wait until watchdog resets device
+}
+
+
+// ---
+// ISR for receiving data.
+//
+ISR(USART_RXC_vect)
+{
+ clear_bit(UCSRB, RXCIE);
+ sei();
+
+ do
+ {
+ uint8_t i = rxwpos;
+ uint8_t p = i + 1;
+ CHECK_RXBUF_END(p);
+
+ if (bit_is_set(UCSRA, DOR))
+ set_bit(reply_err_status, COMM_ERR_OVERRUN);
+ else if (bit_is_set(UCSRA, FE))
+ set_bit(reply_err_status, COMM_ERR_FRAME);
+ else if (p == rxrpos)
+ set_bit(reply_err_status, COMM_ERR_OVERFLOW);
+ else
+ {
+ if (bit_is_set(UCSRB, RXB8))
+ rxspos = i; // save reply start position
+ rxwpos = p; // set data valid
+ }
+ rxbuf[i] = UDR; // read data
+ }
+ while (bit_is_set(UCSRA, RXC));
+
+ cli();
+ set_bit(UCSRB, RXCIE);
+}
+
+
+// ---
+// Read actual system clock counter.
+// Note: Counter is also read inside USB irq handler -> we need save read!
+//
+static uint16_t get_sys_clock(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ uint16_t t = TCNT1;
+ SREG = sreg;
+ nop();
+ return t;
+}
+
+
+// ---
+// Calculate timer ticks from milliseconds.
+//
+static uint16_t ms_to_ticks(uint16_t ms)
+{
+ uint32_t t = F_CPU / SYS_HWPRESCALE;
+ t *= ms;
+ t /= 1000;
+ return (uint16_t) t;
+}
+
+
+// ---
+// Processing while waiting for a event.
+//
+static void background_processing(void)
+{
+ wdt_reset();
+
+ // Write data from transmit buffer to USART
+ while (bit_is_set(UCSRA, UDRE))
+ {
+ uint8_t p = txrpos;
+ if (p == txwpos)
+ break;
+
+ UDR = txbuf[p++];
+ CHECK_TXBUF_END(p);
+ txrpos = p;
+ }
+}
+
+
+// ---
+// Timer based delay.
+//
+static void timer_delay(uint16_t d)
+{
+ uint16_t t = get_sys_clock();
+ while ((get_sys_clock() - t) < d)
+ background_processing();
+}
+
+
+// ---
+// Put data into transmit buffer.
+//
+static void send_data(uint8_t c)
+{
+ uint8_t p = txwpos + 1;
+ CHECK_TXBUF_END(p);
+
+ // Wait until space available
+ while (p == txrpos)
+ background_processing();
+
+ txbuf[txwpos] = c;
+ txwpos = p;
+
+ background_processing();
+}
+
+
+// ---
+// Send command request for PWM controller.
+//
+static void send_request(uint8_t req_type)
+{
+ // Wait until transmit buffers are empty
+ while (txrpos != txwpos || bit_is_clear(UCSRA, UDRE))
+ background_processing();
+
+ rxspos = rxwpos - 1; // Reset start reply position
+
+ ++actual_req_id;
+ actual_req_id &= PWMRQ_ID_MASK;
+
+ set_bit(UCSRB, TXB8); // Set 9th bit for start of request
+ UDR = req_type | actual_req_id; // Send request type and id unbuffered
+ clear_bit(UCSRB, TXB8);
+}
+
+
+// ---
+// Read reply data.
+//
+static uint8_t read_data(void)
+{
+ uint8_t p = rxrpos;
+ uint8_t c = rxbuf[p++];
+ CHECK_RXBUF_END(p);
+ rxrpos = p;
+ return c;
+}
+
+
+// ---
+// Wait for reply data from PWM controller.
+//
+static uint8_t wait_for_reply(void)
+{
+ uint16_t t = get_sys_clock();
+ uint16_t d = reply_timeout;
+
+ while ((get_sys_clock() - t) < d)
+ {
+ background_processing();
+
+ if (rxwpos != rxrpos)
+ {
+ if (reply_start == rxspos) // Check for same reply
+ return 1;
+ set_bit(reply_err_status, COMM_ERR_START);
+ return 0;
+ }
+ }
+
+ set_bit(reply_err_status, COMM_ERR_TIMEOUT);
+ return 0;
+}
+
+
+// ---
+// Wait for start of reply data from PWM controller.
+//
+static uint8_t wait_for_reply_start(void)
+{
+ uint16_t t = get_sys_clock();
+ uint16_t d = reply_start_timeout;
+
+ while ((get_sys_clock() - t) < d)
+ {
+ background_processing();
+
+ uint8_t p = rxrpos;
+ if (rxwpos != p)
+ {
+ if (rxspos == p)
+ { // reply start detected
+ uint8_t id = read_data();
+ if (id == PWMRP_KEEP_ALIVE)
+ { // keep alive reply
+ t = get_sys_clock();
+ continue;
+ }
+ if ((id & PWMRQ_ID_MASK) == actual_req_id)
+ { // reply is for actual request
+ reply_start = p;
+ if (!(id & PWMRP_HAS_PAYLOAD))
+ {
+ reply_count = 0;
+ return 1;
+ }
+ if (wait_for_reply())
+ {
+ reply_count = read_data();
+ return 1;
+ }
+ return 0;
+ }
+ }
+ // drop garbagge
+ ++p;
+ CHECK_RXBUF_END(p);
+ rxrpos = p;
+ }
+
+ if (bit_is_clear(UCSRA, TXC))
+ t = get_sys_clock();
+ }
+
+ set_bit(reply_err_status, COMM_ERR_TIMEOUT);
+ return 0;
+}
+
+
+// ---
+// Stop PWM controller.
+//
+static void stop_pwm_ctrl(void)
+{
+ clear_bit(UCSRB, RXEN); // Disable USART RX
+ clear_bit(RESET_PORT, RESET_BIT);
+}
+
+
+// ---
+// Reset PWM controller.
+//
+static void reset_pwm_ctrl(void)
+{
+ stop_pwm_ctrl();
+ timer_delay(RESET_TIME);
+
+ set_bit(RESET_PORT, RESET_BIT);
+ timer_delay(STARTUP_TIME);
+
+ rxwpos = rxrpos = 0; // Flush reply buffer
+ reply_err_status = 0;
+
+ set_bit(UCSRB, RXEN); // Enable USART RX
+}
+
+
+// ---
+// Send PWM controller request payload data.
+//
+static uint8_t send_payload_data(uint8_t *data, uint8_t len)
+{
+ if(len > payload_count)
+ len = payload_count;
+ payload_count -= len;
+
+ uint8_t i = 0;
+ while (i < len)
+ send_data(data[i++]);
+
+ if (!payload_count)
+ {
+ if (wait_for_reply_start()) // Wait for ACK
+ return 1; // all done successfull
+ return USB_STALL_RC; // error happen
+ }
+
+ return 0; // next packet
+}
+
+
+// ---
+// Read PWM controller request payload data.
+//
+static uint8_t read_payload_data(uint8_t *data, uint8_t len)
+{
+ if (len > reply_count)
+ len = reply_count;
+ if(len > payload_count)
+ len = payload_count;
+ reply_count -= len;
+ payload_count -= len;
+
+ uint8_t i = 0;
+ while (i < len && wait_for_reply())
+ data[i++] = read_data();
+
+ if (i < len)
+ return USB_STALL_RC; // error happen
+
+ return i;
+}
+
+
+// ---
+// Write EE prom data.
+//
+static uint8_t write_ee_data(uint8_t *data, uint8_t len)
+{
+ if(len > payload_count)
+ len = payload_count;
+ payload_count -= len;
+
+ uint8_t i = 0;
+ while (i < len && payload_pos < EE_MEM_SIZE)
+ {
+ uint8_t old_data = eeprom_read_byte((uint8_t *)payload_pos);
+ uint8_t new_data = data[i];
+ if (old_data != new_data)
+ {
+ eeprom_write_byte((uint8_t *)payload_pos, new_data);
+
+ while (!eeprom_is_ready())
+ background_processing();
+
+ old_data = eeprom_read_byte((uint8_t *)payload_pos);
+ if (old_data != new_data)
+ return USB_STALL_RC; // write error
+ }
+ ++i;
+ ++payload_pos;
+ }
+
+ return payload_count == 0;
+}
+
+
+// ---
+// Read EE prom data.
+//
+static uint8_t read_ee_data(uint8_t *data, uint8_t len)
+{
+ if(len > payload_count)
+ len = payload_count;
+ payload_count -= len;
+
+ uint8_t i = 0;
+ while (i < len && payload_pos < EE_MEM_SIZE)
+ {
+ data[i] = eeprom_read_byte((uint8_t *)payload_pos);
+ ++i;
+ ++payload_pos;
+ }
+
+ return i;
+}
+
+
+// ---
+// Write request payload data.
+//
+USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len)
+{
+ uint8_t rc = USB_STALL_RC;
+
+ if (usb_last_rc != USB_STALL_RC)
+ {
+ if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4])
+ {
+ if (usbCurrentDataToken == usb_last_data_token)
+ {
+ set_bit(reply_err_status, COMM_ERR_DUPLICATE);
+ return usb_last_rc; // Ignore packet
+ }
+
+ if (payload_req >= REQ_PWM_START)
+ rc = send_payload_data(data, len);
+ else if (payload_req == REQ_WRITE_EE_DATA)
+ rc = write_ee_data(data, len);
+ }
+ else
+ set_bit(reply_err_status, COMM_ERR_CRC);
+ }
+
+ usb_last_data_token = usbCurrentDataToken;
+ usb_last_rc = rc;
+
+ return rc;
+}
+
+
+// ---
+// Read request payload data.
+//
+USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len)
+{
+ uint8_t rc = USB_STALL_RC;
+
+ if (usb_last_rc != USB_STALL_RC)
+ {
+ if (payload_req >= REQ_PWM_START)
+ rc = read_payload_data(data, len);
+ else if (payload_req == REQ_READ_EE_DATA)
+ rc = read_ee_data(data, len);
+ }
+
+ usb_last_rc = rc;
+
+ return rc;
+}
+
+
+// ---
+// Handle a non-standard USB SETUP packet.
+//
+USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8])
+{
+ usbRequest_t *r = (usbRequest_t *) data;
+ static uint8_t reply[1];
+
+ usb_last_data_token = USBPID_SETUP;
+ usb_last_rc = USB_STALL_RC;
+ uint8_t rc = USB_NO_MSG;
+
+ if (usbCrc16(data, 8) != ((uint16_t *)data)[4])
+ {
+ set_bit(reply_err_status, COMM_ERR_CRC);
+ return rc;
+ }
+
+ uint8_t req = r->bRequest;
+
+ if (req >= REQ_PWM_START)
+ {
+ if (bit_is_clear (RESET_PORT, RESET_BIT))
+ reset_pwm_ctrl();
+
+ uint8_t req_type = (r->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST ? PWMRQ_DEVICE_TO_HOST: 0;
+ if (r->wLength.word <= MAX_REQ_PAYLOAD_SIZE)
+ {
+ send_request(req_type);
+ send_data(req);
+ send_data(r->wValue.bytes[0]);
+ send_data(r->wValue.bytes[1]);
+ send_data(r->wIndex.bytes[0]);
+ send_data(r->wIndex.bytes[1]);
+ send_data(r->wLength.bytes[0]);
+ send_data(r->wLength.bytes[1]);
+
+ payload_req = req;
+ payload_count = r->wLength.word;
+
+ if (req_type == PWMRQ_DEVICE_TO_HOST || !r->wLength.word)
+ {
+ if (wait_for_reply_start())
+ {
+ if (reply_count && r->wLength.word)
+ usb_last_rc = 0;
+ else
+ rc = 0;
+ }
+ }
+ else
+ usb_last_rc = 0;
+ }
+ }
+ else if (req == REQ_READ_EE_DATA || req == REQ_WRITE_EE_DATA)
+ {
+ if (r->wLength.word)
+ {
+ payload_pos = r->wIndex.word;
+ payload_req = req;
+ payload_count = r->wLength.word;
+ usb_last_rc = 0;
+ }
+ else
+ rc = 0;
+ }
+ else if (req == REQ_STOP_PWM_CTRL)
+ {
+ set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT);
+ stop_pwm_ctrl();
+ rc = 0;
+ }
+ else if (req == REQ_RESET_PWM_CTRL)
+ {
+ set_bit(BOOTLOADER_PORT, BOOTLOADER_BIT);
+ reset_pwm_ctrl();
+ rc = 0;
+ }
+ else if (req == REQ_BOOTLOADER_RESET_PWM_CTRL)
+ {
+ clear_bit(BOOTLOADER_PORT, BOOTLOADER_BIT);
+ reset_pwm_ctrl();
+ rc = 0;
+ }
+ else if (req == REQ_GET_REPLY_ERR_STATUS)
+ {
+ reply[0] = reply_err_status;
+ reply_err_status = 0;
+ usbMsgPtr = reply;
+ rc = 1;
+ }
+ else if (req == REQ_SET_REPLY_TIMEOUT)
+ {
+ reply_start_timeout = ms_to_ticks(r->wValue.word);
+ reply_timeout = ms_to_ticks(r->wIndex.word);
+ rc = 0;
+ }
+ else if (req == REQ_START_BOOTLOADER)
+ {
+ bl_start = 1;
+ bl_time = get_sys_clock();
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+// ----
+// Main
+//
+void main(void) NORETURN;
+void main(void)
+{
+ wdt_enable(WDTO_120MS); // Set watchdog timeout
+
+ // Initialize Ports
+ PORTB = PORTB_INIT;
+ DDRB = DDRB_INIT;
+ PORTC = PORTC_INIT;
+ DDRC = DDRC_INIT;
+ PORTD = PORTD_INIT;
+ DDRD = DDRD_INIT;
+
+ usbDeviceDisconnect();
+
+ set_bit(ACSR, ACD); // Disable analog comparator saving some power
+
+ // Initialize Timer 1
+ TCNT1 = 0;
+ TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024
+
+ // Initialize USART
+#include <util/setbaud.h>
+ UBRRH = UBRRH_VALUE;
+ UBRRL = UBRRL_VALUE;
+#if USE_2X
+ UCSRA = _BV(U2X);
+#endif
+ UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // 9 data bits, 1 stop bit, no parity, asynchron mode
+ UCSRB = _BV(TXEN) | _BV(UCSZ2) | _BV(RXCIE); // Enable TX and RX IRQ
+
+ reset_pwm_ctrl();
+
+ timer_delay(USB_DISCONNECT_TIME);
+ usbDeviceConnect();
+ usbInit();
+
+ sei();
+
+ // Main loop
+ for (;;)
+ {
+ background_processing();
+
+ usbPoll(); // process USB requests
+
+ if ((bit_is_clear(BL_SENSE_PIN, BL_SENSE_BIT) ||
+ (bl_start && (get_sys_clock() - bl_time) > BL_START_DELAY_TIME)) &&
+ pgm_read_word(BL_START_VECT) != 0xFFFF)
+ {
+ cli();
+ stop_pwm_ctrl();
+ clear_bit(USB_INTR_ENABLE, USB_INTR_ENABLE_BIT); // Stop USB
+ UCSRB = 0; // Stop USART
+ TCCR1B = 0; // Stop Timer
+
+ // enable boot loader by setting sense pin to 0
+ clear_bit(BL_SENSE_PORT, BL_SENSE_BIT);
+ set_bit(BL_SENSE_DDR, BL_SENSE_BIT);
+
+ // start bootloader
+ void (*jump_to_bl)(void) = BL_START_VECT / 2; // Need flash word address for jump!
+ jump_to_bl();
+ }
+
+
+#if 0
+ if (!usb_is_initialized && get_sys_clock() > USB_INITIALIZE_TIMEOUT)
+ { // request USB device enumeration
+ cli();
+ usb_is_initialized = 1;
+ usbDeviceDisconnect();
+ timer_delay(USB_DISCONNECT_TIME);
+ usbDeviceConnect();
+ usbInit();
+ sei();
+ }
+#endif
+
+ // Check for standby state
+ if (usb_is_resetting)
+ { // ongoing USB reset -> reset activity timeout
+ cli();
+ usb_sof_time = TCNT1;
+ sei();
+ }
+ else
+ {
+ cli();
+ uint16_t t = usb_sof_time;
+ sei();
+ if ((get_sys_clock() - t) > USB_SLEEP_TIMEOUT)
+ { // no USB activity -> go sleeping
+ cli();
+ stop_pwm_ctrl();
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ USB_INTR_CFG &= ~USB_INTR_CFG_SET; // set low level triggered IRQ for wakeup
+ USB_INTR_PENDING = _BV(USB_INTR_PENDING_BIT); // reset pending IRQ
+ wdt_disable();
+ sleep_enable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+ wdt_enable(WDTO_30MS);
+ cli();
+ TCNT1 = 0;
+ usb_sof_time = 0;
+ sei();
+ reset_pwm_ctrl();
+ }
+ }
+ }
+}
diff --git a/usb_appl/Makefile b/usb_appl/Makefile
new file mode 100644
index 0000000..03ca6d8
--- /dev/null
+++ b/usb_appl/Makefile
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+#
+###############################################################################
+# Makefile for the application firmware of USB processor
+###############################################################################
+
+## General Flags
+PROJECT = 10ch_usb_appl
+MCU = atmega8
+TARGET = 10ch_usb_appl.elf
+CC = avr-gcc
+AVRDUDE ?= avrdude -c stk500v2 -P avrdoper
+USBDRV ?= ../usbdrv
+F_CPU ?= 16000000UL
+FIRMWARE_VERSION ?= 1
+
+## Options common to compile, link and assembly rules
+COMMON = -mmcu=$(MCU)
+
+## Compile options common for all C compilation units.
+CFLAGS = $(COMMON)
+CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION)
+
+## Assembly specific flags
+ASMFLAGS = $(COMMON)
+ASMFLAGS += $(CFLAGS)
+ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
+
+## Linker flags
+LDFLAGS = $(COMMON)
+LDFLAGS += -Wl,-Map=10ch_usb_appl.map
+
+
+## Intel Hex file production flags
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
+
+HEX_EEPROM_FLAGS = -j .eeprom
+HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
+
+## Include Directories
+INCLUDES = -I. -I.. -I$(USBDRV)
+
+## Objects that must be built in order to link
+OBJECTS = 10ch_usb_appl.o usbdrvasm.o
+
+## Objects explicitly added by the user
+LINKONLYOBJECTS =
+
+## Build
+all: $(TARGET) 10ch_usb_appl.dff 10ch_usb_appl.lss size
+
+10ch_usb_appl.dff: 10ch_usb_appl.hex
+ echo "@DF10CH-USB" $(FIRMWARE_VERSION) > $@
+ cat 10ch_usb_appl.hex >> $@
+
+prog: flash
+ $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC9:m -Ulock:w:0xEF:m
+
+flash: 10ch_usb_appl.hex
+ $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_usb_appl.hex:i
+
+
+## Compile
+usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h
+ $(CC) $(INCLUDES) $(ASMFLAGS) -c $<
+
+10ch_usb_appl.o: 10ch_usb_appl.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h
+ $(CC) $(INCLUDES) $(CFLAGS) -c $<
+
+##Link
+$(TARGET): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
+
+%.hex: $(TARGET)
+ avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
+
+%.eep: $(TARGET)
+ -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
+
+%.lss: $(TARGET)
+ avr-objdump -h -S $< > $@
+
+size: ${TARGET}
+ @echo
+ @avr-size -C --mcu=${MCU} ${TARGET}
+
+## Clean target
+.PHONY: clean
+clean:
+ -rm -rf $(OBJECTS) 10ch_usb_appl.elf 10ch_usb_appl.dff 10ch_usb_appl.hex 10ch_usb_appl.eep 10ch_usb_appl.lss 10ch_usb_appl.map
diff --git a/usb_appl/usbconfig.h b/usb_appl/usbconfig.h
new file mode 100644
index 0000000..0744d16
--- /dev/null
+++ b/usb_appl/usbconfig.h
@@ -0,0 +1,392 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
++ To create your own usbconfig.h file, copy this file to your project's
++ firmware source directory) and rename it to "usbconfig.h".
++ Then edit it accordingly.
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
+ * crystal, they tolerate +/- 1% deviation from the nominal frequency. All
+ * other rates require a precision of 2000 ppm and thus a crystal!
+ * Default if not specified: 12 MHz
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+#define USB_CFG_PULLUP_IOPORTNAME D
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+#define USB_CFG_PULLUP_BIT 4
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 25
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 98
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 1
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+#define USB_RESET_HOOK(resetStarts) usb_is_resetting = resetStarts;
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+#define USB_SET_ADDRESS_HOOK() usb_is_initialized = 1;
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF 0
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+#define USB_SOF_HOOK customSofHook
+/* This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+
+/* Save timestamp of sof */
+
+#ifdef __ASSEMBLER__
+macro customSofHook
+ in YL, TCNT1L
+ sts usb_sof_time, YL
+ in YL, TCNT1H
+ sts usb_sof_time+1, YL
+endm
+#endif
+
+#define USB_CFG_CHECK_DATA_TOGGLING 1
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 1
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID 0xc0, 0x16
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you use one of obdev's free shared
+ * VID/PID pairs. Be sure to read USBID-License.txt for rules!
+ * + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
+ * + Use this VID/PID pair ONLY if you understand the implications!
+ */
+#define USB_CFG_DEVICE_ID 0xdc, 0x05
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you use obdev's free shared VID/PID pair. Be sure to read the rules in
+ * USBID-License.txt!
+ * + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
+ * + Use this VID/PID pair ONLY if you understand the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, FIRMWARE_VERSION
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 'y', 'a', 'k', '5', '4', '@', 'g', 'm', 'x', '.', 'n', 'e', 't'
+#define USB_CFG_VENDOR_NAME_LEN 13
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USBID-License.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'D', 'F', '1', '0', 'C', 'H'
+#define USB_CFG_DEVICE_NAME_LEN 6
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USBID-License.txt before you assign a name if you
+ * use a shared VID/PID.
+ */
+#define USB_CFG_SERIAL_NUMBER 'A', 'P'
+#define USB_CFG_SERIAL_NUMBER_LEN 2
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 0xff /* define class here if not at device level */
+#define USB_CFG_INTERFACE_SUBCLASS 0
+#define USB_CFG_INTERFACE_PROTOCOL 0
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+#define USB_PUBLIC static
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+#define USB_INTR_CFG MCUCR
+#if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK)
+#define USB_INTR_CFG_SET ((1 << ISC11))
+#else
+#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11))
+#endif
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+#define USB_INTR_ENABLE_BIT INT1
+/* #define USB_INTR_PENDING GIFR */
+#define USB_INTR_PENDING_BIT INTF1
+#define USB_INTR_VECTOR SIG_INTERRUPT1
+
+
+/* This is a new macro that is executed and the beginning of the usb irq handler.
+ * This needs a patch in the corresponding clock dependend assembler file of VUSB!!!
+ * It is save to use register YH here
+ */
+#define USB_START_IRQ_HOOK customTriggerHook
+
+
+/* Reinstall edge level interrupt triggering (after sleep) */
+#ifdef __ASSEMBLER__
+macro customTriggerHook
+ in YH, USB_INTR_CFG
+ ori YH, USB_INTR_CFG_SET
+ out USB_INTR_CFG, YH
+endm
+#endif
+
+#endif /* __usbconfig_h_included__ */
diff --git a/usb_boot/10ch_usb_boot.c b/usb_boot/10ch_usb_boot.c
new file mode 100644
index 0000000..7ba4d92
--- /dev/null
+++ b/usb_boot/10ch_usb_boot.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Andreas Auras
+ *
+ * This file is part of the DF10CH Atmolight controller project.
+ *
+ * DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DF10CH Atmolight controller is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ */
+
+// ======================================================================
+// Bootloader firmware for USB processor.
+//
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/eeprom.h>
+#include <avr/boot.h>
+#include <avr/pgmspace.h>
+
+#include "../df10ch_common.h"
+#include "../df10ch_usb_proto.h"
+#include "usbconfig.h"
+
+
+// ---
+// Fuse-Bit settings for the flash programmer (ATmega8):
+// RSTDISBL=1
+// WDTON=1
+// SPIEN=0
+// CKOPT=0
+// EESAVE=1
+// BOOTSZ1=0
+// BOOTSZ0=0
+// BOOTRST=0
+//
+// BODLEVEL=0
+// BODEN=0
+// SUT1=0
+// SUT0=1
+// CKSEL3=1
+// CKSEL2=1
+// CKSEL1=1
+// CKSEL0=1
+//
+// Memory-Lock Bits:
+// BL12=1, BL11=0, BL02=1, BL01=1, LB2=1, LB1=1
+//
+FUSES =
+{
+ .low = (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT1),
+ .high = (FUSE_SPIEN & FUSE_CKOPT & FUSE_BOOTSZ1 & FUSE_BOOTSZ0 & FUSE_BOOTRST)
+};
+LOCKBITS = (LB_MODE_1 & BLB0_MODE_1 & BLB1_MODE_2);
+SIGNATURE_DATA = { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 } ;
+
+
+// ---
+// System clock related.
+// System clock ist implemented with hardware timer 1
+//
+#define SYS_HWPRESCALE 1024 // Hardware Prescaler
+
+ // useconds <-> timer ticks conversation
+#define US2TICKS(t) ((uint16_t)((double)(t) * (double)F_CPU / (1000000.0 * (double)SYS_HWPRESCALE) + 0.5))
+#define TICKS2US(t) ((uint16_t)((t) / (F_CPU / (1000000UL * SYS_HWPRESCALE))))
+
+
+ // Input pin (Jumper) for enable/disable of bootloader
+ // Enabled when Jumper set -> 0, Disabled if Jumper is away -> 1
+#define BL_SENSE_DDR DDRB
+#define BL_SENSE_PORT PORTB
+#define BL_SENSE_PIN PINB
+#define BL_SENSE_BIT 0
+
+#define APPL_START_VECT 0x0000
+
+static uint8_t leave_state; // Is true when bootloader should be leaved
+
+
+// ---
+// USB related.
+//
+#define USB_DISCONNECT_TIME US2TICKS(500000UL)
+#define USB_STALL_RC 0xFF
+
+static uint8_t usb_last_data_token NOMEMINIT; // Token PID of last usb packet received
+static uint8_t usb_last_rc = USB_STALL_RC; // Return status of last payload packet
+static uint8_t payload_req NOMEMINIT; // ID of actual proccessed USB request
+
+// ---
+// flash programming related.
+//
+static uint16_t page_address NOMEMINIT; // actual page address
+static uint8_t page_offset NOMEMINIT; // actual offset into page
+static uint8_t page_size_reply[2] = { (SPM_PAGESIZE & 0xFF), (SPM_PAGESIZE >> 8) };
+
+#include <usbdrv.c>
+
+
+// ---
+// ISR handler for IRQ's that do not have a dedicated handler.
+//
+EMPTY_INTERRUPT(BADISR_vect)
+
+
+// ---
+// Write request payload data.
+//
+USB_PUBLIC uint8_t usbFunctionWrite(uint8_t *data, uint8_t len)
+{
+ uint8_t rc = USB_STALL_RC;
+
+ if (usb_last_rc != USB_STALL_RC)
+ {
+ if (len != 8 || usbCrc16(data, 8) == ((uint16_t *)data)[4])
+ {
+ if (usbCurrentDataToken == usb_last_data_token)
+ return usb_last_rc; // Ignore packet
+
+ if (payload_req == BL_REQ_WRITE_PAGE)
+ {
+ rc = 0;
+ while (len > 1)
+ {
+ bytes_word_t code;
+ code.bytes[0] = *data++;
+ code.bytes[1] = *data++;
+
+ cli();
+ boot_page_fill(page_address + page_offset, code.word);
+ sei();
+
+ page_offset += 2;
+ len -= 2;
+ if (page_offset >= SPM_PAGESIZE)
+ {
+ cli();
+ boot_page_write(page_address);
+ sei();
+
+ while (boot_spm_busy())
+ wdt_reset();
+
+ rc = 1;
+ }
+ }
+ }
+ }
+ }
+
+ if (rc)
+ usb_last_rc = USB_STALL_RC;
+ usb_last_data_token = usbCurrentDataToken;
+
+ return rc;
+}
+
+
+// ---
+// Read request payload data.
+//
+USB_PUBLIC uint8_t usbFunctionRead(uint8_t *data, uint8_t len)
+{
+ uint8_t rc = USB_STALL_RC;
+
+ if (usb_last_rc != USB_STALL_RC)
+ {
+ if (payload_req == BL_REQ_READ_FLASH)
+ {
+ if (len > page_offset)
+ len = page_offset;
+ rc = len;
+ if (len)
+ {
+ page_offset -= len;
+ PGM_P p = (PGM_P) page_address;
+ page_address += len;
+ memcpy_P(data, p, len);
+ }
+ }
+
+ if (rc != 8)
+ usb_last_rc = USB_STALL_RC;
+ }
+
+ return rc;
+}
+
+
+// ---
+// Handle a non-standard USB SETUP packet.
+//
+USB_PUBLIC usbMsgLen_t usbFunctionSetup(uint8_t data[8])
+{
+ usbRequest_t *r = (usbRequest_t *) data;
+
+ usb_last_data_token = USBPID_SETUP;
+ usb_last_rc = USB_STALL_RC;
+ uint8_t rc = USB_NO_MSG;
+
+ if (leave_state || usbCrc16(data, 8) != ((uint16_t *)data)[4])
+ return rc;
+
+ uint8_t req = r->bRequest;
+ payload_req = req;
+
+ if (req == BL_REQ_WRITE_PAGE)
+ {
+ page_address = r->wIndex.word;
+ page_offset = 0;
+
+ while (!eeprom_is_ready())
+ wdt_reset();
+
+ cli();
+ boot_page_erase(page_address);
+ sei();
+
+ while (boot_spm_busy())
+ wdt_reset();
+
+ usb_last_rc = 0;
+ }
+ else if (req == BL_REQ_LEAVE_BOOT)
+ {
+ if (boot_rww_busy())
+ boot_rww_enable();
+ leave_state = 1;
+ rc = 0;
+ }
+ else if (req == BL_REQ_GET_PAGE_SIZE)
+ {
+ usbMsgPtr = page_size_reply;
+ rc = sizeof(page_size_reply);
+ }
+ else if (req == BL_REQ_READ_FLASH)
+ {
+ if (boot_rww_busy())
+ boot_rww_enable();
+ page_address = r->wIndex.word;
+ page_offset = r->wLength.bytes[0];
+ usb_last_rc = 0;
+ }
+
+ return rc;
+}
+
+
+// ----
+// Main
+//
+void main(void) NORETURN;
+void main(void)
+{
+ cli();
+
+ wdt_enable(WDTO_120MS); // Set watchdog timeout
+
+ // Note: If application calls bootloader it must set the enable pin to output and low level
+ if (bit_is_clear(BL_SENSE_DDR, BL_SENSE_BIT))
+ set_bit(BL_SENSE_PORT, BL_SENSE_BIT); // activate pullup
+
+ if ((pgm_read_word(APPL_START_VECT) != 0xFFFF) && // Application reset vector programmed?
+ bit_is_set(BL_SENSE_PIN, BL_SENSE_BIT))
+ { // boot loader disabled -> start application
+ void (*jump_to_app)(void) = APPL_START_VECT / 2; // Need flash word address!
+ jump_to_app();
+ }
+
+ GICR = _BV(IVCE); // enable change of interrupt vectors
+ GICR = _BV(IVSEL); // move interrupts to boot flash section
+
+ // initialize boot loader disable pin: input + pullup
+ clear_bit(BL_SENSE_DDR, BL_SENSE_BIT);
+ set_bit(BL_SENSE_PORT, BL_SENSE_BIT);
+
+ usbDeviceDisconnect();
+
+ // Initialize Timer 1
+ TIMSK = 0;
+ TCCR1A = 0;
+ TCCR1B = 0;
+ TCNT1 = 0;
+ TCCR1B = _BV(CS12) | _BV(CS10); // Start timer 1, Prescaler 1024
+
+ while (TCNT1 < USB_DISCONNECT_TIME)
+ wdt_reset();
+
+ TCCR1B = 0; // Stop timer 1
+
+ usbDeviceConnect();
+ usbInit();
+
+ sei();
+
+ // Main loop
+ for (;;)
+ {
+ // Note: Delayed boot loader exit is done via watchdog timer reset
+ if (!leave_state)
+ wdt_reset();
+
+ usbPoll(); // process USB requests
+ }
+}
+
diff --git a/usb_boot/Makefile b/usb_boot/Makefile
new file mode 100644
index 0000000..6f63ffa
--- /dev/null
+++ b/usb_boot/Makefile
@@ -0,0 +1,106 @@
+#
+# Copyright (C) 2010 Andreas Auras
+#
+# This file is part of the DF10CH Atmolight controller project.
+#
+# DF10CH Atmolight controller is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# DF10CH Atmolight controller is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+#
+#
+###############################################################################
+# Makefile for the bootloader firmware of USB processor
+###############################################################################
+
+## General Flags
+PROJECT = 10ch_usb_boot
+MCU = atmega8
+TARGET = 10ch_usb_boot.elf
+CC = avr-gcc
+AVRDUDE ?= avrdude -c stk500v2 -P avrdoper
+USBDRV ?= ../usbdrv
+F_CPU ?= 16000000UL
+FIRMWARE_VERSION ?= 1
+
+## Options common to compile, link and assembly rules
+COMMON = -mmcu=$(MCU)
+
+## Compile options common for all C compilation units.
+CFLAGS = $(COMMON)
+CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -DF_CPU=$(F_CPU) -DFIRMWARE_VERSION=$(FIRMWARE_VERSION)
+
+## Assembly specific flags
+ASMFLAGS = $(COMMON)
+ASMFLAGS += $(CFLAGS)
+ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
+
+## Linker flags
+LDFLAGS = $(COMMON)
+LDFLAGS += -Wl,-Map=10ch_usb_boot.map
+LDFLAGS += -Wl,-section-start=.text=0x1800
+
+
+## Intel Hex file production flags
+HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
+
+HEX_EEPROM_FLAGS = -j .eeprom
+HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
+
+## Include Directories
+INCLUDES = -I. -I.. -I$(USBDRV)
+
+## Objects that must be built in order to link
+OBJECTS = 10ch_usb_boot.o usbdrvasm.o
+
+## Objects explicitly added by the user
+LINKONLYOBJECTS =
+
+## Build
+all: $(TARGET) 10ch_usb_boot.hex 10ch_usb_boot.lss size
+
+prog: flash
+ $(AVRDUDE) -p $(MCU) -u -Ulfuse:w:0x1F:m -Uhfuse:w:0xC8:m -Ulock:w:0xEF:m
+
+flash: 10ch_usb_boot.hex
+ $(AVRDUDE) -p $(MCU) -Uflash:w:10ch_usb_boot.hex:i
+
+
+## Compile
+usbdrvasm.o: $(USBDRV)/usbdrvasm.S usbconfig.h
+ $(CC) $(INCLUDES) $(ASMFLAGS) -c $<
+
+10ch_usb_boot.o: 10ch_usb_boot.c usbconfig.h ../df10ch_usb_proto.h ../df10ch_common.h
+ $(CC) $(INCLUDES) $(CFLAGS) -c $<
+
+##Link
+$(TARGET): $(OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
+
+%.hex: $(TARGET)
+ avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
+
+%.eep: $(TARGET)
+ -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
+
+%.lss: $(TARGET)
+ avr-objdump -h -S $< > $@
+
+size: ${TARGET}
+ @echo
+ @avr-size -C --mcu=${MCU} ${TARGET}
+
+## Clean target
+.PHONY: clean
+clean:
+ -rm -rf $(OBJECTS) 10ch_usb_boot.elf 10ch_usb_boot.hex 10ch_usb_boot.eep 10ch_usb_boot.lss 10ch_usb_boot.map
diff --git a/usb_boot/usbconfig.h b/usb_boot/usbconfig.h
new file mode 100644
index 0000000..e9899b7
--- /dev/null
+++ b/usb_boot/usbconfig.h
@@ -0,0 +1,391 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
++ To create your own usbconfig.h file, copy this file to your project's
++ firmware source directory) and rename it to "usbconfig.h".
++ Then edit it accordingly.
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
+ * crystal, they tolerate +/- 1% deviation from the nominal frequency. All
+ * other rates require a precision of 2000 ppm and thus a crystal!
+ * Default if not specified: 12 MHz
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+#define USB_CFG_PULLUP_IOPORTNAME D
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+#define USB_CFG_PULLUP_BIT 4
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 25
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 98
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 1
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/*#define USB_RESET_HOOK(resetStarts) usb_is_resetting = resetStarts;*/
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/*#define USB_SET_ADDRESS_HOOK() usb_is_initialized = 1;*/
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+/*#define USB_COUNT_SOF 0*/
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/*#define USB_SOF_HOOK customSofHook*/
+/* This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+
+/* Save timestamp of sof */
+
+#ifdef __ASSEMBLER__
+macro customSofHook
+ ldi YL, 0
+ out TCNT1H, YL
+ out TCNT1L, YL
+endm
+#endif
+
+#define USB_CFG_CHECK_DATA_TOGGLING 1
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 1
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID 0xc0, 0x16
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you use one of obdev's free shared
+ * VID/PID pairs. Be sure to read USBID-License.txt for rules!
+ * + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
+ * + Use this VID/PID pair ONLY if you understand the implications!
+ */
+#define USB_CFG_DEVICE_ID 0xdc, 0x05
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you use obdev's free shared VID/PID pair. Be sure to read the rules in
+ * USBID-License.txt!
+ * + This template uses obdev's shared VID/PID pair: 0x16c0/0x5dc.
+ * + Use this VID/PID pair ONLY if you understand the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, FIRMWARE_VERSION
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 'y', 'a', 'k', '5', '4', '@', 'g', 'm', 'x', '.', 'n', 'e', 't'
+#define USB_CFG_VENDOR_NAME_LEN 13
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USBID-License.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'D', 'F', '1', '0', 'C', 'H'
+#define USB_CFG_DEVICE_NAME_LEN 6
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USBID-License.txt before you assign a name if you
+ * use a shared VID/PID.
+ */
+#define USB_CFG_SERIAL_NUMBER 'B', 'L'
+#define USB_CFG_SERIAL_NUMBER_LEN 2
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 0xff /* define class here if not at device level */
+#define USB_CFG_INTERFACE_SUBCLASS 0
+#define USB_CFG_INTERFACE_PROTOCOL 0
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+#define USB_PUBLIC static
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+#define USB_INTR_CFG MCUCR
+#if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK) || 1
+#define USB_INTR_CFG_SET ((1 << ISC11))
+#else
+#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11))
+#endif
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+#define USB_INTR_ENABLE_BIT INT1
+/* #define USB_INTR_PENDING GIFR */
+#define USB_INTR_PENDING_BIT INTF1
+#define USB_INTR_VECTOR SIG_INTERRUPT1
+
+
+/* This is a new macro that is executed and the beginning of the usb irq handler.
+ * This needs a patch in the corresponding clock dependend assembler file of VUSB!!!
+ * It is save to use register YH here
+ */
+/*#define USB_START_IRQ_HOOK customTriggerHook*/
+
+
+/* Reinstall edge level interrupt triggering (after sleep) */
+#ifdef __ASSEMBLER__
+macro customTriggerHook
+ in YH, USB_INTR_CFG
+ ori YH, USB_INTR_CFG_SET
+ out USB_INTR_CFG, YH
+endm
+#endif
+
+#endif /* __usbconfig_h_included__ */
diff --git a/usbdrv/Changelog.txt b/usbdrv/Changelog.txt
new file mode 100644
index 0000000..655a9d4
--- /dev/null
+++ b/usbdrv/Changelog.txt
@@ -0,0 +1,296 @@
+This file documents changes in the firmware-only USB driver for atmel's AVR
+microcontrollers. New entries are always appended to the end of the file.
+Scroll down to the bottom to see the most recent changes.
+
+2005-04-01:
+ - Implemented endpoint 1 as interrupt-in endpoint.
+ - Moved all configuration options to usbconfig.h which is not part of the
+ driver.
+ - Changed interface for usbVendorSetup().
+ - Fixed compatibility with ATMega8 device.
+ - Various minor optimizations.
+
+2005-04-11:
+ - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead()
+ and usbFunctionWrite() now. Added configuration options to choose which
+ of these functions to compile in.
+ - Assembler module delivers receive data non-inverted now.
+ - Made register and bit names compatible with more AVR devices.
+
+2005-05-03:
+ - Allow address of usbRxBuf on any memory page as long as the buffer does
+ not cross 256 byte page boundaries.
+ - Better device compatibility: works with Mega88 now.
+ - Code optimization in debugging module.
+ - Documentation updates.
+
+2006-01-02:
+ - Added (free) default Vendor- and Product-IDs bought from voti.nl.
+ - Added USBID-License.txt file which defines the rules for using the free
+ shared VID/PID pair.
+ - Added Readme.txt to the usbdrv directory which clarifies administrative
+ issues.
+
+2006-01-25:
+ - Added "configured state" to become more standards compliant.
+ - Added "HALT" state for interrupt endpoint.
+ - Driver passes the "USB Command Verifier" test from usb.org now.
+ - Made "serial number" a configuration option.
+ - Minor optimizations, we now recommend compiler option "-Os" for best
+ results.
+ - Added a version number to usbdrv.h
+
+2006-02-03:
+ - New configuration variable USB_BUFFER_SECTION for the memory section where
+ the USB rx buffer will go. This defaults to ".bss" if not defined. Since
+ this buffer MUST NOT cross 256 byte pages (not even touch a page at the
+ end), the user may want to pass a linker option similar to
+ "-Wl,--section-start=.mybuffer=0x800060".
+ - Provide structure for usbRequest_t.
+ - New defines for USB constants.
+ - Prepared for HID implementations.
+ - Increased data size limit for interrupt transfers to 8 bytes.
+ - New macro usbInterruptIsReady() to query interrupt buffer state.
+
+2006-02-18:
+ - Ensure that the data token which is sent as an ack to an OUT transfer is
+ always zero sized. This fixes a bug where the host reports an error after
+ sending an out transfer to the device, although all data arrived at the
+ device.
+ - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite().
+
+* Release 2006-02-20
+
+ - Give a compiler warning when compiling with debugging turned on.
+ - Added Oleg Semyonov's changes for IAR-cc compatibility.
+ - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect()
+ (also thanks to Oleg!).
+ - Rearranged tests in usbPoll() to save a couple of instructions in the most
+ likely case that no actions are pending.
+ - We need a delay between the SET ADDRESS request until the new address
+ becomes active. This delay was handled in usbPoll() until now. Since the
+ spec says that the delay must not exceed 2ms, previous versions required
+ aggressive polling during the enumeration phase. We have now moved the
+ handling of the delay into the interrupt routine.
+ - We must not reply with NAK to a SETUP transaction. We can only achieve this
+ by making sure that the rx buffer is empty when SETUP tokens are expected.
+ We therefore don't pass zero sized data packets from the status phase of
+ a transfer to usbPoll(). This change MAY cause troubles if you rely on
+ receiving a less than 8 bytes long packet in usbFunctionWrite() to
+ identify the end of a transfer. usbFunctionWrite() will NEVER be called
+ with a zero length.
+
+* Release 2006-03-14
+
+ - Improved IAR C support: tiny memory model, more devices
+ - Added template usbconfig.h file under the name usbconfig-prototype.h
+
+* Release 2006-03-26
+
+ - Added provision for one more interrupt-in endpoint (endpoint 3).
+ - Added provision for one interrupt-out endpoint (endpoint 1).
+ - Added flowcontrol macros for USB.
+ - Added provision for custom configuration descriptor.
+ - Allow ANY two port bits for D+ and D-.
+ - Merged (optional) receive endpoint number into global usbRxToken variable.
+ - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the
+ variable name from the single port letter instead of computing the address
+ of related ports from the output-port address.
+
+* Release 2006-06-26
+
+ - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the
+ new features.
+ - Removed "#warning" directives because IAR does not understand them. Use
+ unused static variables instead to generate a warning.
+ - Do not include <avr/io.h> when compiling with IAR.
+ - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each
+ USB descriptor should be handled. It is now possible to provide descriptor
+ data in Flash, RAM or dynamically at runtime.
+ - STALL is now a status in usbTxLen* instead of a message. We can now conform
+ to the spec and leave the stall status pending until it is cleared.
+ - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the
+ application code to reset data toggling on interrupt pipes.
+
+* Release 2006-07-18
+
+ - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes
+ an assembler error.
+ - usbDeviceDisconnect() takes pull-up resistor to high impedance now.
+
+* Release 2007-02-01
+
+ - Merged in some code size improvements from usbtiny (thanks to Dick
+ Streefland for these optimizations!)
+ - Special alignment requirement for usbRxBuf not required any more. Thanks
+ again to Dick Streefland for this hint!
+ - Reverted to "#warning" instead of unused static variables -- new versions
+ of IAR CC should handle this directive.
+ - Changed Open Source license to GNU GPL v2 in order to make linking against
+ other free libraries easier. We no longer require publication of the
+ circuit diagrams, but we STRONGLY encourage it. If you improve the driver
+ itself, PLEASE grant us a royalty free license to your changes for our
+ commercial license.
+
+* Release 2007-03-29
+
+ - New configuration option "USB_PUBLIC" in usbconfig.h.
+ - Set USB version number to 1.10 instead of 1.01.
+ - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and
+ USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences
+ to USB_CFG_DESCR_PROPS_STRING_PRODUCT.
+ - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver
+ code.
+ - New assembler module for 16 MHz crystal.
+ - usbdrvasm.S contains common code only, clock-specific parts have been moved
+ to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively.
+
+* Release 2007-06-25
+
+ - 16 MHz module: Do SE0 check in stuffed bits as well.
+
+* Release 2007-07-07
+
+ - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary
+ for negative values.
+ - Added 15 MHz module contributed by V. Bosch.
+ - Interrupt vector name can now be configured. This is useful if somebody
+ wants to use a different hardware interrupt than INT0.
+
+* Release 2007-08-07
+
+ - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is
+ not exceeded.
+ - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN,
+ USB_COUNT_SOF
+ - USB_INTR_PENDING can now be a memory address, not just I/O
+
+* Release 2007-09-19
+
+ - Split out common parts of assembler modules into separate include file
+ - Made endpoint numbers configurable so that given interface definitions
+ can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h.
+ - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut()
+ can handle any number of endpoints.
+ - Define usbDeviceConnect() and usbDeviceDisconnect() even if no
+ USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this
+ case.
+
+* Release 2007-12-01
+
+ - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size
+ when USB_CFG_PULLUP_IOPORTNAME is not defined.
+
+* Release 2007-12-13
+
+ - Renamed all include-only assembler modules from *.S to *.inc so that
+ people don't add them to their project sources.
+ - Distribute leap bits in tx loop more evenly for 16 MHz module.
+ - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR
+ - Avoid compiler warnings for constant expr range by casting some values in
+ USB descriptors.
+
+* Release 2008-01-21
+
+ - Fixed bug in 15 and 16 MHz module where the new address set with
+ SET_ADDRESS was already accepted at the next NAK or ACK we send, not at
+ the next data packet we send. This caused problems when the host polled
+ too fast. Thanks to Alexander Neumann for his help and patience debugging
+ this issue!
+
+* Release 2008-02-05
+
+ - Fixed bug in 16.5 MHz module where a register was used in the interrupt
+ handler before it was pushed. This bug was introduced with version
+ 2007-09-19 when common parts were moved to a separate file.
+ - Optimized CRC routine (thanks to Reimar Doeffinger).
+
+* Release 2008-02-16
+
+ - Removed outdated IAR compatibility stuff (code sections).
+ - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK().
+ - Added optional routine usbMeasureFrameLength() for calibration of the
+ internal RC oscillator.
+
+* Release 2008-02-28
+
+ - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we
+ start with sending USBPID_DATA0.
+ - Changed defaults in usbconfig-prototype.h
+ - Added free USB VID/PID pair for MIDI class devices
+ - Restructured AVR-USB as separate package, not part of PowerSwitch any more.
+
+* Release 2008-04-18
+
+ - Restructured usbdrv.c so that it is easier to read and understand.
+ - Better code optimization with gcc 4.
+ - If a second interrupt in endpoint is enabled, also add it to config
+ descriptor.
+ - Added config option for long transfers (above 254 bytes), see
+ USB_CFG_LONG_TRANSFERS in usbconfig.h.
+ - Added 20 MHz module contributed by Jeroen Benschop.
+
+* Release 2008-05-13
+
+ - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length
+ was not incremented, pointer to length was incremented instead.
+ - Added code to command line tool(s) which claims an interface. This code
+ is disabled by default, but may be necessary on newer Linux kernels.
+ - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING".
+ - New header "usbportability.h" prepares ports to other development
+ environments.
+ - Long transfers (above 254 bytes) did not work when usbFunctionRead() was
+ used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!]
+ - In hiddata.c (example code for sending/receiving data over HID), use
+ USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so
+ that we need not claim the interface.
+ - in usbPoll() loop 20 times polling for RESET state instead of 10 times.
+ This accounts for the higher clock rates we now support.
+ - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop.
+ - Added hook to SOF code so that oscillator can be tuned to USB frame clock.
+ - Added timeout to waitForJ loop. Helps preventing unexpected hangs.
+ - Added example code for oscillator tuning to libs-device (thanks to
+ Henrik Haftmann for the idea to this routine).
+ - Implemented option USB_CFG_SUPPRESS_INTR_CODE.
+
+* Release 2008-10-22
+
+ - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and
+ similar, not offset of 0x20 needs to be added.
+ - Allow distribution under GPLv3 for those who have to link against other
+ code distributed under GPLv3.
+
+* Release 2008-11-26
+
+ - Removed libusb-win32 dependency for hid-data example in Makefile.windows.
+ It was never required and confused many people.
+ - Added extern uchar usbRxToken to usbdrv.h.
+ - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser.
+
+* Release 2009-03-23
+
+ - Hid-mouse example used settings from hid-data example, fixed that.
+ - Renamed project to V-USB due to a trademark issue with Atmel(r).
+ - Changed CommercialLicense.txt and USBID-License.txt to make the
+ background of USB ID registration clearer.
+
+* Release 2009-04-15
+
+ - Changed CommercialLicense.txt to reflect the new range of PIDs from
+ Jason Kotzin.
+ - Removed USBID-License.txt in favor of USB-IDs-for-free.txt and
+ USB-ID-FAQ.txt
+ - Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in
+ the center between bit 0 and 1 of each byte. This is where the data lines
+ are expected to change and the sampled data may therefore be nonsense.
+ We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-.
+ - Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed,
+ the unstuffing code in the receiver routine was 1 cycle too long. If
+ multiple bytes had the unstuffing in bit 6, the error summed up until the
+ receiver was out of sync.
+ - Included option for faster CRC routine.
+ Thanks to Slawomir Fras (BoskiDialer) for this code!
+ - Updated bits in Configuration Descriptor's bmAttributes according to
+ USB 1.1 (in particular bit 7, it is a must-be-set bit now).
+
+* Release 2009-08-22
diff --git a/usbdrv/CommercialLicense.txt b/usbdrv/CommercialLicense.txt
new file mode 100644
index 0000000..11d07d9
--- /dev/null
+++ b/usbdrv/CommercialLicense.txt
@@ -0,0 +1,166 @@
+V-USB Driver Software License Agreement
+Version 2009-08-03
+
+THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
+ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
+THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT.
+
+
+1 DEFINITIONS
+
+1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH,
+Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA.
+
+1.2 "You" shall mean the Licensee.
+
+1.3 "V-USB" shall mean all files included in the package distributed under
+the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/)
+unless otherwise noted. This includes the firmware-only USB device
+implementation for Atmel AVR microcontrollers, some simple device examples
+and host side software examples and libraries.
+
+
+2 LICENSE GRANTS
+
+2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
+code of V-USB.
+
+2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
+non-exclusive right to use, copy and distribute V-USB with your hardware
+product(s), restricted by the limitations in section 3 below.
+
+2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
+the source code and your copy of V-USB according to your needs.
+
+2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB
+Product ID(s), sent to you in e-mail. These Product IDs are reserved
+exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID
+ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen
+Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from
+Jason Kotzin (Clay Logic, www.claylogic.com). Both owners of the Vendor IDs
+have obtained these IDs from the USB Implementers Forum, Inc.
+(www.usb.org). OBJECTIVE DEVELOPMENT disclaims all liability which might
+arise from the assignment of USB IDs.
+
+2.5 USB Certification. Although not part of this agreement, we want to make
+it clear that you cannot become USB certified when you use V-USB or a USB
+Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't
+meet the electrical specifications required by the USB specification and
+the USB Implementers Forum certifies only members who bought a Vendor ID of
+their own.
+
+
+3 LICENSE RESTRICTIONS
+
+3.1 Number of Units. Only one of the following three definitions is
+applicable. Which one is determined by the amount you pay to OBJECTIVE
+DEVELOPMENT, see section 4 ("Payment") below.
+
+Hobby License: You may use V-USB according to section 2 above in no more
+than 5 hardware units. These units must not be sold for profit.
+
+Entry Level License: You may use V-USB according to section 2 above in no
+more than 150 hardware units.
+
+Professional License: You may use V-USB according to section 2 above in
+any number of hardware units, except for large scale production ("unlimited
+fair use"). Quantities below 10,000 units are not considered large scale
+production. If your reach quantities which are obviously large scale
+production, you must pay a license fee of 0.10 EUR per unit for all units
+above 10,000.
+
+3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber
+any copy of V-USB, or any of the rights granted herein.
+
+3.3 Transfer. You may not transfer your rights under this Agreement to
+another party without OBJECTIVE DEVELOPMENT's prior written consent. If
+such consent is obtained, you may permanently transfer this License to
+another party. The recipient of such transfer must agree to all terms and
+conditions of this Agreement.
+
+3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not
+expressly granted.
+
+3.5 Non-Exclusive Rights. Your license rights under this Agreement are
+non-exclusive.
+
+3.6 Third Party Rights. This Agreement cannot grant you rights controlled
+by third parties. In particular, you are not allowed to use the USB logo or
+other trademarks owned by the USB Implementers Forum, Inc. without their
+consent. Since such consent depends on USB certification, it should be
+noted that V-USB will not pass certification because it does not
+implement checksum verification and the microcontroller ports do not meet
+the electrical specifications.
+
+
+4 PAYMENT
+
+The payment amount depends on the variation of this agreement (according to
+section 3.1) into which you want to enter. Concrete prices are listed on
+OBJECTIVE DEVELOPMENT's web site, usually at
+http://www.obdev.at/vusb/license.html. You agree to pay the amount listed
+there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
+or reseller.
+
+
+5 COPYRIGHT AND OWNERSHIP
+
+V-USB is protected by copyright laws and international copyright
+treaties, as well as other intellectual property laws and treaties. V-USB
+is licensed, not sold.
+
+
+6 TERM AND TERMINATION
+
+6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE
+DEVELOPMENT may terminate this Agreement and revoke the granted license and
+USB-IDs if you fail to comply with any of its terms and conditions.
+
+6.2 Survival of Terms. All provisions regarding secrecy, confidentiality
+and limitation of liability shall survive termination of this agreement.
+
+
+7 DISCLAIMER OF WARRANTY AND LIABILITY
+
+LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
+DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
+NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE
+TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
+RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
+STATE/JURISDICTION.
+
+LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
+IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
+(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
+LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE
+PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
+DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
+CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
+AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB.
+
+
+8 MISCELLANEOUS TERMS
+
+8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing
+purposes that you entered into this agreement.
+
+8.2 Entire Agreement. This document represents the entire agreement between
+OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by
+an authorized representative of both, OBJECTIVE DEVELOPMENT and you.
+
+8.3 Severability. In case a provision of these terms and conditions should
+be or become partly or entirely invalid, ineffective, or not executable,
+the validity of all other provisions shall not be affected.
+
+8.4 Applicable Law. This agreement is governed by the laws of the Republic
+of Austria.
+
+8.5 Responsible Courts. The responsible courts in Vienna/Austria will have
+exclusive jurisdiction regarding all disputes in connection with this
+agreement.
+
diff --git a/usbdrv/License.txt b/usbdrv/License.txt
new file mode 100644
index 0000000..4460cfb
--- /dev/null
+++ b/usbdrv/License.txt
@@ -0,0 +1,361 @@
+OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the
+terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is
+your choice whether you apply the terms of version 2 or version 3. The full
+text of GPLv2 is included below. In addition to the requirements in the GPL,
+we STRONGLY ENCOURAGE you to do the following:
+
+(1) Publish your entire project on a web site and drop us a note with the URL.
+Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
+
+(2) Adhere to minimum publication standards. Please include AT LEAST:
+ - a circuit diagram in PDF, PNG or GIF format
+ - full source code for the host software
+ - a Readme.txt file in ASCII format which describes the purpose of the
+ project and what can be found in which directories and which files
+ - a reference to http://www.obdev.at/vusb/
+
+(3) If you improve the driver firmware itself, please give us a free license
+to your modifications for our commercial license offerings.
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/usbdrv/Readme.txt b/usbdrv/Readme.txt
new file mode 100644
index 0000000..a010d97
--- /dev/null
+++ b/usbdrv/Readme.txt
@@ -0,0 +1,158 @@
+This is the Readme file to Objective Development's firmware-only USB driver
+for Atmel AVR microcontrollers. For more information please visit
+http://www.obdev.at/vusb/
+
+This directory contains the USB firmware only. Copy it as-is to your own
+project and add all .c and .S files to your project (these files are marked
+with an asterisk in the list below). Then copy usbconfig-prototype.h as
+usbconfig.h to your project and edit it according to your configuration.
+
+
+TECHNICAL DOCUMENTATION
+=======================
+The technical documentation (API) for the firmware driver is contained in the
+file "usbdrv.h". Please read all of it carefully! Configuration options are
+documented in "usbconfig-prototype.h".
+
+The driver consists of the following files:
+ Readme.txt ............. The file you are currently reading.
+ Changelog.txt .......... Release notes for all versions of the driver.
+ usbdrv.h ............... Driver interface definitions and technical docs.
+* usbdrv.c ............... High level language part of the driver. Link this
+ module to your code!
+* usbdrvasm.S ............ Assembler part of the driver. This module is mostly
+ a stub and includes one of the usbdrvasm*.S files
+ depending on processor clock. Link this module to
+ your code!
+ usbdrvasm*.inc ......... Assembler routines for particular clock frequencies.
+ Included by usbdrvasm.S, don't link it directly!
+ asmcommon.inc .......... Common assembler routines. Included by
+ usbdrvasm*.inc, don't link it directly!
+ usbconfig-prototype.h .. Prototype for your own usbdrv.h file.
+* oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is
+ defined to a value greater than 0. Link this module
+ to your code!
+ oddebug.h .............. Interface definitions of the debug module.
+ usbportability.h ....... Header with compiler-dependent stuff.
+ usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this
+ module instead of usbdrvasm.S when you assembler
+ with IAR's tools.
+ License.txt ............ Open Source license for this driver.
+ CommercialLicense.txt .. Optional commercial license for this driver.
+ USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs.
+ USB-IDs-for-free.txt ... List and terms of use for free shared PIDs.
+
+(*) ... These files should be linked to your project.
+
+
+CPU CORE CLOCK FREQUENCY
+========================
+We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz,
+16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The
+actual clock rate must be configured in usbdrv.h unless you use the default
+12 MHz.
+
+12 MHz Clock
+This is the traditional clock rate of V-USB because it's the lowest clock
+rate where the timing constraints of the USB spec can be met.
+
+15 MHz Clock
+Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock
+rate allows for some loops which make the resulting code size somewhat smaller
+than the 12 MHz version.
+
+16 MHz Clock
+This clock rate has been added for users of the Arduino board and other
+ready-made boards which come with a fixed 16 MHz crystal. It's also an option
+if you need the slightly higher clock rate for performance reasons. Since
+16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
+is somewhat tricky and has to insert a leap cycle every third byte.
+
+12.8 MHz and 16.5 MHz Clock
+The assembler modules for these clock rates differ from the other modules
+because they have been built for an RC oscillator with only 1% precision. The
+receiver code inserts leap cycles to compensate for clock deviations. 1% is
+also the precision which can be achieved by calibrating the internal RC
+oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL
+oscillator can reach 16.5 MHz with the RC oscillator. This includes the very
+popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost
+all AVRs can reach 12.8 MHz, although this is outside the specified range.
+
+See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for
+code which calibrates the RC oscillator based on the USB frame clock.
+
+18 MHz Clock
+This module is closer to the USB specification because it performs an on the
+fly CRC check for incoming packets. Packets with invalid checksum are
+discarded as required by the spec. If you also implement checks for data
+PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING
+in usbconfig.h for more info), this ensures data integrity. Due to the CRC
+tables and alignment requirements, this code is bigger than modules for other
+clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1
+and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h.
+
+20 MHz Clock
+This module is for people who won't do it with less than the maximum. Since
+20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code
+uses similar tricks as the 16 MHz module to insert leap cycles.
+
+
+USB IDENTIFIERS
+===============
+Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs
+are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you
+can assign PIDs at will.
+
+Since an entry level cost of 1,500 USD is too high for most small companies
+and hobbyists, we provide some VID/PID pairs for free. See the file
+USB-IDs-for-free.txt for details.
+
+Objective Development also has some license offerings which include product
+IDs. See http://www.obdev.at/vusb/ for details.
+
+
+DEVELOPMENT SYSTEM
+==================
+This driver has been developed and optimized for the GNU compiler version 3
+(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
+that you use the GNU compiler suite because it is freely available. V-USB
+has also been ported to the IAR compiler and assembler. It has been tested
+with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
+memory model. Not every release is tested with IAR CC and the driver may
+therefore fail to compile with IAR. Please note that gcc is more efficient for
+usbdrv.c because this module has been deliberately optimized for gcc.
+
+
+USING V-USB FOR FREE
+====================
+The AVR firmware driver is published under the GNU General Public License
+Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is
+your choice whether you apply the terms of version 2 or version 3.
+
+If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the
+following things IN ADDITION to the obligations from the GPL:
+
+(1) Publish your entire project on a web site and drop us a note with the URL.
+Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
+If you don't have a web site, you can publish the project in obdev's
+documentation wiki at
+http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects.
+
+(2) Adhere to minimum publication standards. Please include AT LEAST:
+ - a circuit diagram in PDF, PNG or GIF format
+ - full source code for the host software
+ - a Readme.txt file in ASCII format which describes the purpose of the
+ project and what can be found in which directories and which files
+ - a reference to http://www.obdev.at/vusb/
+
+(3) If you improve the driver firmware itself, please give us a free license
+to your modifications for our commercial license offerings.
+
+
+COMMERCIAL LICENSES FOR V-USB
+=============================
+If you don't want to publish your source code under the terms of the GPL,
+you can simply pay money for V-USB. As an additional benefit you get
+USB PIDs for free, reserved exclusively to you. See the file
+"CommercialLicense.txt" for details.
+
diff --git a/usbdrv/USB-ID-FAQ.txt b/usbdrv/USB-ID-FAQ.txt
new file mode 100644
index 0000000..d1de8fb
--- /dev/null
+++ b/usbdrv/USB-ID-FAQ.txt
@@ -0,0 +1,149 @@
+Version 2009-08-22
+
+==========================
+WHY DO WE NEED THESE IDs?
+==========================
+
+USB is more than a low level protocol for data transport. It also defines a
+common set of requests which must be understood by all devices. And as part
+of these common requests, the specification defines data structures, the
+USB Descriptors, which are used to describe the properties of the device.
+
+From the perspective of an operating system, it is therefore possible to find
+out basic properties of a device (such as e.g. the manufacturer and the name
+of the device) without a device-specific driver. This is essential because
+the operating system can choose a driver to load based on this information
+(Plug-And-Play).
+
+Among the most important properties in the Device Descriptor are the USB
+Vendor- and Product-ID. Both are 16 bit integers. The most simple form of
+driver matching is based on these IDs. The driver announces the Vendor- and
+Product-IDs of the devices it can handle and the operating system loads the
+appropriate driver when the device is connected.
+
+It is obvious that this technique only works if the pair Vendor- plus
+Product-ID is unique: Only devices which require the same driver can have the
+same pair of IDs.
+
+
+=====================================================
+HOW DOES THE USB STANDARD ENSURE THAT IDs ARE UNIQUE?
+=====================================================
+
+Since it is so important that USB IDs are unique, the USB Implementers Forum,
+Inc. (usb.org) needs a way to enforce this legally. It is not forbidden by
+law to build a device and assign it any random numbers as IDs. Usb.org
+therefore needs an agreement to regulate the use of USB IDs. The agreement
+binds only parties who agreed to it, of course. Everybody else is free to use
+any numbers for their IDs.
+
+So how can usb.org ensure that every manufacturer of USB devices enters into
+an agreement with them? They do it via trademark licensing. Usb.org has
+registered the trademark "USB", all associated logos and related terms. If
+you want to put an USB logo on your product or claim that it is USB
+compliant, you must license these trademarks from usb.org. And this is where
+you enter into an agreement. See the "USB-IF Trademark License Agreement and
+Usage Guidelines for the USB-IF Logo" at
+http://www.usb.org/developers/logo_license/.
+
+Licensing the USB trademarks requires that you buy a USB Vendor-ID from
+usb.org (one-time fee of ca. 2,000 USD), that you become a member of usb.org
+(yearly fee of ca. 4,000 USD) and that you meet all the technical
+specifications from the USB spec.
+
+This means that most hobbyists and small companies will never be able to
+become USB compliant, just because membership is so expensive. And you can't
+be compliant with a driver based on V-USB anyway, because the AVR's port pins
+don't meet the electrical specifications for USB. So, in principle, all
+hobbyists and small companies are free to choose any random numbers for their
+IDs. They have nothing to lose...
+
+There is one exception worth noting, though: If you use a sub-component which
+implements USB, the vendor of the sub-components may guarantee USB
+compliance. This might apply to some or all of FTDI's solutions.
+
+
+=======================================================================
+WHY SHOULD YOU OBTAIN USB IDs EVEN IF YOU DON'T LICENSE USB TRADEMARKS?
+=======================================================================
+
+You have learned in the previous section that you are free to choose any
+numbers for your IDs anyway. So why not do exactly this? There is still the
+technical issue. If you choose IDs which are already in use by somebody else,
+operating systems will load the wrong drivers and your device won't work.
+Even if you choose IDs which are not currently in use, they may be in use in
+the next version of the operating system or even after an automatic update.
+
+So what you need is a pair of Vendor- and Product-IDs for which you have the
+guarantee that no USB compliant product uses them. This implies that no
+operating system will ever ship with drivers responsible for these IDs.
+
+
+==============================================
+HOW DOES OBJECTIVE DEVELOPMENT HANDLE USB IDs?
+==============================================
+
+Objective Development gives away pairs of USB-IDs with their V-USB licenses.
+In order to ensure that these IDs are unique, Objective Development has an
+agreement with the company/person who has bought the USB Vendor-ID from
+usb.org. This agreement ensures that a range of USB Product-IDs is reserved
+for assignment by Objective Development and that the owner of the Vendor-ID
+won't give it to anybody else.
+
+This means that you have to trust three parties to ensure uniqueness of
+your IDs:
+
+ - Objective Development, that they don't give the same PID to more than
+ one person.
+ - The owner of the Vendor-ID that they don't assign PIDs from the range
+ assigned to Objective Development to anybody else.
+ - Usb.org that they don't assign the same Vendor-ID a second time.
+
+
+==================================
+WHO IS THE OWNER OF THE VENDOR-ID?
+==================================
+
+Objective Development has obtained ranges of USB Product-IDs under two
+Vendor-IDs: Under Vendor-ID 5824 from Wouter van Ooijen (Van Ooijen
+Technische Informatica, www.voti.nl) and under Vendor-ID 8352 from Jason
+Kotzin (Clay Logic, www.claylogic.com). Both VID owners have received their
+Vendor-ID directly from usb.org.
+
+
+=========================================================================
+CAN I USE USB-IDs FROM OBJECTIVE DEVELOPMENT WITH OTHER DRIVERS/HARDWARE?
+=========================================================================
+
+The short answer is: Yes. All you get is a guarantee that the IDs are never
+assigned to anybody else. What more do you need?
+
+
+============================
+WHAT ABOUT SHARED ID PAIRS?
+============================
+
+Objective Development has reserved some PID/VID pairs for shared use. You
+have no guarantee of uniqueness for them, except that no USB compliant device
+uses them. In order to avoid technical problems, we must ensure that all
+devices with the same pair of IDs use the same driver on kernel level. For
+details, see the file USB-IDs-for-free.txt.
+
+
+======================================================
+I HAVE HEARD THAT SUB-LICENSING OF USB-IDs IS ILLEGAL?
+======================================================
+
+A 16 bit integer number cannot be protected by copyright laws. It is not
+sufficiently complex. And since none of the parties involved entered into the
+USB-IF Trademark License Agreement, we are not bound by this agreement. So
+there is no reason why it should be illegal to sub-license USB-IDs.
+
+
+=============================================
+WHO IS LIABLE IF THERE ARE INCOMPATIBILITIES?
+=============================================
+
+Objective Development disclaims all liabilities which might arise from the
+assignment of IDs. If you guarantee product features to your customers
+without proper disclaimer, YOU are liable for that.
diff --git a/usbdrv/USB-IDs-for-free.txt b/usbdrv/USB-IDs-for-free.txt
new file mode 100644
index 0000000..2f4d59a
--- /dev/null
+++ b/usbdrv/USB-IDs-for-free.txt
@@ -0,0 +1,148 @@
+Version 2009-08-22
+
+===========================
+FREE USB-IDs FOR SHARED USE
+===========================
+
+Objective Development has reserved a set of USB Product-IDs for use according
+to the guidelines outlined below. For more information about the concept of
+USB IDs please see the file USB-ID-FAQ.txt. Objective Development guarantees
+that the IDs listed below are not used by any USB compliant devices.
+
+
+====================
+MECHANISM OF SHARING
+====================
+
+From a technical point of view, two different devices can share the same USB
+Vendor- and Product-ID if they require the same driver on operating system
+level. We make use of this fact by assigning separate IDs for various device
+classes. On application layer, devices must be distinguished by their textual
+name or serial number. We offer separate sets of IDs for discrimination by
+textual name and for serial number.
+
+Examples for shared use of USB IDs are included with V-USB in the "examples"
+subdirectory.
+
+
+======================================
+IDs FOR DISCRIMINATION BY TEXTUAL NAME
+======================================
+
+If you use one of the IDs listed below, your device and host-side software
+must conform to these rules:
+
+(1) The USB device MUST provide a textual representation of the manufacturer
+and product identification. The manufacturer identification MUST be available
+at least in USB language 0x0409 (English/US).
+
+(2) The textual manufacturer identification MUST contain either an Internet
+domain name (e.g. "mycompany.com") registered and owned by you, or an e-mail
+address under your control (e.g. "myname@gmx.net"). You can embed the domain
+name or e-mail address in any string you like, e.g. "Objective Development
+http://www.obdev.at/vusb/".
+
+(3) You are responsible for retaining ownership of the domain or e-mail
+address for as long as any of your products are in use.
+
+(4) You may choose any string for the textual product identification, as long
+as this string is unique within the scope of your textual manufacturer
+identification.
+
+(5) Application side device look-up MUST be based on the textual manufacturer
+and product identification in addition to VID/PID matching. The driver
+matching MUST be a comparison of the entire strings, NOT a sub-string match.
+
+(6) For devices which implement a particular USB device class (e.g. HID), the
+operating system's default class driver MUST be used. If an operating system
+driver for Vendor Class devices is needed, this driver must be libusb or
+libusb-win32 (see http://libusb.org/ and
+http://libusb-win32.sourceforge.net/).
+
+Table if IDs for discrimination by textual name:
+
+PID dec (hex) | VID dec (hex) | Description of use
+==============+===============+============================================
+1500 (0x05dc) | 5824 (0x16c0) | For Vendor Class devices with libusb
+--------------+---------------+--------------------------------------------
+1503 (0x05df) | 5824 (0x16c0) | For generic HID class devices (which are
+ | | NOT mice, keyboards or joysticks)
+--------------+---------------+--------------------------------------------
+1505 (0x05e1) | 5824 (0x16c0) | For CDC-ACM class devices (modems)
+--------------+---------------+--------------------------------------------
+1508 (0x05e4) | 5824 (0x16c0) | For MIDI class devices
+--------------+---------------+--------------------------------------------
+
+Note that Windows caches the textual product- and vendor-description for
+mice, keyboards and joysticks. Name-bsed discrimination is therefore not
+recommended for these device classes.
+
+
+=======================================
+IDs FOR DISCRIMINATION BY SERIAL NUMBER
+=======================================
+
+If you use one of the IDs listed below, your device and host-side software
+must conform to these rules:
+
+(1) The USB device MUST provide a textual representation of the serial
+number. The serial number string MUST be available at least in USB language
+0x0409 (English/US).
+
+(2) The serial number MUST start with either an Internet domain name (e.g.
+"mycompany.com") registered and owned by you, or an e-mail address under your
+control (e.g. "myname@gmx.net"), both terminated with a colon (":") character.
+You MAY append any string you like for further discrimination of your devices.
+
+(3) You are responsible for retaining ownership of the domain or e-mail
+address for as long as any of your products are in use.
+
+(5) Application side device look-up MUST be based on the serial number string
+in addition to VID/PID matching. The matching must start at the first
+character of the serial number string and include the colon character
+terminating your domain or e-mail address. It MAY stop anywhere after that.
+
+(6) For devices which implement a particular USB device class (e.g. HID), the
+operating system's default class driver MUST be used. If an operating system
+driver for Vendor Class devices is needed, this driver must be libusb or
+libusb-win32 (see http://libusb.org/ and
+http://libusb-win32.sourceforge.net/).
+
+Table if IDs for discrimination by serial number string:
+
+PID dec (hex) | VID dec (hex) | Description of use
+===============+===============+===========================================
+10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb
+---------------+---------------+-------------------------------------------
+10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are
+ | | NOT mice, keyboards or joysticks)
+---------------+---------------+-------------------------------------------
+10202 (0x27da) | 5824 (0x16c0) | For USB Mice
+---------------+---------------+-------------------------------------------
+10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards
+---------------+---------------+-------------------------------------------
+10204 (0x27db) | 5824 (0x16c0) | For USB Joysticks
+---------------+---------------+-------------------------------------------
+10205 (0x27dc) | 5824 (0x16c0) | For CDC-ACM class devices (modems)
+---------------+---------------+-------------------------------------------
+10206 (0x27dd) | 5824 (0x16c0) | For MIDI class devices
+---------------+---------------+-------------------------------------------
+
+
+=================
+ORIGIN OF USB-IDs
+=================
+
+OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed
+here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition.
+Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc.
+(see www.usb.org). The VID is registered for the company name "Van Ooijen
+Technische Informatica".
+
+
+==========
+DISCLAIMER
+==========
+
+OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any
+problems which are caused by the shared use of these VID/PID pairs.
diff --git a/usbdrv/USBID-License.txt b/usbdrv/USBID-License.txt
new file mode 100644
index 0000000..c40be92
--- /dev/null
+++ b/usbdrv/USBID-License.txt
@@ -0,0 +1,154 @@
+Royalty-Free Non-Exclusive Use of USB Product-IDs
+=================================================
+
+Version 2009-04-13
+
+Strictly speaking, this is not a license. You can't give a license to use
+a simple number (such as e.g. 1500) for any purpose. This is a set of rules
+which should make it possible to build USB devices without the requirement
+for individual USB IDs. If you break one of the rules, you will run into
+technical problems sooner or later, but you don't risk legal trouble.
+
+
+OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive
+right to use four USB.org vendor-ID (VID) / product-ID (PID) pairs with
+products based on Objective Development's firmware-only USB driver for
+Atmel AVR microcontrollers:
+
+ * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no
+ USB device class (vendor-class devices with USB class = 0xff). Devices
+ using this pair will be referred to as "VENDOR CLASS" devices.
+
+ * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices
+ (excluding mice and keyboards). Devices using this pair will be referred
+ to as "HID CLASS" devices.
+
+ * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices
+ Devices using this pair will be referred to as "CDC-ACM CLASS" devices.
+
+ * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices
+ Devices using this pair will be referred to as "MIDI CLASS" devices.
+
+Since the granted right is non-exclusive, the same VID/PID pairs may be
+used by many companies and individuals for different products. To avoid
+conflicts, your device and host driver software MUST adhere to the rules
+outlined below.
+
+OBJECTIVE DEVELOPMENT Software GmbH has obtained these VID/PID pairs from
+Wouter van Ooijen (see www.voti.nl) for exclusive disposition. Wouter van
+Ooijen has obtained the VID from the USB Implementers Forum, Inc.
+(see www.usb.org). The VID is registered for the company name
+"Van Ooijen Technische Informatica".
+
+
+RULES AND RESTRICTIONS
+======================
+
+(1) The USB device MUST provide a textual representation of the
+manufacturer and product identification. The manufacturer identification
+MUST be available at least in USB language 0x0409 (English/US).
+
+(2) The textual manufacturer identification MUST contain either an Internet
+domain name (e.g. "mycompany.com") registered and owned by you, or an
+e-mail address under your control (e.g. "myname@gmx.net"). You can embed
+the domain name or e-mail address in any string you like, e.g. "Objective
+Development http://www.obdev.at/vusb/".
+
+(3) You are responsible for retaining ownership of the domain or e-mail
+address for as long as any of your products are in use.
+
+(4) You may choose any string for the textual product identification, as
+long as this string is unique within the scope of your textual manufacturer
+identification.
+
+(5) Matching of device-specific drivers MUST be based on the textual
+manufacturer and product identification in addition to the usual VID/PID
+matching. This means that operating system features which are based on
+VID/PID matching only (e.g. Windows kernel level drivers, automatic actions
+when the device is plugged in etc) MUST NOT be used. The driver matching
+MUST be a comparison of the entire strings, NOT a sub-string match. For
+CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used
+and the matching is based on the USB device class.
+
+(6) The extent to which VID/PID matching is allowed for non device-specific
+drivers or features depends on the operating system and particular VID/PID
+pair used:
+
+ * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is
+ required and hence no VID/PID-only matching is allowed at all.
+
+ * Windows: The operating system performs VID/PID matching for the kernel
+ level driver. You are REQUIRED to use libusb-win32 (see
+ http://libusb-win32.sourceforge.net/) as the kernel level driver for
+ VENDOR CLASS devices. HID CLASS devices all use the generic HID class
+ driver shipped with Windows, except mice and keyboards. You therefore
+ MUST NOT use any of the shared VID/PID pairs for mice or keyboards.
+ CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID
+ pair. This ".inf" file MUST load the "usbser" driver to configure the
+ device as modem (COM-port).
+
+(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any
+problems which are caused by the shared use of these VID/PID pairs. You
+have been warned that the sharing of VID/PID pairs may cause problems. If
+you want to avoid them, get your own VID/PID pair for exclusive use.
+
+
+HOW TO IMPLEMENT THESE RULES
+============================
+
+The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM
+CLASS and MIDI CLASS devices use the operating system's class driver and
+don't need a custom driver.
+
+The host driver MUST iterate over all devices with the given VID/PID
+numbers in their device descriptors and query the string representation for
+the manufacturer name in USB language 0x0409 (English/US). It MUST compare
+the ENTIRE string with your textual manufacturer identification chosen in
+(2) above. A substring search for your domain or e-mail address is NOT
+acceptable. The driver MUST NOT touch the device (other than querying the
+descriptors) unless the strings match.
+
+For all USB devices with matching VID/PID and textual manufacturer
+identification, the host driver must query the textual product
+identification and string-compare it with the name of the product it can
+control. It may only initialize the device if the product matches exactly.
+
+Objective Development provides examples for these matching rules with the
+"PowerSwitch" project (using libusb) and with the "Automator" project
+(using Windows calls on Windows and libusb on Unix).
+
+
+Technical Notes:
+================
+
+Sharing the same VID/PID pair among devices is possible as long as ALL
+drivers which match the VID/PID also perform matching on the textual
+identification strings. This is easy on all operating systems except
+Windows, since Windows establishes a static connection between the VID/PID
+pair and a kernel level driver. All devices with the same VID/PID pair must
+therefore use THE SAME kernel level driver.
+
+We therefore demand that you use libusb-win32 for VENDOR CLASS devices.
+This is a generic kernel level driver which allows all types of USB access
+for user space applications. This is only a partial solution of the
+problem, though, because different device drivers may come with different
+versions of libusb-win32 and they may not work with the libusb version of
+the respective other driver. You are therefore encouraged to test your
+driver against a broad range of libusb-win32 versions. Do not use new
+features in new versions, or check for their existence before you use them.
+When a new libusb-win32 becomes available, make sure that your driver is
+compatible with it.
+
+For HID CLASS devices it is necessary that all those devices bind to the
+same kernel driver: Microsoft's generic USB HID driver. This is true for
+all HID devices except those with a specialized driver. Currently, the only
+HIDs with specialized drivers are mice and keyboards. You therefore MUST
+NOT use a shared VID/PID with mouse and keyboard devices.
+
+Sharing the same VID/PID among different products is unusual and probably
+violates the USB specification. If you do it, you do it at your own risk.
+
+To avoid possible incompatibilities, we highly recommend that you get your
+own VID/PID pair if you intend to sell your product. Objective
+Development's commercial licenses for V-USB include a PID for
+unrestricted exclusive use.
diff --git a/usbdrv/asmcommon.inc b/usbdrv/asmcommon.inc
new file mode 100644
index 0000000..07d692b
--- /dev/null
+++ b/usbdrv/asmcommon.inc
@@ -0,0 +1,188 @@
+/* Name: asmcommon.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2007-11-05
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id$
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file contains assembler code which is shared among the USB driver
+implementations for different CPU cocks. Since the code must be inserted
+in the middle of the module, it's split out into this file and #included.
+
+Jump destinations called from outside:
+ sofError: Called when no start sequence was found.
+ se0: Called when a package has been successfully received.
+ overflow: Called when receive buffer overflows.
+ doReturn: Called after sending data.
+
+Outside jump destinations used by this module:
+ waitForJ: Called to receive an already arriving packet.
+ sendAckAndReti:
+ sendNakAndReti:
+ sendCntAndReti:
+ usbSendAndReti:
+
+The following macros must be defined before this file is included:
+ .macro POP_STANDARD
+ .endm
+ .macro POP_RETI
+ .endm
+*/
+
+#define token x1
+
+overflow:
+ ldi x2, 1<<USB_INTR_PENDING_BIT
+ USB_STORE_PENDING(x2) ; clear any pending interrupts
+ignorePacket:
+ clr token
+ rjmp storeTokenAndReturn
+
+;----------------------------------------------------------------------------
+; Processing of received packet (numbers in brackets are cycles after center of SE0)
+;----------------------------------------------------------------------------
+;This is the only non-error exit point for the software receiver loop
+;we don't check any CRCs here because there is no time left.
+se0:
+ subi cnt, USB_BUFSIZE ;[5]
+ neg cnt ;[6]
+ sub YL, cnt ;[7]
+ sbci YH, 0 ;[8]
+ ldi x2, 1<<USB_INTR_PENDING_BIT ;[9]
+ USB_STORE_PENDING(x2) ;[10] clear pending intr and check flag later. SE0 should be over.
+ ld token, y ;[11]
+ cpi token, USBPID_DATA0 ;[13]
+ breq handleData ;[14]
+ cpi token, USBPID_DATA1 ;[15]
+ breq handleData ;[16]
+ lds shift, usbDeviceAddr;[17]
+ ldd x2, y+1 ;[19] ADDR and 1 bit endpoint number
+ lsl x2 ;[21] shift out 1 bit endpoint number
+ cpse x2, shift ;[22]
+ rjmp ignorePacket ;[23]
+/* only compute endpoint number in x3 if required later */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT || USB_CFG_IMPLEMENT_FN_WRITEOUT
+ ldd x3, y+2 ;[24] endpoint number + crc
+ rol x3 ;[26] shift in LSB of endpoint
+#endif
+ cpi token, USBPID_IN ;[27]
+ breq handleIn ;[28]
+ cpi token, USBPID_SETUP ;[29]
+ breq handleSetupOrOut ;[30]
+ cpi token, USBPID_OUT ;[31]
+ brne ignorePacket ;[32] must be ack, nak or whatever
+; rjmp handleSetupOrOut ; fallthrough
+
+;Setup and Out are followed by a data packet two bit times (16 cycles) after
+;the end of SE0. The sync code allows up to 40 cycles delay from the start of
+;the sync pattern until the first bit is sampled. That's a total of 56 cycles.
+handleSetupOrOut: ;[32]
+#if USB_CFG_IMPLEMENT_FN_WRITEOUT /* if we have data for endpoint != 0, set usbCurrentTok to address */
+ andi x3, 0xf ;[32]
+ breq storeTokenAndReturn ;[33]
+ mov token, x3 ;[34] indicate that this is endpoint x OUT
+#endif
+storeTokenAndReturn:
+ sts usbCurrentTok, token;[35]
+doReturn:
+ POP_STANDARD ;[37] 12...16 cycles
+ USB_LOAD_PENDING(YL) ;[49]
+ sbrc YL, USB_INTR_PENDING_BIT;[50] check whether data is already arriving
+ rjmp waitForJ ;[51] save the pops and pushes -- a new interrupt is already pending
+sofError:
+ POP_RETI ;macro call
+ reti
+
+handleData:
+#if USB_CFG_CHECK_CRC
+ CRC_CLEANUP_AND_CHECK ; jumps to ignorePacket if CRC error
+#endif
+ lds shift, usbCurrentTok;[18]
+ tst shift ;[20]
+ breq doReturn ;[21]
+ lds x2, usbRxLen ;[22]
+ tst x2 ;[24]
+ brne sendNakAndReti ;[25]
+; 2006-03-11: The following two lines fix a problem where the device was not
+; recognized if usbPoll() was called less frequently than once every 4 ms.
+ cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack
+ brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
+#if USB_CFG_CHECK_DATA_TOGGLING
+ sts usbCurrentDataToken, token ; store for checking by C code
+#endif
+ sts usbRxLen, cnt ;[28] store received data, swap buffers
+ sts usbRxToken, shift ;[30]
+ lds x2, usbInputBufOffset;[32] swap buffers
+ ldi cnt, USB_BUFSIZE ;[34]
+ sub cnt, x2 ;[35]
+ sts usbInputBufOffset, cnt;[36] buffers now swapped
+ rjmp sendAckAndReti ;[38] 40 + 17 = 57 until SOP
+
+handleIn:
+;We don't send any data as long as the C code has not processed the current
+;input data and potentially updated the output data. That's more efficient
+;in terms of code size than clearing the tx buffers when a packet is received.
+ lds x1, usbRxLen ;[30]
+ cpi x1, 1 ;[32] negative values are flow control, 0 means "buffer free"
+ brge sendNakAndReti ;[33] unprocessed input packet?
+ ldi x1, USBPID_NAK ;[34] prepare value for usbTxLen
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+ andi x3, 0xf ;[35] x3 contains endpoint
+#if USB_CFG_SUPPRESS_INTR_CODE
+ brne sendNakAndReti ;[36]
+#else
+ brne handleIn1 ;[36]
+#endif
+#endif
+ lds cnt, usbTxLen ;[37]
+ sbrc cnt, 4 ;[39] all handshake tokens have bit 4 set
+ rjmp sendCntAndReti ;[40] 42 + 16 = 58 until SOP
+ sts usbTxLen, x1 ;[41] x1 == USBPID_NAK from above
+ ldi YL, lo8(usbTxBuf) ;[43]
+ ldi YH, hi8(usbTxBuf) ;[44]
+ rjmp usbSendAndReti ;[45] 57 + 12 = 59 until SOP
+
+; Comment about when to set usbTxLen to USBPID_NAK:
+; We should set it back when we receive the ACK from the host. This would
+; be simple to implement: One static variable which stores whether the last
+; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the
+; ACK. However, we set it back immediately when we send the package,
+; assuming that no error occurs and the host sends an ACK. We save one byte
+; RAM this way and avoid potential problems with endless retries. The rest of
+; the driver assumes error-free transfers anyway.
+
+#if !USB_CFG_SUPPRESS_INTR_CODE && USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */
+handleIn1: ;[38]
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint
+ cpi x3, USB_CFG_EP3_NUMBER;[38]
+ breq handleIn3 ;[39]
+#endif
+ lds cnt, usbTxLen1 ;[40]
+ sbrc cnt, 4 ;[42] all handshake tokens have bit 4 set
+ rjmp sendCntAndReti ;[43] 47 + 16 = 63 until SOP
+ sts usbTxLen1, x1 ;[44] x1 == USBPID_NAK from above
+ ldi YL, lo8(usbTxBuf1) ;[46]
+ ldi YH, hi8(usbTxBuf1) ;[47]
+ rjmp usbSendAndReti ;[48] 50 + 12 = 62 until SOP
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+handleIn3:
+ lds cnt, usbTxLen3 ;[41]
+ sbrc cnt, 4 ;[43]
+ rjmp sendCntAndReti ;[44] 49 + 16 = 65 until SOP
+ sts usbTxLen3, x1 ;[45] x1 == USBPID_NAK from above
+ ldi YL, lo8(usbTxBuf3) ;[47]
+ ldi YH, hi8(usbTxBuf3) ;[48]
+ rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP
+#endif
+#endif
diff --git a/usbdrv/oddebug.c b/usbdrv/oddebug.c
new file mode 100644
index 0000000..945457c
--- /dev/null
+++ b/usbdrv/oddebug.c
@@ -0,0 +1,50 @@
+/* Name: oddebug.c
+ * Project: AVR library
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-01-16
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: oddebug.c 692 2008-11-07 15:07:40Z cs $
+ */
+
+#include "oddebug.h"
+
+#if DEBUG_LEVEL > 0
+
+#warning "Never compile production devices with debugging enabled"
+
+static void uartPutc(char c)
+{
+ while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
+ ODDBG_UDR = c;
+}
+
+static uchar hexAscii(uchar h)
+{
+ h &= 0xf;
+ if(h >= 10)
+ h += 'a' - (uchar)10 - '0';
+ h += '0';
+ return h;
+}
+
+static void printHex(uchar c)
+{
+ uartPutc(hexAscii(c >> 4));
+ uartPutc(hexAscii(c));
+}
+
+void odDebug(uchar prefix, uchar *data, uchar len)
+{
+ printHex(prefix);
+ uartPutc(':');
+ while(len--){
+ uartPutc(' ');
+ printHex(*data++);
+ }
+ uartPutc('\r');
+ uartPutc('\n');
+}
+
+#endif
diff --git a/usbdrv/oddebug.h b/usbdrv/oddebug.h
new file mode 100644
index 0000000..d61309d
--- /dev/null
+++ b/usbdrv/oddebug.h
@@ -0,0 +1,123 @@
+/* Name: oddebug.h
+ * Project: AVR library
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-01-16
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $
+ */
+
+#ifndef __oddebug_h_included__
+#define __oddebug_h_included__
+
+/*
+General Description:
+This module implements a function for debug logs on the serial line of the
+AVR microcontroller. Debugging can be configured with the define
+'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging
+calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is
+2, DBG1 and DBG2 logs will be printed.
+
+A debug log consists of a label ('prefix') to indicate which debug log created
+the output and a memory block to dump in hex ('data' and 'len').
+*/
+
+
+#ifndef F_CPU
+# define F_CPU 12000000 /* 12 MHz */
+#endif
+
+/* make sure we have the UART defines: */
+#include "usbportability.h"
+
+#ifndef uchar
+# define uchar unsigned char
+#endif
+
+#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */
+# warning "Debugging disabled because device has no UART"
+# undef DEBUG_LEVEL
+#endif
+
+#ifndef DEBUG_LEVEL
+# define DEBUG_LEVEL 0
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#if DEBUG_LEVEL > 0
+# define DBG1(prefix, data, len) odDebug(prefix, data, len)
+#else
+# define DBG1(prefix, data, len)
+#endif
+
+#if DEBUG_LEVEL > 1
+# define DBG2(prefix, data, len) odDebug(prefix, data, len)
+#else
+# define DBG2(prefix, data, len)
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#if DEBUG_LEVEL > 0
+extern void odDebug(uchar prefix, uchar *data, uchar len);
+
+/* Try to find our control registers; ATMEL likes to rename these */
+
+#if defined UBRR
+# define ODDBG_UBRR UBRR
+#elif defined UBRRL
+# define ODDBG_UBRR UBRRL
+#elif defined UBRR0
+# define ODDBG_UBRR UBRR0
+#elif defined UBRR0L
+# define ODDBG_UBRR UBRR0L
+#endif
+
+#if defined UCR
+# define ODDBG_UCR UCR
+#elif defined UCSRB
+# define ODDBG_UCR UCSRB
+#elif defined UCSR0B
+# define ODDBG_UCR UCSR0B
+#endif
+
+#if defined TXEN
+# define ODDBG_TXEN TXEN
+#else
+# define ODDBG_TXEN TXEN0
+#endif
+
+#if defined USR
+# define ODDBG_USR USR
+#elif defined UCSRA
+# define ODDBG_USR UCSRA
+#elif defined UCSR0A
+# define ODDBG_USR UCSR0A
+#endif
+
+#if defined UDRE
+# define ODDBG_UDRE UDRE
+#else
+# define ODDBG_UDRE UDRE0
+#endif
+
+#if defined UDR
+# define ODDBG_UDR UDR
+#elif defined UDR0
+# define ODDBG_UDR UDR0
+#endif
+
+static inline void odDebugInit(void)
+{
+ ODDBG_UCR |= (1<<ODDBG_TXEN);
+ ODDBG_UBRR = F_CPU / (19200 * 16L) - 1;
+}
+#else
+# define odDebugInit()
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* __oddebug_h_included__ */
diff --git a/usbdrv/usbconfig-prototype.h b/usbdrv/usbconfig-prototype.h
new file mode 100644
index 0000000..a0fd1bf
--- /dev/null
+++ b/usbdrv/usbconfig-prototype.h
@@ -0,0 +1,369 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 767 2009-08-22 11:39:22Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
++ To create your own usbconfig.h file, copy this file to your project's
++ firmware source directory) and rename it to "usbconfig.h".
++ Then edit it accordingly.
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 4
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
+ * crystal, they tolerate +/- 1% deviation from the nominal frequency. All
+ * other rates require a precision of 2000 ppm and thus a crystal!
+ * Default if not specified: 12 MHz
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 10
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 100
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 0
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF 0
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x05dc = 1500 */
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, 0x01
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't'
+#define USB_CFG_VENDOR_NAME_LEN 8
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
+#define USB_CFG_DEVICE_NAME_LEN 8
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USB-IDs-for-free.txt before you assign a name if
+ * you use a shared VID/PID.
+ */
+/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
+/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
+#define USB_CFG_INTERFACE_SUBCLASS 0
+#define USB_CFG_INTERFACE_PROTOCOL 0
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
+
+#endif /* __usbconfig_h_included__ */
diff --git a/usbdrv/usbdrv.c b/usbdrv/usbdrv.c
new file mode 100644
index 0000000..d00fdca
--- /dev/null
+++ b/usbdrv/usbdrv.c
@@ -0,0 +1,625 @@
+/* Name: usbdrv.c
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbdrv.c 763 2009-08-22 10:27:24Z cs $
+ */
+
+#include "usbportability.h"
+#include "usbdrv.h"
+#include "oddebug.h"
+
+/*
+General Description:
+This module implements the C-part of the USB driver. See usbdrv.h for a
+documentation of the entire driver.
+*/
+
+/* ------------------------------------------------------------------------- */
+
+/* raw USB registers / interface to assembler code: */
+uchar usbRxBuf[2*USB_BUFSIZE]; /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */
+uchar usbInputBufOffset; /* offset in usbRxBuf used for low level receiving */
+uchar usbDeviceAddr; /* assigned during enumeration, defaults to 0 */
+uchar usbNewDeviceAddr; /* device ID which should be set after status phase */
+uchar usbConfiguration; /* currently selected configuration. Administered by driver, but not used */
+volatile schar usbRxLen; /* = 0; number of bytes in usbRxBuf; 0 means free, -1 for flow control */
+uchar usbCurrentTok; /* last token received or endpoint number for last OUT token if != 0 */
+uchar usbRxToken; /* token for data we received; or endpont number for last OUT */
+volatile uchar usbTxLen = USBPID_NAK; /* number of bytes to transmit with next IN token or handshake token */
+uchar usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen contains handshake token */
+#if USB_COUNT_SOF
+volatile uchar usbSofCount; /* incremented by assembler module every SOF */
+#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
+usbTxStatus_t usbTxStatus1;
+# if USB_CFG_HAVE_INTRIN_ENDPOINT3
+usbTxStatus_t usbTxStatus3;
+# endif
+#endif
+#if USB_CFG_CHECK_DATA_TOGGLING
+uchar usbCurrentDataToken;/* when we check data toggling to ignore duplicate packets */
+#endif
+
+/* USB status registers / not shared with asm code */
+uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */
+static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */
+static uchar usbMsgFlags; /* flag values see below */
+
+#define USB_FLG_MSGPTR_IS_ROM (1<<6)
+#define USB_FLG_USE_USER_RW (1<<7)
+
+/*
+optimizing hints:
+- do not post/pre inc/dec integer values in operations
+- assign value of USB_READ_FLASH() to register variables and don't use side effects in arg
+- use narrow scope for variables which should be in X/Y/Z register
+- assign char sized expressions to variables to force 8 bit arithmetics
+*/
+
+/* -------------------------- String Descriptors --------------------------- */
+
+#if USB_CFG_DESCR_PROPS_STRINGS == 0
+
+#if USB_CFG_DESCR_PROPS_STRING_0 == 0
+#undef USB_CFG_DESCR_PROPS_STRING_0
+#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
+PROGMEM char usbDescriptorString0[] = { /* language descriptor */
+ 4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
+ 3, /* descriptor type */
+ 0x09, 0x04, /* language index (0x0409 = US-English) */
+};
+#endif
+
+#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
+#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
+PROGMEM int usbDescriptorStringVendor[] = {
+ USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
+ USB_CFG_VENDOR_NAME
+};
+#endif
+
+#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
+#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
+PROGMEM int usbDescriptorStringDevice[] = {
+ USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
+ USB_CFG_DEVICE_NAME
+};
+#endif
+
+#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN
+#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber)
+PROGMEM int usbDescriptorStringSerialNumber[] = {
+ USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN),
+ USB_CFG_SERIAL_NUMBER
+};
+#endif
+
+#endif /* USB_CFG_DESCR_PROPS_STRINGS == 0 */
+
+/* --------------------------- Device Descriptor --------------------------- */
+
+#if USB_CFG_DESCR_PROPS_DEVICE == 0
+#undef USB_CFG_DESCR_PROPS_DEVICE
+#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
+PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
+ 18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
+ USBDESCR_DEVICE, /* descriptor type */
+ 0x10, 0x01, /* USB version supported */
+ USB_CFG_DEVICE_CLASS,
+ USB_CFG_DEVICE_SUBCLASS,
+ 0, /* protocol */
+ 8, /* max packet size */
+ /* the following two casts affect the first byte of the constant only, but
+ * that's sufficient to avoid a warning with the default values.
+ */
+ (char)USB_CFG_VENDOR_ID,/* 2 bytes */
+ (char)USB_CFG_DEVICE_ID,/* 2 bytes */
+ USB_CFG_DEVICE_VERSION, /* 2 bytes */
+ USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0, /* manufacturer string index */
+ USB_CFG_DESCR_PROPS_STRING_PRODUCT != 0 ? 2 : 0, /* product string index */
+ USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0, /* serial number string index */
+ 1, /* number of configurations */
+};
+#endif
+
+/* ----------------------- Configuration Descriptor ------------------------ */
+
+#if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0
+#undef USB_CFG_DESCR_PROPS_HID
+#define USB_CFG_DESCR_PROPS_HID 9 /* length of HID descriptor in config descriptor below */
+#endif
+
+#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0
+#undef USB_CFG_DESCR_PROPS_CONFIGURATION
+#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration)
+PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
+ 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
+ USBDESCR_CONFIG, /* descriptor type */
+ 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
+ (USB_CFG_DESCR_PROPS_HID & 0xff), 0,
+ /* total length of data returned (including inlined descriptors) */
+ 1, /* number of interfaces in this configuration */
+ 1, /* index of this configuration */
+ 0, /* configuration name string index */
+#if USB_CFG_IS_SELF_POWERED
+ (1 << 7) | USBATTR_SELFPOWER, /* attributes */
+#else
+ (1 << 7), /* attributes */
+#endif
+ USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */
+/* interface descriptor follows inline: */
+ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
+ USBDESCR_INTERFACE, /* descriptor type */
+ 0, /* index of this interface */
+ 0, /* alternate setting for this interface */
+ USB_CFG_HAVE_INTRIN_ENDPOINT + USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */
+ USB_CFG_INTERFACE_CLASS,
+ USB_CFG_INTERFACE_SUBCLASS,
+ USB_CFG_INTERFACE_PROTOCOL,
+ 0, /* string index for interface */
+#if (USB_CFG_DESCR_PROPS_HID & 0xff) /* HID descriptor */
+ 9, /* sizeof(usbDescrHID): length of descriptor in bytes */
+ USBDESCR_HID, /* descriptor type: HID */
+ 0x01, 0x01, /* BCD representation of HID version */
+ 0x00, /* target country code */
+ 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */
+ 0x22, /* descriptor type: report */
+ USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0, /* total length of report descriptor */
+#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ (char)0x81, /* IN endpoint number 1 */
+ 0x03, /* attrib: Interrupt endpoint */
+ 8, 0, /* maximum packet size */
+ USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ (char)0x83, /* IN endpoint number 1 */
+ 0x03, /* attrib: Interrupt endpoint */
+ 8, 0, /* maximum packet size */
+ USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
+};
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static inline void usbResetDataToggling(void)
+{
+#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
+ USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
+# if USB_CFG_HAVE_INTRIN_ENDPOINT3
+ USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
+# endif
+#endif
+}
+
+static inline void usbResetStall(void)
+{
+#if USB_CFG_IMPLEMENT_HALT && USB_CFG_HAVE_INTRIN_ENDPOINT
+ usbTxLen1 = USBPID_NAK;
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+ usbTxLen3 = USBPID_NAK;
+#endif
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if !USB_CFG_SUPPRESS_INTR_CODE
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+static void usbGenericSetInterrupt(uchar *data, uchar len, usbTxStatus_t *txStatus)
+{
+uchar *p;
+char i;
+
+#if USB_CFG_IMPLEMENT_HALT
+ if(usbTxLen1 == USBPID_STALL)
+ return;
+#endif
+ if(txStatus->len & 0x10){ /* packet buffer was empty */
+ txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */
+ }else{
+ txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */
+ }
+ p = txStatus->buffer + 1;
+ i = len;
+ do{ /* if len == 0, we still copy 1 byte, but that's no problem */
+ *p++ = *data++;
+ }while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */
+ usbCrc16Append(&txStatus->buffer[1], len);
+ txStatus->len = len + 4; /* len must be given including sync byte */
+ DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3);
+}
+
+USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len)
+{
+ usbGenericSetInterrupt(data, len, &usbTxStatus1);
+}
+#endif
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
+{
+ usbGenericSetInterrupt(data, len, &usbTxStatus3);
+}
+#endif
+#endif /* USB_CFG_SUPPRESS_INTR_CODE */
+
+/* ------------------ utilities for code following below ------------------- */
+
+/* Use defines for the switch statement so that we can choose between an
+ * if()else if() and a switch/case based implementation. switch() is more
+ * efficient for a LARGE set of sequential choices, if() is better in all other
+ * cases.
+ */
+#if USB_CFG_USE_SWITCH_STATEMENT
+# define SWITCH_START(cmd) switch(cmd){{
+# define SWITCH_CASE(value) }break; case (value):{
+# define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{
+# define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{
+# define SWITCH_DEFAULT }break; default:{
+# define SWITCH_END }}
+#else
+# define SWITCH_START(cmd) {uchar _cmd = cmd; if(0){
+# define SWITCH_CASE(value) }else if(_cmd == (value)){
+# define SWITCH_CASE2(v1,v2) }else if(_cmd == (v1) || _cmd == (v2)){
+# define SWITCH_CASE3(v1,v2,v3) }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){
+# define SWITCH_DEFAULT }else{
+# define SWITCH_END }}
+#endif
+
+#ifndef USB_RX_USER_HOOK
+#define USB_RX_USER_HOOK(data, len)
+#endif
+#ifndef USB_SET_ADDRESS_HOOK
+#define USB_SET_ADDRESS_HOOK()
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* We use if() instead of #if in the macro below because #if can't be used
+ * in macros and the compiler optimizes constant conditions anyway.
+ * This may cause problems with undefined symbols if compiled without
+ * optimizing!
+ */
+#define GET_DESCRIPTOR(cfgProp, staticName) \
+ if(cfgProp){ \
+ if((cfgProp) & USB_PROP_IS_RAM) \
+ flags = 0; \
+ if((cfgProp) & USB_PROP_IS_DYNAMIC){ \
+ len = usbFunctionDescriptor(rq); \
+ }else{ \
+ len = USB_PROP_LENGTH(cfgProp); \
+ usbMsgPtr = (uchar *)(staticName); \
+ } \
+ }
+
+/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used
+ * internally for all types of descriptors.
+ */
+static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq)
+{
+usbMsgLen_t len = 0;
+uchar flags = USB_FLG_MSGPTR_IS_ROM;
+
+ SWITCH_START(rq->wValue.bytes[1])
+ SWITCH_CASE(USBDESCR_DEVICE) /* 1 */
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
+ SWITCH_CASE(USBDESCR_CONFIG) /* 2 */
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration)
+ SWITCH_CASE(USBDESCR_STRING) /* 3 */
+#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC
+ if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM)
+ flags = 0;
+ len = usbFunctionDescriptor(rq);
+#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
+ SWITCH_START(rq->wValue.bytes[0])
+ SWITCH_CASE(0)
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
+ SWITCH_CASE(1)
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor)
+ SWITCH_CASE(2)
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice)
+ SWITCH_CASE(3)
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber)
+ SWITCH_DEFAULT
+ if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
+ len = usbFunctionDescriptor(rq);
+ }
+ SWITCH_END
+#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
+#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */
+ SWITCH_CASE(USBDESCR_HID) /* 0x21 */
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
+ SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */
+ GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
+#endif
+ SWITCH_DEFAULT
+ if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
+ len = usbFunctionDescriptor(rq);
+ }
+ SWITCH_END
+ usbMsgFlags = flags;
+ return len;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for
+ * standard requests instead of class and custom requests.
+ */
+static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
+{
+uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
+uchar value = rq->wValue.bytes[0];
+#if USB_CFG_IMPLEMENT_HALT
+uchar index = rq->wIndex.bytes[0];
+#endif
+
+ dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */
+ SWITCH_START(rq->bRequest)
+ SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */
+ uchar recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */
+ if(USB_CFG_IS_SELF_POWERED && recipient == USBRQ_RCPT_DEVICE)
+ dataPtr[0] = USB_CFG_IS_SELF_POWERED;
+#if USB_CFG_IMPLEMENT_HALT
+ if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */
+ dataPtr[0] = usbTxLen1 == USBPID_STALL;
+#endif
+ dataPtr[1] = 0;
+ len = 2;
+#if USB_CFG_IMPLEMENT_HALT
+ SWITCH_CASE2(USBRQ_CLEAR_FEATURE, USBRQ_SET_FEATURE) /* 1, 3 */
+ if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */
+ usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL;
+ usbResetDataToggling();
+ }
+#endif
+ SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */
+ usbNewDeviceAddr = value;
+ USB_SET_ADDRESS_HOOK();
+ SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */
+ len = usbDriverDescriptor(rq);
+ goto skipMsgPtrAssignment;
+ SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */
+ dataPtr = &usbConfiguration; /* send current configuration value */
+ len = 1;
+ SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */
+ usbConfiguration = value;
+ usbResetStall();
+ SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */
+ len = 1;
+#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
+ SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */
+ usbResetDataToggling();
+ usbResetStall();
+#endif
+ SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
+ /* Should we add an optional hook here? */
+ SWITCH_END
+ usbMsgPtr = dataPtr;
+skipMsgPtrAssignment:
+ return len;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* usbProcessRx() is called for every message received by the interrupt
+ * routine. It distinguishes between SETUP and DATA packets and processes
+ * them accordingly.
+ */
+static inline void usbProcessRx(uchar *data, uchar len)
+{
+usbRequest_t *rq = (void *)data;
+
+/* usbRxToken can be:
+ * 0x2d 00101101 (USBPID_SETUP for setup data)
+ * 0xe1 11100001 (USBPID_OUT: data phase of setup transfer)
+ * 0...0x0f for OUT on endpoint X
+ */
+ DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */
+ USB_RX_USER_HOOK(data, len)
+#if USB_CFG_IMPLEMENT_FN_WRITEOUT
+ if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */
+ usbFunctionWriteOut(data, len);
+ return;
+ }
+#endif
+ if(usbRxToken == (uchar)USBPID_SETUP){
+ if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */
+ return;
+ usbMsgLen_t replyLen;
+ usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */
+ usbTxLen = USBPID_NAK; /* abort pending transmit */
+ usbMsgFlags = 0;
+ uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
+ if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */
+ replyLen = usbFunctionSetup(data);
+ }else{
+ replyLen = usbDriverSetup(rq);
+ }
+#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE
+ if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */
+ /* do some conditioning on replyLen, but on IN transfers only */
+ if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){
+ if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */
+ replyLen = rq->wLength.bytes[0];
+ }else{
+ replyLen = rq->wLength.word;
+ }
+ }
+ usbMsgFlags = USB_FLG_USE_USER_RW;
+ }else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */
+#endif
+ if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */
+ if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */
+ replyLen = rq->wLength.bytes[0];
+ }else{
+ if(replyLen > rq->wLength.word) /* limit length to max */
+ replyLen = rq->wLength.word;
+ }
+ usbMsgLen = replyLen;
+ }else{ /* usbRxToken must be USBPID_OUT, which means data phase of setup (control-out) */
+#if USB_CFG_IMPLEMENT_FN_WRITE
+ if(usbMsgFlags & USB_FLG_USE_USER_RW){
+ uchar rval = usbFunctionWrite(data, len);
+ if(rval == 0xff){ /* an error occurred */
+ usbTxLen = USBPID_STALL;
+ }else if(rval != 0){ /* This was the final package */
+ usbMsgLen = 0; /* answer with a zero-sized data packet */
+ }
+ }
+#endif
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* This function is similar to usbFunctionRead(), but it's also called for
+ * data handled automatically by the driver (e.g. descriptor reads).
+ */
+static uchar usbDeviceRead(uchar *data, uchar len)
+{
+ if(len > 0){ /* don't bother app with 0 sized reads */
+#if USB_CFG_IMPLEMENT_FN_READ
+ if(usbMsgFlags & USB_FLG_USE_USER_RW){
+ len = usbFunctionRead(data, len);
+ }else
+#endif
+ {
+ uchar i = len, *r = usbMsgPtr;
+ if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
+ do{
+ uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
+ *data++ = c;
+ r++;
+ }while(--i);
+ }else{ /* RAM data */
+ do{
+ *data++ = *r++;
+ }while(--i);
+ }
+ usbMsgPtr = r;
+ }
+ }
+ return len;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* usbBuildTxBlock() is called when we have data to transmit and the
+ * interrupt routine's transmit buffer is empty.
+ */
+static inline void usbBuildTxBlock(void)
+{
+usbMsgLen_t wantLen;
+uchar len;
+
+ wantLen = usbMsgLen;
+ if(wantLen > 8)
+ wantLen = 8;
+ usbMsgLen -= wantLen;
+ usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */
+ len = usbDeviceRead(usbTxBuf + 1, wantLen);
+ if(len <= 8){ /* valid data packet */
+ usbCrc16Append(&usbTxBuf[1], len);
+ len += 4; /* length including sync byte */
+ if(len < 12) /* a partial package identifies end of message */
+ usbMsgLen = USB_NO_MSG;
+ }else{
+ len = USBPID_STALL; /* stall the endpoint */
+ usbMsgLen = USB_NO_MSG;
+ }
+ usbTxLen = len;
+ DBG2(0x20, usbTxBuf, len-1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static inline void usbHandleResetHook(uchar notResetState)
+{
+#ifdef USB_RESET_HOOK
+static uchar wasReset;
+uchar isReset = !notResetState;
+
+ if(wasReset != isReset){
+ USB_RESET_HOOK(isReset);
+ wasReset = isReset;
+ }
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+USB_PUBLIC void usbPoll(void)
+{
+schar len;
+uchar i;
+
+ len = usbRxLen - 3;
+ if(len >= 0){
+/* We could check CRC16 here -- but ACK has already been sent anyway. If you
+ * need data integrity checks with this driver, check the CRC in your app
+ * code and report errors back to the host. Since the ACK was already sent,
+ * retries must be handled on application level.
+ * unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3);
+ */
+ usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len);
+#if USB_CFG_HAVE_FLOWCONTROL
+ if(usbRxLen > 0) /* only mark as available if not inactivated */
+ usbRxLen = 0;
+#else
+ usbRxLen = 0; /* mark rx buffer as available */
+#endif
+ }
+ if(usbTxLen & 0x10){ /* transmit system idle */
+ if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */
+ usbBuildTxBlock();
+ }
+ }
+ for(i = 20; i > 0; i--){
+ uchar usbLineStatus = USBIN & USBMASK;
+ if(usbLineStatus != 0) /* SE0 has ended */
+ goto isNotReset;
+ }
+ /* RESET condition, called multiple times during reset */
+ usbNewDeviceAddr = 0;
+ usbDeviceAddr = 0;
+ usbResetStall();
+ DBG1(0xff, 0, 0);
+isNotReset:
+ usbHandleResetHook(i);
+}
+
+/* ------------------------------------------------------------------------- */
+
+USB_PUBLIC void usbInit(void)
+{
+#if USB_INTR_CFG_SET != 0
+ USB_INTR_CFG |= USB_INTR_CFG_SET;
+#endif
+#if USB_INTR_CFG_CLR != 0
+ USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
+#endif
+ USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
+ usbResetDataToggling();
+#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
+ usbTxLen1 = USBPID_NAK;
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+ usbTxLen3 = USBPID_NAK;
+#endif
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/usbdrv/usbdrv.h b/usbdrv/usbdrv.h
new file mode 100644
index 0000000..dc97912
--- /dev/null
+++ b/usbdrv/usbdrv.h
@@ -0,0 +1,735 @@
+/* Name: usbdrv.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbdrv.h 769 2009-08-22 11:49:05Z cs $
+ */
+
+#ifndef __usbdrv_h_included__
+#define __usbdrv_h_included__
+#include "usbconfig.h"
+#include "usbportability.h"
+
+/*
+Hardware Prerequisites:
+=======================
+USB lines D+ and D- MUST be wired to the same I/O port. We recommend that D+
+triggers the interrupt (best achieved by using INT0 for D+), but it is also
+possible to trigger the interrupt from D-. If D- is used, interrupts are also
+triggered by SOF packets. D- requires a pull-up of 1.5k to +3.5V (and the
+device must be powered at 3.5V) to identify as low-speed USB device. A
+pull-down or pull-up of 1M SHOULD be connected from D+ to +3.5V to prevent
+interference when no USB master is connected. If you use Zener diodes to limit
+the voltage on D+ and D-, you MUST use a pull-down resistor, not a pull-up.
+We use D+ as interrupt source and not D- because it does not trigger on
+keep-alive and RESET states. If you want to count keep-alive events with
+USB_COUNT_SOF, you MUST use D- as an interrupt source.
+
+As a compile time option, the 1.5k pull-up resistor on D- can be made
+switchable to allow the device to disconnect at will. See the definition of
+usbDeviceConnect() and usbDeviceDisconnect() further down in this file.
+
+Please adapt the values in usbconfig.h according to your hardware!
+
+The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz
+or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details.
+
+
+Limitations:
+============
+Robustness with respect to communication errors:
+The driver assumes error-free communication. It DOES check for errors in
+the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte,
+token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due
+to timing constraints: We must start sending a reply within 7 bit times.
+Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU
+performance does not permit that. The driver does not check Data0/Data1
+toggling, but application software can implement the check.
+
+Input characteristics:
+Since no differential receiver circuit is used, electrical interference
+robustness may suffer. The driver samples only one of the data lines with
+an ordinary I/O pin's input characteristics. However, since this is only a
+low speed USB implementation and the specification allows for 8 times the
+bit rate over the same hardware, we should be on the safe side. Even the spec
+requires detection of asymmetric states at high bit rate for SE0 detection.
+
+Number of endpoints:
+The driver supports the following endpoints:
+
+- Endpoint 0, the default control endpoint.
+- Any number of interrupt- or bulk-out endpoints. The data is sent to
+ usbFunctionWriteOut() and USB_CFG_IMPLEMENT_FN_WRITEOUT must be defined
+ to 1 to activate this feature. The endpoint number can be found in the
+ global variable 'usbRxToken'.
+- One default interrupt- or bulk-in endpoint. This endpoint is used for
+ interrupt- or bulk-in transfers which are not handled by any other endpoint.
+ You must define USB_CFG_HAVE_INTRIN_ENDPOINT in order to activate this
+ feature and call usbSetInterrupt() to send interrupt/bulk data.
+- One additional interrupt- or bulk-in endpoint. This was endpoint 3 in
+ previous versions of this driver but can now be configured to any endpoint
+ number. You must define USB_CFG_HAVE_INTRIN_ENDPOINT3 in order to activate
+ this feature and call usbSetInterrupt3() to send interrupt/bulk data. The
+ endpoint number can be set with USB_CFG_EP3_NUMBER.
+
+Please note that the USB standard forbids bulk endpoints for low speed devices!
+Most operating systems allow them anyway, but the AVR will spend 90% of the CPU
+time in the USB interrupt polling for bulk data.
+
+Maximum data payload:
+Data payload of control in and out transfers may be up to 254 bytes. In order
+to accept payload data of out transfers, you need to implement
+'usbFunctionWrite()'.
+
+USB Suspend Mode supply current:
+The USB standard limits power consumption to 500uA when the bus is in suspend
+mode. This is not a problem for self-powered devices since they don't need
+bus power anyway. Bus-powered devices can achieve this only by putting the
+CPU in sleep mode. The driver does not implement suspend handling by itself.
+However, the application may implement activity monitoring and wakeup from
+sleep. The host sends regular SE0 states on the bus to keep it active. These
+SE0 states can be detected by using D- as the interrupt source. Define
+USB_COUNT_SOF to 1 and use the global variable usbSofCount to check for bus
+activity.
+
+Operation without an USB master:
+The driver behaves neutral without connection to an USB master if D- reads
+as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M)
+pull-down or pull-up resistor on D+ (interrupt). If Zener diodes are used,
+use a pull-down. If D- becomes statically 0, the driver may block in the
+interrupt routine.
+
+Interrupt latency:
+The application must ensure that the USB interrupt is not disabled for more
+than 25 cycles (this is for 12 MHz, faster clocks allow longer latency).
+This implies that all interrupt routines must either be declared as "INTERRUPT"
+instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler
+with "sei" as the first instruction.
+
+Maximum interrupt duration / CPU cycle consumption:
+The driver handles all USB communication during the interrupt service
+routine. The routine will not return before an entire USB message is received
+and the reply is sent. This may be up to ca. 1200 cycles @ 12 MHz (= 100us) if
+the host conforms to the standard. The driver will consume CPU cycles for all
+USB messages, even if they address another (low-speed) device on the same bus.
+
+*/
+
+/* ------------------------------------------------------------------------- */
+/* --------------------------- Module Interface ---------------------------- */
+/* ------------------------------------------------------------------------- */
+
+#define USBDRV_VERSION 20090822
+/* This define uniquely identifies a driver version. It is a decimal number
+ * constructed from the driver's release date in the form YYYYMMDD. If the
+ * driver's behavior or interface changes, you can use this constant to
+ * distinguish versions. If it is not defined, the driver's release date is
+ * older than 2006-01-25.
+ */
+
+
+#ifndef USB_PUBLIC
+#define USB_PUBLIC
+#endif
+/* USB_PUBLIC is used as declaration attribute for all functions exported by
+ * the USB driver. The default is no attribute (see above). You may define it
+ * to static either in usbconfig.h or from the command line if you include
+ * usbdrv.c instead of linking against it. Including the C module of the driver
+ * directly in your code saves a couple of bytes in flash memory.
+ */
+
+#ifndef __ASSEMBLER__
+#ifndef uchar
+#define uchar unsigned char
+#endif
+#ifndef schar
+#define schar signed char
+#endif
+/* shortcuts for well defined 8 bit integer types */
+
+#if USB_CFG_LONG_TRANSFERS /* if more than 254 bytes transfer size required */
+# define usbMsgLen_t unsigned
+#else
+# define usbMsgLen_t uchar
+#endif
+/* usbMsgLen_t is the data type used for transfer lengths. By default, it is
+ * defined to uchar, allowing a maximum of 254 bytes (255 is reserved for
+ * USB_NO_MSG below). If the usbconfig.h defines USB_CFG_LONG_TRANSFERS to 1,
+ * a 16 bit data type is used, allowing up to 16384 bytes (the rest is used
+ * for flags in the descriptor configuration).
+ */
+#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */
+
+struct usbRequest; /* forward declaration */
+
+USB_PUBLIC void usbInit(void);
+/* This function must be called before interrupts are enabled and the main
+ * loop is entered. We exepct that the PORT and DDR bits for D+ and D- have
+ * not been changed from their default status (which is 0). If you have changed
+ * them, set both back to 0 (configure them as input with no internal pull-up).
+ */
+USB_PUBLIC void usbPoll(void);
+/* This function must be called at regular intervals from the main loop.
+ * Maximum delay between calls is somewhat less than 50ms (USB timeout for
+ * accepting a Setup message). Otherwise the device will not be recognized.
+ * Please note that debug outputs through the UART take ~ 0.5ms per byte
+ * at 19200 bps.
+ */
+extern uchar *usbMsgPtr;
+/* This variable may be used to pass transmit data to the driver from the
+ * implementation of usbFunctionWrite(). It is also used internally by the
+ * driver for standard control requests.
+ */
+USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
+/* This function is called when the driver receives a SETUP transaction from
+ * the host which is not answered by the driver itself (in practice: class and
+ * vendor requests). All control transfers start with a SETUP transaction where
+ * the host communicates the parameters of the following (optional) data
+ * transfer. The SETUP data is available in the 'data' parameter which can
+ * (and should) be casted to 'usbRequest_t *' for a more user-friendly access
+ * to parameters.
+ *
+ * If the SETUP indicates a control-in transfer, you should provide the
+ * requested data to the driver. There are two ways to transfer this data:
+ * (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data
+ * block and return the length of the data in 'usbFunctionSetup()'. The driver
+ * will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The
+ * driver will then call 'usbFunctionRead()' when data is needed. See the
+ * documentation for usbFunctionRead() for details.
+ *
+ * If the SETUP indicates a control-out transfer, the only way to receive the
+ * data from the host is through the 'usbFunctionWrite()' call. If you
+ * implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()'
+ * to indicate that 'usbFunctionWrite()' should be used. See the documentation
+ * of this function for more information. If you just want to ignore the data
+ * sent by the host, return 0 in 'usbFunctionSetup()'.
+ *
+ * Note that calls to the functions usbFunctionRead() and usbFunctionWrite()
+ * are only done if enabled by the configuration in usbconfig.h.
+ */
+USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq);
+/* You need to implement this function ONLY if you provide USB descriptors at
+ * runtime (which is an expert feature). It is very similar to
+ * usbFunctionSetup() above, but it is called only to request USB descriptor
+ * data. See the documentation of usbFunctionSetup() above for more info.
+ */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT
+USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len);
+/* This function sets the message which will be sent during the next interrupt
+ * IN transfer. The message is copied to an internal buffer and must not exceed
+ * a length of 8 bytes. The message may be 0 bytes long just to indicate the
+ * interrupt status to the host.
+ * If you need to transfer more bytes, use a control read after the interrupt.
+ */
+#define usbInterruptIsReady() (usbTxLen1 & 0x10)
+/* This macro indicates whether the last interrupt message has already been
+ * sent. If you set a new interrupt message before the old was sent, the
+ * message already buffered will be lost.
+ */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3
+USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len);
+#define usbInterruptIsReady3() (usbTxLen3 & 0x10)
+/* Same as above for endpoint 3 */
+#endif
+#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */
+#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */
+#define usbHidReportDescriptor usbDescriptorHidReport
+/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */
+/* If you implement an HID device, you need to provide a report descriptor.
+ * The HID report descriptor syntax is a bit complex. If you understand how
+ * report descriptors are constructed, we recommend that you use the HID
+ * Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/.
+ * Otherwise you should probably start with a working example.
+ */
+#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */
+#if USB_CFG_IMPLEMENT_FN_WRITE
+USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len);
+/* This function is called by the driver to provide a control transfer's
+ * payload data (control-out). It is called in chunks of up to 8 bytes. The
+ * total count provided in the current control transfer can be obtained from
+ * the 'length' property in the setup data. If an error occurred during
+ * processing, return 0xff (== -1). The driver will answer the entire transfer
+ * with a STALL token in this case. If you have received the entire payload
+ * successfully, return 1. If you expect more data, return 0. If you don't
+ * know whether the host will send more data (you should know, the total is
+ * provided in the usbFunctionSetup() call!), return 1.
+ * NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called
+ * for the remaining data. You must continue to return 0xff for STALL in these
+ * calls.
+ * In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE
+ * to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
+ */
+#endif /* USB_CFG_IMPLEMENT_FN_WRITE */
+#if USB_CFG_IMPLEMENT_FN_READ
+USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len);
+/* This function is called by the driver to ask the application for a control
+ * transfer's payload data (control-in). It is called in chunks of up to 8
+ * bytes each. You should copy the data to the location given by 'data' and
+ * return the actual number of bytes copied. If you return less than requested,
+ * the control-in transfer is terminated. If you return 0xff, the driver aborts
+ * the transfer with a STALL token.
+ * In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ
+ * to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
+ */
+#endif /* USB_CFG_IMPLEMENT_FN_READ */
+
+extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */
+#if USB_CFG_IMPLEMENT_FN_WRITEOUT
+USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len);
+/* This function is called by the driver when data is received on an interrupt-
+ * or bulk-out endpoint. The endpoint number can be found in the global
+ * variable usbRxToken. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT to 1 in
+ * usbconfig.h to get this function called.
+ */
+#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */
+#ifdef USB_CFG_PULLUP_IOPORTNAME
+#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<<USB_CFG_PULLUP_BIT)), \
+ (USB_PULLUP_OUT |= (1<<USB_CFG_PULLUP_BIT)))
+#define usbDeviceDisconnect() ((USB_PULLUP_DDR &= ~(1<<USB_CFG_PULLUP_BIT)), \
+ (USB_PULLUP_OUT &= ~(1<<USB_CFG_PULLUP_BIT)))
+#else /* USB_CFG_PULLUP_IOPORTNAME */
+#define usbDeviceConnect() (USBDDR &= ~(1<<USBMINUS))
+#define usbDeviceDisconnect() (USBDDR |= (1<<USBMINUS))
+#endif /* USB_CFG_PULLUP_IOPORTNAME */
+/* The macros usbDeviceConnect() and usbDeviceDisconnect() (intended to look
+ * like a function) connect resp. disconnect the device from the host's USB.
+ * If the constants USB_CFG_PULLUP_IOPORT and USB_CFG_PULLUP_BIT are defined
+ * in usbconfig.h, a disconnect consists of removing the pull-up resisitor
+ * from D-, otherwise the disconnect is done by brute-force pulling D- to GND.
+ * This does not conform to the spec, but it works.
+ * Please note that the USB interrupt must be disabled while the device is
+ * in disconnected state, or the interrupt handler will hang! You can either
+ * turn off the USB interrupt selectively with
+ * USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT)
+ * or use cli() to disable interrupts globally.
+ */
+extern unsigned usbCrc16(unsigned data, uchar len);
+#define usbCrc16(data, len) usbCrc16((unsigned)(data), len)
+/* This function calculates the binary complement of the data CRC used in
+ * USB data packets. The value is used to build raw transmit packets.
+ * You may want to use this function for data checksums or to verify received
+ * data. We enforce 16 bit calling conventions for compatibility with IAR's
+ * tiny memory model.
+ */
+extern unsigned usbCrc16Append(unsigned data, uchar len);
+#define usbCrc16Append(data, len) usbCrc16Append((unsigned)(data), len)
+/* This function is equivalent to usbCrc16() above, except that it appends
+ * the 2 bytes CRC (lowbyte first) in the 'data' buffer after reading 'len'
+ * bytes.
+ */
+#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH
+extern unsigned usbMeasureFrameLength(void);
+/* This function MUST be called IMMEDIATELY AFTER USB reset and measures 1/7 of
+ * the number of CPU cycles during one USB frame minus one low speed bit
+ * length. In other words: return value = 1499 * (F_CPU / 10.5 MHz)
+ * Since this is a busy wait, you MUST disable all interrupts with cli() before
+ * calling this function.
+ * This can be used to calibrate the AVR's RC oscillator.
+ */
+#endif
+extern uchar usbConfiguration;
+/* This value contains the current configuration set by the host. The driver
+ * allows setting and querying of this variable with the USB SET_CONFIGURATION
+ * and GET_CONFIGURATION requests, but does not use it otherwise.
+ * You may want to reflect the "configured" status with a LED on the device or
+ * switch on high power parts of the circuit only if the device is configured.
+ */
+#if USB_COUNT_SOF
+extern volatile uchar usbSofCount;
+/* This variable is incremented on every SOF packet. It is only available if
+ * the macro USB_COUNT_SOF is defined to a value != 0.
+ */
+#endif
+#if USB_CFG_CHECK_DATA_TOGGLING
+extern uchar usbCurrentDataToken;
+/* This variable can be checked in usbFunctionWrite() and usbFunctionWriteOut()
+ * to ignore duplicate packets.
+ */
+#endif
+
+#define USB_STRING_DESCRIPTOR_HEADER(stringLength) ((2*(stringLength)+2) | (3<<8))
+/* This macro builds a descriptor header for a string descriptor given the
+ * string's length. See usbdrv.c for an example how to use it.
+ */
+#if USB_CFG_HAVE_FLOWCONTROL
+extern volatile schar usbRxLen;
+#define usbDisableAllRequests() usbRxLen = -1
+/* Must be called from usbFunctionWrite(). This macro disables all data input
+ * from the USB interface. Requests from the host are answered with a NAK
+ * while they are disabled.
+ */
+#define usbEnableAllRequests() usbRxLen = 0
+/* May only be called if requests are disabled. This macro enables input from
+ * the USB interface after it has been disabled with usbDisableAllRequests().
+ */
+#define usbAllRequestsAreDisabled() (usbRxLen < 0)
+/* Use this macro to find out whether requests are disabled. It may be needed
+ * to ensure that usbEnableAllRequests() is never called when requests are
+ * enabled.
+ */
+#endif
+
+#define USB_SET_DATATOKEN1(token) usbTxBuf1[0] = token
+#define USB_SET_DATATOKEN3(token) usbTxBuf3[0] = token
+/* These two macros can be used by application software to reset data toggling
+ * for interrupt-in endpoints 1 and 3. Since the token is toggled BEFORE
+ * sending data, you must set the opposite value of the token which should come
+ * first.
+ */
+
+#endif /* __ASSEMBLER__ */
+
+
+/* ------------------------------------------------------------------------- */
+/* ----------------- Definitions for Descriptor Properties ----------------- */
+/* ------------------------------------------------------------------------- */
+/* This is advanced stuff. See usbconfig-prototype.h for more information
+ * about the various methods to define USB descriptors. If you do nothing,
+ * the default descriptors will be used.
+ */
+#define USB_PROP_IS_DYNAMIC (1 << 14)
+/* If this property is set for a descriptor, usbFunctionDescriptor() will be
+ * used to obtain the particular descriptor. Data directly returned via
+ * usbMsgPtr are FLASH data by default, combine (OR) with USB_PROP_IS_RAM to
+ * return RAM data.
+ */
+#define USB_PROP_IS_RAM (1 << 15)
+/* If this property is set for a descriptor, the data is read from RAM
+ * memory instead of Flash. The property is used for all methods to provide
+ * external descriptors.
+ */
+#define USB_PROP_LENGTH(len) ((len) & 0x3fff)
+/* If a static external descriptor is used, this is the total length of the
+ * descriptor in bytes.
+ */
+
+/* all descriptors which may have properties: */
+#ifndef USB_CFG_DESCR_PROPS_DEVICE
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_CONFIGURATION
+#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_STRINGS
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_STRING_0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_STRING_VENDOR
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_STRING_PRODUCT
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#endif
+#ifndef USB_CFG_DESCR_PROPS_HID
+#define USB_CFG_DESCR_PROPS_HID 0
+#endif
+#if !(USB_CFG_DESCR_PROPS_HID_REPORT)
+# undef USB_CFG_DESCR_PROPS_HID_REPORT
+# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* do some backward compatibility tricks */
+# define USB_CFG_DESCR_PROPS_HID_REPORT USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
+# else
+# define USB_CFG_DESCR_PROPS_HID_REPORT 0
+# endif
+#endif
+#ifndef USB_CFG_DESCR_PROPS_UNKNOWN
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+#endif
+
+/* ------------------ forward declaration of descriptors ------------------- */
+/* If you use external static descriptors, they must be stored in global
+ * arrays as declared below:
+ */
+#ifndef __ASSEMBLER__
+extern
+#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+char usbDescriptorDevice[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+char usbDescriptorConfiguration[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+char usbDescriptorHidReport[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+char usbDescriptorString0[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+int usbDescriptorStringVendor[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+int usbDescriptorStringDevice[];
+
+extern
+#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
+PROGMEM
+#endif
+int usbDescriptorStringSerialNumber[];
+
+#endif /* __ASSEMBLER__ */
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------ General Purpose Macros ------------------------- */
+/* ------------------------------------------------------------------------- */
+
+#define USB_CONCAT(a, b) a ## b
+#define USB_CONCAT_EXPANDED(a, b) USB_CONCAT(a, b)
+
+#define USB_OUTPORT(name) USB_CONCAT(PORT, name)
+#define USB_INPORT(name) USB_CONCAT(PIN, name)
+#define USB_DDRPORT(name) USB_CONCAT(DDR, name)
+/* The double-define trick above lets us concatenate strings which are
+ * defined by macros.
+ */
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------- Constant definitions -------------------------- */
+/* ------------------------------------------------------------------------- */
+
+#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID)
+#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h"
+/* If the user has not defined IDs, we default to obdev's free IDs.
+ * See USB-IDs-for-free.txt for details.
+ */
+#endif
+
+/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */
+#ifndef USB_CFG_VENDOR_ID
+# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
+#endif
+
+#ifndef USB_CFG_DEVICE_ID
+# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH
+# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* = 0x5df = 1503, shared PID for HIDs */
+# elif USB_CFG_INTERFACE_CLASS == 2
+# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* = 0x5e1 = 1505, shared PID for CDC Modems */
+# else
+# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x5dc = 1500, obdev's free PID */
+# endif
+#endif
+
+/* Derive Output, Input and DataDirection ports from port names */
+#ifndef USB_CFG_IOPORTNAME
+#error "You must define USB_CFG_IOPORTNAME in usbconfig.h, see usbconfig-prototype.h"
+#endif
+
+#define USBOUT USB_OUTPORT(USB_CFG_IOPORTNAME)
+#define USB_PULLUP_OUT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME)
+#define USBIN USB_INPORT(USB_CFG_IOPORTNAME)
+#define USBDDR USB_DDRPORT(USB_CFG_IOPORTNAME)
+#define USB_PULLUP_DDR USB_DDRPORT(USB_CFG_PULLUP_IOPORTNAME)
+
+#define USBMINUS USB_CFG_DMINUS_BIT
+#define USBPLUS USB_CFG_DPLUS_BIT
+#define USBIDLE (1<<USB_CFG_DMINUS_BIT) /* value representing J state */
+#define USBMASK ((1<<USB_CFG_DPLUS_BIT) | (1<<USB_CFG_DMINUS_BIT)) /* mask for USB I/O bits */
+
+/* defines for backward compatibility with older driver versions: */
+#define USB_CFG_IOPORT USB_OUTPORT(USB_CFG_IOPORTNAME)
+#ifdef USB_CFG_PULLUP_IOPORTNAME
+#define USB_CFG_PULLUP_IOPORT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME)
+#endif
+
+#ifndef USB_CFG_EP3_NUMBER /* if not defined in usbconfig.h */
+#define USB_CFG_EP3_NUMBER 3
+#endif
+
+#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT3
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
+#endif
+
+#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */
+
+/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */
+
+#ifndef USB_INTR_CFG /* allow user to override our default */
+# if defined EICRA
+# define USB_INTR_CFG EICRA
+# else
+# define USB_INTR_CFG MCUCR
+# endif
+#endif
+#ifndef USB_INTR_CFG_SET /* allow user to override our default */
+# if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK)
+# define USB_INTR_CFG_SET (1 << ISC01) /* cfg for falling edge */
+ /* If any SOF logic is used, the interrupt must be wired to D- where
+ * we better trigger on falling edge
+ */
+# else
+# define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */
+# endif
+#endif
+#ifndef USB_INTR_CFG_CLR /* allow user to override our default */
+# define USB_INTR_CFG_CLR 0 /* no bits to clear */
+#endif
+
+#ifndef USB_INTR_ENABLE /* allow user to override our default */
+# if defined GIMSK
+# define USB_INTR_ENABLE GIMSK
+# elif defined EIMSK
+# define USB_INTR_ENABLE EIMSK
+# else
+# define USB_INTR_ENABLE GICR
+# endif
+#endif
+#ifndef USB_INTR_ENABLE_BIT /* allow user to override our default */
+# define USB_INTR_ENABLE_BIT INT0
+#endif
+
+#ifndef USB_INTR_PENDING /* allow user to override our default */
+# if defined EIFR
+# define USB_INTR_PENDING EIFR
+# else
+# define USB_INTR_PENDING GIFR
+# endif
+#endif
+#ifndef USB_INTR_PENDING_BIT /* allow user to override our default */
+# define USB_INTR_PENDING_BIT INTF0
+#endif
+
+/*
+The defines above don't work for the following chips
+at90c8534: no ISC0?, no PORTB, can't find a data sheet
+at86rf401: no PORTB, no MCUCR etc, low clock rate
+atmega103: no ISC0? (maybe omission in header, can't find data sheet)
+atmega603: not defined in avr-libc
+at43usb320, at43usb355, at76c711: have USB anyway
+at94k: is different...
+
+at90s1200, attiny11, attiny12, attiny15, attiny28: these have no RAM
+*/
+
+/* ------------------------------------------------------------------------- */
+/* ----------------- USB Specification Constants and Types ----------------- */
+/* ------------------------------------------------------------------------- */
+
+/* USB Token values */
+#define USBPID_SETUP 0x2d
+#define USBPID_OUT 0xe1
+#define USBPID_IN 0x69
+#define USBPID_DATA0 0xc3
+#define USBPID_DATA1 0x4b
+
+#define USBPID_ACK 0xd2
+#define USBPID_NAK 0x5a
+#define USBPID_STALL 0x1e
+
+#ifndef USB_INITIAL_DATATOKEN
+#define USB_INITIAL_DATATOKEN USBPID_DATA1
+#endif
+
+#ifndef __ASSEMBLER__
+
+typedef struct usbTxStatus{
+ volatile uchar len;
+ uchar buffer[USB_BUFSIZE];
+}usbTxStatus_t;
+
+extern usbTxStatus_t usbTxStatus1, usbTxStatus3;
+#define usbTxLen1 usbTxStatus1.len
+#define usbTxBuf1 usbTxStatus1.buffer
+#define usbTxLen3 usbTxStatus3.len
+#define usbTxBuf3 usbTxStatus3.buffer
+
+
+typedef union usbWord{
+ unsigned word;
+ uchar bytes[2];
+}usbWord_t;
+
+typedef struct usbRequest{
+ uchar bmRequestType;
+ uchar bRequest;
+ usbWord_t wValue;
+ usbWord_t wIndex;
+ usbWord_t wLength;
+}usbRequest_t;
+/* This structure matches the 8 byte setup request */
+#endif
+
+/* bmRequestType field in USB setup:
+ * d t t r r r r r, where
+ * d ..... direction: 0=host->device, 1=device->host
+ * t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved
+ * r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other
+ */
+
+/* USB setup recipient values */
+#define USBRQ_RCPT_MASK 0x1f
+#define USBRQ_RCPT_DEVICE 0
+#define USBRQ_RCPT_INTERFACE 1
+#define USBRQ_RCPT_ENDPOINT 2
+
+/* USB request type values */
+#define USBRQ_TYPE_MASK 0x60
+#define USBRQ_TYPE_STANDARD (0<<5)
+#define USBRQ_TYPE_CLASS (1<<5)
+#define USBRQ_TYPE_VENDOR (2<<5)
+
+/* USB direction values: */
+#define USBRQ_DIR_MASK 0x80
+#define USBRQ_DIR_HOST_TO_DEVICE (0<<7)
+#define USBRQ_DIR_DEVICE_TO_HOST (1<<7)
+
+/* USB Standard Requests */
+#define USBRQ_GET_STATUS 0
+#define USBRQ_CLEAR_FEATURE 1
+#define USBRQ_SET_FEATURE 3
+#define USBRQ_SET_ADDRESS 5
+#define USBRQ_GET_DESCRIPTOR 6
+#define USBRQ_SET_DESCRIPTOR 7
+#define USBRQ_GET_CONFIGURATION 8
+#define USBRQ_SET_CONFIGURATION 9
+#define USBRQ_GET_INTERFACE 10
+#define USBRQ_SET_INTERFACE 11
+#define USBRQ_SYNCH_FRAME 12
+
+/* USB descriptor constants */
+#define USBDESCR_DEVICE 1
+#define USBDESCR_CONFIG 2
+#define USBDESCR_STRING 3
+#define USBDESCR_INTERFACE 4
+#define USBDESCR_ENDPOINT 5
+#define USBDESCR_HID 0x21
+#define USBDESCR_HID_REPORT 0x22
+#define USBDESCR_HID_PHYS 0x23
+
+//#define USBATTR_BUSPOWER 0x80 // USB 1.1 does not define this value any more
+#define USBATTR_SELFPOWER 0x40
+#define USBATTR_REMOTEWAKE 0x20
+
+/* USB HID Requests */
+#define USBRQ_HID_GET_REPORT 0x01
+#define USBRQ_HID_GET_IDLE 0x02
+#define USBRQ_HID_GET_PROTOCOL 0x03
+#define USBRQ_HID_SET_REPORT 0x09
+#define USBRQ_HID_SET_IDLE 0x0a
+#define USBRQ_HID_SET_PROTOCOL 0x0b
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* __usbdrv_h_included__ */
diff --git a/usbdrv/usbdrvasm.S b/usbdrv/usbdrvasm.S
new file mode 100644
index 0000000..80877e4
--- /dev/null
+++ b/usbdrv/usbdrvasm.S
@@ -0,0 +1,385 @@
+/* Name: usbdrvasm.S
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2007-06-13
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm.S 761 2009-08-12 16:30:23Z cs $
+ */
+
+/*
+General Description:
+This module is the assembler part of the USB driver. This file contains
+general code (preprocessor acrobatics and CRC computation) and then includes
+the file appropriate for the given clock rate.
+*/
+
+#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */
+#include "usbportability.h"
+#include "usbdrv.h" /* for common defs */
+
+/* register names */
+#define x1 r16
+#define x2 r17
+#define shift r18
+#define cnt r19
+#define x3 r20
+#define x4 r21
+#define x5 r22
+#define bitcnt x5
+#define phase x4
+#define leap x4
+
+/* Some assembler dependent definitions and declarations: */
+
+#ifdef __IAR_SYSTEMS_ASM__
+ extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
+ extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
+ extern usbTxBuf, usbTxStatus1, usbTxStatus3
+# if USB_COUNT_SOF
+ extern usbSofCount
+# endif
+ public usbCrc16
+ public usbCrc16Append
+
+ COMMON INTVEC
+# ifndef USB_INTR_VECTOR
+ ORG INT0_vect
+# else /* USB_INTR_VECTOR */
+ ORG USB_INTR_VECTOR
+# undef USB_INTR_VECTOR
+# endif /* USB_INTR_VECTOR */
+# define USB_INTR_VECTOR usbInterruptHandler
+ rjmp USB_INTR_VECTOR
+ RSEG CODE
+
+#else /* __IAR_SYSTEMS_ASM__ */
+
+# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
+# define USB_INTR_VECTOR SIG_INTERRUPT0
+# endif
+ .text
+ .global USB_INTR_VECTOR
+ .type USB_INTR_VECTOR, @function
+ .global usbCrc16
+ .global usbCrc16Append
+#endif /* __IAR_SYSTEMS_ASM__ */
+
+
+#if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */
+# define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING
+# define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg
+#else /* It's a memory address, use lds and sts */
+# define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING
+# define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg
+#endif
+
+#define usbTxLen1 usbTxStatus1
+#define usbTxBuf1 (usbTxStatus1 + 1)
+#define usbTxLen3 usbTxStatus3
+#define usbTxBuf3 (usbTxStatus3 + 1)
+
+
+;----------------------------------------------------------------------------
+; Utility functions
+;----------------------------------------------------------------------------
+
+#ifdef __IAR_SYSTEMS_ASM__
+/* Register assignments for usbCrc16 on IAR cc */
+/* Calling conventions on IAR:
+ * First parameter passed in r16/r17, second in r18/r19 and so on.
+ * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
+ * Result is passed in r16/r17
+ * In case of the "tiny" memory model, pointers are only 8 bit with no
+ * padding. We therefore pass argument 1 as "16 bit unsigned".
+ */
+RTMODEL "__rt_version", "3"
+/* The line above will generate an error if cc calling conventions change.
+ * The value "3" above is valid for IAR 4.10B/W32
+ */
+# define argLen r18 /* argument 2 */
+# define argPtrL r16 /* argument 1 */
+# define argPtrH r17 /* argument 1 */
+
+# define resCrcL r16 /* result */
+# define resCrcH r17 /* result */
+
+# define ptrL ZL
+# define ptrH ZH
+# define ptr Z
+# define byte r22
+# define bitCnt r19
+# define polyL r20
+# define polyH r21
+# define scratch r23
+
+#else /* __IAR_SYSTEMS_ASM__ */
+/* Register assignments for usbCrc16 on gcc */
+/* Calling conventions on gcc:
+ * First parameter passed in r24/r25, second in r22/23 and so on.
+ * Callee must preserve r1-r17, r28/r29
+ * Result is passed in r24/r25
+ */
+# define argLen r22 /* argument 2 */
+# define argPtrL r24 /* argument 1 */
+# define argPtrH r25 /* argument 1 */
+
+# define resCrcL r24 /* result */
+# define resCrcH r25 /* result */
+
+# define ptrL XL
+# define ptrH XH
+# define ptr x
+# define byte r18
+# define bitCnt r19
+# define polyL r20
+# define polyH r21
+# define scratch r23
+
+#endif
+
+#if USB_USE_FAST_CRC
+
+; This implementation is faster, but has bigger code size
+; Thanks to Slawomir Fras (BoskiDialer) for this code!
+; It implements the following C pseudo-code:
+; unsigned table(unsigned char x)
+; {
+; unsigned value;
+;
+; value = (unsigned)x << 6;
+; value ^= (unsigned)x << 7;
+; if(parity(x))
+; value ^= 0xc001;
+; return value;
+; }
+; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen)
+; {
+; unsigned crc = 0xffff;
+;
+; while(argLen--)
+; crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc);
+; return ~crc;
+; }
+
+; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
+; argPtr r24+25 / r16+r17
+; argLen r22 / r18
+; temp variables:
+; byte r18 / r22
+; scratch r23
+; resCrc r24+r25 / r16+r17
+; ptr X / Z
+usbCrc16:
+ mov ptrL, argPtrL
+ mov ptrH, argPtrH
+ ldi resCrcL, 0xFF
+ ldi resCrcH, 0xFF
+ rjmp usbCrc16LoopTest
+usbCrc16ByteLoop:
+ ld byte, ptr+
+ eor resCrcL, byte ; resCrcL is now 'x' in table()
+ mov byte, resCrcL ; compute parity of 'x'
+ swap byte
+ eor byte, resCrcL
+ mov scratch, byte
+ lsr byte
+ lsr byte
+ eor byte, scratch
+ inc byte
+ lsr byte
+ andi byte, 1 ; byte is now parity(x)
+ mov scratch, resCrcL
+ mov resCrcL, resCrcH
+ eor resCrcL, byte ; low byte of if(parity(x)) value ^= 0xc001;
+ neg byte
+ andi byte, 0xc0
+ mov resCrcH, byte ; high byte of if(parity(x)) value ^= 0xc001;
+ clr byte
+ lsr scratch
+ ror byte
+ eor resCrcH, scratch
+ eor resCrcL, byte
+ lsr scratch
+ ror byte
+ eor resCrcH, scratch
+ eor resCrcL, byte
+usbCrc16LoopTest:
+ subi argLen, 1
+ brsh usbCrc16ByteLoop
+ com resCrcL
+ com resCrcH
+ ret
+
+#else /* USB_USE_FAST_CRC */
+
+; This implementation is slower, but has less code size
+;
+; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
+; argPtr r24+25 / r16+r17
+; argLen r22 / r18
+; temp variables:
+; byte r18 / r22
+; bitCnt r19
+; poly r20+r21
+; scratch r23
+; resCrc r24+r25 / r16+r17
+; ptr X / Z
+usbCrc16:
+ mov ptrL, argPtrL
+ mov ptrH, argPtrH
+ ldi resCrcL, 0
+ ldi resCrcH, 0
+ ldi polyL, lo8(0xa001)
+ ldi polyH, hi8(0xa001)
+ com argLen ; argLen = -argLen - 1: modified loop to ensure that carry is set
+ ldi bitCnt, 0 ; loop counter with starnd condition = end condition
+ rjmp usbCrcLoopEntry
+usbCrcByteLoop:
+ ld byte, ptr+
+ eor resCrcL, byte
+usbCrcBitLoop:
+ ror resCrcH ; carry is always set here (see brcs jumps to here)
+ ror resCrcL
+ brcs usbCrcNoXor
+ eor resCrcL, polyL
+ eor resCrcH, polyH
+usbCrcNoXor:
+ subi bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times
+ brcs usbCrcBitLoop
+usbCrcLoopEntry:
+ subi argLen, -1
+ brcs usbCrcByteLoop
+usbCrcReady:
+ ret
+; Thanks to Reimar Doeffinger for optimizing this CRC routine!
+
+#endif /* USB_USE_FAST_CRC */
+
+; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
+usbCrc16Append:
+ rcall usbCrc16
+ st ptr+, resCrcL
+ st ptr+, resCrcH
+ ret
+
+#undef argLen
+#undef argPtrL
+#undef argPtrH
+#undef resCrcL
+#undef resCrcH
+#undef ptrL
+#undef ptrH
+#undef ptr
+#undef byte
+#undef bitCnt
+#undef polyL
+#undef polyH
+#undef scratch
+
+
+#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH
+#ifdef __IAR_SYSTEMS_ASM__
+/* Register assignments for usbMeasureFrameLength on IAR cc */
+/* Calling conventions on IAR:
+ * First parameter passed in r16/r17, second in r18/r19 and so on.
+ * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
+ * Result is passed in r16/r17
+ * In case of the "tiny" memory model, pointers are only 8 bit with no
+ * padding. We therefore pass argument 1 as "16 bit unsigned".
+ */
+# define resL r16
+# define resH r17
+# define cnt16L r30
+# define cnt16H r31
+# define cntH r18
+
+#else /* __IAR_SYSTEMS_ASM__ */
+/* Register assignments for usbMeasureFrameLength on gcc */
+/* Calling conventions on gcc:
+ * First parameter passed in r24/r25, second in r22/23 and so on.
+ * Callee must preserve r1-r17, r28/r29
+ * Result is passed in r24/r25
+ */
+# define resL r24
+# define resH r25
+# define cnt16L r24
+# define cnt16H r25
+# define cntH r26
+#endif
+# define cnt16 cnt16L
+
+; extern unsigned usbMeasurePacketLength(void);
+; returns time between two idle strobes in multiples of 7 CPU clocks
+.global usbMeasureFrameLength
+usbMeasureFrameLength:
+ ldi cntH, 6 ; wait ~ 10 ms for D- == 0
+ clr cnt16L
+ clr cnt16H
+usbMFTime16:
+ dec cntH
+ breq usbMFTimeout
+usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe)
+ sbiw cnt16, 1 ;[0] [6]
+ breq usbMFTime16 ;[2]
+ sbic USBIN, USBMINUS ;[3]
+ rjmp usbMFWaitStrobe ;[4]
+usbMFWaitIdle: ; then wait until idle again
+ sbis USBIN, USBMINUS ;1 wait for D- == 1
+ rjmp usbMFWaitIdle ;2
+ ldi cnt16L, 1 ;1 represents cycles so far
+ clr cnt16H ;1
+usbMFWaitLoop:
+ in cntH, USBIN ;[0] [7]
+ adiw cnt16, 1 ;[1]
+ breq usbMFTimeout ;[3]
+ andi cntH, USBMASK ;[4]
+ brne usbMFWaitLoop ;[5]
+usbMFTimeout:
+#if resL != cnt16L
+ mov resL, cnt16L
+ mov resH, cnt16H
+#endif
+ ret
+
+#undef resL
+#undef resH
+#undef cnt16
+#undef cnt16L
+#undef cnt16H
+#undef cntH
+
+#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */
+
+;----------------------------------------------------------------------------
+; Now include the clock rate specific code
+;----------------------------------------------------------------------------
+
+#ifndef USB_CFG_CLOCK_KHZ
+# define USB_CFG_CLOCK_KHZ 12000
+#endif
+
+#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */
+# if USB_CFG_CLOCK_KHZ == 18000
+# include "usbdrvasm18-crc.inc"
+# else
+# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!"
+# endif
+#else /* USB_CFG_CHECK_CRC */
+# if USB_CFG_CLOCK_KHZ == 12000
+# include "usbdrvasm12.inc"
+# elif USB_CFG_CLOCK_KHZ == 12800
+# include "usbdrvasm128.inc"
+# elif USB_CFG_CLOCK_KHZ == 15000
+# include "usbdrvasm15.inc"
+# elif USB_CFG_CLOCK_KHZ == 16000
+# include "usbdrvasm16.inc"
+# elif USB_CFG_CLOCK_KHZ == 16500
+# include "usbdrvasm165.inc"
+# elif USB_CFG_CLOCK_KHZ == 20000
+# include "usbdrvasm20.inc"
+# else
+# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!"
+# endif
+#endif /* USB_CFG_CHECK_CRC */
diff --git a/usbdrv/usbdrvasm.asm b/usbdrv/usbdrvasm.asm
new file mode 100644
index 0000000..9cc4e4d
--- /dev/null
+++ b/usbdrv/usbdrvasm.asm
@@ -0,0 +1,21 @@
+/* Name: usbdrvasm.asm
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2006-03-01
+ * Tabsize: 4
+ * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id$
+ */
+
+/*
+General Description:
+The IAR compiler/assembler system prefers assembler files with file extension
+".asm". We simply provide this file as an alias for usbdrvasm.S.
+
+Thanks to Oleg Semyonov for his help with the IAR tools port!
+*/
+
+#include "usbdrvasm.S"
+
+end
diff --git a/usbdrv/usbdrvasm12.inc b/usbdrv/usbdrvasm12.inc
new file mode 100644
index 0000000..c116758
--- /dev/null
+++ b/usbdrv/usbdrvasm12.inc
@@ -0,0 +1,393 @@
+/* Name: usbdrvasm12.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2004-12-29
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbdrvasm12.inc 740 2009-04-13 18:23:31Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 12 MHz version of the asssembler part of the USB driver. It
+requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC
+oscillator).
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+
+
+Timing constraints according to spec (in bit times):
+timing subject min max CPUcycles
+---------------------------------------------------------------------------
+EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128
+EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60
+DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60
+*/
+
+;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
+;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
+;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable
+;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes
+;Numbers in brackets are maximum cycles since SOF.
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt
+ push YL ;2 [35] push only what is necessary to sync with edge ASAP
+ in YL, SREG ;1 [37]
+ push YL ;2 [39]
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+foundK:
+;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
+;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push YH ;2 [2]
+ lds YL, usbInputBufOffset;2 [4]
+ clr YH ;1 [5]
+ subi YL, lo8(-(usbRxBuf));1 [6]
+ sbci YH, hi8(-(usbRxBuf));1 [7]
+
+ sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early]
+ rjmp haveTwoBitsK ;2 [10]
+ pop YH ;2 [11] undo the push from before
+ rjmp waitForK ;2 [13] this was not the end of sync, retry
+haveTwoBitsK:
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+ push shift ;2 [16]
+ push x1 ;2 [12]
+ push x2 ;2 [14]
+
+ in x1, USBIN ;1 [17] <-- sample bit 0
+ ldi shift, 0xff ;1 [18]
+ bst x1, USBMINUS ;1 [19]
+ bld shift, 0 ;1 [20]
+ push x3 ;2 [22]
+ push cnt ;2 [24]
+
+ in x2, USBIN ;1 [25] <-- sample bit 1
+ ser x3 ;1 [26] [inserted init instruction]
+ eor x1, x2 ;1 [27]
+ bst x1, USBMINUS ;1 [28]
+ bld shift, 1 ;1 [29]
+ ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction]
+ rjmp rxbit2 ;2 [32]
+
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+
+unstuff0: ;1 (branch taken)
+ andi x3, ~0x01 ;1 [15]
+ mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit
+ in x2, USBIN ;1 [17] <-- sample bit 1 again
+ ori shift, 0x01 ;1 [18]
+ rjmp didUnstuff0 ;2 [20]
+
+unstuff1: ;1 (branch taken)
+ mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit
+ andi x3, ~0x02 ;1 [22]
+ ori shift, 0x02 ;1 [23]
+ nop ;1 [24]
+ in x1, USBIN ;1 [25] <-- sample bit 2 again
+ rjmp didUnstuff1 ;2 [27]
+
+unstuff2: ;1 (branch taken)
+ andi x3, ~0x04 ;1 [29]
+ ori shift, 0x04 ;1 [30]
+ mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit
+ nop ;1 [32]
+ in x2, USBIN ;1 [33] <-- sample bit 3
+ rjmp didUnstuff2 ;2 [35]
+
+unstuff3: ;1 (branch taken)
+ in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late]
+ andi x3, ~0x08 ;1 [35]
+ ori shift, 0x08 ;1 [36]
+ rjmp didUnstuff3 ;2 [38]
+
+unstuff4: ;1 (branch taken)
+ andi x3, ~0x10 ;1 [40]
+ in x1, USBIN ;1 [41] <-- sample stuffed bit 4
+ ori shift, 0x10 ;1 [42]
+ rjmp didUnstuff4 ;2 [44]
+
+unstuff5: ;1 (branch taken)
+ andi x3, ~0x20 ;1 [48]
+ in x2, USBIN ;1 [49] <-- sample stuffed bit 5
+ ori shift, 0x20 ;1 [50]
+ rjmp didUnstuff5 ;2 [52]
+
+unstuff6: ;1 (branch taken)
+ andi x3, ~0x40 ;1 [56]
+ in x1, USBIN ;1 [57] <-- sample stuffed bit 6
+ ori shift, 0x40 ;1 [58]
+ rjmp didUnstuff6 ;2 [60]
+
+; extra jobs done during bit interval:
+; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs]
+; bit 1: se0 check
+; bit 2: overflow check
+; bit 3: recovery from delay [bit 0 tasks took too long]
+; bit 4: none
+; bit 5: none
+; bit 6: none
+; bit 7: jump, eor
+rxLoop:
+ eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others
+ in x1, USBIN ;1 [1] <-- sample bit 0
+ st y+, x3 ;2 [3] store data
+ ser x3 ;1 [4]
+ nop ;1 [5]
+ eor x2, x1 ;1 [6]
+ bst x2, USBMINUS;1 [7]
+ bld shift, 0 ;1 [8]
+ in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed)
+ andi x2, USBMASK ;1 [10]
+ breq se0 ;1 [11] SE0 check for bit 1
+ andi shift, 0xf9 ;1 [12]
+didUnstuff0:
+ breq unstuff0 ;1 [13]
+ eor x1, x2 ;1 [14]
+ bst x1, USBMINUS;1 [15]
+ bld shift, 1 ;1 [16]
+rxbit2:
+ in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed)
+ andi shift, 0xf3 ;1 [18]
+ breq unstuff1 ;1 [19] do remaining work for bit 1
+didUnstuff1:
+ subi cnt, 1 ;1 [20]
+ brcs overflow ;1 [21] loop control
+ eor x2, x1 ;1 [22]
+ bst x2, USBMINUS;1 [23]
+ bld shift, 2 ;1 [24]
+ in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed)
+ andi shift, 0xe7 ;1 [26]
+ breq unstuff2 ;1 [27]
+didUnstuff2:
+ eor x1, x2 ;1 [28]
+ bst x1, USBMINUS;1 [29]
+ bld shift, 3 ;1 [30]
+didUnstuff3:
+ andi shift, 0xcf ;1 [31]
+ breq unstuff3 ;1 [32]
+ in x1, USBIN ;1 [33] <-- sample bit 4
+ eor x2, x1 ;1 [34]
+ bst x2, USBMINUS;1 [35]
+ bld shift, 4 ;1 [36]
+didUnstuff4:
+ andi shift, 0x9f ;1 [37]
+ breq unstuff4 ;1 [38]
+ nop2 ;2 [40]
+ in x2, USBIN ;1 [41] <-- sample bit 5
+ eor x1, x2 ;1 [42]
+ bst x1, USBMINUS;1 [43]
+ bld shift, 5 ;1 [44]
+didUnstuff5:
+ andi shift, 0x3f ;1 [45]
+ breq unstuff5 ;1 [46]
+ nop2 ;2 [48]
+ in x1, USBIN ;1 [49] <-- sample bit 6
+ eor x2, x1 ;1 [50]
+ bst x2, USBMINUS;1 [51]
+ bld shift, 6 ;1 [52]
+didUnstuff6:
+ cpi shift, 0x02 ;1 [53]
+ brlo unstuff6 ;1 [54]
+ nop2 ;2 [56]
+ in x2, USBIN ;1 [57] <-- sample bit 7
+ eor x1, x2 ;1 [58]
+ bst x1, USBMINUS;1 [59]
+ bld shift, 7 ;1 [60]
+didUnstuff7:
+ cpi shift, 0x04 ;1 [61]
+ brsh rxLoop ;2 [63] loop control
+unstuff7:
+ andi x3, ~0x80 ;1 [63]
+ ori shift, 0x80 ;1 [64]
+ in x2, USBIN ;1 [65] <-- sample stuffed bit 7
+ nop ;1 [66]
+ rjmp didUnstuff7 ;2 [68]
+
+macro POP_STANDARD ; 12 cycles
+ pop cnt
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop YH
+ endm
+macro POP_RETI ; 5 cycles
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+#include "asmcommon.inc"
+
+;----------------------------------------------------------------------------
+; Transmitting data
+;----------------------------------------------------------------------------
+
+txByteLoop:
+txBitloop:
+stuffN1Delay: ; [03]
+ ror shift ;[-5] [11] [59]
+ brcc doExorN1 ;[-4] [60]
+ subi x4, 1 ;[-3]
+ brne commonN1 ;[-2]
+ lsl shift ;[-1] compensate ror after rjmp stuffDelay
+ nop ;[00] stuffing consists of just waiting 8 cycles
+ rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear
+
+sendNakAndReti: ;0 [-19] 19 cycles until SOP
+ ldi x3, USBPID_NAK ;1 [-18]
+ rjmp usbSendX3 ;2 [-16]
+sendAckAndReti: ;0 [-19] 19 cycles until SOP
+ ldi x3, USBPID_ACK ;1 [-18]
+ rjmp usbSendX3 ;2 [-16]
+sendCntAndReti: ;0 [-17] 17 cycles until SOP
+ mov x3, cnt ;1 [-16]
+usbSendX3: ;0 [-16]
+ ldi YL, 20 ;1 [-15] 'x3' is R20
+ ldi YH, 0 ;1 [-14]
+ ldi cnt, 2 ;1 [-13]
+; rjmp usbSendAndReti fallthrough
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
+; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
+; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte
+;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt]
+;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
+usbSendAndReti:
+ in x2, USBDDR ;[-12] 12 cycles until SOP
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ out USBDDR, x2 ;[-8] <--- acquire bus
+ in x1, USBOUT ;[-7] port mirror for tx loop
+ ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror)
+ ldi x2, USBMASK ;[-5]
+ push x4 ;[-4]
+doExorN1:
+ eor x1, x2 ;[-2] [06] [62]
+ ldi x4, 6 ;[-1] [07] [63]
+commonN1:
+stuffN2Delay:
+ out USBOUT, x1 ;[00] [08] [64] <--- set bit
+ ror shift ;[01]
+ brcc doExorN2 ;[02]
+ subi x4, 1 ;[03]
+ brne commonN2 ;[04]
+ lsl shift ;[05] compensate ror after rjmp stuffDelay
+ rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear
+doExorN2:
+ eor x1, x2 ;[04] [12]
+ ldi x4, 6 ;[05] [13]
+commonN2:
+ nop ;[06] [14]
+ subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1
+ out USBOUT, x1 ;[08] [16] <--- set bit
+ brcs txBitloop ;[09] [25] [41]
+
+stuff6Delay:
+ ror shift ;[42] [50]
+ brcc doExor6 ;[43]
+ subi x4, 1 ;[44]
+ brne common6 ;[45]
+ lsl shift ;[46] compensate ror after rjmp stuffDelay
+ nop ;[47] stuffing consists of just waiting 8 cycles
+ rjmp stuff6Delay ;[48] after ror, C bit is reliably clear
+doExor6:
+ eor x1, x2 ;[45] [53]
+ ldi x4, 6 ;[46]
+common6:
+stuff7Delay:
+ ror shift ;[47] [55]
+ out USBOUT, x1 ;[48] <--- set bit
+ brcc doExor7 ;[49]
+ subi x4, 1 ;[50]
+ brne common7 ;[51]
+ lsl shift ;[52] compensate ror after rjmp stuffDelay
+ rjmp stuff7Delay ;[53] after ror, C bit is reliably clear
+doExor7:
+ eor x1, x2 ;[51] [59]
+ ldi x4, 6 ;[52]
+common7:
+ ld shift, y+ ;[53]
+ tst cnt ;[55]
+ out USBOUT, x1 ;[56] <--- set bit
+ brne txByteLoop ;[57]
+
+;make SE0:
+ cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles]
+ lds x2, usbNewDeviceAddr;[59]
+ lsl x2 ;[61] we compare with left shifted address
+ subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3
+ sbci YH, 0 ;[63]
+ out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ breq skipAddrAssign ;[01]
+ sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[04]
+ ori x1, USBIDLE ;[05]
+ in x2, USBDDR ;[06]
+ cbr x2, USBMASK ;[07] set both pins to input
+ mov x3, x1 ;[08]
+ cbr x3, USBMASK ;[09] configure no pullup on both pins
+ pop x4 ;[10]
+ nop2 ;[12]
+ nop2 ;[14]
+ out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[17] <-- release bus now
+ out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active
+ rjmp doReturn
diff --git a/usbdrv/usbdrvasm128.inc b/usbdrv/usbdrvasm128.inc
new file mode 100644
index 0000000..bcd6621
--- /dev/null
+++ b/usbdrv/usbdrvasm128.inc
@@ -0,0 +1,750 @@
+/* Name: usbdrvasm128.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2008-10-11
+ * Tabsize: 4
+ * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbdrvasm128.inc 758 2009-08-06 10:12:54Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 12.8 MHz version of the USB driver. It is intended for use
+with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed
+calibration range of the oscillator, almost all AVRs can reach this frequency.
+This version contains a phase locked loop in the receiver routine to cope with
+slight clock rate deviations of up to +/- 1%.
+
+See usbdrv.h for a description of the entire driver.
+
+LIMITATIONS
+===========
+Although it may seem very handy to save the crystal and use the internal
+RC oscillator of the CPU, this method (and this module) has some serious
+limitations:
+(1) The guaranteed calibration range of the oscillator is only 8.1 MHz.
+They typical range is 14.5 MHz and most AVRs can actually reach this rate.
+(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
+the write procedure is timed from the RC oscillator.
+(3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked
+if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may
+cause problems with old hubs which delay SE0 by up to one cycle.
+(4) Code size is much larger than that of the other modules.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+
+Implementation notes:
+======================
+min frequency: 67 cycles for 8 bit -> 12.5625 MHz
+max frequency: 69.286 cycles for 8 bit -> 12.99 MHz
+nominal frequency: 12.77 MHz ( = sqrt(min * max))
+
+sampling positions: (next even number in range [+/- 0.5])
+cycle index range: 0 ... 66
+bits:
+.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125
+[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59]
+
+bit number: 0 1 2 3 4 5 6 7
+spare cycles 1 2 1 2 1 1 1 0
+
+operations to perform: duration cycle
+ ----------------
+ eor fix, shift 1 -> 00
+ andi phase, USBMASK 1 -> 08
+ breq se0 1 -> 16 (moved to 11)
+ st y+, data 2 -> 24, 25
+ mov data, fix 1 -> 33
+ ser data 1 -> 41
+ subi cnt, 1 1 -> 49
+ brcs overflow 1 -> 50
+
+layout of samples and operations:
+[##] = sample bit
+<##> = sample phase
+*##* = operation
+
+0: *00* [01] 02 03 04 <05> 06 07
+1: *08* [09] 10 11 12 <13> 14 15 *16*
+2: [17] 18 19 20 <21> 22 23
+3: *24* *25* [26] 27 28 29 <30> 31 32
+4: *33* [34] 35 36 37 <38> 39 40
+5: *41* [42] 43 44 45 <46> 47 48
+6: *49* *50* [51] 52 53 54 <55> 56 57 58
+7: [59] 60 61 62 <63> 64 65 66
+*****************************************************************************/
+
+/* we prefer positive expressions (do if condition) instead of negative
+ * (skip if condition), therefore use defines for skip instructions:
+ */
+#define ifioclr sbis
+#define ifioset sbic
+#define ifrclr sbrs
+#define ifrset sbrc
+
+/* The registers "fix" and "data" swap their meaning during the loop. Use
+ * defines to keep their name constant.
+ */
+#define fix x2
+#define data x1
+#undef phase /* phase has a default definition to x4 */
+#define phase x3
+
+
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0
+ push YL ;2 push only what is necessary to sync with edge ASAP
+ in YL, SREG ;1
+ push YL ;2
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS ;[0]
+ rjmp foundK ;[1]
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+
+foundK:
+;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
+;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push YH ;[2]
+ lds YL, usbInputBufOffset;[4]
+ clr YH ;[6]
+ subi YL, lo8(-(usbRxBuf));[7]
+ sbci YH, hi8(-(usbRxBuf));[8]
+
+ sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5]
+ rjmp haveTwoBitsK ;[10]
+ pop YH ;[11] undo the push from before
+ rjmp waitForK ;[13] this was not the end of sync, retry
+haveTwoBitsK:
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+#define fix x2
+#define data x1
+
+ push shift ;[12]
+ push x1 ;[14]
+ push x2 ;[16]
+ ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0
+ ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5]
+ ori shift, 1<<0 ;[02]
+ push x3 ;[03]
+ push cnt ;[05]
+ push r0 ;[07]
+ ifioset USBIN, USBMINUS ;[09] <--- bit 1
+ ori shift, 1<<1 ;[10]
+ ser fix ;[11]
+ ldi cnt, USB_BUFSIZE ;[12]
+ mov data, shift ;[13]
+ lsl shift ;[14]
+ nop2 ;[15]
+ ifioset USBIN, USBMINUS ;[17] <--- bit 2
+ ori data, 3<<2 ;[18] store in bit 2 AND bit 3
+ eor shift, data ;[19] do nrzi decoding
+ andi data, 1<<3 ;[20]
+ in phase, USBIN ;[21] <- phase
+ brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1
+ nop ;[23]
+ rjmp entryAfterClr ;[24]
+jumpToEntryAfterSet:
+ rjmp entryAfterSet ;[24]
+
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+#undef fix
+#define fix x1
+#undef data
+#define data x2
+
+bit7IsSet:
+ ifrclr phase, USBMINUS ;[62] check phase only if D- changed
+ lpm ;[63]
+ in phase, USBIN ;[64] <- phase (one cycle too late)
+ ori shift, 1 << 7 ;[65]
+ nop ;[66]
+;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump
+bit0AfterSet:
+ eor fix, shift ;[00]
+#undef fix
+#define fix x2
+#undef data
+#define data x1 /* we now have result in data, fix is reset to 0xff */
+ ifioclr USBIN, USBMINUS ;[01] <--- sample 0
+ rjmp bit0IsClr ;[02]
+ andi shift, ~(7 << 0) ;[03]
+ breq unstuff0s ;[04]
+ in phase, USBIN ;[05] <- phase
+ rjmp bit1AfterSet ;[06]
+unstuff0s:
+ in phase, USBIN ;[06] <- phase (one cycle too late)
+ andi fix, ~(1 << 0) ;[07]
+ ifioclr USBIN, USBMINUS ;[00]
+ ifioset USBIN, USBPLUS ;[01]
+ rjmp bit0IsClr ;[02] executed if first expr false or second true
+se0AndStore: ; executed only if both bits 0
+ st y+, x1 ;[15/17] cycles after start of byte
+ rjmp se0 ;[17/19]
+
+bit0IsClr:
+ ifrset phase, USBMINUS ;[04] check phase only if D- changed
+ lpm ;[05]
+ in phase, USBIN ;[06] <- phase (one cycle too late)
+ ori shift, 1 << 0 ;[07]
+bit1AfterClr:
+ andi phase, USBMASK ;[08]
+ ifioset USBIN, USBMINUS ;[09] <--- sample 1
+ rjmp bit1IsSet ;[10]
+ breq se0AndStore ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0
+ andi shift, ~(7 << 1) ;[12]
+ in phase, USBIN ;[13] <- phase
+ breq unstuff1c ;[14]
+ rjmp bit2AfterClr ;[15]
+unstuff1c:
+ andi fix, ~(1 << 1) ;[16]
+ nop2 ;[08]
+ nop2 ;[10]
+bit1IsSet:
+ ifrclr phase, USBMINUS ;[12] check phase only if D- changed
+ lpm ;[13]
+ in phase, USBIN ;[14] <- phase (one cycle too late)
+ ori shift, 1 << 1 ;[15]
+ nop ;[16]
+bit2AfterSet:
+ ifioclr USBIN, USBMINUS ;[17] <--- sample 2
+ rjmp bit2IsClr ;[18]
+ andi shift, ~(7 << 2) ;[19]
+ breq unstuff2s ;[20]
+ in phase, USBIN ;[21] <- phase
+ rjmp bit3AfterSet ;[22]
+unstuff2s:
+ in phase, USBIN ;[22] <- phase (one cycle too late)
+ andi fix, ~(1 << 2) ;[23]
+ nop2 ;[16]
+ nop2 ;[18]
+bit2IsClr:
+ ifrset phase, USBMINUS ;[20] check phase only if D- changed
+ lpm ;[21]
+ in phase, USBIN ;[22] <- phase (one cycle too late)
+ ori shift, 1 << 2 ;[23]
+bit3AfterClr:
+ st y+, data ;[24]
+entryAfterClr:
+ ifioset USBIN, USBMINUS ;[26] <--- sample 3
+ rjmp bit3IsSet ;[27]
+ andi shift, ~(7 << 3) ;[28]
+ breq unstuff3c ;[29]
+ in phase, USBIN ;[30] <- phase
+ rjmp bit4AfterClr ;[31]
+unstuff3c:
+ in phase, USBIN ;[31] <- phase (one cycle too late)
+ andi fix, ~(1 << 3) ;[32]
+ nop2 ;[25]
+ nop2 ;[27]
+bit3IsSet:
+ ifrclr phase, USBMINUS ;[29] check phase only if D- changed
+ lpm ;[30]
+ in phase, USBIN ;[31] <- phase (one cycle too late)
+ ori shift, 1 << 3 ;[32]
+bit4AfterSet:
+ mov data, fix ;[33] undo this move by swapping defines
+#undef fix
+#define fix x1
+#undef data
+#define data x2
+ ifioclr USBIN, USBMINUS ;[34] <--- sample 4
+ rjmp bit4IsClr ;[35]
+ andi shift, ~(7 << 4) ;[36]
+ breq unstuff4s ;[37]
+ in phase, USBIN ;[38] <- phase
+ rjmp bit5AfterSet ;[39]
+unstuff4s:
+ in phase, USBIN ;[39] <- phase (one cycle too late)
+ andi fix, ~(1 << 4) ;[40]
+ nop2 ;[33]
+ nop2 ;[35]
+bit4IsClr:
+ ifrset phase, USBMINUS ;[37] check phase only if D- changed
+ lpm ;[38]
+ in phase, USBIN ;[39] <- phase (one cycle too late)
+ ori shift, 1 << 4 ;[40]
+bit5AfterClr:
+ ser data ;[41]
+ ifioset USBIN, USBMINUS ;[42] <--- sample 5
+ rjmp bit5IsSet ;[43]
+ andi shift, ~(7 << 5) ;[44]
+ breq unstuff5c ;[45]
+ in phase, USBIN ;[46] <- phase
+ rjmp bit6AfterClr ;[47]
+unstuff5c:
+ in phase, USBIN ;[47] <- phase (one cycle too late)
+ andi fix, ~(1 << 5) ;[48]
+ nop2 ;[41]
+ nop2 ;[43]
+bit5IsSet:
+ ifrclr phase, USBMINUS ;[45] check phase only if D- changed
+ lpm ;[46]
+ in phase, USBIN ;[47] <- phase (one cycle too late)
+ ori shift, 1 << 5 ;[48]
+bit6AfterSet:
+ subi cnt, 1 ;[49]
+ brcs jumpToOverflow ;[50]
+ ifioclr USBIN, USBMINUS ;[51] <--- sample 6
+ rjmp bit6IsClr ;[52]
+ andi shift, ~(3 << 6) ;[53]
+ cpi shift, 2 ;[54]
+ in phase, USBIN ;[55] <- phase
+ brlt unstuff6s ;[56]
+ rjmp bit7AfterSet ;[57]
+
+jumpToOverflow:
+ rjmp overflow
+
+unstuff6s:
+ andi fix, ~(1 << 6) ;[50]
+ lpm ;[51]
+bit6IsClr:
+ ifrset phase, USBMINUS ;[54] check phase only if D- changed
+ lpm ;[55]
+ in phase, USBIN ;[56] <- phase (one cycle too late)
+ ori shift, 1 << 6 ;[57]
+ nop ;[58]
+bit7AfterClr:
+ ifioset USBIN, USBMINUS ;[59] <--- sample 7
+ rjmp bit7IsSet ;[60]
+ andi shift, ~(1 << 7) ;[61]
+ cpi shift, 4 ;[62]
+ in phase, USBIN ;[63] <- phase
+ brlt unstuff7c ;[64]
+ rjmp bit0AfterClr ;[65] -> [00] == [67]
+unstuff7c:
+ andi fix, ~(1 << 7) ;[58]
+ nop ;[59]
+ rjmp bit7IsSet ;[60]
+
+bit7IsClr:
+ ifrset phase, USBMINUS ;[62] check phase only if D- changed
+ lpm ;[63]
+ in phase, USBIN ;[64] <- phase (one cycle too late)
+ ori shift, 1 << 7 ;[65]
+ nop ;[66]
+;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump
+bit0AfterClr:
+ eor fix, shift ;[00]
+#undef fix
+#define fix x2
+#undef data
+#define data x1 /* we now have result in data, fix is reset to 0xff */
+ ifioset USBIN, USBMINUS ;[01] <--- sample 0
+ rjmp bit0IsSet ;[02]
+ andi shift, ~(7 << 0) ;[03]
+ breq unstuff0c ;[04]
+ in phase, USBIN ;[05] <- phase
+ rjmp bit1AfterClr ;[06]
+unstuff0c:
+ in phase, USBIN ;[06] <- phase (one cycle too late)
+ andi fix, ~(1 << 0) ;[07]
+ ifioclr USBIN, USBMINUS ;[00]
+ ifioset USBIN, USBPLUS ;[01]
+ rjmp bit0IsSet ;[02] executed if first expr false or second true
+ rjmp se0AndStore ;[03] executed only if both bits 0
+bit0IsSet:
+ ifrclr phase, USBMINUS ;[04] check phase only if D- changed
+ lpm ;[05]
+ in phase, USBIN ;[06] <- phase (one cycle too late)
+ ori shift, 1 << 0 ;[07]
+bit1AfterSet:
+ andi shift, ~(7 << 1) ;[08] compensated by "ori shift, 1<<1" if bit1IsClr
+ ifioclr USBIN, USBMINUS ;[09] <--- sample 1
+ rjmp bit1IsClr ;[10]
+ breq unstuff1s ;[11]
+ nop2 ;[12] do not check for SE0 if bit 0 was 1
+ in phase, USBIN ;[14] <- phase (one cycle too late)
+ rjmp bit2AfterSet ;[15]
+unstuff1s:
+ in phase, USBIN ;[13] <- phase
+ andi fix, ~(1 << 1) ;[14]
+ lpm ;[07]
+ nop2 ;[10]
+bit1IsClr:
+ ifrset phase, USBMINUS ;[12] check phase only if D- changed
+ lpm ;[13]
+ in phase, USBIN ;[14] <- phase (one cycle too late)
+ ori shift, 1 << 1 ;[15]
+ nop ;[16]
+bit2AfterClr:
+ ifioset USBIN, USBMINUS ;[17] <--- sample 2
+ rjmp bit2IsSet ;[18]
+ andi shift, ~(7 << 2) ;[19]
+ breq unstuff2c ;[20]
+ in phase, USBIN ;[21] <- phase
+ rjmp bit3AfterClr ;[22]
+unstuff2c:
+ in phase, USBIN ;[22] <- phase (one cycle too late)
+ andi fix, ~(1 << 2) ;[23]
+ nop2 ;[16]
+ nop2 ;[18]
+bit2IsSet:
+ ifrclr phase, USBMINUS ;[20] check phase only if D- changed
+ lpm ;[21]
+ in phase, USBIN ;[22] <- phase (one cycle too late)
+ ori shift, 1 << 2 ;[23]
+bit3AfterSet:
+ st y+, data ;[24]
+entryAfterSet:
+ ifioclr USBIN, USBMINUS ;[26] <--- sample 3
+ rjmp bit3IsClr ;[27]
+ andi shift, ~(7 << 3) ;[28]
+ breq unstuff3s ;[29]
+ in phase, USBIN ;[30] <- phase
+ rjmp bit4AfterSet ;[31]
+unstuff3s:
+ in phase, USBIN ;[31] <- phase (one cycle too late)
+ andi fix, ~(1 << 3) ;[32]
+ nop2 ;[25]
+ nop2 ;[27]
+bit3IsClr:
+ ifrset phase, USBMINUS ;[29] check phase only if D- changed
+ lpm ;[30]
+ in phase, USBIN ;[31] <- phase (one cycle too late)
+ ori shift, 1 << 3 ;[32]
+bit4AfterClr:
+ mov data, fix ;[33] undo this move by swapping defines
+#undef fix
+#define fix x1
+#undef data
+#define data x2
+ ifioset USBIN, USBMINUS ;[34] <--- sample 4
+ rjmp bit4IsSet ;[35]
+ andi shift, ~(7 << 4) ;[36]
+ breq unstuff4c ;[37]
+ in phase, USBIN ;[38] <- phase
+ rjmp bit5AfterClr ;[39]
+unstuff4c:
+ in phase, USBIN ;[39] <- phase (one cycle too late)
+ andi fix, ~(1 << 4) ;[40]
+ nop2 ;[33]
+ nop2 ;[35]
+bit4IsSet:
+ ifrclr phase, USBMINUS ;[37] check phase only if D- changed
+ lpm ;[38]
+ in phase, USBIN ;[39] <- phase (one cycle too late)
+ ori shift, 1 << 4 ;[40]
+bit5AfterSet:
+ ser data ;[41]
+ ifioclr USBIN, USBMINUS ;[42] <--- sample 5
+ rjmp bit5IsClr ;[43]
+ andi shift, ~(7 << 5) ;[44]
+ breq unstuff5s ;[45]
+ in phase, USBIN ;[46] <- phase
+ rjmp bit6AfterSet ;[47]
+unstuff5s:
+ in phase, USBIN ;[47] <- phase (one cycle too late)
+ andi fix, ~(1 << 5) ;[48]
+ nop2 ;[41]
+ nop2 ;[43]
+bit5IsClr:
+ ifrset phase, USBMINUS ;[45] check phase only if D- changed
+ lpm ;[46]
+ in phase, USBIN ;[47] <- phase (one cycle too late)
+ ori shift, 1 << 5 ;[48]
+bit6AfterClr:
+ subi cnt, 1 ;[49]
+ brcs overflow ;[50]
+ ifioset USBIN, USBMINUS ;[51] <--- sample 6
+ rjmp bit6IsSet ;[52]
+ andi shift, ~(3 << 6) ;[53]
+ cpi shift, 2 ;[54]
+ in phase, USBIN ;[55] <- phase
+ brlt unstuff6c ;[56]
+ rjmp bit7AfterClr ;[57]
+unstuff6c:
+ andi fix, ~(1 << 6) ;[50]
+ lpm ;[51]
+bit6IsSet:
+ ifrclr phase, USBMINUS ;[54] check phase only if D- changed
+ lpm ;[55]
+ in phase, USBIN ;[56] <- phase (one cycle too late)
+ ori shift, 1 << 6 ;[57]
+bit7AfterSet:
+ ifioclr USBIN, USBMINUS ;[59] <--- sample 7
+ rjmp bit7IsClr ;[60]
+ andi shift, ~(1 << 7) ;[61]
+ cpi shift, 4 ;[62]
+ in phase, USBIN ;[63] <- phase
+ brlt unstuff7s ;[64]
+ rjmp bit0AfterSet ;[65] -> [00] == [67]
+unstuff7s:
+ andi fix, ~(1 << 7) ;[58]
+ nop ;[59]
+ rjmp bit7IsClr ;[60]
+
+macro POP_STANDARD ; 14 cycles
+ pop r0
+ pop cnt
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop YH
+ endm
+macro POP_RETI ; 5 cycles
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+#include "asmcommon.inc"
+
+;----------------------------------------------------------------------------
+; Transmitting data
+;----------------------------------------------------------------------------
+
+txByteLoop:
+txBitloop:
+stuffN1Delay: ; [03]
+ ror shift ;[-5] [11] [63]
+ brcc doExorN1 ;[-4] [64]
+ subi x3, 1 ;[-3]
+ brne commonN1 ;[-2]
+ lsl shift ;[-1] compensate ror after rjmp stuffDelay
+ nop ;[00] stuffing consists of just waiting 8 cycles
+ rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear
+
+sendNakAndReti:
+ ldi cnt, USBPID_NAK ;[-19]
+ rjmp sendCntAndReti ;[-18]
+sendAckAndReti:
+ ldi cnt, USBPID_ACK ;[-17]
+sendCntAndReti:
+ mov r0, cnt ;[-16]
+ ldi YL, 0 ;[-15] R0 address is 0
+ ldi YH, 0 ;[-14]
+ ldi cnt, 2 ;[-13]
+; rjmp usbSendAndReti fallthrough
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
+; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
+; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte
+;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt]
+;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
+usbSendAndReti:
+ in x2, USBDDR ;[-10] 10 cycles until SOP
+ ori x2, USBMASK ;[-9]
+ sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups)
+ out USBDDR, x2 ;[-6] <--- acquire bus
+ in x1, USBOUT ;[-5] port mirror for tx loop
+ ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror)
+ ldi x2, USBMASK ;[-3]
+doExorN1:
+ eor x1, x2 ;[-2] [06] [62]
+ ldi x3, 6 ;[-1] [07] [63]
+commonN1:
+stuffN2Delay:
+ out USBOUT, x1 ;[00] [08] [64] <--- set bit
+ ror shift ;[01]
+ brcc doExorN2 ;[02]
+ subi x3, 1 ;[03]
+ brne commonN2 ;[04]
+ lsl shift ;[05] compensate ror after rjmp stuffDelay
+ rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear
+doExorN2:
+ eor x1, x2 ;[04] [12]
+ ldi x3, 6 ;[05] [13]
+commonN2:
+ nop2 ;[06] [14]
+ subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1
+ out USBOUT, x1 ;[09] [17] <--- set bit
+ brcs txBitloop ;[10] [27] [44]
+
+stuff6Delay:
+ ror shift ;[45] [53]
+ brcc doExor6 ;[46]
+ subi x3, 1 ;[47]
+ brne common6 ;[48]
+ lsl shift ;[49] compensate ror after rjmp stuffDelay
+ nop ;[50] stuffing consists of just waiting 8 cycles
+ rjmp stuff6Delay ;[51] after ror, C bit is reliably clear
+doExor6:
+ eor x1, x2 ;[48] [56]
+ ldi x3, 6 ;[49]
+common6:
+stuff7Delay:
+ ror shift ;[50] [58]
+ out USBOUT, x1 ;[51] <--- set bit
+ brcc doExor7 ;[52]
+ subi x3, 1 ;[53]
+ brne common7 ;[54]
+ lsl shift ;[55] compensate ror after rjmp stuffDelay
+ rjmp stuff7Delay ;[56] after ror, C bit is reliably clear
+doExor7:
+ eor x1, x2 ;[54] [62]
+ ldi x3, 6 ;[55]
+common7:
+ ld shift, y+ ;[56]
+ nop ;[58]
+ tst cnt ;[59]
+ out USBOUT, x1 ;[60] [00]<--- set bit
+ brne txByteLoop ;[61] [01]
+;make SE0:
+ cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles]
+ lds x2, usbNewDeviceAddr;[03]
+ lsl x2 ;[05] we compare with left shifted address
+ subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0
+ sbci YH, 0 ;[07]
+ out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ breq skipAddrAssign ;[01]
+ sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[04]
+ ori x1, USBIDLE ;[05]
+ in x2, USBDDR ;[06]
+ cbr x2, USBMASK ;[07] set both pins to input
+ mov x3, x1 ;[08]
+ cbr x3, USBMASK ;[09] configure no pullup on both pins
+ lpm ;[10]
+ lpm ;[13]
+ out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[17] <-- release bus now
+ out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active
+ rjmp doReturn
+
+
+
+/*****************************************************************************
+The following PHP script generates a code skeleton for the receiver routine:
+
+<?php
+
+function printCmdBuffer($thisBit)
+{
+global $cycle;
+
+ $nextBit = ($thisBit + 1) % 8;
+ $s = ob_get_contents();
+ ob_end_clean();
+ $s = str_replace("#", $thisBit, $s);
+ $s = str_replace("@", $nextBit, $s);
+ $lines = explode("\n", $s);
+ for($i = 0; $i < count($lines); $i++){
+ $s = $lines[$i];
+ if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){
+ $c = $cycle + (int)$regs[1];
+ $s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s);
+ }
+ if(strlen($s) > 0)
+ echo "$s\n";
+ }
+}
+
+function printBit($isAfterSet, $bitNum)
+{
+ ob_start();
+ if($isAfterSet){
+?>
+ ifioclr USBIN, USBMINUS ;[00] <--- sample
+ rjmp bit#IsClr ;[01]
+ andi shift, ~(7 << #) ;[02]
+ breq unstuff#s ;[03]
+ in phase, USBIN ;[04] <- phase
+ rjmp bit@AfterSet ;[05]
+unstuff#s:
+ in phase, USBIN ;[05] <- phase (one cycle too late)
+ andi fix, ~(1 << #) ;[06]
+ nop2 ;[-1]
+ nop2 ;[01]
+bit#IsClr:
+ ifrset phase, USBMINUS ;[03] check phase only if D- changed
+ lpm ;[04]
+ in phase, USBIN ;[05] <- phase (one cycle too late)
+ ori shift, 1 << # ;[06]
+<?php
+ }else{
+?>
+ ifioset USBIN, USBMINUS ;[00] <--- sample
+ rjmp bit#IsSet ;[01]
+ andi shift, ~(7 << #) ;[02]
+ breq unstuff#c ;[03]
+ in phase, USBIN ;[04] <- phase
+ rjmp bit@AfterClr ;[05]
+unstuff#c:
+ in phase, USBIN ;[05] <- phase (one cycle too late)
+ andi fix, ~(1 << #) ;[06]
+ nop2 ;[-1]
+ nop2 ;[01]
+bit#IsSet:
+ ifrclr phase, USBMINUS ;[03] check phase only if D- changed
+ lpm ;[04]
+ in phase, USBIN ;[05] <- phase (one cycle too late)
+ ori shift, 1 << # ;[06]
+<?php
+ }
+ printCmdBuffer($bitNum);
+}
+
+$bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59);
+for($i = 0; $i < 16; $i++){
+ $bit = $i % 8;
+ $emitClrCode = ($i + (int)($i / 8)) % 2;
+ $cycle = $bitStartCycles[$bit];
+ if($emitClrCode){
+ printf("bit%dAfterClr:\n", $bit);
+ }else{
+ printf("bit%dAfterSet:\n", $bit);
+ }
+ ob_start();
+ echo " ***** ;[-1]\n";
+ printCmdBuffer($bit);
+ printBit(!$emitClrCode, $bit);
+ if($i == 7)
+ echo "\n";
+}
+
+?>
+*****************************************************************************/
diff --git a/usbdrv/usbdrvasm15.inc b/usbdrv/usbdrvasm15.inc
new file mode 100644
index 0000000..401b7f8
--- /dev/null
+++ b/usbdrv/usbdrvasm15.inc
@@ -0,0 +1,423 @@
+/* Name: usbdrvasm15.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: contributed by V. Bosch
+ * Creation Date: 2007-08-06
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm15.inc 740 2009-04-13 18:23:31Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 15 MHz version of the asssembler part of the USB driver. It
+requires a 15 MHz crystal (not a ceramic resonator and not a calibrated RC
+oscillator).
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes
+;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte
+; Numbers in brackets are clocks counted from center of last sync bit
+; when instruction starts
+
+;----------------------------------------------------------------------------
+; order of registers pushed:
+; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4
+;----------------------------------------------------------------------------
+USB_INTR_VECTOR:
+ push YL ;2 push only what is necessary to sync with edge ASAP
+ in YL, SREG ;1
+ push YL ;2
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;
+; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+; sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+;-------------------------------------------------------------------------------
+; The following code results in a sampling window of < 1/4 bit
+; which meets the spec.
+;-------------------------------------------------------------------------------
+waitForK: ;-
+ sbis USBIN, USBMINUS ;1 [00] <-- sample
+ rjmp foundK ;2 [01]
+ sbis USBIN, USBMINUS ; <-- sample
+ rjmp foundK
+ sbis USBIN, USBMINUS ; <-- sample
+ rjmp foundK
+ sbis USBIN, USBMINUS ; <-- sample
+ rjmp foundK
+ sbis USBIN, USBMINUS ; <-- sample
+ rjmp foundK
+ sbis USBIN, USBMINUS ; <-- sample
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+;------------------------------------------------------------------------------
+; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for
+; center sampling]
+; we have 1 bit time for setup purposes, then sample again.
+; Numbers in brackets are cycles from center of first sync (double K)
+; bit after the instruction
+;------------------------------------------------------------------------------
+foundK: ;- [02]
+ lds YL, usbInputBufOffset;2 [03+04] tx loop
+ push YH ;2 [05+06]
+ clr YH ;1 [07]
+ subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init]
+ push shift ;2 [10+11]
+ ser shift ;1 [12]
+ sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early)
+ rjmp haveTwoBitsK ;2 [00] [14]
+ pop shift ;2 [15+16] undo the push from before
+ pop YH ;2 [17+18] undo the push from before
+ rjmp waitForK ;2 [19+20] this was not the end of sync, retry
+; The entire loop from waitForK until rjmp waitForK above must not exceed two
+; bit times (= 20 cycles).
+
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+haveTwoBitsK: ;- [01]
+ push x1 ;2 [02+03]
+ push x2 ;2 [04+05]
+ push x3 ;2 [06+07]
+ push bitcnt ;2 [08+09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 0
+ bst x1, USBMINUS ;1 [01]
+ bld shift, 0 ;1 [02]
+ push cnt ;2 [03+04]
+ ldi cnt, USB_BUFSIZE ;1 [05]
+ push x4 ;2 [06+07] tx loop
+ rjmp rxLoop ;2 [08]
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+unstuff0: ;- [07] (branch taken)
+ andi x3, ~0x01 ;1 [08]
+ mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit
+ in x2, USBIN ;1 [00] [10] <-- sample bit 1 again
+ andi x2, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 1
+ ori shift, 0x01 ;1 [03] 0b00000001
+ nop ;1 [04]
+ rjmp didUnstuff0 ;2 [05]
+;-----------------------------------------------------
+unstuff1: ;- [05] (branch taken)
+ mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit
+ andi x3, ~0x02 ;1 [07]
+ ori shift, 0x02 ;1 [08] 0b00000010
+ nop ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 2 again
+ andi x1, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 2
+ rjmp didUnstuff1 ;2 [03]
+;-----------------------------------------------------
+unstuff2: ;- [05] (branch taken)
+ andi x3, ~0x04 ;1 [06]
+ ori shift, 0x04 ;1 [07] 0b00000100
+ mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit
+ nop ;1 [09]
+ in x2, USBIN ;1 [00] [10] <-- sample bit 3
+ andi x2, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 3
+ rjmp didUnstuff2 ;2 [03]
+;-----------------------------------------------------
+unstuff3: ;- [00] [10] (branch taken)
+ in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late
+ andi x2, USBMASK ;1 [02]
+ breq se0Hop ;1 [03] SE0 check for stuffed bit 3
+ andi x3, ~0x08 ;1 [04]
+ ori shift, 0x08 ;1 [05] 0b00001000
+ rjmp didUnstuff3 ;2 [06]
+;----------------------------------------------------------------------------
+; extra jobs done during bit interval:
+;
+; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs],
+; overflow check, jump to the head of rxLoop
+; bit 1: SE0 check
+; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long]
+; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long]
+; bit 4: SE0 check, none
+; bit 5: SE0 check, none
+; bit 6: SE0 check, none
+; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others
+;----------------------------------------------------------------------------
+rxLoop: ;- [09]
+ in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed)
+ andi x2, USBMASK ;1 [01]
+ brne SkipSe0Hop ;1 [02]
+se0Hop: ;- [02]
+ rjmp se0 ;2 [03] SE0 check for bit 1
+SkipSe0Hop: ;- [03]
+ ser x3 ;1 [04]
+ andi shift, 0xf9 ;1 [05] 0b11111001
+ breq unstuff0 ;1 [06]
+didUnstuff0: ;- [06]
+ eor x1, x2 ;1 [07]
+ bst x1, USBMINUS ;1 [08]
+ bld shift, 1 ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed)
+ andi x1, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 2
+ andi shift, 0xf3 ;1 [03] 0b11110011
+ breq unstuff1 ;1 [04] do remaining work for bit 1
+didUnstuff1: ;- [04]
+ eor x2, x1 ;1 [05]
+ bst x2, USBMINUS ;1 [06]
+ bld shift, 2 ;1 [07]
+ nop2 ;2 [08+09]
+ in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed)
+ andi x2, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 3
+ andi shift, 0xe7 ;1 [03] 0b11100111
+ breq unstuff2 ;1 [04]
+didUnstuff2: ;- [04]
+ eor x1, x2 ;1 [05]
+ bst x1, USBMINUS ;1 [06]
+ bld shift, 3 ;1 [07]
+didUnstuff3: ;- [07]
+ andi shift, 0xcf ;1 [08] 0b11001111
+ breq unstuff3 ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 4
+ andi x1, USBMASK ;1 [01]
+ breq se0Hop ;1 [02] SE0 check for bit 4
+ eor x2, x1 ;1 [03]
+ bst x2, USBMINUS ;1 [04]
+ bld shift, 4 ;1 [05]
+didUnstuff4: ;- [05]
+ andi shift, 0x9f ;1 [06] 0b10011111
+ breq unstuff4 ;1 [07]
+ nop2 ;2 [08+09]
+ in x2, USBIN ;1 [00] [10] <-- sample bit 5
+ andi x2, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for bit 5
+ eor x1, x2 ;1 [03]
+ bst x1, USBMINUS ;1 [04]
+ bld shift, 5 ;1 [05]
+didUnstuff5: ;- [05]
+ andi shift, 0x3f ;1 [06] 0b00111111
+ breq unstuff5 ;1 [07]
+ nop2 ;2 [08+09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 6
+ andi x1, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for bit 6
+ eor x2, x1 ;1 [03]
+ bst x2, USBMINUS ;1 [04]
+ bld shift, 6 ;1 [05]
+didUnstuff6: ;- [05]
+ cpi shift, 0x02 ;1 [06] 0b00000010
+ brlo unstuff6 ;1 [07]
+ nop2 ;2 [08+09]
+ in x2, USBIN ;1 [00] [10] <-- sample bit 7
+ andi x2, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for bit 7
+ eor x1, x2 ;1 [03]
+ bst x1, USBMINUS ;1 [04]
+ bld shift, 7 ;1 [05]
+didUnstuff7: ;- [05]
+ cpi shift, 0x04 ;1 [06] 0b00000100
+ brlo unstuff7 ;1 [07]
+ eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others
+ nop ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample bit 0
+ st y+, x3 ;2 [01+02] store data
+ eor x2, x1 ;1 [03]
+ bst x2, USBMINUS ;1 [04]
+ bld shift, 0 ;1 [05]
+ subi cnt, 1 ;1 [06]
+ brcs overflow ;1 [07]
+ rjmp rxLoop ;2 [08]
+;-----------------------------------------------------
+unstuff4: ;- [08]
+ andi x3, ~0x10 ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4
+ andi x1, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for stuffed bit 4
+ ori shift, 0x10 ;1 [03]
+ rjmp didUnstuff4 ;2 [04]
+;-----------------------------------------------------
+unstuff5: ;- [08]
+ ori shift, 0x20 ;1 [09]
+ in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5
+ andi x2, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for stuffed bit 5
+ andi x3, ~0x20 ;1 [03]
+ rjmp didUnstuff5 ;2 [04]
+;-----------------------------------------------------
+unstuff6: ;- [08]
+ andi x3, ~0x40 ;1 [09]
+ in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6
+ andi x1, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for stuffed bit 6
+ ori shift, 0x40 ;1 [03]
+ rjmp didUnstuff6 ;2 [04]
+;-----------------------------------------------------
+unstuff7: ;- [08]
+ andi x3, ~0x80 ;1 [09]
+ in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7
+ andi x2, USBMASK ;1 [01]
+ breq se0 ;1 [02] SE0 check for stuffed bit 7
+ ori shift, 0x80 ;1 [03]
+ rjmp didUnstuff7 ;2 [04]
+
+macro POP_STANDARD ; 16 cycles
+ pop x4
+ pop cnt
+ pop bitcnt
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop YH
+ endm
+macro POP_RETI ; 5 cycles
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+#include "asmcommon.inc"
+
+;---------------------------------------------------------------------------
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1)
+; K = (D+ = 1), (D- = 0)
+; Spec allows 7.5 bit times from EOP to SOP for replies
+;---------------------------------------------------------------------------
+bitstuffN: ;- [04]
+ eor x1, x4 ;1 [05]
+ clr x2 ;1 [06]
+ nop ;1 [07]
+ rjmp didStuffN ;1 [08]
+;---------------------------------------------------------------------------
+bitstuff6: ;- [04]
+ eor x1, x4 ;1 [05]
+ clr x2 ;1 [06]
+ rjmp didStuff6 ;1 [07]
+;---------------------------------------------------------------------------
+bitstuff7: ;- [02]
+ eor x1, x4 ;1 [03]
+ clr x2 ;1 [06]
+ nop ;1 [05]
+ rjmp didStuff7 ;1 [06]
+;---------------------------------------------------------------------------
+sendNakAndReti: ;- [-19]
+ ldi x3, USBPID_NAK ;1 [-18]
+ rjmp sendX3AndReti ;1 [-17]
+;---------------------------------------------------------------------------
+sendAckAndReti: ;- [-17]
+ ldi cnt, USBPID_ACK ;1 [-16]
+sendCntAndReti: ;- [-16]
+ mov x3, cnt ;1 [-15]
+sendX3AndReti: ;- [-15]
+ ldi YL, 20 ;1 [-14] x3==r20 address is 20
+ ldi YH, 0 ;1 [-13]
+ ldi cnt, 2 ;1 [-12]
+; rjmp usbSendAndReti fallthrough
+;---------------------------------------------------------------------------
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
+;uses: x1...x4, btcnt, shift, cnt, Y
+;Numbers in brackets are time since first bit of sync pattern is sent
+;We need not to match the transfer rate exactly because the spec demands
+;only 1.5% precision anyway.
+usbSendAndReti: ;- [-13] 13 cycles until SOP
+ in x2, USBDDR ;1 [-12]
+ ori x2, USBMASK ;1 [-11]
+ sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;1 [-08] port mirror for tx loop
+ out USBDDR, x2 ;1 [-07] <- acquire bus
+ ; need not init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;1 [-06] exor mask
+ ldi shift, 0x80 ;1 [-05] sync byte is first byte sent
+ ldi bitcnt, 6 ;1 [-04]
+txBitLoop: ;- [-04] [06]
+ sbrs shift, 0 ;1 [-03] [07]
+ eor x1, x4 ;1 [-02] [08]
+ ror shift ;1 [-01] [09]
+didStuffN: ;- [09]
+ out USBOUT, x1 ;1 [00] [10] <-- out N
+ ror x2 ;1 [01]
+ cpi x2, 0xfc ;1 [02]
+ brcc bitstuffN ;1 [03]
+ dec bitcnt ;1 [04]
+ brne txBitLoop ;1 [05]
+ sbrs shift, 0 ;1 [06]
+ eor x1, x4 ;1 [07]
+ ror shift ;1 [08]
+didStuff6: ;- [08]
+ nop ;1 [09]
+ out USBOUT, x1 ;1 [00] [10] <-- out 6
+ ror x2 ;1 [01]
+ cpi x2, 0xfc ;1 [02]
+ brcc bitstuff6 ;1 [03]
+ sbrs shift, 0 ;1 [04]
+ eor x1, x4 ;1 [05]
+ ror shift ;1 [06]
+ ror x2 ;1 [07]
+didStuff7: ;- [07]
+ ldi bitcnt, 6 ;1 [08]
+ cpi x2, 0xfc ;1 [09]
+ out USBOUT, x1 ;1 [00] [10] <-- out 7
+ brcc bitstuff7 ;1 [01]
+ ld shift, y+ ;2 [02+03]
+ dec cnt ;1 [04]
+ brne txBitLoop ;1 [05]
+makeSE0:
+ cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles]
+ lds x2, usbNewDeviceAddr;2 [07+08]
+ lsl x2 ;1 [09] we compare with left shifted address
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle
+ subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3
+ sbci YH, 0 ;1 [02]
+ breq skipAddrAssign ;1 [03]
+ sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer
+;----------------------------------------------------------------------------
+;end of usbDeviceAddress transfer
+skipAddrAssign: ;- [03/04]
+ ldi x2, 1<<USB_INTR_PENDING_BIT ;1 [05] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;1 [06]
+ ori x1, USBIDLE ;1 [07]
+ in x2, USBDDR ;1 [08]
+ cbr x2, USBMASK ;1 [09] set both pins to input
+ mov x3, x1 ;1 [10]
+ cbr x3, USBMASK ;1 [11] configure no pullup on both pins
+ ldi x4, 3 ;1 [12]
+se0Delay: ;- [12] [15]
+ dec x4 ;1 [13] [16]
+ brne se0Delay ;1 [14] [17]
+ nop2 ;2 [18+19]
+ out USBOUT, x1 ;1 [20] <--out J (idle) -- end of SE0 (EOP sig.)
+ out USBDDR, x2 ;1 [21] <--release bus now
+ out USBOUT, x3 ;1 [22] <--ensure no pull-up resistors are active
+ rjmp doReturn ;1 [23]
+;---------------------------------------------------------------------------
diff --git a/usbdrv/usbdrvasm16.inc b/usbdrv/usbdrvasm16.inc
new file mode 100644
index 0000000..3ff5587
--- /dev/null
+++ b/usbdrv/usbdrvasm16.inc
@@ -0,0 +1,349 @@
+/* Name: usbdrvasm16.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2007-06-15
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm16.inc 760 2009-08-09 18:59:43Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 16 MHz version of the asssembler part of the USB driver. It
+requires a 16 MHz crystal (not a ceramic resonator and not a calibrated RC
+oscillator).
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes
+;nominal frequency: 16 MHz -> 10.6666666 cycles per bit, 85.333333333 cycles per byte
+; Numbers in brackets are clocks counted from center of last sync bit
+; when instruction starts
+
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt
+ push YL ;[-25] push only what is necessary to sync with edge ASAP
+ in YL, SREG ;[-23]
+ push YL ;[-22]
+ push YH ;[-20]
+#ifdef USB_START_IRQ_HOOK
+ USB_START_IRQ_HOOK
+#endif
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of < 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS ;[-15]
+ rjmp foundK ;[-14]
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+foundK: ;[-12]
+;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
+;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push bitcnt ;[-12]
+; [---] ;[-11]
+ lds YL, usbInputBufOffset;[-10]
+; [---] ;[-9]
+ clr YH ;[-8]
+ subi YL, lo8(-(usbRxBuf));[-7] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init]
+ push shift ;[-5]
+; [---] ;[-4]
+ ldi bitcnt, 0x55 ;[-3] [rx loop init]
+ sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early)
+ rjmp haveTwoBitsK ;[-1]
+ pop shift ;[0] undo the push from before
+ pop bitcnt ;[2] undo the push from before
+ rjmp waitForK ;[4] this was not the end of sync, retry
+; The entire loop from waitForK until rjmp waitForK above must not exceed two
+; bit times (= 21 cycles).
+
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+haveTwoBitsK:
+ push x1 ;[1]
+ push x2 ;[3]
+ push x3 ;[5]
+ ldi shift, 0 ;[7]
+ ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that
+ push x4 ;[9] == leap
+
+ in x1, USBIN ;[11] <-- sample bit 0
+ andi x1, USBMASK ;[12]
+ bst x1, USBMINUS ;[13]
+ bld shift, 7 ;[14]
+ push cnt ;[15]
+ ldi leap, 0 ;[17] [rx loop init]
+ ldi cnt, USB_BUFSIZE;[18] [rx loop init]
+ rjmp rxbit1 ;[19] arrives at [21]
+
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+
+; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap"
+; accordingly to approximate this value in the long run.
+
+unstuff6:
+ andi x2, USBMASK ;[03]
+ ori x3, 1<<6 ;[04] will not be shifted any more
+ andi shift, ~0x80;[05]
+ mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6
+ subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3
+ rjmp didUnstuff6 ;[08]
+
+unstuff7:
+ ori x3, 1<<7 ;[09] will not be shifted any more
+ in x2, USBIN ;[00] [10] re-sample bit 7
+ andi x2, USBMASK ;[01]
+ andi shift, ~0x80;[02]
+ subi leap, 2 ;[03] total duration = 10 bits -> add 1/3
+ rjmp didUnstuff7 ;[04]
+
+unstuffEven:
+ ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0
+ in x1, USBIN ;[00] [10]
+ andi shift, ~0x80;[01]
+ andi x1, USBMASK ;[02]
+ breq se0 ;[03]
+ subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
+ nop2 ;[05]
+ rjmp didUnstuffE ;[06]
+
+unstuffOdd:
+ ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1
+ in x2, USBIN ;[00] [10]
+ andi shift, ~0x80;[01]
+ andi x2, USBMASK ;[02]
+ breq se0 ;[03]
+ subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3
+ nop2 ;[05]
+ rjmp didUnstuffO ;[06]
+
+rxByteLoop:
+ andi x1, USBMASK ;[03]
+ eor x2, x1 ;[04]
+ subi leap, 1 ;[05]
+ brpl skipLeap ;[06]
+ subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte
+ nop ;1
+skipLeap:
+ subi x2, 1 ;[08]
+ ror shift ;[09]
+didUnstuff6:
+ cpi shift, 0xfc ;[10]
+ in x2, USBIN ;[00] [11] <-- sample bit 7
+ brcc unstuff6 ;[01]
+ andi x2, USBMASK ;[02]
+ eor x1, x2 ;[03]
+ subi x1, 1 ;[04]
+ ror shift ;[05]
+didUnstuff7:
+ cpi shift, 0xfc ;[06]
+ brcc unstuff7 ;[07]
+ eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others
+ st y+, x3 ;[09] store data
+rxBitLoop:
+ in x1, USBIN ;[00] [11] <-- sample bit 0/2/4
+ andi x1, USBMASK ;[01]
+ eor x2, x1 ;[02]
+ andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7
+ subi x2, 1 ;[04]
+ ror shift ;[05]
+ cpi shift, 0xfc ;[06]
+ brcc unstuffEven ;[07]
+didUnstuffE:
+ lsr x3 ;[08]
+ lsr x3 ;[09]
+rxbit1:
+ in x2, USBIN ;[00] [10] <-- sample bit 1/3/5
+ andi x2, USBMASK ;[01]
+ breq se0 ;[02]
+ eor x1, x2 ;[03]
+ subi x1, 1 ;[04]
+ ror shift ;[05]
+ cpi shift, 0xfc ;[06]
+ brcc unstuffOdd ;[07]
+didUnstuffO:
+ subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3
+ brcs rxBitLoop ;[09]
+
+ subi cnt, 1 ;[10]
+ in x1, USBIN ;[00] [11] <-- sample bit 6
+ brcc rxByteLoop ;[01]
+ rjmp overflow
+
+macro POP_STANDARD ; 14 cycles
+ pop cnt
+ pop x4
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop bitcnt
+ endm
+macro POP_RETI ; 7 cycles
+ pop YH
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+#include "asmcommon.inc"
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1)
+; K = (D+ = 1), (D- = 0)
+; Spec allows 7.5 bit times from EOP to SOP for replies
+
+bitstuffN:
+ eor x1, x4 ;[5]
+ ldi x2, 0 ;[6]
+ nop2 ;[7]
+ nop ;[9]
+ out USBOUT, x1 ;[10] <-- out
+ rjmp didStuffN ;[0]
+
+bitstuff6:
+ eor x1, x4 ;[5]
+ ldi x2, 0 ;[6] Carry is zero due to brcc
+ rol shift ;[7] compensate for ror shift at branch destination
+ rjmp didStuff6 ;[8]
+
+bitstuff7:
+ ldi x2, 0 ;[2] Carry is zero due to brcc
+ rjmp didStuff7 ;[3]
+
+
+sendNakAndReti:
+ ldi x3, USBPID_NAK ;[-18]
+ rjmp sendX3AndReti ;[-17]
+sendAckAndReti:
+ ldi cnt, USBPID_ACK ;[-17]
+sendCntAndReti:
+ mov x3, cnt ;[-16]
+sendX3AndReti:
+ ldi YL, 20 ;[-15] x3==r20 address is 20
+ ldi YH, 0 ;[-14]
+ ldi cnt, 2 ;[-13]
+; rjmp usbSendAndReti fallthrough
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
+;uses: x1...x4, btcnt, shift, cnt, Y
+;Numbers in brackets are time since first bit of sync pattern is sent
+;We don't match the transfer rate exactly (don't insert leap cycles every third
+;byte) because the spec demands only 1.5% precision anyway.
+usbSendAndReti: ; 12 cycles until SOP
+ in x2, USBDDR ;[-12]
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;[-8] port mirror for tx loop
+ out USBDDR, x2 ;[-7] <- acquire bus
+; need not init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;[-6] exor mask
+ ldi shift, 0x80 ;[-5] sync byte is first byte sent
+txByteLoop:
+ ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101
+txBitLoop:
+ sbrs shift, 0 ;[-3] [7]
+ eor x1, x4 ;[-2] [8]
+ out USBOUT, x1 ;[-1] [9] <-- out N
+ ror shift ;[0] [10]
+ ror x2 ;[1]
+didStuffN:
+ cpi x2, 0xfc ;[2]
+ brcc bitstuffN ;[3]
+ lsr bitcnt ;[4]
+ brcc txBitLoop ;[5]
+ brne txBitLoop ;[6]
+
+ sbrs shift, 0 ;[7]
+ eor x1, x4 ;[8]
+didStuff6:
+ out USBOUT, x1 ;[-1] [9] <-- out 6
+ ror shift ;[0] [10]
+ ror x2 ;[1]
+ cpi x2, 0xfc ;[2]
+ brcc bitstuff6 ;[3]
+ ror shift ;[4]
+didStuff7:
+ ror x2 ;[5]
+ sbrs x2, 7 ;[6]
+ eor x1, x4 ;[7]
+ nop ;[8]
+ cpi x2, 0xfc ;[9]
+ out USBOUT, x1 ;[-1][10] <-- out 7
+ brcc bitstuff7 ;[0] [11]
+ ld shift, y+ ;[1]
+ dec cnt ;[3]
+ brne txByteLoop ;[4]
+;make SE0:
+ cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles]
+ lds x2, usbNewDeviceAddr;[6]
+ lsl x2 ;[8] we compare with left shifted address
+ subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3
+ sbci YH, 0 ;[10]
+ out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ breq skipAddrAssign ;[0]
+ sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[2] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[3]
+ ori x1, USBIDLE ;[4]
+ in x2, USBDDR ;[5]
+ cbr x2, USBMASK ;[6] set both pins to input
+ mov x3, x1 ;[7]
+ cbr x3, USBMASK ;[8] configure no pullup on both pins
+ ldi x4, 4 ;[9]
+se0Delay:
+ dec x4 ;[10] [13] [16] [19]
+ brne se0Delay ;[11] [14] [17] [20]
+ out USBOUT, x1 ;[21] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[22] <-- release bus now
+ out USBOUT, x3 ;[23] <-- ensure no pull-up resistors are active
+ rjmp doReturn
diff --git a/usbdrv/usbdrvasm165.inc b/usbdrv/usbdrvasm165.inc
new file mode 100644
index 0000000..79b3c61
--- /dev/null
+++ b/usbdrv/usbdrvasm165.inc
@@ -0,0 +1,453 @@
+/* Name: usbdrvasm165.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2007-04-22
+ * Tabsize: 4
+ * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm165.inc 740 2009-04-13 18:23:31Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 16.5 MHz version of the USB driver. It is intended for the
+ATTiny45 and similar controllers running on 16.5 MHz internal RC oscillator.
+This version contains a phase locked loop in the receiver routine to cope with
+slight clock rate deviations of up to +/- 1%.
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!
+;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled
+;max allowable interrupt latency: 59 cycles -> max 52 cycles interrupt disable
+;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes
+;nominal frequency: 16.5 MHz -> 11 cycles per bit
+; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%)
+; Numbers in brackets are clocks counted from center of last sync bit
+; when instruction starts
+
+
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt
+ push YL ;[-23] push only what is necessary to sync with edge ASAP
+ in YL, SREG ;[-21]
+ push YL ;[-20]
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of < 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS ;[-15]
+ rjmp foundK ;[-14]
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+foundK: ;[-12]
+;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]
+;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push r0 ;[-12]
+; [---] ;[-11]
+ push YH ;[-10]
+; [---] ;[-9]
+ lds YL, usbInputBufOffset;[-8]
+; [---] ;[-7]
+ clr YH ;[-6]
+ subi YL, lo8(-(usbRxBuf));[-5] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init]
+ mov r0, x2 ;[-3] [rx loop init]
+ sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early)
+ rjmp haveTwoBitsK ;[-1]
+ pop YH ;[0] undo the pushes from before
+ pop r0 ;[2]
+ rjmp waitForK ;[4] this was not the end of sync, retry
+; The entire loop from waitForK until rjmp waitForK above must not exceed two
+; bit times (= 22 cycles).
+
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+haveTwoBitsK: ;[1]
+ push shift ;[1]
+ push x1 ;[3]
+ push x2 ;[5]
+ push x3 ;[7]
+ ldi shift, 0xff ;[9] [rx loop init]
+ ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag
+
+ in x1, USBIN ;[11] <-- sample bit 0
+ bst x1, USBMINUS ;[12]
+ bld shift, 0 ;[13]
+ push x4 ;[14] == phase
+; [---] ;[15]
+ push cnt ;[16]
+; [---] ;[17]
+ ldi phase, 0 ;[18] [rx loop init]
+ ldi cnt, USB_BUFSIZE;[19] [rx loop init]
+ rjmp rxbit1 ;[20]
+; [---] ;[21]
+
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+/*
+byte oriented operations done during loop:
+bit 0: store data
+bit 1: SE0 check
+bit 2: overflow check
+bit 3: catch up
+bit 4: rjmp to achieve conditional jump range
+bit 5: PLL
+bit 6: catch up
+bit 7: jump, fixup bitstuff
+; 87 [+ 2] cycles
+------------------------------------------------------------------
+*/
+continueWithBit5:
+ in x2, USBIN ;[055] <-- bit 5
+ eor r0, x2 ;[056]
+ or phase, r0 ;[057]
+ sbrc phase, USBMINUS ;[058]
+ lpm ;[059] optional nop3; modifies r0
+ in phase, USBIN ;[060] <-- phase
+ eor x1, x2 ;[061]
+ bst x1, USBMINUS ;[062]
+ bld shift, 5 ;[063]
+ andi shift, 0x3f ;[064]
+ in x1, USBIN ;[065] <-- bit 6
+ breq unstuff5 ;[066] *** unstuff escape
+ eor phase, x1 ;[067]
+ eor x2, x1 ;[068]
+ bst x2, USBMINUS ;[069]
+ bld shift, 6 ;[070]
+didUnstuff6: ;[ ]
+ in r0, USBIN ;[071] <-- phase
+ cpi shift, 0x02 ;[072]
+ brlo unstuff6 ;[073] *** unstuff escape
+didUnstuff5: ;[ ]
+ nop2 ;[074]
+; [---] ;[075]
+ in x2, USBIN ;[076] <-- bit 7
+ eor x1, x2 ;[077]
+ bst x1, USBMINUS ;[078]
+ bld shift, 7 ;[079]
+didUnstuff7: ;[ ]
+ eor r0, x2 ;[080]
+ or phase, r0 ;[081]
+ in r0, USBIN ;[082] <-- phase
+ cpi shift, 0x04 ;[083]
+ brsh rxLoop ;[084]
+; [---] ;[085]
+unstuff7: ;[ ]
+ andi x3, ~0x80 ;[085]
+ ori shift, 0x80 ;[086]
+ in x2, USBIN ;[087] <-- sample stuffed bit 7
+ nop ;[088]
+ rjmp didUnstuff7 ;[089]
+; [---] ;[090]
+ ;[080]
+
+unstuff5: ;[067]
+ eor phase, x1 ;[068]
+ andi x3, ~0x20 ;[069]
+ ori shift, 0x20 ;[070]
+ in r0, USBIN ;[071] <-- phase
+ mov x2, x1 ;[072]
+ nop ;[073]
+ nop2 ;[074]
+; [---] ;[075]
+ in x1, USBIN ;[076] <-- bit 6
+ eor r0, x1 ;[077]
+ or phase, r0 ;[078]
+ eor x2, x1 ;[079]
+ bst x2, USBMINUS ;[080]
+ bld shift, 6 ;[081] no need to check bitstuffing, we just had one
+ in r0, USBIN ;[082] <-- phase
+ rjmp didUnstuff5 ;[083]
+; [---] ;[084]
+ ;[074]
+
+unstuff6: ;[074]
+ andi x3, ~0x40 ;[075]
+ in x1, USBIN ;[076] <-- bit 6 again
+ ori shift, 0x40 ;[077]
+ nop2 ;[078]
+; [---] ;[079]
+ rjmp didUnstuff6 ;[080]
+; [---] ;[081]
+ ;[071]
+
+unstuff0: ;[013]
+ eor r0, x2 ;[014]
+ or phase, r0 ;[015]
+ andi x2, USBMASK ;[016] check for SE0
+ in r0, USBIN ;[017] <-- phase
+ breq didUnstuff0 ;[018] direct jump to se0 would be too long
+ andi x3, ~0x01 ;[019]
+ ori shift, 0x01 ;[020]
+ mov x1, x2 ;[021] mov existing sample
+ in x2, USBIN ;[022] <-- bit 1 again
+ rjmp didUnstuff0 ;[023]
+; [---] ;[024]
+ ;[014]
+
+unstuff1: ;[024]
+ eor r0, x1 ;[025]
+ or phase, r0 ;[026]
+ andi x3, ~0x02 ;[027]
+ in r0, USBIN ;[028] <-- phase
+ ori shift, 0x02 ;[029]
+ mov x2, x1 ;[030]
+ rjmp didUnstuff1 ;[031]
+; [---] ;[032]
+ ;[022]
+
+unstuff2: ;[035]
+ eor r0, x2 ;[036]
+ or phase, r0 ;[037]
+ andi x3, ~0x04 ;[038]
+ in r0, USBIN ;[039] <-- phase
+ ori shift, 0x04 ;[040]
+ mov x1, x2 ;[041]
+ rjmp didUnstuff2 ;[042]
+; [---] ;[043]
+ ;[033]
+
+unstuff3: ;[043]
+ in x2, USBIN ;[044] <-- bit 3 again
+ eor r0, x2 ;[045]
+ or phase, r0 ;[046]
+ andi x3, ~0x08 ;[047]
+ ori shift, 0x08 ;[048]
+ nop ;[049]
+ in r0, USBIN ;[050] <-- phase
+ rjmp didUnstuff3 ;[051]
+; [---] ;[052]
+ ;[042]
+
+unstuff4: ;[053]
+ andi x3, ~0x10 ;[054]
+ in x1, USBIN ;[055] <-- bit 4 again
+ ori shift, 0x10 ;[056]
+ rjmp didUnstuff4 ;[057]
+; [---] ;[058]
+ ;[048]
+
+rxLoop: ;[085]
+ eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others
+ in x1, USBIN ;[000] <-- bit 0
+ st y+, x3 ;[001]
+; [---] ;[002]
+ eor r0, x1 ;[003]
+ or phase, r0 ;[004]
+ eor x2, x1 ;[005]
+ in r0, USBIN ;[006] <-- phase
+ ser x3 ;[007]
+ bst x2, USBMINUS ;[008]
+ bld shift, 0 ;[009]
+ andi shift, 0xf9 ;[010]
+rxbit1: ;[ ]
+ in x2, USBIN ;[011] <-- bit 1
+ breq unstuff0 ;[012] *** unstuff escape
+ andi x2, USBMASK ;[013] SE0 check for bit 1
+didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff
+ breq se0 ;[014]
+ eor r0, x2 ;[015]
+ or phase, r0 ;[016]
+ in r0, USBIN ;[017] <-- phase
+ eor x1, x2 ;[018]
+ bst x1, USBMINUS ;[019]
+ bld shift, 1 ;[020]
+ andi shift, 0xf3 ;[021]
+didUnstuff1: ;[ ]
+ in x1, USBIN ;[022] <-- bit 2
+ breq unstuff1 ;[023] *** unstuff escape
+ eor r0, x1 ;[024]
+ or phase, r0 ;[025]
+ subi cnt, 1 ;[026] overflow check
+ brcs overflow ;[027]
+ in r0, USBIN ;[028] <-- phase
+ eor x2, x1 ;[029]
+ bst x2, USBMINUS ;[030]
+ bld shift, 2 ;[031]
+ andi shift, 0xe7 ;[032]
+didUnstuff2: ;[ ]
+ in x2, USBIN ;[033] <-- bit 3
+ breq unstuff2 ;[034] *** unstuff escape
+ eor r0, x2 ;[035]
+ or phase, r0 ;[036]
+ eor x1, x2 ;[037]
+ bst x1, USBMINUS ;[038]
+ in r0, USBIN ;[039] <-- phase
+ bld shift, 3 ;[040]
+ andi shift, 0xcf ;[041]
+didUnstuff3: ;[ ]
+ breq unstuff3 ;[042] *** unstuff escape
+ nop ;[043]
+ in x1, USBIN ;[044] <-- bit 4
+ eor x2, x1 ;[045]
+ bst x2, USBMINUS ;[046]
+ bld shift, 4 ;[047]
+didUnstuff4: ;[ ]
+ eor r0, x1 ;[048]
+ or phase, r0 ;[049]
+ in r0, USBIN ;[050] <-- phase
+ andi shift, 0x9f ;[051]
+ breq unstuff4 ;[052] *** unstuff escape
+ rjmp continueWithBit5;[053]
+; [---] ;[054]
+
+macro POP_STANDARD ; 16 cycles
+ pop cnt
+ pop x4
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop YH
+ pop r0
+ endm
+macro POP_RETI ; 5 cycles
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+#include "asmcommon.inc"
+
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1)
+; K = (D+ = 1), (D- = 0)
+; Spec allows 7.5 bit times from EOP to SOP for replies
+
+bitstuff7:
+ eor x1, x4 ;[4]
+ ldi x2, 0 ;[5]
+ nop2 ;[6] C is zero (brcc)
+ rjmp didStuff7 ;[8]
+
+bitstuffN:
+ eor x1, x4 ;[5]
+ ldi x2, 0 ;[6]
+ lpm ;[7] 3 cycle NOP, modifies r0
+ out USBOUT, x1 ;[10] <-- out
+ rjmp didStuffN ;[0]
+
+#define bitStatus x3
+
+sendNakAndReti:
+ ldi cnt, USBPID_NAK ;[-19]
+ rjmp sendCntAndReti ;[-18]
+sendAckAndReti:
+ ldi cnt, USBPID_ACK ;[-17]
+sendCntAndReti:
+ mov r0, cnt ;[-16]
+ ldi YL, 0 ;[-15] R0 address is 0
+ ldi YH, 0 ;[-14]
+ ldi cnt, 2 ;[-13]
+; rjmp usbSendAndReti fallthrough
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
+;uses: x1...x4, shift, cnt, Y
+;Numbers in brackets are time since first bit of sync pattern is sent
+usbSendAndReti: ; 12 cycles until SOP
+ in x2, USBDDR ;[-12]
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;[-8] port mirror for tx loop
+ out USBDDR, x2 ;[-7] <- acquire bus
+; need not init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;[-6] exor mask
+ ldi shift, 0x80 ;[-5] sync byte is first byte sent
+ ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes
+byteloop:
+bitloop:
+ sbrs shift, 0 ;[8] [-3]
+ eor x1, x4 ;[9] [-2]
+ out USBOUT, x1 ;[10] [-1] <-- out
+ ror shift ;[0]
+ ror x2 ;[1]
+didStuffN:
+ cpi x2, 0xfc ;[2]
+ brcc bitstuffN ;[3]
+ nop ;[4]
+ subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37
+ brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value
+ sbrs shift, 0 ;[7]
+ eor x1, x4 ;[8]
+ ror shift ;[9]
+didStuff7:
+ out USBOUT, x1 ;[10] <-- out
+ ror x2 ;[0]
+ cpi x2, 0xfc ;[1]
+ brcc bitstuff7 ;[2]
+ ld shift, y+ ;[3]
+ dec cnt ;[5]
+ brne byteloop ;[6]
+;make SE0:
+ cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles]
+ lds x2, usbNewDeviceAddr;[8]
+ lsl x2 ;[10] we compare with left shifted address
+ out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0
+ sbci YH, 0 ;[1]
+ breq skipAddrAssign ;[2]
+ sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[5]
+ ori x1, USBIDLE ;[6]
+ in x2, USBDDR ;[7]
+ cbr x2, USBMASK ;[8] set both pins to input
+ mov x3, x1 ;[9]
+ cbr x3, USBMASK ;[10] configure no pullup on both pins
+ ldi x4, 4 ;[11]
+se0Delay:
+ dec x4 ;[12] [15] [18] [21]
+ brne se0Delay ;[13] [16] [19] [22]
+ out USBOUT, x1 ;[23] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[24] <-- release bus now
+ out USBOUT, x3 ;[25] <-- ensure no pull-up resistors are active
+ rjmp doReturn
+
diff --git a/usbdrv/usbdrvasm18-crc.inc b/usbdrv/usbdrvasm18-crc.inc
new file mode 100644
index 0000000..f83347d
--- /dev/null
+++ b/usbdrv/usbdrvasm18-crc.inc
@@ -0,0 +1,707 @@
+/* Name: usbdrvasm18.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
+ * Creation Date: 2009-01-20
+ * Tabsize: 4
+ * Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 18 MHz version of the asssembler part of the USB driver. It
+requires a 18 MHz crystal (not a ceramic resonator and not a calibrated RC
+oscillator).
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+
+;max stack usage: [ret(2), YL, SREG, YH, [sofError], bitcnt(x5), shift, x1, x2, x3, x4, cnt, ZL, ZH] = 14 bytes
+;nominal frequency: 18 MHz -> 12 cycles per bit
+; Numbers in brackets are clocks counted from center of last sync bit
+; when instruction starts
+;register use in receive loop to receive the data bytes:
+; shift assembles the byte currently being received
+; x1 holds the D+ and D- line state
+; x2 holds the previous line state
+; cnt holds the number of bytes left in the receive buffer
+; x3 holds the higher crc byte (see algorithm below)
+; x4 is used as temporary register for the crc algorithm
+; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further
+; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted
+; zl lower crc value and crc table index
+; zh used for crc table accesses
+
+;--------------------------------------------------------------------------------------------------------------
+; CRC mods:
+; table driven crc checker, Z points to table in prog space
+; ZL is the lower crc byte, x3 is the higher crc byte
+; x4 is used as temp register to store different results
+; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the
+; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial
+; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc.
+; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and
+; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF
+; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version
+;--------------------------------------------------------------------------------------------------------------
+; CRC algorithm:
+; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form
+; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order
+; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i
+; propose a research on CRC :-) )
+; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc
+; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3
+; (its destination).
+; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as
+; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored
+; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc
+; calculation is done.
+; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec)
+; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized
+; to a magic number which results in a crc value of 0xFFFF after the first complete byte.
+;
+; This algorithm is split into the extra cycles of the different bits:
+; bit7: XOR the received byte to ZL
+; bit5: load the new high byte to x4
+; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value)
+; move x4 (the new high byte) to x3, the crc value is ready
+;
+
+
+macro POP_STANDARD ; 18 cycles
+ pop ZH
+ pop ZL
+ pop cnt
+ pop x5
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop x4
+ endm
+macro POP_RETI ; 7 cycles
+ pop YH
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+macro CRC_CLEANUP_AND_CHECK
+ ; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor
+ ; x3 is the higher crc byte, zl the lower one
+ ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table
+ lpm x2, Z ;[+2][+3][+4]
+ ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table
+ lpm ZL, Z ;[+6][+7][+8]
+ eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value
+ cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec)
+ brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host
+ cpi x2, 0xb0 ;[+10]
+ brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host
+ endm
+
+
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH
+ push YL ;[-28] push only what is necessary to sync with edge ASAP
+ in YL, SREG ;[-26]
+ push YL ;[-25]
+ push YH ;[-23]
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of < 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS ;[-17]
+ rjmp foundK ;[-16]
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+foundK: ;[-15]
+;{3, 5} after falling D- edge, average delay: 4 cycles
+;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample
+;use 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push x4 ;[-14]
+; [---] ;[-13]
+ lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers
+; [---] ;[-11]
+ clr YH ;[-10]
+ subi YL, lo8(-(usbRxBuf));[-9] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init]
+ push shift ;[-7]
+; [---] ;[-6]
+ ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop
+ clc ;[-4] the carry has to be clear for receipt of pid bit 0
+ sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
+ rjmp haveTwoBitsK ;[-2]
+ pop shift ;[-1] undo the push from before
+ pop x4 ;[1]
+ rjmp waitForK ;[3] this was not the end of sync, retry
+; The entire loop from waitForK until rjmp waitForK above must not exceed two
+; bit times (= 24 cycles).
+
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+haveTwoBitsK:
+ push x1 ;[0]
+ push x2 ;[2]
+ push x3 ;[4] crc high byte
+ ldi x2, 1<<USBPLUS ;[6] [rx loop init] current line state is K state. D+=="1", D-=="0"
+ push x5 ;[7]
+ push cnt ;[9]
+ ldi cnt, USB_BUFSIZE ;[11]
+
+
+;--------------------------------------------------------------------------------------------------------------
+; receives the pid byte
+; there is no real unstuffing algorithm implemented here as a stuffing bit is impossible in the pid byte.
+; That's because the last four bits of the byte are the inverted of the first four bits. If we detect a
+; unstuffing condition something went wrong and abort
+; shift has to be initialized to 0x80
+;--------------------------------------------------------------------------------------------------------------
+
+; pid bit 0 - used for even more register saving (we need the z pointer)
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] filter only D+ and D- bits
+ eor x2, x1 ;[2] generate inverted of actual bit
+ sbrc x2, USBMINUS ;[3] if the bit is set we received a zero
+ sec ;[4]
+ ror shift ;[5] we perform no unstuffing check here as this is the first bit
+ mov x2, x1 ;[6]
+ push ZL ;[7]
+ ;[8]
+ push ZH ;[9]
+ ;[10]
+ ldi x3, 0xFE ;[11] x3 is the high order crc value
+
+
+bitloopPid:
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] filter only D+ and D- bits
+ breq nse0 ;[2] both lines are low so handle se0
+ eor x2, x1 ;[3] generate inverted of actual bit
+ sbrc x2, USBMINUS ;[4] set the carry if we received a zero
+ sec ;[5]
+ ror shift ;[6]
+ ldi ZL, 0x54 ;[7] ZL is the low order crc value
+ ser x4 ;[8] the is no bit stuffing check here as the pid bit can't be stuffed. if so
+ ; some error occured. In this case the paket is discarded later on anyway.
+ mov x2, x1 ;[9] prepare for the next cycle
+ brcc bitloopPid ;[10] while 0s drop out of shift we get the next bit
+ eor x4, shift ;[11] invert all bits in shift and store result in x4
+
+;--------------------------------------------------------------------------------------------------------------
+; receives data bytes and calculates the crc
+; the last USBIN state has to be in x2
+; this is only the first half, due to branch distanc limitations the second half of the loop is near the end
+; of this asm file
+;--------------------------------------------------------------------------------------------------------------
+
+rxDataStart:
+ in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling)
+ ser x5 ;[1] prepare the unstuff marker register
+ eor x2, x1 ;[2] generates the inverted of the actual bit
+ bst x2, USBMINUS ;[3] copy the bit from x2
+ bld shift, 0 ;[4] and store it in shift
+ mov x2, shift ;[5] make a copy of shift for unstuffing check
+ andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact)
+ breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler
+didunstuff0:
+ subi cnt, 1 ;[8] cannot use dec because it doesn't affect the carry flag
+ brcs nOverflow ;[9] Too many bytes received. Ignore packet
+ st Y+, x4 ;[10] store the last received byte
+ ;[11] st needs two cycles
+
+; bit1
+ in x2, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] check for se0 during bit 0
+ breq nse0 ;[2]
+ andi x2, USBMASK ;[3] check se0 during bit 1
+ breq nse0 ;[4]
+ eor x1, x2 ;[5]
+ bst x1, USBMINUS ;[6]
+ bld shift, 1 ;[7]
+ mov x1, shift ;[8]
+ andi x1, 0xF3 ;[9]
+ breq unstuff1 ;[10]
+didunstuff1:
+ nop ;[11]
+
+; bit2
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] check for se0 (as there is nothing else to do here
+ breq nOverflow ;[2]
+ eor x2, x1 ;[3] generates the inverted of the actual bit
+ bst x2, USBMINUS ;[4]
+ bld shift, 2 ;[5] store the bit
+ mov x2, shift ;[6]
+ andi x2, 0xE7 ;[7] if we have six zeros here (which means six 1 in the stream)
+ breq unstuff2 ;[8] the next bit is a stuffing bit
+didunstuff2:
+ nop2 ;[9]
+ ;[10]
+ nop ;[11]
+
+; bit3
+ in x2, USBIN ;[0] sample line state
+ andi x2, USBMASK ;[1] check for se0
+ breq nOverflow ;[2]
+ eor x1, x2 ;[3]
+ bst x1, USBMINUS ;[4]
+ bld shift, 3 ;[5]
+ mov x1, shift ;[6]
+ andi x1, 0xCF ;[7]
+ breq unstuff3 ;[8]
+didunstuff3:
+ nop ;[9]
+ rjmp rxDataBit4 ;[10]
+ ;[11]
+
+; the avr branch instructions allow an offset of +63 insturction only, so we need this
+; 'local copy' of se0
+nse0:
+ rjmp se0 ;[4]
+ ;[5]
+; the same same as for se0 is needed for overflow and StuffErr
+nOverflow:
+stuffErr:
+ rjmp overflow
+
+
+unstuff0: ;[8] this is the branch delay of breq unstuffX
+ andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here
+ breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte
+ ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift)
+ eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[3] mask the interesting bits
+ breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[5] the next bit expects the last state to be in x1
+ rjmp didunstuff0 ;[6]
+ ;[7] jump delay of rjmp didunstuffX
+
+unstuff1: ;[11] this is the jump delay of breq unstuffX
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift)
+ eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[4] mask the interesting bits
+ breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[6] the next bit expects the last state to be in x2
+ nop2 ;[7]
+ ;[8]
+ rjmp didunstuff1 ;[9]
+ ;[10] jump delay of rjmp didunstuffX
+
+unstuff2: ;[9] this is the jump delay of breq unstuffX
+ ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff2 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
+
+unstuff3: ;[9] this is the jump delay of breq unstuffX
+ ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff3 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
+
+
+
+; the include has to be here due to branch distance restirctions
+#define __USE_CRC__
+#include "asmcommon.inc"
+
+
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1)
+; K = (D+ = 1), (D- = 0)
+; Spec allows 7.5 bit times from EOP to SOP for replies
+; 7.5 bit times is 90 cycles. ...there is plenty of time
+
+
+sendNakAndReti:
+ ldi x3, USBPID_NAK ;[-18]
+ rjmp sendX3AndReti ;[-17]
+sendAckAndReti:
+ ldi cnt, USBPID_ACK ;[-17]
+sendCntAndReti:
+ mov x3, cnt ;[-16]
+sendX3AndReti:
+ ldi YL, 20 ;[-15] x3==r20 address is 20
+ ldi YH, 0 ;[-14]
+ ldi cnt, 2 ;[-13]
+; rjmp usbSendAndReti fallthrough
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
+;uses: x1...x4, btcnt, shift, cnt, Y
+;Numbers in brackets are time since first bit of sync pattern is sent
+
+usbSendAndReti: ; 12 cycles until SOP
+ in x2, USBDDR ;[-12]
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;[-8] port mirror for tx loop
+ out USBDDR, x2 ;[-6] <- acquire bus
+ ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;[-5] exor mask
+ ldi shift, 0x80 ;[-4] sync byte is first byte sent
+txByteLoop:
+ ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000
+txBitLoop: ; the loop sends the first 7 bits of the byte
+ sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state
+ eor x1, x4 ;[-1]=[11]
+ out USBOUT, x1 ;[0]
+ ror shift ;[1]
+ ror x2 ;[2] transfers the last sent bit to the stuffing history
+didStuffN:
+ nop ;[3]
+ nop ;[4]
+ cpi x2, 0xfc ;[5] if we sent six consecutive ones
+ brcc bitstuffN ;[6]
+ lsr bitcnt ;[7]
+ brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount
+
+; transmit bit 7
+ sbrs shift, 0 ;[9]
+ eor x1, x4 ;[10]
+didStuff7:
+ ror shift ;[11]
+ out USBOUT, x1 ;[0] transfer bit 7 to the pins
+ ror x2 ;[1] move the bit into the stuffing history
+ cpi x2, 0xfc ;[2]
+ brcc bitstuff7 ;[3]
+ ld shift, y+ ;[4] get next byte to transmit
+ dec cnt ;[5] decrement byte counter
+ brne txByteLoop ;[7] if we have more bytes start next one
+ ;[8] branch delay
+
+;make SE0:
+ cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles]
+ lds x2, usbNewDeviceAddr;[9]
+ lsl x2 ;[11] we compare with left shifted address
+ out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle
+ subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3
+ sbci YH, 0 ;[2]
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ breq skipAddrAssign ;[3]
+ sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[5] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[6]
+ ori x1, USBIDLE ;[7]
+ in x2, USBDDR ;[8]
+ cbr x2, USBMASK ;[9] set both pins to input
+ mov x3, x1 ;[10]
+ cbr x3, USBMASK ;[11] configure no pullup on both pins
+ ldi x4, 4 ;[12]
+se0Delay:
+ dec x4 ;[13] [16] [19] [22]
+ brne se0Delay ;[14] [17] [20] [23]
+ out USBOUT, x1 ;[24] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[25] <-- release bus now
+ out USBOUT, x3 ;[26] <-- ensure no pull-up resistors are active
+ rjmp doReturn
+
+bitstuffN:
+ eor x1, x4 ;[8] generate a zero
+ ldi x2, 0 ;[9] reset the bit stuffing history
+ nop2 ;[10]
+ out USBOUT, x1 ;[0] <-- send the stuffing bit
+ rjmp didStuffN ;[1]
+
+bitstuff7:
+ eor x1, x4 ;[5]
+ ldi x2, 0 ;[6] reset bit stuffing history
+ clc ;[7] fill a zero into the shift register
+ rol shift ;[8] compensate for ror shift at branch destination
+ rjmp didStuff7 ;[9]
+ ;[10] jump delay
+
+;--------------------------------------------------------------------------------------------------------------
+; receives data bytes and calculates the crc
+; second half of the data byte receiver loop
+; most parts of the crc algorithm are here
+;--------------------------------------------------------------------------------------------------------------
+
+nOverflow2:
+ rjmp overflow
+
+rxDataBit4:
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] check for se0
+ breq nOverflow2 ;[2]
+ eor x2, x1 ;[3]
+ bst x2, USBMINUS ;[4]
+ bld shift, 4 ;[5]
+ mov x2, shift ;[6]
+ andi x2, 0x9F ;[7]
+ breq unstuff4 ;[8]
+didunstuff4:
+ nop2 ;[9][10]
+ nop ;[11]
+
+; bit5
+ in x2, USBIN ;[0] sample line state
+ ldi ZH, hi8(usbCrcTableHigh);[1] use the table for the higher byte
+ eor x1, x2 ;[2]
+ bst x1, USBMINUS ;[3]
+ bld shift, 5 ;[4]
+ mov x1, shift ;[5]
+ andi x1, 0x3F ;[6]
+ breq unstuff5 ;[7]
+didunstuff5:
+ lpm x4, Z ;[8] load the higher crc xor-byte and store it for later use
+ ;[9] lpm needs 3 cycles
+ ;[10]
+ ldi ZH, hi8(usbCrcTableLow);[11] load the lower crc xor byte adress
+
+; bit6
+ in x1, USBIN ;[0] sample line state
+ eor x2, x1 ;[1]
+ bst x2, USBMINUS ;[2]
+ bld shift, 6 ;[3]
+ mov x2, shift ;[4]
+ andi x2, 0x7E ;[5]
+ breq unstuff6 ;[6]
+didunstuff6:
+ lpm ZL, Z ;[7] load the lower xor crc byte
+ ;[8] lpm needs 3 cycles
+ ;[9]
+ eor ZL, x3 ;[10] xor the old high crc byte with the low xor-byte
+ mov x3, x4 ;[11] move the new high order crc value from temp to its destination
+
+; bit7
+ in x2, USBIN ;[0] sample line state
+ eor x1, x2 ;[1]
+ bst x1, USBMINUS ;[2]
+ bld shift, 7 ;[3] now shift holds the complete but inverted data byte
+ mov x1, shift ;[4]
+ andi x1, 0xFC ;[5]
+ breq unstuff7 ;[6]
+didunstuff7:
+ eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs
+ mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0
+ eor ZL, x4 ;[9] feed the actual byte into the crc algorithm
+ rjmp rxDataStart ;[10] next byte
+ ;[11] during the reception of the next byte this one will be fed int the crc algorithm
+
+unstuff4: ;[9] this is the jump delay of rjmp unstuffX
+ ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ nop2 ;[5]
+ ;[6]
+ rjmp didunstuff4 ;[7]
+ ;[8] jump delay of rjmp didunstuffX
+
+unstuff5: ;[8] this is the jump delay of rjmp unstuffX
+ nop ;[9]
+ ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ nop ;[5]
+ rjmp didunstuff5 ;[6]
+ ;[7] jump delay of rjmp didunstuffX
+
+unstuff6: ;[7] this is the jump delay of rjmp unstuffX
+ nop2 ;[8]
+ ;[9]
+ ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x1, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x1, x2 ;[4] the next bit expects the last state to be in x1
+ rjmp didunstuff6 ;[5]
+ ;[6] jump delay of rjmp didunstuffX
+
+unstuff7: ;[7] this is the jump delay of rjmp unstuffX
+ nop ;[8]
+ nop ;[9]
+ ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing
+ andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift)
+ in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
+ eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
+ andi x2, USBMASK ;[2] mask the interesting bits
+ breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
+ mov x2, x1 ;[4] the next bit expects the last state to be in x2
+ rjmp didunstuff7 ;[5]
+ ;[6] jump delay of rjmp didunstuff7
+
+; local copy of the stuffErr desitnation for the second half of the receiver loop
+stuffErr2:
+ rjmp stuffErr
+
+;--------------------------------------------------------------------------------------------------------------
+; The crc table follows. It has to be aligned to enable a fast loading of the needed bytes.
+; There are two tables of 256 entries each, the low and the high byte table.
+; Table values were generated with the following C code:
+/*
+#include <stdio.h>
+int main (int argc, char **argv)
+{
+ int i, j;
+ for (i=0; i<512; i++){
+ unsigned short crc = i & 0xff;
+ for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0);
+ if((i & 7) == 0) printf("\n.byte ");
+ printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff);
+ if(i == 255) printf("\n");
+ }
+ return 0;
+}
+
+// Use the following algorithm to compute CRC values:
+ushort computeCrc(uchar *msg, uchar msgLen)
+{
+ uchar i;
+ ushort crc = 0xffff;
+ for(i = 0; i < msgLen; i++)
+ crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc);
+ return crc;
+}
+*/
+
+.balign 256
+usbCrcTableLow:
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
+.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
+
+; .balign 256
+usbCrcTableHigh:
+.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2
+.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04
+.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E
+.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8
+.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A
+.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC
+.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6
+.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10
+.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32
+.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4
+.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE
+.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38
+.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA
+.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C
+.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26
+.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0
+.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62
+.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4
+.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE
+.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68
+.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA
+.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C
+.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76
+.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0
+.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92
+.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54
+.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E
+.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98
+.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A
+.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C
+.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86
+.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
+
diff --git a/usbdrv/usbdrvasm20.inc b/usbdrv/usbdrvasm20.inc
new file mode 100644
index 0000000..303abaf
--- /dev/null
+++ b/usbdrv/usbdrvasm20.inc
@@ -0,0 +1,360 @@
+/* Name: usbdrvasm20.inc
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Jeroen Benschop
+ * Based on usbdrvasm16.inc from Christian Starkjohann
+ * Creation Date: 2008-03-05
+ * Tabsize: 4
+ * Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * Revision: $Id: usbdrvasm20.inc 740 2009-04-13 18:23:31Z cs $
+ */
+
+/* Do not link this file! Link usbdrvasm.S instead, which includes the
+ * appropriate implementation!
+ */
+
+/*
+General Description:
+This file is the 20 MHz version of the asssembler part of the USB driver. It
+requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC
+oscillator).
+
+See usbdrv.h for a description of the entire driver.
+
+Since almost all of this code is timing critical, don't change unless you
+really know what you are doing! Many parts require not only a maximum number
+of CPU cycles, but even an exact number of cycles!
+*/
+
+#define leap2 x3
+#ifdef __IAR_SYSTEMS_ASM__
+#define nextInst $+2
+#else
+#define nextInst .+0
+#endif
+
+;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes
+;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte
+; Numbers in brackets are clocks counted from center of last sync bit
+; when instruction starts
+;register use in receive loop:
+; shift assembles the byte currently being received
+; x1 holds the D+ and D- line state
+; x2 holds the previous line state
+; x4 (leap) is used to add a leap cycle once every three bytes received
+; X3 (leap2) is used to add a leap cycle once every three stuff bits received
+; bitcnt is used to determine when a stuff bit is due
+; cnt holds the number of bytes left in the receive buffer
+
+USB_INTR_VECTOR:
+;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt
+ push YL ;[-28] push only what is necessary to sync with edge ASAP
+ in YL, SREG ;[-26]
+ push YL ;[-25]
+ push YH ;[-23]
+;----------------------------------------------------------------------------
+; Synchronize with sync pattern:
+;----------------------------------------------------------------------------
+;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
+;sync up with J to K edge during sync pattern -- use fastest possible loops
+;The first part waits at most 1 bit long since we must be in sync pattern.
+;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
+;waitForJ, ensure that this prerequisite is met.
+waitForJ:
+ inc YL
+ sbis USBIN, USBMINUS
+ brne waitForJ ; just make sure we have ANY timeout
+waitForK:
+;The following code results in a sampling window of < 1/4 bit which meets the spec.
+ sbis USBIN, USBMINUS ;[-19]
+ rjmp foundK ;[-18]
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+ sbis USBIN, USBMINUS
+ rjmp foundK
+#if USB_COUNT_SOF
+ lds YL, usbSofCount
+ inc YL
+ sts usbSofCount, YL
+#endif /* USB_COUNT_SOF */
+#ifdef USB_SOF_HOOK
+ USB_SOF_HOOK
+#endif
+ rjmp sofError
+foundK: ;[-16]
+;{3, 5} after falling D- edge, average delay: 4 cycles
+;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample
+;use 1 bit time for setup purposes, then sample again. Numbers in brackets
+;are cycles from center of first sync (double K) bit after the instruction
+ push bitcnt ;[-16]
+; [---] ;[-15]
+ lds YL, usbInputBufOffset;[-14]
+; [---] ;[-13]
+ clr YH ;[-12]
+ subi YL, lo8(-(usbRxBuf));[-11] [rx loop init]
+ sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init]
+ push shift ;[-9]
+; [---] ;[-8]
+ ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected
+ nop2 ;[-6]
+; [---] ;[-5]
+ ldi bitcnt, 5 ;[-4] [rx loop init]
+ sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
+ rjmp haveTwoBitsK ;[-2]
+ pop shift ;[-1] undo the push from before
+ pop bitcnt ;[1]
+ rjmp waitForK ;[3] this was not the end of sync, retry
+; The entire loop from waitForK until rjmp waitForK above must not exceed two
+; bit times (= 27 cycles).
+
+;----------------------------------------------------------------------------
+; push more registers and initialize values while we sample the first bits:
+;----------------------------------------------------------------------------
+haveTwoBitsK:
+ push x1 ;[0]
+ push x2 ;[2]
+ push x3 ;[4] (leap2)
+ ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit
+ push x4 ;[7] == leap
+ ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received
+ push cnt ;[10]
+ ldi cnt, USB_BUFSIZE ;[12] [rx loop init]
+ ldi x2, 1<<USBPLUS ;[13] current line state is K state. D+=="1", D-=="0"
+bit0:
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] filter only D+ and D- bits
+ rjmp handleBit ;[2] make bit0 14 cycles long
+
+;----------------------------------------------------------------------------
+; Process bit7. However, bit 6 still may need unstuffing.
+;----------------------------------------------------------------------------
+
+b6checkUnstuff:
+ dec bitcnt ;[9]
+ breq unstuff6 ;[10]
+bit7:
+ subi cnt, 1 ;[11] cannot use dec becaus it does not affect the carry flag
+ brcs overflow ;[12] Too many bytes received. Ignore packet
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] filter only D+ and D- bits
+ cpse x1, x2 ;[2] when previous line state equals current line state, handle "1"
+ rjmp b7handle0 ;[3] when line state differs, handle "0"
+ sec ;[4]
+ ror shift ;[5] shift "1" into the data
+ st y+, shift ;[6] store the data into the buffer
+ ldi shift, 0x40 ;[7] reset data for receiving the next byte
+ subi leap, 0x55 ;[9] trick to introduce a leap cycle every 3 bytes
+ brcc nextInst ;[10 or 11] it will fail after 85 bytes. However low speed can only receive 11
+ dec bitcnt ;[11 or 12]
+ brne bit0 ;[12 or 13]
+ ldi x1, 1 ;[13 or 14] unstuffing bit 7
+ in bitcnt, USBIN ;[0] sample stuff bit
+ rjmp unstuff ;[1]
+
+b7handle0:
+ mov x2,x1 ;[5] Set x2 to current line state
+ ldi bitcnt, 6 ;[6]
+ lsr shift ;[7] shift "0" into the data
+ st y+, shift ;[8] store data into the buffer
+ ldi shift, 0x40 ;[10] reset data for receiving the next byte
+ subi leap, 0x55 ;[11] trick to introduce a leap cycle every 3 bytes
+ brcs bit0 ;[12] it will fail after 85 bytes. However low speed can only receive 11
+ rjmp bit0 ;[13]
+
+
+;----------------------------------------------------------------------------
+; Handle unstuff
+; x1==0xFF indicate unstuffing bit6
+;----------------------------------------------------------------------------
+
+unstuff6:
+ ldi x1,0xFF ;[12] indicate unstuffing bit 6
+ in bitcnt, USBIN ;[0] sample stuff bit
+ nop ;[1] fix timing
+unstuff: ;b0-5 b6 b7
+ mov x2,bitcnt ;[3] [2] [3] Set x2 to match line state
+ subi leap2, 0x55 ;[4] [3] [4] delay loop
+ brcs nextInst ;[5] [4] [5] add one cycle every three stuff bits
+ sbci leap2,0 ;[6] [5] [6]
+ ldi bitcnt,6 ;[7] [6] [7] reset bit stuff counter
+ andi x2, USBMASK ;[8] [7] [8] only keep D+ and D-
+ cpi x1,0 ;[9] [8] [9]
+ brmi bit7 ;[10] [9] [10] finished unstuffing bit6 When x1<0
+ breq bitloop ;[11] --- [11] finished unstuffing bit0-5 when x1=0
+ nop ;--- --- [12]
+ in x1, USBIN ;--- --- [0] sample line state for bit0
+ andi x1, USBMASK ;--- --- [1] filter only D+ and D- bits
+ rjmp handleBit ;--- --- [2] make bit0 14 cycles long
+
+;----------------------------------------------------------------------------
+; Receiver loop (numbers in brackets are cycles within byte after instr)
+;----------------------------------------------------------------------------
+bitloop:
+ in x1, USBIN ;[0] sample line state
+ andi x1, USBMASK ;[1] filter only D+ and D- bits
+ breq se0 ;[2] both lines are low so handle se0
+handleBit:
+ cpse x1, x2 ;[3] when previous line state equals current line state, handle "1"
+ rjmp handle0 ;[4] when line state differs, handle "0"
+ sec ;[5]
+ ror shift ;[6] shift "1" into the data
+ brcs b6checkUnstuff ;[7] When after shift C is set, next bit is bit7
+ nop2 ;[8]
+ dec bitcnt ;[10]
+ brne bitloop ;[11]
+ ldi x1,0 ;[12] indicate unstuff for bit other than bit6 or bit7
+ in bitcnt, USBIN ;[0] sample stuff bit
+ rjmp unstuff ;[1]
+
+handle0:
+ mov x2, x1 ;[6] Set x2 to current line state
+ ldi bitcnt, 6 ;[7] reset unstuff counter.
+ lsr shift ;[8] shift "0" into the data
+ brcs bit7 ;[9] When after shift C is set, next bit is bit7
+ nop ;[10]
+ rjmp bitloop ;[11]
+
+;----------------------------------------------------------------------------
+; End of receive loop. Now start handling EOP
+;----------------------------------------------------------------------------
+
+macro POP_STANDARD ; 14 cycles
+ pop cnt
+ pop x4
+ pop x3
+ pop x2
+ pop x1
+ pop shift
+ pop bitcnt
+ endm
+macro POP_RETI ; 7 cycles
+ pop YH
+ pop YL
+ out SREG, YL
+ pop YL
+ endm
+
+
+
+#include "asmcommon.inc"
+
+; USB spec says:
+; idle = J
+; J = (D+ = 0), (D- = 1)
+; K = (D+ = 1), (D- = 0)
+; Spec allows 7.5 bit times from EOP to SOP for replies
+; 7.5 bit times is 100 cycles. This implementation arrives a bit later at se0
+; then specified in the include file but there is plenty of time
+
+bitstuffN:
+ eor x1, x4 ;[8]
+ ldi x2, 0 ;[9]
+ nop2 ;[10]
+ out USBOUT, x1 ;[12] <-- out
+ rjmp didStuffN ;[0]
+
+bitstuff7:
+ eor x1, x4 ;[6]
+ ldi x2, 0 ;[7] Carry is zero due to brcc
+ rol shift ;[8] compensate for ror shift at branch destination
+ nop2 ;[9]
+ rjmp didStuff7 ;[11]
+
+sendNakAndReti:
+ ldi x3, USBPID_NAK ;[-18]
+ rjmp sendX3AndReti ;[-17]
+sendAckAndReti:
+ ldi cnt, USBPID_ACK ;[-17]
+sendCntAndReti:
+ mov x3, cnt ;[-16]
+sendX3AndReti:
+ ldi YL, 20 ;[-15] x3==r20 address is 20
+ ldi YH, 0 ;[-14]
+ ldi cnt, 2 ;[-13]
+; rjmp usbSendAndReti fallthrough
+
+;usbSend:
+;pointer to data in 'Y'
+;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
+;uses: x1...x4, btcnt, shift, cnt, Y
+;Numbers in brackets are time since first bit of sync pattern is sent
+;We don't match the transfer rate exactly (don't insert leap cycles every third
+;byte) because the spec demands only 1.5% precision anyway.
+usbSendAndReti: ; 12 cycles until SOP
+ in x2, USBDDR ;[-12]
+ ori x2, USBMASK ;[-11]
+ sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
+ in x1, USBOUT ;[-8] port mirror for tx loop
+ out USBDDR, x2 ;[-7] <- acquire bus
+; need not init x2 (bitstuff history) because sync starts with 0
+ ldi x4, USBMASK ;[-6] exor mask
+ ldi shift, 0x80 ;[-5] sync byte is first byte sent
+txByteLoop:
+ ldi bitcnt, 0x49 ;[-4] [10] binary 01001001
+txBitLoop:
+ sbrs shift, 0 ;[-3] [10] [11]
+ eor x1, x4 ;[-2] [11] [12]
+ out USBOUT, x1 ;[-1] [12] [13] <-- out N
+ ror shift ;[0] [13] [14]
+ ror x2 ;[1]
+didStuffN:
+ nop2 ;[2]
+ nop ;[4]
+ cpi x2, 0xfc ;[5]
+ brcc bitstuffN ;[6]
+ lsr bitcnt ;[7]
+ brcc txBitLoop ;[8]
+ brne txBitLoop ;[9]
+
+ sbrs shift, 0 ;[10]
+ eor x1, x4 ;[11]
+didStuff7:
+ out USBOUT, x1 ;[-1] [13] <-- out 7
+ ror shift ;[0] [14]
+ ror x2 ;[1]
+ nop ;[2]
+ cpi x2, 0xfc ;[3]
+ brcc bitstuff7 ;[4]
+ ld shift, y+ ;[5]
+ dec cnt ;[7]
+ brne txByteLoop ;[8]
+;make SE0:
+ cbr x1, USBMASK ;[9] prepare SE0 [spec says EOP may be 25 to 30 cycles]
+ lds x2, usbNewDeviceAddr;[10]
+ lsl x2 ;[12] we compare with left shifted address
+ out USBOUT, x1 ;[13] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle
+ subi YL, 20 + 2 ;[0] Only assign address on data packets, not ACK/NAK in x3
+ sbci YH, 0 ;[1]
+;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
+;set address only after data packet was sent, not after handshake
+ breq skipAddrAssign ;[2]
+ sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer
+skipAddrAssign:
+;end of usbDeviceAddress transfer
+ ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag
+ USB_STORE_PENDING(x2) ;[5]
+ ori x1, USBIDLE ;[6]
+ in x2, USBDDR ;[7]
+ cbr x2, USBMASK ;[8] set both pins to input
+ mov x3, x1 ;[9]
+ cbr x3, USBMASK ;[10] configure no pullup on both pins
+ ldi x4, 5 ;[11]
+se0Delay:
+ dec x4 ;[12] [15] [18] [21] [24]
+ brne se0Delay ;[13] [16] [19] [22] [25]
+ out USBOUT, x1 ;[26] <-- out J (idle) -- end of SE0 (EOP signal)
+ out USBDDR, x2 ;[27] <-- release bus now
+ out USBOUT, x3 ;[28] <-- ensure no pull-up resistors are active
+ rjmp doReturn
diff --git a/usbdrv/usbportability.h b/usbdrv/usbportability.h
new file mode 100644
index 0000000..ccd61b6
--- /dev/null
+++ b/usbdrv/usbportability.h
@@ -0,0 +1,140 @@
+/* Name: usbportability.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2008-06-17
+ * Tabsize: 4
+ * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
+ */
+
+/*
+General Description:
+This header is intended to contain all (or at least most of) the compiler
+and library dependent stuff. The C code is written for avr-gcc and avr-libc.
+The API of other development environments is converted to gcc's and avr-libc's
+API by means of defines.
+
+This header also contains all system includes since they depend on the
+development environment.
+
+Thanks to Oleg Semyonov for his help with the IAR tools port!
+*/
+
+#ifndef __usbportability_h_INCLUDED__
+#define __usbportability_h_INCLUDED__
+
+/* We check explicitly for IAR and CodeVision. Default is avr-gcc/avr-libc. */
+
+/* ------------------------------------------------------------------------- */
+#if defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ /* check for IAR */
+/* ------------------------------------------------------------------------- */
+
+#ifndef ENABLE_BIT_DEFINITIONS
+# define ENABLE_BIT_DEFINITIONS 1 /* Enable bit definitions */
+#endif
+
+/* Include IAR headers */
+#include <ioavr.h>
+#ifndef __IAR_SYSTEMS_ASM__
+# include <inavr.h>
+#endif
+
+#define __attribute__(arg) /* not supported on IAR */
+
+#ifdef __IAR_SYSTEMS_ASM__
+# define __ASSEMBLER__ /* IAR does not define standard macro for asm */
+#endif
+
+#ifdef __HAS_ELPM__
+# define PROGMEM __farflash
+#else
+# define PROGMEM __flash
+#endif
+
+#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))
+
+/* The following definitions are not needed by the driver, but may be of some
+ * help if you port a gcc based project to IAR.
+ */
+#define cli() __disable_interrupt()
+#define sei() __enable_interrupt()
+#define wdt_reset() __watchdog_reset()
+#define _BV(x) (1 << (x))
+
+/* assembler compatibility macros */
+#define nop2 rjmp $+2 /* jump to next instruction */
+#define XL r26
+#define XH r27
+#define YL r28
+#define YH r29
+#define ZL r30
+#define ZH r31
+#define lo8(x) LOW(x)
+#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */
+
+/* Depending on the device you use, you may get problems with the way usbdrv.h
+ * handles the differences between devices. Since IAR does not use #defines
+ * for MCU registers, we can't check for the existence of a particular
+ * register with an #ifdef. If the autodetection mechanism fails, include
+ * definitions for the required USB_INTR_* macros in your usbconfig.h. See
+ * usbconfig-prototype.h and usbdrv.h for details.
+ */
+
+/* ------------------------------------------------------------------------- */
+#elif __CODEVISIONAVR__ /* check for CodeVision AVR */
+/* ------------------------------------------------------------------------- */
+/* This port is not working (yet) */
+
+/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */
+
+#include <io.h>
+#include <delay.h>
+
+#define __attribute__(arg) /* not supported on IAR */
+
+#define PROGMEM __flash
+#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))
+
+#ifndef __ASSEMBLER__
+static inline void cli(void)
+{
+ #asm("cli");
+}
+static inline void sei(void)
+{
+ #asm("sei");
+}
+#endif
+#define _delay_ms(t) delay_ms(t)
+#define _BV(x) (1 << (x))
+#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */
+
+#define macro .macro
+#define endm .endmacro
+#define nop2 rjmp .+0 /* jump to next instruction */
+
+/* ------------------------------------------------------------------------- */
+#else /* default development environment is avr-gcc/avr-libc */
+/* ------------------------------------------------------------------------- */
+
+#include <avr/io.h>
+#ifdef __ASSEMBLER__
+# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */
+#else
+# include <avr/pgmspace.h>
+#endif
+
+#define USB_READ_FLASH(addr) pgm_read_byte(addr)
+
+#define macro .macro
+#define endm .endm
+#define nop2 rjmp .+0 /* jump to next instruction */
+
+#endif /* development environment */
+
+/* for conveniecne, ensure that PRG_RDB exists */
+#ifndef PRG_RDB
+# define PRG_RDB(addr) USB_READ_FLASH(addr)
+#endif
+#endif /* __usbportability_h_INCLUDED__ */