first submission
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
<?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="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" moduleId="org.eclipse.cdt.core.settings" name="obj">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" name="obj" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release">
|
||||
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074." name="/" resourcePath="">
|
||||
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.231146001" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.size" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32i" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" useByScannerDiscovery="false" value="GNU MCU RISC-V GCC" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" useByScannerDiscovery="false" value="riscv-none-embed-" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" useByScannerDiscovery="false" value="512258282" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166" name="Warn on uninitialized variables (-Wuninitialized)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw.1491146035" name="Extra Compressed extension (RVXW)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore.1175750723" name="Small prologue/epilogue (-msave-restore)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon.1177125388" name="No common unitialized (-fno-common)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon" value="true" valueType="boolean"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1944008784" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
|
||||
<builder buildPath="${workspace_loc:/ADC_DMA}/obj" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1421508906" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1692176068" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.1034038285" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Startup}""/>
|
||||
</option>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.126366858" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1567947810" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Debug}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/User/Host_UDisk}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/User/USB_Host}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Udisk_Lib}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Core}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/User}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Peripheral/inc}""/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.2020844713" name="Language standard" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.gnu99" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.177116515" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols"/>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.194760422" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths.2057340378" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Udisk_Lib}""/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.1390103472" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Ld/Link.ld}""/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.913830613" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano.239404511" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys.351964161" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs.16994550" name="Other objects" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs" useByScannerDiscovery="false" valueType="userObjs">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Udisk_Lib/libRV3UFI.a}""/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.1125808200" name="Linker flags (-Xlinker [option])" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags" useByScannerDiscovery="false" valueType="stringList"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.1062411404" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="RV3UFI"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.1859223768" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1689063433" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths.1029177148" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""../LD""/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile.1751226764" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="Link.ld"/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart.642896175" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano.1540675679" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.2052761852" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.439659821" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.67111865" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1549373929" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.1298918921" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble.1859590835" name="Disassemble (--disassemble|-d)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.1404031980" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="User/usb_host_iap_0.h|User/usb_host_iap_0.c|Udisk_Lib|Startup|Peripheral|Ld|Debug|Core" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Debug"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Ld"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Peripheral"/>
|
||||
<entry excluding="startup_ch32v20x_D8W.S|startup_ch32v20x_D6.S|startup_ch32v30x_D8.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Udisk_Lib"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="999.ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf.275846018" name="Executable file" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1375371130;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1473381709">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="obj">
|
||||
<resource resourceType="PROJECT" workspacePath="/ADC_DMA"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/000"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/000"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<projectDescription>
|
||||
<name>Host_Udisk_Exams</name>
|
||||
<comment />
|
||||
<projects />
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments />
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<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>
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1595986042669</id>
|
||||
<name />
|
||||
<type>22</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-*.wvproj</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>Core</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-3-PROJECT_LOC/SRC/Core</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>Debug</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-3-PROJECT_LOC/SRC/Debug</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>Ld</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-3-PROJECT_LOC/SRC/Ld</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>Peripheral</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-3-PROJECT_LOC/SRC/Peripheral</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>Startup</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-3-PROJECT_LOC/SRC/Startup</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>Udisk_Lib</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-1-PROJECT_LOC/Udisk_Lib</location>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" name="obj">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-91903898395255320" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//User/Host_UDisk/UDisk_Operation.h=UTF-8
|
||||
@@ -0,0 +1,16 @@
|
||||
Mcu Type=CH32V30x
|
||||
Address=0x08000000
|
||||
Erase All=true
|
||||
Program=true
|
||||
Verify=true
|
||||
Reset=true
|
||||
|
||||
Vendor=WCH
|
||||
Link=WCH-Link
|
||||
Toolchain=RISC-V
|
||||
Series=CH32V307
|
||||
Description=ROM(byte): 256K, SRAM(byte): 64K, CHIP PINS: 64, GPIO PORTS: 51.\nWCH CH32V3 series of mainstream MCUs covers the needs of a large variety of applications in the industrial,medical and consumer markets. High performance with first-class peripherals and low-power,low-voltage operation is paired with a high level of integration at accessible prices with a simple architecture and easy-to-use tools.
|
||||
|
||||
PeripheralVersion=1.4
|
||||
Target Path=obj\Host_UDisk_Exams.hex
|
||||
MCU=CH32V307RVT6
|
||||
@@ -0,0 +1,2 @@
|
||||
�i“CZ ?"Ç�¸rŸ�F<Fy8E9Y‡½„%Pa³D¶La†%Ã'y€¡]Ç;’¶ŸS)1†1+R4><‚.„ÇÅ¿º°?/£XO©Ä¿ChQN$*¢”»EÅBk‹!2tŒ+buh†nUb]xl‹l|
|
||||
+"Ÿ<“¯AH42}z8p;m€u1Ž-¦eh»Od¼Âwµª7x{5�CqEx©=;¦¢e¢º»2£Š ‚«*BPMš"
|
||||
@@ -0,0 +1,195 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : UDisk_Func_CreatDir.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/11/22
|
||||
* Description : USB full-speed port host operation functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "Udisk_Operation.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CreateDirectory
|
||||
* Description : 新建目录并打开,如果目录已经存在则直接打开,目录名在mCmdParam.Create.mPathName中,与文件名规则相同
|
||||
* Input :
|
||||
* Output : None
|
||||
* Return : ERR_SUCCESS = 打开目录成功或者创建目录成功,
|
||||
ERR_FOUND_NAME = 已经存在同名文件,
|
||||
ERR_MISS_DIR = 路径名无效或者上级目录不存在
|
||||
*******************************************************************************/
|
||||
uint8_t CreateDirectory( void )
|
||||
{
|
||||
uint8_t i, j;
|
||||
uint32_t UpDirCluster;
|
||||
uint8_t * DirXramBuf;
|
||||
uint8_t *DirConstData;
|
||||
j = 0xFF;
|
||||
for ( i = 0; i != sizeof( mCmdParam.Create.mPathName ); i ++ ) //检查目录路径
|
||||
{
|
||||
if ( mCmdParam.Create.mPathName[ i ] == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ( mCmdParam.Create.mPathName[ i ] == PATH_SEPAR_CHAR1 || mCmdParam.Create.mPathName[ i ] == PATH_SEPAR_CHAR2 )
|
||||
{
|
||||
j = i; //记录上级目录
|
||||
}
|
||||
}
|
||||
i = ERR_SUCCESS;
|
||||
if ( j == 0 || (j == 2 && mCmdParam.Create.mPathName[1] == ':') )
|
||||
{
|
||||
UpDirCluster = 0; //在根目录下创建子目录
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( j != 0xFF ) //对于绝对路径应该获取上级目录的起始簇号
|
||||
{
|
||||
mCmdParam.Create.mPathName[ j ] = 0;
|
||||
i = CHRV3FileOpen( ); //打开上级目录
|
||||
if ( i == ERR_SUCCESS )
|
||||
{
|
||||
i = ERR_MISS_DIR; //是文件而非目录
|
||||
}
|
||||
else if ( i == ERR_OPEN_DIR )
|
||||
{
|
||||
i = ERR_SUCCESS; //成功打开上级目录
|
||||
}
|
||||
mCmdParam.Create.mPathName[ j ] = PATH_SEPAR_CHAR1; //恢复目录分隔符
|
||||
}
|
||||
UpDirCluster = CHRV3vStartCluster; //保存上级目录的起始簇号
|
||||
}
|
||||
if ( i == ERR_SUCCESS ) //成功获取上级目录的起始簇号
|
||||
{
|
||||
i = CHRV3FileOpen( ); //打开本级子目录
|
||||
if ( i == ERR_SUCCESS )
|
||||
{
|
||||
i = ERR_FOUND_NAME; //是文件而非目录
|
||||
}
|
||||
else if ( i == ERR_OPEN_DIR )
|
||||
{
|
||||
i = ERR_SUCCESS; //目录已经存在
|
||||
}
|
||||
else if ( i == ERR_MISS_FILE ) //目录不存在,可以新建
|
||||
{
|
||||
i = CHRV3FileCreate( ); //以创建文件的方法创建目录
|
||||
if ( i == ERR_SUCCESS )
|
||||
{
|
||||
if ( pDISK_FAT_BUF == pDISK_BASE_BUF )
|
||||
{
|
||||
memset(pDISK_FAT_BUF,0,CHRV3vSectorSize); //如果FILE_DATA_BUF与DISK_BASE_BUF合用则必须清除磁盘缓冲区
|
||||
}
|
||||
DirXramBuf = pDISK_FAT_BUF; //文件数据缓冲区
|
||||
DirConstData = ". \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0.. \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0";
|
||||
for ( i = 0x40; i != 0; i -- ) //目录的保留单元,分别指向自身和上级目录
|
||||
{
|
||||
*DirXramBuf = *DirConstData;
|
||||
DirXramBuf ++;
|
||||
DirConstData ++;
|
||||
}
|
||||
*(pDISK_FAT_BUF+0x1A) = ( (uint8_t *)&CHRV3vStartCluster )[3];//自身的起始簇号
|
||||
*(pDISK_FAT_BUF+0x1B) = ( (uint8_t *)&CHRV3vStartCluster )[2];
|
||||
*(pDISK_FAT_BUF+0x14) = ( (uint8_t *)&CHRV3vStartCluster )[1];
|
||||
*(pDISK_FAT_BUF+0x15) = ( (uint8_t *)&CHRV3vStartCluster )[0];
|
||||
*(pDISK_FAT_BUF+0x20+0x1A) = ( (uint8_t *)&UpDirCluster )[3];//上级目录的起始簇号
|
||||
*(pDISK_FAT_BUF+0x20+0x1B) = ( (uint8_t *)&UpDirCluster )[2];
|
||||
*(pDISK_FAT_BUF+0x20+0x14) = ( (uint8_t *)&UpDirCluster )[1];
|
||||
*(pDISK_FAT_BUF+0x20+0x15) = ( (uint8_t *)&UpDirCluster )[0];
|
||||
// for ( count = 0x40; count != CHRV3vSectorSizeH*256; count ++ ) { /* 清空目录区剩余部分 */
|
||||
// *DirXramBuf = 0;
|
||||
// DirXramBuf ++;
|
||||
// }
|
||||
mCmdParam.Write.mSectorCount = 1;
|
||||
mCmdParam.Write.mDataBuffer = pDISK_FAT_BUF; //指向文件数据缓冲区的起始地址
|
||||
i = CHRV3FileWrite( ); //向文件写入数据
|
||||
if ( i == ERR_SUCCESS )
|
||||
{
|
||||
DirXramBuf = pDISK_FAT_BUF;
|
||||
for ( i = 0x40; i != 0; i -- ) //清空目录区
|
||||
{
|
||||
*DirXramBuf = 0;
|
||||
DirXramBuf ++;
|
||||
}
|
||||
for ( j = 1; j != CHRV3vSecPerClus; j ++ )
|
||||
{
|
||||
if ( pDISK_FAT_BUF == pDISK_BASE_BUF )
|
||||
{
|
||||
memset(pDISK_FAT_BUF,0,CHRV3vSectorSize); //如果FILE_DATA_BUF与DISK_BASE_BUF合用则必须清除磁盘缓冲区
|
||||
}
|
||||
mCmdParam.Write.mSectorCount = 1;
|
||||
mCmdParam.Write.mDataBuffer = pDISK_FAT_BUF; //指向文件数据缓冲区的起始地址
|
||||
i = CHRV3FileWrite( ); //清空目录的剩余扇区
|
||||
if ( i != ERR_SUCCESS )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == CHRV3vSecPerClus ) //成功清空目录
|
||||
{
|
||||
mCmdParam.Modify.mFileSize = 0; //目录的长度总是0
|
||||
mCmdParam.Modify.mFileDate = 0xFFFF;
|
||||
mCmdParam.Modify.mFileTime = 0xFFFF;
|
||||
mCmdParam.Modify.mFileAttr = 0x10; //置目录属性
|
||||
i = CHRV3FileModify( ); //将文件信息修改为目录
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return( i );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_CreatDirectory
|
||||
*
|
||||
* @brief Demo Function For UDisk Create Directory (EXAM9)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UDisk_USBH_CreatDirectory( void )
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t ret;
|
||||
|
||||
ret = UDisk_USBH_DiskReady( );
|
||||
if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) )
|
||||
{
|
||||
UDisk_Opeation_Flag = 0;
|
||||
printf("CHRV3DiskStatus:%02x\r\n",CHRV3DiskStatus);
|
||||
printf( "Create Level 1 Directory /YEAR2004 \r\n" );
|
||||
strcpy( mCmdParam.Create.mPathName, "/YEAR2004" ); //目录名,该目录建在根目录下
|
||||
ret = CreateDirectory( ); //新建或者打开目录
|
||||
mStopIfError( ret );
|
||||
/* 目录新建或者打开成功,下面在这个子目录中新建一个演示文件 */
|
||||
printf( "Create New File /YEAR2004/DEMO2004.TXT \r\n" );
|
||||
strcpy( mCmdParam.Create.mPathName, "/YEAR2004/DEMO2004.TXT" );//文件名
|
||||
ret = CHRV3FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建
|
||||
mStopIfError( ret );
|
||||
printf( "Write some data to file DEMO2004.TXT \r\n" );
|
||||
i = sprintf( Com_Buffer, "演示文件\xd\xa" );
|
||||
mCmdParam.ByteWrite.mByteCount = i; //指定本次写入的字节数,单次读写的长度不能超过MAX_BYTE_IO
|
||||
mCmdParam.ByteWrite.mByteBuffer = Com_Buffer; //指向缓冲区
|
||||
ret = CHRV3ByteWrite( ); //以字节为单位向文件写入数据,单次读写的长度不能超过MAX_BYTE_IO
|
||||
mStopIfError( ret );
|
||||
printf( "Close file DEMO2004.TXT \r\n" );
|
||||
mCmdParam.Close.mUpdateLen = 1; //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
|
||||
ret = CHRV3FileClose( );
|
||||
mStopIfError( ret );
|
||||
/* 下面新建二级子目录,方法与前面的一级子目录完全相同 */
|
||||
printf( "Create Level 2 Directory /YEAR2004/MONTH05 \r\n" );
|
||||
strcpy( mCmdParam.Create.mPathName, "/YEAR2004/MONTH05" ); //目录名,该目录建在YEAR2004子目录下,YEAR2004目录必须事先存在
|
||||
ret = CreateDirectory( ); //新建或者打开目录
|
||||
mStopIfError( ret );
|
||||
printf( "Close\r\n" );
|
||||
mCmdParam.Close.mUpdateLen = 0; //对于目录不需要自动更新文件长度
|
||||
ret = CHRV3FileClose( ); //关闭目录,目录不需要关闭,关闭只是为了防止下面误操作
|
||||
mStopIfError( ret );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,596 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Udisk_Func_longname.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/11/22
|
||||
* Description : USB full-speed port host operation functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "Udisk_Operation.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
uint8_t LongNameBuf[ LONG_NAME_BUF_LEN ];
|
||||
/*
|
||||
长文件名示例(UNICODE编码的大小端 必须与UNICODE_ENDIAN定义相同)
|
||||
以下是LongName里编码内容:
|
||||
建立长文件名,输入两个参数: 1.采用(unicode 大端),字符串末尾用两个0表示结束;2.ANSI编码短文件名.TXT
|
||||
*/
|
||||
uint8_t LongName[ ] =
|
||||
#if UNICODE_ENDIAN == 1
|
||||
{
|
||||
0x5E, 0xFA, 0x7A, 0xCB, 0x95, 0x7F, 0x65, 0x87, 0x4E, 0xF6, 0x54, 0x0D, 0xFF, 0x0C, 0x8F, 0x93,
|
||||
0x51, 0x65, 0x4E, 0x24, 0x4E, 0x2A, 0x53, 0xC2, 0x65, 0x70, 0xFF, 0x1A, 0x00, 0x20, 0x00, 0x31,
|
||||
0x00, 0x2E, 0x91, 0xC7, 0x75, 0x28, 0x00, 0x28, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x63,
|
||||
0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x59, 0x27, 0x7A, 0xEF, 0x00, 0x29, 0xFF, 0x0C,
|
||||
0x5B, 0x57, 0x7B, 0x26, 0x4E, 0x32, 0x67, 0x2B, 0x5C, 0x3E, 0x75, 0x28, 0x4E, 0x24, 0x4E, 0x2A,
|
||||
0x00, 0x30, 0x88, 0x68, 0x79, 0x3A, 0x7E, 0xD3, 0x67, 0x5F, 0x00, 0x3B, 0x00, 0x32, 0x00, 0x2E,
|
||||
0x00, 0x41, 0x00, 0x4E, 0x00, 0x53, 0x00, 0x49, 0x7F, 0x16, 0x78, 0x01, 0x77, 0xED, 0x65, 0x87,
|
||||
0x4E, 0xF6, 0x54, 0x0D, 0x00, 0x2E, 0x00, 0x54, 0x00, 0x58, 0x00, 0x54
|
||||
};
|
||||
#else
|
||||
{
|
||||
0xFA, 0x5E, 0xCB, 0x7A, 0x7F, 0x95, 0x87, 0x65, 0xF6, 0x4E, 0x0D, 0x54, 0x0C, 0xFF, 0x93, 0x8F,
|
||||
0x65, 0x51, 0x24, 0x4E, 0x2A, 0x4E, 0xC2, 0x53, 0x70, 0x65, 0x1A, 0xFF, 0x20, 0x00, 0x31, 0x00,
|
||||
0x2E, 0x00, 0xC7, 0x91, 0x28, 0x75, 0x28, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x63, 0x00,
|
||||
0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x27, 0x59, 0xEF, 0x7A, 0x29, 0x00, 0x0C, 0xFF,
|
||||
0x57, 0x5B, 0x26, 0x7B, 0x32, 0x4E, 0x2B, 0x67, 0x3E, 0x5C, 0x28, 0x75, 0x24, 0x4E, 0x2A, 0x4E,
|
||||
0x30, 0x00, 0x68, 0x88, 0x3A, 0x79, 0xD3, 0x7E, 0x5F, 0x67, 0x3B, 0x00, 0x32, 0x00, 0x2E, 0x00,
|
||||
0x41, 0x00, 0x4E, 0x00, 0x53, 0x00, 0x49, 0x00, 0x16, 0x7F, 0x01, 0x78, 0xED, 0x77, 0x87, 0x65,
|
||||
0xF6, 0x4E, 0x0D, 0x54, 0x2E, 0x00, 0x54, 0x00, 0x58, 0x00, 0x54, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_Longname
|
||||
*
|
||||
* @brief Demo Function For UDisk long-name Operation(EXAM 13)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UDisk_USBH_Longname( void )
|
||||
{
|
||||
uint8_t ret, i, len;
|
||||
uint16_t j;
|
||||
|
||||
ret = UDisk_USBH_DiskReady( );
|
||||
if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) )
|
||||
{
|
||||
UDisk_Opeation_Flag = 0;
|
||||
/*==================== 以下演示创建及读取长文件名 ============================*/
|
||||
// 复制长文件名(UNICODE 大端)到LongNameBuf里
|
||||
len = LongName_Len;
|
||||
memcpy( LongNameBuf, LongName, len );
|
||||
// 末尾用两个0表示结束
|
||||
LongNameBuf[len] = 0x00;
|
||||
LongNameBuf[len + 1] = 0x00;
|
||||
// 该长文件名的ANSI编码短文件名(8+3格式)
|
||||
strcpy( mCmdParam.Create.mPathName, "\\长文件名.TXT" );
|
||||
i = CHRV3CreateLongName( );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
DUG_PRINTF( "Created Long Name OK!\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error code defined in "udisk_operaion.h" */
|
||||
DUG_PRINTF( "Error Code: %02X\r\n", (uint16_t)i );
|
||||
}
|
||||
|
||||
DUG_PRINTF( "Get long Name#\r\n" );
|
||||
strcpy( mCmdParam.Open.mPathName, "\\长文件名.TXT" );
|
||||
// 以上需要输入文件名的完整路径
|
||||
i = CHRV3GetLongName( );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
// 长文件名收集完成,以UNICODE编码方式(按UNICODE_ENDIAN定义)
|
||||
// 存放在LongNameBuf缓冲里,长文件名最后用两个0结束.
|
||||
// 以下显示缓冲区里所有数据
|
||||
DUG_PRINTF( "LongNameBuf: " );
|
||||
for( j=0; j!=LONG_NAME_BUF_LEN; j++ )
|
||||
{
|
||||
DUG_PRINTF( "%02X ", (uint16_t)LongNameBuf[j] );
|
||||
}
|
||||
DUG_PRINTF( "\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error code defined in "udisk_operaion.h" */
|
||||
DUG_PRINTF( "Error Code: %02X\r\n", (uint16_t)i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CheckNameSum
|
||||
*
|
||||
* @brief 检查长文件名的短文件名检验和
|
||||
*
|
||||
* @return 计算后的校验和
|
||||
*/
|
||||
uint8_t CheckNameSum( uint8_t *p )
|
||||
{
|
||||
uint8_t FcbNameLen;
|
||||
uint8_t Sum;
|
||||
|
||||
Sum = 0;
|
||||
for (FcbNameLen=0; FcbNameLen!=11; FcbNameLen++)
|
||||
Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *p++;
|
||||
return Sum;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn AnalyzeLongName
|
||||
*
|
||||
* @brief 整理长文件名 返回有几个的26长度
|
||||
*
|
||||
* @return 返回有多少个26的长度
|
||||
*/
|
||||
uint8_t AnalyzeLongName( void )
|
||||
{
|
||||
uint8_t i, j;
|
||||
uint16_t index;
|
||||
|
||||
i = FALSE;
|
||||
for( index=0; index!=LONG_NAME_BUF_LEN; index = index + 2 )
|
||||
{
|
||||
if( ( LongNameBuf[index] == 0 ) && ( LongNameBuf[index+1] == 0 ) )
|
||||
{
|
||||
i = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ( i == FALSE ) || ( index == 0) )
|
||||
return 0; // 返回0表示错误的长文件名
|
||||
|
||||
i = index % 26;
|
||||
if( i != 0 )
|
||||
{
|
||||
index += 2;
|
||||
if( index % 26 != 0 ) // 加0刚好结束
|
||||
{
|
||||
for( j=i+2; j!=26; j++ )// 把剩余数据填为0XFF
|
||||
LongNameBuf[index++] = 0xff;
|
||||
}
|
||||
}
|
||||
return (index / 26);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CHRV3CreateLongName
|
||||
*
|
||||
* @brief 创建长文件名,需要输入短文件名的完整路径
|
||||
*
|
||||
* @return 操作状态
|
||||
*/
|
||||
uint8_t CHRV3CreateLongName( void )
|
||||
{
|
||||
// 分析 保留文件路径 创建一个空文件 得到FDT偏移和其所在扇区 删除文件
|
||||
// 向后偏移扇区 可能失败 如FAT12/16处在根目录处 填充完毕后再次创建文件
|
||||
uint8_t i;
|
||||
uint8_t len; // 存放路径的长度
|
||||
uint16_t index; // 长文件偏移索引
|
||||
uint16_t indexBak; // 长文件偏移索引备份
|
||||
uint32_t Secoffset; // 扇区偏移
|
||||
|
||||
uint8_t Fbit; // 第一次进入写扇区
|
||||
uint8_t Mult; // 长文件名长度26的倍数
|
||||
uint8_t MultBak; // 长文件名长度26的倍数备份
|
||||
|
||||
uint16_t Backoffset; // 保存文件偏移备份
|
||||
uint16_t BackoffsetBak; // 保存偏移备份的备份
|
||||
uint32_t BackFdtSector; // 保寸偏移上一个扇区
|
||||
uint8_t sum; // 保存长文件名的校验和
|
||||
|
||||
uint8_t BackPathBuf[MAX_PATH_LEN]; // 保存文件路径
|
||||
|
||||
Mult = AnalyzeLongName( ); // 保存长文件名是26的倍数
|
||||
if( Mult == 0 )
|
||||
return ERR_LONG_NAME;
|
||||
MultBak = Mult;
|
||||
|
||||
i = CHRV3FileOpen(); // 短文件名存在则返回错误
|
||||
if( i == ERR_SUCCESS )
|
||||
return ERR_NAME_EXIST;
|
||||
|
||||
i = CHRV3FileCreate( );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
Backoffset = CHRV3vFdtOffset;
|
||||
BackoffsetBak = Backoffset;
|
||||
BackFdtSector = CHRV3vFdtLba;
|
||||
sum = CheckNameSum( &DISK_BASE_BUF[Backoffset ] );
|
||||
for( i=0; i!=MAX_PATH_LEN; i++ ) // 对文件路径进行备份
|
||||
BackPathBuf[i] = mCmdParam.Open.mPathName[i];
|
||||
CHRV3FileErase( ); // 删除此文件
|
||||
|
||||
Secoffset = 0; // 从0开始偏移
|
||||
index = Mult*26; // 得到长文件名的长度
|
||||
indexBak = index;
|
||||
Fbit = FALSE; // 默认没有进入
|
||||
// 打开上级 进行数据填充数据
|
||||
P_RETRY:
|
||||
for(len=0; len!=MAX_PATH_LEN; len++)
|
||||
{
|
||||
if(mCmdParam.Open.mPathName[len] == 0)
|
||||
break; // 得到字符串长度
|
||||
}
|
||||
|
||||
for(i=len-1; i!=0xff; i--) // 得到上级目录位置
|
||||
{
|
||||
if((mCmdParam.Open.mPathName[i] == '\\') || (mCmdParam.Open.mPathName[i] == '/'))
|
||||
break;
|
||||
}
|
||||
mCmdParam.Open.mPathName[i] = 0x00;
|
||||
|
||||
if( i==0 ) // 打开一级目录注意:处在根目录开始的特殊情况
|
||||
{
|
||||
mCmdParam.Open.mPathName[0] = '/';
|
||||
mCmdParam.Open.mPathName[1] = 0;
|
||||
}
|
||||
|
||||
i = CHRV3FileOpen(); // 打开上级目录
|
||||
if( i == ERR_OPEN_DIR )
|
||||
{
|
||||
while( 1 ) // 循环填写 直到完成
|
||||
{
|
||||
mCmdParam.Locate.mSectorOffset = Secoffset;
|
||||
i = CHRV3FileLocate( );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
if( Fbit ) // 第二次进入次写扇区
|
||||
{
|
||||
if( mCmdParam.Locate.mSectorOffset != 0x0FFFFFFFF )
|
||||
{
|
||||
BackFdtSector = mCmdParam.Locate.mSectorOffset;
|
||||
Backoffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i!=MAX_PATH_LEN; i++ )// 还原文件路径
|
||||
mCmdParam.Open.mPathName[i] = BackPathBuf[i];
|
||||
i = CHRV3FileCreate( ); // 进行空间扩展
|
||||
if( i != ERR_SUCCESS )
|
||||
return i;
|
||||
CHRV3FileErase( );
|
||||
goto P_RETRY; // 重新打开上级目录
|
||||
}
|
||||
}
|
||||
|
||||
if( BackFdtSector == mCmdParam.Locate.mSectorOffset )
|
||||
{
|
||||
mCmdParam.Read.mSectorCount = 1; // 读一个扇区到磁盘缓冲区
|
||||
mCmdParam.Read.mDataBuffer = &DISK_BASE_BUF[0];
|
||||
i = CHRV3FileRead( );
|
||||
CHRV3DirtyBuffer( ); // 清除磁盘缓冲区
|
||||
if( i!= ERR_SUCCESS )
|
||||
return i;
|
||||
|
||||
i = ( CHRV3vSectorSize - Backoffset ) / 32;
|
||||
if( Mult > i )
|
||||
Mult = Mult - i; // 剩余的倍数
|
||||
else
|
||||
{
|
||||
i = Mult;
|
||||
Mult = 0;
|
||||
}
|
||||
|
||||
for( len=i; len!=0; len-- )
|
||||
{
|
||||
indexBak -= 26;
|
||||
index = indexBak;
|
||||
for( i=0; i!=5; i++) // 长文件名的1-5个字符
|
||||
{ // 在磁盘上UNICODE用小端方式存放
|
||||
#if UNICODE_ENDIAN == 1
|
||||
DISK_BASE_BUF[Backoffset + i*2 + 2 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
#else
|
||||
DISK_BASE_BUF[Backoffset + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + i*2 + 2 ] =
|
||||
LongNameBuf[index++];
|
||||
#endif
|
||||
}
|
||||
|
||||
for( i =0; i!=6; i++) // 长文件名的6-11个字符
|
||||
{
|
||||
#if UNICODE_ENDIAN == 1
|
||||
DISK_BASE_BUF[Backoffset + 14 + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + 14 + i*2 ] =
|
||||
LongNameBuf[index++];
|
||||
#else
|
||||
DISK_BASE_BUF[Backoffset + 14 + i*2 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + 14 + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
#endif
|
||||
}
|
||||
|
||||
for( i=0; i!=2; i++) // 长文件名的12-13个字符
|
||||
{
|
||||
#if UNICODE_ENDIAN == 1
|
||||
DISK_BASE_BUF[Backoffset + 28 + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + 28 + i*2 ] =
|
||||
LongNameBuf[index++];
|
||||
#else
|
||||
DISK_BASE_BUF[Backoffset + 28 + i*2 ] =
|
||||
LongNameBuf[index++];
|
||||
DISK_BASE_BUF[Backoffset + 28 + i*2 + 1 ] =
|
||||
LongNameBuf[index++];
|
||||
#endif
|
||||
}
|
||||
|
||||
DISK_BASE_BUF[Backoffset + 0x0b] = 0x0f;
|
||||
DISK_BASE_BUF[Backoffset + 0x0c] = 0x00;
|
||||
DISK_BASE_BUF[Backoffset + 0x0d] = sum;
|
||||
DISK_BASE_BUF[Backoffset + 0x1a] = 0x00;
|
||||
DISK_BASE_BUF[Backoffset + 0x1b] = 0x00;
|
||||
DISK_BASE_BUF[Backoffset] = MultBak--;
|
||||
Backoffset += 32;
|
||||
}
|
||||
|
||||
if( !Fbit )
|
||||
{
|
||||
Fbit = TRUE;
|
||||
DISK_BASE_BUF[ BackoffsetBak ] |= 0x40;
|
||||
}
|
||||
CHRV3vLbaCurrent = BackFdtSector;
|
||||
i = CHRV3WriteSector( 1, DISK_BASE_BUF );
|
||||
if( i!= ERR_SUCCESS )
|
||||
return i;
|
||||
|
||||
if( Mult==0 )
|
||||
{ // 还原文件路径
|
||||
CHRV3FileClose( );
|
||||
for( i=0; i!=MAX_PATH_LEN; i++ )
|
||||
mCmdParam.Open.mPathName[i] = BackPathBuf[i];
|
||||
i = CHRV3FileCreate( );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return i;
|
||||
Secoffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn GetUpSectorData
|
||||
*
|
||||
* @brief 由当前扇区得到上一个扇区的数据,放在磁盘缓冲区
|
||||
*
|
||||
* @return 操作状态
|
||||
*/
|
||||
uint8_t GetUpSectorData( uint32_t *NowSector )
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t len; // 存放路径的长度
|
||||
uint32_t index; // 目录扇区偏移扇区数
|
||||
|
||||
index = 0;
|
||||
for(len=0; len!=MAX_PATH_LEN; len++)
|
||||
{
|
||||
if(mCmdParam.Open.mPathName[len] == 0) // 得到字符串长度
|
||||
break;
|
||||
}
|
||||
|
||||
for(i=len-1; i!=0xff; i--) // 得到上级目录位置
|
||||
{
|
||||
if((mCmdParam.Open.mPathName[i] == '\\') || (mCmdParam.Open.mPathName[i] == '/'))
|
||||
break;
|
||||
}
|
||||
mCmdParam.Open.mPathName[i] = 0x00;
|
||||
|
||||
if( i==0 ) // 打开一级目录注意:处在根目录开始的特殊情况
|
||||
{
|
||||
mCmdParam.Open.mPathName[0] = '/';
|
||||
mCmdParam.Open.mPathName[1] = 0;
|
||||
i = CHRV3FileOpen();
|
||||
if ( i == ERR_OPEN_DIR )
|
||||
goto P_NEXT0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = CHRV3FileOpen();
|
||||
if ( i == ERR_OPEN_DIR )
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
P_NEXT0:
|
||||
mCmdParam.Locate.mSectorOffset = index;
|
||||
i = CHRV3FileLocate( );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
if( *NowSector == mCmdParam.Locate.mSectorOffset )
|
||||
{
|
||||
if( index==0 ) // 处于根目录扇区的开始
|
||||
return ERR_NO_NAME;
|
||||
mCmdParam.Locate.mSectorOffset = --index;
|
||||
i = CHRV3FileLocate( ); // 读上一个扇区的数据
|
||||
if( i == ERR_SUCCESS )
|
||||
{ // 以下保存当前所在扇区数
|
||||
*NowSector = mCmdParam.Locate.mSectorOffset;
|
||||
mCmdParam.Read.mSectorCount = 1; // 读一个扇区到磁盘缓冲区
|
||||
mCmdParam.Read.mDataBuffer = &DISK_BASE_BUF[0];
|
||||
i = CHRV3FileRead( );
|
||||
CHRV3DirtyBuffer( ); // 清除磁盘缓冲区
|
||||
return i;
|
||||
}
|
||||
else
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
return i;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CHRV3GetLongName
|
||||
*
|
||||
* @brief 由完整短文件名路径(可以是文件或文件夹)得到相应的长文件名
|
||||
*
|
||||
* @return 操作状态
|
||||
*/
|
||||
uint8_t CHRV3GetLongName( void )
|
||||
{
|
||||
// 需要变量扇区大小
|
||||
// 第一步:打开文件是否找到文件,分析文件是否存在,并得到FDT在此扇区的偏移和所在扇区
|
||||
// 第二步:分析上面的信息看是否有长文件名存在,是否处于目录的第一个扇区的开始
|
||||
// 第三步:实现向后偏移一个扇区?读取长文件名(扇区512字节的U盘)
|
||||
uint8_t i;
|
||||
uint16_t index; // 在长文件名缓冲区内的索引
|
||||
uint32_t BackFdtSector; // 保寸偏移上一个扇区
|
||||
uint8_t sum; // 保存长文件名的校验和
|
||||
//uint16_t Backoffset; // 保存文件偏移备份
|
||||
uint16_t offset; // 扇区内文件偏移32倍数
|
||||
uint8_t FirstBit; // 长文件名跨越两个扇区标志位
|
||||
uint8_t BackPathBuf[MAX_PATH_LEN]; // 保存文件路径
|
||||
|
||||
i = CHRV3FileOpen( );
|
||||
if( ( i == ERR_SUCCESS ) || ( i == ERR_OPEN_DIR ) )
|
||||
{
|
||||
for( i=0; i!=MAX_PATH_LEN; i++ )
|
||||
BackPathBuf[i] = mCmdParam.Open.mPathName[i];
|
||||
// 以上完成对路径的备份
|
||||
|
||||
sum = CheckNameSum( &DISK_BASE_BUF[CHRV3vFdtOffset] );
|
||||
index = 0;
|
||||
FirstBit = FALSE;
|
||||
// Backoffset = CHRV3vFdtOffset;
|
||||
BackFdtSector = CHRV3vFdtLba;
|
||||
if( CHRV3vFdtOffset == 0 )
|
||||
{
|
||||
// 先判断是否处于一个扇区开始 是否处于根目录开始 ,否则向后偏移
|
||||
if( FirstBit == FALSE )
|
||||
FirstBit = TRUE;
|
||||
i = GetUpSectorData( &BackFdtSector );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
CHRV3vFdtOffset = CHRV3vSectorSize;
|
||||
goto P_NEXT1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 读取偏移后的数据,直到结束。如果不够则向后偏移
|
||||
P_NEXT1:
|
||||
offset = CHRV3vFdtOffset;
|
||||
while( 1 )
|
||||
{
|
||||
if( offset != 0 )
|
||||
{
|
||||
offset = offset - 32;
|
||||
if( ( DISK_BASE_BUF[offset + 11] == ATTR_LONG_NAME )
|
||||
&& ( DISK_BASE_BUF[offset + 13] == sum ) )
|
||||
{
|
||||
if( (index + 26) > LONG_NAME_BUF_LEN )
|
||||
return ERR_BUF_OVER;
|
||||
|
||||
for( i=0; i!=5; i++) // 长文件名的1-5个字符
|
||||
{ // 在磁盘上UNICODE用小端方式存放
|
||||
#if UNICODE_ENDIAN == 1
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + i*2 + 2];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + i*2 + 1];
|
||||
#else
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + i*2 + 1];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + i*2 + 2];
|
||||
#endif
|
||||
}
|
||||
|
||||
for( i =0; i!=6; i++) // 长文件名的6-11个字符
|
||||
{
|
||||
#if UNICODE_ENDIAN == 1
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 14 + i*2 + 1];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + + 14 + i*2 ];
|
||||
#else
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + + 14 + i*2 ];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 14 + i*2 + 1];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for( i=0; i!=2; i++) // 长文件名的12-13个字符
|
||||
{
|
||||
#if UNICODE_ENDIAN == 1
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 28 + i*2 + 1];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 28 + i*2 ];
|
||||
#else
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 28 + i*2 ];
|
||||
LongNameBuf[index++] =
|
||||
DISK_BASE_BUF[offset + 28 + i*2 + 1];
|
||||
#endif
|
||||
}
|
||||
|
||||
if( DISK_BASE_BUF[offset] & 0X40 )
|
||||
{
|
||||
if( ! (((LongNameBuf[index -1] ==0x00)
|
||||
&& (LongNameBuf[index -2] ==0x00))
|
||||
|| ((LongNameBuf[index -1] ==0xFF)
|
||||
&& (LongNameBuf[index -2 ] ==0xFF))))
|
||||
{ // 处理刚好为26字节长倍数的文件名
|
||||
if(index + 52 >LONG_NAME_BUF_LEN )
|
||||
return ERR_BUF_OVER;
|
||||
LongNameBuf[ index ] = 0x00;
|
||||
LongNameBuf[ index + 1] = 0x00;
|
||||
}
|
||||
return ERR_SUCCESS; // 成功完成长文件名收集完成
|
||||
}
|
||||
}
|
||||
else
|
||||
return ERR_NO_NAME; // 错误的长文件名,程序返回
|
||||
}
|
||||
else
|
||||
{
|
||||
if( FirstBit == FALSE )
|
||||
FirstBit = TRUE;
|
||||
else // 否则第二次进入
|
||||
{
|
||||
for( i=0; i!=MAX_PATH_LEN; i++ )// 还原路径
|
||||
mCmdParam.Open.mPathName[i] = BackPathBuf[i];
|
||||
}
|
||||
i = GetUpSectorData( &BackFdtSector );
|
||||
if( i == ERR_SUCCESS )
|
||||
{
|
||||
CHRV3vFdtOffset = CHRV3vSectorSize;
|
||||
goto P_NEXT1;
|
||||
}
|
||||
else
|
||||
return i;
|
||||
// 向后偏移扇区
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return i; // 返回错误
|
||||
}
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : UDisk_HW.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/09/01
|
||||
* Description : USB full-speed port host operation functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "Udisk_Operation.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
__attribute__((aligned(4))) uint8_t Com_Buffer[ DEF_COM_BUF_LEN ]; // even address , used for host enumcation and udisk operation
|
||||
__attribute__((aligned(4))) uint8_t DevDesc_Buf[ 18 ]; // Device Descriptor Buffer
|
||||
struct _ROOT_HUB_DEVICE RootHubDev[ DEF_TOTAL_ROOT_HUB ];
|
||||
struct __HOST_CTL HostCtl[ DEF_TOTAL_ROOT_HUB * DEF_ONE_USB_SUP_DEV_TOTAL ];
|
||||
volatile uint8_t UDisk_Opeation_Flag = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn mStopIfError
|
||||
*
|
||||
* @brief Checking the operation status, displaying the error code and stopping if there is an error
|
||||
* input : iError - Error code input
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void mStopIfError( uint8_t iError )
|
||||
{
|
||||
if ( iError == ERR_SUCCESS )
|
||||
{
|
||||
/* operation success, return */
|
||||
return;
|
||||
}
|
||||
/* Display the errors */
|
||||
DUG_PRINTF( "Error:%02x\r\n", iError );
|
||||
/* After encountering an error, you should analyze the error code and CHRV3DiskStatus status, for example,
|
||||
* call CHRV3DiskReady to check whether the current USB disk is connected or not,
|
||||
* if the disk is disconnected then wait for the disk to be plugged in again and operate again,
|
||||
* Suggested steps to follow after an error:
|
||||
* 1, call CHRV3DiskReady once, if successful, then continue the operation, such as Open, Read/Write, etc.
|
||||
* 2?If CHRV3DiskReady is not successful, then the operation will be forced to start from the beginning.
|
||||
*/
|
||||
while(1)
|
||||
{ }
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Udisk_USBH_Initialization
|
||||
*
|
||||
* @brief USB Host Udisk process Initialization, include usb-host initialization
|
||||
* usb libs initialization, udisk-related values Initialization
|
||||
and the others
|
||||
*
|
||||
* @para none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Udisk_USBH_Initialization( void )
|
||||
{
|
||||
/* USB Host Initialization */
|
||||
printf( "USB Host & UDisk Lib Initialization. \r\n" );
|
||||
/* Initialize USBFS host */
|
||||
DUG_PRINTF( "USBFS Host Init\r\n" );
|
||||
USBFS_RCC_Init( );
|
||||
USBFS_Host_Init( ENABLE );
|
||||
memset( &RootHubDev[ DEF_USB_PORT_FS ].bStatus, 0, sizeof( struct _ROOT_HUB_DEVICE ) );
|
||||
memset( &HostCtl[ DEF_USB_PORT_FS ].InterfaceNum, 0, sizeof( struct __HOST_CTL ) );
|
||||
|
||||
/* USB Libs Initialization */
|
||||
printf( "UDisk library Initialization. \r\n" );
|
||||
CHRV3LibInit( );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Udisk_USBH_EnumRootDevice
|
||||
*
|
||||
* @brief Generally enumerate a device connected to host port.
|
||||
*
|
||||
* @para index: USB host port
|
||||
*
|
||||
* @return Enumeration result
|
||||
*/
|
||||
uint8_t Udisk_USBH_EnumRootDevice( uint8_t usb_port )
|
||||
{
|
||||
uint8_t s;
|
||||
uint8_t enum_cnt;
|
||||
uint8_t cfg_val;
|
||||
uint16_t i;
|
||||
uint16_t len;
|
||||
|
||||
DUG_PRINTF( "Enum:\r\n" );
|
||||
|
||||
enum_cnt = 0;
|
||||
ENUM_START:
|
||||
/* Delay and wait for the device to stabilize */
|
||||
Delay_Ms( 100 );
|
||||
enum_cnt++;
|
||||
Delay_Ms( 8 << enum_cnt );
|
||||
|
||||
/* Reset the USB device and wait for the USB device to reconnect */
|
||||
USBFSH_ResetRootHubPort( 0 );
|
||||
for( i = 0, s = 0; i < DEF_RE_ATTACH_TIMEOUT; i++ )
|
||||
{
|
||||
if( USBFSH_EnableRootHubPort( &RootHubDev[ usb_port ].bSpeed ) == ERR_SUCCESS )
|
||||
{
|
||||
i = 0;
|
||||
s++;
|
||||
if( s > 6 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Delay_Ms( 1 );
|
||||
}
|
||||
if( i )
|
||||
{
|
||||
/* Determine whether the maximum number of retries has been reached, and retry if not reached */
|
||||
if( enum_cnt <= 5 )
|
||||
{
|
||||
goto ENUM_START;
|
||||
}
|
||||
return ERR_USB_DISCON;
|
||||
}
|
||||
|
||||
/* Select USB speed */
|
||||
USBFSH_SetSelfSpeed( RootHubDev[ usb_port].bSpeed );
|
||||
|
||||
/* Get USB device device descriptor */
|
||||
DUG_PRINTF("Get DevDesc: ");
|
||||
s = USBFSH_GetDeviceDescr( &RootHubDev[ usb_port ].bEp0MaxPks, DevDesc_Buf );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
/* Print USB device device descriptor */
|
||||
#if DEF_DEBUG_PRINTF
|
||||
for( i = 0; i < 18; i++ )
|
||||
{
|
||||
DUG_PRINTF( "%02x ", DevDesc_Buf[ i ] );
|
||||
}
|
||||
DUG_PRINTF("\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine whether the maximum number of retries has been reached, and retry if not reached */
|
||||
DUG_PRINTF( "Err(%02x)\n", s );
|
||||
if( enum_cnt <= 5 )
|
||||
{
|
||||
goto ENUM_START;
|
||||
}
|
||||
return DEF_DEV_DESCR_GETFAIL;
|
||||
}
|
||||
|
||||
/* Set the USB device address */
|
||||
DUG_PRINTF("Set DevAddr: ");
|
||||
RootHubDev[ usb_port ].bAddress = (uint8_t)( DEF_USB_PORT_FS + USB_DEVICE_ADDR );
|
||||
s = USBFSH_SetUsbAddress( RootHubDev[ usb_port ].bEp0MaxPks, RootHubDev[ usb_port ].bAddress );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
DUG_PRINTF( "OK\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine whether the maximum number of retries has been reached, and retry if not reached */
|
||||
DUG_PRINTF( "Err(%02x)\n", s );
|
||||
if( enum_cnt <= 5 )
|
||||
{
|
||||
goto ENUM_START;
|
||||
}
|
||||
return DEF_DEV_ADDR_SETFAIL;
|
||||
}
|
||||
Delay_Ms( 5 );
|
||||
|
||||
/* Get the USB device configuration descriptor */
|
||||
DUG_PRINTF("Get CfgDesc: ");
|
||||
s = USBFSH_GetConfigDescr( RootHubDev[ usb_port ].bEp0MaxPks, Com_Buffer, DEF_COM_BUF_LEN, &len );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
cfg_val = ( (PUSB_CFG_DESCR)Com_Buffer )->bConfigurationValue;
|
||||
|
||||
/* Print USB device configuration descriptor */
|
||||
#if DEF_DEBUG_PRINTF
|
||||
for( i = 0; i < len; i++ )
|
||||
{
|
||||
DUG_PRINTF( "%02x ", Com_Buffer[ i ] );
|
||||
}
|
||||
DUG_PRINTF("\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine whether the maximum number of retries has been reached, and retry if not reached */
|
||||
DUG_PRINTF( "Err(%02x)\n", s );
|
||||
if( enum_cnt <= 5 )
|
||||
{
|
||||
goto ENUM_START;
|
||||
}
|
||||
return DEF_CFG_DESCR_GETFAIL;
|
||||
}
|
||||
|
||||
/* Set USB device configuration value */
|
||||
DUG_PRINTF("Set Cfg: ");
|
||||
s = USBFSH_SetUsbConfig( RootHubDev[ usb_port ].bEp0MaxPks, cfg_val );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
DUG_PRINTF( "OK\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine whether the maximum number of retries has been reached, and retry if not reached */
|
||||
DUG_PRINTF( "Err(%02x)\n", s );
|
||||
if( enum_cnt <= 5 )
|
||||
{
|
||||
goto ENUM_START;
|
||||
}
|
||||
return ERR_USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_PreDeal
|
||||
*
|
||||
* @brief usb host preemption operations,
|
||||
* including detecting device insertion and enumerating device information
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t UDisk_USBH_PreDeal( void )
|
||||
{
|
||||
uint8_t usb_port;
|
||||
uint8_t index;
|
||||
uint8_t ret;
|
||||
usb_port = DEF_USB_PORT_FS;
|
||||
ret = USBFSH_CheckRootHubPortStatus( RootHubDev[ usb_port ].bStatus );
|
||||
if( ret == ROOT_DEV_CONNECTED )
|
||||
{
|
||||
DUG_PRINTF("USB Dev In.\n");
|
||||
USBFSH_CheckRootHubPortStatus( RootHubDev[ usb_port ].bStatus );
|
||||
RootHubDev[ usb_port ].bStatus = ROOT_DEV_CONNECTED; // Set connection status_
|
||||
RootHubDev[ usb_port ].DeviceIndex = usb_port * DEF_ONE_USB_SUP_DEV_TOTAL;
|
||||
|
||||
/* Enumerate root device */
|
||||
ret = Udisk_USBH_EnumRootDevice( usb_port );
|
||||
if( ret == ERR_SUCCESS )
|
||||
{
|
||||
DUG_PRINTF( "USB Port %02x Device Enumeration Succeed\r\n", usb_port );
|
||||
RootHubDev[ usb_port ].bStatus = ROOT_DEV_SUCCESS;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DUG_PRINTF( "USB Port %02x Device Enumeration ERR %02x.\r\n", usb_port, ret );
|
||||
RootHubDev[ usb_port ].bStatus = ROOT_DEV_FAILED;
|
||||
return ERR_USB_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
else if( ret == ROOT_DEV_DISCONNECT )
|
||||
{
|
||||
DUG_PRINTF("USB Port %02x Device Out.\r\n", usb_port );
|
||||
/* Clear parameters */
|
||||
index = RootHubDev[ usb_port ].DeviceIndex;
|
||||
memset( &RootHubDev[ usb_port ].bStatus, 0, sizeof( struct _ROOT_HUB_DEVICE ) );
|
||||
memset( &HostCtl[ index ].InterfaceNum, 0, sizeof( struct __HOST_CTL ) );
|
||||
UDisk_Opeation_Flag = 1;
|
||||
CHRV3DiskStatus = DISK_UNKNOWN;
|
||||
return ERR_USB_DISCON;
|
||||
}
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_DiskReady
|
||||
*
|
||||
* @brief Check if UDisk is Ready and update status in 'CHRV3DiskStatus'
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t UDisk_USBH_DiskReady( void )
|
||||
{
|
||||
uint8_t ret, i;
|
||||
|
||||
/* Detect USB Device & Enumeration processing */
|
||||
ret = UDisk_USBH_PreDeal( );
|
||||
if( ret == ERR_SUCCESS )
|
||||
{
|
||||
/* Wait for uDisk Ready */
|
||||
CHRV3DiskStatus = DISK_USB_ADDR;
|
||||
for ( i = 0; i != 10; i ++ )
|
||||
{
|
||||
DUG_PRINTF( "Wait Disk Ready...\r\n" );
|
||||
ret = CHRV3DiskReady( );
|
||||
if ( ret == ERR_SUCCESS )
|
||||
{
|
||||
/* Disk Ready */
|
||||
DUG_PRINTF( "Disk Ready Code:%02x.\r\n", ret );
|
||||
DUG_PRINTF( "CHRV3DiskStatus:%02x\n", CHRV3DiskStatus);
|
||||
UDisk_Opeation_Flag = 1;
|
||||
return DISK_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
DUG_PRINTF("Not Ready Code :%02x.\r\n", ret);
|
||||
DUG_PRINTF("CHRV3DiskStatus:%02x.\n", CHRV3DiskStatus);
|
||||
}
|
||||
Delay_Ms( 50 );
|
||||
}
|
||||
}
|
||||
return CHRV3DiskStatus;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : UDisk_Operation.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/11/20
|
||||
* Description : This file contains all the functions prototypes for the Udisk
|
||||
host operation.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef USER_UDISK_OPERATION_H_
|
||||
#define USER_UDISK_OPERATION_H_
|
||||
|
||||
#include "debug.h"
|
||||
#include "string.h"
|
||||
#include "CHRV3UFI.h"
|
||||
#include "ch32v20x_usbfs_host.h"
|
||||
#include "usb_host_config.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Public Extern Variables */
|
||||
extern volatile uint8_t UDisk_Opeation_Flag;
|
||||
extern struct _ROOT_HUB_DEVICE RootHubDev[ DEF_TOTAL_ROOT_HUB ];
|
||||
extern struct __HOST_CTL HostCtl[ DEF_TOTAL_ROOT_HUB * DEF_ONE_USB_SUP_DEV_TOTAL ];
|
||||
extern volatile uint8_t UDisk_Opeation_Flag;
|
||||
extern uint8_t *pCodeStr;
|
||||
|
||||
extern __attribute__((aligned(4))) uint8_t Com_Buffer[ DEF_COM_BUF_LEN ]; // even address , used for host enumcation and udisk operation
|
||||
extern __attribute__((aligned(4))) uint8_t DevDesc_Buf[ 18 ]; // Device Descriptor Buffer
|
||||
|
||||
/*******************************************************************************/
|
||||
/* 长文件名相关的宏定义极其全局变量 */
|
||||
// 长文件名缓冲区从(0到20)*26
|
||||
#define LONG_NAME_BUF_LEN (20*26)
|
||||
#define UNICODE_ENDIAN 0 // 1为UNICDOE大端编码 0为小端
|
||||
// 长文件名存放缓冲区(Unicode编码)
|
||||
extern uint8_t LongNameBuf[ ];
|
||||
// 长文件名(Unicode编码)
|
||||
extern uint8_t LongName[ ];
|
||||
#define LongName_Len 124
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// 函数返回
|
||||
#define ERR_NO_NAME 0X44 // 此短文件名没有长文件名或错误的长文件
|
||||
#define ERR_BUF_OVER 0X45 // 长文件缓冲区溢出
|
||||
#define ERR_LONG_NAME 0X46 // 错误的长文件名
|
||||
#define ERR_NAME_EXIST 0X47 // 此短文件名存在
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Extern UDisk Operation Functions */
|
||||
extern void mStopIfError( uint8_t iError );
|
||||
extern void Udisk_USBH_Initialization( void );
|
||||
extern uint8_t Udisk_USBH_EnumRootDevice( uint8_t usb_port );
|
||||
extern uint8_t UDisk_USBH_PreDeal( void );
|
||||
extern uint8_t UDisk_USBH_DiskReady( void );
|
||||
|
||||
/* Extern Long-name Operation Functions */
|
||||
extern void UDisk_USBH_Longname( void );
|
||||
extern uint8_t CHRV3GetLongName( void );
|
||||
extern uint8_t GetUpSectorData( uint32_t *NowSector );
|
||||
extern uint8_t CHRV3CreateLongName( void );
|
||||
extern uint8_t AnalyzeLongName( void );
|
||||
extern uint8_t CheckNameSum( uint8_t *p );
|
||||
|
||||
/* Extern Creating Directory Functions */
|
||||
extern void UDisk_USBH_CreatDirectory( void );
|
||||
extern uint8_t CreateDirectory( void );
|
||||
|
||||
/* Extern Byte/Sector Open/Read/Modify/Delete and File-Enumeration Functions */
|
||||
extern void UDisk_USBH_ByteOperation( void );
|
||||
extern void UDisk_USBH_SectorOperation( void );
|
||||
extern void UDisk_USBH_EnumFiles( void );
|
||||
|
||||
#endif /* USER_UDISK_OPERATION_H_ */
|
||||
@@ -0,0 +1,345 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Udisk_Func_BasicOp.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/11/22
|
||||
* Description : USB full-speed port host operation functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "Udisk_Operation.h"
|
||||
uint8_t *pCodeStr;
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
__attribute__((aligned(4))) uint8_t MY_DATA_BUF[ DISK_BASE_BUF_LEN ]; /* MY_DATA_BUF指向外部RAM的磁盘数据缓冲区,缓冲区长度为至少一个扇区的长度,用于用户数据缓存 */
|
||||
uint8_t *pCodeStr;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_ByteOperation
|
||||
*
|
||||
* @brief Demo Function For UDisk File Byte-operation
|
||||
* including Create\Modify\Read\Erase (EXAM1)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UDisk_USBH_ByteOperation( void )
|
||||
{
|
||||
uint8_t ret;
|
||||
uint8_t i,t;
|
||||
uint16_t TotalCount = 0;
|
||||
|
||||
ret = UDisk_USBH_DiskReady( );
|
||||
if( (ret == DISK_READY)&&( UDisk_Opeation_Flag == 1 ) )
|
||||
{
|
||||
UDisk_Opeation_Flag = 0;
|
||||
printf("CHRV3DiskStatus:%02x\r\n",CHRV3DiskStatus);
|
||||
/* 读文件 */
|
||||
strcpy( (char *)mCmdParam.Open.mPathName, "/C51/NEWFILE.C" ); //设置将要操作的文件路径和文件名/C51/NEWFILE.C
|
||||
ret = CHRV3FileOpen( ); //打开文件
|
||||
if ( ret == ERR_MISS_DIR || ret == ERR_MISS_FILE ) //没有找到文件
|
||||
{
|
||||
//创建文件演示
|
||||
printf( "Find No File And Create\r\n" );
|
||||
strcpy( (char *)mCmdParam.Create.mPathName, "/C51/NEWFILE.C" ); //新文件名,在根目录下,中文文件名
|
||||
ret = CHRV3FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建
|
||||
mStopIfError( ret );
|
||||
printf( "ByteWrite\r\n" );
|
||||
//实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入
|
||||
i = sprintf( (char *)Com_Buffer,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,简单演示功能。\xd\xa");
|
||||
for(t=0; t<10; t++)
|
||||
{
|
||||
mCmdParam.ByteWrite.mByteCount = i; //指定本次写入的字节数
|
||||
mCmdParam.ByteWrite.mByteBuffer = Com_Buffer; //指向缓冲区
|
||||
ret = CHRV3ByteWrite( ); //以字节为单位向文件写入数据
|
||||
mStopIfError( ret );
|
||||
printf("成功写入 %02X次\r\n",(uint16_t)t);
|
||||
}
|
||||
//演示修改文件属性
|
||||
printf( "Modify\r\n" );
|
||||
mCmdParam.Modify.mFileAttr = 0xff; //输入参数: 新的文件属性,为0FFH则不修改
|
||||
mCmdParam.Modify.mFileTime = 0xffff; //输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间
|
||||
mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 ); //输入参数: 新的文件日期: 2015.05.18
|
||||
mCmdParam.Modify.mFileSize = 0xffffffff; // 输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改
|
||||
i = CHRV3FileModify( ); //修改当前文件的信息,修改日期
|
||||
mStopIfError( i );
|
||||
printf( "Close\r\n" );
|
||||
mCmdParam.Close.mUpdateLen = 1; //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
|
||||
i = CHRV3FileClose( );
|
||||
mStopIfError( i );
|
||||
|
||||
/* 删除某文件 */
|
||||
// printf( "Erase\n" );
|
||||
// strcpy( (char *)mCmdParam.Create.mPathName, "/OLD" ); //将被删除的文件名,在根目录下
|
||||
// i = CHRV3FileErase( ); //删除文件并关闭
|
||||
// if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (uint16_t)i ); //显示错误
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 一、写入文件 */
|
||||
printf( "ByteWrite\r\n" ); //如果希望将新数据添加到原文件的尾部,可以移动文件指针
|
||||
mCmdParam.ByteLocate.mByteOffset = 0xffffffff; //移到文件的尾部
|
||||
CHRV3ByteLocate( ); //实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入
|
||||
i = sprintf( (char *)Com_Buffer,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,简单演示功能。\xd\xa"); //演示文字
|
||||
for(t=0; t<10; t++)
|
||||
{
|
||||
mCmdParam.ByteWrite.mByteCount = i; //指定本次写入的字节数
|
||||
mCmdParam.ByteWrite.mByteBuffer = Com_Buffer; // 指向缓冲区
|
||||
ret = CHRV3ByteWrite( ); // 以字节为单位向文件写入数据
|
||||
mStopIfError( ret );
|
||||
printf("成功写入 %02X次\r\n",(uint16_t)t);
|
||||
}
|
||||
/* 二、读取文件前N字节 */
|
||||
TotalCount = 60; //设置准备读取总长度100字节
|
||||
strcpy( (char *)mCmdParam.Open.mPathName, "/C51/NEWFILE.C" ); //设置将要操作的文件路径和文件名/C51/NEWFILE.C
|
||||
CHRV3FileOpen( ); //打开文件
|
||||
printf( "读出的前%d个字符是:\r\n",TotalCount );
|
||||
while ( TotalCount )
|
||||
{
|
||||
//如果文件比较大,一次读不完,可以再调用CH103ByteRead继续读取,文件指针自动向后移动
|
||||
if ( TotalCount > (MAX_PATH_LEN-1) )
|
||||
{
|
||||
t = MAX_PATH_LEN-1; // 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.Other.mBuffer )
|
||||
}
|
||||
else
|
||||
{
|
||||
t = TotalCount; //最后剩余的字节数
|
||||
}
|
||||
mCmdParam.ByteRead.mByteCount = t; //请求读出几十字节数据
|
||||
mCmdParam.ByteRead.mByteBuffer= &Com_Buffer[0];
|
||||
ret = CHRV3ByteRead( ); //以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读
|
||||
TotalCount -= mCmdParam.ByteRead.mByteCount; //计数,减去当前实际已经读出的字符数
|
||||
for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ )
|
||||
{
|
||||
printf( "%c", mCmdParam.ByteRead.mByteBuffer[i] ); //显示读出的字符
|
||||
}
|
||||
printf( "\r\n" );
|
||||
|
||||
if ( mCmdParam.ByteRead.mByteCount < t ) //实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾
|
||||
{
|
||||
printf( "\r\n" );
|
||||
printf( "文件已经结束\r\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = CHRV3FileClose( ); //关闭文件
|
||||
mStopIfError( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_SectorOperation
|
||||
*
|
||||
* @brief Demo Function For UDisk File Sector-operation
|
||||
* including Create\Modify\Read\Erase (EXAM6)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UDisk_USBH_SectorOperation( void )
|
||||
{
|
||||
uint8_t ret, SecCount, s;
|
||||
uint8_t i;
|
||||
uint16_t tmp;
|
||||
uint8_t tmpbuf[64];
|
||||
|
||||
ret = UDisk_USBH_DiskReady( );
|
||||
if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) )
|
||||
{
|
||||
UDisk_Opeation_Flag = 0;
|
||||
/* 查询磁盘物理容量 */
|
||||
printf( "DiskSize\r\n" );
|
||||
i = CHRV3DiskQuery( );
|
||||
mStopIfError( i );
|
||||
printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.Query.mTotalSector * CHRV3vSectorSizeB / 2 ) ); //显示为以MB为单位的容量
|
||||
|
||||
/* 读取原文件 */
|
||||
printf( "Open\r\n" );
|
||||
strcpy( mCmdParam.Open.mPathName, "/NEWFILE.TXT" );//文件名,该文件在C51子目录下
|
||||
s = CHRV3FileOpen( ); //打开文件
|
||||
if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE )//没有找到文件
|
||||
{
|
||||
printf( "没有找到文件\r\n" );
|
||||
}
|
||||
else //找到文件或者出错
|
||||
{
|
||||
printf( "Query\r\n" );
|
||||
i = CHRV3FileQuery( ); //查询当前文件的信息
|
||||
mStopIfError( i );
|
||||
printf( "Read\r\n" );
|
||||
CHRV3vFileSize = CHRV3vFileSize+(sizeof( MY_DATA_BUF )-1); //原文件的长度
|
||||
SecCount = CHRV3vFileSize/ sizeof( MY_DATA_BUF ) ;//计算文件的扇区数,因为读写是以扇区为单位的,先加CHRV3vSectorSize-1是为了读出文件尾部不足1个扇区的部分
|
||||
printf( "Size=%ld, Sec=%d\r\n", CHRV3vFileSize, (uint16_t)SecCount );
|
||||
while(SecCount--)
|
||||
{
|
||||
mCmdParam.Read.mSectorCount = sizeof( MY_DATA_BUF )/512; //读取全部数据,如果超过2个扇区则只读取2个扇区
|
||||
mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0];//指向文件数据缓冲区的起始地址
|
||||
i = CHRV3FileRead( ); //从文件读取数据
|
||||
mStopIfError( i );
|
||||
if(SecCount == 0) break;
|
||||
/*
|
||||
for(tmp=0; tmp<sizeof( MY_DATA_BUF ); tmp++)
|
||||
{
|
||||
printf("%02X ",(uint16_t)MY_DATA_BUF[tmp]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
}
|
||||
tmp = (CHRV3vFileSize-(sizeof( MY_DATA_BUF )-1))%sizeof( MY_DATA_BUF );
|
||||
if((tmp == 0)&&(CHRV3vFileSize != 0)) tmp = sizeof( MY_DATA_BUF );
|
||||
CHRV3vFileSize = CHRV3vFileSize-(sizeof( MY_DATA_BUF )-1); //恢复原文件的长度
|
||||
/*
|
||||
for(i=0; i<tmp; i++)
|
||||
{
|
||||
printf("%02X ",(uint16_t)MY_DATA_BUF[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
/*
|
||||
如果文件比较大,一次读不完,可以再调用CHRV3FileRead继续读取,文件指针自动向后移动
|
||||
while ( 1 )
|
||||
{
|
||||
c = 4; 每次读取4个扇区,缓冲区定义的越大,一次读取的扇区数越多
|
||||
mCmdParam.Read.mSectorCount = c; 指定读取的扇区数
|
||||
mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0]; 指向文件数据缓冲区的起始地址
|
||||
CHRV3FileRead(); 读完后文件指针自动后移 处理数据
|
||||
if ( mCmdParam.Read.mSectorCount < c ) break; 实际读出的扇区数较小则说明文件已经结束
|
||||
}
|
||||
如果希望从指定位置开始读写,可以移动文件指针
|
||||
mCmdParam.Locate.mSectorOffset = 3; 跳过文件的前3个扇区开始读写
|
||||
i = CHRV3FileLocate( );
|
||||
mCmdParam.Read.mSectorCount = 10;
|
||||
mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0]; 指向文件数据缓冲区的起始地址
|
||||
CHRV3FileRead(); 直接读取从文件的第(CHRV3vSectorSizeH*256*3)个字节开始的数据,前3个扇区被跳过
|
||||
如果希望将新数据添加到原文件的尾部,可以移动文件指针
|
||||
i = CHRV3FileOpen( );
|
||||
mCmdParam.Locate.mSectorOffset = 0xffffffff; 移到文件的尾部,以扇区为单位,如果原文件是3字节,则从CHRV3vSectorSizeH个字节处开始添加
|
||||
i = CHRV3FileLocate( );
|
||||
mCmdParam.Write.mSectorCount = 10;
|
||||
mCmdParam.Write.mDataBuffer = &MY_DATA_BUF[0];
|
||||
CHRV3FileWrite(); 在原文件的后面添加数据
|
||||
使用CHRV3FileRead可以自行定义数据缓冲区的起始地址
|
||||
mCmdParam.Read.mSectorCount = 2;
|
||||
mCmdParam.Read.mDataBuffer = 0x50; 将读出的数据放到50H开始的缓冲区中,需要指定缓冲区的起始地址
|
||||
CHRV3FileRead(); 从文件中读取2个扇区到指定缓冲区
|
||||
使用CHRV3FileWrite可以自行定义数据缓冲区的起始地址
|
||||
mCmdParam.Wiite.mSectorCount = 2;
|
||||
mCmdParam.Write.mDataBuffer = 0x50; 将50H开始的缓冲区中的数据写入
|
||||
CHRV3FileWrite(); 将指定缓冲区中的数据写入2个扇区到文件中
|
||||
*/
|
||||
printf( "Close\r\n" );
|
||||
i = CHRV3FileClose( ); //关闭文件
|
||||
mStopIfError( i );
|
||||
}
|
||||
printf( "Create\r\n" );
|
||||
strcpy( mCmdParam.Create.mPathName, "/NEWFILE.TXT" );//新文件名,在根目录下,中文文件名
|
||||
s = CHRV3FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建 */
|
||||
mStopIfError( s );
|
||||
printf( "Write\r\n" );
|
||||
strcpy( tmpbuf, "0000ABCDEFGHIJKLMNOPQRSTUVWXYZ\xd\xa" );//准备写文件数据
|
||||
for(i=0; i<(DISK_BASE_BUF_LEN/sizeof(tmpbuf)); i++)
|
||||
{
|
||||
tmp=i*sizeof(tmpbuf);
|
||||
strcpy(&MY_DATA_BUF[tmp],tmpbuf);
|
||||
}
|
||||
for(tmp=0; tmp<sizeof(MY_DATA_BUF); tmp++)
|
||||
{
|
||||
printf("%02X",(uint16_t)MY_DATA_BUF[tmp]);
|
||||
}
|
||||
printf("\r\n");
|
||||
for(s=0; s<10; s++)
|
||||
{
|
||||
mCmdParam.Write.mSectorCount = 1; //写入所有扇区的数据
|
||||
mCmdParam.Write.mDataBuffer = &MY_DATA_BUF[0]; //指向文件数据缓冲区的起始地址
|
||||
i = CHRV3FileWrite( ); //向文件写入数据
|
||||
mStopIfError( i );
|
||||
printf("成功写入 %02X次\r\n",(uint16_t)s);
|
||||
}
|
||||
/* printf( "Modify\n" );
|
||||
mCmdParam.Modify.mFileAttr = 0xff; 输入参数: 新的文件属性,为0FFH则不修改
|
||||
mCmdParam.Modify.mFileTime = 0xffff; 输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间
|
||||
mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 ); 输入参数: 新的文件日期: 2015.05.18
|
||||
mCmdParam.Modify.mFileSize = 0xffffffff; 输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改
|
||||
i = CHRV3FileModify( ); 修改当前文件的信息,修改日期
|
||||
mStopIfError( i );
|
||||
*/
|
||||
printf( "Close\r\n" );
|
||||
mCmdParam.Close.mUpdateLen = 1; //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
|
||||
i = CHRV3FileClose( );
|
||||
mStopIfError( i );
|
||||
/* 删除某文件 */
|
||||
/*printf( "Erase\n" );
|
||||
strcpy( mCmdParam.Create.mPathName, "/OLD.TXT" ); 将被删除的文件名,在根目录下
|
||||
i = CHRV3FileErase( ); 删除文件并关闭
|
||||
if ( i != ERR_SUCCESS ) printf( "Error File not exist: %02X\n", (uint16_t)i ); 显示错误
|
||||
*/
|
||||
printf( "U盘演示完成\r\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UDisk_USBH_EnumFiles
|
||||
*
|
||||
* @brief Demo Function For Enumerating files in UDisk(EXAM11)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UDisk_USBH_EnumFiles( void )
|
||||
{
|
||||
uint8_t i, s, ret;
|
||||
uint16_t j;
|
||||
|
||||
ret = UDisk_USBH_DiskReady( );
|
||||
if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) )
|
||||
{
|
||||
UDisk_Opeation_Flag = 0;
|
||||
/* 读取原文件 */
|
||||
printf( "Open\r\n" );
|
||||
strcpy( mCmdParam.Open.mPathName, "/C51/CHRV3HFT.C" );//文件名,该文件在C51子目录下
|
||||
s = CHRV3FileOpen( ); //打开文件
|
||||
/* 列出文件 */
|
||||
if ( s == ERR_MISS_DIR )
|
||||
{
|
||||
printf("不存在该文件则列出所有文件\r\n"); //C51子目录不存在则列出根目录下的所有文件
|
||||
pCodeStr = "/*";
|
||||
}
|
||||
else
|
||||
{
|
||||
pCodeStr = "/C51/*"; //CHRV3HFT.C文件不存在则列出\C51子目录下的以CHRV3开头的文件
|
||||
}
|
||||
printf( "List file %s\r\n", pCodeStr );
|
||||
for ( j = 0; j < 10000; j ++ ) //最多搜索前10000个文件,实际上没有限制
|
||||
{
|
||||
strcpy( (char *)mCmdParam.Open.mPathName, pCodeStr );//搜索文件名,*为通配符,适用于所有文件或者子目录
|
||||
i = strlen( mCmdParam.Open.mPathName );
|
||||
mCmdParam.Open.mPathName[ i ] = 0xFF; //根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CHRV3vFileSize变量中
|
||||
CHRV3vFileSize = j; //指定搜索/枚举的序号
|
||||
i = CHRV3FileOpen( ); //打开文件,如果文件名中含有通配符*,则为搜索文件而不打开
|
||||
/* CHRV3FileEnum 与 CHRV3FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */
|
||||
if ( i == ERR_MISS_FILE )
|
||||
{
|
||||
break; //再也搜索不到匹配的文件,已经没有匹配的文件名
|
||||
}
|
||||
if ( i == ERR_FOUND_NAME )
|
||||
{
|
||||
/* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */
|
||||
printf( " match file %04d#: %s\r\n", (unsigned int)j, mCmdParam.Open.mPathName );//显示序号和搜索到的匹配文件名或者子目录名
|
||||
continue; //继续搜索下一个匹配的文件名,下次搜索时序号会加1
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 出错 */
|
||||
mStopIfError( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf( "Close\r\n" );
|
||||
CHRV3FileClose( ); //关闭文件
|
||||
printf( "U盘演示完成\r\n" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,655 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32f20x_usbfs_host.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/09/01
|
||||
* Description : USB full-speed port host operation functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "usb_host_config.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
__attribute__((aligned(4))) uint8_t RxBuffer[ MAX_PACKET_SIZE ]; // IN, must even address
|
||||
__attribute__((aligned(4))) uint8_t TxBuffer[ MAX_PACKET_SIZE ]; // OUT, must even address
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFS_RCC_Init
|
||||
*
|
||||
* @brief Set USB port clock.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_RCC_Init( void )
|
||||
{
|
||||
if( SystemCoreClock == 144000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div3 );
|
||||
}
|
||||
else if( SystemCoreClock == 96000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div2 );
|
||||
}
|
||||
else if( SystemCoreClock == 48000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div1 );
|
||||
}
|
||||
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_OTG_FS, ENABLE );
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn USBFS_Host_Init
|
||||
*
|
||||
* @brief Initialize USB port host configuration.
|
||||
*
|
||||
* @param sta - ENABLE or DISABLE
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_Host_Init( FunctionalState sta )
|
||||
{
|
||||
if( sta == ENABLE )
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE;
|
||||
USBOTG_H_FS->HOST_CTRL = 0;
|
||||
USBOTG_H_FS->DEV_ADDR = 0;
|
||||
USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN;
|
||||
|
||||
USBOTG_H_FS->HOST_RX_DMA = (uint32_t)USBFS_RX_Buf;
|
||||
USBOTG_H_FS->HOST_TX_DMA = (uint32_t)USBFS_TX_Buf;
|
||||
|
||||
USBOTG_H_FS->HOST_RX_CTRL = 0;
|
||||
USBOTG_H_FS->HOST_TX_CTRL = 0;
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
|
||||
|
||||
USBOTG_H_FS->INT_FG = 0xFF;
|
||||
|
||||
USBOTG_H_FS->INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortStatus
|
||||
*
|
||||
* @brief Check status of USB port.
|
||||
*
|
||||
* @para dev_sta: The status of the root device connected to this port.
|
||||
*
|
||||
* @return The current status of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortStatus( uint8_t dev_sta )
|
||||
{
|
||||
/* Check USB device connection or disconnection */
|
||||
if( ( USBOTG_H_FS->INT_FG ) & USBFS_UIF_DETECT )
|
||||
{
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT; // Clear flag
|
||||
if( USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH ) // Check that the USB device has been connected to the port
|
||||
{
|
||||
if( ( dev_sta == ROOT_DEV_DISCONNECT ) || ( ( dev_sta != ROOT_DEV_FAILED ) && ( USBFSH_CheckRootHubPortEnable( ) == 0x00 ) ) )
|
||||
{
|
||||
return ROOT_DEV_CONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROOT_DEV_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROOT_DEV_DISCONNECT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROOT_DEV_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortEnable
|
||||
*
|
||||
* @brief Check the enable status of the USB port.
|
||||
*
|
||||
* @return The current enable status of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortEnable( void )
|
||||
{
|
||||
return ( USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortSpeed
|
||||
*
|
||||
* @brief Check the speed of the USB port.
|
||||
*
|
||||
* @return The current speed of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortSpeed( void )
|
||||
{
|
||||
return ( USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL? USB_LOW_SPEED: USB_FULL_SPEED );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetSelfAddr
|
||||
*
|
||||
* @brief Set the USB device address.
|
||||
*
|
||||
* @para addr: USB device address.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_SetSelfAddr( uint8_t addr )
|
||||
{
|
||||
USBOTG_H_FS->DEV_ADDR = ( USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT ) | ( addr & USBFS_USB_ADDR_MASK );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetSelfSpeed
|
||||
*
|
||||
* @brief Set USB speed.
|
||||
*
|
||||
* @para speed: USB speed.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_SetSelfSpeed( uint8_t speed )
|
||||
{
|
||||
if( speed )
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL &= ~USBFS_UC_LOW_SPEED;
|
||||
USBOTG_H_FS->HOST_SETUP &= ~USBFS_UH_PRE_PID_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_ResetRootHubPort
|
||||
*
|
||||
* @brief Reset USB port.
|
||||
*
|
||||
* @para mod: Reset host port operating mode.
|
||||
* 0 -> reset and wait end
|
||||
* 1 -> begin reset
|
||||
* 2 -> end reset
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_ResetRootHubPort( uint8_t mode )
|
||||
{
|
||||
USBFSH_SetSelfAddr( 0x00 );
|
||||
USBFSH_SetSelfSpeed( 1 );
|
||||
if( mode <= 1 )
|
||||
{
|
||||
USBOTG_H_FS->HOST_CTRL = ( USBOTG_H_FS->HOST_CTRL & ~USBFS_UH_LOW_SPEED ) | USBFS_UH_BUS_RESET;
|
||||
}
|
||||
if( mode == 0 )
|
||||
{
|
||||
Delay_Ms( DEF_BUS_RESET_TIME ); // Reset time from 10mS to 20mS
|
||||
}
|
||||
if( mode != 1 )
|
||||
{
|
||||
USBOTG_H_FS->HOST_CTRL = USBOTG_H_FS->HOST_CTRL & ~USBFS_UH_BUS_RESET; // End Reset
|
||||
}
|
||||
Delay_Ms( 2 );
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_EnableRootHubPort
|
||||
*
|
||||
* @brief Enable USB host port.
|
||||
*
|
||||
* @para *pspeed: USB speed.
|
||||
*
|
||||
* @return Operation result of the enabled port.
|
||||
*/
|
||||
uint8_t USBFSH_EnableRootHubPort( uint8_t *pspeed )
|
||||
{
|
||||
if( USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH )
|
||||
{
|
||||
if( USBFSH_CheckRootHubPortEnable( ) == 0x00 )
|
||||
{
|
||||
*pspeed = USBFSH_CheckRootHubPortSpeed( );
|
||||
if( *pspeed == 0 )
|
||||
{
|
||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED;
|
||||
}
|
||||
}
|
||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
|
||||
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERR_USB_DISCON;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_Transact
|
||||
*
|
||||
* @brief Perform USB transaction.
|
||||
*
|
||||
* @para endp_pid: Token PID.
|
||||
* endp_tog: Toggle
|
||||
* timeout: Timeout time.
|
||||
*
|
||||
* @return USB transfer result.
|
||||
*/
|
||||
uint8_t USBFSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint16_t timeout )
|
||||
{
|
||||
uint8_t r, trans_rerty;
|
||||
uint16_t i;
|
||||
|
||||
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = endp_tog;
|
||||
trans_rerty = 0;
|
||||
do
|
||||
{
|
||||
USBOTG_H_FS->HOST_EP_PID = endp_pid; // Specify token PID and endpoint number
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; // Allow transmission
|
||||
for( i = DEF_WAIT_USB_TOUT_200US; ( i != 0 ) && ( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 ); i-- )
|
||||
{
|
||||
Delay_Us( 1 );
|
||||
}
|
||||
USBOTG_H_FS->HOST_EP_PID = 0x00; // Stop USB transfer
|
||||
if( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 )
|
||||
{
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Complete transfer */
|
||||
if( USBOTG_H_FS->INT_ST & USBFS_UIS_TOG_OK )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
r = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK; // USB device answer status
|
||||
if( r == USB_PID_STALL )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
if( r == USB_PID_NAK )
|
||||
{
|
||||
if( timeout == 0 )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
if( timeout < 0xFFFF )
|
||||
{
|
||||
timeout--;
|
||||
}
|
||||
--trans_rerty;
|
||||
}
|
||||
else switch ( endp_pid >> 4 )
|
||||
{
|
||||
case USB_PID_SETUP:
|
||||
case USB_PID_OUT:
|
||||
if( r )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
break;
|
||||
case USB_PID_IN:
|
||||
if( ( r == USB_PID_DATA0 ) && ( r == USB_PID_DATA1 ) )
|
||||
{
|
||||
;
|
||||
}
|
||||
else if( r )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
}
|
||||
Delay_Us( 15 );
|
||||
if( USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT )
|
||||
{
|
||||
Delay_Us( 200 );
|
||||
if( USBFSH_CheckRootHubPortEnable( ) == 0 )
|
||||
{
|
||||
return ERR_USB_DISCON; // USB device disconnect event
|
||||
}
|
||||
}
|
||||
}while( ++trans_rerty < 10 );
|
||||
|
||||
return ERR_USB_TRANSFER; // Reply timeout
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CtrlTransfer
|
||||
*
|
||||
* @brief USB host control transfer.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
* plen: Data length
|
||||
*
|
||||
* @return USB control transfer result.
|
||||
*/
|
||||
uint8_t USBFSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t rem_len, rx_len, rx_cnt, tx_cnt;
|
||||
|
||||
if( plen )
|
||||
{
|
||||
*plen = 0;
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_LEN = sizeof( USB_SETUP_REQ );
|
||||
s = USBFSH_Transact( USB_PID_SETUP << 4 | 0x00, 0x00, DEF_CTRL_TRANS_TIMEOVER_CNT ); // SETUP stage, 200mS timeout
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = USBFS_UH_T_TOG | USBFS_UH_R_TOG | USBFS_UH_T_AUTO_TOG | USBFS_UH_R_AUTO_TOG; // Default DATA1
|
||||
USBOTG_H_FS->HOST_TX_LEN = 0x01; // The default no-data state stage is IN
|
||||
rem_len = pUSBFS_SetupRequest->wLength;
|
||||
if( rem_len && pbuf )
|
||||
{
|
||||
if( pUSBFS_SetupRequest->bRequestType & USB_REQ_TYP_IN )
|
||||
{
|
||||
/* Receive data */
|
||||
while( rem_len )
|
||||
{
|
||||
Delay_Us( 100 );
|
||||
s = USBFSH_Transact( USB_PID_IN << 4 | 0x00, USBOTG_H_FS->HOST_RX_CTRL, DEF_CTRL_TRANS_TIMEOVER_CNT ); // IN
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
rx_len = ( USBOTG_H_FS->RX_LEN < rem_len )? USBOTG_H_FS->RX_LEN : rem_len;
|
||||
rem_len -= rx_len;
|
||||
if( plen )
|
||||
{
|
||||
*plen += rx_len; // The total length of the actual successful transmission and reception
|
||||
}
|
||||
for( rx_cnt = 0; rx_cnt != rx_len; rx_cnt++ )
|
||||
{
|
||||
*pbuf = USBFS_RX_Buf[ rx_cnt ];
|
||||
pbuf++;
|
||||
}
|
||||
|
||||
if( ( USBOTG_H_FS->RX_LEN == 0 ) || ( USBOTG_H_FS->RX_LEN & ( ep0_size - 1 ) ) )
|
||||
{
|
||||
break; // Short package
|
||||
}
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_LEN = 0x00; // Status stage is OUT
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send data */
|
||||
while( rem_len )
|
||||
{
|
||||
Delay_Us( 100 );
|
||||
USBOTG_H_FS->HOST_TX_LEN = ( rem_len >= ep0_size )? ep0_size : rem_len;
|
||||
for( tx_cnt = 0; tx_cnt != USBOTG_H_FS->HOST_TX_LEN; tx_cnt++ )
|
||||
{
|
||||
USBFS_TX_Buf[ tx_cnt ] = *pbuf;
|
||||
pbuf++;
|
||||
}
|
||||
s = USBFSH_Transact( USB_PID_OUT << 4 | 0x00, USBOTG_H_FS->HOST_TX_CTRL, DEF_CTRL_TRANS_TIMEOVER_CNT ); // OUT
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
rem_len -= USBOTG_H_FS->HOST_TX_LEN;
|
||||
if( plen )
|
||||
{
|
||||
*plen += USBOTG_H_FS->HOST_TX_LEN; // The total length of the actual successful transmission and reception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Delay_Us( 100 );
|
||||
s = USBFSH_Transact( ( USBOTG_H_FS->HOST_TX_LEN )? ( USB_PID_IN << 4 | 0x00 ) : ( USB_PID_OUT << 4 | 0x00 ), USBFS_UH_R_TOG | USBFS_UH_T_TOG, DEF_CTRL_TRANS_TIMEOVER_CNT ); /* STATUS½×¶Î */
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
if( USBOTG_H_FS->HOST_TX_LEN == 0 )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
if( USBOTG_H_FS->RX_LEN == 0 )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetDeviceDescr
|
||||
*
|
||||
* @brief Get the device descriptor of the USB device.
|
||||
*
|
||||
* @para pep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
*
|
||||
* @return The result of getting the device descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t len;
|
||||
|
||||
*pep0_size = DEFAULT_ENDP0_SIZE;
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetDevDesc, sizeof( USB_SETUP_REQ ) );
|
||||
s = USBFSH_CtrlTransfer( *pep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
*pep0_size = ( (PUSB_DEV_DESCR)pbuf )->bMaxPacketSize0;
|
||||
if( len < ( (PUSB_SETUP_REQ)SetupGetDevDesc )->wLength )
|
||||
{
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetConfigDescr
|
||||
*
|
||||
* @brief Get the configuration descriptor of the USB device.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
* buf_len: Data buffer length
|
||||
* pcfg_len: The length of the device configuration descriptor
|
||||
*
|
||||
* @return The result of getting the configuration descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) );
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, pcfg_len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
if( *pcfg_len < ( (PUSB_SETUP_REQ)SetupGetCfgDesc )->wLength )
|
||||
{
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
|
||||
*pcfg_len = ( (PUSB_CFG_DESCR)pbuf )->wTotalLength;
|
||||
if( *pcfg_len > buf_len )
|
||||
{
|
||||
*pcfg_len = buf_len;
|
||||
}
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wLength = *pcfg_len;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, pcfg_len );
|
||||
return s;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetStrDescr
|
||||
*
|
||||
* @brief Get the string descriptor of the USB device.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* str_num: Index of string descriptor
|
||||
* pbuf: Data buffer
|
||||
*
|
||||
* @return The result of getting the string descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t len;
|
||||
|
||||
/* Get the string descriptor of the first 4 bytes */
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Get the complete string descriptor */
|
||||
len = pbuf[ 0 ];
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num;
|
||||
pUSBFS_SetupRequest->wLength = len;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetUsbAddress
|
||||
*
|
||||
* @brief Set USB device address.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* addr: Device address
|
||||
*
|
||||
* @return The result of setting device address.
|
||||
*/
|
||||
uint8_t USBFSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( pUSBFS_SetupRequest, SetupSetAddr, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = (uint16_t)addr;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBFSH_SetSelfAddr( addr );
|
||||
Delay_Ms( DEF_BUS_RESET_TIME >> 1 ); // Wait for the USB device to complete its operation.
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetUsbConfig
|
||||
*
|
||||
* @brief Set USB configuration.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* cfg: Device configuration value
|
||||
*
|
||||
* @return The result of setting device configuration.
|
||||
*/
|
||||
uint8_t USBFSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val )
|
||||
{
|
||||
memcpy( pUSBFS_SetupRequest, SetupSetConfig, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = (uint16_t)cfg_val;
|
||||
return USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_ClearEndpStall
|
||||
*
|
||||
* @brief Clear endpoint stall.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* endp_num: Endpoint number.
|
||||
*
|
||||
* @return The result of clearing endpoint stall.
|
||||
*/
|
||||
uint8_t USBFSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num )
|
||||
{
|
||||
memcpy( pUSBFS_SetupRequest, SetupClearEndpStall, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wIndex = (uint16_t)endp_num;
|
||||
return USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetEndpData
|
||||
*
|
||||
* @brief Get data from USB device input endpoint.
|
||||
*
|
||||
* @para endp_num: Endpoint number
|
||||
* pendp_tog: Endpoint toggle
|
||||
* pbuf: Data Buffer
|
||||
* plen: Data length
|
||||
*
|
||||
* @return The result of getting data.
|
||||
*/
|
||||
uint8_t USBFSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
s = USBFSH_Transact( ( USB_PID_IN << 4 ) | endp_num, *pendp_tog, 0 );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
*pendp_tog ^= USBFS_UH_T_TOG | USBFS_UH_R_TOG;
|
||||
*plen = USBOTG_H_FS->RX_LEN;
|
||||
memcpy( pbuf, USBFS_RX_Buf, *plen );
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SendEndpData
|
||||
*
|
||||
* @brief Send data to the USB device output endpoint.
|
||||
*
|
||||
* @para endp_num: Endpoint number
|
||||
* pendp_tog: Endpoint toggle
|
||||
* pbuf: Data Buffer
|
||||
* plen: Data length
|
||||
*
|
||||
* @return The result of sending data.
|
||||
*/
|
||||
uint8_t USBFSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( USBFS_TX_Buf, pbuf, len );
|
||||
USBOTG_H_FS->HOST_TX_LEN = len;
|
||||
|
||||
s = USBFSH_Transact( ( USB_PID_OUT << 4 ) | endp_num, *pendp_tog, 0 );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
*pendp_tog ^= USBFS_UH_T_TOG | USBFS_UH_R_TOG;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbfs_host.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : USBOTG full speed host header file
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CH32V20x_USBFS_HOST_H__
|
||||
#define __CH32V20x_USBFS_HOST_H__
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "ch32v20x.h"
|
||||
#include "ch32v20x_usb.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* USB Setup Request Macro Definition */
|
||||
#define pUSBFS_SetupRequest ( (PUSB_SETUP_REQ)USBFS_TX_Buf )
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Constant Definition */
|
||||
#ifndef DEF_GET_USB_DEV_DESC
|
||||
#define DEF_GET_USB_DEV_DESC
|
||||
/* Get Device Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetDevDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof( USB_DEV_DESCR ), 0x00
|
||||
};
|
||||
|
||||
/* Get Configuration Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetCfgDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00
|
||||
};
|
||||
|
||||
/* Get String Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetStrDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_STRING, 0x09, 0x04, 0x04, 0x00
|
||||
};
|
||||
|
||||
/* Set USB Address Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetAddr[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT, USB_SET_ADDRESS, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Set USB Configuration Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetConfig[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Clear Endpoint STALL Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupClearEndpStall[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Set Device Interface Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetInterface[ ] =
|
||||
{
|
||||
USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Declaration */
|
||||
extern __attribute__((aligned(4))) uint8_t RxBuffer[ ]; // IN, must even address
|
||||
extern __attribute__((aligned(4))) uint8_t TxBuffer[ ]; // OUT, must even address
|
||||
#define USBFS_RX_Buf RxBuffer
|
||||
#define USBFS_TX_Buf TxBuffer
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Function Declaration */
|
||||
extern void USBFS_RCC_Init( void );
|
||||
extern void USBFS_Host_Init( FunctionalState sta );
|
||||
extern uint8_t USBFSH_CheckRootHubPortStatus( uint8_t dev_sta );
|
||||
extern uint8_t USBFSH_CheckRootHubPortEnable( void );
|
||||
extern uint8_t USBFSH_CheckRootHubPortSpeed( void );
|
||||
extern void USBFSH_SetSelfAddr( uint8_t addr );
|
||||
extern void USBFSH_SetSelfSpeed( uint8_t speed );
|
||||
extern void USBFSH_ResetRootHubPort( uint8_t mode );
|
||||
extern uint8_t USBFSH_EnableRootHubPort( uint8_t *pspeed );
|
||||
extern uint8_t USBFSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint16_t timeout );
|
||||
extern uint8_t USBFSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen );
|
||||
extern uint8_t USBFSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf );
|
||||
extern uint8_t USBFSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len );
|
||||
extern uint8_t USBFSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf );
|
||||
extern uint8_t USBFSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr );
|
||||
extern uint8_t USBFSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val );
|
||||
extern uint8_t USBFSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num );
|
||||
extern uint8_t USBFSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen );
|
||||
extern uint8_t USBFSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len );
|
||||
extern uint8_t USBFSH_PortDetect( uint8_t status );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,169 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : usb_host_config.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/08/29
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __USB_HOST_CONFIG_H
|
||||
#define __USB_HOST_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header File */
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
#include "ch32v20x_usb.h"
|
||||
#include "ch32v20x_usbfs_host.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* USB Host Communication Related Macro Definition */
|
||||
|
||||
/* USB Host Port General Control */
|
||||
#define DEF_TOTAL_ROOT_HUB 1
|
||||
#define DEF_USB_PORT_FS_EN 1
|
||||
#define DEF_USB_PORT_FS 0x00
|
||||
|
||||
/* USB Root Device Status */
|
||||
#define ROOT_DEV_DISCONNECT 0
|
||||
#define ROOT_DEV_CONNECTED 1
|
||||
#define ROOT_DEV_FAILED 2
|
||||
#define ROOT_DEV_SUCCESS 3
|
||||
|
||||
/* USB Device Address */
|
||||
#define USB_DEVICE_ADDR 0x02
|
||||
|
||||
/* USB Speed */
|
||||
#define USB_LOW_SPEED 0x00
|
||||
#define USB_FULL_SPEED 0x01
|
||||
#define USB_HIGH_SPEED 0x02
|
||||
#define USB_SPEED_CHECK_ERR 0xFF
|
||||
|
||||
/* Configuration Descriptor Type */
|
||||
#define DEF_DECR_CONFIG 0x02
|
||||
#define DEF_DECR_INTERFACE 0x04
|
||||
#define DEF_DECR_ENDPOINT 0x05
|
||||
#define DEF_DECR_HID 0x21
|
||||
|
||||
/* USB Communication Status Code */
|
||||
#define ERR_SUCCESS 0x00
|
||||
#define ERR_USB_CONNECT 0x15
|
||||
#define ERR_USB_DISCON 0x16
|
||||
#define ERR_USB_BUF_OVER 0x17
|
||||
#define ERR_USB_DISK_ERR 0x1F
|
||||
#define ERR_USB_TRANSFER 0x20
|
||||
#define ERR_USB_UNSUPPORT 0xFB
|
||||
#define ERR_USB_UNAVAILABLE 0xFC
|
||||
#define ERR_USB_UNKNOWN 0xFE
|
||||
|
||||
/* USB Device Enumeration Status Code */
|
||||
#define DEF_DEV_DESCR_GETFAIL 0x45
|
||||
#define DEF_DEV_ADDR_SETFAIL 0x46
|
||||
#define DEF_CFG_DESCR_GETFAIL 0x47
|
||||
#define DEF_REP_DESCR_GETFAIL 0x48
|
||||
#define DEF_DEV_TYPE_UNKNOWN 0xFF
|
||||
|
||||
/* USB Communication Time */
|
||||
#define DEF_BUS_RESET_TIME 11 // USB bus reset time
|
||||
#define DEF_RE_ATTACH_TIMEOUT 100 // Wait for the USB device to reconnect after reset, 100mS timeout
|
||||
#define DEF_WAIT_USB_TOUT_200US 1000
|
||||
#define DEF_CTRL_TRANS_TIMEOVER_CNT 60000 // Control transmission delay timing
|
||||
|
||||
/* General */
|
||||
#define DEF_ONE_USB_SUP_DEV_TOTAL 1
|
||||
#define DEF_NEXT_HUB_PORT_NUM_MAX 4
|
||||
#define DEF_INTERFACE_NUM_MAX 4
|
||||
#define DEF_COM_BUF_LEN 255
|
||||
|
||||
/* Debug */
|
||||
#define DEF_DEBUG_PRINTF 1
|
||||
#if ( DEF_DEBUG_PRINTF == 1 )
|
||||
#define DUG_PRINTF( format, arg... ) printf( format, ##arg )
|
||||
#else
|
||||
#define DUG_PRINTF( format, arg... ) do{ if( 0 )printf( format, ##arg ); }while( 0 );
|
||||
#endif
|
||||
|
||||
/* HUB Port Device */
|
||||
typedef struct _HUB_DEVICE
|
||||
{
|
||||
uint8_t bStatus;
|
||||
uint8_t bType;
|
||||
uint8_t bAddress;
|
||||
uint8_t bSpeed;
|
||||
uint8_t bEp0MaxPks;
|
||||
uint8_t DeviceIndex;
|
||||
}HUB_DEVICE, *PHUB_DEVICE;
|
||||
|
||||
/* Root HUB Device Structure, Physical Interface */
|
||||
typedef struct _ROOT_HUB_DEVICE
|
||||
{
|
||||
uint8_t bStatus;
|
||||
uint8_t bType;
|
||||
uint8_t bAddress;
|
||||
uint8_t bSpeed;
|
||||
uint8_t bEp0MaxPks;
|
||||
uint8_t DeviceIndex;
|
||||
uint8_t bPortNum;
|
||||
HUB_DEVICE Device[ DEF_NEXT_HUB_PORT_NUM_MAX ];
|
||||
} ROOT_HUB_DEVICE, *PROOT_HUB_DEVICE;
|
||||
|
||||
/* USB Host Control Structure */
|
||||
struct __HOST_CTL
|
||||
{
|
||||
uint8_t InterfaceNum;
|
||||
uint8_t ErrorCount;
|
||||
|
||||
struct interface
|
||||
{
|
||||
uint8_t Type;
|
||||
uint16_t HidDescLen;
|
||||
uint8_t HidReportID;
|
||||
uint8_t Full_KB_Flag;
|
||||
|
||||
uint8_t InEndpNum;
|
||||
uint8_t InEndpAddr[ 4 ];
|
||||
uint8_t InEndpType[ 4 ];
|
||||
uint16_t InEndpSize[ 4 ];
|
||||
uint8_t InEndpTog[ 4 ];
|
||||
uint8_t InEndpInterval[ 4 ];
|
||||
uint8_t InEndpTimeCount[ 4 ];
|
||||
|
||||
uint8_t OutEndpNum;
|
||||
uint8_t OutEndpAddr[ 4 ];
|
||||
uint8_t OutEndpType[ 4 ];
|
||||
uint16_t OutEndpSize[ 4 ];
|
||||
uint8_t OutEndpTog[ 4 ];
|
||||
|
||||
uint8_t IDFlag;
|
||||
uint8_t ReportID;
|
||||
|
||||
uint8_t LED_Usage_Min;
|
||||
uint8_t LED_Usage_Max;
|
||||
|
||||
uint8_t SetReport_Swi;
|
||||
uint8_t SetReport_Value;
|
||||
uint8_t SetReport_Flag;
|
||||
|
||||
}Interface[ DEF_INTERFACE_NUM_MAX ];
|
||||
};
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Declaration */
|
||||
extern uint8_t DevDesc_Buf[ ];
|
||||
extern uint8_t Com_Buf[ ];
|
||||
extern struct _ROOT_HUB_DEVICE RootHubDev[ ];
|
||||
extern struct __HOST_CTL HostCtl[ ];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x_it.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v30x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V30x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CH32V20x_USB_H
|
||||
#define __CH32V20x_USB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header Files */
|
||||
#include "stdint.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* USB Communication Related Macro Definition */
|
||||
|
||||
/* USB Endpoint0 Size */
|
||||
#ifndef DEFAULT_ENDP0_SIZE
|
||||
#define DEFAULT_ENDP0_SIZE 8 // default maximum packet size for endpoint 0
|
||||
#endif
|
||||
#ifndef MAX_PACKET_SIZE
|
||||
#define MAX_PACKET_SIZE 64 // maximum packet size
|
||||
#endif
|
||||
|
||||
/* USB PID */
|
||||
#ifndef USB_PID_SETUP
|
||||
#define USB_PID_NULL 0x00
|
||||
#define USB_PID_SOF 0x05
|
||||
#define USB_PID_SETUP 0x0D
|
||||
#define USB_PID_IN 0x09
|
||||
#define USB_PID_OUT 0x01
|
||||
#define USB_PID_NYET 0x06
|
||||
#define USB_PID_ACK 0x02
|
||||
#define USB_PID_NAK 0x0A
|
||||
#define USB_PID_STALL 0x0E
|
||||
#define USB_PID_DATA0 0x03
|
||||
#define USB_PID_DATA1 0x0B
|
||||
#define USB_PID_PRE 0x0C
|
||||
#endif
|
||||
|
||||
/* USB standard device request code */
|
||||
#ifndef USB_GET_DESCRIPTOR
|
||||
#define USB_GET_STATUS 0x00
|
||||
#define USB_CLEAR_FEATURE 0x01
|
||||
#define USB_SET_FEATURE 0x03
|
||||
#define USB_SET_ADDRESS 0x05
|
||||
#define USB_GET_DESCRIPTOR 0x06
|
||||
#define USB_SET_DESCRIPTOR 0x07
|
||||
#define USB_GET_CONFIGURATION 0x08
|
||||
#define USB_SET_CONFIGURATION 0x09
|
||||
#define USB_GET_INTERFACE 0x0A
|
||||
#define USB_SET_INTERFACE 0x0B
|
||||
#define USB_SYNCH_FRAME 0x0C
|
||||
#endif
|
||||
|
||||
#define DEF_STRING_DESC_LANG 0x00
|
||||
#define DEF_STRING_DESC_MANU 0x01
|
||||
#define DEF_STRING_DESC_PROD 0x02
|
||||
#define DEF_STRING_DESC_SERN 0x03
|
||||
|
||||
/* USB hub class request code */
|
||||
#ifndef HUB_GET_DESCRIPTOR
|
||||
#define HUB_GET_STATUS 0x00
|
||||
#define HUB_CLEAR_FEATURE 0x01
|
||||
#define HUB_GET_STATE 0x02
|
||||
#define HUB_SET_FEATURE 0x03
|
||||
#define HUB_GET_DESCRIPTOR 0x06
|
||||
#define HUB_SET_DESCRIPTOR 0x07
|
||||
#endif
|
||||
|
||||
/* USB HID class request code */
|
||||
#ifndef HID_GET_REPORT
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
#define HID_GET_PROTOCOL 0x03
|
||||
#define HID_SET_REPORT 0x09
|
||||
#define HID_SET_IDLE 0x0A
|
||||
#define HID_SET_PROTOCOL 0x0B
|
||||
#endif
|
||||
|
||||
/* Bit Define for USB Request Type */
|
||||
#ifndef USB_REQ_TYP_MASK
|
||||
#define USB_REQ_TYP_IN 0x80
|
||||
#define USB_REQ_TYP_OUT 0x00
|
||||
#define USB_REQ_TYP_READ 0x80
|
||||
#define USB_REQ_TYP_WRITE 0x00
|
||||
#define USB_REQ_TYP_MASK 0x60
|
||||
#define USB_REQ_TYP_STANDARD 0x00
|
||||
#define USB_REQ_TYP_CLASS 0x20
|
||||
#define USB_REQ_TYP_VENDOR 0x40
|
||||
#define USB_REQ_TYP_RESERVED 0x60
|
||||
#define USB_REQ_RECIP_MASK 0x1F
|
||||
#define USB_REQ_RECIP_DEVICE 0x00
|
||||
#define USB_REQ_RECIP_INTERF 0x01
|
||||
#define USB_REQ_RECIP_ENDP 0x02
|
||||
#define USB_REQ_RECIP_OTHER 0x03
|
||||
#define USB_REQ_FEAT_REMOTE_WAKEUP 0x01
|
||||
#define USB_REQ_FEAT_ENDP_HALT 0x00
|
||||
#endif
|
||||
|
||||
/* USB Descriptor Type */
|
||||
#ifndef USB_DESCR_TYP_DEVICE
|
||||
#define USB_DESCR_TYP_DEVICE 0x01
|
||||
#define USB_DESCR_TYP_CONFIG 0x02
|
||||
#define USB_DESCR_TYP_STRING 0x03
|
||||
#define USB_DESCR_TYP_INTERF 0x04
|
||||
#define USB_DESCR_TYP_ENDP 0x05
|
||||
#define USB_DESCR_TYP_QUALIF 0x06
|
||||
#define USB_DESCR_TYP_SPEED 0x07
|
||||
#define USB_DESCR_TYP_OTG 0x09
|
||||
#define USB_DESCR_TYP_BOS 0X0F
|
||||
#define USB_DESCR_TYP_HID 0x21
|
||||
#define USB_DESCR_TYP_REPORT 0x22
|
||||
#define USB_DESCR_TYP_PHYSIC 0x23
|
||||
#define USB_DESCR_TYP_CS_INTF 0x24
|
||||
#define USB_DESCR_TYP_CS_ENDP 0x25
|
||||
#define USB_DESCR_TYP_HUB 0x29
|
||||
#endif
|
||||
|
||||
/* USB Device Class */
|
||||
#ifndef USB_DEV_CLASS_HUB
|
||||
#define USB_DEV_CLASS_RESERVED 0x00
|
||||
#define USB_DEV_CLASS_AUDIO 0x01
|
||||
#define USB_DEV_CLASS_COMMUNIC 0x02
|
||||
#define USB_DEV_CLASS_HID 0x03
|
||||
#define USB_DEV_CLASS_MONITOR 0x04
|
||||
#define USB_DEV_CLASS_PHYSIC_IF 0x05
|
||||
#define USB_DEV_CLASS_POWER 0x06
|
||||
#define USB_DEV_CLASS_PRINTER 0x07
|
||||
#define USB_DEV_CLASS_STORAGE 0x08
|
||||
#define USB_DEV_CLASS_HUB 0x09
|
||||
#define USB_DEV_CLASS_VEN_SPEC 0xFF
|
||||
#endif
|
||||
|
||||
/* USB Hub Class Request */
|
||||
#ifndef HUB_GET_HUB_DESCRIPTOR
|
||||
#define HUB_CLEAR_HUB_FEATURE 0x20
|
||||
#define HUB_CLEAR_PORT_FEATURE 0x23
|
||||
#define HUB_GET_BUS_STATE 0xA3
|
||||
#define HUB_GET_HUB_DESCRIPTOR 0xA0
|
||||
#define HUB_GET_HUB_STATUS 0xA0
|
||||
#define HUB_GET_PORT_STATUS 0xA3
|
||||
#define HUB_SET_HUB_DESCRIPTOR 0x20
|
||||
#define HUB_SET_HUB_FEATURE 0x20
|
||||
#define HUB_SET_PORT_FEATURE 0x23
|
||||
#endif
|
||||
|
||||
/* Hub Class Feature Selectors */
|
||||
#ifndef HUB_PORT_RESET
|
||||
#define HUB_C_HUB_LOCAL_POWER 0
|
||||
#define HUB_C_HUB_OVER_CURRENT 1
|
||||
#define HUB_PORT_CONNECTION 0
|
||||
#define HUB_PORT_ENABLE 1
|
||||
#define HUB_PORT_SUSPEND 2
|
||||
#define HUB_PORT_OVER_CURRENT 3
|
||||
#define HUB_PORT_RESET 4
|
||||
#define HUB_PORT_POWER 8
|
||||
#define HUB_PORT_LOW_SPEED 9
|
||||
#define HUB_C_PORT_CONNECTION 16
|
||||
#define HUB_C_PORT_ENABLE 17
|
||||
#define HUB_C_PORT_SUSPEND 18
|
||||
#define HUB_C_PORT_OVER_CURRENT 19
|
||||
#define HUB_C_PORT_RESET 20
|
||||
#endif
|
||||
|
||||
/* USB HID Class Request Code */
|
||||
#ifndef HID_GET_REPORT
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
#define HID_GET_PROTOCOL 0x03
|
||||
#define HID_SET_REPORT 0x09
|
||||
#define HID_SET_IDLE 0x0A
|
||||
#define HID_SET_PROTOCOL 0x0B
|
||||
#endif
|
||||
|
||||
/* USB UDisk */
|
||||
#ifndef USB_BO_CBW_SIZE
|
||||
#define USB_BO_CBW_SIZE 0x1F
|
||||
#define USB_BO_CSW_SIZE 0x0D
|
||||
#endif
|
||||
#ifndef USB_BO_CBW_SIG0
|
||||
#define USB_BO_CBW_SIG0 0x55
|
||||
#define USB_BO_CBW_SIG1 0x53
|
||||
#define USB_BO_CBW_SIG2 0x42
|
||||
#define USB_BO_CBW_SIG3 0x43
|
||||
#define USB_BO_CSW_SIG0 0x55
|
||||
#define USB_BO_CSW_SIG1 0x53
|
||||
#define USB_BO_CSW_SIG2 0x42
|
||||
#define USB_BO_CSW_SIG3 0x53
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* USBFS Related Register Macro Definition */
|
||||
|
||||
/* R8_USB_CTRL */
|
||||
#define USBFS_UC_HOST_MODE 0x80
|
||||
#define USBFS_UC_LOW_SPEED 0x40
|
||||
#define USBFS_UC_DEV_PU_EN 0x20
|
||||
#define USBFS_UC_SYS_CTRL_MASK 0x30
|
||||
#define USBFS_UC_SYS_CTRL0 0x00
|
||||
#define USBFS_UC_SYS_CTRL1 0x10
|
||||
#define USBFS_UC_SYS_CTRL2 0x20
|
||||
#define USBFS_UC_SYS_CTRL3 0x30
|
||||
#define USBFS_UC_INT_BUSY 0x08
|
||||
#define USBFS_UC_RESET_SIE 0x04
|
||||
#define USBFS_UC_CLR_ALL 0x02
|
||||
#define USBFS_UC_DMA_EN 0x01
|
||||
|
||||
/* R8_USB_INT_EN */
|
||||
#define USBFS_UIE_DEV_SOF 0x80
|
||||
#define USBFS_UIE_DEV_NAK 0x40
|
||||
#define USBFS_UIE_FIFO_OV 0x10
|
||||
#define USBFS_UIE_HST_SOF 0x08
|
||||
#define USBFS_UIE_SUSPEND 0x04
|
||||
#define USBFS_UIE_TRANSFER 0x02
|
||||
#define USBFS_UIE_DETECT 0x01
|
||||
#define USBFS_UIE_BUS_RST 0x01
|
||||
|
||||
/* R8_USB_DEV_AD */
|
||||
#define USBFS_UDA_GP_BIT 0x80
|
||||
#define USBFS_USB_ADDR_MASK 0x7F
|
||||
|
||||
/* R8_USB_MIS_ST */
|
||||
#define USBFS_UMS_SOF_PRES 0x80
|
||||
#define USBFS_UMS_SOF_ACT 0x40
|
||||
#define USBFS_UMS_SIE_FREE 0x20
|
||||
#define USBFS_UMS_R_FIFO_RDY 0x10
|
||||
#define USBFS_UMS_BUS_RESET 0x08
|
||||
#define USBFS_UMS_SUSPEND 0x04
|
||||
#define USBFS_UMS_DM_LEVEL 0x02
|
||||
#define USBFS_UMS_DEV_ATTACH 0x01
|
||||
|
||||
/* R8_USB_INT_FG */
|
||||
#define USBFS_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
|
||||
#define USBFS_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBFS_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
|
||||
|
||||
/* R8_USB_INT_ST */
|
||||
#define USBFS_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
|
||||
#define USBFS_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
|
||||
#define USBFS_UIS_TOKEN_OUT 0x00
|
||||
#define USBFS_UIS_TOKEN_SOF 0x10
|
||||
#define USBFS_UIS_TOKEN_IN 0x20
|
||||
#define USBFS_UIS_TOKEN_SETUP 0x30
|
||||
// bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received for USB device mode
|
||||
// 00: OUT token PID received
|
||||
// 01: SOF token PID received
|
||||
// 10: IN token PID received
|
||||
// 11: SETUP token PID received
|
||||
#define USBFS_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
|
||||
#define USBFS_UIS_H_RES_MASK 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
|
||||
|
||||
/* R32_USB_OTG_CR */
|
||||
#define USBFS_CR_SESS_VTH 0x20
|
||||
#define USBFS_CR_VBUS_VTH 0x10
|
||||
#define USBFS_CR_OTG_EN 0x08
|
||||
#define USBFS_CR_IDPU 0x04
|
||||
#define USBFS_CR_CHARGE_VBUS 0x02
|
||||
#define USBFS_CR_DISCHAR_VBUS 0x01
|
||||
|
||||
/* R32_USB_OTG_SR */
|
||||
#define USBFS_SR_ID_DIG 0x08
|
||||
#define USBFS_SR_SESS_END 0x04
|
||||
#define USBFS_SR_SESS_VLD 0x02
|
||||
#define USBFS_SR_VBUS_VLD 0x01
|
||||
|
||||
/* R8_UDEV_CTRL */
|
||||
#define USBFS_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UD_GP_BIT 0x02 // general purpose bit
|
||||
#define USBFS_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
|
||||
|
||||
/* R8_UEP4_1_MOD */
|
||||
#define USBFS_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
|
||||
#define USBFS_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
|
||||
#define USBFS_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
|
||||
// bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
|
||||
// 0 0 x: disable endpoint and disable buffer
|
||||
// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
|
||||
// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
|
||||
// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
|
||||
// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
|
||||
#define USBFS_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
|
||||
#define USBFS_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
|
||||
// bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
|
||||
// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
|
||||
// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
|
||||
// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
|
||||
#define USBFS_UEP4_BUF_MOD 0x01
|
||||
|
||||
/* R8_UEP2_3_MOD */
|
||||
#define USBFS_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
|
||||
#define USBFS_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
|
||||
#define USBFS_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
|
||||
#define USBFS_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
|
||||
#define USBFS_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
|
||||
#define USBFS_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
|
||||
|
||||
/* R8_UEP5_6_MOD */
|
||||
#define USBFS_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
|
||||
#define USBFS_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
|
||||
#define USBFS_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
|
||||
#define USBFS_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
|
||||
#define USBFS_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
|
||||
#define USBFS_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
|
||||
|
||||
/* R8_UEP7_MOD */
|
||||
#define USBFS_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
|
||||
#define USBFS_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
|
||||
#define USBFS_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
|
||||
|
||||
/* R8_UEPn_TX_CTRL */
|
||||
#define USBFS_UEP_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
|
||||
#define USBFS_UEP_T_RES_ACK 0x00
|
||||
#define USBFS_UEP_T_RES_NONE 0x01
|
||||
#define USBFS_UEP_T_RES_NAK 0x02
|
||||
#define USBFS_UEP_T_RES_STALL 0x03
|
||||
// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
|
||||
// 00: DATA0 or DATA1 then expecting ACK (ready)
|
||||
// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: STALL (error)
|
||||
// host aux setup
|
||||
|
||||
/* R8_UEPn_RX_CTRL, n=0-7 */
|
||||
#define USBFS_UEP_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
|
||||
#define USBFS_UEP_R_RES_ACK 0x00
|
||||
#define USBFS_UEP_R_RES_NONE 0x01
|
||||
#define USBFS_UEP_R_RES_NAK 0x02
|
||||
#define USBFS_UEP_R_RES_STALL 0x03
|
||||
// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
|
||||
// 00: ACK (ready)
|
||||
// 01: no response, time out to host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: STALL (error)
|
||||
|
||||
/* R8_UHOST_CTRL */
|
||||
#define USBFS_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
|
||||
#define USBFS_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
|
||||
|
||||
/* R32_UH_EP_MOD */
|
||||
#define USBFS_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
|
||||
#define USBFS_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
|
||||
// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
|
||||
// 0 x: disable endpoint and disable buffer
|
||||
// 1 0: 64 bytes buffer for transmittal (OUT endpoint)
|
||||
// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
|
||||
#define USBFS_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
|
||||
#define USBFS_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
|
||||
// bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
|
||||
// 0 x: disable endpoint and disable buffer
|
||||
// 1 0: 64 bytes buffer for receiving (IN endpoint)
|
||||
// 1 1: dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
|
||||
|
||||
/* R16_UH_SETUP */
|
||||
#define USBFS_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub
|
||||
#define USBFS_UH_SOF_EN 0x0004 // USB host automatic SOF enable
|
||||
|
||||
/* R8_UH_EP_PID */
|
||||
#define USBFS_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer
|
||||
#define USBFS_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer
|
||||
|
||||
/* R8_UH_RX_CTRL */
|
||||
#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
|
||||
|
||||
/* R8_UH_TX_CTRL */
|
||||
#define USBFS_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Struct Definition */
|
||||
|
||||
/* USB Setup Request */
|
||||
typedef struct __attribute__((packed)) _USB_SETUP_REQ
|
||||
{
|
||||
uint8_t bRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} USB_SETUP_REQ, *PUSB_SETUP_REQ;
|
||||
|
||||
/* USB Device Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_DEVICE_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} USB_DEV_DESCR, *PUSB_DEV_DESCR;
|
||||
|
||||
/* USB Configuration Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_CONFIG_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t MaxPower;
|
||||
} USB_CFG_DESCR, *PUSB_CFG_DESCR;
|
||||
|
||||
/* USB Interface Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_INTERF_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} USB_ITF_DESCR, *PUSB_ITF_DESCR;
|
||||
|
||||
/* USB Endpoint Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_ENDPOINT_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wMaxPacketSizeL;
|
||||
uint8_t wMaxPacketSizeH;
|
||||
uint8_t bInterval;
|
||||
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
|
||||
|
||||
/* USB Configuration Descriptor Set */
|
||||
typedef struct __attribute__((packed)) _USB_CONFIG_DESCR_LONG
|
||||
{
|
||||
USB_CFG_DESCR cfg_descr;
|
||||
USB_ITF_DESCR itf_descr;
|
||||
USB_ENDP_DESCR endp_descr[ 1 ];
|
||||
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
|
||||
|
||||
/* USB HUB Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_HUB_DESCR
|
||||
{
|
||||
uint8_t bDescLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bNbrPorts;
|
||||
uint8_t wHubCharacteristicsL;
|
||||
uint8_t wHubCharacteristicsH;
|
||||
uint8_t bPwrOn2PwrGood;
|
||||
uint8_t bHubContrCurrent;
|
||||
uint8_t DeviceRemovable;
|
||||
uint8_t PortPwrCtrlMask;
|
||||
} USB_HUB_DESCR, *PUSB_HUB_DESCR;
|
||||
|
||||
/* USB HID Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_HID_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bDescriptorTypeX;
|
||||
uint8_t wDescriptorLengthL;
|
||||
uint8_t wDescriptorLengthH;
|
||||
} USB_HID_DESCR, *PUSB_HID_DESCR;
|
||||
|
||||
/* USB UDisk */
|
||||
typedef struct __attribute__((packed)) _UDISK_BOC_CBW
|
||||
{
|
||||
uint32_t mCBW_Sig;
|
||||
uint32_t mCBW_Tag;
|
||||
uint32_t mCBW_DataLen;
|
||||
uint8_t mCBW_Flag;
|
||||
uint8_t mCBW_LUN;
|
||||
uint8_t mCBW_CB_Len;
|
||||
uint8_t mCBW_CB_Buf[ 16 ];
|
||||
} UDISK_BOC_CBW, *PXUDISK_BOC_CBW;
|
||||
|
||||
/* USB UDisk */
|
||||
typedef struct __attribute__((packed)) _UDISK_BOC_CSW
|
||||
{
|
||||
uint32_t mCBW_Sig;
|
||||
uint32_t mCBW_Tag;
|
||||
uint32_t mCSW_Residue;
|
||||
uint8_t mCSW_Status;
|
||||
} UDISK_BOC_CSW, *PXUDISK_BOC_CSW;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CH32V20x_USB_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Main program body.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
*@Note
|
||||
1,Exam 1 :
|
||||
USBFS host controller enumeration routines for byte manipulation of USB flash drives,
|
||||
including file creation, modification, reading and deletion.
|
||||
2,Exam 6 :
|
||||
USBFS host controller enumeration routines for sector manipulation of USB flash drives,
|
||||
including file creation, modification, reading and deletion
|
||||
3,Exam 9 :
|
||||
The USBFS host controller enumerates the USB flash drive to create folders on the drive,
|
||||
including the primary and secondary directories, and the demo files in the corresponding directories.
|
||||
4,Exam 11 :
|
||||
USBFS host controller enumerates USB flash drives, enabling the enumeration of
|
||||
the first 1000 files on the drive.
|
||||
5,Exam 13 :USBFS host controller enumerates USB drives to create long filename files,
|
||||
or to get long filename files.
|
||||
Important: Only FAT12/FAT16/FAT32 formats are supported:
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "Udisk_Operation.h"
|
||||
|
||||
/* Switches for code demonstration, 1:Enable 0:Disable */
|
||||
#define DEF_TEST_FUNC_NUM DEF_TEST_FUNC_1
|
||||
#define DEF_TEST_FUNC_1 1 /* Test 1 , Operation for Open/Read/Modify/Delete a file by bytes */
|
||||
#define DEF_TEST_FUNC_6 6 /* Test 6 , Operation for Open/Read/Modify/Delete a file by sectors */
|
||||
#define DEF_TEST_FUNC_9 9 /* Test 9 , Operation for creating folders */
|
||||
#define DEF_TEST_FUNC_11 11 /* Test 11 , Operation for enumeration of the first 1000 files */
|
||||
#define DEF_TEST_FUNC_13 13 /* Test 13 , Operation for creating long filename files */
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
USART_Printf_Init( 115200 );
|
||||
Delay_Init( );
|
||||
printf( "SystemClk:%d\r\n", SystemCoreClock );
|
||||
printf( "USBFS HOST Test EXAM %d\r\n", DEF_TEST_FUNC_NUM );
|
||||
|
||||
/* General USB Host UDisk Operation Initialization */
|
||||
Udisk_USBH_Initialization( );
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if DEF_TEST_FUNC_NUM == DEF_TEST_FUNC_1
|
||||
UDisk_USBH_ByteOperation( );
|
||||
#elif DEF_TEST_FUNC_NUM == DEF_TEST_FUNC_6
|
||||
UDisk_USBH_SectorOperation( );
|
||||
#elif DEF_TEST_FUNC_NUM == DEF_TEST_FUNC_9
|
||||
UDisk_USBH_CreatDirectory( );
|
||||
#elif DEF_TEST_FUNC_NUM == DEF_TEST_FUNC_11
|
||||
UDisk_USBH_EnumFiles( );
|
||||
#elif DEF_TEST_FUNC_NUM == DEF_TEST_FUNC_13
|
||||
UDisk_USBH_Longname( );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,986 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
//#define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( void );
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user