diff options
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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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 "${plugin_state_location}/${specs_file}"'" 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 "${plugin_state_location}/specs.cpp"'" 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 "${plugin_state_location}/specs.c"'" 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
@@ -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 @@ -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__ */ |