commit
da43152a7e
3380 changed files with 1128754 additions and 0 deletions
File diff suppressed because it is too large
@ -0,0 +1,230 @@ |
|||||
|
<?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.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094"> |
||||
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" moduleId="org.eclipse.cdt.core.settings" name="Debug"> |
||||
|
<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="rtthread" 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.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug"> |
||||
|
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094." name="/" resourcePath=""> |
||||
|
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1201710416" name="ARM Cross GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.251260409" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1365878149" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting" useByScannerDiscovery="false" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.709136944" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1986446770" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1312975261" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1538128212" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.2136804218" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.244767666" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1055848773" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.default" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.501941135" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.dwarf2" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1696308067" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1558403188" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.749415257" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m7" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.2114153533" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1600865811" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1109963929" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1040883831" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1678200391" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1171840296" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.342604837" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.898269225" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.2016398076" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.1606171496" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.540792084" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="1287942917" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.430121817" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.none" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.966735324" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1381561249" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.target.other.2041717463" name="Other target flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.target.other" useByScannerDiscovery="true" value="" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.1463655269" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv5spd16" valueType="enumerated" /> |
||||
|
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1798638225" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform" /> |
||||
|
<builder buildPath="${workspace_loc:/qemu-vexpress-a9}/Debug" cleanBuildTarget="clean2" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1736709688" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder" /> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1810966071" name="GNU ARM Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1072524326" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.161242639" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}"" /> |
||||
|
</option> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.1521934876" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" useByScannerDiscovery="true" /> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags.1325367962" name="Assembler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags" useByScannerDiscovery="false" valueType="stringList"> |
||||
|
<listOptionValue builtIn="false" value="-mimplicit-it=thumb" /> |
||||
|
</option> |
||||
|
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1843333483" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input" /> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559" name="GNU ARM Cross C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler"> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.634882052" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include//config}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include//usb}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//CMSIS}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//CMSIS//GD//GD32H75E//Include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//GD32H75E_standard_peripheral//Include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/.}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/applications}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//.}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/phy}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/smp_call}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/finsh}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/epoll}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/eventfd}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/poll}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/ipc}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/net/utest}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/libcpu/arm/common}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/libcpu/arm/cortex-m7}"" /> |
||||
|
</option> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.100549972" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols"> |
||||
|
<listOptionValue builtIn="false" value="SOC_FAMILY_GD32" /> |
||||
|
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H7" /> |
||||
|
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H75E" /> |
||||
|
<listOptionValue builtIn="false" value="GD32H75E" /> |
||||
|
</option> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other.2133065240" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other" useByScannerDiscovery="true" value="" valueType="string" /> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files.714348818" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/rtconfig_preinc.h}"" /> |
||||
|
</option> |
||||
|
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input" /> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.869072473" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.1167322178" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.351692886" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs.1009243715" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs.2016026082" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.923990336" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option defaultValue="true" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared.548869459" name="Shared (-shared)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared" useByScannerDiscovery="false" valueType="boolean" /> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.1818777301" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//linkscripts//GD32H75EYM//link.ld}"" /> |
||||
|
</option> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.1135656995" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" useByScannerDiscovery="false"> |
||||
|
<listOptionValue builtIn="false" value="c " /> |
||||
|
<listOptionValue builtIn="false" value="m " /> |
||||
|
</option> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths.36884122" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths" useByScannerDiscovery="false" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.396049466" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" useByScannerDiscovery="false" value="" valueType="string" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref.1645737861" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.334732222" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input"> |
||||
|
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)" /> |
||||
|
<additionalInput kind="additionalinput" paths="$(LIBS)" /> |
||||
|
</inputType> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1601059928" name="GNU ARM Cross C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.437759352" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean" /> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.1101974459" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//linkscripts//GD32H75EYM//link.ld}"" /> |
||||
|
</option> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.2007675975" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.2105838438" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs.934137837" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs" useByScannerDiscovery="false" valueType="libs" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart.2118356996" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs.1427884346" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs.1433863653" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections.1387745410" name="Print removed sections (-Xlinker --print-gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip.1230158061" name="Omit all symbol information (-s)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap.1307581821" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat.960778920" name="Use float with nano printf (-u _printf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat.637205035" name="Use float with nano scanf (-u _scanf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys.1948314201" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose.273162112" name="Verbose (-v)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose" useByScannerDiscovery="false" value="false" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths.1399535143" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths" useByScannerDiscovery="false" valueType="libPaths" /> |
||||
|
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.262373798" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input"> |
||||
|
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)" /> |
||||
|
<additionalInput kind="additionalinput" paths="$(LIBS)" /> |
||||
|
</inputType> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.506412204" name="GNU ARM Cross Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver" /> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.1461589245" name="GNU ARM Cross Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.1937707052" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary" valueType="enumerated" /> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.82359725" name="GNU ARM Cross Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.601724476" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.692505279" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.97345172" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.1342893377" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean" /> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.1533725981" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean" /> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.1073550295" name="GNU ARM Cross Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize"> |
||||
|
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.946451386" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format" useByScannerDiscovery="false" /> |
||||
|
</tool> |
||||
|
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1302177015" name="GNU ARM Cross C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.704468062" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols"> |
||||
|
<listOptionValue builtIn="false" value="SOC_FAMILY_GD32" /> |
||||
|
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H7" /> |
||||
|
<listOptionValue builtIn="false" value="SOC_SERIES_GD32H75E" /> |
||||
|
<listOptionValue builtIn="false" value="GD32H75E" /> |
||||
|
</option> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.302877723" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include//config}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/drivers//include//usb}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//CMSIS}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//CMSIS//GD//GD32H75E//Include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/libraries//GD32H75E_standard_peripheral//Include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/.}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}/applications}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//.}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/phy}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/drivers/smp_call}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/finsh}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/epoll}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/eventfd}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/io/poll}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/libc/posix/ipc}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/net/utest}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/include}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/libcpu/arm/common}"" /> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/libcpu/arm/cortex-m7}"" /> |
||||
|
</option> |
||||
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files.343249373" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles"> |
||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/rtconfig_preinc.h}"" /> |
||||
|
</option> |
||||
|
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.45918001" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input" /> |
||||
|
</tool> |
||||
|
</toolChain> |
||||
|
</folderInfo> |
||||
|
<sourceEntries> |
||||
|
<entry excluding="//rt-thread/components/dfs|//rt-thread/components/drivers/ata|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/block|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/bus.c|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/mnt.c|//rt-thread/components/drivers/core/numa.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/core/power_domain.c|//rt-thread/components/drivers/core/utest|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/dma|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/iio|//rt-thread/components/drivers/ipc/completion_mp.c|//rt-thread/components/drivers/ipc/utest|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/led|//rt-thread/components/drivers/mailbox|//rt-thread/components/drivers/mfd|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd|//rt-thread/components/drivers/nvme|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/pci|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/phye|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/dev_pin_dm.c|//rt-thread/components/drivers/pin/dev_pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/regulator|//rt-thread/components/drivers/reset|//rt-thread/components/drivers/rtc|//rt-thread/components/drivers/scsi|//rt-thread/components/drivers/sdio|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/bypass.c|//rt-thread/components/drivers/serial/dev_serial_v2.c|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/utest|//rt-thread/components/drivers/smp_call|//rt-thread/components/drivers/spi|//rt-thread/components/drivers/thermal|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/watchdog|//rt-thread/components/drivers/wlan|//rt-thread/components/fal|//rt-thread/components/finsh/msh_file.c|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/examples|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu_mp.c|//rt-thread/src/klibc/rt_vsnprintf_std.c|//rt-thread/src/klibc/utest|//rt-thread/src/memheap.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/signal.c|//rt-thread/src/slab.c|//rt-thread/src/utest|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" /> |
||||
|
</sourceEntries> |
||||
|
</configuration> |
||||
|
</storageModule> |
||||
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings" /> |
||||
|
</cconfiguration> |
||||
|
</storageModule> |
||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> |
||||
|
<project id="qemu-vexpress-a9.ilg.gnuarmeclipse.managedbuild.cross.target.elf.860020518" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf" /> |
||||
|
</storageModule> |
||||
|
<storageModule moduleId="scannerConfiguration"> |
||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="" /> |
||||
|
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094;ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063"> |
||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="" /> |
||||
|
</scannerConfigBuildInfo> |
||||
|
</storageModule> |
||||
|
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders" /> |
||||
|
<storageModule moduleId="refreshScope" versionNumber="2"> |
||||
|
<configuration configurationName="Debug"> |
||||
|
<resource resourceType="PROJECT" workspacePath="/project" /> |
||||
|
</configuration> |
||||
|
</storageModule> |
||||
|
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets" /> |
||||
|
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"> |
||||
|
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen"> |
||||
|
<path value="" /> |
||||
|
</doc-comment-owner> |
||||
|
</storageModule> |
||||
|
</cproject> |
||||
@ -0,0 +1,36 @@ |
|||||
|
# Sources |
||||
|
*.c text diff=c |
||||
|
*.cc text diff=cpp |
||||
|
*.cxx text diff=cpp |
||||
|
*.cpp text diff=cpp |
||||
|
*.c++ text diff=cpp |
||||
|
*.hpp text diff=cpp |
||||
|
*.h text diff=c |
||||
|
*.h++ text diff=cpp |
||||
|
*.hh text diff=cpp |
||||
|
|
||||
|
# Compiled Object files |
||||
|
*.slo binary |
||||
|
*.lo binary |
||||
|
*.o binary |
||||
|
*.obj binary |
||||
|
|
||||
|
# Precompiled Headers |
||||
|
*.gch binary |
||||
|
*.pch binary |
||||
|
|
||||
|
# Compiled Dynamic libraries |
||||
|
*.so binary |
||||
|
*.dylib binary |
||||
|
*.dll binary |
||||
|
|
||||
|
# Compiled Static libraries |
||||
|
*.lai binary |
||||
|
*.la binary |
||||
|
*.a binary |
||||
|
*.lib binary |
||||
|
|
||||
|
# Executables |
||||
|
*.exe binary |
||||
|
*.out binary |
||||
|
*.app binary |
||||
@ -0,0 +1,37 @@ |
|||||
|
*.pyc |
||||
|
*.map |
||||
|
*.dblite |
||||
|
*.elf |
||||
|
*.bin |
||||
|
*.hex |
||||
|
*.axf |
||||
|
*.pdb |
||||
|
*.idb |
||||
|
*.ilk |
||||
|
*.old |
||||
|
build |
||||
|
Debug |
||||
|
*~ |
||||
|
*.o |
||||
|
*.obj |
||||
|
*.out |
||||
|
*.bak |
||||
|
*.dep |
||||
|
*.lib |
||||
|
*.i |
||||
|
*.d |
||||
|
.DS_Stor* |
||||
|
.config 3 |
||||
|
.config 4 |
||||
|
.config 5 |
||||
|
*.uimg |
||||
|
GPATH |
||||
|
GRTAGS |
||||
|
GTAGS |
||||
|
.vscode |
||||
|
JLinkLog.txt |
||||
|
JLinkSettings.ini |
||||
|
DebugConfig/ |
||||
|
RTE/ |
||||
|
settings/ |
||||
|
*.uvguix* |
||||
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<projectDescription> |
||||
|
<name>828ECO</name> |
||||
|
<comment></comment> |
||||
|
<projects> |
||||
|
</projects> |
||||
|
<buildSpec> |
||||
|
<buildCommand> |
||||
|
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> |
||||
|
<triggers>clean,full,incremental,</triggers> |
||||
|
<arguments> |
||||
|
</arguments> |
||||
|
</buildCommand> |
||||
|
<buildCommand> |
||||
|
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> |
||||
|
<triggers>full,incremental,</triggers> |
||||
|
<arguments> |
||||
|
</arguments> |
||||
|
</buildCommand> |
||||
|
</buildSpec> |
||||
|
<natures> |
||||
|
<nature>org.eclipse.cdt.core.cnature</nature> |
||||
|
<nature>org.rt-thread.studio.rttnature</nature> |
||||
|
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> |
||||
|
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> |
||||
|
</natures> |
||||
|
</projectDescription> |
||||
Binary file not shown.
@ -0,0 +1,63 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.pyocd.launchConfigurationType"> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.adapterName" value="DAP-LINK"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.binFlashStartAddress" value=""/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doContinue" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doDebugInRam" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doFirstReset" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doGdbServerAllocateConsole" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doSecondReset" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.doStartGdbServer" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.enableSemihosting" value="true"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.firstResetType" value="init"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbClientOtherOptions" value=""/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerBusSpeed" value="1000000"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerConnectionAddress" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerDeviceName" value="GD32H75EYMJ7"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerEnableSemihosting" value="false"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerExecutable" value="${debugger_install_path}/${daplink_debugger_relative_path}\pyocd.exe"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerFlashMode" value="0"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerGdbPortNumber" value="3333"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerOther" value=""/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.gdbServerTelnetPortNumber" value="4444"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.otherInitCommands" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.otherRunCommands" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.programMode" value="BIN"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.pyocd.secondResetType" value="halt"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU PyOCD"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="false"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/> |
||||
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
||||
|
<listEntry value="/828ECO"/> |
||||
|
</listAttribute> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
||||
|
<listEntry value="4"/> |
||||
|
</listAttribute> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/> |
||||
|
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/> |
||||
|
</launchConfiguration> |
||||
@ -0,0 +1,91 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.jlink.launchConfigurationType"> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.adapterName" value="J-Link"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.binFileStartAddress" value=""/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doConnectToRunning" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doContinue" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doDebugInRam" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doFirstReset" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerAllocateConsole" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerAllocateSemihostingConsole" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerInitRegs" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerLocalOnly" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerSilent" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doGdbServerVerifyDownload" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doSecondReset" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.doStartGdbServer" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableFlashBreakpoints" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihosting" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihostingIoclientGdbClient" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSemihostingIoclientTelnet" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.enableSwo" value="true"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseEndAddress" value=""/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseMode" value="0"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.eraseStartAddress" value=""/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.firstResetSpeed" value="1000"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.firstResetType" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.flashDeviceName" value="GD32H75EYMJ7"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.flashDownloadHex" value="false"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbClientOtherOptions" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerConnection" value="usb"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerConnectionAddress" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDebugInterface" value="swd"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceEndianness" value="little"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceName" value="GD32H75EYMJ7"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerDeviceSpeed" value="1000"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerExecutable" value="${debugger_install_path}/${jlink_debugger_relative_path}\JLinkGDBServerCL.exe"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerGdbPortNumber" value="2331"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerLog" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerOther" value="-singlerun"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerRunAfterStopDebug" value="true"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerSwoPortNumber" value="2332"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.gdbServerTelnetPortNumber" value="2333"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.interfaceSpeed" value="auto"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.jlinkExecutable" value="${debugger_install_path}/${jlink_debugger_relative_path}\JLink.exe"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.otherInitCommands" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.otherRunCommands" value=""/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.runAfterDownload" value="true"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.secondResetType" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.serailBaudRate" value="115200"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.serailPort" value=""/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetCpuFreq" value="0"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetPortMask" value="0x1"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.jlink.swoEnableTargetSwoFreq" value="0"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU J-Link"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> |
||||
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="2331"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/> |
||||
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
||||
|
<listEntry value="/828ECO"/> |
||||
|
</listAttribute> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
||||
|
<listEntry value="4"/> |
||||
|
</listAttribute> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/> |
||||
|
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/> |
||||
|
</launchConfiguration> |
||||
@ -0,0 +1,58 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.qemu.launchConfigurationType"> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doContinue" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doDebugInRam" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doFirstReset" value="false"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doSecondReset" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.doStartGdbServer" value="true"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.enableSemihosting" value="true"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbClientOtherCommands" value="set mem inaccessible-by-default off "/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbClientOtherOptions" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerBoardModel" value="?"/> |
||||
|
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerCpuQuantity" value="1"/> |
||||
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerEnableNetwork" value="false"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerExecutable" value="${debugger_install_path}/${qemu_debugger_relative_path}\qemu-system-arm.exe"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerExtraQemuCmd" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerSdcardMemory" value="64.0"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerSerialPort" value="COM1"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerStartup" value="${studio_install_path}/repo/Extract/Debugger_Support_Packages/RealThread/QEMU/4.2.0.4/qemu-system-arm.exe -M ? -sd sd.bin -nographic -S -s"/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.gdbServerTapName" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.otherInitCommands" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.qemu.otherRunCommands" value=""/> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU QEMU"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> |
||||
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="1234"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/> |
||||
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
||||
|
<listEntry value="/828ECO"/> |
||||
|
</listAttribute> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
||||
|
<listEntry value="4"/> |
||||
|
</listAttribute> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/> |
||||
|
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/> |
||||
|
</launchConfiguration> |
||||
@ -0,0 +1,57 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
<launchConfiguration type="org.rtthread.studio.debug.gdbjtag.stlink.launchConfigurationType"> |
||||
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${studio_install_path}\repo\Extract\Chip_Support_Packages\RealThread\GD32H7\2.0.0\debug/svd/GD32H75E.svd"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.connectMode" value="NORMAL"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.debugInterface" value="SWD"/> |
||||
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="3"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.flashVerify" value="false"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.genericDevice"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.otherDownloadOption" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.otherGdbserverOption" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/> |
||||
|
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="61235"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.resetMode" value=" -hardRst"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.resetRun" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/> |
||||
|
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${rtt_gnu_gcc}/arm-none-eabi-gdb.exe"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/> |
||||
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/rtthread.elf"/> |
||||
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="828ECO"/> |
||||
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
||||
|
<listEntry value="/828ECO"/> |
||||
|
</listAttribute> |
||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
||||
|
<listEntry value="4"/> |
||||
|
</listAttribute> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.cdt.debug.core.sourceLocator"/> |
||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/> |
||||
|
<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="true"/> |
||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="true"/> |
||||
|
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.adapterName" value="ST-LINK"/> |
||||
|
<booleanAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.doContinue" value="true"/> |
||||
|
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.gdbServerDeviceName" value="GD32H75EYMJ7"/> |
||||
|
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.gdbServerExecutable" value="${debugger_install_path}/${stlink_debugger_relative_path}/ST-LINK_gdbserver.exe"/> |
||||
|
<stringAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.stlinkGdbServer" value="${debugger_install_path}/${stlink_debugger_relative_path}/tools/bin/STM32_Programmer_CLI.exe"/> |
||||
|
<booleanAttribute key="org.rtthread.studio.stlink.debug.gdbjtag.useRemoteTarget" value="true"/> |
||||
|
</launchConfiguration> |
||||
@ -0,0 +1,2 @@ |
|||||
|
eclipse.preferences.version=1 |
||||
|
toolchain.path.1287942917=${toolchain_install_path}/ARM/GNU_Tools_for_ARM_Embedded_Processors/13.3/bin |
||||
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
<project> |
||||
|
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" name="Debug"> |
||||
|
<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="-1180059202540270600" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM 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/<project>=UTF-8 |
||||
@ -0,0 +1,3 @@ |
|||||
|
content-types/enabled=true |
||||
|
content-types/org.eclipse.cdt.core.asmSource/file-extensions=s |
||||
|
eclipse.preferences.version=1 |
||||
@ -0,0 +1,22 @@ |
|||||
|
#RT-Thread Studio Project Configuration |
||||
|
#Wed Feb 11 14:08:06 CST 2026 |
||||
|
project_type=rtt |
||||
|
chip_name=GD32H75EYMJ7 |
||||
|
cpu_name=None |
||||
|
target_freq=180 |
||||
|
clock_source=hsi |
||||
|
dvendor_name=GigaDevice |
||||
|
rx_pin_name=PA10 |
||||
|
rtt_path=repo/Extract/RT-Thread_Source_Code/RT-Thread/5.2.2 |
||||
|
source_freq=0 |
||||
|
csp_path=repo/Extract/Chip_Support_Packages/RealThread/GD32H7xx/2.0.0 |
||||
|
sub_series_name=GD32H75E |
||||
|
selected_rtt_version=5.2.2 |
||||
|
cfg_version=v3.0 |
||||
|
tool_chain=gcc |
||||
|
uart_name=uart1 |
||||
|
tx_pin_name=PA9 |
||||
|
rtt_nano_path= |
||||
|
output_project_path=C\:/RT-ThreadStudio/workspace |
||||
|
hardware_adapter=J-Link |
||||
|
project_name=828ECO |
||||
@ -0,0 +1,32 @@ |
|||||
|
mainmenu "RT-Thread Configuration" |
||||
|
|
||||
|
config BSP_DIR |
||||
|
string |
||||
|
option env="BSP_ROOT" |
||||
|
default "." |
||||
|
|
||||
|
config RTT_DIR |
||||
|
string |
||||
|
option env="RTT_ROOT" |
||||
|
default "rt-thread" |
||||
|
|
||||
|
config PKGS_DIR |
||||
|
string |
||||
|
option env="PKGS_ROOT" |
||||
|
default "packages" |
||||
|
|
||||
|
config PLATFORM_DIR |
||||
|
string |
||||
|
option env="PLATFORM_DIR" |
||||
|
default "C:/RT-ThreadStudio/workspace/828ECO/platform" |
||||
|
|
||||
|
source "$RTT_DIR/Kconfig" |
||||
|
source "$PKGS_DIR/Kconfig" |
||||
|
source "$PKGS_DIR/packages/misc/samples/Kconfig" |
||||
|
|
||||
|
config RT_STUDIO_BUILT_IN |
||||
|
bool |
||||
|
select ARCH_ARM_CORTEX_M7 |
||||
|
select RT_USING_COMPONENTS_INIT |
||||
|
select RT_USING_USER_MAIN |
||||
|
default y |
||||
@ -0,0 +1,15 @@ |
|||||
|
# for module compiling |
||||
|
import os |
||||
|
Import('RTT_ROOT') |
||||
|
from building import * |
||||
|
|
||||
|
cwd = GetCurrentDir() |
||||
|
objs = [] |
||||
|
list = os.listdir(cwd) |
||||
|
|
||||
|
for d in list: |
||||
|
path = os.path.join(cwd, d) |
||||
|
if os.path.isfile(os.path.join(path, 'SConscript')): |
||||
|
objs = objs + SConscript(os.path.join(d, 'SConscript')) |
||||
|
|
||||
|
Return('objs') |
||||
@ -0,0 +1,36 @@ |
|||||
|
import os |
||||
|
import sys |
||||
|
import rtconfig |
||||
|
|
||||
|
RTT_ROOT = os.path.normpath(os.getcwd() + '/rt-thread') |
||||
|
|
||||
|
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] |
||||
|
try: |
||||
|
from building import * |
||||
|
except Exception as e: |
||||
|
print("Error message:", e.message) |
||||
|
print('Cannot found RT-Thread root directory, please check RTT_ROOT') |
||||
|
print(RTT_ROOT) |
||||
|
sys.exit(-1) |
||||
|
|
||||
|
TARGET = 'rt-thread.elf' |
||||
|
|
||||
|
DefaultEnvironment(tools=[]) |
||||
|
env = Environment(tools = ['mingw'], |
||||
|
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, |
||||
|
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, |
||||
|
AR = rtconfig.AR, ARFLAGS = '-rc', |
||||
|
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, |
||||
|
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) |
||||
|
env.PrependENVPath('PATH', rtconfig.EXEC_PATH) |
||||
|
|
||||
|
env.AppendUnique(CPPDEFINES = []) |
||||
|
|
||||
|
Export('RTT_ROOT') |
||||
|
Export('rtconfig') |
||||
|
|
||||
|
# prepare building environment |
||||
|
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) |
||||
|
|
||||
|
# make a building |
||||
|
DoBuilding(TARGET, objs) |
||||
@ -0,0 +1,28 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2026, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2026-02-11 RT-Thread first version |
||||
|
*/ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
|
||||
|
#define DBG_TAG "main" |
||||
|
#define DBG_LVL DBG_LOG |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
int count = 1; |
||||
|
LOG_D("Hello RT-Thread!"); |
||||
|
|
||||
|
while (count++) |
||||
|
{ |
||||
|
rt_thread_mdelay(1000); |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2026, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2026-02-11 RealThread first version |
||||
|
*/ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
#include <drv_common.h> |
||||
|
|
||||
|
#ifndef RT_WEAK |
||||
|
#define RT_WEAK rt_weak |
||||
|
#endif |
||||
|
|
||||
|
RT_WEAK void rt_hw_board_init() |
||||
|
{ |
||||
|
/* Heap initialization */ |
||||
|
#if defined(RT_USING_HEAP) |
||||
|
rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END); |
||||
|
#endif |
||||
|
|
||||
|
extern void hw_board_init(); |
||||
|
hw_board_init(); |
||||
|
|
||||
|
/* Set the shell console output device */ |
||||
|
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) |
||||
|
rt_console_set_device(RT_CONSOLE_DEVICE_NAME); |
||||
|
#endif |
||||
|
|
||||
|
/* Board underlying hardware initialization */ |
||||
|
#ifdef RT_USING_COMPONENTS_INIT |
||||
|
rt_components_board_init(); |
||||
|
#endif |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,543 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2026, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2026-02-11 RealThread first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __BOARD_H__ |
||||
|
#define __BOARD_H__ |
||||
|
|
||||
|
#ifdef SOC_SERIES_GD32H75E |
||||
|
#include <gd32h75e.h> |
||||
|
#include "gd32h75e_exti.h" |
||||
|
#else |
||||
|
#include <gd32h7xx.h> |
||||
|
#include "gd32h7xx_exti.h" |
||||
|
#endif |
||||
|
#include <drv_gpio.h> |
||||
|
#include "drv_legacy.h" |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" |
||||
|
{ |
||||
|
#endif |
||||
|
|
||||
|
/*-------------------------- CHIP CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
#define CHIP_FAMILY_GD32 |
||||
|
#define CHIP_SERIES_GD32H7 |
||||
|
#define CHIP_NAME_GD32H75EYMJ7 |
||||
|
|
||||
|
/*-------------------------- CHIP CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- ROM/RAM CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
#define ROM_START ((uint32_t)0x8000000) |
||||
|
#define ROM_SIZE (3840 * 1024) |
||||
|
#define ROM_END ((uint32_t)(ROM_START + ROM_SIZE)) |
||||
|
|
||||
|
#define RAM_START (0x24000000) |
||||
|
#define RAM_SIZE (512 * 1024) |
||||
|
#define RAM_END (RAM_START + RAM_SIZE) |
||||
|
|
||||
|
/*-------------------------- ROM/RAM CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- UART CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** After configuring corresponding UART or UART DMA, you can use it.
|
||||
|
* |
||||
|
* STEP 1, define macro define related to the serial port opening based on the serial port number |
||||
|
* such as #define BSP_USING_UART1 |
||||
|
* |
||||
|
* STEP 2, according to the corresponding pin of serial port, define the related serial port information macro |
||||
|
* such as #define BSP_UART1_TX_PIN "PA9" |
||||
|
* #define BSP_UART1_RX_PIN "PA10" |
||||
|
* |
||||
|
* STEP 3, if you want using SERIAL DMA, you must open it in the RT-Thread Settings. |
||||
|
* RT-Thread Setting -> Components -> Device Drivers -> Serial Device Drivers -> Enable Serial DMA Mode |
||||
|
* |
||||
|
* STEP 4, according to serial port number to define serial port tx/rx DMA function in the board.h file |
||||
|
* such as #define BSP_UART1_RX_USING_DMA |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
#define BSP_USING_UART1 |
||||
|
#define BSP_UART1_TX_PIN "PA9" |
||||
|
#define BSP_UART1_RX_PIN "PA10" |
||||
|
|
||||
|
/*-------------------------- UART CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- I2C CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure I2C (hardware)
|
||||
|
* |
||||
|
* STEP 1, enable the I2C driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using I2C device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the I2C instance by defining the related macro, and prefer the |
||||
|
* default board-level settings provided in i2c_config.h. |
||||
|
* e.g. #define BSP_USING_I2C1 |
||||
|
* |
||||
|
* STEP 3, if you accept the default pins in i2c_config.h, you are done. No further |
||||
|
* pin configuration is required here. |
||||
|
* |
||||
|
* STEP 4, to override pins, set the port pins below for your MCU package according |
||||
|
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_I2C1_SCL_PIN "PH4" |
||||
|
* #define BSP_I2C1_SDA_PIN "PB11" |
||||
|
* |
||||
|
* STEP 5, to override alternate function (AF), set the AF macro below in this file |
||||
|
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_I2C1_AFIO "AF4" |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the I2C device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/i2c
|
||||
|
* - If using the default configuration in i2c_config.h, just add the device macro (e.g., BSP_USING_I2C1) in board.h. |
||||
|
* - To use custom pins, follow the definitions below. |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_I2C1 */ |
||||
|
/* #define BSP_I2C1_SCL_PIN "PH4" */ |
||||
|
/* #define BSP_I2C1_SDA_PIN "PB11" */ |
||||
|
/* #define BSP_I2C1_AFIO "AF4" */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- I2C CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- SPI CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure SPI (hardware)
|
||||
|
* |
||||
|
* STEP 1, enable the SPI driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using SPI Bus/Device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the SPI instance by defining the related macro, and prefer the |
||||
|
* default board-level settings provided in spi_config.h. |
||||
|
* e.g. #define BSP_USING_SPI1 |
||||
|
* |
||||
|
* STEP 3, if you accept the default pins in spi_config.h, you are done. No further |
||||
|
* pin configuration is required here. |
||||
|
* |
||||
|
* STEP 4, to override pins, set the port pins below for your MCU package according |
||||
|
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_SPI1_SCK_PIN "PB13" |
||||
|
* #define BSP_SPI1_MISO_PIN "PB14" |
||||
|
* #define BSP_SPI1_MOSI_PIN "PB15" |
||||
|
* |
||||
|
* STEP 5, to override alternate function (AF), set the AF macro below in this file |
||||
|
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_SPI1_AFIO "AF5" |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the SPI device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi
|
||||
|
* - If using the default configuration in spi_config.h, just add the device macro (e.g., BSP_USING_SPI1) in board.h. |
||||
|
* - To use custom pins, follow the definitions below. |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_SPI1 */ |
||||
|
/* #define BSP_SPI1_SCK_PIN "PB13" */ |
||||
|
/* #define BSP_SPI1_MISO_PIN "PB14" */ |
||||
|
/* #define BSP_SPI1_MOSI_PIN "PB15" */ |
||||
|
/* #define BSP_SPI1_AFIO "AF5" */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- SPI CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- PWM CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure PWM (hardware)
|
||||
|
* |
||||
|
* STEP 1, enable the PWM driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using PWM device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the PWM instance by defining the related macro, and prefer the |
||||
|
* default board-level settings provided in pwm_config.h. |
||||
|
* e.g. #define BSP_USING_PWM0 |
||||
|
* |
||||
|
* STEP 3, if you accept the default pins in pwm_config.h, you are done. No further |
||||
|
* pin configuration is required here. |
||||
|
* |
||||
|
* STEP 4, to override pins, set the port pins below for your MCU package according |
||||
|
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_PWM0_PIN "PC7" |
||||
|
* #define BSP_PWM0_CHANNEL 3 |
||||
|
* |
||||
|
* STEP 5, to override alternate function (AF), set the AF macro below in this file |
||||
|
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_PWM0_AFIO "AF1" |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the PWM device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/pwm/pwm
|
||||
|
* - If using the default configuration in pwm_config.h, just add the device macro (e.g., BSP_USING_PWM0) in board.h. |
||||
|
* - To use custom pins, follow the definitions below. |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- PWM Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_PWM0 */ |
||||
|
/* #define BSP_PWM0_PIN "PC7" */ |
||||
|
/* #define BSP_PWM0_CHANNEL 3 */ |
||||
|
/* #define BSP_PWM0_AFIO "AF1" */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- PWM CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- ADC CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure ADC
|
||||
|
* |
||||
|
* STEP 1, enable the ADC driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using ADC device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the ADC instance by defining the related macro. |
||||
|
* e.g. #define BSP_USING_ADC0 |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the ADC device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/adc/adc
|
||||
|
* - The ADC pins are defined in adc_config.h. |
||||
|
* - To view the corresponding pins and channels, refer to the GD32H759xx Datasheet. |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- ADC Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_ADC0 */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- ADC CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- DAC CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure DAC
|
||||
|
* |
||||
|
* STEP 1, enable the DAC driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using DAC device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the DAC instance by defining the related macro, and prefer the |
||||
|
* default board-level settings provided in dac_config.h. |
||||
|
* e.g. #define BSP_USING_DAC0 |
||||
|
* |
||||
|
* STEP 3, if you accept the default pins in dac_config.h, you are done. No further |
||||
|
* pin configuration is required here. |
||||
|
* |
||||
|
* STEP 4, to override pins, set the port pins below for your MCU package according |
||||
|
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_DAC0_PIN "PA4" |
||||
|
* #define BSP_DAC0_CHANNEL DAC_OUT0 |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the DAC device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/dac/dac
|
||||
|
* - If using the default configuration in dac_config.h, just add the device macro (e.g., BSP_USING_DAC0) in board.h. |
||||
|
* - To use custom pins, follow the definitions below. |
||||
|
*/ |
||||
|
|
||||
|
/*-----------------------DAC Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_DAC0 */ |
||||
|
/* #define BSP_DAC0_PIN "PA4" */ |
||||
|
/* #define BSP_DAC0_CHANNEL DAC_OUT0 */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- DAC CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- WDT CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure WDT
|
||||
|
* |
||||
|
* STEP 1, enable the WDT driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using Watchdog device drivers |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the WDT device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/watchdog/watchdog
|
||||
|
*/ |
||||
|
|
||||
|
/*-------------------------- WDT CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- HARDWARE TIMER CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** if you want to use hardware timer you can use the following instructions.
|
||||
|
* |
||||
|
* STEP 1, enable the hardware timer driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using hardware timer device drivers |
||||
|
* |
||||
|
* STEP 2, define macro related to the hwtimer |
||||
|
* such as #define BSP_USING_HWTIMER0 |
||||
|
* |
||||
|
* Notes: |
||||
|
* - The macro definitions and device names for the hardware timer are defined in drv_hwtimer.c. |
||||
|
* - For details on using the hardware timer device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/hwtimer/hwtimer
|
||||
|
*/ |
||||
|
|
||||
|
/*-----------------------HARDWARE TIMER configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_HWTIMER0 */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- HARDWARE TIMER CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- RTC CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure RTC
|
||||
|
* |
||||
|
* STEP 1, enable the RTC driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using RTC device drivers |
||||
|
* |
||||
|
* STEP 2, define macro related to the RTC |
||||
|
* such as #define BSP_USING_ALARM0 |
||||
|
* |
||||
|
* Notes: |
||||
|
* - The macro definitions and device names for the RTC are defined in drv_rtc.c. |
||||
|
* - For details on using the RTC device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/rtc/rtc
|
||||
|
*/ |
||||
|
|
||||
|
/*-----------------------RTC configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_ALARM0 */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- RTC CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- SDIO CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure SDIO
|
||||
|
* STEP 1, enable the SDIO driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using SD/EMMC device drivers |
||||
|
* STEP 2, enable the DFS driver in RT-Thread Settings. |
||||
|
* e.g. Components -> DFS -> Using DFS device drivers |
||||
|
* STEP 3, enable the elm-Fatfs driver in RT-Thread Settings. |
||||
|
* e.g. Components -> DFS -> Using elm-Fatfs device drivers |
||||
|
* |
||||
|
* Notes: |
||||
|
* - The SDIO pin configuration is implemented in the gpio_config() function |
||||
|
* located in drv_sdio.c. |
||||
|
* - Before using the SDIO interface, please consult the MCU datasheet and ensure |
||||
|
* that all related pins are configured according to the hardware requirements. |
||||
|
* - If custom pins are needed, update the configuration inside gpio_config() |
||||
|
* accordingly. |
||||
|
*/ |
||||
|
|
||||
|
/*-------------------------- SDIO CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- CAN CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure CAN
|
||||
|
* |
||||
|
* STEP 1, enable the CAN driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using CAN device drivers |
||||
|
* |
||||
|
* STEP 2, turn on the CAN instance by defining the related macro, and prefer the |
||||
|
* default board-level settings provided in can_config.h. |
||||
|
* e.g. #define BSP_USING_CAN0 |
||||
|
* |
||||
|
* STEP 3, if you accept the default pins in can_config.h, you are done. No further |
||||
|
* pin configuration is required here. |
||||
|
* |
||||
|
* STEP 4, to override pins, set the port pins below for your MCU package according |
||||
|
* to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_CAN0_RX_PIN "PD0" |
||||
|
* #define BSP_CAN0_TX_PIN "PD1" |
||||
|
* |
||||
|
* STEP 5, to override alternate function (AF), set the AF macro below in this file |
||||
|
* according to the datasheet (GD32H759xx Datasheet 2.6.3. GD32H759xx pin alternate functions): |
||||
|
* e.g. #define BSP_CAN0_AFIO "AF9" |
||||
|
* |
||||
|
* Notes: |
||||
|
* - For details on using the CAN device, refer to the documentation center at the following link: |
||||
|
* - https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/can/can
|
||||
|
* - If using the default configuration in can_config.h, just add the device macro (e.g., BSP_USING_CAN0) in board.h. |
||||
|
* - To use custom pins, follow the definitions below. |
||||
|
*/ |
||||
|
|
||||
|
/*-----------------------CAN Driver configuration example ----------------------*/ |
||||
|
/* #define BSP_USING_CAN0 */ |
||||
|
/* #define BSP_CAN0_RX_PIN "PD0" */ |
||||
|
/* #define BSP_CAN0_TX_PIN "PD1" */ |
||||
|
/* #define BSP_CAN0_AFIO "AF9" */ |
||||
|
|
||||
|
/*---------- Configure your desired device here as described above ---------*/ |
||||
|
/* USER CODE BEGIN */ |
||||
|
|
||||
|
/* USER CODE END */ |
||||
|
|
||||
|
/*-------------------------- CAN CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- LCD CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure LCD
|
||||
|
* STEP 1, enable the SDIO driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using LCD device drivers |
||||
|
* |
||||
|
* Notes: |
||||
|
* - The LCD pin configuration is implemented in the tli_gpio_config() function |
||||
|
* located in drv_lcd.c. |
||||
|
* - Before using the LCD, please consult the MCU datasheet and ensure that all |
||||
|
* related pins are configured according to the hardware requirements. |
||||
|
* - If custom pins are needed, update the configuration inside tli_gpio_config() |
||||
|
* accordingly. |
||||
|
*/ |
||||
|
|
||||
|
/*-------------------------- LCD CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- ETH CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** if you want to use eth you can use the following instructions.
|
||||
|
* |
||||
|
* STEP 1, enable the network interface device in RT-Thread Settings. |
||||
|
* e.g. Components -> Network -> Enable network interface device |
||||
|
* |
||||
|
* STEP 2, enable the socket abstraction layer in RT-Thread Settings. |
||||
|
* e.g. Components -> Network -> SAL: socket abstraction layer |
||||
|
* |
||||
|
* STEP 3, select the lwip stack and features you need: |
||||
|
* e.g. Components -> Network -> LwIP: light weight TCP/IP stack |
||||
|
* |
||||
|
* STEP 4, configure MPU settings for Ethernet DMA descriptors and buffers: |
||||
|
* Check and modify the enet_mpu_config() function in drivers/drv_enet.c: |
||||
|
* - Configure MPU region for DMA descriptors and Rx/Tx buffers (0x30000000) |
||||
|
* - Set appropriate memory attributes (bufferable, non-cacheable, non-shareable) |
||||
|
* - Ensure MPU region size matches your actual buffer requirements |
||||
|
* |
||||
|
* STEP 5, configure Ethernet GPIO pins according to your hardware design: |
||||
|
* Check and modify the enet_gpio_config() function in drivers/rtt/include/config/enet_config.h: |
||||
|
* - Verify all MII/RMII/RGMII interface pins are correctly configured |
||||
|
* - Check clock output configuration (such as: PA8 for PHY reference clock) |
||||
|
* - Ensure correct alternate function (such as: AF11 for Ethernet pins) |
||||
|
* - Configure PHY reset pin if required by your hardware |
||||
|
* |
||||
|
* Notes: |
||||
|
* - The pin configuration in enet_gpio_config() must match your actual hardware design and PCB layout |
||||
|
* - MPU configuration in enet_mpu_config() is critical for proper DMA operation |
||||
|
* - For MII/RMII/RGMII interface, ensure all required pins are properly configured in enet_gpio_config() |
||||
|
* - Refer to GD32H7xx datasheet for Ethernet pin alternate function mapping |
||||
|
* - Refer to PHY chip datasheet for specific configuration requirements |
||||
|
*/ |
||||
|
|
||||
|
/*-------------------------- ETH CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- USB HOST CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure USB Host (hardware)
|
||||
|
* |
||||
|
* STEP 1, enable the USB Host driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using USB -> USB Host |
||||
|
* |
||||
|
* STEP 2, select the USB Host stack and drivers you need: |
||||
|
* e.g. USB Host -> Using USB Host |
||||
|
* USB Host -> Using USB Host -> Enable UDisk Drivers |
||||
|
* USB Host -> Using USB Host -> Enable HID Drivers |
||||
|
* |
||||
|
* STEP 3, define the basic USB configuration macros in board.h: |
||||
|
* e.g. #define BSP_USING_USB // Enable USB peripheral
|
||||
|
* #define USE_USBHS0 // Enable USBHS0 instance
|
||||
|
* |
||||
|
* STEP 4, select USB speed mode in board.h: |
||||
|
* For High Speed (HS) mode: |
||||
|
* e.g. #define USE_USB_HS |
||||
|
* For Full Speed (FS) mode: |
||||
|
* e.g. #define USE_USB_FS |
||||
|
* |
||||
|
* STEP 5, verify and modify the VBUS power switch configuration in the hardware driver: |
||||
|
* Check and modify the following definitions in drivers/usb/gd32h7_usb_hw.c: |
||||
|
* e.g. #define HOST_POWERSW_PORT_RCC RCU_GPIOG |
||||
|
* #define HOST_POWERSW_PORT GPIOG |
||||
|
* #define HOST_POWERSW_VBUS GPIO_PIN_7 |
||||
|
* Ensure these definitions match your actual hardware design and pin connections. |
||||
|
* |
||||
|
* Notes: |
||||
|
* - USB HS (High Speed) requires external PHY and supports 480 Mbps data rate |
||||
|
* - USB FS (Full Speed) uses internal PHY and supports 12 Mbps data rate |
||||
|
* - The pin configuration depends on the specific USB instance (USBHS0/USBHS1) and package type |
||||
|
* - The HOST_POWERSW_VBUS configuration in gd32h7_usb_hw.c must match your actual hardware design |
||||
|
* - Refer to GD32H7xx datasheet for the specific pin alternate function mapping |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- Driver configuration example ----------------------*/ |
||||
|
/* Basic USB configuration in board.h */ |
||||
|
/* #define BSP_USING_USB */ |
||||
|
/* #define USE_USBHS0 | #define USE_USBHS1 */ |
||||
|
/* #define USE_USB_HS | #define USE_USB_FS */ |
||||
|
|
||||
|
/*-------------------------- USB HOST CONFIG END --------------------------*/ |
||||
|
|
||||
|
/*-------------------------- USB DEVICE CONFIG BEGIN --------------------------*/ |
||||
|
|
||||
|
/** How to enable and configure USB Device (hardware)
|
||||
|
* |
||||
|
* STEP 1, enable the USB Device driver in RT-Thread Settings. |
||||
|
* e.g. Components -> Device Drivers -> Using USB -> USB Device |
||||
|
* |
||||
|
* STEP 2, select the USB Device stack and device classes you need: |
||||
|
* e.g. USB Device -> Using USB Device |
||||
|
* USB Device -> Using USB Device -> Enable CDC Virtual Com Port |
||||
|
* USB Device -> Using USB Device -> Enable Mass Storage Gadget |
||||
|
* USB Device -> Using USB Device -> Enable HID Gadget |
||||
|
* -> ... |
||||
|
* |
||||
|
* STEP 3, define the basic USB configuration macros in board.h: |
||||
|
* e.g. #define BSP_USING_USB // Enable USB peripheral
|
||||
|
* #define USE_USBHS0 // Enable USBHS0 instance
|
||||
|
* |
||||
|
* STEP 4, select USB speed mode in board.h: |
||||
|
* For High Speed (HS) mode: |
||||
|
* e.g. #define USE_USB_HS |
||||
|
* For Full Speed (FS) mode: |
||||
|
* e.g. #define USE_USB_FS |
||||
|
* |
||||
|
* Notes: |
||||
|
* - USB HS (High Speed) requires external PHY and supports 480 Mbps data rate |
||||
|
* - USB FS (Full Speed) uses internal PHY and supports 12 Mbps data rate |
||||
|
* - The pin configuration depends on the specific USB instance (USBHS0/USBHS1) and package type |
||||
|
* - The DEVICE_VBUS configuration in gd32h7_usb_hw.c must match your actual hardware design |
||||
|
* - For CDC Virtual Com Port, additional configurations may be needed in the device class settings |
||||
|
* - Refer to GD32H7xx datasheet for the specific pin alternate function mapping |
||||
|
*/ |
||||
|
|
||||
|
/*----------------------- Driver configuration example ----------------------*/ |
||||
|
/* Basic USB configuration in board.h */ |
||||
|
/* #define BSP_USING_USB */ |
||||
|
/* #define USE_USBHS0 | #define USE_USBHS1 */ |
||||
|
/* #define USE_USB_HS | #define USE_USB_FS */ |
||||
|
|
||||
|
/*-------------------------- USB DEVICE CONFIG END --------------------------*/ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __BOARD_H__ */ |
||||
@ -0,0 +1,286 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-15 LZerro first version |
||||
|
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_adc.h" |
||||
|
#include "adc_config.h" |
||||
|
|
||||
|
#define DBG_TAG "drv.adc" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#ifdef RT_USING_ADC |
||||
|
|
||||
|
#if defined(BSP_USING_ADC0) |
||||
|
struct rt_adc_device adc0; |
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_ADC1) |
||||
|
struct rt_adc_device adc1; |
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_ADC2) |
||||
|
struct rt_adc_device adc2; |
||||
|
#endif |
||||
|
|
||||
|
static const struct gd32_adc adc_obj[] = { |
||||
|
#ifdef BSP_USING_ADC0 |
||||
|
ADC0_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_ADC1 |
||||
|
ADC1_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_ADC2 |
||||
|
ADC2_CONFIG, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief ADC MSP Initialization |
||||
|
* This function configures the hardware resources. |
||||
|
* @param adc_clk, pin_name |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void gd32_adc_gpio_init(rcu_periph_enum adc_clk, const char *pin_name) |
||||
|
{ |
||||
|
rt_uint32_t port, pin; |
||||
|
rcu_periph_enum gpio_periph; |
||||
|
|
||||
|
/* Skip if no valid pin name */ |
||||
|
if (pin_name == RT_NULL || rt_strcmp(pin_name, "-1") == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* Parse pin configuration */ |
||||
|
if (get_pin_config(pin_name, &port, &pin, &gpio_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
LOG_E("Failed to get pin config for %s", pin_name); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* Enable ADC clock */ |
||||
|
rcu_periph_clock_enable(adc_clk); |
||||
|
|
||||
|
/* Enable GPIO clock */ |
||||
|
rcu_periph_clock_enable(gpio_periph); |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
/* Configure ADC pin as analog mode */ |
||||
|
gpio_mode_set(port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, pin); |
||||
|
#else |
||||
|
/* Configure ADC pin as analog input */ |
||||
|
gpio_init(port, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, pin); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief ADC enable |
||||
|
* This function enables ADC. |
||||
|
* @param device, channel, enabled |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled) |
||||
|
{ |
||||
|
uint32_t adc_periph; |
||||
|
struct gd32_adc *adc = (struct gd32_adc *)device->parent.user_data; |
||||
|
|
||||
|
if (channel >= MAX_EXTERN_ADC_CHANNEL) |
||||
|
{ |
||||
|
LOG_E("invalid channel"); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
adc_periph = (uint32_t)(adc->adc_periph); |
||||
|
|
||||
|
if (enabled == ENABLE) |
||||
|
{ |
||||
|
#if defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
/* Disable ADC first */ |
||||
|
adc_disable(adc_periph); |
||||
|
#endif |
||||
|
|
||||
|
/* Initialize pin */ |
||||
|
gd32_adc_gpio_init(adc->adc_clk, adc->adc_pins[channel]); |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
/* Configure clock, ADC0/1 max clock config 72M, ADC2 80M */ |
||||
|
adc_clock_config(adc_periph, ADC_CLK_SYNC_HCLK_DIV6); |
||||
|
|
||||
|
/* Set ADC resolution */ |
||||
|
adc_resolution_config(adc_periph, ADC_RESOLUTION_12B); |
||||
|
#endif |
||||
|
|
||||
|
/* Set ADC data alignment mode */ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_data_alignment_config(ADC_DATAALIGN_RIGHT); |
||||
|
#else |
||||
|
adc_data_alignment_config(adc_periph, ADC_DATAALIGN_RIGHT); |
||||
|
#endif |
||||
|
|
||||
|
/* Set as regular channel */ |
||||
|
#if defined SOC_SERIES_GD32F4xx |
||||
|
adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, 1); |
||||
|
adc_external_trigger_source_config(adc_periph, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_EXTI_11); |
||||
|
adc_external_trigger_config(adc_periph, ADC_ROUTINE_CHANNEL, ENABLE); |
||||
|
#elif defined SOC_SERIES_GD32H75E |
||||
|
adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, 1); |
||||
|
adc_external_trigger_config(adc_periph, ADC_ROUTINE_CHANNEL, ENABLE); |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1); |
||||
|
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE); |
||||
|
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE); |
||||
|
#elif defined SOC_SERIES_GD32H7xx |
||||
|
adc_channel_length_config(adc_periph, ADC_REGULAR_CHANNEL, 1); |
||||
|
#else |
||||
|
adc_channel_length_config(adc_periph, ADC_REGULAR_CHANNEL, 1); |
||||
|
adc_external_trigger_source_config(adc_periph, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); |
||||
|
adc_external_trigger_config(adc_periph, ADC_REGULAR_CHANNEL, ENABLE); |
||||
|
#endif |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_enable(); |
||||
|
#else |
||||
|
adc_enable(adc_periph); |
||||
|
#endif |
||||
|
|
||||
|
/* Delay for ADC startup */ |
||||
|
rt_thread_mdelay(1); |
||||
|
|
||||
|
/* Calibrate ADC */ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_calibration_enable(); |
||||
|
#elif defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
adc_calibration_mode_config(adc_periph, ADC_CALIBRATION_OFFSET); |
||||
|
adc_calibration_number(adc_periph, ADC_CALIBRATION_NUM1); |
||||
|
adc_calibration_enable(adc_periph); |
||||
|
#else |
||||
|
adc_calibration_enable(adc_periph); |
||||
|
#endif |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_disable(); |
||||
|
#else |
||||
|
adc_disable(adc_periph); |
||||
|
#endif |
||||
|
} |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief Convert ADC. |
||||
|
* This function gets ADC value. |
||||
|
* @param device, channel, value |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value) |
||||
|
{ |
||||
|
uint32_t adc_periph; |
||||
|
uint32_t timeout = 0; |
||||
|
struct gd32_adc *adc = (struct gd32_adc *)(device->parent.user_data); |
||||
|
|
||||
|
if (!value) |
||||
|
{ |
||||
|
LOG_E("invalid param"); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
adc_periph = (uint32_t)(adc->adc_periph); |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#else |
||||
|
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#endif |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H75E |
||||
|
adc_routine_channel_config(adc_periph, 0, channel, 480); |
||||
|
adc_software_trigger_enable(adc_periph, ADC_ROUTINE_CHANNEL); |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
adc_regular_channel_config(0, channel, ADC_SAMPLETIME_13POINT5); |
||||
|
adc_software_trigger_enable(ADC_REGULAR_CHANNEL); |
||||
|
#elif defined SOC_SERIES_GD32H7xx |
||||
|
adc_regular_channel_config(adc_periph, 0, channel, 480); |
||||
|
adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL); |
||||
|
#else |
||||
|
adc_regular_channel_config(adc_periph, 0, channel, ADC_SAMPLETIME_13POINT5); |
||||
|
adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL); |
||||
|
#endif |
||||
|
|
||||
|
/* Wait for conversion complete */ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
while (!adc_flag_get(ADC_FLAG_EOC)) |
||||
|
#else |
||||
|
while (!adc_flag_get(adc_periph, ADC_FLAG_EOC)) |
||||
|
#endif |
||||
|
{ |
||||
|
if (timeout >= 100) |
||||
|
{ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#else |
||||
|
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#endif |
||||
|
LOG_E("Convert Timeout"); |
||||
|
return -RT_ETIMEOUT; |
||||
|
} |
||||
|
|
||||
|
timeout++; |
||||
|
rt_thread_delay(1); |
||||
|
} |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H75E |
||||
|
*value = adc_routine_data_read(adc_periph); |
||||
|
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
*value = adc_regular_data_read(); |
||||
|
adc_flag_clear(ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#else |
||||
|
*value = adc_regular_data_read(adc_periph); |
||||
|
adc_flag_clear(adc_periph, ADC_FLAG_EOC | ADC_FLAG_STRC); |
||||
|
#endif |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static struct rt_adc_ops gd32_adc_ops = { |
||||
|
.enabled = gd32_adc_enabled, |
||||
|
.convert = gd32_adc_convert, |
||||
|
}; |
||||
|
|
||||
|
static int rt_hw_adc_init(void) |
||||
|
{ |
||||
|
int ret, i = 0; |
||||
|
|
||||
|
syscfg_analog_switch_enable(SYSCFG_PA0_ANALOG_SWITCH); |
||||
|
syscfg_analog_switch_enable(SYSCFG_PA1_ANALOG_SWITCH); |
||||
|
syscfg_analog_switch_enable(SYSCFG_PC2_ANALOG_SWITCH); |
||||
|
syscfg_analog_switch_enable(SYSCFG_PC3_ANALOG_SWITCH); |
||||
|
|
||||
|
for (; i < sizeof(adc_obj) / sizeof(adc_obj[0]); i++) |
||||
|
{ |
||||
|
ret = rt_hw_adc_register(adc_obj[i].adc, |
||||
|
(const char *)adc_obj[i].device_name, |
||||
|
&gd32_adc_ops, &adc_obj[i]); |
||||
|
if (ret != RT_EOK) |
||||
|
{ |
||||
|
/* TODO err handler */ |
||||
|
LOG_E("failed register %s, err=%d", adc_obj[i].device_name, ret); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
INIT_BOARD_EXPORT(rt_hw_adc_init); |
||||
|
#endif |
||||
@ -0,0 +1,788 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2024-12-30 qingsong.yin first version |
||||
|
* 2024-03-07 qingsong.yin for CAN20kBaud/CAN10kBaud |
||||
|
* 2024-09-09 qingsong.yin for CANFD and DMA |
||||
|
* 2025-10-22 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include "drv_can.h" |
||||
|
#include "can_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_CAN |
||||
|
#if defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2) |
||||
|
|
||||
|
#define LOG_TAG "drv_can" |
||||
|
#include <drv_log.h> |
||||
|
|
||||
|
#ifdef BSP_USING_CAN0 |
||||
|
struct rt_can_device dev_can0; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_CAN1 |
||||
|
struct rt_can_device dev_can1; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_CAN2 |
||||
|
struct rt_can_device dev_can2; |
||||
|
#endif |
||||
|
|
||||
|
static gd32_can_struct can_obj[] = { |
||||
|
#ifdef BSP_USING_CAN0 |
||||
|
CAN0_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_CAN1 |
||||
|
CAN1_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_CAN2 |
||||
|
CAN2_CONFIG, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
/* baud calculation example */ |
||||
|
#if defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32H7xx) /* APB2 300MHz(max) */ |
||||
|
static const struct gd32_baud_rate_tab can_baud_rate_tab[] = { |
||||
|
/* baud, sjw, prop, seg1, seg2, prescaler */ |
||||
|
{ CAN1MBaud, 1, 20, 27, 12, 5 }, |
||||
|
{ CAN800kBaud, 1, 2, 9, 3, 25 }, |
||||
|
{ CAN500kBaud, 1, 2, 5, 2, 60 }, |
||||
|
{ CAN250kBaud, 1, 2, 5, 2, 120 }, |
||||
|
{ CAN125kBaud, 1, 2, 5, 2, 240 }, |
||||
|
{ CAN100kBaud, 1, 2, 5, 2, 300 }, |
||||
|
{ CAN50kBaud, 1, 2, 5, 2, 600 }, |
||||
|
{ CAN20kBaud, 1, 14, 25, 10, 300 }, |
||||
|
{ CAN10kBaud, 1, 14, 25, 10, 600 }, |
||||
|
}; |
||||
|
|
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
static const gd32_fd_data_baud_t can_fd_data_baud_tab[] = { |
||||
|
/* baud, sjw, prop, seg1, seg2, prescaler */ |
||||
|
{ CANFD_5MBaud, 1, 2, 7, 2, 5 }, /* 5Mbps */ |
||||
|
{ CANFD_4MBaud, 1, 3, 8, 3, 5 }, /* 4Mbps */ |
||||
|
{ CANFD_3MBaud, 1, 4, 11, 4, 5 }, /* 3Mbps */ |
||||
|
{ CANFD_2MBaud, 1, 6, 17, 6, 5 }, /* 2Mbps */ |
||||
|
{ CANFD_1MBaud, 1, 20, 27, 12, 5 }, /* 1Mbps: Total Tq=60, SamplePoint≈80% */ |
||||
|
{ CANFD_800kBaud, 1, 2, 9, 3, 25 }, /* 800kbps */ |
||||
|
{ CANFD_500kBaud, 1, 2, 5, 2, 60 }, /* 500kbps */ |
||||
|
{ CANFD_250kBaud, 1, 2, 5, 2, 120 }, /* 250kbps */ |
||||
|
{ CANFD_125kBaud, 1, 2, 5, 2, 240 }, /* 125kbps */ |
||||
|
{ CANFD_100kBaud, 1, 2, 5, 2, 300 }, /* 100kbps */ |
||||
|
{ CANFD_50kBaud, 1, 2, 5, 2, 600 }, /* 50kbps */ |
||||
|
{ CANFD_20kBaud, 1, 14, 25, 10, 300 }, /* 20kbps */ |
||||
|
{ CANFD_10kBaud, 1, 14, 25, 10, 600 }, /* 10kbps */ |
||||
|
}; |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
static rt_uint32_t get_can_baud_index(rt_uint32_t baud) |
||||
|
{ |
||||
|
rt_uint32_t len, index; |
||||
|
|
||||
|
len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]); |
||||
|
for (index = 0; index < len; index++) |
||||
|
{ |
||||
|
if (can_baud_rate_tab[index].baud_rate == baud) |
||||
|
{ |
||||
|
return index; |
||||
|
} |
||||
|
} |
||||
|
return 0; /* default baud is CAN1MBaud */ |
||||
|
} |
||||
|
|
||||
|
rt_weak void can_gpio_config(void) |
||||
|
{ |
||||
|
int i; |
||||
|
rt_uint32_t tx_port, rx_port; |
||||
|
rt_uint32_t tx_pin, rx_pin; |
||||
|
rt_uint32_t pin_af; |
||||
|
rcu_periph_enum tx_periph, rx_periph; |
||||
|
|
||||
|
#ifdef BSP_USING_CAN0 |
||||
|
rcu_can_clock_config(IDX_CAN0, RCU_CANSRC_APB2); |
||||
|
rcu_periph_clock_enable(RCU_CAN0); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_CAN1 |
||||
|
rcu_can_clock_config(IDX_CAN1, RCU_CANSRC_APB2); |
||||
|
rcu_periph_clock_enable(RCU_CAN1); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_CAN2 |
||||
|
rcu_can_clock_config(IDX_CAN2, RCU_CANSRC_APB2); |
||||
|
rcu_periph_clock_enable(RCU_CAN2); |
||||
|
#endif |
||||
|
|
||||
|
for (i = 0; i < sizeof(can_obj) / sizeof(can_obj[0]); i++) |
||||
|
{ |
||||
|
get_pin_config(can_obj[i].tx_pin_name, &tx_port, &tx_pin, &tx_periph); |
||||
|
get_pin_config(can_obj[i].rx_pin_name, &rx_port, &rx_pin, &rx_periph); |
||||
|
pin_alternate_config(can_obj[i].alternate, &pin_af); |
||||
|
|
||||
|
rcu_periph_clock_enable(tx_periph); |
||||
|
rcu_periph_clock_enable(rx_periph); |
||||
|
|
||||
|
gpio_output_options_set(tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, tx_pin); |
||||
|
gpio_mode_set(tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, tx_pin); |
||||
|
gpio_af_set(tx_port, pin_af, tx_pin); |
||||
|
|
||||
|
gpio_output_options_set(rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, rx_pin); |
||||
|
gpio_mode_set(rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, rx_pin); |
||||
|
gpio_af_set(rx_port, pin_af, rx_pin); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd32_can_configure(struct rt_can_device *can, struct can_configure *cfg) |
||||
|
{ |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
rt_uint32_t baud_index; |
||||
|
|
||||
|
RT_ASSERT(can); |
||||
|
RT_ASSERT(cfg); |
||||
|
RT_ASSERT(drv_can); |
||||
|
|
||||
|
/* init can gpio and enable can clock */ |
||||
|
can_gpio_config(); |
||||
|
|
||||
|
/* initialize CAN register */ |
||||
|
can_deinit(drv_can->can_periph); |
||||
|
/* initialize CAN */ |
||||
|
can_struct_para_init(CAN_INIT_STRUCT, &drv_can->can_init); |
||||
|
/* initialize CAN parameters */ |
||||
|
drv_can->can_init.internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK; |
||||
|
drv_can->can_init.self_reception = DISABLE; |
||||
|
drv_can->can_init.mb_tx_order = CAN_TX_HIGH_PRIORITY_MB_FIRST; |
||||
|
drv_can->can_init.mb_tx_abort_enable = ENABLE; |
||||
|
drv_can->can_init.local_priority_enable = DISABLE; |
||||
|
drv_can->can_init.mb_rx_ide_rtr_type = CAN_IDE_RTR_FILTERED; |
||||
|
drv_can->can_init.mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME; |
||||
|
drv_can->can_init.rx_private_filter_queue_enable = ENABLE; |
||||
|
drv_can->can_init.edge_filter_enable = DISABLE; |
||||
|
drv_can->can_init.protocol_exception_enable = DISABLE; |
||||
|
drv_can->can_init.rx_filter_order = CAN_RX_FILTER_ORDER_MAILBOX_FIRST; |
||||
|
drv_can->can_init.memory_size = CAN_MEMSIZE_32_UNIT; |
||||
|
/* filter configuration */ |
||||
|
drv_can->can_init.mb_public_filter = 0U; |
||||
|
/* can baud config */ |
||||
|
baud_index = get_can_baud_index(cfg->baud_rate); |
||||
|
drv_can->can_init.resync_jump_width = can_baud_rate_tab[baud_index].resync_jump_width; |
||||
|
drv_can->can_init.prop_time_segment = can_baud_rate_tab[baud_index].prop_time_segment; |
||||
|
drv_can->can_init.time_segment_1 = can_baud_rate_tab[baud_index].time_segment_1; |
||||
|
drv_can->can_init.time_segment_2 = can_baud_rate_tab[baud_index].time_segment_2; |
||||
|
drv_can->can_init.prescaler = can_baud_rate_tab[baud_index].prescaler; |
||||
|
|
||||
|
if (can_init(drv_can->can_periph, &drv_can->can_init) != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("can init error"); |
||||
|
return RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
/* Configure CANFD if enabled in user config */ |
||||
|
drv_can->fd_enabled = 0; |
||||
|
can_struct_para_init(CAN_FD_INIT_STRUCT, &drv_can->can_fd_init); |
||||
|
if (cfg->enable_canfd) |
||||
|
{ |
||||
|
/* default: enable bitrate switch and ISO mode */ |
||||
|
drv_can->can_fd_init.bitrate_switch_enable = ENABLE; |
||||
|
drv_can->can_fd_init.iso_can_fd_enable = ENABLE; |
||||
|
/* select mailbox data size according to arbitration len requirement; default 64 bytes */ |
||||
|
drv_can->can_fd_init.mailbox_data_size = CAN_MAILBOX_DATA_SIZE_8_BYTES; |
||||
|
drv_can->can_fd_init.tdc_enable = DISABLE; |
||||
|
drv_can->can_fd_init.tdc_offset = 0U; |
||||
|
if (cfg->use_bit_timing) |
||||
|
{ |
||||
|
/* Arbitration timing has been already applied by classic init; now apply data phase */ |
||||
|
drv_can->can_fd_init.resync_jump_width = cfg->canfd_timing.num_sjw; |
||||
|
drv_can->can_fd_init.prop_time_segment = cfg->canfd_timing.num_sspoff; /* heuristic if library expects prop vs seg1 */ |
||||
|
drv_can->can_fd_init.time_segment_1 = cfg->canfd_timing.num_seg1; |
||||
|
drv_can->can_fd_init.time_segment_2 = cfg->canfd_timing.num_seg2; |
||||
|
drv_can->can_fd_init.prescaler = cfg->canfd_timing.prescaler; |
||||
|
} |
||||
|
else if (cfg->baud_rate_fd) |
||||
|
{ |
||||
|
/* Simple reuse arbitration timing table for data speed if user sets baud_rate_fd as multiple (rough placeholder) */ |
||||
|
/* NOTE: For precise FD data phase user should set use_bit_timing */ |
||||
|
drv_can->can_fd_init.resync_jump_width = 1; |
||||
|
drv_can->can_fd_init.prop_time_segment = 2; |
||||
|
drv_can->can_fd_init.time_segment_1 = 5; |
||||
|
drv_can->can_fd_init.time_segment_2 = 2; |
||||
|
drv_can->can_fd_init.prescaler = 15; /* placeholder from example */ |
||||
|
} |
||||
|
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init); |
||||
|
drv_can->fd_enabled = 1; |
||||
|
} |
||||
|
#else |
||||
|
#ifdef RT_CAN_USING_HDR |
||||
|
/* Rxfifo configuration */ |
||||
|
drv_can->can_fifo.dma_enable = DISABLE; |
||||
|
drv_can->can_fifo.filter_format_and_number = CAN_RXFIFO_FILTER_A_NUM_40; |
||||
|
drv_can->can_fifo.fifo_public_filter = 0; |
||||
|
can_rx_fifo_config(drv_can->can_periph, &drv_can->can_fifo); |
||||
|
#endif |
||||
|
#endif /* RT_CAN_USING_CANFD */ |
||||
|
for (uint8_t i = 0; i < 16; i++) |
||||
|
{ |
||||
|
can_struct_para_init(CAN_MDSC_STRUCT, &drv_can->rx_message[i]); |
||||
|
drv_can->rx_message[i].rtr = 0U; |
||||
|
drv_can->rx_message[i].ide = 0U; |
||||
|
drv_can->rx_message[i].code = CAN_MB_RX_STATUS_EMPTY; |
||||
|
/* rx mailbox */ |
||||
|
drv_can->rx_message[i].id = 0x55U; |
||||
|
#if defined(SOC_SERIES_GD32H7xx) |
||||
|
drv_can->rx_message[i].data = (uint32_t *)(drv_can->fd_rx_buf[i]); |
||||
|
#elif defined(SOC_SERIES_GD32H75E) |
||||
|
memcpy(drv_can->rx_message[i].data, drv_can->fd_rx_buf[i], sizeof(drv_can->rx_message[i].data)); |
||||
|
#endif |
||||
|
can_mailbox_config(drv_can->can_periph, i, &drv_can->rx_message[i]); |
||||
|
} |
||||
|
|
||||
|
/* clear msg16-31 for tx */ |
||||
|
CAN_STAT(drv_can->can_periph) = BITS(16, 31); |
||||
|
|
||||
|
/* can mode config */ |
||||
|
switch (cfg->mode) |
||||
|
{ |
||||
|
case RT_CAN_MODE_NORMAL: |
||||
|
drv_can->mode = CAN_NORMAL_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LISTEN: |
||||
|
drv_can->mode = CAN_MONITOR_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LOOPBACK: |
||||
|
drv_can->mode = CAN_LOOPBACK_SILENT_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LOOPBACKANLISTEN: |
||||
|
drv_can->mode = CAN_LOOPBACK_SILENT_MODE; |
||||
|
break; |
||||
|
default: |
||||
|
drv_can->mode = CAN_NORMAL_MODE; |
||||
|
break; |
||||
|
} |
||||
|
can_operation_mode_enter(drv_can->can_periph, drv_can->mode); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd32_can_control(struct rt_can_device *can, int cmd, void *arg) |
||||
|
{ |
||||
|
rt_uint32_t baud_index; |
||||
|
rt_uint32_t argval; |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
|
||||
|
RT_ASSERT(can != RT_NULL); |
||||
|
RT_ASSERT(drv_can != RT_NULL); |
||||
|
|
||||
|
switch (cmd) |
||||
|
{ |
||||
|
case RT_DEVICE_CTRL_CLR_INT: |
||||
|
argval = (rt_uint32_t)arg; |
||||
|
if (argval == RT_DEVICE_FLAG_INT_RX) |
||||
|
{ |
||||
|
CAN_INTEN(drv_can->can_periph) &= ~BITS(0, 15); |
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN0_RX_IRQn); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN1_RX_IRQn); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN2_RX_IRQn); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
else if (argval == RT_DEVICE_FLAG_INT_TX) |
||||
|
{ //int tx
|
||||
|
CAN_INTEN(drv_can->can_periph) &= ~BITS(15, 31); |
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN0_TX_IRQn); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN1_TX_IRQn); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN2_TX_IRQn); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
else if (argval == RT_DEVICE_CAN_INT_ERR) |
||||
|
{ //int error
|
||||
|
can_interrupt_disable(drv_can->can_periph, CAN_INT_ERR_SUMMARY); |
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN0_Error_IRQn); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN1_Error_IRQn); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_disable(CAN2_Error_IRQn); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
case RT_DEVICE_CTRL_SET_INT: |
||||
|
argval = (rt_uint32_t)arg; |
||||
|
if (argval == RT_DEVICE_FLAG_INT_RX) |
||||
|
{ |
||||
|
CAN_INTEN(drv_can->can_periph) |= BITS(0, 15); |
||||
|
|
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN0_RX_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN1_RX_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN2_RX_IRQn, 15, 0); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
else if (argval == RT_DEVICE_FLAG_INT_TX) |
||||
|
{ |
||||
|
CAN_INTEN(drv_can->can_periph) |= BITS(16, 31); |
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN0_TX_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN1_TX_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN2_TX_IRQn, 15, 0); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
else if (argval == RT_DEVICE_CAN_INT_ERR) |
||||
|
{ |
||||
|
can_interrupt_enable(drv_can->can_periph, CAN_INT_ERR_SUMMARY); |
||||
|
if (CAN0 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN0_ERROR_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN1 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN1_ERROR_IRQn, 15, 0); |
||||
|
} |
||||
|
else if (CAN2 == drv_can->can_periph) |
||||
|
{ |
||||
|
nvic_irq_enable(CAN2_ERROR_IRQn, 15, 0); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* not reach */ |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_SET_FILTER: |
||||
|
{ |
||||
|
drv_can->filter_cb = (void (*)(uint32_t can_periph))arg; |
||||
|
if (drv_can->filter_cb) |
||||
|
{ |
||||
|
drv_can->filter_cb(drv_can->can_periph); |
||||
|
} |
||||
|
#ifdef RT_CAN_USING_HDR |
||||
|
struct rt_can_filter_config *filter_cfg; |
||||
|
|
||||
|
filter_cfg = (struct rt_can_filter_config *)arg; |
||||
|
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE); |
||||
|
CAN_RFIFOPUBF(drv_can->can_periph) = 0xFFFFFFFF; |
||||
|
for (i = 0; i < 16; i++) |
||||
|
{ |
||||
|
can_private_filter_config(drv_can->can_periph, i, 0xFFFFFFFF); |
||||
|
} |
||||
|
|
||||
|
for (i = 0; i < filter_cfg->count; i++) |
||||
|
{ |
||||
|
if (filter_cfg->items[i].hdr_bank == -1) |
||||
|
{ |
||||
|
can_private_filter_config(drv_can->can_periph, i, filter_cfg->items[i].mask); |
||||
|
drv_can->fifo_element[i].extended_frame = filter_cfg->items[i].ide; |
||||
|
drv_can->fifo_element[i].remote_frame = filter_cfg->items[i].rtr; |
||||
|
drv_can->fifo_element[i].id = filter_cfg->items[i].id; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
can_private_filter_config(drv_can->can_periph, filter_cfg->items[i].hdr_bank, filter_cfg->items[i].mask); |
||||
|
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].extended_frame = filter_cfg->items[i].ide; |
||||
|
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].remote_frame = filter_cfg->items[i].rtr; |
||||
|
drv_can->fifo_element[filter_cfg->items[i].hdr_bank].id = filter_cfg->items[i].id; |
||||
|
} |
||||
|
} |
||||
|
can_rx_fifo_filter_table_config(drv_can->can_periph, drv_can->fifo_element); |
||||
|
can_rx_fifo_clear(drv_can->can_periph); |
||||
|
can_operation_mode_enter(drv_can->can_periph, drv_can->mode); |
||||
|
#endif |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_SET_MODE: |
||||
|
argval = (rt_uint32_t)arg; |
||||
|
if (argval != drv_can->device->config.mode) |
||||
|
{ |
||||
|
/* can mode config */ |
||||
|
switch (argval) |
||||
|
{ |
||||
|
case RT_CAN_MODE_NORMAL: |
||||
|
drv_can->mode = CAN_NORMAL_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LISTEN: |
||||
|
drv_can->mode = CAN_MONITOR_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LOOPBACK: |
||||
|
drv_can->mode = CAN_LOOPBACK_SILENT_MODE; |
||||
|
break; |
||||
|
case RT_CAN_MODE_LOOPBACKANLISTEN: |
||||
|
drv_can->mode = CAN_LOOPBACK_SILENT_MODE; |
||||
|
break; |
||||
|
default: |
||||
|
return RT_ERROR; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (SUCCESS == can_operation_mode_enter(drv_can->can_periph, drv_can->mode)) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return RT_ERROR; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_SET_BAUD: |
||||
|
argval = (rt_uint32_t)arg; |
||||
|
if (argval != CAN1MBaud && |
||||
|
argval != CAN800kBaud && |
||||
|
argval != CAN500kBaud && |
||||
|
argval != CAN250kBaud && |
||||
|
argval != CAN125kBaud && |
||||
|
argval != CAN100kBaud && |
||||
|
argval != CAN50kBaud && |
||||
|
argval != CAN20kBaud && |
||||
|
argval != CAN10kBaud) |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
if (argval != drv_can->device->config.baud_rate) |
||||
|
{ |
||||
|
baud_index = get_can_baud_index(argval); |
||||
|
drv_can->can_init.resync_jump_width = can_baud_rate_tab[baud_index].resync_jump_width; |
||||
|
drv_can->can_init.prop_time_segment = can_baud_rate_tab[baud_index].prop_time_segment; |
||||
|
drv_can->can_init.time_segment_1 = can_baud_rate_tab[baud_index].time_segment_1; |
||||
|
drv_can->can_init.time_segment_2 = can_baud_rate_tab[baud_index].time_segment_2; |
||||
|
drv_can->can_init.prescaler = can_baud_rate_tab[baud_index].prescaler; |
||||
|
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE); |
||||
|
CAN_BT(drv_can->can_periph) &= ~(CAN_BT_BAUDPSC | CAN_BT_SJW | CAN_BT_PTS | CAN_BT_PBS1 | CAN_BT_PBS2); |
||||
|
CAN_BT(drv_can->can_periph) |= (uint32_t)(BT_BAUDPSC(drv_can->can_init.prescaler - 1U) | |
||||
|
BT_SJW((uint32_t)drv_can->can_init.resync_jump_width - 1U) | |
||||
|
BT_PTS((uint32_t)drv_can->can_init.prop_time_segment - 1U) | |
||||
|
BT_PBS1((uint32_t)drv_can->can_init.time_segment_1 - 1U) | |
||||
|
BT_PBS2((uint32_t)drv_can->can_init.time_segment_2 - 1U)); |
||||
|
can_operation_mode_enter(drv_can->can_periph, drv_can->mode); |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_SET_PRIV: |
||||
|
{ |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_GET_STATUS: |
||||
|
{ |
||||
|
} |
||||
|
break; |
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
case RT_CAN_CMD_SET_CANFD: |
||||
|
{ |
||||
|
/* enable or disable CANFD dynamically */ |
||||
|
rt_uint32_t enable = (rt_uint32_t)arg; |
||||
|
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE); |
||||
|
if (enable) |
||||
|
{ |
||||
|
drv_can->fd_enabled = 1; |
||||
|
drv_can->can_fd_init.bitrate_switch_enable = ENABLE; |
||||
|
drv_can->can_fd_init.iso_can_fd_enable = ENABLE; |
||||
|
drv_can->can_fd_init.mailbox_data_size = CAN_MAILBOX_DATA_SIZE_16_BYTES; |
||||
|
drv_can->can_fd_init.tdc_enable = DISABLE; |
||||
|
drv_can->can_fd_init.tdc_offset = 0U; |
||||
|
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no direct API to disable FD; re-init classic CAN */ |
||||
|
drv_can->fd_enabled = 0; |
||||
|
} |
||||
|
can_operation_mode_enter(drv_can->can_periph, drv_can->mode); |
||||
|
} |
||||
|
break; |
||||
|
case RT_CAN_CMD_SET_BAUD_FD: |
||||
|
{ |
||||
|
rt_uint32_t data_baud; |
||||
|
int found; |
||||
|
unsigned k; |
||||
|
data_baud = (rt_uint32_t)arg; |
||||
|
if (!drv_can->fd_enabled || data_baud == 0) |
||||
|
break; |
||||
|
found = -1; |
||||
|
for (k = 0; k < (sizeof(can_fd_data_baud_tab) / sizeof(can_fd_data_baud_tab[0])); k++) |
||||
|
{ |
||||
|
if (can_fd_data_baud_tab[k].baud == data_baud) |
||||
|
{ |
||||
|
found = (int)k; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (found < 0) |
||||
|
break; /* unsupported */ |
||||
|
can_operation_mode_enter(drv_can->can_periph, CAN_INACTIVE_MODE); |
||||
|
drv_can->can_fd_init.resync_jump_width = can_fd_data_baud_tab[found].sjw; |
||||
|
drv_can->can_fd_init.prop_time_segment = can_fd_data_baud_tab[found].prop; |
||||
|
drv_can->can_fd_init.time_segment_1 = can_fd_data_baud_tab[found].seg1; |
||||
|
drv_can->can_fd_init.time_segment_2 = can_fd_data_baud_tab[found].seg2; |
||||
|
drv_can->can_fd_init.prescaler = can_fd_data_baud_tab[found].prescaler; |
||||
|
can_fd_config(drv_can->can_periph, &drv_can->can_fd_init); |
||||
|
can_operation_mode_enter(drv_can->can_periph, drv_can->mode); |
||||
|
} |
||||
|
break; |
||||
|
#endif /* RT_CAN_USING_CANFD */ |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t gd32_can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno) |
||||
|
{ |
||||
|
uint8_t i = 0; |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
struct rt_can_msg *tx_msg = (struct rt_can_msg *)buf; |
||||
|
|
||||
|
RT_ASSERT(can != RT_NULL); |
||||
|
RT_ASSERT(buf != RT_NULL); |
||||
|
RT_ASSERT(drv_can != RT_NULL); |
||||
|
RT_ASSERT(tx_msg != RT_NULL); |
||||
|
|
||||
|
/* transmit message */ |
||||
|
for (i = 16; i < 31; i++) |
||||
|
{ |
||||
|
if (0U == (CAN_STAT(drv_can->can_periph) & BIT(i))) |
||||
|
{ |
||||
|
/* initialize transmit message */ |
||||
|
drv_can->tx_message[i].rtr = tx_msg->rtr; |
||||
|
drv_can->tx_message[i].ide = tx_msg->ide; |
||||
|
drv_can->tx_message[i].esi = 0U; |
||||
|
drv_can->tx_message[i].code = CAN_MB_TX_STATUS_DATA; |
||||
|
drv_can->tx_message[i].brs = tx_msg->brs; |
||||
|
drv_can->tx_message[i].fdf = tx_msg->fd_frame; |
||||
|
drv_can->tx_message[i].prio = tx_msg->priv; |
||||
|
drv_can->tx_message[i].data_bytes = tx_msg->len; /* classic frame length or already set for FD */ |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H7xx) |
||||
|
drv_can->tx_message[i].data = (uint32_t *)tx_msg->data; |
||||
|
#elif defined(SOC_SERIES_GD32H75E) |
||||
|
memcpy(drv_can->tx_message[i].data, tx_msg->data, sizeof(drv_can->tx_message[i].data)); |
||||
|
#endif |
||||
|
drv_can->tx_message[i].id = tx_msg->id; |
||||
|
can_mailbox_config(drv_can->can_periph, i, &drv_can->tx_message[i]); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
} |
||||
|
return RT_EFULL; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t gd32_can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno) |
||||
|
{ |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
struct rt_can_msg *pmsg = (struct rt_can_msg *)buf; |
||||
|
RT_ASSERT(can); |
||||
|
RT_ASSERT(pmsg); |
||||
|
|
||||
|
uint8_t i; |
||||
|
/* receive data */ |
||||
|
for (i = 0; i < 16; i++) |
||||
|
{ |
||||
|
if (drv_can->rx_message_valid[i] == 1) |
||||
|
{ |
||||
|
drv_can->rx_message_valid[i] = 0; |
||||
|
pmsg->id = drv_can->rx_message[i].id; |
||||
|
pmsg->ide = drv_can->rx_message[i].ide; |
||||
|
pmsg->rtr = drv_can->rx_message[i].rtr; |
||||
|
pmsg->len = drv_can->rx_message[i].data_bytes; |
||||
|
pmsg->priv = 0; |
||||
|
pmsg->hdr_index = i; |
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
pmsg->fd_frame = drv_can->rx_message[i].fdf; |
||||
|
pmsg->brs = drv_can->rx_message[i].brs; |
||||
|
#endif |
||||
|
rt_memcpy(pmsg->data, drv_can->rx_message[i].data, pmsg->len); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
} |
||||
|
return RT_EEMPTY; |
||||
|
} |
||||
|
|
||||
|
static const struct rt_can_ops _can_ops = { |
||||
|
gd32_can_configure, |
||||
|
gd32_can_control, |
||||
|
gd32_can_sendmsg, |
||||
|
gd32_can_recvmsg, |
||||
|
}; |
||||
|
|
||||
|
static void _can_rx_tx_isr(struct rt_can_device *can) |
||||
|
{ |
||||
|
uint8_t i; |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
RT_ASSERT(can != RT_NULL); |
||||
|
RT_ASSERT(drv_can != RT_NULL); |
||||
|
|
||||
|
for (i = 0; i < 16; i++) |
||||
|
{ |
||||
|
if (CAN_STAT(drv_can->can_periph) & BIT(i)) |
||||
|
{ |
||||
|
can_mailbox_receive_data_read(drv_can->can_periph, i, &drv_can->rx_message[i]); |
||||
|
drv_can->rx_message_valid[i] = 1; |
||||
|
rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND); |
||||
|
CAN_STAT(drv_can->can_periph) = BIT(i); /* Clear the status bit */ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (i = 16; i < 31; i++) |
||||
|
{ |
||||
|
if (0U != (CAN_STAT(drv_can->can_periph) & BIT(i))) |
||||
|
{ |
||||
|
CAN_STAT(drv_can->can_periph) = BIT(i); |
||||
|
rt_hw_can_isr(can, RT_CAN_EVENT_TX_DONE); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static void _can_sce_isr(struct rt_can_device *can) |
||||
|
{ |
||||
|
gd32_can_struct *drv_can = (gd32_can_struct *)can->parent.user_data; |
||||
|
rt_uint32_t err_code; |
||||
|
|
||||
|
RT_ASSERT(can != RT_NULL); |
||||
|
RT_ASSERT(drv_can != RT_NULL); |
||||
|
|
||||
|
if (SET == can_interrupt_flag_get(drv_can->can_periph, CAN_INT_FLAG_ERR_SUMMARY)) |
||||
|
{ |
||||
|
can_interrupt_flag_clear(drv_can->can_periph, CAN_INT_FLAG_ERR_SUMMARY); |
||||
|
err_code = GET_BITS(CAN_ERR1(drv_can->can_periph), 10U, 15U); |
||||
|
|
||||
|
if (err_code & CAN_ERR1_FMERR) |
||||
|
{ |
||||
|
can->status.formaterrcnt++; |
||||
|
} |
||||
|
|
||||
|
if (err_code & CAN_ERR1_CRCERR) |
||||
|
{ |
||||
|
can->status.crcerrcnt++; |
||||
|
} |
||||
|
|
||||
|
if (err_code & CAN_ERR1_ACKERR) |
||||
|
{ |
||||
|
can->status.ackerrcnt++; |
||||
|
} |
||||
|
can->status.errcode = err_code; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#ifdef BSP_USING_CAN0 |
||||
|
void CAN0_Message_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_rx_tx_isr(&dev_can0); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void CAN0_Error_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_sce_isr(&dev_can0); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif /* BSP_USING_CAN0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_CAN1 |
||||
|
void CAN1_Message_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_rx_tx_isr(&dev_can1); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void CAN1_Error_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_sce_isr(&dev_can1); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif /* BSP_USING_CAN1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_CAN2 |
||||
|
void CAN2_Message_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_rx_tx_isr(&dev_can2); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void CAN2_Error_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
_can_sce_isr(&dev_can2); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif /* BSP_USING_CAN2 */ |
||||
|
|
||||
|
int rt_hw_can_init(void) |
||||
|
{ |
||||
|
int i; |
||||
|
struct can_configure config = CANDEFAULTCONFIG; |
||||
|
config.privmode = RT_CAN_MODE_NOPRIV; |
||||
|
config.ticks = 50; |
||||
|
#ifdef RT_CAN_USING_HDR |
||||
|
config.maxhdr = 40; |
||||
|
#endif |
||||
|
|
||||
|
for (i = 0; i < sizeof(can_obj) / sizeof(can_obj[0]); i++) |
||||
|
{ |
||||
|
can_obj[i].device->config = config; |
||||
|
rt_hw_can_register(can_obj[i].device, can_obj[i].name, &_can_ops, &can_obj[i]); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
INIT_BOARD_EXPORT(rt_hw_can_init); |
||||
|
|
||||
|
#endif /* defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2) */ |
||||
|
#endif /*RT_USING_CAN*/ |
||||
@ -0,0 +1,107 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2018-11-7 SummerGift first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_common.h" |
||||
|
#include "board.h" |
||||
|
|
||||
|
#ifdef RT_USING_SERIAL |
||||
|
#ifdef RT_USING_SERIAL_V2 |
||||
|
#include "drv_usart_v2.h" |
||||
|
#else |
||||
|
#include "drv_usart.h" |
||||
|
#endif /* RT_USING_SERIAL */ |
||||
|
#endif /* RT_USING_SERIAL_V2 */ |
||||
|
|
||||
|
#define DBG_TAG "drv_common" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#ifdef RT_USING_FINSH |
||||
|
#include <finsh.h> |
||||
|
static void reboot(uint8_t argc, char **argv) |
||||
|
{ |
||||
|
rt_hw_cpu_reset(); |
||||
|
} |
||||
|
MSH_CMD_EXPORT(reboot, Reboot System); |
||||
|
#endif /* RT_USING_FINSH */ |
||||
|
|
||||
|
/**
|
||||
|
* @brief This function is executed in case of error occurrence. |
||||
|
* @param None |
||||
|
* @retval None |
||||
|
*/ |
||||
|
void Error_Handler(void) |
||||
|
{ |
||||
|
/* USER CODE BEGIN Error_Handler */ |
||||
|
/* User can add his own implementation to report the HAL error return state */ |
||||
|
while (1) |
||||
|
{ |
||||
|
} |
||||
|
/* USER CODE END Error_Handler */ |
||||
|
} |
||||
|
|
||||
|
/** System Clock Configuration
|
||||
|
*/ |
||||
|
void SystemClock_Config(void) |
||||
|
{ |
||||
|
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* This is the timer interrupt service routine. |
||||
|
* |
||||
|
*/ |
||||
|
void SysTick_Handler(void) |
||||
|
{ |
||||
|
/* enter interrupt */ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
rt_tick_increase(); |
||||
|
|
||||
|
/* leave interrupt */ |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* This function will initial gd32 board. |
||||
|
*/ |
||||
|
void hw_board_init() |
||||
|
{ |
||||
|
/* NVIC Configuration */ |
||||
|
#define NVIC_VTOR_MASK 0x3FFFFF80 |
||||
|
#ifdef VECT_TAB_RAM |
||||
|
/* Set the Vector Table base location at 0x10000000 */ |
||||
|
SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); |
||||
|
#else /* VECT_TAB_FLASH */ |
||||
|
/* Set the Vector Table base location at 0x08000000 */ |
||||
|
SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); |
||||
|
#endif |
||||
|
|
||||
|
/* Enable IChace */ |
||||
|
SCB_EnableICache(); |
||||
|
|
||||
|
/* Enable DChace */ |
||||
|
SCB_EnableDCache(); |
||||
|
|
||||
|
SystemClock_Config(); |
||||
|
|
||||
|
/* Pin driver initialization is open by default */ |
||||
|
#ifdef RT_USING_PIN |
||||
|
extern int rt_hw_pin_init(void); |
||||
|
rt_hw_pin_init(); |
||||
|
#endif |
||||
|
|
||||
|
/* USART driver initialization is open by default */ |
||||
|
#ifdef RT_USING_SERIAL |
||||
|
extern int rt_hw_usart_init(void); |
||||
|
rt_hw_usart_init(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,218 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-11 kurisaw first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_dac.h" |
||||
|
#include "dac_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_DAC |
||||
|
|
||||
|
#define DBG_TAG "drv.dac" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
static struct gd32_dac gd32_dac_obj[] = { |
||||
|
|
||||
|
#ifdef BSP_USING_DAC0 |
||||
|
DAC0_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_DAC1 |
||||
|
DAC1_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
/* DAC initialization status */ |
||||
|
typedef struct |
||||
|
{ |
||||
|
uint32_t dac_periph; |
||||
|
rt_bool_t initialized; |
||||
|
} DAC_INIT_STATUS; |
||||
|
|
||||
|
static DAC_INIT_STATUS dac_init_status[] = { |
||||
|
#if defined(DAC0) |
||||
|
{ DAC0, RT_FALSE }, |
||||
|
#elif defined(DAC1) |
||||
|
{ DAC1, RT_FALSE }, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
/* Private functions */ |
||||
|
static void gd32_dac_hw_init(struct gd32_dac *gd32_dac) |
||||
|
{ |
||||
|
rt_uint32_t dac_port, dac_pin; |
||||
|
rcu_periph_enum dac_periph; |
||||
|
|
||||
|
/* Get pin configuration */ |
||||
|
if (get_pin_config(gd32_dac->pin_name, &dac_port, &dac_pin, &dac_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
LOG_E("Failed to get pin config for %s", gd32_dac->pin_name); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* Enable clocks */ |
||||
|
rcu_periph_clock_enable(RCU_DAC); |
||||
|
rcu_periph_clock_enable(dac_periph); |
||||
|
|
||||
|
/* Configure GPIO as analog mode for DAC output */ |
||||
|
gpio_mode_set(dac_port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, dac_pin); |
||||
|
|
||||
|
LOG_D("DAC GPIO %s configured", gd32_dac->pin_name); |
||||
|
} |
||||
|
|
||||
|
static void dac_initialize(uint32_t dac_periph) |
||||
|
{ |
||||
|
/* Check if DAC is already initialized */ |
||||
|
for (int i = 0; i < sizeof(dac_init_status) / sizeof(dac_init_status[0]); i++) |
||||
|
{ |
||||
|
if (dac_init_status[i].dac_periph == dac_periph && !dac_init_status[i].initialized) |
||||
|
{ |
||||
|
/* Initialize DAC */ |
||||
|
dac_deinit(dac_periph); |
||||
|
|
||||
|
/* DAC trigger disable for both channels */ |
||||
|
dac_trigger_disable(dac_periph, gd32_dac_obj[i].channel); |
||||
|
|
||||
|
/* DAC wave mode disable for both channels */ |
||||
|
dac_wave_mode_config(dac_periph, gd32_dac_obj[i].channel, DAC_WAVE_DISABLE); |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32F10x) || defined(SOC_SERIES_GD32F20x) || defined(SOC_SERIES_GD32F30x) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32E50x) |
||||
|
/* DAC output buffer enable */ |
||||
|
dac_output_buffer_enable(dac_periph, gd32_dac_obj[i].channel); |
||||
|
#endif |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
/* DAC mode configuration - normal mode with buffer enabled */ |
||||
|
dac_mode_config(dac_periph, gd32_dac_obj[i].channel, NORMAL_PIN_BUFFON); |
||||
|
#endif |
||||
|
|
||||
|
dac_init_status[i].initialized = RT_TRUE; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel) |
||||
|
{ |
||||
|
struct gd32_dac *dac_dev = (struct gd32_dac *)device; |
||||
|
|
||||
|
/* Validate channel */ |
||||
|
if (channel != DAC_OUT0 && channel != DAC_OUT1) |
||||
|
{ |
||||
|
LOG_E("Invalid DAC channel: %d", channel); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Enable DAC channel */ |
||||
|
dac_enable(dac_dev->dac_periph, (uint8_t)channel); |
||||
|
LOG_D("DAC %s channel %d enabled", dac_dev->name, channel); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel) |
||||
|
{ |
||||
|
struct gd32_dac *dac_dev = (struct gd32_dac *)device; |
||||
|
|
||||
|
/* Validate channel */ |
||||
|
if (channel != DAC_OUT0 && channel != DAC_OUT1) |
||||
|
{ |
||||
|
LOG_E("Invalid DAC channel: %d", channel); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Disable DAC channel */ |
||||
|
dac_disable(dac_dev->dac_periph, (uint8_t)channel); |
||||
|
LOG_D("DAC %s channel %d disabled", dac_dev->name, channel); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_dac_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value) |
||||
|
{ |
||||
|
struct gd32_dac *dac_dev = (struct gd32_dac *)device; |
||||
|
|
||||
|
if (value == RT_NULL) |
||||
|
{ |
||||
|
LOG_E("DAC value pointer is NULL"); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Validate channel */ |
||||
|
if (channel != DAC_OUT0 && channel != DAC_OUT1) |
||||
|
{ |
||||
|
LOG_E("Invalid DAC channel: %d", channel); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Check value range for 12-bit DAC */ |
||||
|
if (*value > 4095) |
||||
|
{ |
||||
|
LOG_E("DAC value %u exceeds maximum 4095", *value); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
/* Set DAC data with 12-bit right aligned */ |
||||
|
dac_data_set(dac_dev->dac_periph, (uint8_t)channel, DAC_ALIGN_12B_R, (uint16_t)(*value)); |
||||
|
LOG_D("DAC %s channel %d set to value %u", dac_dev->name, channel, *value); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_dac_set_mode(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t mode) |
||||
|
{ |
||||
|
struct gd32_dac *dac_dev = (struct gd32_dac *)device; |
||||
|
|
||||
|
if (channel != DAC_OUT0 && channel != DAC_OUT1) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
dac_mode_config(dac_dev->dac_periph, channel, mode); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static struct rt_dac_ops drv_ops = { |
||||
|
.disabled = drv_dac_disabled, |
||||
|
.enabled = drv_dac_enabled, |
||||
|
.convert = drv_dac_convert, |
||||
|
}; |
||||
|
|
||||
|
static int drv_dac_init(void) |
||||
|
{ |
||||
|
int i, result = RT_EOK; |
||||
|
|
||||
|
for (i = 0; i < sizeof(gd32_dac_obj) / sizeof(gd32_dac_obj[0]); i++) |
||||
|
{ |
||||
|
/* Initialize DAC hardware - GPIO configuration */ |
||||
|
gd32_dac_hw_init(&gd32_dac_obj[i]); |
||||
|
|
||||
|
/* Initialize DAC peripheral if not already initialized */ |
||||
|
dac_initialize(gd32_dac_obj[i].dac_periph); |
||||
|
|
||||
|
/* Register DAC device */ |
||||
|
if (rt_hw_dac_register(&gd32_dac_obj[i].dac_device, gd32_dac_obj[i].name, |
||||
|
&drv_ops, RT_NULL) == RT_EOK) |
||||
|
{ |
||||
|
LOG_D("%s register success (channel %d)", |
||||
|
gd32_dac_obj[i].name, gd32_dac_obj[i].channel); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
LOG_E("%s register failed", gd32_dac_obj[i].name); |
||||
|
result = -RT_ERROR; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
INIT_DEVICE_EXPORT(drv_dac_init); |
||||
|
|
||||
|
#endif /* RT_USING_DAC */ |
||||
File diff suppressed because it is too large
@ -0,0 +1,945 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include <rtdevice.h> |
||||
|
#include <rthw.h> |
||||
|
#include <rtconfig.h> |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#ifdef RT_USING_PIN |
||||
|
|
||||
|
#include "drv_gpio.h" |
||||
|
|
||||
|
static const struct pin_index pins[] = { |
||||
|
#ifdef GPIOA |
||||
|
GD32_PIN(0, A, 0), |
||||
|
GD32_PIN(1, A, 1), |
||||
|
GD32_PIN(2, A, 2), |
||||
|
GD32_PIN(3, A, 3), |
||||
|
GD32_PIN(4, A, 4), |
||||
|
GD32_PIN(5, A, 5), |
||||
|
GD32_PIN(6, A, 6), |
||||
|
GD32_PIN(7, A, 7), |
||||
|
GD32_PIN(8, A, 8), |
||||
|
GD32_PIN(9, A, 9), |
||||
|
GD32_PIN(10, A, 10), |
||||
|
GD32_PIN(11, A, 11), |
||||
|
GD32_PIN(12, A, 12), |
||||
|
GD32_PIN(13, A, 13), |
||||
|
GD32_PIN(14, A, 14), |
||||
|
GD32_PIN(15, A, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOB |
||||
|
GD32_PIN(16, B, 0), |
||||
|
GD32_PIN(17, B, 1), |
||||
|
GD32_PIN(18, B, 2), |
||||
|
GD32_PIN(19, B, 3), |
||||
|
GD32_PIN(20, B, 4), |
||||
|
GD32_PIN(21, B, 5), |
||||
|
GD32_PIN(22, B, 6), |
||||
|
GD32_PIN(23, B, 7), |
||||
|
GD32_PIN(24, B, 8), |
||||
|
GD32_PIN(25, B, 9), |
||||
|
GD32_PIN(26, B, 10), |
||||
|
GD32_PIN(27, B, 11), |
||||
|
GD32_PIN(28, B, 12), |
||||
|
GD32_PIN(29, B, 13), |
||||
|
GD32_PIN(30, B, 14), |
||||
|
GD32_PIN(31, B, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOC |
||||
|
GD32_PIN(32, C, 0), |
||||
|
GD32_PIN(33, C, 1), |
||||
|
GD32_PIN(34, C, 2), |
||||
|
GD32_PIN(35, C, 3), |
||||
|
GD32_PIN(36, C, 4), |
||||
|
GD32_PIN(37, C, 5), |
||||
|
GD32_PIN(38, C, 6), |
||||
|
GD32_PIN(39, C, 7), |
||||
|
GD32_PIN(40, C, 8), |
||||
|
GD32_PIN(41, C, 9), |
||||
|
GD32_PIN(42, C, 10), |
||||
|
GD32_PIN(43, C, 11), |
||||
|
GD32_PIN(44, C, 12), |
||||
|
GD32_PIN(45, C, 13), |
||||
|
GD32_PIN(46, C, 14), |
||||
|
GD32_PIN(47, C, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOD |
||||
|
GD32_PIN(48, D, 0), |
||||
|
GD32_PIN(49, D, 1), |
||||
|
GD32_PIN(50, D, 2), |
||||
|
GD32_PIN(51, D, 3), |
||||
|
GD32_PIN(52, D, 4), |
||||
|
GD32_PIN(53, D, 5), |
||||
|
GD32_PIN(54, D, 6), |
||||
|
GD32_PIN(55, D, 7), |
||||
|
GD32_PIN(56, D, 8), |
||||
|
GD32_PIN(57, D, 9), |
||||
|
GD32_PIN(58, D, 10), |
||||
|
GD32_PIN(59, D, 11), |
||||
|
GD32_PIN(60, D, 12), |
||||
|
GD32_PIN(61, D, 13), |
||||
|
GD32_PIN(62, D, 14), |
||||
|
GD32_PIN(63, D, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOE |
||||
|
GD32_PIN(64, E, 0), |
||||
|
GD32_PIN(65, E, 1), |
||||
|
GD32_PIN(66, E, 2), |
||||
|
GD32_PIN(67, E, 3), |
||||
|
GD32_PIN(68, E, 4), |
||||
|
GD32_PIN(69, E, 5), |
||||
|
GD32_PIN(70, E, 6), |
||||
|
GD32_PIN(71, E, 7), |
||||
|
GD32_PIN(72, E, 8), |
||||
|
GD32_PIN(73, E, 9), |
||||
|
GD32_PIN(74, E, 10), |
||||
|
GD32_PIN(75, E, 11), |
||||
|
GD32_PIN(76, E, 12), |
||||
|
GD32_PIN(77, E, 13), |
||||
|
GD32_PIN(78, E, 14), |
||||
|
GD32_PIN(79, E, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOF |
||||
|
GD32_PIN(80, F, 0), |
||||
|
GD32_PIN(81, F, 1), |
||||
|
GD32_PIN(82, F, 2), |
||||
|
GD32_PIN(83, F, 3), |
||||
|
GD32_PIN(84, F, 4), |
||||
|
GD32_PIN(85, F, 5), |
||||
|
GD32_PIN(86, F, 6), |
||||
|
GD32_PIN(87, F, 7), |
||||
|
GD32_PIN(88, F, 8), |
||||
|
GD32_PIN(89, F, 9), |
||||
|
GD32_PIN(90, F, 10), |
||||
|
GD32_PIN(91, F, 11), |
||||
|
GD32_PIN(92, F, 12), |
||||
|
GD32_PIN(93, F, 13), |
||||
|
GD32_PIN(94, F, 14), |
||||
|
GD32_PIN(95, F, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOG |
||||
|
GD32_PIN(96, G, 0), |
||||
|
GD32_PIN(97, G, 1), |
||||
|
GD32_PIN(98, G, 2), |
||||
|
GD32_PIN(99, G, 3), |
||||
|
GD32_PIN(100, G, 4), |
||||
|
GD32_PIN(101, G, 5), |
||||
|
GD32_PIN(102, G, 6), |
||||
|
GD32_PIN(103, G, 7), |
||||
|
GD32_PIN(104, G, 8), |
||||
|
GD32_PIN(105, G, 9), |
||||
|
GD32_PIN(106, G, 10), |
||||
|
GD32_PIN(107, G, 11), |
||||
|
GD32_PIN(108, G, 12), |
||||
|
GD32_PIN(109, G, 13), |
||||
|
GD32_PIN(110, G, 14), |
||||
|
GD32_PIN(111, G, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOH |
||||
|
GD32_PIN(112, H, 0), |
||||
|
GD32_PIN(113, H, 1), |
||||
|
GD32_PIN(114, H, 2), |
||||
|
GD32_PIN(115, H, 3), |
||||
|
GD32_PIN(116, H, 4), |
||||
|
GD32_PIN(117, H, 5), |
||||
|
GD32_PIN(118, H, 6), |
||||
|
GD32_PIN(119, H, 7), |
||||
|
GD32_PIN(120, H, 8), |
||||
|
GD32_PIN(121, H, 9), |
||||
|
GD32_PIN(122, H, 10), |
||||
|
GD32_PIN(123, H, 11), |
||||
|
GD32_PIN(124, H, 12), |
||||
|
GD32_PIN(125, H, 13), |
||||
|
GD32_PIN(126, H, 14), |
||||
|
GD32_PIN(127, H, 15), |
||||
|
#endif |
||||
|
#ifdef GPIOI |
||||
|
GD32_PIN(128, I, 0), |
||||
|
GD32_PIN(129, I, 1), |
||||
|
GD32_PIN(130, I, 2), |
||||
|
GD32_PIN(131, I, 3), |
||||
|
GD32_PIN(132, I, 4), |
||||
|
GD32_PIN(133, I, 5), |
||||
|
GD32_PIN(134, I, 6), |
||||
|
GD32_PIN(135, I, 7), |
||||
|
GD32_PIN(136, I, 8), |
||||
|
GD32_PIN(137, I, 9), |
||||
|
GD32_PIN(138, I, 10), |
||||
|
GD32_PIN(139, I, 11), |
||||
|
GD32_PIN(140, I, 12), |
||||
|
GD32_PIN(141, I, 13), |
||||
|
GD32_PIN(142, I, 14), |
||||
|
GD32_PIN(143, I, 15), |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
static const struct pin_irq_map pin_irq_map[] = { |
||||
|
{ GPIO_PIN_0, EXTI0_1_IRQn }, |
||||
|
{ GPIO_PIN_1, EXTI0_1_IRQn }, |
||||
|
{ GPIO_PIN_2, EXTI2_3_IRQn }, |
||||
|
{ GPIO_PIN_3, EXTI2_3_IRQn }, |
||||
|
{ GPIO_PIN_4, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_5, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_6, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_7, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_8, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_9, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_10, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_11, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_12, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_13, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_14, EXTI4_15_IRQn }, |
||||
|
{ GPIO_PIN_15, EXTI4_15_IRQn }, |
||||
|
}; |
||||
|
#else |
||||
|
static const struct pin_irq_map pin_irq_map[] = { |
||||
|
{ GPIO_PIN_0, EXTI0_IRQn }, |
||||
|
{ GPIO_PIN_1, EXTI1_IRQn }, |
||||
|
{ GPIO_PIN_2, EXTI2_IRQn }, |
||||
|
{ GPIO_PIN_3, EXTI3_IRQn }, |
||||
|
{ GPIO_PIN_4, EXTI4_IRQn }, |
||||
|
{ GPIO_PIN_5, EXTI5_9_IRQn }, |
||||
|
{ GPIO_PIN_6, EXTI5_9_IRQn }, |
||||
|
{ GPIO_PIN_7, EXTI5_9_IRQn }, |
||||
|
{ GPIO_PIN_8, EXTI5_9_IRQn }, |
||||
|
{ GPIO_PIN_9, EXTI5_9_IRQn }, |
||||
|
{ GPIO_PIN_10, EXTI10_15_IRQn }, |
||||
|
{ GPIO_PIN_11, EXTI10_15_IRQn }, |
||||
|
{ GPIO_PIN_12, EXTI10_15_IRQn }, |
||||
|
{ GPIO_PIN_13, EXTI10_15_IRQn }, |
||||
|
{ GPIO_PIN_14, EXTI10_15_IRQn }, |
||||
|
{ GPIO_PIN_15, EXTI10_15_IRQn }, |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
struct rt_pin_irq_hdr pin_irq_hdr_tab[] = { |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
{ -1, 0, RT_NULL, RT_NULL }, |
||||
|
}; |
||||
|
|
||||
|
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) |
||||
|
|
||||
|
/**
|
||||
|
* @brief get pin |
||||
|
* @param pin |
||||
|
* @retval None |
||||
|
*/ |
||||
|
const struct pin_index *get_pin(rt_uint8_t pin) |
||||
|
{ |
||||
|
const struct pin_index *index; |
||||
|
|
||||
|
if (pin < ITEM_NUM(pins)) |
||||
|
{ |
||||
|
index = &pins[pin]; |
||||
|
if (index->index == -1) |
||||
|
index = RT_NULL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
index = RT_NULL; |
||||
|
} |
||||
|
|
||||
|
return index; |
||||
|
} |
||||
|
|
||||
|
int get_pin_config(const char *pin_name, uint32_t *port, uint32_t *pin, rcu_periph_enum *clk) |
||||
|
{ |
||||
|
if (pin_name == NULL || port == NULL || pin == NULL || clk == NULL) |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
if (strlen(pin_name) < 3 || pin_name[0] != 'P') |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
char port_letter = pin_name[1]; |
||||
|
switch (port_letter) |
||||
|
{ |
||||
|
#ifdef GPIOA |
||||
|
case 'A': |
||||
|
*port = GPIOA; |
||||
|
*clk = RCU_GPIOA; |
||||
|
break; |
||||
|
#endif /* GPIOA */ |
||||
|
#ifdef GPIOB |
||||
|
case 'B': |
||||
|
*port = GPIOB; |
||||
|
*clk = RCU_GPIOB; |
||||
|
break; |
||||
|
#endif /* GPIOB */ |
||||
|
#ifdef GPIOC |
||||
|
case 'C': |
||||
|
*port = GPIOC; |
||||
|
*clk = RCU_GPIOC; |
||||
|
break; |
||||
|
#endif /* GPIOC */ |
||||
|
#ifdef GPIOD |
||||
|
case 'D': |
||||
|
*port = GPIOD; |
||||
|
*clk = RCU_GPIOD; |
||||
|
break; |
||||
|
#endif /* GPIOD */ |
||||
|
#ifdef GPIOE |
||||
|
case 'E': |
||||
|
*port = GPIOE; |
||||
|
*clk = RCU_GPIOE; |
||||
|
break; |
||||
|
#endif /* GPIOE */ |
||||
|
#ifdef GPIOF |
||||
|
case 'F': |
||||
|
*port = GPIOF; |
||||
|
*clk = RCU_GPIOF; |
||||
|
break; |
||||
|
#endif /* GPIOF */ |
||||
|
#ifdef GPIOG |
||||
|
case 'G': |
||||
|
*port = GPIOG; |
||||
|
*clk = RCU_GPIOG; |
||||
|
break; |
||||
|
#endif /* GPIOG */ |
||||
|
#ifdef GPIOH |
||||
|
case 'H': |
||||
|
*port = GPIOH; |
||||
|
*clk = RCU_GPIOH; |
||||
|
break; |
||||
|
#endif /* GPIOH */ |
||||
|
#ifdef GPIOI |
||||
|
case 'I': |
||||
|
*port = GPIOI; |
||||
|
*clk = RCU_GPIOI; |
||||
|
break; |
||||
|
#endif /* GPIOI */ |
||||
|
#ifdef GPIOJ |
||||
|
case 'J': |
||||
|
*port = GPIOJ; |
||||
|
*clk = RCU_GPIOJ; |
||||
|
break; |
||||
|
#endif /* GPIOJ */ |
||||
|
#ifdef GPIOK |
||||
|
case 'K': |
||||
|
*port = GPIOK; |
||||
|
*clk = RCU_GPIOK; |
||||
|
break; |
||||
|
#endif /* GPIOK */ |
||||
|
default: |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
int pin_num = atoi(pin_name + 2); |
||||
|
if (pin_num < 0 || pin_num > 15) |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
*pin = GPIO_PIN_0 << pin_num; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int pin_alternate_config(const char *alternate, uint32_t *af) |
||||
|
{ |
||||
|
if (alternate == NULL || af == NULL) |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
if (alternate[0] != 'A' || alternate[1] != 'F') |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
int af_num = atoi(alternate + 2); |
||||
|
if (af_num < 0 || af_num > 15) |
||||
|
{ |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
switch (af_num) |
||||
|
{ |
||||
|
case 0: |
||||
|
*af = GPIO_AF_0; |
||||
|
break; |
||||
|
case 1: |
||||
|
*af = GPIO_AF_1; |
||||
|
break; |
||||
|
case 2: |
||||
|
*af = GPIO_AF_2; |
||||
|
break; |
||||
|
case 3: |
||||
|
*af = GPIO_AF_3; |
||||
|
break; |
||||
|
case 4: |
||||
|
*af = GPIO_AF_4; |
||||
|
break; |
||||
|
case 5: |
||||
|
*af = GPIO_AF_5; |
||||
|
break; |
||||
|
case 6: |
||||
|
*af = GPIO_AF_6; |
||||
|
break; |
||||
|
case 7: |
||||
|
*af = GPIO_AF_7; |
||||
|
break; |
||||
|
case 8: |
||||
|
*af = GPIO_AF_8; |
||||
|
break; |
||||
|
case 9: |
||||
|
*af = GPIO_AF_9; |
||||
|
break; |
||||
|
case 10: |
||||
|
*af = GPIO_AF_10; |
||||
|
break; |
||||
|
case 11: |
||||
|
*af = GPIO_AF_11; |
||||
|
break; |
||||
|
case 12: |
||||
|
*af = GPIO_AF_12; |
||||
|
break; |
||||
|
case 13: |
||||
|
*af = GPIO_AF_13; |
||||
|
break; |
||||
|
case 14: |
||||
|
*af = GPIO_AF_14; |
||||
|
break; |
||||
|
case 15: |
||||
|
*af = GPIO_AF_15; |
||||
|
break; |
||||
|
default: |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief set pin mode |
||||
|
* @param dev, pin, mode |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode) |
||||
|
{ |
||||
|
const struct pin_index *index = RT_NULL; |
||||
|
rt_uint32_t pin_mode = 0; |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
rt_uint32_t pin_pupd = 0, pin_odpp = 0; |
||||
|
#endif |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* GPIO Periph clock enable */ |
||||
|
rcu_periph_clock_enable(index->clk); |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_OUTPUT; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_OUT_PP; |
||||
|
#endif |
||||
|
|
||||
|
switch (mode) |
||||
|
{ |
||||
|
case PIN_MODE_OUTPUT: |
||||
|
/* output setting */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_OUTPUT; |
||||
|
pin_pupd = GPIO_PUPD_NONE; |
||||
|
pin_odpp = GPIO_OTYPE_PP; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_OUT_PP; |
||||
|
#endif |
||||
|
break; |
||||
|
case PIN_MODE_OUTPUT_OD: |
||||
|
/* output setting: od. */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_OUTPUT; |
||||
|
pin_pupd = GPIO_PUPD_NONE; |
||||
|
pin_odpp = GPIO_OTYPE_OD; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_OUT_OD; |
||||
|
#endif |
||||
|
break; |
||||
|
case PIN_MODE_INPUT: |
||||
|
/* input setting: not pull. */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_INPUT; |
||||
|
pin_pupd = GPIO_PUPD_PULLUP | GPIO_PUPD_PULLDOWN; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_IN_FLOATING; |
||||
|
#endif |
||||
|
break; |
||||
|
case PIN_MODE_INPUT_PULLUP: |
||||
|
/* input setting: pull up. */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_INPUT; |
||||
|
pin_pupd = GPIO_PUPD_PULLUP; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_IPU; |
||||
|
#endif |
||||
|
break; |
||||
|
case PIN_MODE_INPUT_PULLDOWN: |
||||
|
/* input setting: pull down. */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
pin_mode = GPIO_MODE_INPUT; |
||||
|
pin_pupd = GPIO_PUPD_PULLDOWN; |
||||
|
#else |
||||
|
pin_mode = GPIO_MODE_IPD; |
||||
|
#endif |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin); |
||||
|
if (pin_mode == GPIO_MODE_OUTPUT) |
||||
|
{ |
||||
|
gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_50MHZ, index->pin); |
||||
|
} |
||||
|
#elif defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin); |
||||
|
if (pin_mode == GPIO_MODE_OUTPUT) |
||||
|
{ |
||||
|
gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_60MHZ, index->pin); |
||||
|
} |
||||
|
#else |
||||
|
gpio_init(index->gpio_periph, pin_mode, GPIO_OSPEED_50MHZ, index->pin); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin write |
||||
|
* @param dev, pin, valuie |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value) |
||||
|
{ |
||||
|
const struct pin_index *index = RT_NULL; |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value); |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin read |
||||
|
* @param dev, pin |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_ssize_t gd32_pin_read(rt_device_t dev, rt_base_t pin) |
||||
|
{ |
||||
|
rt_ssize_t value = PIN_LOW; |
||||
|
const struct pin_index *index = RT_NULL; |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
value = gpio_input_bit_get(index->gpio_periph, index->pin); |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief bit2bitno |
||||
|
* @param bit |
||||
|
* @retval None |
||||
|
*/ |
||||
|
rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) |
||||
|
{ |
||||
|
rt_uint8_t i; |
||||
|
for (i = 0; i < 32; i++) |
||||
|
{ |
||||
|
if ((0x01 << i) == bit) |
||||
|
{ |
||||
|
return i; |
||||
|
} |
||||
|
} |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin write |
||||
|
* @param pinbit |
||||
|
* @retval None |
||||
|
*/ |
||||
|
rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit) |
||||
|
{ |
||||
|
rt_int32_t map_index = bit2bitno(pinbit); |
||||
|
if (map_index < 0 || map_index >= ITEM_NUM(pin_irq_map)) |
||||
|
{ |
||||
|
return RT_NULL; |
||||
|
} |
||||
|
return &pin_irq_map[map_index]; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin irq attach |
||||
|
* @param device, pin, mode |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_base_t pin, |
||||
|
rt_uint8_t mode, void (*hdr)(void *args), void *args) |
||||
|
{ |
||||
|
const struct pin_index *index = RT_NULL; |
||||
|
rt_base_t level; |
||||
|
rt_int32_t hdr_index = -1; |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
hdr_index = bit2bitno(index->pin); |
||||
|
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
level = rt_hw_interrupt_disable(); |
||||
|
if (pin_irq_hdr_tab[hdr_index].pin == pin && |
||||
|
pin_irq_hdr_tab[hdr_index].hdr == hdr && |
||||
|
pin_irq_hdr_tab[hdr_index].mode == mode && |
||||
|
pin_irq_hdr_tab[hdr_index].args == args) |
||||
|
{ |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
if (pin_irq_hdr_tab[hdr_index].pin != -1) |
||||
|
{ |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
return -RT_EFULL; |
||||
|
} |
||||
|
pin_irq_hdr_tab[hdr_index].pin = pin; |
||||
|
pin_irq_hdr_tab[hdr_index].hdr = hdr; |
||||
|
pin_irq_hdr_tab[hdr_index].mode = mode; |
||||
|
pin_irq_hdr_tab[hdr_index].args = args; |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin irq detach |
||||
|
* @param device, pin |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_base_t pin) |
||||
|
{ |
||||
|
const struct pin_index *index = RT_NULL; |
||||
|
rt_base_t level; |
||||
|
rt_int32_t hdr_index = -1; |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
hdr_index = bit2bitno(index->pin); |
||||
|
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
level = rt_hw_interrupt_disable(); |
||||
|
if (pin_irq_hdr_tab[hdr_index].pin == -1) |
||||
|
{ |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
pin_irq_hdr_tab[hdr_index].pin = -1; |
||||
|
pin_irq_hdr_tab[hdr_index].hdr = RT_NULL; |
||||
|
pin_irq_hdr_tab[hdr_index].mode = 0; |
||||
|
pin_irq_hdr_tab[hdr_index].args = RT_NULL; |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin irq enable |
||||
|
* @param device, pin, enabled |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled) |
||||
|
{ |
||||
|
const struct pin_index *index; |
||||
|
const struct pin_irq_map *irqmap; |
||||
|
rt_base_t level; |
||||
|
rt_int32_t hdr_index = -1; |
||||
|
exti_trig_type_enum trigger_mode; |
||||
|
|
||||
|
index = get_pin(pin); |
||||
|
if (index == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
if (enabled == PIN_IRQ_ENABLE) |
||||
|
{ |
||||
|
hdr_index = bit2bitno(index->pin); |
||||
|
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
level = rt_hw_interrupt_disable(); |
||||
|
if (pin_irq_hdr_tab[hdr_index].pin == -1) |
||||
|
{ |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
irqmap = &pin_irq_map[hdr_index]; |
||||
|
|
||||
|
switch (pin_irq_hdr_tab[hdr_index].mode) |
||||
|
{ |
||||
|
case PIN_IRQ_MODE_RISING: |
||||
|
trigger_mode = EXTI_TRIG_RISING; |
||||
|
break; |
||||
|
case PIN_IRQ_MODE_FALLING: |
||||
|
trigger_mode = EXTI_TRIG_FALLING; |
||||
|
break; |
||||
|
case PIN_IRQ_MODE_RISING_FALLING: |
||||
|
trigger_mode = EXTI_TRIG_BOTH; |
||||
|
break; |
||||
|
default: |
||||
|
rt_hw_interrupt_enable(level); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx |
||||
|
rcu_periph_clock_enable(RCU_SYSCFG); |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
rcu_periph_clock_enable(RCU_CFGCMP); |
||||
|
#else |
||||
|
rcu_periph_clock_enable(RCU_AF); |
||||
|
#endif |
||||
|
|
||||
|
/* enable and set interrupt priority */ |
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
nvic_irq_enable(irqmap->irqno, 5U); |
||||
|
#else |
||||
|
nvic_irq_enable(irqmap->irqno, 5U, 0U); |
||||
|
#endif |
||||
|
/* connect EXTI line to GPIO pin */ |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x |
||||
|
syscfg_exti_line_config(index->port_src, index->pin_src); |
||||
|
#else |
||||
|
gpio_exti_source_select(index->port_src, index->pin_src); |
||||
|
#endif |
||||
|
|
||||
|
/* configure EXTI line */ |
||||
|
exti_init((exti_line_enum)(index->exit_line), EXTI_INTERRUPT, trigger_mode); |
||||
|
exti_interrupt_flag_clear((exti_line_enum)(index->exit_line)); |
||||
|
|
||||
|
rt_hw_interrupt_enable(level); |
||||
|
} |
||||
|
else if (enabled == PIN_IRQ_DISABLE) |
||||
|
{ |
||||
|
irqmap = get_pin_irq_map(index->pin); |
||||
|
if (irqmap == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
nvic_irq_disable(irqmap->irqno); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
const static struct rt_pin_ops gd32_pin_ops = { |
||||
|
.pin_mode = gd32_pin_mode, |
||||
|
.pin_write = gd32_pin_write, |
||||
|
.pin_read = gd32_pin_read, |
||||
|
.pin_attach_irq = gd32_pin_attach_irq, |
||||
|
.pin_detach_irq = gd32_pin_detach_irq, |
||||
|
.pin_irq_enable = gd32_pin_irq_enable, |
||||
|
RT_NULL, |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief pin write |
||||
|
* @param irqno |
||||
|
* @retval None |
||||
|
*/ |
||||
|
rt_inline void pin_irq_hdr(int irqno) |
||||
|
{ |
||||
|
if (pin_irq_hdr_tab[irqno].hdr) |
||||
|
{ |
||||
|
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief gd32 exit interrupt |
||||
|
* @param exti_line |
||||
|
* @retval None |
||||
|
*/ |
||||
|
void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line) |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
exti_line_enum pin_exti_line = exti_line; |
||||
|
#else |
||||
|
exti_line_enum pin_exti_line = 1 << exti_line; |
||||
|
#endif |
||||
|
|
||||
|
if (RESET != exti_interrupt_flag_get(pin_exti_line)) |
||||
|
{ |
||||
|
pin_irq_hdr(exti_line); |
||||
|
exti_interrupt_flag_clear(pin_exti_line); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
void EXTI0_1_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
GD32_GPIO_EXTI_IRQHandler(0); |
||||
|
GD32_GPIO_EXTI_IRQHandler(1); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI2_3_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
GD32_GPIO_EXTI_IRQHandler(2); |
||||
|
GD32_GPIO_EXTI_IRQHandler(3); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI4_15_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
GD32_GPIO_EXTI_IRQHandler(4); |
||||
|
GD32_GPIO_EXTI_IRQHandler(5); |
||||
|
GD32_GPIO_EXTI_IRQHandler(6); |
||||
|
GD32_GPIO_EXTI_IRQHandler(7); |
||||
|
GD32_GPIO_EXTI_IRQHandler(8); |
||||
|
GD32_GPIO_EXTI_IRQHandler(9); |
||||
|
GD32_GPIO_EXTI_IRQHandler(10); |
||||
|
GD32_GPIO_EXTI_IRQHandler(11); |
||||
|
GD32_GPIO_EXTI_IRQHandler(12); |
||||
|
GD32_GPIO_EXTI_IRQHandler(13); |
||||
|
GD32_GPIO_EXTI_IRQHandler(14); |
||||
|
GD32_GPIO_EXTI_IRQHandler(15); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#else |
||||
|
void EXTI0_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(0); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI1_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(1); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI2_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(2); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI3_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(3); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI4_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(4); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI5_9_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(5); |
||||
|
GD32_GPIO_EXTI_IRQHandler(6); |
||||
|
GD32_GPIO_EXTI_IRQHandler(7); |
||||
|
GD32_GPIO_EXTI_IRQHandler(8); |
||||
|
GD32_GPIO_EXTI_IRQHandler(9); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
void EXTI10_15_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
GD32_GPIO_EXTI_IRQHandler(10); |
||||
|
GD32_GPIO_EXTI_IRQHandler(11); |
||||
|
GD32_GPIO_EXTI_IRQHandler(12); |
||||
|
GD32_GPIO_EXTI_IRQHandler(13); |
||||
|
GD32_GPIO_EXTI_IRQHandler(14); |
||||
|
GD32_GPIO_EXTI_IRQHandler(15); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
int rt_hw_pin_init(void) |
||||
|
{ |
||||
|
int result; |
||||
|
|
||||
|
result = rt_device_pin_register("pin", &gd32_pin_ops, RT_NULL); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
INIT_BOARD_EXPORT(rt_hw_pin_init); |
||||
|
|
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,278 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-02-25 iysheng first version |
||||
|
* 2025-10-22 kurisaw optimized configuration |
||||
|
*/ |
||||
|
|
||||
|
#include <board.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include "drv_hwtimer.h" |
||||
|
#include "hwtimer_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_HWTIMER |
||||
|
|
||||
|
/*
|
||||
|
* static void __set_timerx_freq |
||||
|
* Set freq with timerx |
||||
|
* |
||||
|
* @param timerx the pointer of TIMER_TypeDef |
||||
|
* @param freq of the timer clock |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void __set_timerx_freq(uint32_t timerx, uint32_t freq) |
||||
|
{ |
||||
|
uint32_t ap1freq, ap2freq; |
||||
|
uint16_t prescaler; |
||||
|
uint32_t temp; |
||||
|
uint32_t timesel; |
||||
|
uint32_t APBPSC_limit; |
||||
|
uint32_t multiple; |
||||
|
timesel = RCU_CFG1 & RCU_CFG1_TIMERSEL; |
||||
|
if (timesel == 0) |
||||
|
{ |
||||
|
multiple = 2; |
||||
|
APBPSC_limit = 0b100; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
multiple = 4; |
||||
|
APBPSC_limit = 0b101; |
||||
|
} |
||||
|
/* APB1 */ |
||||
|
if (!(timerx & (1 << 16))) |
||||
|
{ |
||||
|
ap1freq = rcu_clock_freq_get(CK_APB1); |
||||
|
/* Check if APB1 is divided */ |
||||
|
temp = RCU_CFG0 & RCU_CFG0_APB1PSC; |
||||
|
temp >>= (__builtin_ctz(temp)); |
||||
|
/* When the division factor is less than expected, the clock frequency equals AHB clock, otherwise needs multiplication */ |
||||
|
prescaler = (temp <= APBPSC_limit) ? (rcu_clock_freq_get(CK_AHB) / freq - 1) : ((ap1freq * multiple) / freq - 1); |
||||
|
} |
||||
|
else /* APB2 */ |
||||
|
{ |
||||
|
ap2freq = rcu_clock_freq_get(CK_APB2); |
||||
|
/* Check if APB2 is divided */ |
||||
|
temp = RCU_CFG0 & RCU_CFG0_APB2PSC; |
||||
|
temp >>= (__builtin_ctz(temp)); |
||||
|
/* When the division factor is less than expected, the clock frequency equals AHB clock, otherwise needs multiplication */ |
||||
|
prescaler = (temp <= APBPSC_limit) ? (rcu_clock_freq_get(CK_AHB) / freq - 1) : ((ap2freq * multiple) / freq - 1); |
||||
|
} |
||||
|
timer_prescaler_config(timerx, prescaler, TIMER_PSC_RELOAD_NOW); |
||||
|
} |
||||
|
|
||||
|
static void gd32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) |
||||
|
{ |
||||
|
uint32_t timer_base = (uint32_t)timer->parent.user_data; |
||||
|
timer_parameter_struct initpara; |
||||
|
if (state) |
||||
|
{ |
||||
|
/* Set internal clock source */ |
||||
|
timer_internal_clock_config(timer_base); |
||||
|
/* Initialize timer configuration */ |
||||
|
timer_struct_para_init(&initpara); |
||||
|
/* Set maximum timer period */ |
||||
|
initpara.period = timer->info->maxcnt; |
||||
|
/* Configure timer */ |
||||
|
timer_init(timer_base, &initpara); |
||||
|
/* Set timer input frequency */ |
||||
|
__set_timerx_freq(timer_base, timer->info->maxfreq); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd32_hwtimer_start(struct rt_hwtimer_device *timer, |
||||
|
rt_uint32_t cnt, rt_hwtimer_mode_t mode) |
||||
|
{ |
||||
|
uint32_t timer_base = (uint32_t)timer->parent.user_data; |
||||
|
if (mode == HWTIMER_MODE_ONESHOT) |
||||
|
{ |
||||
|
timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_SINGLE); |
||||
|
} |
||||
|
else if (mode == HWTIMER_MODE_PERIOD) |
||||
|
{ |
||||
|
timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_REPETITIVE); |
||||
|
} |
||||
|
/* Reset timer count value */ |
||||
|
timer_counter_value_config(timer_base, 0); |
||||
|
/* Set timer auto-reload value */ |
||||
|
timer_autoreload_value_config(timer_base, cnt - 1); |
||||
|
/* Enable timer */ |
||||
|
timer_enable(timer_base); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static void gd32_hwtimer_stop(struct rt_hwtimer_device *timer) |
||||
|
{ |
||||
|
uint32_t timer_base = (uint32_t)timer->parent.user_data; |
||||
|
timer_disable(timer_base); |
||||
|
} |
||||
|
|
||||
|
static rt_uint32_t gd32_hwtimer_count_get(struct rt_hwtimer_device *timer) |
||||
|
{ |
||||
|
uint32_t timer_base = (uint32_t)timer->parent.user_data; |
||||
|
rt_uint32_t count; |
||||
|
count = timer_counter_read(timer_base); |
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, |
||||
|
void *args) |
||||
|
{ |
||||
|
int ret = RT_EOK; |
||||
|
rt_int32_t freq; |
||||
|
switch (cmd) |
||||
|
{ |
||||
|
case HWTIMER_CTRL_FREQ_SET: |
||||
|
freq = *(rt_uint32_t *)args; |
||||
|
__set_timerx_freq((uint32_t)timer->parent.user_data, freq); |
||||
|
break; |
||||
|
default: |
||||
|
rt_kprintf("invalid cmd:%x\n", cmd); |
||||
|
ret = -RT_EINVAL; |
||||
|
break; |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
static const struct rt_hwtimer_ops g_gd32_hwtimer_ops = { |
||||
|
gd32_hwtimer_init, |
||||
|
gd32_hwtimer_start, |
||||
|
gd32_hwtimer_stop, |
||||
|
gd32_hwtimer_count_get, |
||||
|
gd32_hwtimer_control, |
||||
|
}; |
||||
|
|
||||
|
static gd32_hwtimer_device g_gd32_hwtimer[] = { |
||||
|
#ifdef BSP_USING_HWTIMER0 |
||||
|
HWTIMER0_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER1 |
||||
|
HWTIMER1_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER2 |
||||
|
HWTIMER2_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER3 |
||||
|
HWTIMER3_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER4 |
||||
|
HWTIMER4_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER5 |
||||
|
HWTIMER5_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER6 |
||||
|
HWTIMER6_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER7 |
||||
|
HWTIMER7_CONFIG, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER0 |
||||
|
void TIMER0_UP_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER1 |
||||
|
void TIMER1_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER2 |
||||
|
void TIMER2_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER3 |
||||
|
void TIMER3_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER4 |
||||
|
void TIMER4_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER5 |
||||
|
void TIMER5_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER6 |
||||
|
void TIMER6_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER7 |
||||
|
void TIMER7_UP_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev); |
||||
|
timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev.parent.user_data, TIMER_INT_UP); |
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
static int rt_hwtimer_init(void) |
||||
|
{ |
||||
|
int ret = 0, i = 0; |
||||
|
for (; i < sizeof(g_gd32_hwtimer) / sizeof(g_gd32_hwtimer[0]); i++) |
||||
|
{ |
||||
|
g_gd32_hwtimer[i].hwtimer_dev.ops = &g_gd32_hwtimer_ops; |
||||
|
g_gd32_hwtimer[i].hwtimer_dev.info = &g_gd32_hwtimer[i].hwtimer_info; |
||||
|
/* Enable clock */ |
||||
|
rcu_periph_clock_enable(g_gd32_hwtimer[i].hw_data.rcu); |
||||
|
/* Set timer interrupt priority */ |
||||
|
NVIC_SetPriority(g_gd32_hwtimer[i].hw_data.irqn, 0); |
||||
|
/* Enable NVIC */ |
||||
|
NVIC_EnableIRQ(g_gd32_hwtimer[i].hw_data.irqn); |
||||
|
/* Enable timer interrupt */ |
||||
|
timer_interrupt_enable(g_gd32_hwtimer[i].hw_data.reg_base, TIMER_INT_UP); |
||||
|
/* Register device to system */ |
||||
|
ret = rt_device_hwtimer_register(&g_gd32_hwtimer[i].hwtimer_dev, |
||||
|
g_gd32_hwtimer[i].dev_name, (void *)g_gd32_hwtimer[i].hw_data.reg_base); |
||||
|
if (RT_EOK != ret) |
||||
|
{ |
||||
|
rt_kprintf("failed register %s, err=%d\n", g_gd32_hwtimer[i].dev_name, |
||||
|
ret); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
INIT_BOARD_EXPORT(rt_hwtimer_init); |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,622 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-12-20 BruceOu the first version |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_i2c.h" |
||||
|
#include "i2c_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_I2C |
||||
|
|
||||
|
#define DBG_TAG "drv.i2c" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && \ |
||||
|
!defined(BSP_USING_I2C4) && !defined(BSP_USING_I2C5) |
||||
|
#error "Please define at least one BSP_USING_I2Cx" |
||||
|
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ |
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_I2C0) |
||||
|
struct rt_i2c_bus_device i2c0; |
||||
|
#endif /* BSP_USING_I2C0 */ |
||||
|
|
||||
|
#if defined(BSP_USING_I2C1) |
||||
|
struct rt_i2c_bus_device i2c1; |
||||
|
#endif /* BSP_USING_I2C1 */ |
||||
|
|
||||
|
#if defined(BSP_USING_I2C2) |
||||
|
struct rt_i2c_bus_device i2c2; |
||||
|
#endif /* BSP_USING_I2C2 */ |
||||
|
|
||||
|
#if defined(BSP_USING_I2C3) |
||||
|
struct rt_i2c_bus_device i2c3; |
||||
|
#endif /* BSP_USING_I2C3 */ |
||||
|
|
||||
|
#if defined(BSP_USING_I2C4) |
||||
|
struct rt_i2c_bus_device i2c4; |
||||
|
#endif /* BSP_USING_I2C4 */ |
||||
|
|
||||
|
#if defined(BSP_USING_I2C5) |
||||
|
struct rt_i2c_bus_device i2c5; |
||||
|
#endif /* BSP_USING_I2C5 */ |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32F5xx) |
||||
|
#define i2c_flag_get_gd i2c_add_flag_get |
||||
|
#define i2c_timing_config_gd i2c_add_timing_config |
||||
|
#define i2c_master_clock_config_gd i2c_add_master_clock_config |
||||
|
#define i2c_enable_gd i2c_add_enable |
||||
|
#define i2c_flag_clear_gd i2c_add_flag_clear |
||||
|
#define i2c_stop_on_bus_gd i2c_add_stop_on_bus |
||||
|
#define i2c_transfer_byte_number_config_gd i2c_add_transfer_byte_number_config |
||||
|
#define i2c_start_on_bus_gd i2c_add_start_on_bus |
||||
|
#define i2c_address10_enable_gd i2c_add_address10_enable |
||||
|
#define i2c_address10_disable_gd i2c_add_address10_disable |
||||
|
#define i2c_master_addressing_gd i2c_add_master_addressing |
||||
|
#define i2c_data_transmit_gd i2c_add_data_transmit |
||||
|
#define i2c_data_receive_gd i2c_add_data_receive |
||||
|
|
||||
|
#define I2C_FLAG_RBNE_GD I2C_ADD_FLAG_RBNE |
||||
|
#define I2C_STAT_GD I2C_ADD_STAT |
||||
|
#define I2C_STAT_TBE_GD I2C_ADD_STAT_TBE |
||||
|
#define I2C_STAT_TI_GD I2C_ADD_STAT_TI |
||||
|
#define I2C_MASTER_RECEIVE_GD I2C_ADD_MASTER_RECEIVE |
||||
|
#define I2C_MASTER_TRANSMIT_GD I2C_ADD_MASTER_TRANSMIT |
||||
|
#define I2C_FLAG_I2CBSY_GD I2C_ADD_FLAG_I2CBSY |
||||
|
#define I2C_FLAG_TC_GD I2C_ADD_FLAG_TC |
||||
|
#define I2C_FLAG_TI_GD I2C_ADD_FLAG_TI |
||||
|
#define I2C_FLAG_STPDET_GD I2C_ADD_FLAG_STPDET |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
#define i2c_flag_get_gd i2c_flag_get |
||||
|
#define i2c_timing_config_gd i2c_timing_config |
||||
|
#define i2c_master_clock_config_gd i2c_master_clock_config |
||||
|
#define i2c_enable_gd i2c_enable |
||||
|
#define i2c_flag_clear_gd i2c_flag_clear |
||||
|
#define i2c_data_receive_gd i2c_data_receive |
||||
|
#define i2c_data_transmit_gd i2c_data_transmit |
||||
|
#define i2c_address10_enable_gd i2c_address10_enable |
||||
|
#define i2c_address10_disable_gd i2c_address10_disable |
||||
|
#define i2c_master_addressing_gd i2c_master_addressing |
||||
|
#define i2c_transfer_byte_number_config_gd i2c_transfer_byte_number_config |
||||
|
#define i2c_start_on_bus_gd i2c_start_on_bus |
||||
|
#define i2c_stop_on_bus_gd i2c_stop_on_bus |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32E51x) |
||||
|
|
||||
|
#undef i2c_flag_get_gd |
||||
|
#undef i2c_flag_clear_gd |
||||
|
#undef i2c_master_addressing_gd |
||||
|
#define i2c_flag_get_gd i2c2_flag_get |
||||
|
#define i2c_flag_clear_gd i2c2_flag_clear |
||||
|
#define i2c_master_addressing_gd i2c2_master_addressing |
||||
|
|
||||
|
#undef I2C_STAT_GD |
||||
|
#undef I2C_STAT_TBE_GD |
||||
|
#undef I2C_STAT_TI_GD |
||||
|
#define I2C_STAT_GD I2C2_STAT |
||||
|
#define I2C_STAT_TBE_GD I2C2_STAT_TBE |
||||
|
#define I2C_STAT_TI_GD I2C2_STAT_TI |
||||
|
|
||||
|
#undef I2C_MASTER_RECEIVE_GD |
||||
|
#undef I2C_MASTER_TRANSMIT_GD |
||||
|
#define I2C_MASTER_RECEIVE_GD I2C2_MASTER_RECEIVE |
||||
|
#define I2C_MASTER_TRANSMIT_GD I2C2_MASTER_TRANSMIT |
||||
|
|
||||
|
#undef I2C_FLAG_RBNE_GD |
||||
|
#undef I2C_FLAG_I2CBSY_GD |
||||
|
#undef I2C_FLAG_TC_GD |
||||
|
#undef I2C_FLAG_TI_GD |
||||
|
#undef I2C_FLAG_STPDET_GD |
||||
|
#define I2C_FLAG_RBNE_GD I2C2_FLAG_RBNE |
||||
|
#define I2C_FLAG_I2CBSY_GD I2C2_FLAG_I2CBSY |
||||
|
#define I2C_FLAG_TC_GD I2C2_FLAG_TC |
||||
|
#define I2C_FLAG_TI_GD I2C2_FLAG_TI |
||||
|
#define I2C_FLAG_STPDET_GD I2C2_FLAG_STPDET |
||||
|
/* also needed in write path */ |
||||
|
#define I2C_FLAG_TBE_GD I2C2_FLAG_TBE |
||||
|
|
||||
|
#else |
||||
|
#define I2C_FLAG_RBNE_GD I2C_FLAG_RBNE |
||||
|
#define I2C_STAT_GD I2C_STAT |
||||
|
#define I2C_STAT_TBE_GD I2C_STAT_TBE |
||||
|
#define I2C_STAT_TI_GD I2C_STAT_TI |
||||
|
#define I2C_MASTER_RECEIVE_GD I2C_MASTER_RECEIVE |
||||
|
#define I2C_MASTER_TRANSMIT_GD I2C_MASTER_TRANSMIT |
||||
|
#define I2C_FLAG_I2CBSY_GD I2C_FLAG_I2CBSY |
||||
|
#define I2C_FLAG_TC_GD I2C_FLAG_TC |
||||
|
#define I2C_FLAG_TI_GD I2C_FLAG_TI |
||||
|
#define I2C_FLAG_STPDET_GD I2C_FLAG_STPDET |
||||
|
/* used in write path */ |
||||
|
#define I2C_FLAG_TBE_GD I2C_FLAG_TBE |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32F5xx) |
||||
|
#define IS_I2C_LEGACY(periph) ((periph) == I2C0 || (periph) == I2C1 || (periph) == I2C2) |
||||
|
#elif defined(SOC_SERIES_GD32F4xx) |
||||
|
#define IS_I2C_LEGACY(periph) (1) |
||||
|
#elif defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) |
||||
|
#define IS_I2C_LEGACY(periph) (0) |
||||
|
#elif defined(SOC_SERIES_GD32E51x) |
||||
|
#define IS_I2C_LEGACY(periph) ((periph) == I2C0 || (periph) == I2C1) |
||||
|
#endif |
||||
|
|
||||
|
static const struct gd32_i2c_bus gd_i2c_config[] = { |
||||
|
#ifdef BSP_USING_I2C0 |
||||
|
I2C0_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_I2C1 |
||||
|
I2C1_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_I2C2 |
||||
|
I2C2_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_I2C3 |
||||
|
I2C3_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_I2C4 |
||||
|
I2C4_CONFIG, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_I2C5 |
||||
|
I2C5_CONFIG, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief This function initializes the i2c pin. |
||||
|
* @param i2c |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void gd32_i2c_gpio_init(const struct gd32_i2c_bus *i2c) |
||||
|
{ |
||||
|
rt_uint32_t scl_port, sda_port; |
||||
|
rt_uint32_t scl_pin, sda_pin; |
||||
|
rt_uint32_t pin_af; |
||||
|
rcu_periph_enum scl_periph, sda_periph; |
||||
|
|
||||
|
if (get_pin_config(i2c->scl_pin_name, &scl_port, &scl_pin, &scl_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (get_pin_config(i2c->sda_pin_name, &sda_port, &sda_pin, &sda_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
pin_alternate_config(i2c->alternate, &pin_af); |
||||
|
|
||||
|
/* enable I2C and GPIO clock */ |
||||
|
rcu_periph_clock_enable(scl_periph); |
||||
|
rcu_periph_clock_enable(sda_periph); |
||||
|
rcu_periph_clock_enable(i2c->per_clk); |
||||
|
|
||||
|
/* configure I2C_SCL as alternate function push-pull */ |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32E51x) |
||||
|
|
||||
|
gpio_init(scl_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, scl_pin); |
||||
|
gpio_init(sda_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, sda_pin); |
||||
|
|
||||
|
if (!IS_I2C_LEGACY(i2c->i2c_periph)) |
||||
|
{ |
||||
|
rcu_periph_clock_enable(RCU_AF); |
||||
|
gpio_afio_port_config(AFIO_PA8_I2C2_CFG, ENABLE); |
||||
|
gpio_afio_port_config(AFIO_PC9_I2C2_CFG, ENABLE); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
i2c_deinit(i2c->i2c_periph); |
||||
|
} |
||||
|
|
||||
|
/* configure remap function */ |
||||
|
if (i2c->i2c_remap != 0) |
||||
|
{ |
||||
|
rcu_periph_clock_enable(RCU_AF); |
||||
|
gpio_pin_remap_config(i2c->i2c_remap, ENABLE); |
||||
|
} |
||||
|
|
||||
|
gpio_init(scl_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, scl_pin); |
||||
|
gpio_init(sda_port, GPIO_MODE_AF_OD, GPIO_OSPEED_10MHZ, sda_pin); |
||||
|
|
||||
|
/* configure alternate1 function */ |
||||
|
if (pin_af != 0 || pin_af != 0) |
||||
|
{ |
||||
|
rcu_periph_clock_enable(RCU_AF); |
||||
|
gpio_afio_port_config(pin_af, ENABLE); |
||||
|
gpio_afio_port_config(pin_af, ENABLE); |
||||
|
} |
||||
|
|
||||
|
i2c_deinit(i2c->i2c_periph); |
||||
|
|
||||
|
#else |
||||
|
gpio_af_set(scl_port, pin_af, scl_pin); |
||||
|
gpio_mode_set(scl_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, scl_pin); |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
gpio_output_options_set(scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, scl_pin); |
||||
|
/* configure I2C_SDA as alternate function push-pull */ |
||||
|
gpio_af_set(sda_port, pin_af, sda_pin); |
||||
|
gpio_mode_set(sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, sda_pin); |
||||
|
gpio_output_options_set(sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, sda_pin); |
||||
|
#else |
||||
|
gpio_output_options_set(scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, scl_pin); |
||||
|
/* configure I2C_SDA as alternate function push-pull */ |
||||
|
gpio_af_set(sda_port, pin_af, sda_pin); |
||||
|
gpio_mode_set(sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, sda_pin); |
||||
|
gpio_output_options_set(sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, sda_pin); |
||||
|
#endif |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief read data. |
||||
|
* @param i2c_periph |
||||
|
* @param *p_buffer |
||||
|
* @param data_byte |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static uint8_t gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint8_t *p_buffer, rt_uint16_t data_byte) |
||||
|
{ |
||||
|
if (data_byte == 0) |
||||
|
return 1; |
||||
|
/* while there is data to be read */ |
||||
|
|
||||
|
while (data_byte) |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (IS_I2C_LEGACY(i2c_periph)) |
||||
|
{ |
||||
|
if (3 == data_byte) |
||||
|
{ |
||||
|
/* wait until BTC bit is set */ |
||||
|
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)) |
||||
|
; |
||||
|
/* disable acknowledge */ |
||||
|
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE); |
||||
|
} |
||||
|
|
||||
|
if (2 == data_byte) |
||||
|
{ |
||||
|
/* wait until BTC bit is set */ |
||||
|
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)) |
||||
|
; |
||||
|
/* send a stop condition to I2C bus */ |
||||
|
i2c_stop_on_bus(i2c_periph); |
||||
|
} |
||||
|
/* wait until RBNE bit is set */ |
||||
|
if (i2c_flag_get(i2c_periph, I2C_FLAG_RBNE)) |
||||
|
{ |
||||
|
/* read a byte from the EEPROM */ |
||||
|
*p_buffer = i2c_data_receive(i2c_periph); |
||||
|
/* point to the next location where the byte read will be saved */ |
||||
|
p_buffer++; |
||||
|
/* decrement the read bytes counter */ |
||||
|
data_byte--; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
/* wait until the RBNE bit is set */ |
||||
|
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_RBNE_GD)) |
||||
|
; |
||||
|
|
||||
|
/* read a byte */ |
||||
|
*p_buffer = i2c_data_receive_gd(i2c_periph); |
||||
|
/* point to the next location where the byte read will be saved */ |
||||
|
p_buffer++; |
||||
|
/* decrement the read bytes counter */ |
||||
|
data_byte--; |
||||
|
} |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief write data. |
||||
|
* @param i2c_periph |
||||
|
* @param *p_buffer |
||||
|
* @param data_byte |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static uint8_t gd32_i2c_write(rt_uint32_t i2c_periph, uint8_t *p_buffer, uint16_t data_byte) |
||||
|
{ |
||||
|
if (data_byte == 0) |
||||
|
return 1; |
||||
|
|
||||
|
while (data_byte) |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (IS_I2C_LEGACY(i2c_periph)) |
||||
|
{ |
||||
|
/* data transmission */ |
||||
|
i2c_data_transmit(i2c_periph, *p_buffer); |
||||
|
/* point to the next byte to be written */ |
||||
|
p_buffer++; |
||||
|
/* decrement the write bytes counter */ |
||||
|
data_byte--; |
||||
|
/* wait until the TI bit is set */ |
||||
|
while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)) |
||||
|
; |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x) |
||||
|
/* wait until the transmit data buffer is empty */ |
||||
|
I2C_STAT_GD(i2c_periph) |= I2C_STAT_TBE_GD; |
||||
|
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_TBE)) |
||||
|
; |
||||
|
|
||||
|
while (data_byte) |
||||
|
{ |
||||
|
/* wait until the TI bit is set */ |
||||
|
while (!i2c_flag_get_gd(i2c_periph, I2C_FLAG_TI_GD)) |
||||
|
; |
||||
|
/* data transmission */ |
||||
|
i2c_data_transmit(i2c_periph, *p_buffer); |
||||
|
/* point to the next byte to be written */ |
||||
|
p_buffer++; |
||||
|
/* decrement the write bytes counter */ |
||||
|
data_byte--; |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (data_byte != 0) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) |
||||
|
{ |
||||
|
static struct rt_i2c_msg *msg; |
||||
|
|
||||
|
rt_uint32_t i, w_total_byte = 0, r_total_byte = 0; |
||||
|
rt_err_t ret = RT_ERROR; |
||||
|
|
||||
|
RT_ASSERT(bus != RT_NULL); |
||||
|
|
||||
|
struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus->priv; |
||||
|
|
||||
|
for (i = 0; i < num; i++) |
||||
|
{ |
||||
|
msg = &msgs[i]; |
||||
|
|
||||
|
if (msg->flags & RT_I2C_RD) |
||||
|
{ |
||||
|
r_total_byte += msg->len; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
w_total_byte += msg->len; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (i = 0; i < num; i++) |
||||
|
{ |
||||
|
msg = &msgs[i]; |
||||
|
if (!(msg->flags & RT_I2C_NO_START)) |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (IS_I2C_LEGACY(gd32_i2c->i2c_periph)) |
||||
|
{ |
||||
|
if (msg->flags & RT_I2C_RD) |
||||
|
{ |
||||
|
if (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)) |
||||
|
{ |
||||
|
i2c_stop_on_bus(gd32_i2c->i2c_periph); |
||||
|
} |
||||
|
/* enable acknowledge */ |
||||
|
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_ENABLE); |
||||
|
/* i2c master sends start signal only when the bus is idle */ |
||||
|
while (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)) |
||||
|
; |
||||
|
/* send the start signal */ |
||||
|
i2c_start_on_bus(gd32_i2c->i2c_periph); |
||||
|
/* i2c master sends START signal successfully */ |
||||
|
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND)) |
||||
|
; |
||||
|
|
||||
|
i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_RECEIVER); |
||||
|
|
||||
|
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND)) |
||||
|
; |
||||
|
/* address flag set means i2c slave sends ACK */ |
||||
|
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* configure slave address */ |
||||
|
while (i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY)) |
||||
|
; |
||||
|
//i2c_transfer_byte_number_config(gd32_i2c->i2c_periph, w_total_byte);
|
||||
|
/* send a start condition to I2C bus */ |
||||
|
i2c_start_on_bus(gd32_i2c->i2c_periph); |
||||
|
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND)) |
||||
|
; |
||||
|
|
||||
|
i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_TRANSMITTER); |
||||
|
while (!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND)) |
||||
|
; |
||||
|
|
||||
|
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (msg->flags & RT_I2C_ADDR_10BIT) |
||||
|
{ |
||||
|
/* enable 10-bit addressing mode in master mode */ |
||||
|
i2c_address10_enable_gd(gd32_i2c->i2c_periph); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* disable 10-bit addressing mode in master mode */ |
||||
|
i2c_address10_disable_gd(gd32_i2c->i2c_periph); |
||||
|
} |
||||
|
|
||||
|
if (msg->flags & RT_I2C_RD) |
||||
|
{ |
||||
|
/* configure slave address */ |
||||
|
i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_RECEIVE_GD); |
||||
|
|
||||
|
i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, r_total_byte); |
||||
|
/* send a start condition to I2C bus */ |
||||
|
i2c_start_on_bus_gd(gd32_i2c->i2c_periph); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* configure slave address */ |
||||
|
i2c_master_addressing_gd(gd32_i2c->i2c_periph, msg->addr, I2C_MASTER_TRANSMIT_GD); |
||||
|
while (i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY_GD)) |
||||
|
; |
||||
|
i2c_transfer_byte_number_config_gd(gd32_i2c->i2c_periph, w_total_byte); |
||||
|
/* send a start condition to I2C bus */ |
||||
|
i2c_start_on_bus_gd(gd32_i2c->i2c_periph); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (msg->flags & RT_I2C_RD) |
||||
|
{ |
||||
|
if (gd32_i2c_read(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0) |
||||
|
{ |
||||
|
LOG_E("i2c bus read failed,i2c bus stop!"); |
||||
|
goto out; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (gd32_i2c_write(gd32_i2c->i2c_periph, msg->buf, msg->len) != 0) |
||||
|
{ |
||||
|
LOG_E("i2c bus write failed,i2c bus stop!"); |
||||
|
goto out; |
||||
|
} |
||||
|
} |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (!IS_I2C_LEGACY(gd32_i2c->i2c_periph)) |
||||
|
{ |
||||
|
if (r_total_byte != 0) |
||||
|
{ |
||||
|
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD)) |
||||
|
; |
||||
|
} |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
ret = i; |
||||
|
|
||||
|
out: |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (IS_I2C_LEGACY(gd32_i2c->i2c_periph)) |
||||
|
{ |
||||
|
if (!(msg->flags & RT_I2C_NO_STOP)) |
||||
|
{ |
||||
|
if (msg->flags & RT_I2C_RD) |
||||
|
{ |
||||
|
while ((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP)) |
||||
|
; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* send a stop condition to I2C bus */ |
||||
|
i2c_stop_on_bus(gd32_i2c->i2c_periph); |
||||
|
/* wait until stop condition generate */ |
||||
|
while ((I2C_CTL0(gd32_i2c->i2c_periph) & I2C_CTL0_STOP)) |
||||
|
; |
||||
|
/* clear the STPDET bit */ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (!(msg->flags & RT_I2C_NO_STOP)) |
||||
|
{ |
||||
|
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_TC_GD)) |
||||
|
; |
||||
|
/* send a stop condition to I2C bus */ |
||||
|
i2c_stop_on_bus_gd(gd32_i2c->i2c_periph); |
||||
|
/* wait until stop condition generate */ |
||||
|
while (!i2c_flag_get_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD)) |
||||
|
; |
||||
|
/* clear the STPDET bit */ |
||||
|
i2c_flag_clear_gd(gd32_i2c->i2c_periph, I2C_FLAG_STPDET_GD); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
static const struct rt_i2c_bus_device_ops i2c_ops = { |
||||
|
.master_xfer = gd32_i2c_master_xfer, |
||||
|
.slave_xfer = RT_NULL, |
||||
|
.i2c_bus_control = RT_NULL |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief I2C initialization function |
||||
|
* @param None |
||||
|
* @retval RT_EOK indicates successful initialization. |
||||
|
*/ |
||||
|
int rt_hw_i2c_init(void) |
||||
|
{ |
||||
|
rt_size_t obj_num = sizeof(gd_i2c_config) / sizeof(gd_i2c_config[0]); |
||||
|
|
||||
|
for (int i = 0; i < obj_num; i++) |
||||
|
{ |
||||
|
gd32_i2c_gpio_init(&gd_i2c_config[i]); |
||||
|
|
||||
|
/* configure I2C timing. I2C speed clock=400kHz*/ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32F4xx) || defined(SOC_SERIES_GD32E51x) |
||||
|
if (IS_I2C_LEGACY(gd_i2c_config[i].i2c_periph)) |
||||
|
{ |
||||
|
i2c_clock_config(gd_i2c_config[i].i2c_periph, 100000, I2C_DTCY_2); |
||||
|
i2c_mode_addr_config(gd_i2c_config[i].i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xa0); |
||||
|
i2c_enable(gd_i2c_config[i].i2c_periph); |
||||
|
i2c_ack_config(gd_i2c_config[i].i2c_periph, I2C_ACK_ENABLE); |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32F5xx) || defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) || defined(SOC_SERIES_GD32L23x) || defined(SOC_SERIES_GD32E51x) |
||||
|
i2c_timing_config_gd(gd_i2c_config[i].i2c_periph, 0x1, 0x7, 0); |
||||
|
i2c_master_clock_config_gd(gd_i2c_config[i].i2c_periph, 0x2D, 0x87); |
||||
|
|
||||
|
/* enable I2C1 */ |
||||
|
i2c_enable_gd(gd_i2c_config[i].i2c_periph); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
gd_i2c_config[i].i2c_bus->ops = &i2c_ops; |
||||
|
gd_i2c_config[i].i2c_bus->priv = (void *)&gd_i2c_config[i]; |
||||
|
|
||||
|
rt_i2c_bus_device_register(gd_i2c_config[i].i2c_bus, gd_i2c_config[i].device_name); |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
INIT_BOARD_EXPORT(rt_hw_i2c_init); |
||||
|
|
||||
|
#endif /* RT_USING_I2C */ |
||||
|
|
||||
@ -0,0 +1,403 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include <stddef.h> |
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
|
||||
|
#include "drv_lcd.h" |
||||
|
|
||||
|
#ifdef RT_USING_LCD |
||||
|
|
||||
|
#define DBG_TAG "drv_lcd" |
||||
|
#define DBG_LVL DBG_LOG |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
struct drv_lcd_device |
||||
|
{ |
||||
|
struct rt_device parent; |
||||
|
struct rt_device_graphic_info lcd_info; |
||||
|
}; |
||||
|
|
||||
|
static uint16_t *frame_buffer = RT_NULL; |
||||
|
struct drv_lcd_device _lcd = { 0 }; |
||||
|
RGB color_write = { 0, 0xFF, 0xFF, 0xFF }; |
||||
|
RGB color_black = { 0, 0x00, 0x00, 0x00 }; |
||||
|
RGB color_red = { 0, 0xFF, 0x00, 0x00 }; |
||||
|
RGB color_blue = { 0, 0x00, 0x00, 0xFF }; |
||||
|
RGB color_green = { 0, 0x00, 0xFF, 0x00 }; |
||||
|
RGB color_yellow = { 0, 0xFF, 0xFF, 0x00 }; |
||||
|
RGB color_cyan = { 0, 0x00, 0xFF, 0xFF }; |
||||
|
RGB color_magenta = { 0, 0xFF, 0x00, 0xFF }; |
||||
|
RGB color_orange = { 0, 0xFF, 0xA5, 0x00 }; |
||||
|
RGB color_purple = { 0, 0x80, 0x00, 0x80 }; |
||||
|
RGB color_gray = { 0, 0x80, 0x80, 0x80 }; |
||||
|
RGB color_lightgray = { 0, 0xD3, 0xD3, 0xD3 }; |
||||
|
RGB color_darkgray = { 0, 0x40, 0x40, 0x40 }; |
||||
|
RGB color_brown = { 0, 0xA5, 0x2A, 0x2A }; |
||||
|
RGB color_pink = { 0, 0xFF, 0xC0, 0xCB }; |
||||
|
RGB color_gold = { 0, 0xFF, 0xD7, 0x00 }; |
||||
|
RGB color_silver = { 0, 0xC0, 0xC0, 0xC0 }; |
||||
|
|
||||
|
static void framebuffer_init(void); |
||||
|
static void tli_config(RGB *blackground_color); |
||||
|
static void tli_gpio_config(void); |
||||
|
|
||||
|
rt_err_t drv_lcd_init(rt_device_t dev) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
rt_err_t drv_lcd_open(rt_device_t dev, rt_uint16_t oflag) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
rt_err_t drv_lcd_close(rt_device_t dev) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
rt_ssize_t drv_lcd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
rt_ssize_t drv_lcd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
rt_err_t drv_lcd_control(struct rt_device *device, int cmd, void *args) |
||||
|
{ |
||||
|
switch (cmd) |
||||
|
{ |
||||
|
case RTGRAPHIC_CTRL_GET_INFO: |
||||
|
{ |
||||
|
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args; |
||||
|
|
||||
|
RT_ASSERT(info != RT_NULL); |
||||
|
info->pixel_format = _lcd.lcd_info.pixel_format; |
||||
|
info->bits_per_pixel = _lcd.lcd_info.bits_per_pixel; |
||||
|
info->width = _lcd.lcd_info.width; |
||||
|
info->height = _lcd.lcd_info.height; |
||||
|
info->framebuffer = _lcd.lcd_info.framebuffer; |
||||
|
} |
||||
|
break; |
||||
|
case RTGRAPHIC_CTRL_RECT_UPDATE: |
||||
|
tli_reload_config(TLI_REQUEST_RELOAD_EN); |
||||
|
break; |
||||
|
default: |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static int hw_drv_lcd_init(void) |
||||
|
{ |
||||
|
// malloc frame buffer
|
||||
|
frame_buffer = rt_malloc(ACTIVE_WIDTH * ACTIVE_HEIGHT * PRE_PIXEL_BYTES); |
||||
|
framebuffer_init(); |
||||
|
|
||||
|
_lcd.parent.type = RT_Device_Class_Graphic; |
||||
|
_lcd.parent.init = drv_lcd_init; |
||||
|
_lcd.parent.open = drv_lcd_open; |
||||
|
_lcd.parent.close = drv_lcd_close; |
||||
|
_lcd.parent.read = drv_lcd_read; |
||||
|
_lcd.parent.write = drv_lcd_write; |
||||
|
_lcd.parent.control = drv_lcd_control; |
||||
|
|
||||
|
_lcd.lcd_info.framebuffer = (rt_uint8_t *)frame_buffer; |
||||
|
_lcd.lcd_info.width = LCD_WIGHT; |
||||
|
_lcd.lcd_info.height = LCD_HIGHT; |
||||
|
_lcd.lcd_info.bits_per_pixel = PRE_PIXEL_BYTES * 8; |
||||
|
_lcd.lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; |
||||
|
|
||||
|
/* configure TLI peripheral */ |
||||
|
tli_config(&color_write); |
||||
|
|
||||
|
/* enable TLI layers */ |
||||
|
tli_layer_enable(LAYER0); |
||||
|
tli_reload_config(TLI_REQUEST_RELOAD_EN); |
||||
|
/* enable TLI */ |
||||
|
tli_enable(); |
||||
|
|
||||
|
rt_device_register(&_lcd.parent, "lcd", RT_DEVICE_FLAG_RDWR); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
INIT_APP_EXPORT(hw_drv_lcd_init); |
||||
|
|
||||
|
static void framebuffer_init(void) |
||||
|
{ |
||||
|
for (uint32_t y = 0; y < ACTIVE_HEIGHT; ++y) |
||||
|
{ |
||||
|
for (uint32_t x = 0; x < ACTIVE_WIDTH; ++x) |
||||
|
{ |
||||
|
frame_buffer[y * ACTIVE_WIDTH + x] = 0xFFFF; |
||||
|
} |
||||
|
} |
||||
|
SCB_CleanInvalidateDCache(); |
||||
|
} |
||||
|
|
||||
|
static void tli_gpio_config(void) |
||||
|
{ |
||||
|
/* enable GPIO clock */ |
||||
|
rcu_periph_clock_enable(RCU_GPIOA); |
||||
|
rcu_periph_clock_enable(RCU_GPIOB); |
||||
|
rcu_periph_clock_enable(RCU_GPIOC); |
||||
|
rcu_periph_clock_enable(RCU_GPIOD); |
||||
|
rcu_periph_clock_enable(RCU_GPIOE); |
||||
|
rcu_periph_clock_enable(RCU_GPIOF); |
||||
|
rcu_periph_clock_enable(RCU_GPIOH); |
||||
|
rcu_periph_clock_enable(RCU_GPIOG); |
||||
|
|
||||
|
/* configure HSYNC(PE15), VSYNC(PA7), PCLK(PG7) */ |
||||
|
gpio_af_set(GPIOE, GPIO_AF_10, GPIO_PIN_15); |
||||
|
gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_7); |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_7); |
||||
|
gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15); |
||||
|
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_15); |
||||
|
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); |
||||
|
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7); |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7); |
||||
|
|
||||
|
/* configure LCD_R7(PG6), LCD_R6(PH12), LCD_R5(PH11), LCD_R4(PA5), LCD_R3(PH9),LCD_R2(PH8),
|
||||
|
LCD_R1(PH3), LCD_R0(PH2) */ |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_6); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_12); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_11); |
||||
|
gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_5); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_9); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_8); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_3); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_2); |
||||
|
|
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_6); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_12); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11); |
||||
|
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); |
||||
|
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_5); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_3); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_2); |
||||
|
|
||||
|
/* configure LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PC1), LCD_G4(PH15), LCD_G3(PH14), LCD_G2(PH13),LCD_G1(PB0), LCD_G0(PB1) */ |
||||
|
gpio_af_set(GPIOD, GPIO_AF_14, GPIO_PIN_3); |
||||
|
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_7); |
||||
|
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_1); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_15); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_14); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_13); |
||||
|
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_0); |
||||
|
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_1); |
||||
|
|
||||
|
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); |
||||
|
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_3); |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_7); |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_1); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_15); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_14); |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_13); |
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_0); |
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_1); |
||||
|
|
||||
|
/* configure LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PB5), LCD_B4(PC11), LCD_B3(PG11),LCD_B2(PG10), LCD_B1(PG12), LCD_B0(PG14) */ |
||||
|
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_9); |
||||
|
gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_8); |
||||
|
gpio_af_set(GPIOB, GPIO_AF_3, GPIO_PIN_5); |
||||
|
gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_11); |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_11); |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_10); |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_12); |
||||
|
gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_14); |
||||
|
|
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9); |
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8); |
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_5); |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11); |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_11); |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_10); |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_12); |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_14); |
||||
|
|
||||
|
/* configure LCD_DE(PF10) */ |
||||
|
gpio_af_set(GPIOF, GPIO_AF_14, GPIO_PIN_10); |
||||
|
gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); |
||||
|
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_10); |
||||
|
/* LCD PWM BackLight(PG13) */ |
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_13); |
||||
|
gpio_bit_set(GPIOG, GPIO_PIN_13); |
||||
|
} |
||||
|
|
||||
|
static void tli_config(RGB *blackground_color) |
||||
|
{ |
||||
|
tli_parameter_struct tli_init_struct; |
||||
|
tli_layer_parameter_struct tli_layer_init_struct; |
||||
|
|
||||
|
rcu_periph_clock_enable(RCU_TLI); |
||||
|
tli_gpio_config(); |
||||
|
|
||||
|
rcu_pll_input_output_clock_range_config(IDX_PLL2, RCU_PLL2RNG_1M_2M, RCU_PLL2VCO_192M_836M); |
||||
|
if (ERROR == rcu_pll2_config(25, 192, 3, 3, 3)) |
||||
|
{ |
||||
|
while (1) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
rcu_pll_clock_output_enable(RCU_PLL2R); |
||||
|
rcu_tli_clock_div_config(RCU_PLL2R_DIV8); |
||||
|
|
||||
|
rcu_osci_on(RCU_PLL2_CK); |
||||
|
|
||||
|
if (ERROR == rcu_osci_stab_wait(RCU_PLL2_CK)) |
||||
|
{ |
||||
|
while (1) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* configure TLI parameter struct */ |
||||
|
tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW; |
||||
|
tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW; |
||||
|
tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW; |
||||
|
tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI; |
||||
|
|
||||
|
/* LCD display timing configuration */ |
||||
|
tli_init_struct.synpsz_hpsz = HORIZONTAL_SYNCHRONOUS_PULSE - 1; |
||||
|
tli_init_struct.synpsz_vpsz = VERTICAL_SYNCHRONOUS_PULSE - 1; |
||||
|
tli_init_struct.backpsz_hbpsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1; |
||||
|
tli_init_struct.backpsz_vbpsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1; |
||||
|
tli_init_struct.activesz_hasz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH - 1; |
||||
|
tli_init_struct.activesz_vasz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT - |
||||
|
1; |
||||
|
tli_init_struct.totalsz_htsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH + |
||||
|
HORIZONTAL_FRONT_PORCH - 1; |
||||
|
tli_init_struct.totalsz_vtsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT + |
||||
|
VERTICAL_FRONT_PORCH - 1; |
||||
|
/* configure LCD background R,G,B values */ |
||||
|
tli_init_struct.backcolor_red = blackground_color->R; |
||||
|
tli_init_struct.backcolor_green = blackground_color->G; |
||||
|
tli_init_struct.backcolor_blue = blackground_color->B; |
||||
|
tli_init(&tli_init_struct); |
||||
|
|
||||
|
/* TLI layer configuration */ |
||||
|
tli_layer_init_struct.layer_window_leftpos = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH; |
||||
|
tli_layer_init_struct.layer_window_rightpos = (480 + HORIZONTAL_SYNCHRONOUS_PULSE + |
||||
|
HORIZONTAL_BACK_PORCH - 1); |
||||
|
tli_layer_init_struct.layer_window_toppos = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH; |
||||
|
tli_layer_init_struct.layer_window_bottompos = (272 + VERTICAL_SYNCHRONOUS_PULSE + |
||||
|
VERTICAL_BACK_PORCH - 1); |
||||
|
tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565; |
||||
|
tli_layer_init_struct.layer_sa = 255; |
||||
|
tli_layer_init_struct.layer_default_blue = 0x0; |
||||
|
tli_layer_init_struct.layer_default_green = 0x0; |
||||
|
tli_layer_init_struct.layer_default_red = 0x0; |
||||
|
tli_layer_init_struct.layer_default_alpha = 0x00; |
||||
|
tli_layer_init_struct.layer_acf1 = LAYER_ACF1_SA; |
||||
|
tli_layer_init_struct.layer_acf2 = LAYER_ACF2_SA; |
||||
|
tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)frame_buffer; |
||||
|
tli_layer_init_struct.layer_frame_line_length = ((480 * 2) + 7); |
||||
|
tli_layer_init_struct.layer_frame_buf_stride_offset = (480 * 2); |
||||
|
tli_layer_init_struct.layer_frame_total_line_number = 272; |
||||
|
tli_layer_init(LAYER0, &tli_layer_init_struct); |
||||
|
} |
||||
|
|
||||
|
void lcd_draw_picture(uint32_t picture_addr, uint32_t picture_width, uint32_t picture_height, uint32_t picture_x, uint32_t picture_y) |
||||
|
{ |
||||
|
ipa_destination_parameter_struct ipa_destination_init_struct; |
||||
|
ipa_foreground_parameter_struct ipa_fg_init_struct; |
||||
|
|
||||
|
uint16_t *_address = &frame_buffer[picture_y * ACTIVE_WIDTH + picture_x]; |
||||
|
uint32_t line_offset = ACTIVE_WIDTH - picture_width; |
||||
|
|
||||
|
rcu_periph_clock_enable(RCU_IPA); |
||||
|
|
||||
|
ipa_deinit(); |
||||
|
/* configure IPA pixel format convert mode */ |
||||
|
ipa_pixel_format_convert_mode_set(IPA_FGTODE); |
||||
|
/* configure destination pixel format */ |
||||
|
ipa_destination_init_struct.destination_pf = IPA_DPF_RGB565; |
||||
|
/* configure destination memory base address */ |
||||
|
ipa_destination_init_struct.destination_memaddr = (uint32_t)_address; |
||||
|
/* configure destination pre-defined alpha value RGB */ |
||||
|
ipa_destination_init_struct.destination_pregreen = 0; |
||||
|
ipa_destination_init_struct.destination_preblue = 0; |
||||
|
ipa_destination_init_struct.destination_prered = 0; |
||||
|
ipa_destination_init_struct.destination_prealpha = 0; |
||||
|
/* configure destination line offset */ |
||||
|
ipa_destination_init_struct.destination_lineoff = line_offset; |
||||
|
/* configure height of the image to be processed */ |
||||
|
ipa_destination_init_struct.image_height = picture_height; |
||||
|
/* configure width of the image to be processed */ |
||||
|
ipa_destination_init_struct.image_width = picture_width; |
||||
|
ipa_destination_init_struct.image_rotate = DESTINATION_ROTATE_0; |
||||
|
ipa_destination_init_struct.image_hor_decimation = DESTINATION_HORDECIMATE_DISABLE; |
||||
|
ipa_destination_init_struct.image_ver_decimation = DESTINATION_VERDECIMATE_DISABLE; |
||||
|
/* IPA destination initialization */ |
||||
|
ipa_destination_init(&ipa_destination_init_struct); |
||||
|
|
||||
|
/* configure IPA foreground */ |
||||
|
ipa_fg_init_struct.foreground_memaddr = picture_addr; |
||||
|
ipa_fg_init_struct.foreground_pf = FOREGROUND_PPF_RGB565; |
||||
|
ipa_fg_init_struct.foreground_alpha_algorithm = IPA_FG_ALPHA_MODE_0; |
||||
|
ipa_fg_init_struct.foreground_prealpha = 0x0; |
||||
|
ipa_fg_init_struct.foreground_lineoff = 0x0; |
||||
|
ipa_fg_init_struct.foreground_preblue = 0x0; |
||||
|
ipa_fg_init_struct.foreground_pregreen = 0x0; |
||||
|
ipa_fg_init_struct.foreground_prered = 0x0; |
||||
|
/* foreground initialization */ |
||||
|
ipa_foreground_init(&ipa_fg_init_struct); |
||||
|
|
||||
|
/* start transfer */ |
||||
|
ipa_transfer_enable(); |
||||
|
while (RESET == ipa_interrupt_flag_get(IPA_INT_FLAG_FTF)) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void lcd_draw_point(uint32_t point_x, uint32_t point_y, RGB *color) |
||||
|
{ |
||||
|
frame_buffer[point_y * ACTIVE_WIDTH + point_x] = to_RGB565(color); |
||||
|
} |
||||
|
|
||||
|
uint32_t to_RGB565(RGB *color) |
||||
|
{ |
||||
|
uint32_t res = ((uint32_t)(color->R & 0xF8) << 8) | ((uint32_t)(color->G & 0xFC) << 3) | ((uint32_t)(color->B & 0xF8) >> 3); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
#endif /* RT_USING_LCD */ |
||||
@ -0,0 +1,296 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2023-06-05 zengjianwei first version |
||||
|
* 2025-06-23 Yucai Liu Support for non-complementary PWM output with advanced timers |
||||
|
* 2025-10-11 kurisaw compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_pwm.h" |
||||
|
#include "pwm_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_PWM |
||||
|
|
||||
|
#define DBG_TAG "drv.pwm" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#define MAX_PERIOD 65535 |
||||
|
#define MIN_PERIOD 3 |
||||
|
#define MIN_PULSE 2 |
||||
|
|
||||
|
static struct gd32_pwm gd32_pwm_obj[] = { |
||||
|
|
||||
|
#ifdef BSP_USING_PWM0 |
||||
|
PWM0_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM1 |
||||
|
PWM1_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM2 |
||||
|
PWM2_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM3 |
||||
|
PWM3_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM4 |
||||
|
PWM4_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM5 |
||||
|
PWM5_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM6 |
||||
|
PWM6_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM7 |
||||
|
PWM7_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
rt_uint32_t timer_periph; |
||||
|
rt_bool_t initialized; |
||||
|
} TIMER_INIT_STATUS; |
||||
|
|
||||
|
static TIMER_INIT_STATUS timer_init_status[] = { |
||||
|
{ TIMER0, RT_FALSE }, |
||||
|
{ TIMER1, RT_FALSE }, |
||||
|
{ TIMER2, RT_FALSE }, |
||||
|
{ TIMER3, RT_FALSE }, |
||||
|
{ TIMER4, RT_FALSE }, |
||||
|
{ TIMER5, RT_FALSE }, |
||||
|
{ TIMER6, RT_FALSE }, |
||||
|
{ TIMER7, RT_FALSE }, |
||||
|
}; |
||||
|
|
||||
|
static void gd32_pwm_init(struct gd32_pwm *gd32_pwm) |
||||
|
{ |
||||
|
rt_uint32_t pwm_port, pwm_pin; |
||||
|
rcu_periph_enum pwm_periph; |
||||
|
rt_uint32_t pin_af; |
||||
|
|
||||
|
if (get_pin_config(gd32_pwm->pin_name, &pwm_port, &pwm_pin, &pwm_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
pin_alternate_config(gd32_pwm->alternate, &pin_af); |
||||
|
|
||||
|
/* enable timer clock */ |
||||
|
rcu_periph_clock_enable(gd32_pwm->timer_clk); |
||||
|
rcu_periph_clock_enable(pwm_periph); |
||||
|
|
||||
|
/* GPIO pin configuration */ |
||||
|
gpio_af_set(pwm_port, pin_af, pwm_pin); |
||||
|
gpio_mode_set(pwm_port, GPIO_MODE_AF, GPIO_PUPD_NONE, pwm_pin); |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
gpio_output_options_set(pwm_port, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, pwm_pin); |
||||
|
#else |
||||
|
gpio_output_options_set(pwm_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pwm_pin); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_pwm_enable(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration, rt_bool_t enable) |
||||
|
{ |
||||
|
if (!enable) |
||||
|
{ |
||||
|
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel, TIMER_CCX_DISABLE); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (configuration->complementary == RT_TRUE) |
||||
|
{ |
||||
|
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel - 1, TIMER_CCXN_ENABLE); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
timer_channel_output_state_config(pwm_dev->timer_periph, configuration->channel, TIMER_CCX_ENABLE); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_pwm_get(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration) |
||||
|
{ |
||||
|
rt_uint64_t tim_clock; |
||||
|
rt_uint16_t psc; |
||||
|
rt_uint32_t chxcv; |
||||
|
|
||||
|
tim_clock = rcu_clock_freq_get(CK_SYS); |
||||
|
|
||||
|
psc = timer_prescaler_read(pwm_dev->timer_periph); |
||||
|
if (psc == TIMER_CKDIV_DIV2) |
||||
|
{ |
||||
|
tim_clock = tim_clock / 2; |
||||
|
} |
||||
|
else if (psc == TIMER_CKDIV_DIV4) |
||||
|
{ |
||||
|
tim_clock = tim_clock / 4; |
||||
|
} |
||||
|
|
||||
|
chxcv = timer_channel_capture_value_register_read(pwm_dev->timer_periph, configuration->channel); |
||||
|
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */ |
||||
|
tim_clock /= 1000000UL; |
||||
|
configuration->period = (TIMER_CAR(pwm_dev->timer_periph) + 1) * (psc + 1) * 1000UL / tim_clock; |
||||
|
configuration->pulse = (chxcv + 1) * (psc + 1) * 1000UL / tim_clock; |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_pwm_set(struct gd32_pwm *pwm_dev, struct rt_pwm_configuration *configuration) |
||||
|
{ |
||||
|
rt_uint32_t period, pulse; |
||||
|
rt_uint64_t tim_clock, psc; |
||||
|
|
||||
|
tim_clock = rcu_clock_freq_get(CK_SYS); |
||||
|
|
||||
|
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */ |
||||
|
tim_clock /= 1000000UL; |
||||
|
period = (unsigned long long)configuration->period * tim_clock / 1000ULL; |
||||
|
psc = period / MAX_PERIOD + 1; |
||||
|
period = period / psc; |
||||
|
|
||||
|
timer_prescaler_config(pwm_dev->timer_periph, psc - 1, TIMER_PSC_RELOAD_NOW); |
||||
|
|
||||
|
if (period < MIN_PERIOD) |
||||
|
{ |
||||
|
period = MIN_PERIOD; |
||||
|
} |
||||
|
|
||||
|
timer_autoreload_value_config(pwm_dev->timer_periph, period - 1); |
||||
|
|
||||
|
pulse = (unsigned long long)configuration->pulse * tim_clock / psc / 1000ULL; |
||||
|
if (pulse < MIN_PULSE) |
||||
|
{ |
||||
|
pulse = MIN_PULSE; |
||||
|
} |
||||
|
else if (pulse > period) |
||||
|
{ |
||||
|
pulse = period; |
||||
|
} |
||||
|
|
||||
|
timer_channel_output_pulse_value_config(pwm_dev->timer_periph, configuration->channel, pulse); |
||||
|
timer_counter_value_config(pwm_dev->timer_periph, 0); |
||||
|
|
||||
|
/* Update frequency value */ |
||||
|
timer_event_software_generate(pwm_dev->timer_periph, TIMER_EVENT_SRC_UPG); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) |
||||
|
{ |
||||
|
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg; |
||||
|
struct gd32_pwm *pwm_dev = (struct gd32_pwm *)device; |
||||
|
|
||||
|
switch (cmd) |
||||
|
{ |
||||
|
case PWM_CMD_ENABLE: |
||||
|
return drv_pwm_enable(pwm_dev, configuration, RT_TRUE); |
||||
|
case PWM_CMD_DISABLE: |
||||
|
return drv_pwm_enable(pwm_dev, configuration, RT_FALSE); |
||||
|
case PWM_CMD_SET: |
||||
|
return drv_pwm_set(pwm_dev, configuration); |
||||
|
case PWM_CMD_GET: |
||||
|
return drv_pwm_get(pwm_dev, configuration); |
||||
|
default: |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static struct rt_pwm_ops drv_ops = { |
||||
|
.control = drv_pwm_control |
||||
|
}; |
||||
|
|
||||
|
static void timer_initialize(uint32_t timer_periph) |
||||
|
{ |
||||
|
timer_oc_parameter_struct timer_ocintpara; |
||||
|
timer_parameter_struct timer_initpara; |
||||
|
|
||||
|
/* Check if timer is already initialized */ |
||||
|
for (int i = 0; i < sizeof(timer_init_status) / sizeof(timer_init_status[0]); i++) |
||||
|
{ |
||||
|
if (timer_init_status[i].timer_periph == timer_periph && !timer_init_status[i].initialized) |
||||
|
{ |
||||
|
/* TIMER configuration */ |
||||
|
timer_initpara.prescaler = 119; |
||||
|
timer_initpara.alignedmode = TIMER_COUNTER_EDGE; |
||||
|
timer_initpara.counterdirection = TIMER_COUNTER_UP; |
||||
|
timer_initpara.period = 15999; |
||||
|
timer_initpara.clockdivision = TIMER_CKDIV_DIV1; |
||||
|
timer_initpara.repetitioncounter = 0; |
||||
|
timer_init(timer_periph, &timer_initpara); |
||||
|
|
||||
|
/* CHX configuration in PWM mode */ |
||||
|
timer_ocintpara.outputstate = TIMER_CCX_ENABLE; |
||||
|
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; |
||||
|
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; |
||||
|
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; |
||||
|
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; |
||||
|
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; |
||||
|
timer_channel_output_config(gd32_pwm_obj[i].timer_periph, gd32_pwm_obj[i].channel, &timer_ocintpara); |
||||
|
|
||||
|
timer_init_status[i].initialized = RT_TRUE; |
||||
|
|
||||
|
/* Configure channel output */ |
||||
|
timer_channel_output_pulse_value_config(gd32_pwm_obj[i].timer_periph, |
||||
|
gd32_pwm_obj[i].channel, 7999); |
||||
|
timer_channel_output_mode_config(gd32_pwm_obj[i].timer_periph, |
||||
|
gd32_pwm_obj[i].channel, TIMER_OC_MODE_PWM0); |
||||
|
timer_channel_output_shadow_config(gd32_pwm_obj[i].timer_periph, |
||||
|
gd32_pwm_obj[i].channel, TIMER_OC_SHADOW_DISABLE); |
||||
|
|
||||
|
/* Enable timer */ |
||||
|
timer_primary_output_config(timer_periph, ENABLE); |
||||
|
/* auto-reload preload enable */ |
||||
|
timer_auto_reload_shadow_enable(gd32_pwm_obj[i].timer_periph); |
||||
|
timer_enable(timer_periph); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static int drv_pwm_init(void) |
||||
|
{ |
||||
|
int i, result = RT_EOK; |
||||
|
|
||||
|
for (i = 0; i < sizeof(gd32_pwm_obj) / sizeof(gd32_pwm_obj[0]); i++) |
||||
|
{ |
||||
|
/* Initialize PWM hardware */ |
||||
|
gd32_pwm_init(&gd32_pwm_obj[i]); |
||||
|
|
||||
|
/* Initialize timer if not already initialized */ |
||||
|
timer_initialize(gd32_pwm_obj[i].timer_periph); |
||||
|
|
||||
|
/* Register PWM device */ |
||||
|
if (rt_device_pwm_register(&gd32_pwm_obj[i].pwm_device, gd32_pwm_obj[i].name, |
||||
|
&drv_ops, RT_NULL) == RT_EOK) |
||||
|
{ |
||||
|
LOG_D("%s register success", gd32_pwm_obj[i].name); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
LOG_E("%s register failed", gd32_pwm_obj[i].name); |
||||
|
result = -RT_ERROR; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
INIT_DEVICE_EXPORT(drv_pwm_init); |
||||
|
|
||||
|
#endif /* RT_USING_PWM */ |
||||
@ -0,0 +1,443 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2022-01-25 iysheng first version |
||||
|
* 2025-09-25 kurisaw adapt to rt_rtc_ops interface |
||||
|
* 2025-09-25 kurisaw add alarm interrupt support |
||||
|
*/ |
||||
|
|
||||
|
#include <board.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <rthw.h> |
||||
|
#include <sys/time.h> |
||||
|
|
||||
|
#define DBG_TAG "drv.rtc" |
||||
|
#define DBG_LVL DBG_LOG |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#ifdef RT_USING_RTC |
||||
|
|
||||
|
#if defined(RT_USING_ALARM) |
||||
|
#if defined(BSP_USING_ALARM0) && defined(BSP_USING_ALARM1) |
||||
|
#error "Only supports using one alarm at a time." |
||||
|
#elif !defined(BSP_USING_ALARM0) && !defined(BSP_USING_ALARM1) |
||||
|
#error "Please Enable RTC alarm define (BSP_USING_ALARM0 | BSP_USING_ALARM1)" |
||||
|
#elif defined(BSP_USING_ALARM0) |
||||
|
#define BSP_ALARM_FLAG RTC_FLAG_ALARM0 |
||||
|
#define BSP_RTC_ALARM RTC_ALARM0 |
||||
|
#define BSP_RTC_INT_ALARM RTC_INT_ALARM0 |
||||
|
#elif defined(BSP_USING_ALARM1) |
||||
|
#define BSP_ALARM_FLAG RTC_FLAG_ALARM1 |
||||
|
#define BSP_RTC_ALARM RTC_ALARM1 |
||||
|
#define BSP_RTC_INT_ALARM RTC_INT_ALARM1 |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
|
||||
|
#define rtc_year year |
||||
|
#define rtc_month month |
||||
|
#define rtc_date date |
||||
|
#define rtc_day_of_week day_of_week |
||||
|
#define rtc_hour hour |
||||
|
#define rtc_minute minute |
||||
|
#define rtc_second second |
||||
|
#define rtc_display_format display_format |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
static time_t get_rtc_timestamp(void); |
||||
|
static rt_err_t set_rtc_timestamp(time_t time_stamp); |
||||
|
|
||||
|
/**
|
||||
|
* @brief Helper function: Convert BCD value to binary. |
||||
|
* @param val: BCD value. |
||||
|
* @return Binary value. |
||||
|
*/ |
||||
|
static rt_uint8_t bcd_to_bin(rt_uint8_t val) |
||||
|
{ |
||||
|
return (val & 0x0F) + ((val >> 4) & 0x0F) * 10; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief Helper function: Convert binary to BCD. |
||||
|
* @param val: Binary value. |
||||
|
* @return BCD value. |
||||
|
*/ |
||||
|
static rt_uint8_t bin_to_bcd(rt_uint8_t val) |
||||
|
{ |
||||
|
return ((val / 10) << 4) | (val % 10); |
||||
|
} |
||||
|
|
||||
|
#ifdef RT_USING_ALARM |
||||
|
/* RTC device for alarm callback */ |
||||
|
static rt_device_t g_rtc_device = RT_NULL; |
||||
|
|
||||
|
/**
|
||||
|
* @brief RTC Alarm Interrupt Handler |
||||
|
*/ |
||||
|
void RTC_Alarm_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
/* Check if alarm interrupt occurred */ |
||||
|
if (rtc_flag_get(RTC_FLAG_ALARM0) != RESET) |
||||
|
{ |
||||
|
/* Clear alarm flag */ |
||||
|
rtc_flag_clear(RTC_FLAG_ALARM0); |
||||
|
exti_flag_clear(EXTI_17); |
||||
|
|
||||
|
/* Notify RTC framework about alarm event */ |
||||
|
if (g_rtc_device != RT_NULL) |
||||
|
{ |
||||
|
rt_alarm_update(g_rtc_device, 1); |
||||
|
} |
||||
|
LOG_D("RTC Alarm0 triggered"); |
||||
|
} |
||||
|
|
||||
|
if (rtc_flag_get(RTC_FLAG_ALARM1) != RESET) |
||||
|
{ |
||||
|
/* Clear alarm flag */ |
||||
|
rtc_flag_clear(RTC_FLAG_ALARM1); |
||||
|
exti_flag_clear(EXTI_17); |
||||
|
|
||||
|
/* Notify RTC framework about alarm event */ |
||||
|
if (g_rtc_device != RT_NULL) |
||||
|
{ |
||||
|
rt_alarm_update(g_rtc_device, 1); |
||||
|
} |
||||
|
LOG_D("RTC Alarm1 triggered"); |
||||
|
} |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
#endif /* RT_USING_ALARM */ |
||||
|
|
||||
|
static rt_err_t gd_rtc_init(void) |
||||
|
{ |
||||
|
/* Enable PMU and backup domain clocks */ |
||||
|
rcu_periph_clock_enable(RCU_PMU); |
||||
|
pmu_backup_write_enable(); |
||||
|
|
||||
|
/* Enable BKP and RTC clocks */ |
||||
|
#ifdef SOC_SERIES_GD32F10x |
||||
|
rcu_periph_clock_enable(RCU_BKPI); |
||||
|
#else |
||||
|
rcu_periph_clock_enable(RCU_RTC); |
||||
|
#endif |
||||
|
|
||||
|
/* Check if RTC is already initialized by backup domain reset */ |
||||
|
if (RTC_STAT & RTC_STAT_INITF) |
||||
|
{ |
||||
|
LOG_D("RTC already initialized"); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
/* Reset backup domain only if RTC is not running */ |
||||
|
if ((RTC_STAT & RTC_STAT_RSYNF) == 0) |
||||
|
{ |
||||
|
rcu_bkp_reset_enable(); |
||||
|
rcu_bkp_reset_disable(); |
||||
|
|
||||
|
/* Re-enable clocks after reset */ |
||||
|
#ifdef SOC_SERIES_GD32F10x |
||||
|
rcu_periph_clock_enable(RCU_BKPI); |
||||
|
#else |
||||
|
rcu_periph_clock_enable(RCU_RTC); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/* Use LSE (32.768kHz) as RTC clock source */ |
||||
|
#define PRESCALER_S 0xFF |
||||
|
#define PRESCALER_A 0x7F |
||||
|
|
||||
|
rcu_osci_on(RCU_LXTAL); |
||||
|
if (rcu_osci_stab_wait(RCU_LXTAL) != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("LSE oscillator failed to stabilize"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); |
||||
|
LOG_D("RTC clock source: LSE (32.768kHz)"); |
||||
|
|
||||
|
/* Wait for RTC registers synchronization */ |
||||
|
if (rtc_register_sync_wait() != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("RTC register synchronization failed"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
/* Set default time if RTC is not initialized */ |
||||
|
if ((RTC_DATE == 0) || (RTC_TIME == 0)) |
||||
|
{ |
||||
|
time_t default_time = 1704067200; /* 2024-01-01 00:00:00 */ |
||||
|
if (set_rtc_timestamp(default_time) != RT_EOK) |
||||
|
{ |
||||
|
LOG_E("Failed to set default RTC time"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
LOG_D("RTC set to default time: 2024-01-01 00:00:00"); |
||||
|
} |
||||
|
|
||||
|
LOG_D("RTC initialization successful"); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static time_t get_rtc_timestamp(void) |
||||
|
{ |
||||
|
struct tm tm_new = {0}; |
||||
|
rtc_parameter_struct rtc_current_time; |
||||
|
|
||||
|
/* Wait for register synchronization before reading */ |
||||
|
if (rtc_register_sync_wait() != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("RTC sync failed before reading time"); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
rtc_current_time_get(&rtc_current_time); |
||||
|
|
||||
|
/* Convert BCD to binary and adjust year/month values */ |
||||
|
tm_new.tm_year = bcd_to_bin(rtc_current_time.rtc_year) + 100; /* RTC year starts from 2000 */ |
||||
|
tm_new.tm_mon = bcd_to_bin(rtc_current_time.rtc_month) - 1; /* tm_mon: 0-11 */ |
||||
|
tm_new.tm_mday = bcd_to_bin(rtc_current_time.rtc_date); |
||||
|
tm_new.tm_hour = bcd_to_bin(rtc_current_time.rtc_hour); |
||||
|
tm_new.tm_min = bcd_to_bin(rtc_current_time.rtc_minute); |
||||
|
tm_new.tm_sec = bcd_to_bin(rtc_current_time.rtc_second); |
||||
|
|
||||
|
/* Convert weekday: RTC uses 1-7 (Monday-Sunday), tm uses 0-6 (Sunday-Saturday) */ |
||||
|
uint8_t rtc_wday = bcd_to_bin(rtc_current_time.rtc_day_of_week); |
||||
|
tm_new.tm_wday = (rtc_wday == 7) ? 0 : rtc_wday; /* Sunday conversion */ |
||||
|
|
||||
|
/* Calculate day of year */ |
||||
|
tm_new.tm_yday = 0; /* Will be calculated by timegm */ |
||||
|
tm_new.tm_isdst = 0; /* No daylight saving */ |
||||
|
|
||||
|
/* Use timegm instead of mktime to avoid timezone issues */ |
||||
|
return timegm(&tm_new); |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd_get_secs(time_t *sec) |
||||
|
{ |
||||
|
if (sec == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
*sec = get_rtc_timestamp(); |
||||
|
LOG_D("RTC: get timestamp %lu", *sec); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t set_rtc_timestamp(time_t time_stamp) |
||||
|
{ |
||||
|
struct tm now; |
||||
|
rtc_parameter_struct rtc_init_struct; |
||||
|
ErrStatus status; |
||||
|
|
||||
|
/* Use gmtime_r for thread safety */ |
||||
|
gmtime_r(&time_stamp, &now); |
||||
|
|
||||
|
if (now.tm_year < 100) |
||||
|
{ |
||||
|
LOG_E("Year must be >= 2000"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
/* Convert to BCD format */ |
||||
|
rtc_init_struct.rtc_year = bin_to_bcd(now.tm_year - 100); /* RTC year: 0-99 (2000-2099) */ |
||||
|
rtc_init_struct.rtc_month = bin_to_bcd(now.tm_mon + 1); /* RTC month: 1-12 */ |
||||
|
rtc_init_struct.rtc_date = bin_to_bcd(now.tm_mday); |
||||
|
|
||||
|
/* Convert weekday: tm_wday 0-6 (Sun-Sat) to RTC 1-7 (Mon-Sun) */ |
||||
|
rtc_init_struct.rtc_day_of_week = bin_to_bcd(now.tm_wday == 0 ? 7 : now.tm_wday); |
||||
|
|
||||
|
rtc_init_struct.rtc_hour = bin_to_bcd(now.tm_hour); |
||||
|
rtc_init_struct.rtc_minute = bin_to_bcd(now.tm_min); |
||||
|
rtc_init_struct.rtc_second = bin_to_bcd(now.tm_sec); |
||||
|
rtc_init_struct.rtc_display_format = RTC_24HOUR; |
||||
|
|
||||
|
/* Use default prescaler values */ |
||||
|
rtc_init_struct.factor_asyn = PRESCALER_A; |
||||
|
rtc_init_struct.factor_syn = PRESCALER_S; |
||||
|
rtc_init_struct.am_pm = RTC_AM; |
||||
|
|
||||
|
status = rtc_init(&rtc_init_struct); |
||||
|
if (status != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("RTC time set failed: %d", status); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
/* Wait for synchronization after setting time */ |
||||
|
if (rtc_register_sync_wait() != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("RTC sync failed after setting time"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
LOG_D("RTC time set successfully: %lu", time_stamp); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd_set_secs(time_t *sec) |
||||
|
{ |
||||
|
if (sec == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
rt_err_t result = set_rtc_timestamp(*sec); |
||||
|
if (result == RT_EOK) |
||||
|
{ |
||||
|
LOG_D("RTC: set rtc_time %lu", *sec); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
LOG_E("RTC: set rtc_time failed %lu", *sec); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
#ifdef RT_USING_ALARM |
||||
|
static rt_err_t gd_get_alarm(struct rt_rtc_wkalarm *alarm) |
||||
|
{ |
||||
|
if (alarm == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
rtc_alarm_struct rtc_alarm; |
||||
|
|
||||
|
/* Get current alarm configuration */ |
||||
|
rtc_alarm_get(BSP_RTC_ALARM, &rtc_alarm); |
||||
|
|
||||
|
/* Convert RTC alarm to RT-Thread alarm format */ |
||||
|
alarm->tm_hour = bcd_to_bin(rtc_alarm.alarm_hour); |
||||
|
alarm->tm_min = bcd_to_bin(rtc_alarm.alarm_minute); |
||||
|
alarm->tm_sec = bcd_to_bin(rtc_alarm.alarm_second); |
||||
|
|
||||
|
|
||||
|
/* Check if alarm is enabled */ |
||||
|
alarm->enable = (RTC_CTL & (BSP_RTC_ALARM == RTC_ALARM0 ? RTC_CTL_ALRM0EN : RTC_CTL_ALRM1EN)) ? 1 : 0; |
||||
|
|
||||
|
LOG_D("RTC: get alarm %02d:%02d:%02d, enable: %d", |
||||
|
alarm->tm_hour, alarm->tm_min, alarm->tm_sec, alarm->enable); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd_set_alarm(struct rt_rtc_wkalarm *alarm) |
||||
|
{ |
||||
|
if (alarm == RT_NULL) |
||||
|
{ |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
|
||||
|
rtc_alarm_struct rtc_alarm; |
||||
|
|
||||
|
rtc_alarm_disable(BSP_RTC_ALARM); |
||||
|
/* Initialize alarm structure */ |
||||
|
rtc_alarm.alarm_mask = RTC_ALARM_ALL_MASK; |
||||
|
rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED; |
||||
|
rtc_alarm.alarm_day = 1; /* Not used when mask is set to ALL_MASK */ |
||||
|
rtc_alarm.alarm_hour = bin_to_bcd(alarm->tm_hour); |
||||
|
rtc_alarm.alarm_minute = bin_to_bcd(alarm->tm_min); |
||||
|
rtc_alarm.alarm_second = bin_to_bcd(alarm->tm_sec); |
||||
|
rtc_alarm.am_pm = RTC_AM; |
||||
|
|
||||
|
/* Configure alarm */ |
||||
|
rtc_alarm_config(BSP_RTC_ALARM, &rtc_alarm); |
||||
|
|
||||
|
/* Enable or disable alarm */ |
||||
|
if (alarm->enable) |
||||
|
{ |
||||
|
/* Clear any pending alarm flag first */ |
||||
|
rtc_flag_clear(BSP_ALARM_FLAG); |
||||
|
|
||||
|
/* Clear EXTI line 17 flag */ |
||||
|
exti_flag_clear(EXTI_17); |
||||
|
|
||||
|
/* Enable RTC alarm interrupt */ |
||||
|
rtc_interrupt_enable(BSP_RTC_INT_ALARM); |
||||
|
|
||||
|
/* Enable alarm */ |
||||
|
rtc_alarm_enable(BSP_RTC_ALARM); |
||||
|
|
||||
|
/* Configure EXTI line 17 for RTC alarm interrupt */ |
||||
|
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING); |
||||
|
|
||||
|
/* Enable RTC Alarm global interrupt in NVIC */ |
||||
|
nvic_irq_enable(RTC_Alarm_IRQn, 0, 0); |
||||
|
|
||||
|
LOG_D("RTC Alarm enabled with interrupt"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable alarm interrupt first */ |
||||
|
rtc_interrupt_disable(BSP_RTC_INT_ALARM); |
||||
|
|
||||
|
/* Disable alarm */ |
||||
|
rtc_alarm_disable(BSP_RTC_ALARM); |
||||
|
|
||||
|
/* Clear alarm flag */ |
||||
|
rtc_flag_clear(BSP_ALARM_FLAG); |
||||
|
exti_flag_clear(EXTI_17); |
||||
|
|
||||
|
LOG_D("RTC Alarm disabled"); |
||||
|
} |
||||
|
|
||||
|
LOG_D("RTC: set alarm %02d:%02d:%02d, enable: %d", |
||||
|
alarm->tm_hour, alarm->tm_min, alarm->tm_sec, alarm->enable); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
#endif /* RT_USING_ALARM */ |
||||
|
|
||||
|
static const struct rt_rtc_ops gd_rtc_ops = |
||||
|
{ |
||||
|
.init = gd_rtc_init, |
||||
|
.get_secs = gd_get_secs, |
||||
|
.set_secs = gd_set_secs, |
||||
|
#ifdef RT_USING_ALARM |
||||
|
.set_alarm = gd_set_alarm, |
||||
|
.get_alarm = gd_get_alarm, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
static rt_rtc_dev_t gd_rtc_dev; |
||||
|
|
||||
|
static int rt_hw_rtc_init(void) |
||||
|
{ |
||||
|
rt_err_t result; |
||||
|
|
||||
|
gd_rtc_dev.ops = &gd_rtc_ops; |
||||
|
|
||||
|
result = rt_hw_rtc_register(&gd_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL); |
||||
|
if (result != RT_EOK) |
||||
|
{ |
||||
|
LOG_E("RTC register failed: %d", result); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
#ifdef RT_USING_ALARM |
||||
|
/* Store RTC device for alarm callback */ |
||||
|
g_rtc_device = rt_device_find("rtc"); |
||||
|
if (g_rtc_device == RT_NULL) |
||||
|
{ |
||||
|
LOG_W("RTC device not found for alarm callback"); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
LOG_D("RTC hardware init success"); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
INIT_DEVICE_EXPORT(rt_hw_rtc_init); |
||||
|
|
||||
|
#endif /* RT_USING_RTC */ |
||||
File diff suppressed because it is too large
@ -0,0 +1,640 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-12-20 BruceOu first implementation |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
#include "drv_spi.h" |
||||
|
#include "spi_config.h" |
||||
|
|
||||
|
#ifdef RT_USING_SPI |
||||
|
|
||||
|
#if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) |
||||
|
|
||||
|
#define DBG_TAG "drv.spi" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#ifdef BSP_USING_SPI0 |
||||
|
static struct rt_spi_bus spi_bus0; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_SPI1 |
||||
|
static struct rt_spi_bus spi_bus1; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_SPI2 |
||||
|
static struct rt_spi_bus spi_bus2; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_SPI3 |
||||
|
static struct rt_spi_bus spi_bus3; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_SPI4 |
||||
|
static struct rt_spi_bus spi_bus4; |
||||
|
#endif |
||||
|
#ifdef BSP_USING_SPI5 |
||||
|
static struct rt_spi_bus spi_bus5; |
||||
|
#endif |
||||
|
|
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
gd32_spi_dma spi_dma[] = { |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI0_TX, |
||||
|
DMA_REQUEST_SPI0_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI1_TX, |
||||
|
DMA_REQUEST_SPI1_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI2_TX, |
||||
|
DMA_REQUEST_SPI2_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI3_TX, |
||||
|
DMA_REQUEST_SPI3_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI4_TX, |
||||
|
DMA_REQUEST_SPI4_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
DMA0, |
||||
|
DMA_CH2, |
||||
|
DMA_CH3, |
||||
|
DMA_REQUEST_SPI5_TX, |
||||
|
DMA_REQUEST_SPI5_RX, |
||||
|
DMA_INTF_FTFIF, |
||||
|
|
||||
|
0 |
||||
|
}, |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
static const struct gd32_spi spi_bus_obj[] = { |
||||
|
#ifdef BSP_USING_SPI0 |
||||
|
SPI0_BUS_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI1 |
||||
|
SPI1_BUS_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI2 |
||||
|
SPI2_BUS_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI3 |
||||
|
SPI3_BUS_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI4 |
||||
|
SPI4_BUS_CONFIG, |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI5 |
||||
|
SPI5_BUS_CONFIG, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
/* private rt-thread spi ops function */ |
||||
|
static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration); |
||||
|
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message); |
||||
|
|
||||
|
static struct rt_spi_ops gd32_spi_ops = { |
||||
|
.configure = spi_configure, |
||||
|
.xfer = spixfer, |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief SPI Initialization |
||||
|
* @param gd32_spi: SPI BUS |
||||
|
* @retval None |
||||
|
*/ |
||||
|
static void gd32_spi_init(struct gd32_spi *gd32_spi) |
||||
|
{ |
||||
|
rt_uint32_t sck_port, miso_port, mosi_port; |
||||
|
rt_uint32_t sck_pin, miso_pin, mosi_pin; |
||||
|
rcu_periph_enum sck_periph, miso_periph, mosi_periph; |
||||
|
rt_uint32_t pin_af; |
||||
|
|
||||
|
if (get_pin_config(gd32_spi->sck_pin_name, &sck_port, &sck_pin, &sck_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (get_pin_config(gd32_spi->miso_pin_name, &miso_port, &miso_pin, &miso_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (get_pin_config(gd32_spi->mosi_pin_name, &mosi_port, &mosi_pin, &mosi_periph) == -RT_ERROR) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
pin_alternate_config(gd32_spi->alternate, &pin_af); |
||||
|
|
||||
|
/* enable SPI clock */ |
||||
|
rcu_periph_clock_enable(gd32_spi->spi_clk); |
||||
|
rcu_periph_clock_enable(sck_periph); |
||||
|
rcu_periph_clock_enable(miso_periph); |
||||
|
rcu_periph_clock_enable(mosi_periph); |
||||
|
|
||||
|
/*GPIO pin configuration*/ |
||||
|
gpio_af_set(sck_port, pin_af, sck_pin); |
||||
|
gpio_af_set(miso_port, pin_af, miso_pin); |
||||
|
gpio_af_set(mosi_port, pin_af, mosi_pin); |
||||
|
gpio_mode_set(sck_port, GPIO_MODE_AF, GPIO_PUPD_NONE, sck_pin); |
||||
|
gpio_mode_set(miso_port, GPIO_MODE_AF, GPIO_PUPD_NONE, miso_pin); |
||||
|
gpio_mode_set(mosi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, mosi_pin); |
||||
|
gpio_output_options_set(sck_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, sck_pin); |
||||
|
gpio_output_options_set(miso_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, miso_pin); |
||||
|
gpio_output_options_set(mosi_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, mosi_pin); |
||||
|
} |
||||
|
|
||||
|
static rt_err_t spi_configure(struct rt_spi_device *device, |
||||
|
struct rt_spi_configuration *configuration) |
||||
|
{ |
||||
|
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus; |
||||
|
struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data; |
||||
|
spi_parameter_struct spi_init_struct; |
||||
|
uint32_t spi_periph = spi_device->spi_periph; |
||||
|
|
||||
|
RT_ASSERT(device != RT_NULL); |
||||
|
RT_ASSERT(configuration != RT_NULL); |
||||
|
|
||||
|
/* Init SPI */ |
||||
|
gd32_spi_init(spi_device); |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32H7xx || defined(SOC_SERIES_GD32H75E) |
||||
|
/* data_width */ |
||||
|
if (configuration->data_width >= 4 && configuration->data_width <= 32) |
||||
|
{ |
||||
|
spi_init_struct.data_size = CFG0_DZ(configuration->data_width - 1); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return -RT_EIO; |
||||
|
} |
||||
|
#else |
||||
|
/* data_width */ |
||||
|
if (configuration->data_width <= 8) |
||||
|
{ |
||||
|
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; |
||||
|
} |
||||
|
else if (configuration->data_width <= 16) |
||||
|
{ |
||||
|
spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return -RT_EIO; |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
/* baudrate */ |
||||
|
{ |
||||
|
rcu_clock_freq_enum spi_src; |
||||
|
uint32_t spi_apb_clock; |
||||
|
uint32_t max_hz; |
||||
|
|
||||
|
max_hz = configuration->max_hz; |
||||
|
|
||||
|
LOG_D("sys freq: %d\n", rcu_clock_freq_get(CK_SYS)); |
||||
|
LOG_D("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2)); |
||||
|
LOG_D("max freq: %d\n", max_hz); |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
spi_src = CK_APB2; |
||||
|
#else |
||||
|
if (spi_periph == SPI1 || spi_periph == SPI2) |
||||
|
{ |
||||
|
spi_src = CK_APB1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
spi_src = CK_APB2; |
||||
|
} |
||||
|
#endif |
||||
|
spi_apb_clock = rcu_clock_freq_get(spi_src); |
||||
|
|
||||
|
if (max_hz >= spi_apb_clock / 2) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_2; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 4) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_4; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 8) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_8; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 16) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_16; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 32) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_32; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 64) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_64; |
||||
|
} |
||||
|
else if (max_hz >= spi_apb_clock / 128) |
||||
|
{ |
||||
|
spi_init_struct.prescale = SPI_PSC_128; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* min prescaler 256 */ |
||||
|
spi_init_struct.prescale = SPI_PSC_256; |
||||
|
} |
||||
|
} /* baudrate */ |
||||
|
|
||||
|
switch (configuration->mode & RT_SPI_MODE_3) |
||||
|
{ |
||||
|
case RT_SPI_MODE_0: |
||||
|
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; |
||||
|
break; |
||||
|
case RT_SPI_MODE_1: |
||||
|
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; |
||||
|
break; |
||||
|
case RT_SPI_MODE_2: |
||||
|
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; |
||||
|
break; |
||||
|
case RT_SPI_MODE_3: |
||||
|
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* MSB or LSB */ |
||||
|
if (configuration->mode & RT_SPI_MSB) |
||||
|
{ |
||||
|
spi_init_struct.endian = SPI_ENDIAN_MSB; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
spi_init_struct.endian = SPI_ENDIAN_LSB; |
||||
|
} |
||||
|
|
||||
|
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; |
||||
|
spi_init_struct.device_mode = SPI_MASTER; |
||||
|
spi_init_struct.nss = SPI_NSS_SOFT; |
||||
|
|
||||
|
spi_crc_off(spi_periph); |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
/* enable SPI byte access */ |
||||
|
spi_byte_access_enable(spi_periph); |
||||
|
/* enable SPI NSS output */ |
||||
|
spi_nss_output_enable(spi_periph); |
||||
|
#endif |
||||
|
|
||||
|
/* init SPI */ |
||||
|
spi_init(spi_periph, &spi_init_struct); |
||||
|
/* Enable SPI_MASTER */ |
||||
|
spi_enable(spi_periph); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
static rt_err_t dma_spi_config(struct rt_spi_device *device, struct rt_spi_message *message) |
||||
|
{ |
||||
|
struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus; |
||||
|
struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data; |
||||
|
rt_uint8_t *recv_ptr_dma = RT_NULL; |
||||
|
rt_uint8_t *send_ptr_dma = RT_NULL; |
||||
|
|
||||
|
dma_single_data_parameter_struct dma_init_struct; |
||||
|
/* deinitialize DMA registers of a channel */ |
||||
|
dma_deinit(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch); |
||||
|
dma_deinit(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch); |
||||
|
dma_single_data_para_struct_init(&dma_init_struct); |
||||
|
|
||||
|
/* SPI transmit DMA config */ |
||||
|
dma_init_struct.request = spi_device->spi_dma->dma_mux_req_tx; |
||||
|
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH; |
||||
|
if (message->send_buf == RT_NULL) |
||||
|
{ |
||||
|
dma_init_struct.memory0_addr = (uint32_t)send_ptr_dma; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
dma_init_struct.memory0_addr = (uint32_t)message->send_buf; |
||||
|
} |
||||
|
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; |
||||
|
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; |
||||
|
dma_init_struct.number = message->length; |
||||
|
dma_init_struct.periph_addr = (uint32_t)&SPI_TDATA(spi_device->spi_periph); |
||||
|
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; |
||||
|
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; |
||||
|
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE; |
||||
|
dma_single_data_mode_init(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, &dma_init_struct); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_FTF); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_HTF); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->txdma_ch, DMA_FLAG_FEE); |
||||
|
|
||||
|
/* SPI receive DMA config */ |
||||
|
dma_init_struct.request = spi_device->spi_dma->dma_mux_req_rx; |
||||
|
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY; |
||||
|
if (message->recv_buf == RT_NULL) |
||||
|
{ |
||||
|
dma_init_struct.memory0_addr = (uint32_t)recv_ptr_dma; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
dma_init_struct.memory0_addr = (uint32_t)message->recv_buf; |
||||
|
} |
||||
|
dma_init_struct.periph_addr = (uint32_t)&SPI_RDATA(spi_device->spi_periph); |
||||
|
dma_init_struct.priority = DMA_PRIORITY_HIGH; |
||||
|
dma_single_data_mode_init(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, &dma_init_struct); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_FTF); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_HTF); |
||||
|
dma_flag_clear(spi_device->spi_dma->dma_periph, spi_device->spi_dma->rxdma_ch, DMA_FLAG_FEE); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) |
||||
|
{ |
||||
|
struct rt_spi_bus *gd32_spi_bus = (struct rt_spi_bus *)device->bus; |
||||
|
struct gd32_spi *spi_device = (struct gd32_spi *)gd32_spi_bus->parent.user_data; |
||||
|
struct rt_spi_configuration *config = &device->config; |
||||
|
uint32_t spi_periph = spi_device->spi_periph; |
||||
|
|
||||
|
RT_ASSERT(device != NULL); |
||||
|
RT_ASSERT(message != NULL); |
||||
|
|
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
dma_spi_config(device, message); |
||||
|
#endif |
||||
|
|
||||
|
/* take CS */ |
||||
|
if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) |
||||
|
{ |
||||
|
if (device->config.mode & RT_SPI_CS_HIGH) |
||||
|
{ |
||||
|
rt_pin_write(device->cs_pin, PIN_HIGH); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
rt_pin_write(device->cs_pin, PIN_LOW); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
LOG_D("%s transfer prepare and start", spi_device->bus_name); |
||||
|
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d", |
||||
|
spi_device->bus_name, |
||||
|
(uint32_t)message->send_buf, |
||||
|
(uint32_t)message->recv_buf, message->length); |
||||
|
|
||||
|
{ |
||||
|
if (config->data_width <= 8) |
||||
|
{ |
||||
|
const rt_uint8_t *send_ptr = message->send_buf; |
||||
|
rt_uint8_t *recv_ptr = message->recv_buf; |
||||
|
rt_uint32_t size = message->length; |
||||
|
|
||||
|
LOG_D("spi poll transfer start: %d\n", size); |
||||
|
|
||||
|
while (size--) |
||||
|
{ |
||||
|
rt_uint8_t data = 0xFF; |
||||
|
|
||||
|
if (send_ptr != RT_NULL) |
||||
|
{ |
||||
|
data = *send_ptr++; |
||||
|
} |
||||
|
|
||||
|
/* Todo: replace register read/write by gd32f4 lib */ |
||||
|
/* Wait until the transmit buffer is empty */ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
spi_master_transfer_start(spi_periph, SPI_TRANS_START); |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP)) |
||||
|
; |
||||
|
#else |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) |
||||
|
; |
||||
|
#endif |
||||
|
/* Send the byte */ |
||||
|
spi_i2s_data_transmit(spi_periph, data); |
||||
|
|
||||
|
/* Wait until a data is received */ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP)) |
||||
|
; |
||||
|
#else |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)) |
||||
|
; |
||||
|
#endif |
||||
|
/* Get the received data */ |
||||
|
data = spi_i2s_data_receive(spi_periph); |
||||
|
|
||||
|
if (recv_ptr != RT_NULL) |
||||
|
{ |
||||
|
*recv_ptr++ = data; |
||||
|
} |
||||
|
} |
||||
|
LOG_D("spi poll transfer finsh\n"); |
||||
|
} |
||||
|
else if (config->data_width <= 16) |
||||
|
{ |
||||
|
const rt_uint16_t *send_ptr = message->send_buf; |
||||
|
rt_uint16_t *recv_ptr = message->recv_buf; |
||||
|
rt_uint32_t size = message->length; |
||||
|
|
||||
|
while (size--) |
||||
|
{ |
||||
|
rt_uint16_t data = 0xFF; |
||||
|
|
||||
|
if (send_ptr != RT_NULL) |
||||
|
{ |
||||
|
data = *send_ptr++; |
||||
|
} |
||||
|
|
||||
|
/* Wait until the transmit buffer is empty */ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
spi_master_transfer_start(spi_periph, SPI_TRANS_START); |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP)) |
||||
|
; |
||||
|
#else |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)) |
||||
|
; |
||||
|
#endif |
||||
|
/* Send the byte */ |
||||
|
spi_i2s_data_transmit(spi_periph, data); |
||||
|
|
||||
|
/* Wait until a data is received */ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP)) |
||||
|
; |
||||
|
#else |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)) |
||||
|
; |
||||
|
#endif |
||||
|
/* Get the received data */ |
||||
|
data = spi_i2s_data_receive(spi_periph); |
||||
|
|
||||
|
if (recv_ptr != RT_NULL) |
||||
|
{ |
||||
|
*recv_ptr++ = data; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#if defined SOC_SERIES_GD32H7xx || defined(SOC_SERIES_GD32H75E) |
||||
|
else if (config->data_width <= 32) |
||||
|
{ |
||||
|
const rt_uint32_t *send_ptr = message->send_buf; |
||||
|
rt_uint32_t *recv_ptr = message->recv_buf; |
||||
|
rt_uint32_t size = message->length; |
||||
|
/* SPI master start transfer */ |
||||
|
spi_master_transfer_start(spi_periph, SPI_TRANS_START); |
||||
|
while (size--) |
||||
|
{ |
||||
|
rt_uint32_t data = 0xFF; |
||||
|
|
||||
|
if (send_ptr != RT_NULL) |
||||
|
{ |
||||
|
data = *send_ptr++; |
||||
|
} |
||||
|
|
||||
|
/* Wait until the transmit buffer is empty */ |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP)) |
||||
|
; |
||||
|
/* Send the byte */ |
||||
|
spi_i2s_data_transmit(spi_periph, data); |
||||
|
|
||||
|
/* Wait until a data is received */ |
||||
|
while (RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP)) |
||||
|
; |
||||
|
/* Get the received data */ |
||||
|
data = spi_i2s_data_receive(spi_periph); |
||||
|
|
||||
|
if (recv_ptr != RT_NULL) |
||||
|
{ |
||||
|
*recv_ptr++ = data; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#endif |
||||
|
else |
||||
|
{ |
||||
|
return -RT_EIO; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* release CS */ |
||||
|
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) |
||||
|
{ |
||||
|
if (device->config.mode & RT_SPI_CS_HIGH) |
||||
|
rt_pin_write(device->cs_pin, PIN_LOW); |
||||
|
else |
||||
|
rt_pin_write(device->cs_pin, PIN_HIGH); |
||||
|
} |
||||
|
|
||||
|
return message->length; |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* Attach the spi device to SPI bus, this function must be used after initialization. |
||||
|
*/ |
||||
|
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin) |
||||
|
{ |
||||
|
RT_ASSERT(bus_name != RT_NULL); |
||||
|
RT_ASSERT(device_name != RT_NULL); |
||||
|
|
||||
|
rt_err_t result; |
||||
|
struct rt_spi_device *spi_device; |
||||
|
|
||||
|
/* attach the device to spi bus*/ |
||||
|
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); |
||||
|
RT_ASSERT(spi_device != RT_NULL); |
||||
|
|
||||
|
if (cs_pin != PIN_NONE) |
||||
|
{ |
||||
|
/* initialize the cs pin && select the slave*/ |
||||
|
rt_pin_mode(cs_pin, PIN_MODE_OUTPUT); |
||||
|
rt_pin_write(cs_pin, PIN_HIGH); |
||||
|
} |
||||
|
|
||||
|
result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL); |
||||
|
|
||||
|
if (result != RT_EOK) |
||||
|
{ |
||||
|
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result); |
||||
|
} |
||||
|
|
||||
|
RT_ASSERT(result == RT_EOK); |
||||
|
|
||||
|
LOG_D("%s attach to %s done", device_name, bus_name); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
int rt_hw_spi_init(void) |
||||
|
{ |
||||
|
int result = 0; |
||||
|
int i; |
||||
|
|
||||
|
for (i = 0; i < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); i++) |
||||
|
{ |
||||
|
spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i]; |
||||
|
|
||||
|
result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &gd32_spi_ops); |
||||
|
|
||||
|
RT_ASSERT(result == RT_EOK); |
||||
|
|
||||
|
LOG_D("%s bus init done", spi_bus_obj[i].bus_name); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
INIT_BOARD_EXPORT(rt_hw_spi_init); |
||||
|
|
||||
|
#endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */ |
||||
|
#endif /* RT_USING_SPI */ |
||||
|
|
||||
File diff suppressed because it is too large
@ -0,0 +1,149 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2022-01-25 iysheng first version |
||||
|
* 2025-10-09 kurisaw fix inaccurate WDT clock timeout feeding issue |
||||
|
*/ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <rthw.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#define DBG_TAG "drv.wdt" |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#include <rtdbg.h> |
||||
|
|
||||
|
#ifdef RT_USING_WDT |
||||
|
|
||||
|
/* User-configurable macros for WDT clock source and prescaler */ |
||||
|
/* Default select oscillator type: RCU_IRC32K */ |
||||
|
#define WDT_OSCI_TYPE RCU_IRC32K |
||||
|
|
||||
|
/* Prescaler divider value (must match WDT_PSC_VALUE) */ |
||||
|
#define WDT_PSC_DIVIDER 256U |
||||
|
/* Prescaler register value */ |
||||
|
#define WDT_PSC_VALUE FWDGT_PSC_DIV256 |
||||
|
|
||||
|
/* Derived values */ |
||||
|
#define WDT_CLOCK_FREQ IRC32K_VALUE |
||||
|
|
||||
|
#define WDT_TICK_HZ (WDT_CLOCK_FREQ / WDT_PSC_DIVIDER) |
||||
|
#define WDT_MAX_RELOAD_VALUE 0xfffU |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
struct rt_watchdog_device wdt; |
||||
|
rt_uint32_t min_threshold_s; |
||||
|
rt_uint32_t max_threshold_s; |
||||
|
rt_uint32_t current_threshold_s; |
||||
|
} gd32_wdt_device_t; |
||||
|
|
||||
|
static gd32_wdt_device_t g_wdt_dev; |
||||
|
|
||||
|
static rt_err_t gd32_wdt_init(rt_watchdog_t *wdt) |
||||
|
{ |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
/* Enable and wait for oscillator stabilization */ |
||||
|
rcu_osci_on(WDT_OSCI_TYPE); |
||||
|
if (ERROR == rcu_osci_stab_wait(WDT_OSCI_TYPE)) |
||||
|
{ |
||||
|
LOG_E("failed init %u clock for free watchdog.", WDT_OSCI_TYPE); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
/* Calculate thresholds */ |
||||
|
g_wdt_dev.min_threshold_s = 1U; |
||||
|
g_wdt_dev.max_threshold_s = ((WDT_MAX_RELOAD_VALUE + 1U) * WDT_PSC_DIVIDER) / WDT_CLOCK_FREQ; |
||||
|
LOG_I("WDT clock: %u Hz (tick: %u Hz), threshold section [%u, %u]", |
||||
|
WDT_CLOCK_FREQ, WDT_TICK_HZ, |
||||
|
g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s); |
||||
|
|
||||
|
/* Configure FWDGT with max timeout */ |
||||
|
fwdgt_write_enable(); |
||||
|
if (fwdgt_config(WDT_MAX_RELOAD_VALUE, WDT_PSC_VALUE) != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("failed to configure FWDGT"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
fwdgt_enable(); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t gd32_wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) |
||||
|
{ |
||||
|
rt_uint32_t param; |
||||
|
|
||||
|
switch (cmd) |
||||
|
{ |
||||
|
case RT_DEVICE_CTRL_WDT_KEEPALIVE: |
||||
|
fwdgt_counter_reload(); |
||||
|
break; |
||||
|
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: |
||||
|
param = *(rt_uint32_t *)arg; |
||||
|
if ((param > g_wdt_dev.max_threshold_s) || |
||||
|
(param < g_wdt_dev.min_threshold_s)) |
||||
|
{ |
||||
|
LOG_E("invalid param@%u (out of [%u, %u])", param, |
||||
|
g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s); |
||||
|
return -RT_EINVAL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
g_wdt_dev.current_threshold_s = param; |
||||
|
rt_uint32_t reload_value = (param * WDT_TICK_HZ) - 1U; |
||||
|
fwdgt_write_enable(); |
||||
|
if (fwdgt_config(reload_value, WDT_PSC_VALUE) != SUCCESS) |
||||
|
{ |
||||
|
LOG_E("failed to set timeout %u s", param); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
fwdgt_write_disable(); |
||||
|
} |
||||
|
break; |
||||
|
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: |
||||
|
*(rt_uint32_t *)arg = g_wdt_dev.current_threshold_s; |
||||
|
break; |
||||
|
case RT_DEVICE_CTRL_WDT_START: |
||||
|
fwdgt_enable(); |
||||
|
break; |
||||
|
default: |
||||
|
LOG_W("This command is not supported."); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static struct rt_watchdog_ops g_wdt_ops = { |
||||
|
gd32_wdt_init, |
||||
|
gd32_wdt_control, |
||||
|
}; |
||||
|
|
||||
|
static int rt_hw_wdt_init(void) |
||||
|
{ |
||||
|
rt_err_t ret = RT_EOK; |
||||
|
|
||||
|
g_wdt_dev.wdt.ops = &g_wdt_ops; |
||||
|
/* register watchdog device */ |
||||
|
if (rt_hw_watchdog_register(&g_wdt_dev.wdt, "wdt", |
||||
|
RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK) |
||||
|
{ |
||||
|
LOG_E("wdt device register failed."); |
||||
|
ret = -RT_ERROR; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
LOG_D("wdt device register success."); |
||||
|
} |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
INIT_PREV_EXPORT(rt_hw_wdt_init); |
||||
|
#endif |
||||
@ -0,0 +1,438 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-15 LZerro compatible with RT-Studio |
||||
|
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __ADC_CONFIG_H__ |
||||
|
#define __ADC_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" |
||||
|
{ |
||||
|
#endif |
||||
|
|
||||
|
#include "drv_adc.h" |
||||
|
|
||||
|
#ifdef RT_USING_ADC |
||||
|
#define MAX_EXTERN_ADC_CHANNEL 20 |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_ADC0 |
||||
|
#ifdef BSP_ADC0_CH0_PIN |
||||
|
#define ADC0_CH0_PIN BSP_ADC0_CH0_PIN |
||||
|
#else |
||||
|
#define ADC0_CH0_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH1_PIN |
||||
|
#define ADC0_CH1_PIN BSP_ADC0_CH1_PIN |
||||
|
#else |
||||
|
#define ADC0_CH1_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH2_PIN |
||||
|
#define ADC0_CH2_PIN BSP_ADC0_CH2_PIN |
||||
|
#else |
||||
|
#define ADC0_CH2_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH3_PIN |
||||
|
#define ADC0_CH3_PIN BSP_ADC0_CH3_PIN |
||||
|
#else |
||||
|
#define ADC0_CH3_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH4_PIN |
||||
|
#define ADC0_CH4_PIN BSP_ADC0_CH4_PIN |
||||
|
#else |
||||
|
#define ADC0_CH4_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH5_PIN |
||||
|
#define ADC0_CH5_PIN BSP_ADC0_CH5_PIN |
||||
|
#else |
||||
|
#define ADC0_CH5_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH6_PIN |
||||
|
#define ADC0_CH6_PIN BSP_ADC0_CH6_PIN |
||||
|
#else |
||||
|
#define ADC0_CH6_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH7_PIN |
||||
|
#define ADC0_CH7_PIN BSP_ADC0_CH7_PIN |
||||
|
#else |
||||
|
#define ADC0_CH7_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH8_PIN |
||||
|
#define ADC0_CH8_PIN BSP_ADC0_CH8_PIN |
||||
|
#else |
||||
|
#define ADC0_CH8_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH9_PIN |
||||
|
#define ADC0_CH9_PIN BSP_ADC0_CH9_PIN |
||||
|
#else |
||||
|
#define ADC0_CH9_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH10_PIN |
||||
|
#define ADC0_CH10_PIN BSP_ADC0_CH10_PIN |
||||
|
#else |
||||
|
#define ADC0_CH10_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH11_PIN |
||||
|
#define ADC0_CH11_PIN BSP_ADC0_CH11_PIN |
||||
|
#else |
||||
|
#define ADC0_CH11_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH12_PIN |
||||
|
#define ADC0_CH12_PIN BSP_ADC0_CH12_PIN |
||||
|
#else |
||||
|
#define ADC0_CH12_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH13_PIN |
||||
|
#define ADC0_CH13_PIN BSP_ADC0_CH13_PIN |
||||
|
#else |
||||
|
#define ADC0_CH13_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH14_PIN |
||||
|
#define ADC0_CH14_PIN BSP_ADC0_CH14_PIN |
||||
|
#else |
||||
|
#define ADC0_CH14_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH15_PIN |
||||
|
#define ADC0_CH15_PIN BSP_ADC0_CH15_PIN |
||||
|
#else |
||||
|
#define ADC0_CH15_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH16_PIN |
||||
|
#define ADC0_CH16_PIN BSP_ADC0_CH16_PIN |
||||
|
#else |
||||
|
#define ADC0_CH16_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH17_PIN |
||||
|
#define ADC0_CH17_PIN BSP_ADC0_CH17_PIN |
||||
|
#else |
||||
|
#define ADC0_CH17_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH18_PIN |
||||
|
#define ADC0_CH18_PIN BSP_ADC0_CH18_PIN |
||||
|
#else |
||||
|
#define ADC0_CH18_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC0_CH19_PIN |
||||
|
#define ADC0_CH19_PIN BSP_ADC0_CH19_PIN |
||||
|
#else |
||||
|
#define ADC0_CH19_PIN RT_NULL |
||||
|
#endif |
||||
|
|
||||
|
#ifndef ADC0_CONFIG |
||||
|
#define ADC0_CONFIG \ |
||||
|
{ \ |
||||
|
ADC0, \ |
||||
|
RCU_ADC0, \ |
||||
|
{ \ |
||||
|
ADC0_CH0_PIN, \ |
||||
|
ADC0_CH1_PIN, \ |
||||
|
ADC0_CH2_PIN, \ |
||||
|
ADC0_CH3_PIN, \ |
||||
|
ADC0_CH4_PIN, \ |
||||
|
ADC0_CH5_PIN, \ |
||||
|
ADC0_CH6_PIN, \ |
||||
|
ADC0_CH7_PIN, \ |
||||
|
ADC0_CH8_PIN, \ |
||||
|
ADC0_CH9_PIN, \ |
||||
|
ADC0_CH10_PIN, \ |
||||
|
ADC0_CH11_PIN, \ |
||||
|
ADC0_CH12_PIN, \ |
||||
|
ADC0_CH13_PIN, \ |
||||
|
ADC0_CH14_PIN, \ |
||||
|
ADC0_CH15_PIN, \ |
||||
|
ADC0_CH16_PIN, \ |
||||
|
ADC0_CH17_PIN, \ |
||||
|
ADC0_CH18_PIN, \ |
||||
|
ADC0_CH19_PIN, \ |
||||
|
}, \ |
||||
|
&adc0, \ |
||||
|
"adc0", \ |
||||
|
} |
||||
|
#endif /* ADC0_CONFIG */ |
||||
|
#endif /* BSP_USING_ADC0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_ADC1 |
||||
|
#ifdef BSP_ADC1_CH0_PIN |
||||
|
#define ADC1_CH0_PIN BSP_ADC1_CH0_PIN |
||||
|
#else |
||||
|
#define ADC1_CH0_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH1_PIN |
||||
|
#define ADC1_CH1_PIN BSP_ADC1_CH1_PIN |
||||
|
#else |
||||
|
#define ADC1_CH1_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH2_PIN |
||||
|
#define ADC1_CH2_PIN BSP_ADC1_CH2_PIN |
||||
|
#else |
||||
|
#define ADC1_CH2_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH3_PIN |
||||
|
#define ADC1_CH3_PIN BSP_ADC1_CH3_PIN |
||||
|
#else |
||||
|
#define ADC1_CH3_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH4_PIN |
||||
|
#define ADC1_CH4_PIN BSP_ADC1_CH4_PIN |
||||
|
#else |
||||
|
#define ADC1_CH4_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH5_PIN |
||||
|
#define ADC1_CH5_PIN BSP_ADC1_CH5_PIN |
||||
|
#else |
||||
|
#define ADC1_CH5_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH6_PIN |
||||
|
#define ADC1_CH6_PIN BSP_ADC1_CH6_PIN |
||||
|
#else |
||||
|
#define ADC1_CH6_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH7_PIN |
||||
|
#define ADC1_CH7_PIN BSP_ADC1_CH7_PIN |
||||
|
#else |
||||
|
#define ADC1_CH7_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH8_PIN |
||||
|
#define ADC1_CH8_PIN BSP_ADC1_CH8_PIN |
||||
|
#else |
||||
|
#define ADC1_CH8_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH9_PIN |
||||
|
#define ADC1_CH9_PIN BSP_ADC1_CH9_PIN |
||||
|
#else |
||||
|
#define ADC1_CH9_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH10_PIN |
||||
|
#define ADC1_CH10_PIN BSP_ADC1_CH10_PIN |
||||
|
#else |
||||
|
#define ADC1_CH10_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH11_PIN |
||||
|
#define ADC1_CH11_PIN BSP_ADC1_CH11_PIN |
||||
|
#else |
||||
|
#define ADC1_CH11_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH12_PIN |
||||
|
#define ADC1_CH12_PIN BSP_ADC1_CH12_PIN |
||||
|
#else |
||||
|
#define ADC1_CH12_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH13_PIN |
||||
|
#define ADC1_CH13_PIN BSP_ADC1_CH13_PIN |
||||
|
#else |
||||
|
#define ADC1_CH13_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH14_PIN |
||||
|
#define ADC1_CH14_PIN BSP_ADC1_CH14_PIN |
||||
|
#else |
||||
|
#define ADC1_CH14_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH15_PIN |
||||
|
#define ADC1_CH15_PIN BSP_ADC1_CH15_PIN |
||||
|
#else |
||||
|
#define ADC1_CH15_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH16_PIN |
||||
|
#define ADC1_CH16_PIN BSP_ADC1_CH16_PIN |
||||
|
#else |
||||
|
#define ADC1_CH16_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH17_PIN |
||||
|
#define ADC1_CH17_PIN BSP_ADC1_CH17_PIN |
||||
|
#else |
||||
|
#define ADC1_CH17_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH18_PIN |
||||
|
#define ADC1_CH18_PIN BSP_ADC1_CH18_PIN |
||||
|
#else |
||||
|
#define ADC1_CH18_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC1_CH19_PIN |
||||
|
#define ADC1_CH19_PIN BSP_ADC1_CH19_PIN |
||||
|
#else |
||||
|
#define ADC1_CH19_PIN RT_NULL |
||||
|
#endif |
||||
|
|
||||
|
#ifndef ADC1_CONFIG |
||||
|
#define ADC1_CONFIG \ |
||||
|
{ \ |
||||
|
ADC1, \ |
||||
|
RCU_ADC1, \ |
||||
|
{ \ |
||||
|
ADC1_CH0_PIN, \ |
||||
|
ADC1_CH1_PIN, \ |
||||
|
ADC1_CH2_PIN, \ |
||||
|
ADC1_CH3_PIN, \ |
||||
|
ADC1_CH4_PIN, \ |
||||
|
ADC1_CH5_PIN, \ |
||||
|
ADC1_CH6_PIN, \ |
||||
|
ADC1_CH7_PIN, \ |
||||
|
ADC1_CH8_PIN, \ |
||||
|
ADC1_CH9_PIN, \ |
||||
|
ADC1_CH10_PIN, \ |
||||
|
ADC1_CH11_PIN, \ |
||||
|
ADC1_CH12_PIN, \ |
||||
|
ADC1_CH13_PIN, \ |
||||
|
ADC1_CH14_PIN, \ |
||||
|
ADC1_CH15_PIN, \ |
||||
|
ADC1_CH16_PIN, \ |
||||
|
ADC1_CH17_PIN, \ |
||||
|
ADC1_CH18_PIN, \ |
||||
|
ADC1_CH19_PIN, \ |
||||
|
}, \ |
||||
|
&adc1, \ |
||||
|
"adc1", \ |
||||
|
} |
||||
|
#endif /* ADC1_CONFIG */ |
||||
|
#endif /* BSP_USING_ADC1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_ADC2 |
||||
|
#ifdef BSP_ADC2_CH0_PIN |
||||
|
#define ADC2_CH0_PIN BSP_ADC2_CH0_PIN |
||||
|
#else |
||||
|
#define ADC2_CH0_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH1_PIN |
||||
|
#define ADC2_CH1_PIN BSP_ADC2_CH1_PIN |
||||
|
#else |
||||
|
#define ADC2_CH1_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH2_PIN |
||||
|
#define ADC2_CH2_PIN BSP_ADC2_CH2_PIN |
||||
|
#else |
||||
|
#define ADC2_CH2_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH3_PIN |
||||
|
#define ADC2_CH3_PIN BSP_ADC2_CH3_PIN |
||||
|
#else |
||||
|
#define ADC2_CH3_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH4_PIN |
||||
|
#define ADC2_CH4_PIN BSP_ADC2_CH4_PIN |
||||
|
#else |
||||
|
#define ADC2_CH4_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH5_PIN |
||||
|
#define ADC2_CH5_PIN BSP_ADC2_CH5_PIN |
||||
|
#else |
||||
|
#define ADC2_CH5_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH6_PIN |
||||
|
#define ADC2_CH6_PIN BSP_ADC2_CH6_PIN |
||||
|
#else |
||||
|
#define ADC2_CH6_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH7_PIN |
||||
|
#define ADC2_CH7_PIN BSP_ADC2_CH7_PIN |
||||
|
#else |
||||
|
#define ADC2_CH7_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH8_PIN |
||||
|
#define ADC2_CH8_PIN BSP_ADC2_CH8_PIN |
||||
|
#else |
||||
|
#define ADC2_CH8_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH9_PIN |
||||
|
#define ADC2_CH9_PIN BSP_ADC2_CH9_PIN |
||||
|
#else |
||||
|
#define ADC2_CH9_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH10_PIN |
||||
|
#define ADC2_CH10_PIN BSP_ADC2_CH10_PIN |
||||
|
#else |
||||
|
#define ADC2_CH10_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH11_PIN |
||||
|
#define ADC2_CH11_PIN BSP_ADC2_CH11_PIN |
||||
|
#else |
||||
|
#define ADC2_CH11_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH12_PIN |
||||
|
#define ADC2_CH12_PIN BSP_ADC2_CH12_PIN |
||||
|
#else |
||||
|
#define ADC2_CH12_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH13_PIN |
||||
|
#define ADC2_CH13_PIN BSP_ADC2_CH13_PIN |
||||
|
#else |
||||
|
#define ADC2_CH13_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH14_PIN |
||||
|
#define ADC2_CH14_PIN BSP_ADC2_CH14_PIN |
||||
|
#else |
||||
|
#define ADC2_CH14_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH15_PIN |
||||
|
#define ADC2_CH15_PIN BSP_ADC2_CH15_PIN |
||||
|
#else |
||||
|
#define ADC2_CH15_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH16_PIN |
||||
|
#define ADC2_CH16_PIN BSP_ADC2_CH16_PIN |
||||
|
#else |
||||
|
#define ADC2_CH16_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH17_PIN |
||||
|
#define ADC2_CH17_PIN BSP_ADC2_CH17_PIN |
||||
|
#else |
||||
|
#define ADC2_CH17_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH18_PIN |
||||
|
#define ADC2_CH18_PIN BSP_ADC2_CH18_PIN |
||||
|
#else |
||||
|
#define ADC2_CH18_PIN RT_NULL |
||||
|
#endif |
||||
|
#ifdef BSP_ADC2_CH19_PIN |
||||
|
#define ADC2_CH19_PIN BSP_ADC2_CH19_PIN |
||||
|
#else |
||||
|
#define ADC2_CH19_PIN RT_NULL |
||||
|
#endif |
||||
|
|
||||
|
#ifndef ADC2_CONFIG |
||||
|
#define ADC2_CONFIG \ |
||||
|
{ \ |
||||
|
ADC2, \ |
||||
|
RCU_ADC2, \ |
||||
|
{ \ |
||||
|
ADC2_CH0_PIN, \ |
||||
|
ADC2_CH1_PIN, \ |
||||
|
ADC2_CH2_PIN, \ |
||||
|
ADC2_CH3_PIN, \ |
||||
|
ADC2_CH4_PIN, \ |
||||
|
ADC2_CH5_PIN, \ |
||||
|
ADC2_CH6_PIN, \ |
||||
|
ADC2_CH7_PIN, \ |
||||
|
ADC2_CH8_PIN, \ |
||||
|
ADC2_CH9_PIN, \ |
||||
|
ADC2_CH10_PIN, \ |
||||
|
ADC2_CH11_PIN, \ |
||||
|
ADC2_CH12_PIN, \ |
||||
|
ADC2_CH13_PIN, \ |
||||
|
ADC2_CH14_PIN, \ |
||||
|
ADC2_CH15_PIN, \ |
||||
|
ADC2_CH16_PIN, \ |
||||
|
ADC2_CH17_PIN, \ |
||||
|
ADC2_CH18_PIN, \ |
||||
|
ADC2_CH19_PIN, \ |
||||
|
}, \ |
||||
|
&adc2, \ |
||||
|
"adc2", \ |
||||
|
} |
||||
|
#endif /* ADC2_CONFIG */ |
||||
|
#endif /* BSP_USING_ADC2 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif // __ADC_CONFIG_H__
|
||||
@ -0,0 +1,83 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-22 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __CAN_CONFIG_H__ |
||||
|
#define __CAN_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_CAN0) |
||||
|
#ifndef BSP_CAN0_RX_PIN |
||||
|
#define BSP_CAN0_RX_PIN "PD0" |
||||
|
#define BSP_CAN0_TX_PIN "PD1" |
||||
|
#define BSP_CAN0_AFIO "AF9" |
||||
|
#endif /* BSP_CAN0_RX_PIN */ |
||||
|
#ifndef CAN0_CONFIG |
||||
|
#define CAN0_CONFIG \ |
||||
|
{ \ |
||||
|
.name = "can0", \ |
||||
|
.can_periph = CAN0, \ |
||||
|
.tx_pin_name = BSP_CAN0_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_CAN0_RX_PIN, \ |
||||
|
.alternate = BSP_CAN0_AFIO, \ |
||||
|
.device = &dev_can0, \ |
||||
|
} |
||||
|
#endif /* CAN0_CONFIG */ |
||||
|
#endif /* BSP_USING_CAN0 */ |
||||
|
|
||||
|
#if defined(BSP_USING_CAN1) |
||||
|
#ifndef BSP_CAN1_RX_PIN |
||||
|
#define BSP_CAN1_RX_PIN "PB5" |
||||
|
#define BSP_CAN1_TX_PIN "PB6" |
||||
|
#define BSP_CAN1_AFIO "AF9" |
||||
|
#endif /* BSP_CAN0_RX_PIN */ |
||||
|
#ifndef CAN1_CONFIG |
||||
|
#define CAN1_CONFIG \ |
||||
|
{ \ |
||||
|
.name = "can1", \ |
||||
|
.can_periph = CAN1, \ |
||||
|
.tx_pin_name = BSP_CAN1_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_CAN1_RX_PIN, \ |
||||
|
.alternate = BSP_CAN1_AFIO, \ |
||||
|
.device = &dev_can1, \ |
||||
|
} |
||||
|
#endif /* CAN1_CONFIG */ |
||||
|
#endif /* BSP_USING_CAN1 */ |
||||
|
|
||||
|
#if defined(BSP_USING_CAN2) |
||||
|
#ifndef BSP_CAN2_RX_PIN |
||||
|
#define BSP_CAN2_RX_PIN "PD12" |
||||
|
#define BSP_CAN2_TX_PIN "PD13" |
||||
|
#define BSP_CAN2_AFIO "AF5" |
||||
|
#endif /* BSP_CAN2_RX_PIN */ |
||||
|
#ifndef CAN2_CONFIG |
||||
|
#define CAN2_CONFIG \ |
||||
|
{ \ |
||||
|
.name = "can2", \ |
||||
|
.can_periph = CAN2, \ |
||||
|
.tx_pin_name = BSP_CAN2_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_CAN2_RX_PIN, \ |
||||
|
.alternate = BSP_CAN2_AFIO, \ |
||||
|
.device = &dev_can2, \ |
||||
|
} |
||||
|
#endif /* CAN2_CONFIG */ |
||||
|
#endif /* BSP_USING_CAN2 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __CAN_CONFIG_H__ */ |
||||
|
|
||||
@ -0,0 +1,51 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-11 kurisaw first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DAC_CONFIG_H__ |
||||
|
#define __DAC_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_DAC0 |
||||
|
|
||||
|
#ifndef DAC0_CONFIG |
||||
|
#define DAC0_CONFIG \ |
||||
|
{ \ |
||||
|
.dac_periph = DAC0, \ |
||||
|
.name = "dac0", \ |
||||
|
.pin_name = BSP_DAC0_PIN, \ |
||||
|
.channel = BSP_DAC0_CHANNEL, \ |
||||
|
} |
||||
|
#endif /* DAC0_CONFIG */ |
||||
|
#endif /* BSP_USING_DAC0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_DAC1 |
||||
|
|
||||
|
#ifndef DAC1_CONFIG |
||||
|
#define DAC1_CONFIG \ |
||||
|
{ \ |
||||
|
.dac_periph = DAC0, \ |
||||
|
.name = "dac1", \ |
||||
|
.pin_name = BSP_DAC1_PIN, \ |
||||
|
.channel = BSP_DAC1_CHANNEL, \ |
||||
|
} |
||||
|
#endif /* DAC1_CONFIG */ |
||||
|
#endif /* BSP_USING_DAC1 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /*__DAC_CONFIG_H__ */ |
||||
@ -0,0 +1,59 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-10 kurisaw ENET configuration |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __ENET_CONFIG_H__ |
||||
|
#define __ENET_CONFIG_H__ |
||||
|
|
||||
|
#include "drv_enet.h" |
||||
|
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP) |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
/* ENET pin configuration table for RMII interface */ |
||||
|
const struct enet_pin_config enet0_pins[] = |
||||
|
{ |
||||
|
/* ETH_RMII_REF_CLK */ {"PA1", "AF11"}, |
||||
|
/* ETH_MDIO */ {"PA2", "AF11"}, |
||||
|
/* ETH_RMII_CRS_DV */ {"PA7", "AF11"}, |
||||
|
/* ETH_RMII_TX_EN */ {"PG11", "AF11"}, |
||||
|
/* ETH_RMII_TXD0 */ {"PB12", "AF11"}, |
||||
|
/* ETH_RMII_TXD1 */ {"PG12", "AF11"}, |
||||
|
/* ETH_MDC */ {"PC1", "AF11"}, |
||||
|
/* ETH_RMII_RXD0 */ {"PC4", "AF11"}, |
||||
|
/* ETH_RMII_RXD1 */ {"PC5", "AF11"}, |
||||
|
}; |
||||
|
|
||||
|
/* Clock output pin for PHY */ |
||||
|
const struct enet_pin_config enet_clock_pin = { |
||||
|
"PA8", "AF0" /* Clock output for PHY */ |
||||
|
}; |
||||
|
|
||||
|
/* ENET configuration */ |
||||
|
const struct enet_config enet0_cfg = { |
||||
|
.pins = enet0_pins, |
||||
|
.pin_count = sizeof(enet0_pins) / sizeof(enet0_pins[0]), |
||||
|
.enet_periph = ENET0, |
||||
|
.enet_clk = RCU_ENET0, |
||||
|
.enet_tx_clk = RCU_ENET0TX, |
||||
|
.enet_rx_clk = RCU_ENET0RX, |
||||
|
.phy_interface = SYSCFG_ENET_PHY_RMII, |
||||
|
.speed = GPIO_OSPEED_100_220MHZ, |
||||
|
.otype = GPIO_OTYPE_PP, |
||||
|
.pupd = GPIO_PUPD_NONE, |
||||
|
}; |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */ |
||||
|
#endif /* __ENET_CONFIG_H__ */ |
||||
@ -0,0 +1,195 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-22 kurisaw initial commit |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __HWTIMER_CONFIG_H__ |
||||
|
#define __HWTIMER_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#include "drv_hwtimer.h" |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER0 |
||||
|
#ifndef HWTIMER0_CONFIG |
||||
|
#define HWTIMER0_CONFIG \ |
||||
|
{ \ |
||||
|
"timer0", \ |
||||
|
{ \ |
||||
|
TIMER0, \ |
||||
|
TIMER0_UP_IRQn, \ |
||||
|
RCU_TIMER0, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, /* max frequency */ \ |
||||
|
1000, /* min frequency */ \ |
||||
|
0xFFFF, /* 16-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, /* count up mode */ \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER0_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER1 |
||||
|
#ifndef HWTIMER1_CONFIG |
||||
|
#define HWTIMER1_CONFIG \ |
||||
|
{ \ |
||||
|
"timer1", \ |
||||
|
{ \ |
||||
|
TIMER1, \ |
||||
|
TIMER1_IRQn, \ |
||||
|
RCU_TIMER1, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFFFFFF, /* 32-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER1_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER2 |
||||
|
#ifndef HWTIMER2_CONFIG |
||||
|
#define HWTIMER2_CONFIG \ |
||||
|
{ \ |
||||
|
"timer2", \ |
||||
|
{ \ |
||||
|
TIMER2, \ |
||||
|
TIMER2_IRQn, \ |
||||
|
RCU_TIMER2, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFF, /* 16-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER2_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER2 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER3 |
||||
|
#ifndef HWTIMER3_CONFIG |
||||
|
#define HWTIMER3_CONFIG \ |
||||
|
{ \ |
||||
|
"timer3", \ |
||||
|
{ \ |
||||
|
TIMER3, \ |
||||
|
TIMER3_IRQn, \ |
||||
|
RCU_TIMER3, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFF, /* 16-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER3_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER3 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER4 |
||||
|
#ifndef HWTIMER4_CONFIG |
||||
|
#define HWTIMER4_CONFIG \ |
||||
|
{ \ |
||||
|
"timer4", \ |
||||
|
{ \ |
||||
|
TIMER4, \ |
||||
|
TIMER4_IRQn, \ |
||||
|
RCU_TIMER4, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFFFFFF, /* 32-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER4_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER4 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER5 |
||||
|
#ifndef HWTIMER5_CONFIG |
||||
|
#define HWTIMER5_CONFIG \ |
||||
|
{ \ |
||||
|
"timer5", \ |
||||
|
{ \ |
||||
|
TIMER5, \ |
||||
|
TIMER5_IRQn, \ |
||||
|
RCU_TIMER5, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFFFFFF, /* 32-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER5_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER5 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER6 |
||||
|
#ifndef HWTIMER6_CONFIG |
||||
|
#define HWTIMER6_CONFIG \ |
||||
|
{ \ |
||||
|
"timer6", \ |
||||
|
{ \ |
||||
|
TIMER6, \ |
||||
|
TIMER6_IRQn, \ |
||||
|
RCU_TIMER6, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFFFFFF, /* 32-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER6_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER6 */ |
||||
|
|
||||
|
#ifdef BSP_USING_HWTIMER7 |
||||
|
#ifndef HWTIMER7_CONFIG |
||||
|
#define HWTIMER7_CONFIG \ |
||||
|
{ \ |
||||
|
"timer7", \ |
||||
|
{ \ |
||||
|
TIMER7, \ |
||||
|
TIMER7_UP_IRQn, \ |
||||
|
RCU_TIMER7, \ |
||||
|
}, \ |
||||
|
{ 0 }, \ |
||||
|
{ \ |
||||
|
10000000, \ |
||||
|
1000, \ |
||||
|
0xFFFF, /* 16-bit counter */ \ |
||||
|
HWTIMER_CNTMODE_UP, \ |
||||
|
}, \ |
||||
|
} |
||||
|
#endif /* HWTIMER7_CONFIG */ |
||||
|
#endif /* BSP_USING_HWTIMER7 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __HWTIMER_CONFIG_H__ */ |
||||
@ -0,0 +1,146 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __I2C_CONFIG_H__ |
||||
|
#define __I2C_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_I2C0 |
||||
|
#ifndef BSP_I2C0_SCL_PIN |
||||
|
#define BSP_I2C0_SCL_PIN "PB6" |
||||
|
#define BSP_I2C0_SDA_PIN "PB7" |
||||
|
#define BSP_I2C0_AFIO "AF4" |
||||
|
#endif /* BSP_I2C0_SCL_PIN */ |
||||
|
#ifndef I2C0_CONFIG |
||||
|
#define I2C0_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C0, \ |
||||
|
.per_clk = RCU_I2C0, \ |
||||
|
.scl_pin_name = BSP_I2C0_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C0_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C0_AFIO, \ |
||||
|
.i2c_bus = &i2c0, \ |
||||
|
.device_name = "i2c0", \ |
||||
|
} |
||||
|
#endif /* I2C0_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_I2C1 |
||||
|
#ifndef BSP_I2C1_SCL_PIN |
||||
|
#define BSP_I2C1_SCL_PIN "PH4" |
||||
|
#define BSP_I2C1_SDA_PIN "PB11" |
||||
|
#define BSP_I2C1_AFIO "AF4" |
||||
|
#endif /* BSP_I2C1_SCL_PIN */ |
||||
|
#ifndef I2C1_CONFIG |
||||
|
#define I2C1_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C1, \ |
||||
|
.per_clk = RCU_I2C1, \ |
||||
|
.scl_pin_name = BSP_I2C1_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C1_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C1_AFIO, \ |
||||
|
.i2c_bus = &i2c1, \ |
||||
|
.device_name = "i2c1", \ |
||||
|
} |
||||
|
#endif /* I2C1_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_I2C2 |
||||
|
#ifndef BSP_I2C2_SCL_PIN |
||||
|
#define BSP_I2C2_SCL_PIN "PA8" |
||||
|
#define BSP_I2C2_SDA_PIN "PC9" |
||||
|
#define BSP_I2C2_AFIO "AF4" |
||||
|
#endif /* BSP_I2C2_SCL_PIN */ |
||||
|
#ifndef I2C2_CONFIG |
||||
|
#define I2C2_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C2, \ |
||||
|
.per_clk = RCU_I2C2, \ |
||||
|
.scl_pin_name = BSP_I2C2_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C2_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C2_AFIO, \ |
||||
|
.i2c_bus = &i2c2, \ |
||||
|
.device_name = "i2c2", \ |
||||
|
} |
||||
|
#endif /* I2C2_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C2 */ |
||||
|
|
||||
|
#ifdef BSP_USING_I2C3 |
||||
|
#ifndef BSP_I2C3_SCL_PIN |
||||
|
#define BSP_I2C3_SCL_PIN "PD12" |
||||
|
#define BSP_I2C3_SDA_PIN "PD13" |
||||
|
#define BSP_I2C3_AFIO "AF4" |
||||
|
#endif /* BSP_I2C3_SCL_PIN */ |
||||
|
#ifndef I2C3_CONFIG |
||||
|
#define I2C3_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C3, \ |
||||
|
.per_clk = RCU_I2C3, \ |
||||
|
.scl_pin_name = BSP_I2C3_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C3_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C3_AFIO, \ |
||||
|
.i2c_bus = &i2c3, \ |
||||
|
.device_name = "i2c3", \ |
||||
|
} |
||||
|
#endif /* I2C3_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C3 */ |
||||
|
|
||||
|
#ifdef BSP_USING_I2C4 |
||||
|
#ifndef BSP_I2C4_SCL_PIN |
||||
|
#define BSP_I2C4_SCL_PIN "PG7" |
||||
|
#define BSP_I2C4_SDA_PIN "PG8" |
||||
|
#define BSP_I2C4_AFIO "AF6" |
||||
|
#endif /* BSP_I2C4_SCL_PIN */ |
||||
|
#ifndef I2C4_CONFIG |
||||
|
#define I2C4_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C4, \ |
||||
|
.per_clk = RCU_I2C4, \ |
||||
|
.scl_pin_name = BSP_I2C4_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C4_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C4_AFIO, \ |
||||
|
.i2c_bus = &i2c4, \ |
||||
|
.device_name = "i2c4", \ |
||||
|
} |
||||
|
#endif /* I2C4_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C4 */ |
||||
|
|
||||
|
#ifdef BSP_USING_I2C5 |
||||
|
#ifndef BSP_I2C5_SCL_PIN |
||||
|
#define BSP_I2C5_SCL_PIN "PF11" |
||||
|
#define BSP_I2C5_SDA_PIN "PF12" |
||||
|
#define BSP_I2C5_AFIO "AF4" |
||||
|
#endif /* BSP_I2C5_SCL_PIN */ |
||||
|
#ifndef I2C5_CONFIG |
||||
|
#define I2C5_CONFIG \ |
||||
|
{ \ |
||||
|
.i2c_periph = I2C5, \ |
||||
|
.per_clk = RCU_I2C5, \ |
||||
|
.scl_pin_name = BSP_I2C5_SCL_PIN, \ |
||||
|
.sda_pin_name = BSP_I2C5_SDA_PIN, \ |
||||
|
.alternate = BSP_I2C5_AFIO, \ |
||||
|
.i2c_bus = &i2c5, \ |
||||
|
.device_name = "i2c5", \ |
||||
|
} |
||||
|
#endif /* I2C5_CONFIG */ |
||||
|
#endif /* BSP_USING_I2C5 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /*__I2C_CONFIG_H__ */ |
||||
|
|
||||
@ -0,0 +1,145 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-11 kurisaw compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __PWM_CONFIG_H__ |
||||
|
#define __PWM_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_PWM0 |
||||
|
|
||||
|
#ifndef PWM0_CONFIG |
||||
|
#define PWM0_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER0, \ |
||||
|
.name = "pwm0", \ |
||||
|
.timer_clk = RCU_TIMER0, \ |
||||
|
.pin_name = BSP_PWM0_PIN, \ |
||||
|
.channel = BSP_PWM0_CHANNEL, \ |
||||
|
.alternate = BSP_PWM0_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM0_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM1 |
||||
|
|
||||
|
#ifndef PWM1_CONFIG |
||||
|
#define PWM1_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER1, \ |
||||
|
.name = "pwm1", \ |
||||
|
.timer_clk = RCU_TIMER1, \ |
||||
|
.pin_name = BSP_PWM1_PIN, \ |
||||
|
.channel = BSP_PWM1_CHANNEL, \ |
||||
|
.alternate = BSP_PWM1_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM1_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM2 |
||||
|
|
||||
|
#ifndef PWM2_CONFIG |
||||
|
#define PWM2_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER2, \ |
||||
|
.name = "pwm2", \ |
||||
|
.timer_clk = RCU_TIMER2, \ |
||||
|
.pin_name = BSP_PWM2_PIN, \ |
||||
|
.channel = BSP_PWM2_CHANNEL, \ |
||||
|
.alternate = BSP_PWM2_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM2_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM2 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM3 |
||||
|
|
||||
|
#ifndef PWM3_CONFIG |
||||
|
#define PWM3_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER3, \ |
||||
|
.name = "pwm3", \ |
||||
|
.timer_clk = RCU_TIMER3, \ |
||||
|
.pin_name = BSP_PWM3_PIN, \ |
||||
|
.channel = BSP_PWM3_CHANNEL, \ |
||||
|
.alternate = BSP_PWM3_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM3_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM3 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM4 |
||||
|
|
||||
|
#ifndef PWM4_CONFIG |
||||
|
#define PWM4_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER4, \ |
||||
|
.name = "pwm4", \ |
||||
|
.timer_clk = RCU_TIMER4, \ |
||||
|
.pin_name = BSP_PWM4_PIN, \ |
||||
|
.channel = BSP_PWM4_CHANNEL, \ |
||||
|
.alternate = BSP_PWM4_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM4_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM4 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM5 |
||||
|
|
||||
|
#ifndef PWM5_CONFIG |
||||
|
#define PWM5_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER5, \ |
||||
|
.name = "pwm5", \ |
||||
|
.timer_clk = RCU_TIMER5, \ |
||||
|
.pin_name = BSP_PWM5_PIN, \ |
||||
|
.channel = BSP_PWM5_CHANNEL, \ |
||||
|
.alternate = BSP_PWM5_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM5_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM5 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM6 |
||||
|
|
||||
|
#ifndef PWM6_CONFIG |
||||
|
#define PWM6_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER6, \ |
||||
|
.name = "pwm6", \ |
||||
|
.timer_clk = RCU_TIMER6, \ |
||||
|
.pin_name = BSP_PWM6_PIN, \ |
||||
|
.channel = BSP_PWM6_CHANNEL, \ |
||||
|
.alternate = BSP_PWM6_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM6_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM6 */ |
||||
|
|
||||
|
#ifdef BSP_USING_PWM7 |
||||
|
|
||||
|
#ifndef PWM7_CONFIG |
||||
|
#define PWM7_CONFIG \ |
||||
|
{ \ |
||||
|
.timer_periph = TIMER7, \ |
||||
|
.name = "pwm7", \ |
||||
|
.timer_clk = RCU_TIMER7, \ |
||||
|
.pin_name = BSP_PWM7_PIN, \ |
||||
|
.channel = BSP_PWM7_CHANNEL, \ |
||||
|
.alternate = BSP_PWM7_AFIO, \ |
||||
|
} |
||||
|
#endif /* PWM7_CONFIG */ |
||||
|
#endif /* BSP_USING_PWM7 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /*__PWM_CONFIG_H__ */ |
||||
@ -0,0 +1,178 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2018-11-06 SummerGift first version |
||||
|
* 2019-01-03 zylx modify DMA support |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __SPI_CONFIG_H__ |
||||
|
#define __SPI_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
#define IF_SPI_DMA(x) x |
||||
|
#else |
||||
|
#define IF_SPI_DMA(x) |
||||
|
#endif |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef BSP_USING_SPI0 |
||||
|
#ifndef BSP_SPI0_SCK_PIN |
||||
|
#define BSP_SPI0_SCK_PIN "PA5" |
||||
|
#define BSP_SPI0_MISO_PIN "PA6" |
||||
|
#define BSP_SPI0_MOSI_PIN "PA7" |
||||
|
#define BSP_SPI0_AFIO "AF5" |
||||
|
#endif /* BSP_SPI0_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI0_BUS_CONFIG |
||||
|
#define SPI0_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI0, \ |
||||
|
.bus_name = "spi0", \ |
||||
|
.spi_clk = RCU_SPI0, \ |
||||
|
.spi_bus = &spi_bus0, \ |
||||
|
.sck_pin_name = BSP_SPI0_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI0_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI0_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI0_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[0]) \ |
||||
|
} |
||||
|
#endif /* SPI0_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI0 */ |
||||
|
|
||||
|
#ifdef BSP_USING_SPI1 |
||||
|
#ifndef BSP_SPI1_SCK_PIN |
||||
|
#define BSP_SPI1_SCK_PIN "PB13" |
||||
|
#define BSP_SPI1_MISO_PIN "PB14" |
||||
|
#define BSP_SPI1_MOSI_PIN "PB15" |
||||
|
#define BSP_SPI1_AFIO "AF5" |
||||
|
#endif /* BSP_SPI1_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI1_BUS_CONFIG |
||||
|
#define SPI1_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI1, \ |
||||
|
.bus_name = "spi1", \ |
||||
|
.spi_clk = RCU_SPI1, \ |
||||
|
.spi_bus = &spi_bus1, \ |
||||
|
.sck_pin_name = BSP_SPI1_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI1_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI1_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI1_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[1]) \ |
||||
|
} |
||||
|
#endif /* SPI1_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI1 */ |
||||
|
|
||||
|
#ifdef BSP_USING_SPI2 |
||||
|
#ifndef BSP_SPI2_SCK_PIN |
||||
|
#define BSP_SPI2_SCK_PIN "PB3" |
||||
|
#define BSP_SPI2_MISO_PIN "PB4" |
||||
|
#define BSP_SPI2_MOSI_PIN "PB5" |
||||
|
#define BSP_SPI2_AFIO "AF6" |
||||
|
#endif /* BSP_SPI1_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI2_BUS_CONFIG |
||||
|
#define SPI2_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI2, \ |
||||
|
.bus_name = "spi2", \ |
||||
|
.spi_clk = RCU_SPI2, \ |
||||
|
.spi_bus = &spi_bus2, \ |
||||
|
.sck_pin_name = BSP_SPI2_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI2_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI2_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI2_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[2]) \ |
||||
|
} |
||||
|
#endif /* SPI2_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI2 */ |
||||
|
|
||||
|
#ifdef BSP_USING_SPI3 |
||||
|
#ifndef BSP_SPI3_SCK_PIN |
||||
|
#define BSP_SPI3_SCK_PIN "PE12" |
||||
|
#define BSP_SPI3_MISO_PIN "PE13" |
||||
|
#define BSP_SPI3_MOSI_PIN "PE14" |
||||
|
#define BSP_SPI3_AFIO "AF5" |
||||
|
#endif /* BSP_SPI3_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI3_BUS_CONFIG |
||||
|
#define SPI3_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI3, \ |
||||
|
.bus_name = "spi3", \ |
||||
|
.spi_clk = RCU_SPI3, \ |
||||
|
.spi_bus = &spi_bus3, \ |
||||
|
.sck_pin_name = BSP_SPI3_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI3_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI3_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI3_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[3]) \ |
||||
|
} |
||||
|
#endif /* SPI3_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI3 */ |
||||
|
|
||||
|
#ifdef BSP_USING_SPI4 |
||||
|
#ifndef BSP_SPI4_SCK_PIN |
||||
|
#define BSP_SPI4_SCK_PIN "PF7" |
||||
|
#define BSP_SPI4_MISO_PIN "PF8" |
||||
|
#define BSP_SPI4_MOSI_PIN "PF9" |
||||
|
#define BSP_SPI4_AFIO "AF5" |
||||
|
#endif /* BSP_SPI4_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI4_BUS_CONFIG |
||||
|
#define SPI4_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI4, \ |
||||
|
.bus_name = "spi4", \ |
||||
|
.spi_clk = RCU_SPI4, \ |
||||
|
.spi_bus = &spi_bus4, \ |
||||
|
.sck_pin_name = BSP_SPI4_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI4_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI4_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI4_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[4]) \ |
||||
|
} |
||||
|
#endif /* SPI4_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI4 */ |
||||
|
|
||||
|
#ifdef BSP_USING_SPI5 |
||||
|
#ifndef BSP_SPI5_SCK_PIN |
||||
|
#define BSP_SPI5_SCK_PIN "PG13" |
||||
|
#define BSP_SPI5_MISO_PIN "PG12" |
||||
|
#define BSP_SPI5_MOSI_PIN "PG14" |
||||
|
#define BSP_SPI5_AFIO "AF5" |
||||
|
#endif /* BSP_SPI5_SCK_PIN */ |
||||
|
|
||||
|
#ifndef SPI5_BUS_CONFIG |
||||
|
#define SPI5_BUS_CONFIG \ |
||||
|
{ \ |
||||
|
.spi_periph = SPI5, \ |
||||
|
.bus_name = "spi5", \ |
||||
|
.spi_clk = RCU_SPI5, \ |
||||
|
.spi_bus = &spi_bus5, \ |
||||
|
.sck_pin_name = BSP_SPI5_SCK_PIN, \ |
||||
|
.miso_pin_name = BSP_SPI5_MISO_PIN, \ |
||||
|
.mosi_pin_name = BSP_SPI5_MOSI_PIN, \ |
||||
|
.alternate = BSP_SPI5_AFIO, \ |
||||
|
IF_SPI_DMA(.spi_dma = &spi_dma[5]) \ |
||||
|
} |
||||
|
#endif /* SPI5_BUS_CONFIG */ |
||||
|
#endif /* BSP_USING_SPI5 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /*__SPI_CONFIG_H__ */ |
||||
|
|
||||
@ -0,0 +1,204 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2018-10-30 SummerGift first version |
||||
|
* 2019-01-03 zylx modify dma support |
||||
|
* 2025-10-09 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __UART_CONFIG_H__ |
||||
|
#define __UART_CONFIG_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART0_AFIO |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
#define BSP_UART0_AFIO "AF4" |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
#define BSP_UART0_AFIO "AF1" |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART1_AFIO |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32H75E |
||||
|
#define BSP_UART1_AFIO "AF7" |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
#define BSP_UART1_AFIO "AF1" |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART2_AFIO |
||||
|
#define BSP_UART2_AFIO "AF7" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART3_AFIO |
||||
|
#define BSP_UART3_AFIO "AF8" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART4_AFIO |
||||
|
#define BSP_UART4_AFIO "AF8" |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART5_AFIO |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx |
||||
|
#define BSP_UART5_AFIO "AF8" |
||||
|
#elif defined (SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
#define BSP_UART5_AFIO "AF7" |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART6_AFIO |
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx |
||||
|
#define BSP_UART6_AFIO "AF8" |
||||
|
#elif defined (SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
#define BSP_UART6_AFIO "AF7" |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifndef BSP_UART7_AFIO |
||||
|
#define BSP_UART7_AFIO "AF8" |
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_UART0) |
||||
|
#ifndef UART0_CONFIG |
||||
|
#define UART0_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = USART0, \ |
||||
|
.irqn = USART0_IRQn, \ |
||||
|
.per_clk = RCU_USART0, \ |
||||
|
.tx_pin_name = BSP_UART0_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART0_RX_PIN, \ |
||||
|
.alternate = BSP_UART0_AFIO, \ |
||||
|
.serial = &serial0, \ |
||||
|
.device_name = "uart0", \ |
||||
|
} |
||||
|
#endif /* UART0_CONFIG */ |
||||
|
#endif /* BSP_USING_UART0 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART1) |
||||
|
#ifndef UART1_CONFIG |
||||
|
#define UART1_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = USART1, \ |
||||
|
.irqn = USART1_IRQn, \ |
||||
|
.per_clk = RCU_USART1, \ |
||||
|
.tx_pin_name = BSP_UART1_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART1_RX_PIN, \ |
||||
|
.alternate = BSP_UART1_AFIO, \ |
||||
|
.serial = &serial1, \ |
||||
|
.device_name = "uart1", \ |
||||
|
} |
||||
|
#endif /* UART1_CONFIG */ |
||||
|
#endif /* BSP_USING_UART1 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART2) |
||||
|
#ifndef UART2_CONFIG |
||||
|
#define UART2_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = USART2, \ |
||||
|
.irqn = USART2_IRQn, \ |
||||
|
.per_clk = RCU_USART2, \ |
||||
|
.tx_pin_name = BSP_UART2_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART2_RX_PIN, \ |
||||
|
.alternate = BSP_UART2_AFIO, \ |
||||
|
.serial = &serial2, \ |
||||
|
.device_name = "uart2", \ |
||||
|
} |
||||
|
#endif /* UART2_CONFIG */ |
||||
|
#endif /* BSP_USING_UART2 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART3) |
||||
|
#ifndef UART3_CONFIG |
||||
|
#define UART3_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = UART3, \ |
||||
|
.irqn = UART3_IRQn, \ |
||||
|
.per_clk = RCU_UART3, \ |
||||
|
.tx_pin_name = BSP_UART3_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART3_RX_PIN, \ |
||||
|
.alternate = BSP_UART3_AFIO, \ |
||||
|
.serial = &serial3, \ |
||||
|
.device_name = "uart3", \ |
||||
|
} |
||||
|
#endif /* UART3_CONFIG */ |
||||
|
#endif /* BSP_USING_UART3 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART4) |
||||
|
#ifndef UART4_CONFIG |
||||
|
#define UART4_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = UART4, \ |
||||
|
.irqn = UART4_IRQn, \ |
||||
|
.per_clk = RCU_UART4, \ |
||||
|
.tx_pin_name = BSP_UART4_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART4_RX_PIN, \ |
||||
|
.alternate = BSP_UART4_AFIO, \ |
||||
|
.serial = &serial4, \ |
||||
|
.device_name = "uart4", \ |
||||
|
} |
||||
|
#endif /* UART4_CONFIG */ |
||||
|
#endif /* BSP_USING_UART4 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART5) |
||||
|
#ifndef UART5_CONFIG |
||||
|
#define UART5_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = USART5, \ |
||||
|
.irqn = USART5_IRQn, \ |
||||
|
.per_clk = RCU_USART5, \ |
||||
|
.tx_pin_name = BSP_UART5_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART5_RX_PIN, \ |
||||
|
.alternate = BSP_UART5_AFIO, \ |
||||
|
.serial = &serial5, \ |
||||
|
.device_name = "uart5", \ |
||||
|
} |
||||
|
#endif /* UART5_CONFIG */ |
||||
|
#endif /* BSP_USING_UART5 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART6) |
||||
|
#ifndef UART6_CONFIG |
||||
|
#define UART6_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = UART6, \ |
||||
|
.irqn = UART6_IRQn, \ |
||||
|
.per_clk = RCU_UART6, \ |
||||
|
.tx_pin_name = BSP_UART6_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART6_RX_PIN, \ |
||||
|
.alternate = BSP_UART6_AFIO, \ |
||||
|
.serial = &serial6, \ |
||||
|
.device_name = "uart6", \ |
||||
|
} |
||||
|
#endif /* UART6_CONFIG */ |
||||
|
#endif /* BSP_USING_UART6 */ |
||||
|
|
||||
|
#if defined(BSP_USING_UART7) |
||||
|
#ifndef UART7_CONFIG |
||||
|
#define UART7_CONFIG \ |
||||
|
{ \ |
||||
|
.uart_periph = UART7, \ |
||||
|
.irqn = UART7_IRQn, \ |
||||
|
.per_clk = RCU_UART7, \ |
||||
|
.tx_pin_name = BSP_UART7_TX_PIN, \ |
||||
|
.rx_pin_name = BSP_UART7_RX_PIN, \ |
||||
|
.alternate = BSP_UART7_AFIO, \ |
||||
|
.serial = &serial7, \ |
||||
|
.device_name = "uart7", \ |
||||
|
} |
||||
|
#endif /* UART7_CONFIG */ |
||||
|
#endif /* BSP_USING_UART7 */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __UART_CONFIG_H__ */ |
||||
|
|
||||
@ -0,0 +1,40 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2022-05-03 BruceOu first implementation |
||||
|
* 2025-10-22 kurisaw optimize multi-channel GPIO configuration |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_ADC_H__ |
||||
|
#define __DRV_ADC_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
#include "drv_gpio.h" |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#define MAX_EXTERN_ADC_CHANNEL 20 |
||||
|
|
||||
|
/* gd32 adc driver class */ |
||||
|
struct gd32_adc |
||||
|
{ |
||||
|
uint32_t adc_periph; |
||||
|
rcu_periph_enum adc_clk; |
||||
|
const char *adc_pins[MAX_EXTERN_ADC_CHANNEL]; |
||||
|
struct rt_adc_device *adc; |
||||
|
char *device_name; |
||||
|
}; |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_ADC_H__ */ |
||||
@ -0,0 +1,109 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_CAN_H__ |
||||
|
#define __DRV_CAN_H__ |
||||
|
|
||||
|
#include <rtdevice.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef RT_USING_CAN |
||||
|
/* Aliases for __IRQn */ |
||||
|
#if defined(BSP_USING_CAN0) || defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2) |
||||
|
/* BSP_USING_CAN0 */ |
||||
|
#define CAN0_TX_IRQn CAN0_Message_IRQn |
||||
|
#define CAN0_RX_IRQn CAN0_Message_IRQn |
||||
|
#define CAN0_ERROR_IRQn CAN0_Error_IRQn |
||||
|
/* BSP_USING_CAN1 */ |
||||
|
#define CAN1_TX_IRQn CAN1_Message_IRQn |
||||
|
#define CAN1_RX_IRQn CAN1_Message_IRQn |
||||
|
#define CAN1_ERROR_IRQn CAN1_Error_IRQn |
||||
|
/* BSP_USING_CAN2 */ |
||||
|
#define CAN2_TX_IRQn CAN2_Message_IRQn |
||||
|
#define CAN2_RX_IRQn CAN2_Message_IRQn |
||||
|
#define CAN2_ERROR_IRQn CAN2_Error_IRQn |
||||
|
#endif |
||||
|
|
||||
|
struct gd32_baud_rate_tab |
||||
|
{ |
||||
|
uint32_t baud_rate; |
||||
|
uint8_t resync_jump_width; |
||||
|
uint8_t prop_time_segment; |
||||
|
uint8_t time_segment_1; |
||||
|
uint8_t time_segment_2; |
||||
|
uint32_t prescaler; |
||||
|
}; |
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
rt_uint32_t baud; |
||||
|
rt_uint8_t sjw; |
||||
|
rt_uint8_t prop; |
||||
|
rt_uint8_t seg1; |
||||
|
rt_uint8_t seg2; |
||||
|
rt_uint16_t prescaler; |
||||
|
} gd32_fd_data_baud_t; |
||||
|
|
||||
|
enum CANFD_BAUD |
||||
|
{ |
||||
|
CANFD_5MBaud = 5000UL * 1000, /* 5 MBit/sec */ |
||||
|
CANFD_4MBaud = 4000UL * 1000, /* 4 MBit/sec */ |
||||
|
CANFD_3MBaud = 3000UL * 1000, /* 3 MBit/sec */ |
||||
|
CANFD_2MBaud = 2000UL * 1000, /* 2 MBit/sec */ |
||||
|
CANFD_1MBaud = 1000UL * 1000, /* 1 MBit/sec */ |
||||
|
CANFD_800kBaud = 1000UL * 800, /* 800 kBit/sec */ |
||||
|
CANFD_500kBaud = 1000UL * 500, /* 500 kBit/sec */ |
||||
|
CANFD_250kBaud = 1000UL * 250, /* 250 kBit/sec */ |
||||
|
CANFD_125kBaud = 1000UL * 125, /* 125 kBit/sec */ |
||||
|
CANFD_100kBaud = 1000UL * 100, /* 100 kBit/sec */ |
||||
|
CANFD_50kBaud = 1000UL * 50, /* 50 kBit/sec */ |
||||
|
CANFD_20kBaud = 1000UL * 20, /* 20 kBit/sec */ |
||||
|
CANFD_10kBaud = 1000UL * 10 /* 10 kBit/sec */ |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
/* gd32 can device */ |
||||
|
typedef struct |
||||
|
{ |
||||
|
char *name; |
||||
|
const char *tx_pin_name; /* can pin name */ |
||||
|
const char *rx_pin_name; /* rx pin name */ |
||||
|
const char *alternate; |
||||
|
uint32_t can_periph; |
||||
|
can_parameter_struct can_init; |
||||
|
can_fifo_parameter_struct can_fifo; |
||||
|
can_operation_modes_enum mode; |
||||
|
can_mailbox_descriptor_struct tx_message[16]; |
||||
|
can_mailbox_descriptor_struct rx_message[16]; |
||||
|
rt_uint8_t rx_message_valid[16]; |
||||
|
void (*filter_cb)(uint32_t can_periph); |
||||
|
#ifdef RT_CAN_USING_CANFD |
||||
|
can_fd_parameter_struct can_fd_init; |
||||
|
rt_uint8_t fd_enabled; |
||||
|
rt_uint8_t fd_rx_buf[16][64]; |
||||
|
#endif |
||||
|
struct rt_can_device *device; /* can device */ |
||||
|
} gd32_can_struct; |
||||
|
|
||||
|
void can_gpio_config(void); |
||||
|
int rt_hw_can_init(void); |
||||
|
#endif /* RT_USING_CAN */ |
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_CAN_H__ */ |
||||
|
|
||||
@ -0,0 +1,40 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-09-0 WangShun first implementation |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_COMMON_H__ |
||||
|
#define __DRV_COMMON_H__ |
||||
|
|
||||
|
#include "drv_usart.h" |
||||
|
#include "drv_gpio.h" |
||||
|
#include <board.h> |
||||
|
|
||||
|
#define GD32_FLASH_START_ADRESS ROM_START |
||||
|
#define GD32_FLASH_SIZE ROM_SIZE |
||||
|
#define GD32_FLASH_END_ADDRESS ROM_END |
||||
|
|
||||
|
#define GD32_SRAM_SIZE RAM_SIZE |
||||
|
#define GD32_SRAM_START RAM_START |
||||
|
#define GD32_SRAM_END RAM_END |
||||
|
|
||||
|
#ifdef __ARMCC_VERSION |
||||
|
extern int Image$$RW_IRAM1$$ZI$$Limit; |
||||
|
#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) |
||||
|
#elif __ICCARM__ |
||||
|
#pragma section="HEAP" |
||||
|
#define HEAP_BEGIN (__segment_end("HEAP")) |
||||
|
#else |
||||
|
extern int __bss_end; |
||||
|
#define HEAP_BEGIN (&__bss_end) |
||||
|
#endif |
||||
|
|
||||
|
#define HEAP_END GD32_SRAM_END |
||||
|
|
||||
|
#endif /* __DRV_COMMON_H__ */ |
||||
|
|
||||
@ -0,0 +1,21 @@ |
|||||
|
/*
|
||||
|
* drv_config.h for GD32 platform |
||||
|
*/ |
||||
|
#ifndef __DRV_CONFIG_H__ |
||||
|
#define __DRV_CONFIG_H__ |
||||
|
|
||||
|
#include <board.h> |
||||
|
#include <rtthread.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
/* Include peripheral configuration headers under drivers/include/config */ |
||||
|
#include "config/uart_config.h" |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_CONFIG_H__ */ |
||||
@ -0,0 +1,41 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-11 kurisaw first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_DAC_H__ |
||||
|
#define __DRV_DAC_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if defined(RT_USING_DAC) |
||||
|
|
||||
|
/* gd32 dac driver class */ |
||||
|
struct gd32_dac |
||||
|
{ |
||||
|
struct rt_dac_device dac_device; |
||||
|
uint32_t dac_periph; |
||||
|
char *name; |
||||
|
const char *pin_name; |
||||
|
rt_int16_t channel; |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_DAC_H__ */ |
||||
@ -0,0 +1,58 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2024-03-19 Evlers first implementation |
||||
|
*/ |
||||
|
|
||||
|
#ifndef _DRV_DMA_H_ |
||||
|
#define _DRV_DMA_H_ |
||||
|
|
||||
|
|
||||
|
#if defined SOC_SERIES_GD32E23x |
||||
|
#define DRV_DMA_CONFIG(chx) \ |
||||
|
(struct dma_config) |
||||
|
{ \ |
||||
|
.periph = DMA, \ |
||||
|
.rcu = RCU_DMA, \ |
||||
|
.channel = DMA_CH##chx, \ |
||||
|
.irq = ((chx) == 0 ? DMA_Channel0_IRQn : \ |
||||
|
(chx) == 1 ? DMA_Channel1_2_IRQn : \ |
||||
|
(chx) == 2 ? DMA_Channel1_2_IRQn : \ |
||||
|
(chx) == 3 ? DMA_Channel3_4_IRQn : \ |
||||
|
(chx) == 4 ? DMA_Channel3_4_IRQn : (IRQn_Type)0) \ |
||||
|
} |
||||
|
struct dma_config |
||||
|
{ |
||||
|
uint32_t periph; |
||||
|
rcu_periph_enum rcu; |
||||
|
dma_channel_enum channel; |
||||
|
IRQn_Type irq; |
||||
|
}; |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
#define DRV_DMA_CONFIG(dmax, chx, subx) { \ |
||||
|
.periph = DMA##dmax, \ |
||||
|
.channel = DMA_CH##chx, \ |
||||
|
.rcu = RCU_DMA##dmax, \ |
||||
|
.subperiph = DMA_SUBPERI##subx, \ |
||||
|
.irq = DMA##dmax##_Channel##chx##_IRQn, \ |
||||
|
} |
||||
|
|
||||
|
struct dma_config |
||||
|
{ |
||||
|
uint32_t periph; |
||||
|
rcu_periph_enum rcu; |
||||
|
dma_channel_enum channel; |
||||
|
dma_subperipheral_enum subperiph; |
||||
|
IRQn_Type irq; |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#endif /* _DRV_DMA_H_ */ |
||||
|
|
||||
@ -0,0 +1,98 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-10 kurisaw the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_ENET_H__ |
||||
|
#define __DRV_ENET_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP) |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#include "gd32h7xx.h" |
||||
|
#include "synopsys_emac.h" |
||||
|
|
||||
|
#define EMAC_RXBUFNB 5 |
||||
|
#define EMAC_TXBUFNB 5 |
||||
|
|
||||
|
#define EMAC_PHY_AUTO 0 |
||||
|
#define EMAC_PHY_10MBIT 1 |
||||
|
#define EMAC_PHY_100MBIT 2 |
||||
|
|
||||
|
#define MAX_ADDR_LEN 6 |
||||
|
|
||||
|
/* ENET pin configuration structure */ |
||||
|
struct enet_pin_config |
||||
|
{ |
||||
|
const char *pin_name; /* Pin name in format "PxY" */ |
||||
|
const char *alternate; /* Alternate function in format "AFx" */ |
||||
|
}; |
||||
|
|
||||
|
/* ENET configuration structure */ |
||||
|
struct enet_config |
||||
|
{ |
||||
|
const struct enet_pin_config *pins; |
||||
|
uint32_t pin_count; |
||||
|
uint32_t enet_periph; |
||||
|
rcu_periph_enum enet_clk; |
||||
|
rcu_periph_enum enet_tx_clk; |
||||
|
rcu_periph_enum enet_rx_clk; |
||||
|
uint32_t phy_interface; |
||||
|
uint32_t speed; /* GPIO speed - common for all pins */ |
||||
|
uint8_t otype; /* Output type - common for all pins */ |
||||
|
uint8_t pupd; /* Pull-up/pull-down - common for all pins */ |
||||
|
}; |
||||
|
|
||||
|
struct gd32_emac |
||||
|
{ |
||||
|
/* inherit from Ethernet device */ |
||||
|
struct eth_device parent; |
||||
|
|
||||
|
__ALIGNED(4) |
||||
|
rt_uint8_t phy_mode; |
||||
|
/* interface address info. */ |
||||
|
__ALIGNED(4) |
||||
|
rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ |
||||
|
|
||||
|
const struct enet_pin_config *pins; |
||||
|
uint32_t pin_count; |
||||
|
struct rt_synopsys_eth *ETHERNET_MAC; |
||||
|
IRQn_Type ETHER_MAC_IRQ; |
||||
|
|
||||
|
EMAC_DMADESCTypeDef *DMATxDescToSet; |
||||
|
EMAC_DMADESCTypeDef *DMARxDescToGet; |
||||
|
|
||||
|
#pragma pack(4) |
||||
|
EMAC_DMADESCTypeDef DMARxDscrTab[EMAC_RXBUFNB]; |
||||
|
#pragma pack(4) |
||||
|
EMAC_DMADESCTypeDef DMATxDscrTab[EMAC_TXBUFNB]; |
||||
|
#pragma pack(4) |
||||
|
rt_uint8_t Rx_Buff[EMAC_RXBUFNB][EMAC_MAX_PACKET_SIZE]; |
||||
|
#pragma pack(4) |
||||
|
rt_uint8_t Tx_Buff[EMAC_TXBUFNB][EMAC_MAX_PACKET_SIZE]; |
||||
|
|
||||
|
struct rt_semaphore tx_buf_free; |
||||
|
}; |
||||
|
|
||||
|
/* Function declarations */ |
||||
|
rt_err_t gd32_enet_gpio_init(struct gd32_emac *emac); |
||||
|
const struct enet_config *gd32_get_enet_config(void); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */ |
||||
|
#endif /* __DRV_ENET_H__ */ |
||||
@ -0,0 +1,93 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-08-20 BruceOu the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_GPIO_H__ |
||||
|
#define __DRV_GPIO_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F10x |
||||
|
#include "gd32f10x_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32F20x |
||||
|
#include "gd32f20x_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32F30x |
||||
|
#include "gd32f30x_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32F4xx |
||||
|
#include "gd32f4xx_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32H7xx |
||||
|
#include "gd32h7xx_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32H75e |
||||
|
#include "gd32h75e_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32E50x |
||||
|
#include "gd32e50x_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32F5xx |
||||
|
#include "gd32f5xx_gpio.h" |
||||
|
#elif defined SOC_SERIES_GD32E23x |
||||
|
#include "gd32e23x_gpio.h" |
||||
|
#endif |
||||
|
|
||||
|
#define __GD32_PORT(port) GPIO##port |
||||
|
|
||||
|
#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32F5xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32H75E || defined SOC_SERIES_GD32H7xx |
||||
|
#define GD32_PIN(index, port, pin) {index, RCU_GPIO##port, \ |
||||
|
GPIO##port, GPIO_PIN_##pin, \ |
||||
|
EXTI_SOURCE_GPIO##port, \ |
||||
|
EXTI_SOURCE_PIN##pin, \ |
||||
|
EXTI_##pin} |
||||
|
#else |
||||
|
#define GD32_PIN(index, port, pin) {index, RCU_GPIO##port, \ |
||||
|
GPIO##port, GPIO_PIN_##pin, \ |
||||
|
GPIO_PORT_SOURCE_GPIO##port, \ |
||||
|
GPIO_PIN_SOURCE_##pin} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#define GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0, 0, 0} |
||||
|
|
||||
|
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__GD32_PORT(PORTx) - (rt_base_t)GPIO_BASE)/(0x0400UL) )) + PIN) |
||||
|
|
||||
|
#define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu)) |
||||
|
#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) |
||||
|
|
||||
|
#define PIN_GDPORT(pin) (GPIO_BASE + (0x400u * PIN_PORT(pin))) |
||||
|
#define PIN_GDPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) |
||||
|
|
||||
|
struct pin_index |
||||
|
{ |
||||
|
rt_int16_t index; |
||||
|
rcu_periph_enum clk; |
||||
|
rt_uint32_t gpio_periph; |
||||
|
rt_uint32_t pin; |
||||
|
rt_uint8_t port_src; |
||||
|
rt_uint8_t pin_src; |
||||
|
rt_uint32_t exit_line; |
||||
|
}; |
||||
|
|
||||
|
struct pin_irq_map |
||||
|
{ |
||||
|
rt_uint16_t pinbit; |
||||
|
IRQn_Type irqno; |
||||
|
}; |
||||
|
|
||||
|
int get_pin_config(const char *pin_name, uint32_t *port, uint32_t *pin, rcu_periph_enum *clk); |
||||
|
int pin_alternate_config(const char *alternate, uint32_t *af); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_GPIO_H__ */ |
||||
|
|
||||
@ -0,0 +1,72 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-22 kurisaw first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_HWTIMER_H__ |
||||
|
#define __DRV_HWTIMER_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtdevice.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#ifdef RT_USING_HWTIMER |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
uint32_t reg_base; |
||||
|
IRQn_Type irqn; |
||||
|
rcu_periph_enum rcu; |
||||
|
} gd32_hwtimer_data; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
char dev_name[RT_NAME_MAX]; |
||||
|
const gd32_hwtimer_data hw_data; |
||||
|
rt_hwtimer_t hwtimer_dev; |
||||
|
const struct rt_hwtimer_info hwtimer_info; |
||||
|
} gd32_hwtimer_device; |
||||
|
|
||||
|
enum timer_index |
||||
|
{ |
||||
|
#ifdef BSP_USING_HWTIMER0 |
||||
|
TIM0_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER1 |
||||
|
TIM1_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER2 |
||||
|
TIM2_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER3 |
||||
|
TIM3_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER4 |
||||
|
TIM4_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER5 |
||||
|
TIM5_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER6 |
||||
|
TIM6_INDEX, |
||||
|
#endif |
||||
|
#ifdef BSP_USING_HWTIMER7 |
||||
|
TIM7_INDEX, |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_HWTIMER_H__ */ |
||||
@ -0,0 +1,43 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-12-20 BruceOu the first version |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_I2C__ |
||||
|
#define __DRV_I2C__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include <rthw.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
/* GD32 i2c driver */ |
||||
|
struct gd32_i2c_bus |
||||
|
{ |
||||
|
uint32_t i2c_periph; |
||||
|
rcu_periph_enum per_clk; |
||||
|
|
||||
|
const char *scl_pin_name; /* scl pin name */ |
||||
|
const char *sda_pin_name; /* sda pin name */ |
||||
|
const char *alternate; /* afio name */ |
||||
|
|
||||
|
struct rt_i2c_bus_device *i2c_bus; |
||||
|
char *device_name; |
||||
|
}; |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_I2C__ */ |
||||
|
|
||||
@ -0,0 +1,66 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_LCD_H__ |
||||
|
#define __DRV_LCD_H__ |
||||
|
|
||||
|
#include <board.h> |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H7xx) |
||||
|
#include "gd32h7xx_tli.h" |
||||
|
#include "gd32h7xx_ipa.h" |
||||
|
#endif |
||||
|
|
||||
|
#define HORIZONTAL_SYNCHRONOUS_PULSE 41 |
||||
|
#define HORIZONTAL_BACK_PORCH 2 |
||||
|
#define ACTIVE_WIDTH 480 |
||||
|
#define HORIZONTAL_FRONT_PORCH 2 |
||||
|
|
||||
|
#define VERTICAL_SYNCHRONOUS_PULSE 10 |
||||
|
#define VERTICAL_BACK_PORCH 2 |
||||
|
#define ACTIVE_HEIGHT 272 |
||||
|
#define VERTICAL_FRONT_PORCH 2 |
||||
|
|
||||
|
#define LCD_WIGHT ACTIVE_WIDTH |
||||
|
#define LCD_HIGHT ACTIVE_HEIGHT |
||||
|
#define PIXEL_FORMAT LAYER_PPF_RGB565 |
||||
|
#define PRE_PIXEL_BYTES 2 |
||||
|
|
||||
|
typedef struct _RGB_DATA |
||||
|
{ |
||||
|
uint8_t Alpha; |
||||
|
uint8_t R; |
||||
|
uint8_t G; |
||||
|
uint8_t B; |
||||
|
} RGB; |
||||
|
|
||||
|
extern RGB color_write; |
||||
|
extern RGB color_black; |
||||
|
extern RGB color_red; |
||||
|
extern RGB color_blue; |
||||
|
extern RGB color_green; |
||||
|
extern RGB color_yellow; |
||||
|
extern RGB color_cyan; |
||||
|
extern RGB color_magenta; |
||||
|
extern RGB color_orange; |
||||
|
extern RGB color_purple; |
||||
|
extern RGB color_gray; |
||||
|
extern RGB color_lightgray; |
||||
|
extern RGB color_darkgray; |
||||
|
extern RGB color_brown; |
||||
|
extern RGB color_pink; |
||||
|
extern RGB color_gold; |
||||
|
extern RGB color_silver; |
||||
|
|
||||
|
void lcd_draw_picture(uint32_t picture_addr, uint32_t picture_width, uint32_t picture_height, uint32_t picture_x, uint32_t picture_y); |
||||
|
void lcd_draw_point(uint32_t point_x, uint32_t point_y, RGB *color); |
||||
|
uint32_t to_RGB565(RGB *color); |
||||
|
|
||||
|
#endif // __DRV_LCD_H__
|
||||
@ -0,0 +1,32 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-09-12 RTT the first version |
||||
|
*/ |
||||
|
#ifndef DRIVERS_DRV_LEGACY_H_ |
||||
|
#define DRIVERS_DRV_LEGACY_H_ |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
#include "rtdef.h" |
||||
|
|
||||
|
#if RTTHREAD_VERSION <= 40101 |
||||
|
#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) |
||||
|
typedef size_t rt_size_t; /**< Type for size number */ |
||||
|
typedef ssize_t rt_ssize_t; /**< Used for a count of bytes or an error indication */ |
||||
|
#else |
||||
|
typedef rt_base_t rt_ssize_t; /**< Used for a count of bytes or an error indication */ |
||||
|
#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ |
||||
|
#else |
||||
|
#define RT_SECTION rt_section |
||||
|
#define RT_WEAK rt_weak |
||||
|
#define RT_USED rt_used |
||||
|
#ifndef ALIGN |
||||
|
#define ALIGN rt_align |
||||
|
#endif |
||||
|
#endif /* RTTHREAD_VERSION <= RT_VERSION_CHECK(4, 1, 1) */ |
||||
|
|
||||
|
#endif /* DRIVERS_DRV_LEGACY_H_ */ |
||||
@ -0,0 +1,28 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2018-11-15 SummerGift first version |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* NOTE: DO NOT include this file on the header file. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef LOG_TAG |
||||
|
#define DBG_TAG "drv" |
||||
|
#else |
||||
|
#define DBG_TAG LOG_TAG |
||||
|
#endif /* LOG_TAG */ |
||||
|
|
||||
|
#ifdef DRV_DEBUG |
||||
|
#define DBG_LVL DBG_LOG |
||||
|
#else |
||||
|
#define DBG_LVL DBG_INFO |
||||
|
#endif /* DRV_DEBUG */ |
||||
|
|
||||
|
#include <rtdbg.h> |
||||
|
|
||||
@ -0,0 +1,45 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-10-11 kurisaw compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_PWM_H__ |
||||
|
#define __DRV_PWM_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if defined(RT_USING_PWM) |
||||
|
|
||||
|
/* gd32 pwm driver class */ |
||||
|
struct gd32_pwm |
||||
|
{ |
||||
|
struct rt_device_pwm pwm_device; |
||||
|
uint32_t timer_periph; |
||||
|
char *name; |
||||
|
rcu_periph_enum timer_clk; |
||||
|
const char *pin_name; |
||||
|
rt_int16_t channel; |
||||
|
const char *alternate; |
||||
|
}; |
||||
|
|
||||
|
rt_err_t rt_hw_pwm_init(void); |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_PWM_H__ */ |
||||
@ -0,0 +1,297 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __SDCARD_H_ |
||||
|
#define __SDCARD_H_ |
||||
|
|
||||
|
#include <board.h> |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32F10x) |
||||
|
#include "gd32f10x_sdio.h" |
||||
|
#include "gd32f10x_dma.h" |
||||
|
#elif defined(SOC_SERIES_GD32F20x) |
||||
|
#include "gd32f20x_sdio.h" |
||||
|
#include "gd32f20x_dma.h" |
||||
|
#elif defined(SOC_SERIES_GD32F30x) |
||||
|
#include "gd32f30x_sdio.h" |
||||
|
#include "gd32f30x_dma.h" |
||||
|
#elif defined(SOC_SERIES_GD32F4xx) |
||||
|
#include "gd32f4xx_sdio.h" |
||||
|
#include "gd32f4xx_dma.h" |
||||
|
#elif defined(SOC_SERIES_GD32H7xx) |
||||
|
#include "gd32h7xx_sdio.h" |
||||
|
#include "gd32h7xx_dma.h" |
||||
|
#endif |
||||
|
|
||||
|
// #define USE_18V_SWITCH /* use SD Transceiver 1.8V mode */
|
||||
|
|
||||
|
#define SDIO_PERI_CLOCK RCU_SDIO0 |
||||
|
#define SDIO_GPIO_CLK RCU_GPIOC |
||||
|
#define SDIO_GPIO_CMD RCU_GPIOD |
||||
|
#define SDIO_GPIO_D0 RCU_GPIOB |
||||
|
#define SDIO_GPIO_D1 RCU_GPIOC |
||||
|
#define SDIO_GPIO_D2 RCU_GPIOC |
||||
|
#define SDIO_GPIO_D3 RCU_GPIOC |
||||
|
|
||||
|
#define SDIO_CLK_PORT GPIOC |
||||
|
#define SDIO_CLK_PIN GPIO_PIN_12 |
||||
|
#define SDIO_CMD_PORT GPIOD |
||||
|
#define SDIO_CMD_PIN GPIO_PIN_2 |
||||
|
#define SDIO_D0_PORT GPIOB |
||||
|
#define SDIO_D0_PIN GPIO_PIN_13 |
||||
|
#define SDIO_D1_PORT GPIOC |
||||
|
#define SDIO_D1_PIN GPIO_PIN_9 |
||||
|
#define SDIO_D2_PORT GPIOC |
||||
|
#define SDIO_D2_PIN GPIO_PIN_10 |
||||
|
#define SDIO_D3_PORT GPIOC |
||||
|
#define SDIO_D3_PIN GPIO_PIN_11 |
||||
|
|
||||
|
/* SD memory card bus commands index */ |
||||
|
#define SD_CMD_GO_IDLE_STATE ((uint8_t)0) /* CMD0, GO_IDLE_STATE */ |
||||
|
#define SD_CMD_ALL_SEND_CID ((uint8_t)2) /* CMD2, ALL_SEND_CID */ |
||||
|
#define SD_CMD_SEND_RELATIVE_ADDR ((uint8_t)3) /* CMD3, SEND_RELATIVE_ADDR */ |
||||
|
#define SD_CMD_SET_DSR ((uint8_t)4) /* CMD4, SET_DSR */ |
||||
|
#define SD_CMD_SWITCH_FUNC ((uint8_t)6) /* CMD6, SWITCH_FUNC */ |
||||
|
#define SD_CMD_SELECT_DESELECT_CARD ((uint8_t)7) /* CMD7, SELECT_DESELECT_CARD */ |
||||
|
#define SD_CMD_SEND_IF_COND ((uint8_t)8) /* CMD8, SEND_IF_COND */ |
||||
|
#define SD_CMD_SEND_CSD ((uint8_t)9) /* CMD9, SEND_CSD */ |
||||
|
#define SD_CMD_SEND_CID ((uint8_t)10) /* CMD10, SEND_CID */ |
||||
|
#define SD_CMD_VOLATAGE_SWITCH ((uint8_t)11) /* CMD11, SD_CMD_VOLATAGE_SWITCH */ |
||||
|
#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) /* CMD12, STOP_TRANSMISSION */ |
||||
|
#define SD_CMD_SEND_STATUS ((uint8_t)13) /* CMD13, SEND_STATUS */ |
||||
|
#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15) /* CMD15, GO_INACTIVE_STATE */ |
||||
|
#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) /* CMD16, SET_BLOCKLEN */ |
||||
|
#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /* CMD17, READ_SINGLE_BLOCK */ |
||||
|
#define SD_CMD_READ_MULTIPLE_BLOCK ((uint8_t)18) /* CMD18, READ_MULTIPLE_BLOCK */ |
||||
|
#define SD_SEND_TUNING_PATTERN ((uint8_t)19) /* CMD19, SEND_TUNING_PATTERN */ |
||||
|
#define SD_CMD_WRITE_BLOCK ((uint8_t)24) /* CMD24, WRITE_BLOCK */ |
||||
|
#define SD_CMD_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /* CMD25, WRITE_MULTIPLE_BLOCK */ |
||||
|
#define SD_CMD_PROG_CSD ((uint8_t)27) /* CMD27, PROG_CSD */ |
||||
|
#define SD_CMD_SET_WRITE_PROT ((uint8_t)28) /* CMD28, SET_WRITE_PROT */ |
||||
|
#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29) /* CMD29, CLR_WRITE_PROT */ |
||||
|
#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30) /* CMD30, SEND_WRITE_PROT */ |
||||
|
#define SD_CMD_ERASE_WR_BLK_START ((uint8_t)32) /* CMD32, ERASE_WR_BLK_START */ |
||||
|
#define SD_CMD_ERASE_WR_BLK_END ((uint8_t)33) /* CMD33, ERASE_WR_BLK_END */ |
||||
|
#define SD_CMD_ERASE ((uint8_t)38) /* CMD38, ERASE */ |
||||
|
#define SD_CMD_LOCK_UNLOCK ((uint8_t)42) /* CMD42, LOCK_UNLOCK */ |
||||
|
#define SD_CMD_APP_CMD ((uint8_t)55) /* CMD55, APP_CMD */ |
||||
|
#define SD_CMD_GEN_CMD ((uint8_t)56) /* CMD56, GEN_CMD */ |
||||
|
|
||||
|
/* SD memory card application specific commands index */ |
||||
|
#define SD_APPCMD_SET_BUS_WIDTH ((uint8_t)6) /* ACMD6, SET_BUS_WIDTH */ |
||||
|
#define SD_APPCMD_SD_STATUS ((uint8_t)13) /* ACMD13, SD_STATUS */ |
||||
|
#define SD_APPCMD_SEND_NUM_WR_BLOCKS ((uint8_t)22) /* ACMD22, SEND_NUM_WR_BLOCKS */ |
||||
|
#define SD_APPCMD_SET_WR_BLK_ERASE_COUNT ((uint8_t)23) /* ACMD23, SET_WR_BLK_ERASE_COUNT */ |
||||
|
#define SD_APPCMD_SD_SEND_OP_COND ((uint8_t)41) /* ACMD41, SD_SEND_OP_COND */ |
||||
|
#define SD_APPCMD_SET_CLR_CARD_DETECT ((uint8_t)42) /* ACMD42, SET_CLR_CARD_DETECT */ |
||||
|
#define SD_APPCMD_SEND_SCR ((uint8_t)51) /* ACMD51, SEND_SCR */ |
||||
|
|
||||
|
/* card command class */ |
||||
|
#define SD_CCC_SWITCH BIT(10) /* class 10 */ |
||||
|
#define SD_CCC_IO_MODE BIT(9) /* class 9 */ |
||||
|
#define SD_CCC_APPLICATION_SPECIFIC BIT(8) /* class 8 */ |
||||
|
#define SD_CCC_LOCK_CARD BIT(7) /* class 7 */ |
||||
|
#define SD_CCC_WRITE_PROTECTION BIT(6) /* class 6 */ |
||||
|
#define SD_CCC_ERASE BIT(5) /* class 5 */ |
||||
|
#define SD_CCC_BLOCK_WRITE BIT(4) /* class 4 */ |
||||
|
#define SD_CCC_BLOCK_READ BIT(2) /* class 2 */ |
||||
|
#define SD_CCC_BASIC BIT(0) /* class 0 */ |
||||
|
|
||||
|
/* SD card data transmission mode */ |
||||
|
#define SD_DMA_MODE ((uint32_t)0x00000000) /* DMA mode */ |
||||
|
#define SD_POLLING_MODE ((uint32_t)0x00000001) /* polling mode */ |
||||
|
|
||||
|
/* lock unlock status */ |
||||
|
#define SD_LOCK ((uint8_t)0x05) /* lock the SD card */ |
||||
|
#define SD_UNLOCK ((uint8_t)0x02) /* unlock the SD card */ |
||||
|
|
||||
|
#define SD_SDSC ((uint32_t)0x00000000U) /*!< SD Standard Capacity <2G*/ |
||||
|
#define SD_SDHC_SDXC ((uint32_t)0x00000001U) /*!< SD High Capacity <32G, SD Extended Capacity <2T */ |
||||
|
|
||||
|
#define SD_SPEED_DEFAULT ((uint32_t)0x00000000U) /*!< maintain current speed , clock frequency max value 25M*/ |
||||
|
#define SD_SPEED_HIGH ((uint32_t)0x00000001U) /*!< switch high speed, clock frequency max value 50M */ |
||||
|
#define SD_SPEED_SDR25 ((uint32_t)0x80FFFF01U) /*!< switch UHS-I SDR25 speed, clock frequency max value 50M */ |
||||
|
#define SD_SPEED_SDR50 ((uint32_t)0x80FF1F02U) /*!< switch UHS-I SDR50 speed, clock frequency max value 104M */ |
||||
|
#define SD_SPEED_SDR104 ((uint32_t)0x80FF1F03U) /*!< switch UHS-I SDR104 speed, clock frequency max value 208M */ |
||||
|
#define SD_SPEED_DDR50 ((uint32_t)0x80FF1F04U) /*!< switch UHS-I DDR speed , clock frequency max value 50M */ |
||||
|
|
||||
|
/* supported memory cards types */ |
||||
|
typedef enum |
||||
|
{ |
||||
|
SDIO_STD_CAPACITY_SD_CARD_V1_1 = 0, /* standard capacity SD card version 1.1 */ |
||||
|
SDIO_STD_CAPACITY_SD_CARD_V2_0, /* standard capacity SD card version 2.0 */ |
||||
|
SDIO_STD_CAPACITY_SD_CARD_V3_0, /* standard capacity SD card version 3.0 */ |
||||
|
SDIO_HIGH_CAPACITY_SD_CARD, /* high capacity SD card */ |
||||
|
SDIO_SECURE_DIGITAL_IO_CARD, /* secure digital IO card */ |
||||
|
SDIO_SECURE_DIGITAL_IO_COMBO_CARD, /* secure digital IO combo card */ |
||||
|
SDIO_MULTIMEDIA_CARD, /* multimedia card */ |
||||
|
SDIO_HIGH_CAPACITY_MULTIMEDIA_CARD, /* high capacity multimedia card */ |
||||
|
SDIO_HIGH_SPEED_MULTIMEDIA_CARD /* high speed multimedia card */ |
||||
|
} sdio_card_type_enum; |
||||
|
|
||||
|
/* card identification (CID) register */ |
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint8_t mid; /* manufacturer ID */ |
||||
|
__IO uint16_t oid; /* OEM/application ID */ |
||||
|
__IO uint32_t pnm0; /* product name */ |
||||
|
__IO uint8_t pnm1; /* product name */ |
||||
|
__IO uint8_t prv; /* product revision */ |
||||
|
__IO uint32_t psn; /* product serial number */ |
||||
|
__IO uint16_t mdt; /* manufacturing date */ |
||||
|
__IO uint8_t cid_crc; /* CID CRC7 checksum */ |
||||
|
} sd_cid_struct; |
||||
|
|
||||
|
/* CSD register (CSD version 1.0 and 2.0) */ |
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint8_t csd_struct; /* CSD struct */ |
||||
|
__IO uint8_t taac; /* data read access-time */ |
||||
|
__IO uint8_t nsac; /* data read access-time in CLK cycles */ |
||||
|
__IO uint8_t tran_speed; /* max. data transfer rate */ |
||||
|
__IO uint16_t ccc; /* card command classes */ |
||||
|
__IO uint8_t read_bl_len; /* max. read data block length */ |
||||
|
__IO uint8_t read_bl_partial; /* partial blocks for read allowed */ |
||||
|
__IO uint8_t write_blk_misalign; /* write block misalignment */ |
||||
|
__IO uint8_t read_blk_misalign; /* read block misalignment */ |
||||
|
__IO uint8_t dsp_imp; /* DSR implemented */ |
||||
|
__IO uint32_t c_size; /* device size, 12 bits in CSD version 1.0, 22 bits in CSD version 2.0 */ |
||||
|
__IO uint8_t vdd_r_curr_min; /* max. read current @VDD min, CSD version 1.0 */ |
||||
|
__IO uint8_t vdd_r_curr_max; /* max. read current @VDD max, CSD version 1.0 */ |
||||
|
__IO uint8_t vdd_w_curr_min; /* max. write current @VDD min, CSD version 1.0 */ |
||||
|
__IO uint8_t vdd_w_curr_max; /* max. write current @VDD max, CSD version 1.0 */ |
||||
|
__IO uint8_t c_size_mult; /* device size multiplier, CSD version 1.0 */ |
||||
|
__IO uint8_t erase_blk_en; /* erase single block enable */ |
||||
|
__IO uint8_t sector_size; /* erase sector size */ |
||||
|
__IO uint8_t wp_grp_size; /* write protect group size */ |
||||
|
__IO uint8_t wp_grp_enable; /* write protect group enable */ |
||||
|
__IO uint8_t r2w_factor; /* write speed factor */ |
||||
|
__IO uint8_t write_bl_len; /* max. write data block length */ |
||||
|
__IO uint8_t write_bl_partial; /* partial blocks for write allowed */ |
||||
|
__IO uint8_t file_format_grp; /* file format group */ |
||||
|
__IO uint8_t copy_flag; /* copy flag (OTP) */ |
||||
|
__IO uint8_t perm_write_protect; /* permanent write protection */ |
||||
|
__IO uint8_t tmp_write_protect; /* temporary write protection */ |
||||
|
__IO uint8_t file_format; /* file format */ |
||||
|
__IO uint8_t csd_crc; /* CSD CRC checksum */ |
||||
|
} sd_csd_struct; |
||||
|
|
||||
|
/* information of card */ |
||||
|
typedef struct |
||||
|
{ |
||||
|
sd_cid_struct card_cid; /* CID register */ |
||||
|
sd_csd_struct card_csd; /* CSD register */ |
||||
|
sdio_card_type_enum card_type; /* card tpye */ |
||||
|
uint32_t card_capacity; /* card capacity */ |
||||
|
uint32_t card_blocksize; /* card block size */ |
||||
|
uint16_t card_rca; /* card relative card address */ |
||||
|
} sd_card_info_struct; |
||||
|
|
||||
|
/* SD error flags */ |
||||
|
typedef enum |
||||
|
{ |
||||
|
SD_OUT_OF_RANGE = 0, /* command's argument was out of range */ |
||||
|
SD_ADDRESS_ERROR, /* misaligned address which did not match the block length */ |
||||
|
SD_BLOCK_LEN_ERROR, /* transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */ |
||||
|
SD_ERASE_SEQ_ERROR, /* an error in the sequence of erase command occurs */ |
||||
|
SD_ERASE_PARAM, /* an invalid selection of write-blocks for erase occurred */ |
||||
|
SD_WP_VIOLATION, /* attempt to program a write protect block or permanent write protected card */ |
||||
|
SD_LOCK_UNLOCK_FAILED, /* sequence or password error has been detected in lock/unlock card command */ |
||||
|
SD_COM_CRC_ERROR, /* CRC check of the previous command failed */ |
||||
|
SD_ILLEGAL_COMMAND, /* command not legal for the card state */ |
||||
|
SD_CARD_ECC_FAILED, /* card internal ECC was applied but failed to correct the data */ |
||||
|
SD_CC_ERROR, /* internal card controller error */ |
||||
|
SD_GENERAL_UNKNOWN_ERROR, /* general or unknown error occurred during the operation */ |
||||
|
SD_CSD_OVERWRITE, /* read only section of the CSD does not match the card content or an attempt to reverse the copy or permanent WP bits was made */ |
||||
|
SD_WP_ERASE_SKIP, /* only partial address space was erased or the temporary or permanent write protected card was erased */ |
||||
|
SD_CARD_ECC_DISABLED, /* command has been executed without using internal ECC */ |
||||
|
SD_ERASE_RESET, /* erase sequence was cleared before executing because an out of erase sequence command was received */ |
||||
|
SD_AKE_SEQ_ERROR, /* error in the sequence of the authentication process */ |
||||
|
|
||||
|
SD_CMD_CRC_ERROR, /* command response received (CRC check failed) */ |
||||
|
SD_DATA_CRC_ERROR, /* data block sent/received (CRC check failed) */ |
||||
|
SD_CMD_RESP_TIMEOUT, /* command response timeout */ |
||||
|
SD_DATA_TIMEOUT, /* data timeout */ |
||||
|
SD_TX_UNDERRUN_ERROR, /* transmit FIFO underrun error occurs */ |
||||
|
SD_RX_OVERRUN_ERROR, /* received FIFO overrun error occurs */ |
||||
|
SD_START_BIT_ERROR, /* start bit error in the bus */ |
||||
|
|
||||
|
SD_VOLTRANGE_INVALID, /* the voltage range is invalid */ |
||||
|
SD_PARAMETER_INVALID, /* the parameter is invalid */ |
||||
|
SD_OPERATION_IMPROPER, /* the operation is improper */ |
||||
|
SD_FUNCTION_UNSUPPORTED, /* the function is unsupported */ |
||||
|
SD_ERROR, /* an error occurred */ |
||||
|
SD_DMA_ERROR, /* an error when idma transfer */ |
||||
|
SD_OK /* no error occurred */ |
||||
|
} sd_error_enum; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
SD_NO_TRANSFER = 0, /* no data transfer is acting */ |
||||
|
SD_TRANSFER_IN_PROGRESS /* data transfer is in progress */ |
||||
|
} sd_transfer_state_enum; |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* initialize the SD card and make it in standby state */ |
||||
|
sd_error_enum sd_init(uint32_t SDIO); |
||||
|
/* initialize the card and get CID and CSD of the card */ |
||||
|
sd_error_enum sd_card_init(uint32_t SDIO); |
||||
|
/* configure the clock and the work voltage, and get the card type */ |
||||
|
sd_error_enum sd_power_on(uint32_t SDIO); |
||||
|
/* close the power of SDIO */ |
||||
|
sd_error_enum sd_power_off(uint32_t SDIO); |
||||
|
|
||||
|
/* configure the bus mode */ |
||||
|
sd_error_enum sd_bus_mode_config(uint32_t SDIO, uint32_t busmode, uint32_t speed); |
||||
|
/* configure the mode of transmission */ |
||||
|
sd_error_enum sd_transfer_mode_config(uint32_t txmode); |
||||
|
|
||||
|
/* read a block data into a buffer from the specified address of a card */ |
||||
|
sd_error_enum sd_block_read(uint32_t SDIO, uint32_t *preadbuffer, uint32_t readaddr, uint16_t blocksize); |
||||
|
/* read multiple blocks data into a buffer from the specified address of a card */ |
||||
|
sd_error_enum sd_multiblocks_read(uint32_t SDIO, uint32_t *preadbuffer, uint32_t readaddr, uint16_t blocksize, uint32_t blocksnumber); |
||||
|
/* write a block data to the specified address of a card */ |
||||
|
sd_error_enum sd_block_write(uint32_t SDIO, uint32_t *pwritebuffer, uint32_t writeaddr, uint16_t blocksize); |
||||
|
/* write multiple blocks data to the specified address of a card */ |
||||
|
sd_error_enum sd_multiblocks_write(uint32_t SDIO, uint32_t *pwritebuffer, uint32_t writeaddr, uint16_t blocksize, uint32_t blocksnumber); |
||||
|
/* erase a continuous area of a card */ |
||||
|
sd_error_enum sd_erase(uint32_t SDIO, uint32_t startaddr, uint32_t endaddr); |
||||
|
/* process all the interrupts which the corresponding flags are set */ |
||||
|
sd_error_enum sd_interrupts_process(uint32_t SDIO); |
||||
|
|
||||
|
/* select or deselect a card */ |
||||
|
sd_error_enum sd_card_select_deselect(uint32_t SDIO, uint16_t cardrca); |
||||
|
/* get the card status whose response format R1 contains a 32-bit field */ |
||||
|
sd_error_enum sd_cardstatus_get(uint32_t SDIO, uint32_t *pcardstatus); |
||||
|
/* get the SD status, the size of the SD status is one data block of 512 bit */ |
||||
|
sd_error_enum sd_sdstatus_get(uint32_t SDIO, uint32_t *psdstatus); |
||||
|
/* stop an ongoing data transfer */ |
||||
|
sd_error_enum sd_transfer_stop(uint32_t SDIO); |
||||
|
/* lock or unlock a card */ |
||||
|
sd_error_enum sd_lock_unlock(uint32_t SDIO, uint8_t lockstate); |
||||
|
|
||||
|
/* get the data transfer state */ |
||||
|
sd_transfer_state_enum sd_transfer_state_get(uint32_t SDIO); |
||||
|
/* get SD card capacity(KB) */ |
||||
|
uint32_t sd_card_capacity_get(uint32_t SDIO); |
||||
|
/* get the detailed information of the SD card based on received CID and CSD */ |
||||
|
sd_error_enum sd_card_information_get(uint32_t SDIO, sd_card_info_struct *pcardinfo); |
||||
|
|
||||
|
/* switch 1.8V power level of SD card */ |
||||
|
sd_error_enum sd_card_voltage_switch(uint32_t SDIO); |
||||
|
|
||||
|
#ifdef USE_18V_SWITCH |
||||
|
/* configure CPDM */ |
||||
|
void cpdm_config(void); |
||||
|
/* perform sampling point tuning using tuning command */ |
||||
|
sd_error_enum sd_tuning(uint32_t SDIO); |
||||
|
#endif /* USE_18V_SWITCH */ |
||||
|
|
||||
|
#endif /* __SDCARD_H_ */ |
||||
@ -0,0 +1,81 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-12-20 BruceOu first implementation |
||||
|
* 2025-10-10 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_SPI_H__ |
||||
|
#define __DRV_SPI_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#define RT_SPI_USING_DMA |
||||
|
|
||||
|
#if !defined(SOC_SERIES_GD32H7xx) && !defined(SOC_SERIES_GD32H75E) |
||||
|
#undef RT_SPI_USING_DMA |
||||
|
#endif |
||||
|
|
||||
|
struct gd32_spi_cs |
||||
|
{ |
||||
|
uint32_t GPIOx; |
||||
|
uint32_t GPIO_Pin; |
||||
|
}; |
||||
|
|
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
/* dma peripheral */ |
||||
|
uint32_t dma_periph; |
||||
|
/* dma txchannel */ |
||||
|
dma_channel_enum txdma_ch; |
||||
|
/* dma rxchannel */ |
||||
|
dma_channel_enum rxdma_ch; |
||||
|
/* tx dma request */ |
||||
|
uint32_t dma_mux_req_tx; |
||||
|
/* rx dma request */ |
||||
|
uint32_t dma_mux_req_rx; |
||||
|
/* dma flag */ |
||||
|
uint32_t rx_flag; |
||||
|
/* setting receive len */ |
||||
|
rt_size_t setting_recv_len; |
||||
|
|
||||
|
} gd32_spi_dma; |
||||
|
#endif |
||||
|
|
||||
|
/* gd32 spi dirver class */ |
||||
|
struct gd32_spi |
||||
|
{ |
||||
|
uint32_t spi_periph; |
||||
|
char *bus_name; |
||||
|
rcu_periph_enum spi_clk; |
||||
|
struct rt_spi_bus *spi_bus; |
||||
|
const char *sck_pin_name; /* sck pin name */ |
||||
|
const char *miso_pin_name; /* miso pin name */ |
||||
|
const char *mosi_pin_name; /* mosi pin name */ |
||||
|
const char *alternate; /* afio mode */ |
||||
|
#ifdef RT_SPI_USING_DMA |
||||
|
gd32_spi_dma *spi_dma; |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_SPI_H__ */ |
||||
|
|
||||
@ -0,0 +1,82 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2021-08-20 BruceOu first implementation |
||||
|
* 2025-10-09 WangShun compatible with RT-Studio |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_USART_H__ |
||||
|
#define __DRV_USART_H__ |
||||
|
|
||||
|
#include <rthw.h> |
||||
|
#include <rtthread.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if !defined(SOC_SERIES_GD32H7xx) || !defined(SOC_SERIES_GD32H75E) |
||||
|
#undef RT_SERIAL_USING_DMA |
||||
|
#endif |
||||
|
#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) |
||||
|
#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) |
||||
|
|
||||
|
#ifdef RT_SERIAL_USING_DMA |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
/* dma peripheral */ |
||||
|
uint32_t dma_periph; |
||||
|
/* dma channel */ |
||||
|
dma_channel_enum dma_ch; |
||||
|
#if defined(SOC_SERIES_GD32H7xx) || defined(SOC_SERIES_GD32H75E) |
||||
|
/* rx dma request */ |
||||
|
uint32_t dma_mux_req_rx; |
||||
|
#endif |
||||
|
/* dma flag */ |
||||
|
uint32_t rx_flag; |
||||
|
/* dma irq channel */ |
||||
|
uint8_t rx_irq_ch; |
||||
|
/* setting receive len */ |
||||
|
rt_size_t setting_recv_len; |
||||
|
/* last receive index */ |
||||
|
rt_size_t last_recv_index; |
||||
|
} gd32_uart_dma; |
||||
|
|
||||
|
#endif |
||||
|
/* GD32 uart driver */ |
||||
|
|
||||
|
struct gd32_uart |
||||
|
{ |
||||
|
uint32_t uart_periph; /* Instance */ |
||||
|
IRQn_Type irqn; /* irqn */ |
||||
|
rcu_periph_enum per_clk; /* uart_clk */ |
||||
|
|
||||
|
const char *tx_pin_name; /* tx pin name */ |
||||
|
const char *rx_pin_name; /* rx pin name */ |
||||
|
const char *alternate; /* rx pin name */ |
||||
|
|
||||
|
#ifdef RT_SERIAL_USING_DMA |
||||
|
gd32_uart_dma *uart_dma; |
||||
|
#ifdef RT_SERIAL_USING_TX_DMA |
||||
|
gd32_uart_dma *uart_tx_dma; |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
struct rt_serial_device * serial; /* serial device */ |
||||
|
char *device_name; |
||||
|
}; |
||||
|
|
||||
|
int rt_hw_usart_init(void); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* __DRV_USART_H__ */ |
||||
|
|
||||
File diff suppressed because it is too large
@ -0,0 +1,29 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_OTGFS_DEV_H__ |
||||
|
#define __DRV_OTGFS_DEV_H__ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
#include "drv_usb_dev.h" |
||||
|
|
||||
|
void usbd_reset_callback(void); |
||||
|
|
||||
|
void usbd_setup_stage_callback(struct urequest *setup_packet); |
||||
|
|
||||
|
void usbd_data_in_stage_callback(uint8_t epnum, uint16_t data_count); |
||||
|
|
||||
|
void usbd_data_out_stage_callback(uint8_t epnum, uint16_t data_count); |
||||
|
|
||||
|
void usbd_set_connection_state(uint8_t state); |
||||
|
|
||||
|
int gd_usbd_register(void); |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,34 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_OTGFS_HOST_H__ |
||||
|
#define __DRV_OTGFS_HOST_H__ |
||||
|
|
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
|
||||
|
#include "drv_usb_host.h" |
||||
|
#include "drv_usbh_transc.h" |
||||
|
#include "drv_usbh_pipe.h" |
||||
|
|
||||
|
#define OTG_FS_PORT 1 |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
void usbh_connect_callback(usb_core_driver *hhcd); |
||||
|
|
||||
|
void usbh_disconnect_callback(usb_core_driver *hhcd); |
||||
|
|
||||
|
void usbh_hc_notifyurbchange_callback(usb_core_driver *hhcd, uint8_t chnum, usb_urb_state urb_state); |
||||
|
|
||||
|
int gd_usbh_register(void); |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
|
#endif |
||||
@ -0,0 +1,369 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USB_CORE_H |
||||
|
#define DRV_USB_CORE_H |
||||
|
|
||||
|
#include "drv_usb_regs.h" |
||||
|
|
||||
|
#define USB_FS_EP0_MAX_LEN 64U /*!< maximum packet size of endpoint 0 */ |
||||
|
#define HC_MAX_PACKET_COUNT 140U /*!< maximum packet count */ |
||||
|
|
||||
|
#define EP_ID(x) ((uint8_t)((x) & 0x7FU)) /*!< endpoint number */ |
||||
|
#define EP_DIR(x) ((uint8_t)((x) >> 7)) /*!< endpoint direction */ |
||||
|
|
||||
|
typedef struct urequest usb_req; |
||||
|
|
||||
|
enum _usb_eptype |
||||
|
{ |
||||
|
USB_EPTYPE_CTRL = 0U, /*!< control endpoint type */ |
||||
|
USB_EPTYPE_ISOC = 1U, /*!< isochronous endpoint type */ |
||||
|
USB_EPTYPE_BULK = 2U, /*!< bulk endpoint type */ |
||||
|
USB_EPTYPE_INTR = 3U, /*!< interrupt endpoint type */ |
||||
|
USB_EPTYPE_MASK = 3U /*!< endpoint type mask */ |
||||
|
}; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
USB_OTG_OK = 0U, /*!< USB OTG status OK */ |
||||
|
USB_OTG_FAIL /*!< USB OTG status fail */ |
||||
|
} usb_otg_status; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
USB_OK = 0U, /*!< USB status OK */ |
||||
|
USB_FAIL /*!< USB status fail */ |
||||
|
} usb_status; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
USB_USE_FIFO, /*!< USB use FIFO transfer mode */ |
||||
|
USB_USE_DMA /*!< USB use DMA transfer mode */ |
||||
|
} usb_transfer_mode; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
LPM_L0 = 0U, /*!< on */ |
||||
|
LPM_L1, /*!< LPM L1 sleep */ |
||||
|
LPM_L2, /*!< suspend */ |
||||
|
LPM_L3, /*!< off */ |
||||
|
} usb_lpm_state; |
||||
|
|
||||
|
enum usb_ctl_status |
||||
|
{ |
||||
|
USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */ |
||||
|
USB_CTL_DATA_IN, /*!< USB control transfer data IN state */ |
||||
|
USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data IN state */ |
||||
|
USB_CTL_DATA_OUT, /*!< USB control transfer data OUT state */ |
||||
|
USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data OUT state */ |
||||
|
USB_CTL_STATUS_IN, /*!< USB control transfer status IN state*/ |
||||
|
USB_CTL_STATUS_OUT /*!< USB control transfer status OUT state */ |
||||
|
}; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
LPM_L0_ACTIVE = 0U, /*!< on */ |
||||
|
LPM_L1_ACTIVE, /*!< LPM L1 sleep */ |
||||
|
} usb_lpm_type; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
uint8_t core_enum; /*!< USB core type */ |
||||
|
uint8_t core_speed; /*!< USB core speed */ |
||||
|
uint8_t num_pipe; /*!< USB host channel numbers */ |
||||
|
uint8_t num_ep; /*!< USB device endpoint numbers */ |
||||
|
uint8_t transfer_mode; /*!< USB transfer mode */ |
||||
|
uint8_t phy_itf; /*!< USB core PHY interface */ |
||||
|
uint8_t sof_enable; /*!< USB SOF output */ |
||||
|
uint8_t low_power; /*!< USB low power */ |
||||
|
uint8_t lpm_enable; /*!< USB link power mode(LPM) */ |
||||
|
uint8_t vbus_sensing_enable; /*!< USB VBUS sensing feature */ |
||||
|
uint8_t use_dedicated_ep1; /*!< USB dedicated endpoint1 interrupt */ |
||||
|
uint8_t use_external_vbus; /*!< enable or disable the use of the external VBUS */ |
||||
|
uint32_t base_reg; /*!< base register address */ |
||||
|
} usb_core_basic; |
||||
|
|
||||
|
#ifdef USE_DEVICE_MODE |
||||
|
|
||||
|
/* USB descriptor */ |
||||
|
typedef struct _usb_desc |
||||
|
{ |
||||
|
uint8_t *dev_desc; /*!< device descriptor */ |
||||
|
uint8_t *config_desc; /*!< configuration descriptor */ |
||||
|
uint8_t *bos_desc; /*!< BOS descriptor */ |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
uint8_t *other_speed_config_desc; /*!< other speed configuration descriptor */ |
||||
|
uint8_t *qualifier_desc; /*!< qualifier descriptor */ |
||||
|
#endif |
||||
|
|
||||
|
void * const *strings; /*!< string descriptor */ |
||||
|
} usb_desc; |
||||
|
|
||||
|
/* USB power management */ |
||||
|
typedef struct _usb_pm |
||||
|
{ |
||||
|
uint8_t power_mode; /*!< power mode */ |
||||
|
uint8_t power_low; /*!< power low */ |
||||
|
uint8_t dev_remote_wakeup; /*!< remote wakeup */ |
||||
|
uint8_t remote_wakeup_on; /*!< remote wakeup on */ |
||||
|
usb_lpm_state lpm_state; /*!< LPM state */ |
||||
|
uint32_t BESL; /*!< BESL value */ |
||||
|
} usb_pm; |
||||
|
|
||||
|
/* USB control information */ |
||||
|
typedef struct _usb_control |
||||
|
{ |
||||
|
usb_req req; /*!< USB standard device request */ |
||||
|
|
||||
|
uint8_t ctl_state; /*!< USB control transfer state */ |
||||
|
uint8_t ctl_zlp; /*!< zero length package */ |
||||
|
} usb_control; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
struct |
||||
|
{ |
||||
|
uint8_t num : 4U; /*!< the endpoint number.it can be from 0 to 6 */ |
||||
|
uint8_t pad : 3U; /*!< padding between number and direction */ |
||||
|
uint8_t dir : 1U; /*!< the endpoint direction */ |
||||
|
} ep_addr; |
||||
|
|
||||
|
uint8_t ep_type; /*!< USB endpoint type */ |
||||
|
uint8_t ep_stall; /*!< USB endpoint STALL status */ |
||||
|
|
||||
|
uint8_t frame_num; /*!< number of frame */ |
||||
|
uint16_t max_len; /*!< maximum packet length */ |
||||
|
|
||||
|
/* transaction level variables */ |
||||
|
uint8_t *xfer_buf; /*!< transmit buffer */ |
||||
|
uint32_t xfer_len; /*!< transmit buffer length */ |
||||
|
uint32_t xfer_count; /*!< transmit buffer count */ |
||||
|
|
||||
|
uint32_t remain_len; /*!< remain packet length */ |
||||
|
|
||||
|
uint32_t dma_addr; /*!< DMA address */ |
||||
|
} usb_transc; |
||||
|
|
||||
|
typedef struct _usb_core_driver usb_dev; |
||||
|
|
||||
|
typedef struct _usb_class_core |
||||
|
{ |
||||
|
uint8_t alter_set; /*!< alternative set */ |
||||
|
uint8_t command; /*!< device class request command */ |
||||
|
|
||||
|
uint8_t (*init)(usb_dev *udev, uint8_t config_index); /*!< initialize handler */ |
||||
|
uint8_t (*deinit)(usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */ |
||||
|
uint8_t (*req_proc)(usb_dev *udev, usb_req *req); /*!< device request handler */ |
||||
|
uint8_t (*set_intf)(usb_dev *udev, usb_req *req); /*!< device set interface callback */ |
||||
|
uint8_t (*ctlx_in)(usb_dev *udev); /*!< device control IN callback */ |
||||
|
uint8_t (*ctlx_out)(usb_dev *udev); /*!< device control OUT callback */ |
||||
|
uint8_t (*data_in)(usb_dev *udev, uint8_t ep_num); /*!< device data IN handler */ |
||||
|
uint8_t (*data_out)(usb_dev *udev, uint8_t ep_num); /*!< device data OUT handler */ |
||||
|
uint8_t (*SOF)(usb_dev *udev); /*!< start of frame handler */ |
||||
|
uint8_t (*incomplete_isoc_in)(usb_dev *udev); /*!< incomplete synchronization IN transfer handler */ |
||||
|
uint8_t (*incomplete_isoc_out)(usb_dev *udev); /*!< incomplete synchronization OUT transfer handler */ |
||||
|
} usb_class_core; |
||||
|
|
||||
|
typedef struct _usb_perp_dev |
||||
|
{ |
||||
|
uint8_t config; /*!< configuration */ |
||||
|
uint8_t dev_addr; /*!< device address */ |
||||
|
|
||||
|
__IO uint8_t cur_status; /*!< current status */ |
||||
|
__IO uint8_t backup_status; /*!< backup status */ |
||||
|
|
||||
|
usb_transc transc_in[USBHS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */ |
||||
|
usb_transc transc_out[USBHS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */ |
||||
|
|
||||
|
usb_pm pm; /*!< power management */ |
||||
|
usb_control control; /*!< USB control information */ |
||||
|
usb_desc *desc; /*!< USB descriptors pointer */ |
||||
|
usb_class_core *class_core; /*!< class driver */ |
||||
|
void *class_data[4]; /*!< class data pointer */ |
||||
|
void *user_data; /*!< user data pointer */ |
||||
|
void *pdata; /*!< reserved data pointer */ |
||||
|
} usb_perp_dev; |
||||
|
|
||||
|
#endif /* USE_DEVICE_MODE */ |
||||
|
|
||||
|
#ifdef USE_HOST_MODE |
||||
|
|
||||
|
typedef enum _usb_pipe_status |
||||
|
{ |
||||
|
PIPE_IDLE = 0U, /*!< host pipe IDLE status */ |
||||
|
PIPE_XF, /*!< host pipe transfer completed status */ |
||||
|
PIPE_HALTED, /*!< host pipe halted status */ |
||||
|
PIPE_NAK, /*!< host pipe NAK status */ |
||||
|
PIPE_NYET, /*!< host pipe NYET status */ |
||||
|
PIPE_STALL, /*!< host pipe STALL status */ |
||||
|
PIPE_TRACERR, /*!< host pipe transaction error status */ |
||||
|
PIPE_BBERR, /*!< host pipe babble error status */ |
||||
|
PIPE_REQOVR, /*!< host pipe frame overrun status */ |
||||
|
PIPE_DTGERR, /*!< host pipe data toggle error status */ |
||||
|
} usb_pipe_status; |
||||
|
|
||||
|
typedef enum _usb_pipe_mode |
||||
|
{ |
||||
|
PIPE_PERIOD = 0U, /*!< USB host pipe PERIOD mode */ |
||||
|
PIPE_NON_PERIOD = 1U /*!< USB host pipe NOT PERIOD mode */ |
||||
|
} usb_pipe_mode; |
||||
|
|
||||
|
typedef enum _usb_urb_state |
||||
|
{ |
||||
|
URB_IDLE = 0U, /*!< USB URB IDLE state */ |
||||
|
URB_DONE, /*!< USB URB DONE state */ |
||||
|
URB_NOTREADY, /*!< USB URB NOT READY state */ |
||||
|
URB_ERROR, /*!< USB URB ERROR state */ |
||||
|
URB_STALL, /*!< USB URB STALL state */ |
||||
|
URB_PING /*!< USB URB PING state */ |
||||
|
} usb_urb_state; |
||||
|
|
||||
|
typedef struct _usb_pipe |
||||
|
{ |
||||
|
uint8_t in_used; /*!< pipe used */ |
||||
|
uint8_t dev_addr; /*!< USB device address */ |
||||
|
uint32_t dev_speed; /*!< USB device speed */ |
||||
|
|
||||
|
struct |
||||
|
{ |
||||
|
uint8_t num; /*!< endpoint numbers */ |
||||
|
uint8_t dir; /*!< endpoint direction */ |
||||
|
uint8_t type; /*!< endpoint transfer type */ |
||||
|
uint16_t mps; /*!< endpoint max packet size */ |
||||
|
} ep; |
||||
|
|
||||
|
__IO uint8_t supp_ping; /*!< host pipe support PING */ |
||||
|
__IO uint8_t do_ping; /*!< host pipe do PING */ |
||||
|
__IO uint32_t DPID; /*!< data PID */ |
||||
|
|
||||
|
uint8_t *xfer_buf; /*!< USB transfer buffer */ |
||||
|
uint32_t xfer_len; /*!< USB transfer length */ |
||||
|
uint32_t xfer_count; /*!< USB transfer count */ |
||||
|
|
||||
|
uint8_t data_toggle_in; /*!< toggle DATA IN */ |
||||
|
uint8_t data_toggle_out; /*!< toggle DATA OUT */ |
||||
|
|
||||
|
__IO uint32_t err_count; /*!< error count */ |
||||
|
__IO usb_pipe_status pp_status; /*!< USB pipe status */ |
||||
|
__IO usb_urb_state urb_state; /*!< USB URB state */ |
||||
|
} usb_pipe; |
||||
|
|
||||
|
typedef struct _usb_host_drv |
||||
|
{ |
||||
|
__IO uint32_t connect_status; /*!< connect status */ |
||||
|
__IO uint32_t port_enabled; /*!< USB port enable */ |
||||
|
__IO uint32_t backup_xfercount[USBHS_MAX_TX_FIFOS]; /*!< USB backup transfer data count */ |
||||
|
|
||||
|
usb_pipe pipe[USBHS_MAX_TX_FIFOS]; /*!< USB host pipe handles */ |
||||
|
void *data; /*!< user data pointer */ |
||||
|
} usb_host_drv; |
||||
|
|
||||
|
#endif /* USE_HOST_MODE */ |
||||
|
|
||||
|
typedef struct _usb_core_driver |
||||
|
{ |
||||
|
usb_core_basic bp; /*!< USB basic parameters */ |
||||
|
usb_core_regs regs; /*!< USB registers */ |
||||
|
|
||||
|
#ifdef USE_DEVICE_MODE |
||||
|
usb_perp_dev dev; /*!< USB peripheral device */ |
||||
|
#endif /* USE_DEVICE_MODE */ |
||||
|
|
||||
|
#ifdef USE_HOST_MODE |
||||
|
usb_host_drv host; /*!< USB peripheral host */ |
||||
|
#endif /* USE_HOST_MODE */ |
||||
|
} usb_core_driver; |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
BCD_NONE = 0, |
||||
|
BCD_SDP, |
||||
|
BCD_DCP, |
||||
|
BCD_CDP, |
||||
|
BCD_PS2, |
||||
|
BCD_ERROR |
||||
|
} bcd_type; |
||||
|
|
||||
|
/* static inline function definitions */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief get the global interrupts |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval interrupt status |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_coreintr_get(usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
uint32_t reg_data = usb_regs->gr->GINTEN; |
||||
|
|
||||
|
reg_data &= usb_regs->gr->GINTF; |
||||
|
|
||||
|
return reg_data; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set USB RX FIFO size |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] size: assigned FIFO size |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_set_rxfifo(usb_core_regs *usb_regs, uint16_t size) |
||||
|
{ |
||||
|
usb_regs->gr->GRFLEN = size; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief enable the global interrupts |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_globalint_enable(usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
/* enable USB global interrupt */ |
||||
|
usb_regs->gr->GAHBCS |= GAHBCS_GINTEN; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief disable the global interrupts |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_globalint_disable(usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
/* disable USB global interrupt */ |
||||
|
usb_regs->gr->GAHBCS &= ~GAHBCS_GINTEN; |
||||
|
} |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* configures USB parameters */ |
||||
|
void usb_para_init(usb_core_driver *core, uint32_t usb_periph, uint32_t usb_speed); |
||||
|
/* configure core capabilities */ |
||||
|
usb_status usb_basic_init(usb_core_basic *usb_basic, usb_core_regs *usb_regs); |
||||
|
/*initializes the USB controller registers and prepares the core device mode or host mode operation*/ |
||||
|
usb_status usb_core_init(usb_core_basic usb_basic, usb_core_regs *usb_regs); |
||||
|
/* write a packet into the TX FIFO associated with the endpoint */ |
||||
|
usb_status usb_txfifo_write(usb_core_regs *usb_regs, uint8_t *src_buf, uint8_t fifo_num, uint16_t byte_count); |
||||
|
/* read a packet from the RX FIFO associated with the endpoint */ |
||||
|
void *usb_rxfifo_read(usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count); |
||||
|
/* flush a TX FIFO or all TX FIFOs */ |
||||
|
usb_status usb_txfifo_flush(usb_core_regs *usb_regs, uint8_t fifo_num); |
||||
|
/* flush the entire RX FIFO */ |
||||
|
usb_status usb_rxfifo_flush(usb_core_regs *usb_regs); |
||||
|
/* set endpoint or channel TX FIFO size */ |
||||
|
void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size); |
||||
|
/* set USB current mode */ |
||||
|
void usb_curmode_set(usb_core_regs *usb_regs, uint8_t mode); |
||||
|
void usb_clock_active(usb_core_driver *udev); |
||||
|
|
||||
|
#endif /* DRV_USB_CORE_H */ |
||||
@ -0,0 +1,195 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USB_DEV_H |
||||
|
#define DRV_USB_DEV_H |
||||
|
|
||||
|
#include "drv_usb_core.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE) |
||||
|
|
||||
|
#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */ |
||||
|
#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */ |
||||
|
#define EP_MAX_PACKET_SIZE_MASK 0x07FFU /*!< endpoint maximum packet size mask */ |
||||
|
|
||||
|
#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b)) |
||||
|
|
||||
|
/* static inline function definitions */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure the USB device to be disconnected |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_dev_disconnect(usb_core_driver *udev) |
||||
|
{ |
||||
|
udev->regs.dr->DCTL |= DCTL_SD; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure the USB device to be connected |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_dev_connect(usb_core_driver *udev) |
||||
|
{ |
||||
|
udev->regs.dr->DCTL &= ~DCTL_SD; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set the USB device address |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] dev_addr: device address for setting |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_devaddr_set(usb_core_driver *udev, uint8_t dev_addr) |
||||
|
{ |
||||
|
udev->regs.dr->DCFG &= ~DCFG_DAR; |
||||
|
udev->regs.dr->DCFG |= (uint32_t)dev_addr << 4; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read device all OUT endpoint interrupt register |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval interrupt status |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_oepintnum_read(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t value = udev->regs.dr->DAEPINT; |
||||
|
|
||||
|
value &= udev->regs.dr->DAEPINTEN; |
||||
|
|
||||
|
return (value & DAEPINT_OEPITB) >> 16; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read device OUT endpoint interrupt flag register |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] ep_num: endpoint number |
||||
|
\param[out] none |
||||
|
\retval interrupt status |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_oepintr_read(usb_core_driver *udev, uint8_t ep_num) |
||||
|
{ |
||||
|
uint32_t value = udev->regs.er_out[ep_num]->DOEPINTF; |
||||
|
|
||||
|
value &= udev->regs.dr->DOEPINTEN; |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read device all IN endpoint interrupt register |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval interrupt status |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_iepintnum_read(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t value = udev->regs.dr->DAEPINT; |
||||
|
|
||||
|
value &= udev->regs.dr->DAEPINTEN; |
||||
|
|
||||
|
return value & DAEPINT_IEPITB; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set remote wakeup signaling |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_rwkup_set(usb_core_driver *udev) |
||||
|
{ |
||||
|
if (udev->dev.pm.dev_remote_wakeup) |
||||
|
{ |
||||
|
/* enable remote wakeup signaling */ |
||||
|
udev->regs.dr->DCTL |= DCTL_RWKUP; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief reset remote wakeup signaling |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_rwkup_reset(usb_core_driver *udev) |
||||
|
{ |
||||
|
if (udev->dev.pm.dev_remote_wakeup) |
||||
|
{ |
||||
|
/* disable remote wakeup signaling */ |
||||
|
udev->regs.dr->DCTL &= ~DCTL_RWKUP; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief enable USB BCD function |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_bcd_enable(usb_core_driver *udev) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG |= GCCFG_BCDEN; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief disable USB BCD function |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
__STATIC_INLINE void usb_bcd_disable(usb_core_driver *udev) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_BCDEN; |
||||
|
} |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* initialize USB core registers for device mode */ |
||||
|
usb_status usb_devcore_init(usb_core_driver *udev); |
||||
|
/* enable the USB device mode interrupts */ |
||||
|
usb_status usb_devint_enable(usb_core_driver *udev); |
||||
|
/* active the USB endpoint 0 transaction */ |
||||
|
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc); |
||||
|
/* active the USB transaction */ |
||||
|
usb_status usb_ep_active(usb_core_driver *udev, uint8_t ep_addr, uint8_t ep_mps, uint8_t ep_attr); |
||||
|
/* deactivate the USB transaction */ |
||||
|
usb_status usb_ep_deactivate(usb_core_driver *udev, uint8_t ep_addr); |
||||
|
/* configure USB transaction to start IN transfer */ |
||||
|
usb_status usb_ep_inxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count); |
||||
|
/* configure USB transaction to start OUT transfer */ |
||||
|
usb_status usb_ep_outxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count); |
||||
|
/* set the USB transaction STALL status */ |
||||
|
usb_status usb_ep_stall(usb_core_driver *udev, uint8_t ep_addr); |
||||
|
/* clear the USB transaction STALL status */ |
||||
|
usb_status usb_ep_clrstall(usb_core_driver *udev, uint8_t ep_addr); |
||||
|
/* read device IN endpoint interrupt flag register */ |
||||
|
uint32_t usb_iepintr_read(usb_core_driver *udev, uint8_t ep_num); |
||||
|
/* configures OUT endpoint 0 to receive SETUP packets */ |
||||
|
void usb_ctlep_startout(usb_core_driver *udev); |
||||
|
/* active remote wakeup signaling */ |
||||
|
void usb_rwkup_active(usb_core_driver *udev); |
||||
|
/* active USB core clock */ |
||||
|
void usb_clock_active(usb_core_driver *udev); |
||||
|
/* USB device suspend */ |
||||
|
void usb_dev_suspend(usb_core_driver *udev); |
||||
|
/* stop the device and clean up FIFOs */ |
||||
|
void usb_dev_stop(usb_core_driver *udev); |
||||
|
/* USB battery charging detect operation */ |
||||
|
bcd_type usbd_bcd_detect(usb_core_driver *udev); |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */ |
||||
|
|
||||
|
#endif /* DRV_USB_DEV_H */ |
||||
@ -0,0 +1,93 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USB_HOST_H |
||||
|
#define DRV_USB_HOST_H |
||||
|
|
||||
|
#include "drv_usb_core.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
USBH_OK = 0U, |
||||
|
USBH_BUSY, |
||||
|
USBH_FAIL, |
||||
|
USBH_NOT_SUPPORTED, |
||||
|
USBH_UNRECOVERED_ERROR, |
||||
|
USBH_SPEED_UNKNOWN_ERROR, |
||||
|
USBH_APPLY_DEINIT |
||||
|
} usbh_status; |
||||
|
|
||||
|
/*!
|
||||
|
\brief get USB even frame |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval USB even frame state |
||||
|
*/ |
||||
|
__STATIC_INLINE uint8_t usb_frame_even(usb_core_driver *udev) |
||||
|
{ |
||||
|
return (uint8_t) !(udev->regs.hr->HFINFR & 0x01U); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read USB port |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval port status |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_port_read(usb_core_driver *udev) |
||||
|
{ |
||||
|
return *udev->regs.HPCS & ~(HPCS_PE | HPCS_PCD | HPCS_PEDC); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief get USB current speed |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval USB current speed |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_curspeed_get(usb_core_driver *udev) |
||||
|
{ |
||||
|
return *udev->regs.HPCS & HPCS_PS; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief get USB current frame |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval USB current frame |
||||
|
*/ |
||||
|
__STATIC_INLINE uint32_t usb_curframe_get(usb_core_driver *udev) |
||||
|
{ |
||||
|
return (udev->regs.hr->HFINFR & 0xFFFFU); |
||||
|
} |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* initializes USB core for host mode */ |
||||
|
usb_status usb_host_init(usb_core_driver *udev); |
||||
|
/* control the VBUS to power */ |
||||
|
void usb_portvbus_switch(usb_core_driver *udev, uint8_t state); |
||||
|
/* reset host port */ |
||||
|
uint32_t usb_port_reset(usb_core_driver *udev); |
||||
|
/* initialize host pipe */ |
||||
|
usb_status usb_pipe_init(usb_core_driver *udev, uint8_t pipe_num); |
||||
|
/* prepare host pipe for transferring packets */ |
||||
|
usb_status usb_pipe_xfer(usb_core_driver *udev, uint8_t pipe_num); |
||||
|
/* halt host pipe */ |
||||
|
usb_status usb_pipe_halt(usb_core_driver *udev, uint8_t pipe_num); |
||||
|
/* configure host pipe to do ping operation */ |
||||
|
usb_status usb_pipe_ping(usb_core_driver *udev, uint8_t pipe_num); |
||||
|
/* stop the USB host and clean up FIFO */ |
||||
|
void usb_host_stop(usb_core_driver *udev); |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
|
|
||||
|
#endif /* DRV_USB_HOST_H */ |
||||
@ -0,0 +1,42 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USB_HW_H |
||||
|
#define DRV_USB_HW_H |
||||
|
|
||||
|
#include "drv_usb_core.h" |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* configure USB clock */ |
||||
|
void usb_rcu_config(void); |
||||
|
/* configure USB data line GPIO */ |
||||
|
void usb_gpio_config(void); |
||||
|
/* configure USB interrupt */ |
||||
|
void usb_intr_config(void); |
||||
|
/* initializes delay unit using Timer2 */ |
||||
|
void usb_timer_init(void); |
||||
|
/* delay in microseconds */ |
||||
|
void usb_udelay(const uint32_t usec); |
||||
|
/* delay in milliseconds */ |
||||
|
void usb_mdelay(const uint32_t msec); |
||||
|
|
||||
|
/* configure USB clock */ |
||||
|
void pllusb_rcu_config(uint32_t usb_periph); |
||||
|
|
||||
|
#ifdef USE_HOST_MODE |
||||
|
/* configure systick */ |
||||
|
void systick_config(void); |
||||
|
/* configure USB VBus */ |
||||
|
void usb_vbus_config(void); |
||||
|
/* drive USB VBus */ |
||||
|
void usb_vbus_drive(uint8_t State); |
||||
|
#endif /* USE_HOST_MODE */ |
||||
|
|
||||
|
#endif /* DRV_USB_HW_H */ |
||||
@ -0,0 +1,728 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USB_REGS_H |
||||
|
#define DRV_USB_REGS_H |
||||
|
|
||||
|
#include "usb_conf.h" |
||||
|
|
||||
|
#define USBHS0 USBHS_BASE |
||||
|
#define USBHS1 (USBHS_BASE + 0x00040000U) |
||||
|
|
||||
|
#define USBHS0_REG_BASE USBHS0 /*!< base address of USBHS0 registers */ |
||||
|
#define USBHS1_REG_BASE USBHS1 /*!< base address of USBHS1 registers */ |
||||
|
|
||||
|
/* register definition */ |
||||
|
|
||||
|
#define USBHS_MAX_TX_FIFOS 16U /*!< FIFO number */ |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t GOTGCS; /*!< USB global OTG control and status register 000h */ |
||||
|
__IO uint32_t GOTGINTF; /*!< USB global OTG interrupt flag register 004h */ |
||||
|
__IO uint32_t GAHBCS; /*!< USB global AHB control and status register 008h */ |
||||
|
__IO uint32_t GUSBCS; /*!< USB global USB control and status register 00Ch */ |
||||
|
__IO uint32_t GRSTCTL; /*!< USB global reset control register 010h */ |
||||
|
__IO uint32_t GINTF; /*!< USB global interrupt flag register 014h */ |
||||
|
__IO uint32_t GINTEN; /*!< USB global interrupt enable register 018h */ |
||||
|
__IO uint32_t GRSTATR; /*!< USB receive status debug read register 01Ch */ |
||||
|
__IO uint32_t GRSTATP; /*!< USB receive status and pop register 020h */ |
||||
|
__IO uint32_t GRFLEN; /*!< USB global receive FIFO length register 024h */ |
||||
|
__IO uint32_t DIEP0TFLEN_HNPTFLEN; /*!< USB device IN endpoint 0/host non-periodic transmit FIFO length register 028h */ |
||||
|
__IO uint32_t HNPTFQSTAT; /*!< USB host non-periodic FIFO/queue status register 02Ch */ |
||||
|
uint32_t Reserved30[2]; /*!< Reserved 030h */ |
||||
|
__IO uint32_t GCCFG; /*!< USB global core configuration register 038h */ |
||||
|
__IO uint32_t CID; /*!< USB core ID register 03Ch */ |
||||
|
uint32_t Reserved40[5]; /*!< Reserved 040h-053h */ |
||||
|
__IO uint32_t GLPMCFG; /*!< LPM configuration register 54h */ |
||||
|
__IO uint32_t PWRD; /*!< power down register 58h */ |
||||
|
uint32_t Reserved5C; /*!< Reserved 5Ch */ |
||||
|
__IO uint32_t ADPCTL; /*!< ADP control and status register 60h */ |
||||
|
uint32_t Reserved64[3]; /*!< Reserved 64h-6Fh */ |
||||
|
__IO uint32_t PHYCTL; /*!< USBHS PHY control register 70h */ |
||||
|
uint32_t Reserved74[35]; /*!< Reserved 74h-FFh */ |
||||
|
__IO uint32_t HPTFLEN; /*!< USB host periodic transmit FIFO length register 100h */ |
||||
|
__IO uint32_t DIEPTFLEN[15]; /*!< USB device IN endpoint transmit FIFO length register 104h */ |
||||
|
} usb_gr; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t HCTL; /*!< USB host control register 400h */ |
||||
|
__IO uint32_t HFT; /*!< USB host frame interval register 404h */ |
||||
|
__IO uint32_t HFINFR; /*!< USB host frame information remaining register 408h */ |
||||
|
uint32_t Reserved40C; /*!< Reserved 40Ch */ |
||||
|
__IO uint32_t HPTFQSTAT; /*!< USB host periodic transmit FIFO/queue status register 410h */ |
||||
|
__IO uint32_t HACHINT; /*!< USB host all channels interrupt register 414h */ |
||||
|
__IO uint32_t HACHINTEN; /*!< USB host all channels interrupt enable register 418h */ |
||||
|
} usb_hr; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t HCHCTL; /*!< USB host channel control register 500h */ |
||||
|
__IO uint32_t HCHSTCTL; /*!< Reserved 504h */ |
||||
|
__IO uint32_t HCHINTF; /*!< USB host channel interrupt flag register 508h */ |
||||
|
__IO uint32_t HCHINTEN; /*!< USB host channel interrupt enable register 50Ch */ |
||||
|
__IO uint32_t HCHLEN; /*!< USB host channel transfer length register 510h */ |
||||
|
__IO uint32_t HCHDMAADDR; /*!< USB host channel-x DMA address register 514h*/ |
||||
|
uint32_t Reserved[2]; |
||||
|
} usb_pr; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t DCFG; /*!< USB device configuration register 800h */ |
||||
|
__IO uint32_t DCTL; /*!< USB device control register 804h */ |
||||
|
__IO uint32_t DSTAT; /*!< USB device status register 808h */ |
||||
|
uint32_t Reserved0C; /*!< Reserved 80Ch */ |
||||
|
__IO uint32_t DIEPINTEN; /*!< USB device IN endpoint common interrupt enable register 810h */ |
||||
|
__IO uint32_t DOEPINTEN; /*!< USB device OUT endpoint common interrupt enable register 814h */ |
||||
|
__IO uint32_t DAEPINT; /*!< USB device all endpoints interrupt register 818h */ |
||||
|
__IO uint32_t DAEPINTEN; /*!< USB device all endpoints interrupt enable register 81Ch */ |
||||
|
uint32_t Reserved20; /*!< Reserved 820h */ |
||||
|
uint32_t Reserved24; /*!< Reserved 824h */ |
||||
|
__IO uint32_t DVBUSDT; /*!< USB device VBUS discharge time register 828h */ |
||||
|
__IO uint32_t DVBUSPT; /*!< USB device VBUS pulsing time register 82Ch */ |
||||
|
uint32_t Reserved30; /*!< Reserved 830h */ |
||||
|
__IO uint32_t DIEPFEINTEN; /*!< USB Device IN endpoint FIFO empty interrupt enable register 834h */ |
||||
|
__IO uint32_t DEP1INT; /*!< USB device endpoint 1 interrupt register 838h */ |
||||
|
__IO uint32_t DEP1INTEN; /*!< USB device endpoint 1 interrupt enable register 83Ch */ |
||||
|
uint32_t Reserved40; /*!< Reserved 840h */ |
||||
|
__IO uint32_t DIEP1INTEN; /*!< USB device IN endpoint-1 interrupt enable register 844h */ |
||||
|
uint32_t Reserved48[15]; /*!< Reserved 848-880h */ |
||||
|
__IO uint32_t DOEP1INTEN; /*!< USB device OUT endpoint-1 interrupt enable register 884h */ |
||||
|
} usb_dr; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t DIEPCTL; /*!< USB device IN endpoint control register 900h + (EpNum * 20h) + 00h */ |
||||
|
uint32_t Reserved04; /*!< Reserved 900h + (EpNum * 20h) + 04h */ |
||||
|
__IO uint32_t DIEPINTF; /*!< USB device IN endpoint interrupt flag register 900h + (EpNum * 20h) + 08h */ |
||||
|
uint32_t Reserved0C; /*!< Reserved 900h + (EpNum * 20h) + 0Ch */ |
||||
|
__IO uint32_t DIEPLEN; /*!< USB device IN endpoint transfer length register 900h + (EpNum * 20h) + 10h */ |
||||
|
__IO uint32_t DIEPDMAADDR; /*!< Device IN endpoint-x DMA address register 900h + (EpNum * 20h) + 14h */ |
||||
|
__IO uint32_t DIEPTFSTAT; /*!< USB device IN endpoint transmit FIFO status register 900h + (EpNum * 20h) + 18h */ |
||||
|
} usb_erin; |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
__IO uint32_t DOEPCTL; /*!< USB device IN endpoint control register B00h + (EpNum * 20h) + 00h */ |
||||
|
uint32_t Reserved04; /*!< Reserved B00h + (EpNum * 20h) + 04h */ |
||||
|
__IO uint32_t DOEPINTF; /*!< USB device IN endpoint interrupt flag register B00h + (EpNum * 20h) + 08h */ |
||||
|
uint32_t Reserved0C; /*!< Reserved B00h + (EpNum * 20h) + 0Ch */ |
||||
|
__IO uint32_t DOEPLEN; /*!< USB device IN endpoint transfer length register B00h + (EpNum * 20h) + 10h */ |
||||
|
__IO uint32_t DOEPDMAADDR; /*!< Device OUT endpoint-x DMA address register B00h + (EpNum * 20h) + 0Ch */ |
||||
|
} usb_erout; |
||||
|
|
||||
|
typedef struct _usb_regs |
||||
|
{ |
||||
|
usb_gr *gr; /*!< USBHS global registers */ |
||||
|
usb_dr *dr; /*!< device control and status registers */ |
||||
|
usb_hr *hr; /*!< host control and status registers */ |
||||
|
usb_erin *er_in[8]; /*!< USB device IN endpoint register */ |
||||
|
usb_erout *er_out[8]; /*!< USB device OUT endpoint register */ |
||||
|
usb_pr *pr[16]; /*!< USB Host channel-x control register */ |
||||
|
|
||||
|
__IO uint32_t *HPCS; /*!< USB host port control and status register */ |
||||
|
__IO uint32_t *DFIFO[USBHS_MAX_TX_FIFOS]; |
||||
|
__IO uint32_t *PWRCLKCTL; /*!< USB power and clock control register */ |
||||
|
} usb_core_regs; |
||||
|
|
||||
|
/* global OTG control and status register bits definitions */ |
||||
|
#define GOTGCS_OV BIT(20) /*!< select OTG version */ |
||||
|
#define GOTGCS_BSV BIT(19) /*!< B-Session Valid */ |
||||
|
#define GOTGCS_ASV BIT(18) /*!< A-session valid */ |
||||
|
#define GOTGCS_DI BIT(17) /*!< debounce interval */ |
||||
|
#define GOTGCS_IDPS BIT(16) /*!< id pin status */ |
||||
|
#define GOTGCS_EHE BIT(12) /*!< embedded host enable */ |
||||
|
#define GOTGCS_DHNPEN BIT(11) /*!< device HNP enable */ |
||||
|
#define GOTGCS_HHNPEN BIT(10) /*!< host HNP enable */ |
||||
|
#define GOTGCS_HNPREQ BIT(9) /*!< HNP request */ |
||||
|
#define GOTGCS_HNPS BIT(8) /*!< HNP successes */ |
||||
|
#define GOTGCS_BVOV BIT(7) /*!< override value of B-peripheral session valid */ |
||||
|
#define GOTGCS_BVOE BIT(6) /*!< override enable of B-peripheral session valid */ |
||||
|
#define GOTGCS_AVOV BIT(5) /*!< override value of A-peripheral session valid */ |
||||
|
#define GOTGCS_AVOE BIT(4) /*!< override enable of A-peripheral session valid */ |
||||
|
#define GOTGCS_VOV BIT(3) /*!< override value of VBUS valid */ |
||||
|
#define GOTGCS_VOE BIT(2) /*!< override enable of VBUS valid */ |
||||
|
#define GOTGCS_SRPREQ BIT(1) /*!< SRP request */ |
||||
|
#define GOTGCS_SRPS BIT(0) /*!< SRP successes */ |
||||
|
|
||||
|
/* global OTG interrupt flag register bits definitions */ |
||||
|
#define GOTGINTF_IDCHG BIT(20) /*!< ID input change */ |
||||
|
#define GOTGINTF_DF BIT(19) /*!< debounce finish */ |
||||
|
#define GOTGINTF_ADTO BIT(18) /*!< A-device timeout */ |
||||
|
#define GOTGINTF_HNPDET BIT(17) /*!< host negotiation request detected */ |
||||
|
#define GOTGINTF_HNPEND BIT(9) /*!< HNP end */ |
||||
|
#define GOTGINTF_SRPEND BIT(8) /*!< SRP end */ |
||||
|
#define GOTGINTF_SESEND BIT(2) /*!< session end */ |
||||
|
|
||||
|
/* global AHB control and status register bits definitions */ |
||||
|
#define GAHBCS_PTXFTH BIT(8) /*!< periodic Tx FIFO threshold */ |
||||
|
#define GAHBCS_TXFTH BIT(7) /*!< tx FIFO threshold */ |
||||
|
#define GAHBCS_DMAEN BIT(5) /*!< DMA function Enable */ |
||||
|
#define GAHBCS_BURST BITS(1, 4) /*!< the AHB burst type used by DMA */ |
||||
|
#define GAHBCS_GINTEN BIT(0) /*!< global interrupt enable */ |
||||
|
|
||||
|
/* global USB control and status register bits definitions */ |
||||
|
#define GUSBCS_FDM BIT(30) /*!< force device mode */ |
||||
|
#define GUSBCS_FHM BIT(29) /*!< force host mode */ |
||||
|
#define GUSBCS_ULPIEOI BIT(21) /*!< ULPI external over-current indicator */ |
||||
|
#define GUSBCS_ULPIEVD BIT(20) /*!< ULPI external VBUS driver */ |
||||
|
#define GUSBCS_UTT BITS(10, 13) /*!< USB turnaround time */ |
||||
|
#define GUSBCS_HNPCEN BIT(9) /*!< HNP capability enable */ |
||||
|
#define GUSBCS_SRPCEN BIT(8) /*!< SRP capability enable */ |
||||
|
#define GUSBCS_EMBPHY_FS BIT(6) /*!< embedded FS PHY selected */ |
||||
|
#define GUSBCS_EMBPHY_HS BIT(5) /*!< embedded HS PHY selected */ |
||||
|
#define GUSBCS_HS_CUR_FE BIT(4) /*!< HS current software enable */ |
||||
|
#define GUSBCS_TOC BITS(0, 2) /*!< timeout calibration */ |
||||
|
|
||||
|
/* global reset control register bits definitions */ |
||||
|
#define GRSTCTL_DMAIDL BIT(31) /*!< DMA idle state */ |
||||
|
#define GRSTCTL_DMABSY BIT(30) /*!< DMA busy */ |
||||
|
#define GRSTCTL_TXFNUM BITS(6, 10) /*!< tx FIFO number */ |
||||
|
#define GRSTCTL_TXFF BIT(5) /*!< tx FIFO flush */ |
||||
|
#define GRSTCTL_RXFF BIT(4) /*!< rx FIFO flush */ |
||||
|
#define GRSTCTL_HFCRST BIT(2) /*!< host frame counter reset */ |
||||
|
#define GRSTCTL_HCSRST BIT(1) /*!< HCLK soft reset */ |
||||
|
#define GRSTCTL_CSRST BIT(0) /*!< core soft reset */ |
||||
|
|
||||
|
/* global interrupt flag register bits definitions */ |
||||
|
#define GINTF_WKUPIF BIT(31) /*!< wakeup interrupt flag */ |
||||
|
#define GINTF_SESIF BIT(30) /*!< session interrupt flag */ |
||||
|
#define GINTF_DISCIF BIT(29) /*!< disconnect interrupt flag */ |
||||
|
#define GINTF_IDPSC BIT(28) /*!< id pin status change */ |
||||
|
#define GINTF_LPMIF BIT(27) /*!< LPM interrupt flag */ |
||||
|
#define GINTF_PTXFEIF BIT(26) /*!< periodic tx FIFO empty interrupt flag */ |
||||
|
#define GINTF_HCIF BIT(25) /*!< host channels interrupt flag */ |
||||
|
#define GINTF_HPIF BIT(24) /*!< host port interrupt flag */ |
||||
|
#define GINTF_PXNCIF BIT(21) /*!< periodic transfer not complete interrupt flag */ |
||||
|
#define GINTF_ISOONCIF BIT(21) /*!< isochronous OUT transfer not complete interrupt flag */ |
||||
|
#define GINTF_ISOINCIF BIT(20) /*!< isochronous IN transfer not complete interrupt flag */ |
||||
|
#define GINTF_OEPIF BIT(19) /*!< OUT endpoint interrupt flag */ |
||||
|
#define GINTF_IEPIF BIT(18) /*!< IN endpoint interrupt flag */ |
||||
|
#define GINTF_EOPFIF BIT(15) /*!< end of periodic frame interrupt flag */ |
||||
|
#define GINTF_ISOOPDIF BIT(14) /*!< isochronous OUT packet dropped interrupt flag */ |
||||
|
#define GINTF_ENUMFIF BIT(13) /*!< enumeration finished */ |
||||
|
#define GINTF_RST BIT(12) /*!< USB reset */ |
||||
|
#define GINTF_SP BIT(11) /*!< USB suspend */ |
||||
|
#define GINTF_ESP BIT(10) /*!< early suspend */ |
||||
|
#define GINTF_GONAK BIT(7) /*!< global OUT NAK effective */ |
||||
|
#define GINTF_GNPINAK BIT(6) /*!< global IN non-periodic NAK effective */ |
||||
|
#define GINTF_NPTXFEIF BIT(5) /*!< non-periodic tx FIFO empty interrupt flag */ |
||||
|
#define GINTF_RXFNEIF BIT(4) /*!< rx FIFO non-empty interrupt flag */ |
||||
|
#define GINTF_SOF BIT(3) /*!< start of frame */ |
||||
|
#define GINTF_OTGIF BIT(2) /*!< OTG interrupt flag */ |
||||
|
#define GINTF_MFIF BIT(1) /*!< mode fault interrupt flag */ |
||||
|
#define GINTF_COPM BIT(0) /*!< current operation mode */ |
||||
|
|
||||
|
/* global interrupt enable register bits definitions */ |
||||
|
#define GINTEN_WKUPIE BIT(31) /*!< wakeup interrupt enable */ |
||||
|
#define GINTEN_SESIE BIT(30) /*!< session interrupt enable */ |
||||
|
#define GINTEN_DISCIE BIT(29) /*!< disconnect interrupt enable */ |
||||
|
#define GINTEN_IDPSCIE BIT(28) /*!< id pin status change interrupt enable */ |
||||
|
#define GINTEN_LPMIE BIT(27) /*!< LPM interrupt enable */ |
||||
|
#define GINTEN_PTXFEIE BIT(26) /*!< periodic tx FIFO empty interrupt enable */ |
||||
|
#define GINTEN_HCIE BIT(25) /*!< host channels interrupt enable */ |
||||
|
#define GINTEN_HPIE BIT(24) /*!< host port interrupt enable */ |
||||
|
#define GINTEN_IPXIE BIT(21) /*!< periodic transfer not complete interrupt enable */ |
||||
|
#define GINTEN_ISOONCIE BIT(21) /*!< isochronous OUT transfer not complete interrupt enable */ |
||||
|
#define GINTEN_ISOINCIE BIT(20) /*!< isochronous IN transfer not complete interrupt enable */ |
||||
|
#define GINTEN_OEPIE BIT(19) /*!< OUT endpoints interrupt enable */ |
||||
|
#define GINTEN_IEPIE BIT(18) /*!< IN endpoints interrupt enable */ |
||||
|
#define GINTEN_EOPFIE BIT(15) /*!< end of periodic frame interrupt enable */ |
||||
|
#define GINTEN_ISOOPDIE BIT(14) /*!< isochronous OUT packet dropped interrupt enable */ |
||||
|
#define GINTEN_ENUMFIE BIT(13) /*!< enumeration finish enable */ |
||||
|
#define GINTEN_RSTIE BIT(12) /*!< USB reset interrupt enable */ |
||||
|
#define GINTEN_SPIE BIT(11) /*!< USB suspend interrupt enable */ |
||||
|
#define GINTEN_ESPIE BIT(10) /*!< early suspend interrupt enable */ |
||||
|
#define GINTEN_GONAKIE BIT(7) /*!< global OUT NAK effective interrupt enable */ |
||||
|
#define GINTEN_GNPINAKIE BIT(6) /*!< global non-periodic IN NAK effective interrupt enable */ |
||||
|
#define GINTEN_NPTXFEIE BIT(5) /*!< non-periodic Tx FIFO empty interrupt enable */ |
||||
|
#define GINTEN_RXFNEIE BIT(4) /*!< receive FIFO non-empty interrupt enable */ |
||||
|
#define GINTEN_SOFIE BIT(3) /*!< start of frame interrupt enable */ |
||||
|
#define GINTEN_OTGIE BIT(2) /*!< OTG interrupt enable */ |
||||
|
#define GINTEN_MFIE BIT(1) /*!< mode fault interrupt enable */ |
||||
|
|
||||
|
/* global receive status read and pop register bits definitions */ |
||||
|
#define GRSTATRP_RPCKST BITS(17, 20) /*!< received packet status */ |
||||
|
#define GRSTATRP_DPID BITS(15, 16) /*!< data PID */ |
||||
|
#define GRSTATRP_BCOUNT BITS(4, 14) /*!< byte count */ |
||||
|
#define GRSTATRP_CNUM BITS(0, 3) /*!< channel number */ |
||||
|
#define GRSTATRP_EPNUM BITS(0, 3) /*!< endpoint number */ |
||||
|
|
||||
|
/* global receive FIFO length register bits definitions */ |
||||
|
#define GRFLEN_RXFD BITS(0, 15) /*!< rx FIFO depth */ |
||||
|
|
||||
|
/* host non-periodic transmit FIFO length register bits definitions */ |
||||
|
#define HNPTFLEN_HNPTXFD BITS(16, 31) /*!< non-periodic Tx FIFO depth */ |
||||
|
#define HNPTFLEN_HNPTXRSAR BITS(0, 15) /*!< non-periodic Tx RAM start address */ |
||||
|
|
||||
|
/* USB IN endpoint 0 transmit FIFO length register bits definitions */ |
||||
|
#define DIEP0TFLEN_IEP0TXFD BITS(16, 31) /*!< IN Endpoint 0 Tx FIFO depth */ |
||||
|
#define DIEP0TFLEN_IEP0TXRSAR BITS(0, 15) /*!< IN Endpoint 0 TX RAM start address */ |
||||
|
|
||||
|
/* host non-periodic transmit FIFO/queue status register bits definitions */ |
||||
|
#define HNPTFQSTAT_NPTXRQTOP BITS(24, 30) /*!< top entry of the non-periodic Tx request queue */ |
||||
|
#define HNPTFQSTAT_NPTXRQS BITS(16, 23) /*!< non-periodic Tx request queue space */ |
||||
|
#define HNPTFQSTAT_NPTXFS BITS(0, 15) /*!< non-periodic Tx FIFO space */ |
||||
|
#define HNPTFQSTAT_CNUM BITS(27, 30) /*!< channel number*/ |
||||
|
#define HNPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ |
||||
|
#define HNPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ |
||||
|
#define HNPTFQSTAT_TMF BIT(24) /*!< terminate flag */ |
||||
|
|
||||
|
/* global core configuration register bits definitions */ |
||||
|
#define GCCFG_VDEN BIT(21) /*!< enable of VBUS sensing comparator to detect VBUS valid */ |
||||
|
#define GCCFG_SOFOEN BIT(20) /*!< SOF output enable */ |
||||
|
#define GCCFG_PWRON BIT(16) /*!< power on */ |
||||
|
#define GCCFG_SDMEN BIT(15) /*!< secondary detection mode enable */ |
||||
|
#define GCCFG_PEMEN BIT(14) /*!< primary detection mode enable */ |
||||
|
#define GCCFG_DCDEN BIT(13) /*!< data connect detection mode enable */ |
||||
|
#define GCCFG_BCDEN BIT(12) /*!< battery charging detection enable */ |
||||
|
#define GCCFG_PS2F BIT(3) /*!< PS2 detection status */ |
||||
|
#define GCCFG_SDF BIT(2) /*!< secondary detection status */ |
||||
|
#define GCCFG_PDF BIT(1) /*!< primary detection status */ |
||||
|
#define GCCFG_DCDF BIT(0) /*!< battery connect detection status */ |
||||
|
|
||||
|
/* core ID register bits definitions */ |
||||
|
#define CID_CID BITS(0, 31) /*!< core ID */ |
||||
|
|
||||
|
/* global core LPM configuration register bits definitions */ |
||||
|
#define GLPMCFG_BESLEN BIT(28) /*!< LPM Errata selection enable */ |
||||
|
#define GLPMCFG_LPMRCS BITS(25, 27) /*!< LPM retry count status */ |
||||
|
#define GLPMCFG_LPMSND BIT(24) /*!< send LPM transaction */ |
||||
|
#define GLPMCFG_LPMRC BITS(21, 23) /*!< LPM retry count */ |
||||
|
#define GLPMCFG_LPMCHI BITS(17, 20) /*!< channel number index */ |
||||
|
#define GLPMCFG_RSOK BIT(16) /*!< Resume can be sent after sleep state */ |
||||
|
#define GLPMCFG_LPMSLPS BIT(15) /*!< sleep status */ |
||||
|
#define GLPMCFG_LPMRSP BITS(13, 14) /*!< response of LPM */ |
||||
|
#define GLPMCFG_DSEN BIT(12) /*!< deep sleep enable */ |
||||
|
#define GLPMCFG_BESLTH BITS(8, 11) /*!< BESL threshold */ |
||||
|
#define GLPMCFG_SSEN BIT(7) /*!< shallow sleep enable */ |
||||
|
#define GLPMCFG_REW BIT(6) /*!< bRemoteWake value */ |
||||
|
#define GLPMCFG_BESL BITS(2, 5) /*!< best effort service latency */ |
||||
|
#define GLPMCFG_ACKLPM BIT(1) /*!< ACK in LPM transaction enable */ |
||||
|
#define GLPMCFG_LPMEN BIT(0) /*!< LPM enable */ |
||||
|
|
||||
|
/* power down register bits definition */ |
||||
|
#define PWRD_ADPF BIT(23) /*!< ADP event interrupt flag */ |
||||
|
#define PWRD_ADPMEN BIT(0) /*!< ADP module enable */ |
||||
|
|
||||
|
/* ADP control and status register bits definition */ |
||||
|
#define ADPCTL_RWR BITS(27, 28) /*!< read and write request */ |
||||
|
#define ADPCTL_ADPTFM BIT(26) /*!< the mask of ADP timeout interrupt flag */ |
||||
|
#define ADPCTL_ADPSNFM BIT(25) /*!< the mask of ADP sense interrupt flag */ |
||||
|
#define ADPCTL_ADPPRFM BIT(24) /*!< the mask of ADP probe interrupt flag */ |
||||
|
#define ADPCTL_ADPTF BIT(23) /*!< ADP timeout interrupt flag */ |
||||
|
#define ADPCTL_ADPSNF BIT(22) /*!< ADP sense interrupt flag */ |
||||
|
#define ADPCTL_ADPPRF BIT(21) /*!< ADP probe interrupt flag */ |
||||
|
#define ADPCTL_ADPEN BIT(20) /*!< ADP enable */ |
||||
|
#define ADPCTL_ADPRST BIT(19) /*!< ADP reset */ |
||||
|
#define ADPCTL_SNEN BIT(18) /*!< ADP sense enable */ |
||||
|
#define ADPCTL_PREN BIT(17) /*!< ADP probe enable */ |
||||
|
#define ADPCTL_CHGT BITS(6, 16) /*!< the latest time that VBUS ramps from VADPSINK to VADPPRB */ |
||||
|
#define ADPCTL_PERPR BITS(4, 5) /*!< period of probe */ |
||||
|
#define ADPCTL_RESOPR BITS(2, 3) /*!< the resolution of CHGT value */ |
||||
|
#define ADPCTL_DSCHGPR BITS(0, 1) /*!< Time of probe discharge */ |
||||
|
|
||||
|
/* USBHS PHY control register bits definitions */ |
||||
|
#define PHYCTL_HS_CALEN BIT(31) /*!< HS PHY calibration enable */ |
||||
|
#define PHYCTL_HS_CALR BITS(25, 30) /*!< HS PHY calibration value */ |
||||
|
#define PHYCTL_HS_RCALR BITS(21, 24) /*!< HS PHY R calibration value */ |
||||
|
#define PHYCTL_SQUECH BIT(16) /*!< HS PHY squech flag */ |
||||
|
#define PHYCTL_HS_BIST_DONE BIT(15) /*!< HS PHY bist finished flag */ |
||||
|
#define PHYCTL_HS_BIST_SUCCESS BIT(14) /*!< HS PHY bist success flag */ |
||||
|
#define PHYCTL_HS_BIST_FAIL BIT(13) /*!< HS PHY bist fail flag */ |
||||
|
#define PHYCTL_HS_BIST_PKT_SEL BITS(11, 12) /*!< HS PHY bist packet select */ |
||||
|
#define PHYCTL_HS_BIST_SEED BITS(3, 10) /*!< HS PHY bist seed */ |
||||
|
#define PHYCTL_HS_BIST_EN BIT(2) /*!< HS PHY bist enable */ |
||||
|
#define PHYCTL_HS_BIST_RESET BIT(1) /*!< HS PHY bist logic reset */ |
||||
|
#define PHYCTL_HS_BIST_START BIT(0) /*!< HS PHY bist start */ |
||||
|
|
||||
|
/* host periodic transmit FIFO length register bits definitions */ |
||||
|
#define HPTFLEN_HPTXFD BITS(16, 31) /*!< host periodic Tx FIFO depth */ |
||||
|
#define HPTFLEN_HPTXFSAR BITS(0, 15) /*!< host periodic Tx RAM start address */ |
||||
|
|
||||
|
/* device IN endpoint transmit FIFO length register bits definitions */ |
||||
|
#define DIEPTFLEN_IEPTXFD BITS(16, 31) /*!< IN endpoint Tx FIFO x depth */ |
||||
|
#define DIEPTFLEN_IEPTXRSAR BITS(0, 15) /*!< IN endpoint FIFOx Tx x RAM start address */ |
||||
|
|
||||
|
/* host control register bits definitions */ |
||||
|
#define HCTL_SPDFSLS BIT(2) /*!< speed limited to FS and LS */ |
||||
|
|
||||
|
/* host frame interval register bits definitions */ |
||||
|
#define HFT_FRI BITS(0, 15) /*!< frame interval */ |
||||
|
|
||||
|
/* host frame information remaining register bits definitions */ |
||||
|
#define HFINFR_FRT BITS(16, 31) /*!< frame remaining time */ |
||||
|
#define HFINFR_FRNUM BITS(0, 15) /*!< frame number */ |
||||
|
|
||||
|
/* host periodic transmit FIFO/queue status register bits definitions */ |
||||
|
#define HPTFQSTAT_PTXREQT BITS(24, 31) /*!< top entry of the periodic Tx request queue */ |
||||
|
#define HPTFQSTAT_PTXREQS BITS(16, 23) /*!< periodic Tx request queue space */ |
||||
|
#define HPTFQSTAT_PTXFS BITS(0, 15) /*!< periodic Tx FIFO space */ |
||||
|
#define HPTFQSTAT_OEFRM BIT(31) /*!< odd/eveb frame */ |
||||
|
#define HPTFQSTAT_CNUM BITS(27, 30) /*!< channel number */ |
||||
|
#define HPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ |
||||
|
#define HPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ |
||||
|
#define HPTFQSTAT_TMF BIT(24) /*!< terminate flag */ |
||||
|
|
||||
|
#define TFQSTAT_TXFS BITS(0, 15) |
||||
|
#define TFQSTAT_CNUM BITS(27, 30) |
||||
|
|
||||
|
/* host all channels interrupt register bits definitions */ |
||||
|
#define HACHINT_HACHINT BITS(0, 15) /*!< host all channel interrupts */ |
||||
|
|
||||
|
/* host all channels interrupt enable register bits definitions */ |
||||
|
#define HACHINTEN_CINTEN BITS(0, 15) /*!< channel interrupt enable */ |
||||
|
|
||||
|
/* host port control and status register bits definitions */ |
||||
|
#define HPCS_PS BITS(17, 18) /*!< port speed */ |
||||
|
#define HPCS_PTEST BITS(13, 16) /*!< port test control */ |
||||
|
#define HPCS_PP BIT(12) /*!< port power */ |
||||
|
#define HPCS_PLST BITS(10, 11) /*!< port line status */ |
||||
|
#define HPCS_PRST BIT(8) /*!< port reset */ |
||||
|
#define HPCS_PSP BIT(7) /*!< port suspend */ |
||||
|
#define HPCS_PREM BIT(6) /*!< port resume */ |
||||
|
#define HPCS_PEDC BIT(3) /*!< port enable/disable change */ |
||||
|
#define HPCS_PE BIT(2) /*!< port enable */ |
||||
|
#define HPCS_PCD BIT(1) /*!< port connect detected */ |
||||
|
#define HPCS_PCST BIT(0) /*!< port connect status */ |
||||
|
|
||||
|
/* host channel-x control register bits definitions */ |
||||
|
#define HCHCTL_CEN BIT(31) /*!< channel enable */ |
||||
|
#define HCHCTL_CDIS BIT(30) /*!< channel disable */ |
||||
|
#define HCHCTL_ODDFRM BIT(29) /*!< odd frame */ |
||||
|
#define HCHCTL_DAR BITS(22, 28) /*!< device address */ |
||||
|
#define HCHCTL_MPC BITS(20, 21) /*!< multiple packet count */ |
||||
|
#define HCHCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ |
||||
|
#define HCHCTL_LSD BIT(17) /*!< low-speed device */ |
||||
|
#define HCHCTL_EPDIR BIT(15) /*!< endpoint direction */ |
||||
|
#define HCHCTL_EPNUM BITS(11, 14) /*!< endpoint number */ |
||||
|
#define HCHCTL_MPL BITS(0, 10) /*!< maximum packet length */ |
||||
|
|
||||
|
/* host channel-x split transaction register bits definitions */ |
||||
|
#define HCHSTCTL_SPLEN BIT(31) /*!< enable high-speed split transaction */ |
||||
|
#define HCHSTCTL_CSPLT BIT(16) /*!< complete-split enable */ |
||||
|
#define HCHSTCTL_ISOPCE BITS(14, 15) /*!< isochronous OUT payload continuation encoding */ |
||||
|
#define HCHSTCTL_HADDR BITS(7, 13) /*!< HUB address */ |
||||
|
#define HCHSTCTL_PADDR BITS(0, 6) /*!< port address */ |
||||
|
|
||||
|
/* host channel-x interrupt flag register bits definitions */ |
||||
|
#define HCHINTF_DTER BIT(10) /*!< data toggle error */ |
||||
|
#define HCHINTF_REQOVR BIT(9) /*!< request queue overrun */ |
||||
|
#define HCHINTF_BBER BIT(8) /*!< babble error */ |
||||
|
#define HCHINTF_USBER BIT(7) /*!< USB bus Error */ |
||||
|
#define HCHINTF_NYET BIT(6) /*!< NYET */ |
||||
|
#define HCHINTF_ACK BIT(5) /*!< ACK */ |
||||
|
#define HCHINTF_NAK BIT(4) /*!< NAK */ |
||||
|
#define HCHINTF_STALL BIT(3) /*!< STALL */ |
||||
|
#define HCHINTF_DMAER BIT(2) /*!< DMA error */ |
||||
|
#define HCHINTF_CH BIT(1) /*!< channel halted */ |
||||
|
#define HCHINTF_TF BIT(0) /*!< transfer finished */ |
||||
|
|
||||
|
/* host channel-x interrupt enable register bits definitions */ |
||||
|
#define HCHINTEN_DTERIE BIT(10) /*!< data toggle error interrupt enable */ |
||||
|
#define HCHINTEN_REQOVRIE BIT(9) /*!< request queue overrun interrupt enable */ |
||||
|
#define HCHINTEN_BBERIE BIT(8) /*!< babble error interrupt enable */ |
||||
|
#define HCHINTEN_USBERIE BIT(7) /*!< USB bus error interrupt enable */ |
||||
|
#define HCHINTEN_NYETIE BIT(6) /*!< NYET interrupt enable */ |
||||
|
#define HCHINTEN_ACKIE BIT(5) /*!< ACK interrupt enable */ |
||||
|
#define HCHINTEN_NAKIE BIT(4) /*!< NAK interrupt enable */ |
||||
|
#define HCHINTEN_STALLIE BIT(3) /*!< STALL interrupt enable */ |
||||
|
#define HCHINTEN_DMAERIE BIT(2) /*!< DMA error interrupt enable */ |
||||
|
#define HCHINTEN_CHIE BIT(1) /*!< channel halted interrupt enable */ |
||||
|
#define HCHINTEN_TFIE BIT(0) /*!< transfer finished interrupt enable */ |
||||
|
|
||||
|
/* host channel-x transfer length register bits definitions */ |
||||
|
#define HCHLEN_PING BIT(31) /*!< PING token request */ |
||||
|
#define HCHLEN_DPID BITS(29, 30) /*!< data PID */ |
||||
|
#define HCHLEN_PCNT BITS(19, 28) /*!< packet count */ |
||||
|
#define HCHLEN_TLEN BITS(0, 18) /*!< transfer length */ |
||||
|
|
||||
|
/* host channel-x DMA address register bits definitions */ |
||||
|
#define HCHDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ |
||||
|
|
||||
|
#define PORT_SPEED(x) (((uint32_t)(x) << 17U) & HPCS_PS) /*!< Port speed */ |
||||
|
|
||||
|
#define PORT_SPEED_HIGH PORT_SPEED(0U) /*!< high speed */ |
||||
|
#define PORT_SPEED_FULL PORT_SPEED(1U) /*!< full speed */ |
||||
|
#define PORT_SPEED_LOW PORT_SPEED(2U) /*!< low speed */ |
||||
|
|
||||
|
#define PIPE_CTL_DAR(x) (((uint32_t)(x) << 22U) & HCHCTL_DAR) /*!< device address */ |
||||
|
#define PIPE_CTL_EPTYPE(x) (((uint32_t)(x) << 18U) & HCHCTL_EPTYPE) /*!< endpoint type */ |
||||
|
#define PIPE_CTL_EPNUM(x) (((uint32_t)(x) << 11U) & HCHCTL_EPNUM) /*!< endpoint number */ |
||||
|
#define PIPE_CTL_EPDIR(x) (((uint32_t)(x) << 15U) & HCHCTL_EPDIR) /*!< endpoint direction */ |
||||
|
#define PIPE_CTL_EPMPL(x) (((uint32_t)(x) << 0U) & HCHCTL_MPL) /*!< maximum packet length */ |
||||
|
#define PIPE_CTL_LSD(x) (((uint32_t)(x) << 17U) & HCHCTL_LSD) /*!< low-Speed device */ |
||||
|
|
||||
|
#define PIPE_XFER_PCNT(x) (((uint32_t)(x) << 19U) & HCHLEN_PCNT) /*!< packet count */ |
||||
|
#define PIPE_XFER_DPID(x) (((uint32_t)(x) << 29U) & HCHLEN_DPID) /*!< data PID */ |
||||
|
|
||||
|
#define PIPE_DPID_DATA0 PIPE_XFER_DPID(0) /*!< DATA0 */ |
||||
|
#define PIPE_DPID_DATA1 PIPE_XFER_DPID(2) /*!< DATA1 */ |
||||
|
#define PIPE_DPID_DATA2 PIPE_XFER_DPID(1) /*!< DATA2 */ |
||||
|
#define PIPE_DPID_SETUP PIPE_XFER_DPID(3) /*!< MDATA (non-control)/SETUP (control) */ |
||||
|
|
||||
|
extern const uint32_t PIPE_DPID[2]; |
||||
|
|
||||
|
/* device configuration registers bits definitions */ |
||||
|
#define DCFG_EOPFT BITS(11, 12) /*!< end of periodic frame time */ |
||||
|
#define DCFG_DAR BITS(4, 10) /*!< device address */ |
||||
|
#define DCFG_NZLSOH BIT(2) /*!< non-zero-length status OUT handshake */ |
||||
|
#define DCFG_DS BITS(0, 1) /*!< device speed */ |
||||
|
|
||||
|
/* device control registers bits definitions */ |
||||
|
#define DCTL_L1RJCT BIT(18) /*!< deep sleep reject */ |
||||
|
#define DCTL_POIF BIT(11) /*!< power-on initialization finished */ |
||||
|
#define DCTL_CGONAK BIT(10) /*!< clear global OUT NAK */ |
||||
|
#define DCTL_SGONAK BIT(9) /*!< set global OUT NAK */ |
||||
|
#define DCTL_CGINAK BIT(8) /*!< clear global IN NAK */ |
||||
|
#define DCTL_SGINAK BIT(7) /*!< set global IN NAK */ |
||||
|
#define DCTL_DTEST BITS(4, 6) /*!< device test control */ |
||||
|
#define DCTL_GONS BIT(3) /*!< global OUT NAK status */ |
||||
|
#define DCTL_GINS BIT(2) /*!< global IN NAK status */ |
||||
|
#define DCTL_SD BIT(1) /*!< soft disconnect */ |
||||
|
#define DCTL_RWKUP BIT(0) /*!< remote wakeup */ |
||||
|
|
||||
|
/* device status registers bits definitions */ |
||||
|
#define DSTAT_FNRSOF BITS(8, 21) /*!< the frame number of the received SOF. */ |
||||
|
#define DSTAT_ES BITS(1, 2) /*!< enumerated speed */ |
||||
|
#define DSTAT_SPST BIT(0) /*!< suspend status */ |
||||
|
|
||||
|
/* device IN endpoint common interrupt enable registers bits definitions */ |
||||
|
#define DIEPINTEN_NAKEN BIT(13) /*!< NAK handshake sent by USBHS interrupt enable bit */ |
||||
|
#define DIEPINTEN_TXFEEN BIT(7) /*!< transmit FIFO empty interrupt enable bit */ |
||||
|
#define DIEPINTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */ |
||||
|
#define DIEPINTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */ |
||||
|
#define DIEPINTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */ |
||||
|
#define DIEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ |
||||
|
#define DIEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ |
||||
|
|
||||
|
/* device OUT endpoint common interrupt enable registers bits definitions */ |
||||
|
#define DOEPINTEN_NYETEN BIT(14) /*!< NYET handshake is sent interrupt enable bit */ |
||||
|
#define DOEPINTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */ |
||||
|
#define DOEPINTEN_EPRXFOVREN BIT(4) /*!< endpoint Rx FIFO overrun interrupt enable bit */ |
||||
|
#define DOEPINTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */ |
||||
|
#define DOEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ |
||||
|
#define DOEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ |
||||
|
|
||||
|
/* device all endpoints interrupt registers bits definitions */ |
||||
|
#define DAEPINT_OEPITB BITS(16, 23) /*!< device all OUT endpoint interrupt bits */ |
||||
|
#define DAEPINT_IEPITB BITS(0, 7) /*!< device all IN endpoint interrupt bits */ |
||||
|
|
||||
|
/* device all endpoints interrupt enable registers bits definitions */ |
||||
|
#define DAEPINTEN_OEPIE BITS(16, 23) /*!< OUT endpoint interrupt enable */ |
||||
|
#define DAEPINTEN_IEPIE BITS(0, 7) /*!< IN endpoint interrupt enable */ |
||||
|
|
||||
|
/* device VBUS discharge time registers bits definitions */ |
||||
|
#define DVBUSDT_DVBUSDT BITS(0, 15) /*!< device VBUS discharge time */ |
||||
|
|
||||
|
/* device VBUS pulsing time registers bits definitions */ |
||||
|
#define DVBUSPT_DVBUSPT BITS(0, 11) /*!< device VBUS pulsing time */ |
||||
|
|
||||
|
/* device IN endpoint FIFO empty interrupt enable register bits definitions */ |
||||
|
#define DIEPFEINTEN_IEPTXFEIE BITS(0, 5) /*!< IN endpoint Tx FIFO empty interrupt enable bits */ |
||||
|
|
||||
|
/* device endpoint 0 control register bits definitions */ |
||||
|
#define DEP0CTL_EPEN BIT(31) /*!< endpoint enable */ |
||||
|
#define DEP0CTL_EPD BIT(30) /*!< endpoint disable */ |
||||
|
#define DEP0CTL_SNAK BIT(27) /*!< set NAK */ |
||||
|
#define DEP0CTL_CNAK BIT(26) /*!< clear NAK */ |
||||
|
#define DIEP0CTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ |
||||
|
#define DEP0CTL_STALL BIT(21) /*!< STALL handshake */ |
||||
|
#define DOEP0CTL_SNOOP BIT(20) /*!< snoop mode */ |
||||
|
#define DEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */ |
||||
|
#define DEP0CTL_NAKS BIT(17) /*!< NAK status */ |
||||
|
#define DEP0CTL_EPACT BIT(15) /*!< endpoint active */ |
||||
|
#define DEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */ |
||||
|
|
||||
|
/* device endpoint x control register bits definitions */ |
||||
|
#define DEPCTL_EPEN BIT(31) /*!< endpoint enable */ |
||||
|
#define DEPCTL_EPD BIT(30) /*!< endpoint disable */ |
||||
|
#define DEPCTL_SODDFRM BIT(29) /*!< set odd frame */ |
||||
|
#define DEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */ |
||||
|
#define DEPCTL_SEVNFRM BIT(28) /*!< set even frame */ |
||||
|
#define DEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */ |
||||
|
#define DEPCTL_SNAK BIT(27) /*!< set NAK */ |
||||
|
#define DEPCTL_CNAK BIT(26) /*!< clear NAK */ |
||||
|
#define DIEPCTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ |
||||
|
#define DEPCTL_STALL BIT(21) /*!< STALL handshake */ |
||||
|
#define DOEPCTL_SNOOP BIT(20) /*!< snoop mode */ |
||||
|
#define DEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ |
||||
|
#define DEPCTL_NAKS BIT(17) /*!< NAK status */ |
||||
|
#define DEPCTL_EOFRM BIT(16) /*!< even/odd frame */ |
||||
|
#define DEPCTL_DPID BIT(16) /*!< endpoint data PID */ |
||||
|
#define DEPCTL_EPACT BIT(15) /*!< endpoint active */ |
||||
|
#define DEPCTL_MPL BITS(0, 10) /*!< maximum packet length */ |
||||
|
|
||||
|
/* device IN endpoint-x interrupt flag register bits definitions */ |
||||
|
#define DIEPINTF_NAK BIT(13) /*!< NAK handshake sent by USBHS */ |
||||
|
#define DIEPINTF_TXFE BIT(7) /*!< transmit FIFO empty */ |
||||
|
#define DIEPINTF_IEPNE BIT(6) /*!< IN endpoint NAK effective */ |
||||
|
#define DIEPINTF_EPTXFUD BIT(4) /*!< endpoint Tx FIFO underrun */ |
||||
|
#define DIEPINTF_CITO BIT(3) /*!< control In Timeout interrupt */ |
||||
|
#define DIEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ |
||||
|
#define DIEPINTF_TF BIT(0) /*!< transfer finished */ |
||||
|
|
||||
|
/* device OUT endpoint-x interrupt flag register bits definitions */ |
||||
|
#define DOEPINTF_NYET BIT(14) /*!< NYET handshake is sent */ |
||||
|
#define DOEPINTF_BTBSTP BIT(6) /*!< back-to-back SETUP packets */ |
||||
|
#define DOEPINTF_EPRXFOVR BIT(4) /*!< endpoint Rx FIFO overrun */ |
||||
|
#define DOEPINTF_STPF BIT(3) /*!< SETUP phase finished */ |
||||
|
#define DOEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ |
||||
|
#define DOEPINTF_TF BIT(0) /*!< transfer finished */ |
||||
|
|
||||
|
/* device IN endpoint 0 transfer length register bits definitions */ |
||||
|
#define DIEP0LEN_PCNT BITS(19, 20) /*!< packet count */ |
||||
|
#define DIEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ |
||||
|
|
||||
|
/* device OUT endpoint 0 transfer length register bits definitions */ |
||||
|
#define DOEP0LEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ |
||||
|
#define DOEP0LEN_PCNT BIT(19) /*!< packet count */ |
||||
|
#define DOEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ |
||||
|
|
||||
|
/* device OUT endpoint-x transfer length register bits definitions */ |
||||
|
#define DOEPLEN_RXDPID BITS(29, 30) /*!< received data PID */ |
||||
|
#define DOEPLEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ |
||||
|
#define DIEPLEN_MCNT BITS(29, 30) /*!< multi count */ |
||||
|
#define DEPLEN_PCNT BITS(19, 28) /*!< packet count */ |
||||
|
#define DEPLEN_TLEN BITS(0, 18) /*!< transfer length */ |
||||
|
|
||||
|
/* device IN endpoint-x DMA address register bits definitions */ |
||||
|
#define DIEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ |
||||
|
|
||||
|
/* device OUT endpoint-x DMA address register bits definitions */ |
||||
|
#define DOEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ |
||||
|
|
||||
|
/* device IN endpoint-x transmit FIFO status register bits definitions */ |
||||
|
#define DIEPTFSTAT_IEPTFS BITS(0, 15) /*!< IN endpoint Tx FIFO space remaining */ |
||||
|
|
||||
|
/* USB power and clock registers bits definition */ |
||||
|
#define PWRCLKCTL_DSLEEP BIT(7) /*!< PHY is in deep sleep status */ |
||||
|
#define PWRCLKCTL_SSLEEP BIT(6) /*!< PHY is in shallow sleep status */ |
||||
|
#define PWRCLKCTL_SCGEN BIT(5) /*!< When this bit is set, the internal clock gating is enabled */ |
||||
|
#define PWRCLKCTL_SUSP BIT(4) /*!< PHY is in suspend status */ |
||||
|
#define PWRCLKCTL_SHCLK BIT(1) /*!< stop HCLK */ |
||||
|
#define PWRCLKCTL_SUCLK BIT(0) /*!< stop the USB clock */ |
||||
|
|
||||
|
#define RSTAT_GOUT_NAK 1U /*!< global OUT NAK (triggers an interrupt) */ |
||||
|
#define RSTAT_DATA_UPDT 2U /*!< OUT data packet received */ |
||||
|
#define RSTAT_XFER_COMP 3U /*!< OUT transfer completed (triggers an interrupt) */ |
||||
|
#define RSTAT_SETUP_COMP 4U /*!< SETUP transaction completed (triggers an interrupt) */ |
||||
|
#define RSTAT_SETUP_UPDT 6U /*!< SETUP data packet received */ |
||||
|
|
||||
|
#define DSTAT_EM_HS_PHY_30MHZ_60MHZ 0U /*!< USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */ |
||||
|
#define DSTAT_EM_FS_PHY_30MHZ_60MHZ 1U /*!< USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */ |
||||
|
#define DSTAT_EM_LS_PHY_6MHZ 2U /*!< USB enumerate speed use low-speed PHY clock in 6MHz */ |
||||
|
#define DSTAT_EM_FS_PHY_48MHZ 3U /*!< USB enumerate speed use full-speed PHY clock in 48MHz */ |
||||
|
|
||||
|
#define DPID_DATA0 0U /*!< device endpoint data PID is DATA0 */ |
||||
|
#define DPID_DATA1 2U /*!< device endpoint data PID is DATA1 */ |
||||
|
#define DPID_DATA2 1U /*!< device endpoint data PID is DATA2 */ |
||||
|
#define DPID_MDATA 3U /*!< device endpoint data PID is MDATA */ |
||||
|
|
||||
|
#define GAHBCS_DMAINCR(regval) (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA */ |
||||
|
|
||||
|
#define DMA_INCR0 GAHBCS_DMAINCR(0U) /*!< single burst type used by DMA*/ |
||||
|
#define DMA_INCR1 GAHBCS_DMAINCR(1U) /*!< 4-beat incrementing burst type used by DMA */ |
||||
|
#define DMA_INCR4 GAHBCS_DMAINCR(3U) /*!< 8-beat incrementing burst type used by DMA */ |
||||
|
#define DMA_INCR8 GAHBCS_DMAINCR(5U) /*!< 16-beat incrementing burst type used by DMA */ |
||||
|
#define DMA_INCR16 GAHBCS_DMAINCR(7U) /*!< 32-beat incrementing burst type used by DMA */ |
||||
|
|
||||
|
#define DCFG_PFRI(regval) (DCFG_EOPFT & ((regval) << 11U)) /*!< end of periodic frame time configuration */ |
||||
|
|
||||
|
#define FRAME_INTERVAL_80 DCFG_PFRI(0U) /*!< 80% of the frame time */ |
||||
|
#define FRAME_INTERVAL_85 DCFG_PFRI(1U) /*!< 85% of the frame time */ |
||||
|
#define FRAME_INTERVAL_90 DCFG_PFRI(2U) /*!< 90% of the frame time */ |
||||
|
#define FRAME_INTERVAL_95 DCFG_PFRI(3U) /*!< 95% of the frame time */ |
||||
|
|
||||
|
#define DCFG_DEVSPEED(regval) (DCFG_DS & ((regval) << 0U)) /*!< device speed configuration */ |
||||
|
|
||||
|
#define USB_SPEED_INP_HIGH DCFG_DEVSPEED(0U) /*!< device internal PHY high speed */ |
||||
|
#define USB_SPEED_INP_FULL DCFG_DEVSPEED(1U) /*!< device internal PHY full speed */ |
||||
|
|
||||
|
#define DEP0_MPL(regval) (DEP0CTL_MPL & ((regval) << 0U)) /*!< maximum packet length configuration */ |
||||
|
|
||||
|
#define EP0MPL_64 DEP0_MPL(0U) /*!< maximum packet length 64 bytes */ |
||||
|
#define EP0MPL_32 DEP0_MPL(1U) /*!< maximum packet length 32 bytes */ |
||||
|
#define EP0MPL_16 DEP0_MPL(2U) /*!< maximum packet length 16 bytes */ |
||||
|
#define EP0MPL_8 DEP0_MPL(3U) /*!< maximum packet length 8 bytes */ |
||||
|
|
||||
|
#define DOEP0_TLEN(regval) (DOEP0LEN_TLEN & ((regval) << 0U)) /*!< Transfer length */ |
||||
|
#define DOEP0_PCNT(regval) (DOEP0LEN_PCNT & ((regval) << 19U)) /*!< Packet count */ |
||||
|
#define DOEP0_STPCNT(regval) (DOEP0LEN_STPCNT & ((regval) << 29U)) /*!< SETUP packet count */ |
||||
|
|
||||
|
#define GRXSTS_PKTSTS_IN 2U |
||||
|
#define GRXSTS_PKTSTS_IN_XFER_COMP 3U |
||||
|
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U |
||||
|
#define GRXSTS_PKTSTS_CH_HALTED 7U |
||||
|
|
||||
|
#define DEVICE_MODE 0U /*!< device mode */ |
||||
|
#define HOST_MODE 1U /*!< host mode */ |
||||
|
#define OTG_MODE 2U /*!< OTG mode */ |
||||
|
|
||||
|
#define HCTL_30_60MHZ 0U /*!< USB clock 30-60MHZ */ |
||||
|
#define HCTL_48MHZ 1U /*!< USB clock 48MHZ */ |
||||
|
#define HCTL_6MHZ 2U /*!< USB clock 6MHZ */ |
||||
|
|
||||
|
#define USBHS_MAX_PACKET_SIZE 512U /*!< USBHS max packet size */ |
||||
|
#define USBHS_MAX_CHANNEL_COUNT 16U /*!< USBHS host channel count */ |
||||
|
#define USBHS_MAX_EP_COUNT 8U /*!< USBHS device endpoint count */ |
||||
|
#define USBHS_MAX_FIFO_WORDLEN 1280U /*!< USBHS max fifo size in words */ |
||||
|
|
||||
|
#define USB_DATA_FIFO_OFFSET 0x1000U /*!< USB data fifo offset */ |
||||
|
#define USB_DATA_FIFO_SIZE 0x1000U /*!< USB data fifo size */ |
||||
|
|
||||
|
typedef enum |
||||
|
{ |
||||
|
USB_EMBEDDED_PHY_FS = 0U, /*!< USB embedded FS PHY */ |
||||
|
USB_EMBEDDED_PHY_HS, /*!< USB embedded HS PHY */ |
||||
|
USB_ULPI_PHY_EXTERNAL /*!< USB external ULPI PHY */ |
||||
|
} usb_phy_enum; |
||||
|
|
||||
|
enum usb_reg_offset |
||||
|
{ |
||||
|
USB_REG_OFFSET_CORE = 0x0000U, /*!< global OTG control and status register */ |
||||
|
USB_REG_OFFSET_DEV = 0x0800U, /*!< device mode control and status registers */ |
||||
|
USB_REG_OFFSET_EP = 0x0020U, /*!< offset of each endpoint */ |
||||
|
USB_REG_OFFSET_EP_IN = 0x0900U, /*!< device IN endpoint 0 control register */ |
||||
|
USB_REG_OFFSET_EP_OUT = 0x0B00U, /*!< device OUT endpoint 0 control register */ |
||||
|
USB_REG_OFFSET_HOST = 0x0400U, /*!< host control register */ |
||||
|
USB_REG_OFFSET_CH = 0x0020U, /*!< offset of each channel */ |
||||
|
USB_REG_OFFSET_PORT = 0x0440U, /*!< host port control and status register */ |
||||
|
USB_REG_OFFSET_CH_INOUT = 0x0500U, /*!< host channel-x control registers */ |
||||
|
USB_REG_OFFSET_PWRCLKCTL = 0x0E00U /*!< power and clock register */ |
||||
|
}; |
||||
|
|
||||
|
enum USB_SPEED |
||||
|
{ |
||||
|
USB_SPEED_UNKNOWN = 0, /*!< USB speed unknown */ |
||||
|
USB_SPEED_LOW, /*!< USB speed low */ |
||||
|
USB_SPEED_FULL, /*!< USB speed full */ |
||||
|
USB_SPEED_HIGH /*!< USB speed high */ |
||||
|
}; |
||||
|
|
||||
|
#define EP0_OUT ((uint8_t)0x00U) /*!< endpoint out 0 */ |
||||
|
#define EP0_IN ((uint8_t)0x80U) /*!< endpoint in 0 */ |
||||
|
#define EP1_OUT ((uint8_t)0x01U) /*!< endpoint out 1 */ |
||||
|
#define EP1_IN ((uint8_t)0x81U) /*!< endpoint in 1 */ |
||||
|
#define EP2_OUT ((uint8_t)0x02U) /*!< endpoint out 2 */ |
||||
|
#define EP2_IN ((uint8_t)0x82U) /*!< endpoint in 2 */ |
||||
|
#define EP3_OUT ((uint8_t)0x03U) /*!< endpoint out 3 */ |
||||
|
#define EP3_IN ((uint8_t)0x83U) /*!< endpoint in 3 */ |
||||
|
#define EP4_OUT ((uint8_t)0x04U) /*!< endpoint out 4 */ |
||||
|
#define EP4_IN ((uint8_t)0x84U) /*!< endpoint in 4 */ |
||||
|
#define EP5_OUT ((uint8_t)0x05U) /*!< endpoint out 5 */ |
||||
|
#define EP5_IN ((uint8_t)0x85U) /*!< endpoint in 5 */ |
||||
|
#define EP6_OUT ((uint8_t)0x06U) /*!< endpoint out 6 */ |
||||
|
#define EP6_IN ((uint8_t)0x86U) /*!< endpoint in 6 */ |
||||
|
#define EP7_OUT ((uint8_t)0x06U) /*!< endpoint out 7 */ |
||||
|
#define EP7_IN ((uint8_t)0x86U) /*!< endpoint in 7 */ |
||||
|
|
||||
|
#endif /* DRV_USB_REGS_H */ |
||||
@ -0,0 +1,28 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USBD_INT_H |
||||
|
#define DRV_USBD_INT_H |
||||
|
|
||||
|
#include "drv_usb_core.h" |
||||
|
#include "drv_usb_dev.h" |
||||
|
|
||||
|
/* function declarations */ |
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
/* USB dedicated OUT endpoint 1 interrupt service routine handler */ |
||||
|
uint32_t usbd_int_dedicated_ep1out(usb_core_driver *udev); |
||||
|
/* USB dedicated IN endpoint 1 interrupt service routine handler */ |
||||
|
uint32_t usbd_int_dedicated_ep1in(usb_core_driver *udev); |
||||
|
#endif /* USB_DEDICATED_EP1_ENABLED */ |
||||
|
|
||||
|
/* USB device-mode interrupts global service routine handler */ |
||||
|
void usbd_isr(usb_core_driver *udev); |
||||
|
|
||||
|
#endif /* DRV_USBD_INT_H */ |
||||
@ -0,0 +1,19 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DRV_USBH_INT_H |
||||
|
#define DRV_USBH_INT_H |
||||
|
|
||||
|
#include "drv_usb_host.h" |
||||
|
|
||||
|
/* handle global host interrupt */ |
||||
|
uint32_t usbh_isr(usb_core_driver *udev); |
||||
|
|
||||
|
#endif /* DRV_USBH_INT_H */ |
||||
@ -0,0 +1,48 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_USBH_PIPE_H |
||||
|
#define __DRV_USBH_PIPE_H |
||||
|
|
||||
|
#include "drv_usb_host.h" |
||||
|
|
||||
|
#define HC_MAX 8U |
||||
|
|
||||
|
#define HC_OK 0x0000U |
||||
|
#define HC_USED 0x8000U |
||||
|
#define HC_ERROR 0xFFFFU |
||||
|
#define HC_USED_MASK 0x7FFFU |
||||
|
|
||||
|
/* allocate a new pipe */ |
||||
|
uint8_t usbh_pipe_allocate(usb_core_driver *pudev, uint8_t ep_addr); |
||||
|
|
||||
|
/* delete all USB host pipe */ |
||||
|
uint8_t usbh_pipe_delete(usb_core_driver *pudev); |
||||
|
|
||||
|
/* free a pipe */ |
||||
|
uint8_t usbh_pipe_free(usb_core_driver *pudev, uint8_t pp_num); |
||||
|
|
||||
|
/* create a pipe */ |
||||
|
uint8_t usbh_pipe_create(usb_core_driver *pudev, |
||||
|
uint8_t dev_addr, |
||||
|
uint8_t dev_speed, |
||||
|
uint8_t pp_num, |
||||
|
uint8_t ep_num, |
||||
|
uint8_t ep_type, |
||||
|
uint16_t ep_mpl); |
||||
|
|
||||
|
/* modify a pipe */ |
||||
|
uint8_t usbh_pipe_update(usb_core_driver *pudev, |
||||
|
uint8_t pp_num, |
||||
|
uint8_t dev_addr, |
||||
|
uint32_t dev_speed, |
||||
|
uint16_t ep_mpl); |
||||
|
|
||||
|
#endif /* __DRV_USBH_PIPE_H */ |
||||
@ -0,0 +1,41 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __DRV_USBH_TRANSC_H |
||||
|
#define __DRV_USBH_TRANSC_H |
||||
|
|
||||
|
#include "drv_usb_host.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
/* send the setup packet to the USB device */ |
||||
|
usbh_status usbh_ctlsetup_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num); |
||||
|
|
||||
|
/* send a data packet to the USB device */ |
||||
|
usbh_status usbh_data_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len); |
||||
|
|
||||
|
/* receive a data packet from the USB device */ |
||||
|
usbh_status usbh_data_recev(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len); |
||||
|
|
||||
|
/* get USB URB state */ |
||||
|
static inline usb_urb_state usbh_urbstate_get(usb_core_driver *pudev, uint8_t pp_num) |
||||
|
{ |
||||
|
return pudev->host.pipe[pp_num].urb_state; |
||||
|
} |
||||
|
|
||||
|
/* get USB transfer data count */ |
||||
|
static inline uint32_t usbh_xfercount_get(usb_core_driver *pudev, uint8_t pp_num) |
||||
|
{ |
||||
|
return pudev->host.backup_xfercount[pp_num]; |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
|
#endif /* __DRV_USBH_TRANSC_H */ |
||||
|
|
||||
@ -0,0 +1,139 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#ifndef USB_CONF_H |
||||
|
#define USB_CONF_H |
||||
|
|
||||
|
#include <board.h> |
||||
|
|
||||
|
#if defined(BSP_USING_USB) |
||||
|
|
||||
|
#if defined(SOC_SERIES_GD32H75E) |
||||
|
#include "gd32h75e.h" |
||||
|
#elif defined(SOC_SERIES_GD32H7xx) |
||||
|
#include "gd32h7xx.h" |
||||
|
#endif |
||||
|
/* USB Core and PHY interface configuration */ |
||||
|
|
||||
|
/* USB HS PHY CONFIGURATION */ |
||||
|
|
||||
|
/* on-chip full-speed USB PHY */ |
||||
|
#ifdef USE_USB_FS |
||||
|
#define OC_FS_PHY |
||||
|
#endif |
||||
|
|
||||
|
/* on-chip high-speed USB PHY */ |
||||
|
#ifdef USE_USB_HS |
||||
|
#define OC_HS_PHY |
||||
|
#endif /* USE_USB_HS */ |
||||
|
|
||||
|
#if defined(RT_USING_USB_DEVICE) |
||||
|
|
||||
|
#define USB_SOF_OUTPUT 0U |
||||
|
|
||||
|
/* USB FIFO size config */ |
||||
|
#define RX_FIFO_SIZE 512U |
||||
|
#define TX0_FIFO_SIZE 128U |
||||
|
#define TX1_FIFO_SIZE 384U |
||||
|
#define TX2_FIFO_SIZE 0U |
||||
|
#define TX3_FIFO_SIZE 0U |
||||
|
#define TX4_FIFO_SIZE 0U |
||||
|
#define TX5_FIFO_SIZE 0U |
||||
|
#define TX6_FIFO_SIZE 0U |
||||
|
#define TX7_FIFO_SIZE 0U |
||||
|
|
||||
|
#elif defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
#define USBH_USE_RTOS |
||||
|
#define USB_SOF_OUTPUT 1U |
||||
|
|
||||
|
/* USB FIFO size config */ |
||||
|
#define USB_RX_FIFO_SIZE 512 |
||||
|
#define USB_HTX_NPFIFO_SIZE 256 |
||||
|
#define USB_HTX_PFIFO_SIZE 256 |
||||
|
#endif |
||||
|
|
||||
|
/* General USB Configuration */ |
||||
|
#define USB_LOW_POWER 0U |
||||
|
|
||||
|
/* if uncomment it, need jump to USB JP */ |
||||
|
//#define VBUS_SENSING_ENABLED
|
||||
|
|
||||
|
//#define USB_INTERNAL_DMA_ENABLED
|
||||
|
//#define USB_DEDICATED_EP1_ENABLED
|
||||
|
/* End General USB Configuration */ |
||||
|
|
||||
|
#ifdef USE_ULPI_PHY |
||||
|
#define USB_EXTERNAL_ULPI_PHY_ENABLED |
||||
|
#else |
||||
|
#ifdef OC_FS_PHY |
||||
|
#define USB_EMBEDDED_FS_PHY_ENABLED |
||||
|
#elif defined(OC_HS_PHY) |
||||
|
#define USB_EMBEDDED_HS_PHY_ENABLED |
||||
|
#else |
||||
|
#error "PHY is not selected" |
||||
|
#endif /* OC_FS_PHY */ |
||||
|
#endif /* USE_ULPI_PHY */ |
||||
|
|
||||
|
#if defined(RT_USING_USB_HOST) |
||||
|
#define USE_HOST_MODE |
||||
|
#elif defined(RT_USING_USB_DEVICE) |
||||
|
#define USE_DEVICE_MODE |
||||
|
#else |
||||
|
#warning "Please select the USB mode as USBD or USBH; otherwise, the USE_OTG_MODE will be enabled by default." |
||||
|
#define USE_OTG_MODE |
||||
|
#endif |
||||
|
|
||||
|
#ifndef OC_FS_PHY |
||||
|
#ifndef OC_HS_PHY |
||||
|
#error "OC_FS_PHY or OC_HS_PHY should be defined!" |
||||
|
#endif |
||||
|
#endif /* OC_FS_PHY */ |
||||
|
|
||||
|
#ifndef RT_USING_USB_DEVICE |
||||
|
#ifndef RT_USING_USB_HOST |
||||
|
#error "RT_USING_USB_DEVICE or RT_USING_USB_HOST should be defined!" |
||||
|
#endif |
||||
|
#endif /* USE_DEVICE_MODE */ |
||||
|
|
||||
|
#ifndef USE_USB_HS |
||||
|
#ifndef USE_USB_FS |
||||
|
#error "USE_USB_HS or USE_USB_FS should be defined!" |
||||
|
#endif |
||||
|
#endif /* USE_USB_HS */ |
||||
|
|
||||
|
/* all variables and data structures during the transaction process should be 4-bytes aligned */ |
||||
|
#if defined(__GNUC__) /* GNU Compiler */ |
||||
|
#define __ALIGN_END __attribute__((aligned(4))) |
||||
|
#define __ALIGN_BEGIN |
||||
|
#else |
||||
|
#define __ALIGN_END |
||||
|
|
||||
|
#if defined(__CC_ARM) /* ARM Compiler */ |
||||
|
#define __ALIGN_BEGIN __align(4) |
||||
|
#elif defined(__ICCARM__) /* IAR Compiler */ |
||||
|
#define __ALIGN_BEGIN |
||||
|
#elif defined(__TASKING__)/* TASKING Compiler */ |
||||
|
#define __ALIGN_BEGIN __align(4) |
||||
|
#endif /* __CC_ARM */ |
||||
|
#endif /* __GNUC__ */ |
||||
|
|
||||
|
/* __packed keyword used to decrease the data type alignment to 1-byte */ |
||||
|
#if defined(__GNUC__) /* GNU Compiler */ |
||||
|
#ifndef __packed |
||||
|
#define __packed __unaligned |
||||
|
#endif |
||||
|
#elif defined(__TASKING__) /* TASKING Compiler */ |
||||
|
#define __packed __unaligned |
||||
|
#endif /* __GNUC__ */ |
||||
|
|
||||
|
#endif /* BSP_USING_USB */ |
||||
|
|
||||
|
#endif /* USB_CONF_H */ |
||||
@ -0,0 +1,285 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include <rtthread.h> |
||||
|
|
||||
|
#if defined(RT_USING_SAL) && defined(RT_USING_NETDEV) && defined(RT_USING_LWIP) |
||||
|
|
||||
|
#include "synopsys_emac.h" |
||||
|
#include "gd32h7xx_enet.h" |
||||
|
|
||||
|
/* The state of enet initialization */ |
||||
|
volatile uint32_t enet_init_state = 0; |
||||
|
|
||||
|
/* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */ |
||||
|
extern EMAC_DMADESCTypeDef *DMATxDescToSet; |
||||
|
extern EMAC_DMADESCTypeDef *DMARxDescToGet; |
||||
|
|
||||
|
/**
|
||||
|
* Initializes the ETHERNET peripheral according to the specified |
||||
|
*/ |
||||
|
rt_uint32_t EMAC_init(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t SystemCoreClock) |
||||
|
{ |
||||
|
/*-------------------------------- Reset ethernet -------------------------------*/ |
||||
|
enet_deinit(ENET0); |
||||
|
enet_software_reset(ENET0); |
||||
|
|
||||
|
/* configure the parameters which are usually less cared for enet initialization */ |
||||
|
enet_initpara_config(HALFDUPLEX_OPTION, ENET_CARRIERSENSE_DISABLE | ENET_RECEIVEOWN_ENABLE | ENET_RETRYTRANSMISSION_DISABLE | ENET_BACKOFFLIMIT_10 | ENET_DEFERRALCHECK_DISABLE); |
||||
|
|
||||
|
/*-------------------------------- Initialize ENET ------------------------------*/ |
||||
|
#ifdef RT_LWIP_USING_HW_CHECKSUM |
||||
|
enet_init_state = enet_init(ENET0, ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS); |
||||
|
#else |
||||
|
enet_init_state = enet_init(ENET0, ENET_AUTO_NEGOTIATION, ENET_NO_AUTOCHECKSUM, ENET_BROADCAST_FRAMES_PASS); |
||||
|
#endif |
||||
|
if (SUCCESS != enet_init_state) |
||||
|
{ |
||||
|
rt_kprintf("enet init failed. \r\n"); |
||||
|
return EMAC_ERROR; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Return Ethernet configuration success */ |
||||
|
return EMAC_SUCCESS; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables or disables the specified ETHERNET DMA interrupts. |
||||
|
*/ |
||||
|
void EMAC_INT_config(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState) |
||||
|
{ |
||||
|
if (NewState) |
||||
|
{ |
||||
|
/* Enable the selected ETHERNET DMA interrupts */ |
||||
|
ETHERNET_MAC->IER |= EMAC_DMA_IT; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable the selected ETHERNET DMA interrupts */ |
||||
|
ETHERNET_MAC->IER &= (~(rt_uint32_t)EMAC_DMA_IT); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Configures the selected MAC address. |
||||
|
*/ |
||||
|
void EMAC_MAC_Addr_config(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr) |
||||
|
{ |
||||
|
rt_uint32_t value; |
||||
|
|
||||
|
/* Calculate the selectecd MAC address high register */ |
||||
|
value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4]; |
||||
|
/* Load the selectecd MAC address high register */ |
||||
|
//(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value;
|
||||
|
ETHERNET_MAC->MARs[MacAddr].MARH = value; |
||||
|
/* Calculate the selectecd MAC address low register */ |
||||
|
value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0]; |
||||
|
|
||||
|
/* Load the selectecd MAC address low register */ |
||||
|
//(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value;
|
||||
|
ETHERNET_MAC->MARs[MacAddr].MARL = value; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables or disables the MAC transmission. |
||||
|
*/ |
||||
|
void EMAC_MACTransmissionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState) |
||||
|
{ |
||||
|
if (NewState) |
||||
|
{ |
||||
|
/* Enable the MAC transmission */ |
||||
|
ETHERNET_MAC->MCR |= EMAC_MACCR_TE; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable the MAC transmission */ |
||||
|
ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Clears the ETHERNET transmit FIFO. |
||||
|
*/ |
||||
|
void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth *ETHERNET_MAC) |
||||
|
{ |
||||
|
/* Set the Flush Transmit FIFO bit */ |
||||
|
ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables or disables the MAC reception. |
||||
|
*/ |
||||
|
void EMAC_MACReceptionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState) |
||||
|
{ |
||||
|
if (NewState) |
||||
|
{ |
||||
|
/* Enable the MAC reception */ |
||||
|
ETHERNET_MAC->MCR |= EMAC_MACCR_RE; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable the MAC reception */ |
||||
|
ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables or disables the DMA transmission. |
||||
|
*/ |
||||
|
void EMAC_DMATransmissionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState) |
||||
|
{ |
||||
|
if (NewState) |
||||
|
{ |
||||
|
/* Enable the DMA transmission */ |
||||
|
ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable the DMA transmission */ |
||||
|
ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables or disables the DMA reception. |
||||
|
*/ |
||||
|
void EMAC_DMAReceptionCmd(struct rt_synopsys_eth *ETHERNET_MAC, rt_bool_t NewState) |
||||
|
{ |
||||
|
if (NewState) |
||||
|
{ |
||||
|
/* Enable the DMA reception */ |
||||
|
ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* Disable the DMA reception */ |
||||
|
ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Enables ENET MAC and DMA reception/transmission |
||||
|
*/ |
||||
|
void EMAC_start(struct rt_synopsys_eth *ETHERNET_MAC) |
||||
|
{ |
||||
|
/* Enable transmit state machine of the MAC for transmission on the MII */ |
||||
|
EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE); |
||||
|
/* Flush Transmit FIFO */ |
||||
|
enet_txfifo_flush(ENET0); |
||||
|
/* Enable receive state machine of the MAC for reception from the MII */ |
||||
|
EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE); |
||||
|
|
||||
|
/* Start DMA transmission */ |
||||
|
EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE); |
||||
|
/* Start DMA reception */ |
||||
|
EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE); |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Clears the ETHERNET's DMA interrupt pending bit. |
||||
|
*/ |
||||
|
void EMAC_clear_pending(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint32_t pending) |
||||
|
{ |
||||
|
/* Clear the selected ETHERNET DMA IT */ |
||||
|
ETHERNET_MAC->SR = (rt_uint32_t)pending; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Resumes the DMA Transmission by writing to the DmaRxPollDemand register |
||||
|
* (the data written could be anything). This forces the DMA to resume reception. |
||||
|
*/ |
||||
|
void EMAC_resume_reception(struct rt_synopsys_eth *ETHERNET_MAC) |
||||
|
{ |
||||
|
ETHERNET_MAC->RPDR = 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Resumes the DMA Transmission by writing to the DmaTxPollDemand register |
||||
|
* (the data written could be anything). This forces the DMA to resume transmission. |
||||
|
*/ |
||||
|
void EMAC_resume_transmission(struct rt_synopsys_eth *ETHERNET_MAC) |
||||
|
{ |
||||
|
ETHERNET_MAC->TPDR = 0; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Read a PHY register |
||||
|
*/ |
||||
|
rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg) |
||||
|
{ |
||||
|
rt_uint32_t value = 0; |
||||
|
volatile rt_uint32_t timeout = 0; |
||||
|
|
||||
|
/* Get the ETHERNET MACMIIAR value */ |
||||
|
value = ETHERNET_MAC->GAR; |
||||
|
/* Keep only the CSR Clock Range CR[2:0] bits value */ |
||||
|
value &= ~MACMIIAR_CR_MASK; |
||||
|
/* Prepare the MII address register value */ |
||||
|
value |= (((rt_uint32_t)PHYAddress << 11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */ |
||||
|
value |= (((rt_uint32_t)PHYReg << 6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */ |
||||
|
value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */ |
||||
|
value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */ |
||||
|
/* Write the result value into the MII Address register */ |
||||
|
ETHERNET_MAC->GAR = value; |
||||
|
/* Check for the Busy flag */ |
||||
|
do |
||||
|
{ |
||||
|
timeout++; |
||||
|
value = ETHERNET_MAC->GAR; |
||||
|
} while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO)); |
||||
|
/* Return ERROR in case of timeout */ |
||||
|
if (timeout == PHY_READ_TO) |
||||
|
{ |
||||
|
return (rt_uint16_t)EMAC_ERROR; |
||||
|
} |
||||
|
|
||||
|
/* Return data register value */ |
||||
|
return (rt_uint16_t)(ETHERNET_MAC->GDR); |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* Write to a PHY register |
||||
|
*/ |
||||
|
rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth *ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue) |
||||
|
{ |
||||
|
rt_uint32_t value = 0; |
||||
|
volatile rt_uint32_t timeout = 0; |
||||
|
|
||||
|
/* Get the ETHERNET MACMIIAR value */ |
||||
|
value = ETHERNET_MAC->GAR; |
||||
|
/* Keep only the CSR Clock Range CR[2:0] bits value */ |
||||
|
value &= ~MACMIIAR_CR_MASK; |
||||
|
/* Prepare the MII register address value */ |
||||
|
value |= (((rt_uint32_t)PHYAddress << 11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */ |
||||
|
value |= (((rt_uint32_t)PHYReg << 6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */ |
||||
|
value |= EMAC_MACMIIAR_MW; /* Set the write mode */ |
||||
|
value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */ |
||||
|
/* Give the value to the MII data register */ |
||||
|
ETHERNET_MAC->GDR = PHYValue; |
||||
|
/* Write the result value into the MII Address register */ |
||||
|
ETHERNET_MAC->GAR = value; |
||||
|
/* Check for the Busy flag */ |
||||
|
do |
||||
|
{ |
||||
|
timeout++; |
||||
|
value = ETHERNET_MAC->GAR; |
||||
|
} while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO)); |
||||
|
/* Return ERROR in case of timeout */ |
||||
|
if (timeout == PHY_WRITE_TO) |
||||
|
{ |
||||
|
return EMAC_ERROR; |
||||
|
} |
||||
|
|
||||
|
/* Return SUCCESS */ |
||||
|
return EMAC_SUCCESS; |
||||
|
} |
||||
|
#endif /* RT_USING_SAL && RT_USING_NETDEV && RT_USING_LWIP */ |
||||
@ -0,0 +1,336 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_otghs_dev.h" |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include "board.h" |
||||
|
#include "drv_usb_hw.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE) |
||||
|
|
||||
|
usb_core_driver gd_usb_core; |
||||
|
|
||||
|
static struct udcd _gd_udc; |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
static struct ep_id _ep_pool[] = { |
||||
|
{ 0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED }, |
||||
|
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED }, |
||||
|
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED }, |
||||
|
{ 0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED }, |
||||
|
{ 0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED }, |
||||
|
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED }, |
||||
|
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED }, |
||||
|
{ 0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED }, |
||||
|
}; |
||||
|
#elif defined USE_USB_HS |
||||
|
static struct ep_id _ep_pool[] = { |
||||
|
{ 0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED }, |
||||
|
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED }, |
||||
|
{ 0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 512, ID_UNASSIGNED }, |
||||
|
{ 0x2, USB_EP_ATTR_INT, USB_DIR_IN, 512, ID_UNASSIGNED }, |
||||
|
{ 0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 512, ID_UNASSIGNED }, |
||||
|
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 512, ID_UNASSIGNED }, |
||||
|
{ 0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 512, ID_UNASSIGNED }, |
||||
|
{ 0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED }, |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
void usbd_reset_callback(void) |
||||
|
{ |
||||
|
rt_usbd_reset_handler(&_gd_udc); |
||||
|
} |
||||
|
|
||||
|
void usbd_setup_stage_callback(struct urequest *setup_packet) |
||||
|
{ |
||||
|
rt_usbd_ep0_setup_handler(&_gd_udc, setup_packet); |
||||
|
} |
||||
|
|
||||
|
void usbd_data_in_stage_callback(uint8_t epnum, uint16_t data_count) |
||||
|
{ |
||||
|
if (epnum == 0) |
||||
|
{ |
||||
|
rt_usbd_ep0_in_handler(&_gd_udc); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
rt_usbd_ep_in_handler(&_gd_udc, 0x80 | epnum, data_count); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void usbd_connect_callback(void) |
||||
|
{ |
||||
|
rt_usbd_connect_handler(&_gd_udc); |
||||
|
} |
||||
|
|
||||
|
void usbd_sof_callback(void) |
||||
|
{ |
||||
|
rt_usbd_sof_handler(&_gd_udc); |
||||
|
} |
||||
|
|
||||
|
void usbd_disconnect_callback(void) |
||||
|
{ |
||||
|
rt_usbd_disconnect_handler(&_gd_udc); |
||||
|
} |
||||
|
|
||||
|
void usbd_data_out_stage_callback(uint8_t epnum, uint16_t data_count) |
||||
|
{ |
||||
|
if (epnum == 0) |
||||
|
{ |
||||
|
rt_usbd_ep0_out_handler(&_gd_udc, data_count); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
rt_usbd_ep_out_handler(&_gd_udc, epnum, data_count); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void usbd_set_connection_state(uint8_t state) |
||||
|
{ |
||||
|
if (state == 1) |
||||
|
{ |
||||
|
usb_dev_connect(&gd_usb_core); |
||||
|
|
||||
|
usb_mdelay(3); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
usb_dev_disconnect(&gd_usb_core); |
||||
|
|
||||
|
usb_mdelay(3); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _ep_set_stall(rt_uint8_t address) |
||||
|
{ |
||||
|
usb_ep_stall(&gd_usb_core, address); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _ep_clear_stall(rt_uint8_t address) |
||||
|
{ |
||||
|
usb_ep_clrstall(&gd_usb_core, address); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _set_address(rt_uint8_t address) |
||||
|
{ |
||||
|
usb_devaddr_set(&gd_usb_core, address); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _set_config(rt_uint8_t address) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _ep_enable(uep_t ep) |
||||
|
{ |
||||
|
RT_ASSERT(ep != RT_NULL); |
||||
|
RT_ASSERT(ep->ep_desc != RT_NULL); |
||||
|
|
||||
|
usb_ep_active(&gd_usb_core, |
||||
|
ep->ep_desc->bEndpointAddress, |
||||
|
ep->ep_desc->wMaxPacketSize, |
||||
|
ep->ep_desc->bmAttributes); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _ep_disable(uep_t ep) |
||||
|
{ |
||||
|
RT_ASSERT(ep != RT_NULL); |
||||
|
RT_ASSERT(ep->ep_desc != RT_NULL); |
||||
|
|
||||
|
usb_ep_deactivate(&gd_usb_core, ep->ep_desc->bEndpointAddress); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t _ep_read(rt_uint8_t address, void *buffer) |
||||
|
{ |
||||
|
rt_size_t size = 0; |
||||
|
RT_ASSERT(buffer != RT_NULL); |
||||
|
|
||||
|
return size; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t _ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size) |
||||
|
{ |
||||
|
usb_ep_outxfer(&gd_usb_core, address, buffer, size); |
||||
|
|
||||
|
return size; |
||||
|
} |
||||
|
|
||||
|
static rt_ssize_t _ep_write(rt_uint8_t address, void *buffer, rt_size_t size) |
||||
|
{ |
||||
|
usb_ep_inxfer(&gd_usb_core, address, buffer, size); |
||||
|
|
||||
|
return size; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _ep0_send_status(void) |
||||
|
{ |
||||
|
usb_ep_inxfer(&gd_usb_core, 0, NULL, 0); |
||||
|
|
||||
|
usb_ctlep_startout(&gd_usb_core); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _suspend(void) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _wakeup(void) |
||||
|
{ |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t _init(rt_device_t device) |
||||
|
{ |
||||
|
usb_rcu_config(); |
||||
|
|
||||
|
usb_timer_init(); |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_FULL); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_HIGH); |
||||
|
#endif |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_FULL); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_HIGH); |
||||
|
#endif |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
/* configure USB capabilites */ |
||||
|
usb_basic_init(&gd_usb_core.bp, &gd_usb_core.regs); |
||||
|
|
||||
|
usb_globalint_disable(&gd_usb_core.regs); |
||||
|
|
||||
|
/* initailizes the USB core*/ |
||||
|
usb_core_init(gd_usb_core.bp, &gd_usb_core.regs); |
||||
|
|
||||
|
/* set device disconnect */ |
||||
|
usbd_set_connection_state(0); |
||||
|
|
||||
|
usb_curmode_set(&gd_usb_core.regs, DEVICE_MODE); |
||||
|
|
||||
|
/* initailizes device mode */ |
||||
|
usb_devcore_init(&gd_usb_core); |
||||
|
|
||||
|
usb_globalint_enable(&gd_usb_core.regs); |
||||
|
|
||||
|
/* set device connect */ |
||||
|
usbd_set_connection_state(1); |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
#ifdef USE_USBHS0 |
||||
|
pllusb_rcu_config(USBHS0); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
pllusb_rcu_config(USBHS1); |
||||
|
#endif |
||||
|
#endif /* USE_USB_HS */ |
||||
|
|
||||
|
usb_intr_config(); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
const static struct udcd_ops _udc_ops = { |
||||
|
_set_address, |
||||
|
_set_config, |
||||
|
_ep_set_stall, |
||||
|
_ep_clear_stall, |
||||
|
_ep_enable, |
||||
|
_ep_disable, |
||||
|
_ep_read_prepare, |
||||
|
_ep_read, |
||||
|
_ep_write, |
||||
|
_ep0_send_status, |
||||
|
_suspend, |
||||
|
_wakeup, |
||||
|
}; |
||||
|
|
||||
|
int gd_usbd_register(void) |
||||
|
{ |
||||
|
rt_memset((void *)&_gd_udc, 0, sizeof(struct udcd)); |
||||
|
_gd_udc.parent.type = RT_Device_Class_USBDevice; |
||||
|
_gd_udc.parent.init = _init; |
||||
|
_gd_udc.parent.user_data = NULL; |
||||
|
_gd_udc.ops = &_udc_ops; |
||||
|
/* Register endpoint infomation */ |
||||
|
_gd_udc.ep_pool = _ep_pool; |
||||
|
_gd_udc.ep0.id = &_ep_pool[0]; |
||||
|
|
||||
|
rt_device_register((rt_device_t)&_gd_udc, "usbd", 0); |
||||
|
rt_usb_device_init(); |
||||
|
return RT_EOK; |
||||
|
} |
||||
|
INIT_DEVICE_EXPORT(gd_usbd_register); |
||||
|
|
||||
|
#ifdef RT_USB_DEVICE_HID |
||||
|
|
||||
|
void usbd_hid_send(uint8_t *buffer, uint16_t size) |
||||
|
{ |
||||
|
struct hid_s |
||||
|
{ |
||||
|
struct rt_device parent; |
||||
|
struct ufunction *func; |
||||
|
uep_t ep_in; |
||||
|
uep_t ep_out; |
||||
|
int status; |
||||
|
rt_uint16_t protocol; |
||||
|
rt_uint8_t report_buf[64]; |
||||
|
struct rt_messagequeue hid_mq; |
||||
|
}; |
||||
|
|
||||
|
udevice_t device = RT_NULL; |
||||
|
uintf_t intf; |
||||
|
ufunction_t func; |
||||
|
|
||||
|
struct hid_s *hiddev; |
||||
|
|
||||
|
device = rt_usbd_find_device(&_gd_udc); |
||||
|
|
||||
|
intf = rt_usbd_find_interface(device, 0, &func); |
||||
|
|
||||
|
if (RT_NULL != intf) |
||||
|
{ |
||||
|
hiddev = (struct hid_s *)func->user_data; |
||||
|
|
||||
|
hiddev->parent.write(&hiddev->parent, 0, buffer, size); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */ |
||||
@ -0,0 +1,315 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_otghs_host.h" |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include "board.h" |
||||
|
|
||||
|
#include "drv_usb_hw.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
#define OTG_FS_PORT 1 |
||||
|
|
||||
|
usb_core_driver gd_usb_core; |
||||
|
|
||||
|
static struct rt_completion urb_completion; |
||||
|
static volatile rt_bool_t connect_status = RT_FALSE; |
||||
|
|
||||
|
void usbh_connect_callback(usb_core_driver *hhcd) |
||||
|
{ |
||||
|
uhcd_t hcd = (uhcd_t)hhcd->host.data; |
||||
|
if (!connect_status) |
||||
|
{ |
||||
|
connect_status = RT_TRUE; |
||||
|
rt_usbh_root_hub_connect_handler(hcd, OTG_FS_PORT, RT_FALSE); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void usbh_disconnect_callback(usb_core_driver *hhcd) |
||||
|
{ |
||||
|
uhcd_t hcd = (uhcd_t)hhcd->host.data; |
||||
|
if (connect_status) |
||||
|
{ |
||||
|
connect_status = RT_FALSE; |
||||
|
rt_usbh_root_hub_disconnect_handler(hcd, OTG_FS_PORT); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void usbh_hc_notifyurbchange_callback(usb_core_driver *hhcd, uint8_t chnum, usb_urb_state urb_state) |
||||
|
{ |
||||
|
rt_completion_done(&urb_completion); |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_reset_port(rt_uint8_t port) |
||||
|
{ |
||||
|
usb_port_reset(&gd_usb_core); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeout) |
||||
|
{ |
||||
|
while (1) |
||||
|
{ |
||||
|
uint8_t dir = (pipe->ep.bEndpointAddress & 0x80) >> 7; |
||||
|
|
||||
|
if (!connect_status) |
||||
|
{ |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
rt_completion_init(&urb_completion); |
||||
|
|
||||
|
if (dir == 0) |
||||
|
{ |
||||
|
if (token == 0) |
||||
|
{ |
||||
|
usbh_ctlsetup_send(&gd_usb_core, buffer, pipe->pipe_index); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
usbh_data_send(&gd_usb_core, buffer, pipe->pipe_index, nbytes); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
usbh_data_recev(&gd_usb_core, buffer, pipe->pipe_index, nbytes); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
rt_completion_wait(&urb_completion, timeout); |
||||
|
|
||||
|
rt_thread_mdelay(1); |
||||
|
|
||||
|
if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_NOTREADY) |
||||
|
{ |
||||
|
if (pipe->ep.bmAttributes == USB_EP_ATTR_INT) |
||||
|
{ |
||||
|
rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1); |
||||
|
} |
||||
|
|
||||
|
usb_pipe_halt(&gd_usb_core, pipe->pipe_index); |
||||
|
|
||||
|
usbh_pipe_create(&gd_usb_core, |
||||
|
pipe->inst->address, |
||||
|
(uint8_t)PORT_SPEED_FULL, |
||||
|
pipe->pipe_index, |
||||
|
pipe->ep.bEndpointAddress, |
||||
|
pipe->ep.bmAttributes, |
||||
|
pipe->ep.wMaxPacketSize); |
||||
|
continue; |
||||
|
} |
||||
|
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_STALL) |
||||
|
{ |
||||
|
pipe->status = UPIPE_STATUS_STALL; |
||||
|
if (pipe->callback != RT_NULL) |
||||
|
{ |
||||
|
pipe->callback(pipe); |
||||
|
} |
||||
|
return -1; |
||||
|
} |
||||
|
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_ERROR) |
||||
|
{ |
||||
|
pipe->status = UPIPE_STATUS_ERROR; |
||||
|
if (pipe->callback != RT_NULL) |
||||
|
{ |
||||
|
pipe->callback(pipe); |
||||
|
} |
||||
|
return -1; |
||||
|
} |
||||
|
else if (usbh_urbstate_get(&gd_usb_core, pipe->pipe_index) == URB_DONE) |
||||
|
{ |
||||
|
pipe->status = UPIPE_STATUS_OK; |
||||
|
if (pipe->callback != RT_NULL) |
||||
|
{ |
||||
|
pipe->callback(pipe); |
||||
|
} |
||||
|
if (pipe->ep.bEndpointAddress & 0x80) |
||||
|
{ |
||||
|
return usbh_xfercount_get(&gd_usb_core, pipe->pipe_index); |
||||
|
} |
||||
|
return nbytes; |
||||
|
} |
||||
|
return -1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static rt_uint16_t pipe_index = 0; |
||||
|
static rt_uint8_t drv_get_free_pipe_index() |
||||
|
{ |
||||
|
rt_uint8_t idx; |
||||
|
for (idx = 1; idx < 16; idx++) |
||||
|
{ |
||||
|
if (!(pipe_index & (0x01 << idx))) |
||||
|
{ |
||||
|
pipe_index |= (0x01 << idx); |
||||
|
return (idx - 1); |
||||
|
} |
||||
|
} |
||||
|
return 0xff; |
||||
|
} |
||||
|
|
||||
|
static void drv_free_pipe_index(rt_uint8_t index) |
||||
|
{ |
||||
|
pipe_index &= ~(0x01 << index); |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_open_pipe(upipe_t pipe) |
||||
|
{ |
||||
|
pipe->pipe_index = drv_get_free_pipe_index(); |
||||
|
|
||||
|
usbh_pipe_create(&gd_usb_core, |
||||
|
pipe->inst->address, |
||||
|
(uint8_t)PORT_SPEED_FULL, |
||||
|
pipe->pipe_index, |
||||
|
pipe->ep.bEndpointAddress, |
||||
|
pipe->ep.bmAttributes, |
||||
|
pipe->ep.wMaxPacketSize); |
||||
|
|
||||
|
/* Set DATA0 PID token*/ |
||||
|
if (gd_usb_core.host.pipe[pipe->pipe_index].ep.dir) |
||||
|
{ |
||||
|
gd_usb_core.host.pipe[pipe->pipe_index].data_toggle_in = 0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
gd_usb_core.host.pipe[pipe->pipe_index].data_toggle_out = 0; |
||||
|
} |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
static rt_err_t drv_close_pipe(upipe_t pipe) |
||||
|
{ |
||||
|
usb_pipe_halt(&gd_usb_core, pipe->pipe_index); |
||||
|
|
||||
|
drv_free_pipe_index(pipe->pipe_index); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
struct uhcd_ops _uhcd_ops = { |
||||
|
drv_reset_port, |
||||
|
drv_pipe_xfer, |
||||
|
drv_open_pipe, |
||||
|
drv_close_pipe, |
||||
|
}; |
||||
|
|
||||
|
static rt_err_t gd32_hcd_init(rt_device_t device) |
||||
|
{ |
||||
|
usb_rcu_config(); |
||||
|
|
||||
|
usb_timer_init(); |
||||
|
|
||||
|
/* configure GPIO pin used for switching VBUS power and charge pump I/O */ |
||||
|
usb_vbus_config(); |
||||
|
|
||||
|
uint8_t i = 0U; |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_FULL); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
usb_para_init(&gd_usb_core, USBHS0, USB_SPEED_HIGH); |
||||
|
#endif |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_FULL); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
usb_para_init(&gd_usb_core, USBHS1, USB_SPEED_HIGH); |
||||
|
#endif |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
gd_usb_core.host.connect_status = 0U; |
||||
|
|
||||
|
for (i = 0U; i < USBHS_MAX_TX_FIFOS; i++) |
||||
|
{ |
||||
|
gd_usb_core.host.pipe[i].err_count = 0U; |
||||
|
gd_usb_core.host.pipe[i].pp_status = PIPE_IDLE; |
||||
|
gd_usb_core.host.backup_xfercount[i] = 0U; |
||||
|
} |
||||
|
|
||||
|
gd_usb_core.host.pipe[0].ep.mps = 8U; |
||||
|
|
||||
|
usb_basic_init(&gd_usb_core.bp, &gd_usb_core.regs); |
||||
|
|
||||
|
usb_globalint_disable(&gd_usb_core.regs); |
||||
|
|
||||
|
usb_core_init(gd_usb_core.bp, &gd_usb_core.regs); |
||||
|
|
||||
|
#ifndef USE_OTG_MODE |
||||
|
usb_curmode_set(&gd_usb_core.regs, HOST_MODE); |
||||
|
#endif /* USE_OTG_MODE */ |
||||
|
|
||||
|
usb_host_init(&gd_usb_core); |
||||
|
|
||||
|
usb_globalint_enable(&gd_usb_core.regs); |
||||
|
|
||||
|
#ifdef USE_USB_HS |
||||
|
#ifdef USE_USBHS0 |
||||
|
pllusb_rcu_config(USBHS0); |
||||
|
#elif defined USE_USBHS1 |
||||
|
pllusb_rcu_config(USBHS1); |
||||
|
#else |
||||
|
#endif |
||||
|
#endif /* USE_USB_HS */ |
||||
|
|
||||
|
/* enable interrupts */ |
||||
|
usb_intr_config(); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
|
||||
|
int gd_usbh_register(void) |
||||
|
{ |
||||
|
rt_err_t res = -RT_ERROR; |
||||
|
|
||||
|
uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd)); |
||||
|
if (uhcd == RT_NULL) |
||||
|
{ |
||||
|
rt_kprintf("uhcd malloc failed\r\n"); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
rt_memset((void *)uhcd, 0, sizeof(struct uhcd)); |
||||
|
uhcd->parent.type = RT_Device_Class_USBHost; |
||||
|
uhcd->parent.init = gd32_hcd_init; |
||||
|
uhcd->parent.user_data = &gd_usb_core; |
||||
|
|
||||
|
uhcd->ops = &_uhcd_ops; |
||||
|
uhcd->num_ports = OTG_FS_PORT; |
||||
|
gd_usb_core.host.data = uhcd; |
||||
|
|
||||
|
res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE); |
||||
|
if (res != RT_EOK) |
||||
|
{ |
||||
|
rt_kprintf("register usb host failed res = %d\r\n", res); |
||||
|
return -RT_ERROR; |
||||
|
} |
||||
|
|
||||
|
rt_usb_host_init("usbh"); |
||||
|
|
||||
|
return RT_EOK; |
||||
|
} |
||||
|
INIT_DEVICE_EXPORT(gd_usbh_register); |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
@ -0,0 +1,440 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usb_hw.h" |
||||
|
#include "drv_usb_core.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) |
||||
|
|
||||
|
/* local function prototypes ('static') */ |
||||
|
static void usb_core_reset(usb_core_regs *usb_regs); |
||||
|
|
||||
|
/*!
|
||||
|
\brief configures USB parameters |
||||
|
\param[in] udev: pointer to USB core instance |
||||
|
\param[in] usb_periph: USBHSx(x=0,1) |
||||
|
\param[in] usb_speed: USB speed type (full-speed or high-speed) |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_para_init(usb_core_driver *udev, uint32_t usb_periph, uint32_t usb_speed) |
||||
|
{ |
||||
|
usb_core_basic *usb_basic = &udev->bp; |
||||
|
|
||||
|
/* configure USB default transfer mode as FIFO mode */ |
||||
|
usb_basic->transfer_mode = (uint8_t)USB_USE_FIFO; |
||||
|
|
||||
|
/* USB default speed is full-speed */ |
||||
|
usb_basic->core_speed = (uint8_t)USB_SPEED_FULL; |
||||
|
|
||||
|
/* USB basic register address setting */ |
||||
|
switch (usb_periph) |
||||
|
{ |
||||
|
case USBHS0: |
||||
|
usb_basic->base_reg = (uint32_t)USBHS0_REG_BASE; |
||||
|
break; |
||||
|
case USBHS1: |
||||
|
usb_basic->base_reg = (uint32_t)USBHS1_REG_BASE; |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* set the host channel numbers */ |
||||
|
usb_basic->num_pipe = USBHS_MAX_CHANNEL_COUNT; |
||||
|
|
||||
|
/* set the device endpoint numbers */ |
||||
|
usb_basic->num_ep = USBHS_MAX_EP_COUNT; |
||||
|
|
||||
|
if (USB_SPEED_HIGH == usb_speed) |
||||
|
{ |
||||
|
#ifdef USB_EXTERNAL_ULPI_PHY_ENABLED |
||||
|
usb_basic->phy_itf = USB_ULPI_PHY_EXTERNAL; |
||||
|
#endif /* USB_EXTERNAL_ULPI_PHY_ENABLED */ |
||||
|
|
||||
|
#ifdef USB_EMBEDDED_HS_PHY_ENABLED |
||||
|
usb_basic->phy_itf = USB_EMBEDDED_PHY_HS; |
||||
|
#endif /* USB_EMBEDDED_HS_PHY_ENABLED */ |
||||
|
} |
||||
|
else if (USB_SPEED_FULL == usb_speed) |
||||
|
{ |
||||
|
#ifdef USB_EMBEDDED_FS_PHY_ENABLED |
||||
|
usb_basic->phy_itf = USB_EMBEDDED_PHY_FS; |
||||
|
#endif /* USB_EMBEDDED_FS_PHY_ENABLED */ |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
#ifdef USB_INTERNAL_DMA_ENABLED |
||||
|
usb_basic->transfer_mode = USB_USE_DMA; |
||||
|
#endif /* USB_INTERNAL_DMA_ENABLED */ |
||||
|
|
||||
|
usb_basic->sof_enable = (uint8_t)USB_SOF_OUTPUT; |
||||
|
usb_basic->low_power = (uint8_t)USB_LOW_POWER; |
||||
|
|
||||
|
#if (1U == LPM_ENABLED) |
||||
|
usb_basic->lpm_enable = 1U; |
||||
|
#endif /* LPM_ENABLED */ |
||||
|
} |
||||
|
/*!
|
||||
|
\brief configure USB core basic |
||||
|
\param[in] usb_basic: pointer to USB capabilities |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_basic_init(usb_core_basic *usb_basic, usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
/* assign main registers address */ |
||||
|
*usb_regs = (usb_core_regs){ |
||||
|
.gr = (usb_gr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CORE), |
||||
|
.hr = (usb_hr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_HOST), |
||||
|
.dr = (usb_dr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_DEV), |
||||
|
|
||||
|
.HPCS = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PORT), |
||||
|
.PWRCLKCTL = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PWRCLKCTL) |
||||
|
}; |
||||
|
|
||||
|
/* assign device endpoint registers address */ |
||||
|
for (uint8_t i = 0U; i < usb_basic->num_ep; i++) |
||||
|
{ |
||||
|
usb_regs->er_in[i] = (usb_erin *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_IN + (i * (uint32_t)USB_REG_OFFSET_EP)); |
||||
|
|
||||
|
usb_regs->er_out[i] = (usb_erout *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_OUT + (i * (uint32_t)USB_REG_OFFSET_EP)); |
||||
|
} |
||||
|
|
||||
|
/* assign host pipe registers address */ |
||||
|
for (uint8_t i = 0U; i < usb_basic->num_pipe; i++) |
||||
|
{ |
||||
|
usb_regs->pr[i] = (usb_pr *)(usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CH_INOUT + (i * (uint32_t)USB_REG_OFFSET_CH)); |
||||
|
|
||||
|
usb_regs->DFIFO[i] = (uint32_t *)(usb_basic->base_reg + (uint32_t)USB_DATA_FIFO_OFFSET + (i * (uint32_t)USB_DATA_FIFO_SIZE)); |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief initializes the USB controller registers and |
||||
|
prepares the core device mode or host mode operation |
||||
|
\param[in] usb_basic: pointer to USB capabilities |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_core_init(usb_core_basic usb_basic, usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
if (USB_ULPI_PHY_EXTERNAL == usb_basic.phy_itf) |
||||
|
{ |
||||
|
usb_regs->gr->GCCFG &= ~GCCFG_PWRON; |
||||
|
|
||||
|
usb_regs->gr->GUSBCS &= ~(GUSBCS_EMBPHY_HS | GUSBCS_EMBPHY_FS); |
||||
|
|
||||
|
if (usb_basic.sof_enable) |
||||
|
{ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_SOFOEN; |
||||
|
} |
||||
|
|
||||
|
/* initialize the ULPI interface */ |
||||
|
usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEOI; |
||||
|
|
||||
|
#ifdef USBHS_EXTERNAL_VBUS_ENABLED |
||||
|
/* use external VBUS driver */ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_ULPIEVD; |
||||
|
#else |
||||
|
/* use internal VBUS driver */ |
||||
|
usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEVD; |
||||
|
#endif /* USBHS_EXTERNAL_VBUS_ENABLED */ |
||||
|
|
||||
|
/* soft reset the core */ |
||||
|
usb_core_reset(usb_regs); |
||||
|
} |
||||
|
else if (USB_EMBEDDED_PHY_HS == usb_basic.phy_itf) |
||||
|
{ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_HS; |
||||
|
|
||||
|
/* soft reset the core */ |
||||
|
usb_core_reset(usb_regs); |
||||
|
|
||||
|
usb_regs->gr->GCCFG = 0U; |
||||
|
|
||||
|
#ifdef VBUS_SENSING_ENABLED |
||||
|
/* active the transceiver and enable VBUS sensing */ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON; |
||||
|
#else |
||||
|
#ifdef USE_HOST_MODE |
||||
|
usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE; |
||||
|
#endif /* USE_HOST_MODE */ |
||||
|
|
||||
|
#ifdef USE_DEVICE_MODE |
||||
|
usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE; |
||||
|
#endif /* USE_DEVICE_MODE */ |
||||
|
|
||||
|
/* active the transceiver */ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_PWRON; |
||||
|
#endif /* VBUS_SENSING_ENABLED */ |
||||
|
|
||||
|
if (usb_basic.sof_enable) |
||||
|
{ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_SOFOEN; |
||||
|
} |
||||
|
|
||||
|
usb_mdelay(20U); |
||||
|
} |
||||
|
else if (USB_EMBEDDED_PHY_FS == usb_basic.phy_itf) |
||||
|
{ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_FS; |
||||
|
|
||||
|
/* soft reset the core */ |
||||
|
usb_core_reset(usb_regs); |
||||
|
|
||||
|
#ifdef VBUS_SENSING_ENABLED |
||||
|
/* active the transceiver and enable VBUS sensing */ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON; |
||||
|
#else |
||||
|
#ifdef USE_HOST_MODE |
||||
|
usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE; |
||||
|
#endif /* USE_HOST_MODE */ |
||||
|
|
||||
|
#ifdef USE_DEVICE_MODE |
||||
|
usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE; |
||||
|
#endif /* USE_DEVICE_MODE */ |
||||
|
|
||||
|
/* active the transceiver */ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_PWRON; |
||||
|
#endif /* VBUS_SENSING_ENABLED */ |
||||
|
|
||||
|
/* enable SOF output */ |
||||
|
if (usb_basic.sof_enable) |
||||
|
{ |
||||
|
usb_regs->gr->GCCFG |= GCCFG_SOFOEN; |
||||
|
} |
||||
|
|
||||
|
usb_mdelay(20U); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == usb_basic.transfer_mode) |
||||
|
{ |
||||
|
usb_regs->gr->GAHBCS &= ~GAHBCS_BURST; |
||||
|
usb_regs->gr->GAHBCS |= DMA_INCR8 | GAHBCS_DMAEN; |
||||
|
} |
||||
|
|
||||
|
#ifdef USE_OTG_MODE |
||||
|
|
||||
|
/* enable USB OTG features */ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_HNPCEN | GUSBCS_SRPCEN; |
||||
|
|
||||
|
/* enable the USB wakeup and suspend interrupts */ |
||||
|
usb_regs->gr->GINTF = 0xBFFFFFFFU; |
||||
|
|
||||
|
usb_regs->gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE | |
||||
|
GINTEN_OTGIE | GINTEN_SESIE | GINTEN_IDPSCIE; |
||||
|
|
||||
|
#endif /* USE_OTG_MODE */ |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief write a packet into the TX FIFO associated with the endpoint |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] src_buf: pointer to source buffer |
||||
|
\param[in] fifo_num: FIFO number which is in (0..5) |
||||
|
\param[in] byte_count: packet byte count |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_txfifo_write(usb_core_regs *usb_regs, |
||||
|
uint8_t *src_buf, |
||||
|
uint8_t fifo_num, |
||||
|
uint16_t byte_count) |
||||
|
{ |
||||
|
uint32_t word_count = (byte_count + 3U) / 4U; |
||||
|
|
||||
|
__IO uint32_t *fifo = usb_regs->DFIFO[fifo_num]; |
||||
|
|
||||
|
while (word_count-- > 0U) |
||||
|
{ |
||||
|
*fifo = *((__IO uint32_t *)src_buf); |
||||
|
|
||||
|
src_buf += 4U; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read a packet from the Rx FIFO associated with the endpoint |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] dest_buf: pointer to destination buffer |
||||
|
\param[in] byte_count: packet byte count |
||||
|
\param[out] none |
||||
|
\retval void type pointer |
||||
|
*/ |
||||
|
void *usb_rxfifo_read(usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count) |
||||
|
{ |
||||
|
__IO uint32_t word_count = (byte_count + 3U) / 4U; |
||||
|
__IO uint32_t *fifo = usb_regs->DFIFO[0]; |
||||
|
|
||||
|
while (word_count-- > 0U) |
||||
|
{ |
||||
|
*(__IO uint32_t *)dest_buf = *fifo; |
||||
|
|
||||
|
dest_buf += 4U; |
||||
|
} |
||||
|
|
||||
|
return ((void *)dest_buf); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief flush a TX FIFO or all TX FIFOs |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] fifo_num: FIFO number which is in (0..5) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_txfifo_flush(usb_core_regs *usb_regs, uint8_t fifo_num) |
||||
|
{ |
||||
|
usb_regs->gr->GRSTCTL = ((uint32_t)fifo_num << 6) | GRSTCTL_TXFF; |
||||
|
|
||||
|
/* wait for TX FIFO flush bit is set */ |
||||
|
while (usb_regs->gr->GRSTCTL & GRSTCTL_TXFF) |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
/* wait for 3 PHY clocks*/ |
||||
|
usb_udelay(3U); |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief flush the entire RX FIFO |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_rxfifo_flush(usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
usb_regs->gr->GRSTCTL = GRSTCTL_RXFF; |
||||
|
|
||||
|
/* wait for RX FIFO flush bit is set */ |
||||
|
while (usb_regs->gr->GRSTCTL & GRSTCTL_RXFF) |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
/* wait for 3 PHY clocks */ |
||||
|
usb_udelay(3U); |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set endpoint or channel TX FIFO size |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] fifo: TX FIFO number |
||||
|
\param[in] size: assigned TX FIFO size |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size) |
||||
|
{ |
||||
|
uint32_t tx_offset = usb_regs->gr->GRFLEN; |
||||
|
|
||||
|
if (0U == fifo) |
||||
|
{ |
||||
|
usb_regs->gr->DIEP0TFLEN_HNPTFLEN = ((uint32_t)size << 16) | tx_offset; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
tx_offset += (usb_regs->gr->DIEP0TFLEN_HNPTFLEN) >> 16; |
||||
|
|
||||
|
for (uint8_t i = 0U; i < (fifo - 1U); i++) |
||||
|
{ |
||||
|
tx_offset += (usb_regs->gr->DIEPTFLEN[i] >> 16); |
||||
|
} |
||||
|
|
||||
|
usb_regs->gr->DIEPTFLEN[fifo - 1U] = ((uint32_t)size << 16) | tx_offset; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set USB current mode |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[in] mode: USB current mode |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_curmode_set(usb_core_regs *usb_regs, uint8_t mode) |
||||
|
{ |
||||
|
usb_regs->gr->GUSBCS &= ~(GUSBCS_FDM | GUSBCS_FHM); |
||||
|
|
||||
|
if (DEVICE_MODE == mode) |
||||
|
{ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_FDM; |
||||
|
} |
||||
|
else if (HOST_MODE == mode) |
||||
|
{ |
||||
|
usb_regs->gr->GUSBCS |= GUSBCS_FHM; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* OTG mode and other mode can not be here! */ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB core to soft reset |
||||
|
\param[in] usb_regs: pointer to USB core registers |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void usb_core_reset(usb_core_regs *usb_regs) |
||||
|
{ |
||||
|
/* enable core soft reset */ |
||||
|
usb_regs->gr->GRSTCTL |= GRSTCTL_CSRST; |
||||
|
|
||||
|
/* wait for the core to be soft reset */ |
||||
|
while (usb_regs->gr->GRSTCTL & GRSTCTL_CSRST) |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
/* wait for additional 3 PHY clocks */ |
||||
|
usb_udelay(3U); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief active USB core clock |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_clock_active(usb_core_driver *udev) |
||||
|
{ |
||||
|
if (udev->bp.low_power) |
||||
|
{ |
||||
|
if (udev->regs.dr->DSTAT & DSTAT_SPST) |
||||
|
{ |
||||
|
/* un-gate USB Core clock */ |
||||
|
*udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB */ |
||||
@ -0,0 +1,755 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usb_hw.h" |
||||
|
#include "drv_usb_dev.h" |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE) |
||||
|
|
||||
|
/* endpoint 0 max packet length */ |
||||
|
static const uint8_t EP0_MAXLEN[4] = { |
||||
|
[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = EP0MPL_64, |
||||
|
[DSTAT_EM_FS_PHY_30MHZ_60MHZ] = EP0MPL_64, |
||||
|
[DSTAT_EM_FS_PHY_48MHZ] = EP0MPL_64, |
||||
|
[DSTAT_EM_LS_PHY_6MHZ] = EP0MPL_8 |
||||
|
}; |
||||
|
|
||||
|
/* USB endpoint TX FIFO size */ |
||||
|
static uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_EP_COUNT] = { |
||||
|
(uint16_t)TX0_FIFO_SIZE, |
||||
|
(uint16_t)TX1_FIFO_SIZE, |
||||
|
(uint16_t)TX2_FIFO_SIZE, |
||||
|
(uint16_t)TX3_FIFO_SIZE, |
||||
|
(uint16_t)TX4_FIFO_SIZE, |
||||
|
(uint16_t)TX5_FIFO_SIZE, |
||||
|
(uint16_t)TX6_FIFO_SIZE, |
||||
|
(uint16_t)TX7_FIFO_SIZE, |
||||
|
}; |
||||
|
|
||||
|
/*!
|
||||
|
\brief initialize USB core registers for device mode |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_devcore_init(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint8_t i = 0U; |
||||
|
|
||||
|
/* restart the PHY clock (maybe don't need to...) */ |
||||
|
*udev->regs.PWRCLKCTL = 0U; |
||||
|
|
||||
|
/* configure periodic frame interval to default value */ |
||||
|
udev->regs.dr->DCFG &= ~DCFG_EOPFT; |
||||
|
udev->regs.dr->DCFG |= FRAME_INTERVAL_80; |
||||
|
|
||||
|
udev->regs.dr->DCFG &= ~DCFG_DS; |
||||
|
|
||||
|
if (USB_EMBEDDED_PHY_HS == udev->bp.phy_itf) |
||||
|
{ |
||||
|
udev->regs.dr->DCFG |= USB_SPEED_INP_HIGH; |
||||
|
} |
||||
|
else if (USB_EMBEDDED_PHY_FS == udev->bp.phy_itf) |
||||
|
{ |
||||
|
udev->regs.dr->DCFG |= USB_SPEED_INP_FULL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
/* set RX FIFO size */ |
||||
|
usb_set_rxfifo(&udev->regs, (uint16_t)RX_FIFO_SIZE); |
||||
|
|
||||
|
/* set endpoint 0 to 3's TX FIFO length and RAM address */ |
||||
|
for (i = 0U; i < USBHS_MAX_EP_COUNT; i++) |
||||
|
{ |
||||
|
usb_set_txfifo(&udev->regs, i, USBHS_TX_FIFO_SIZE[i]); |
||||
|
} |
||||
|
|
||||
|
/* make sure all FIFOs are flushed */ |
||||
|
|
||||
|
/* flush all TX FIFOs */ |
||||
|
(void)usb_txfifo_flush(&udev->regs, 0x10U); |
||||
|
|
||||
|
/* flush entire RX FIFO */ |
||||
|
(void)usb_rxfifo_flush(&udev->regs); |
||||
|
|
||||
|
/* clear all pending device interrupts */ |
||||
|
udev->regs.dr->DIEPINTEN = 0U; |
||||
|
udev->regs.dr->DOEPINTEN = 0U; |
||||
|
udev->regs.dr->DAEPINT = 0xFFFFFFFFU; |
||||
|
udev->regs.dr->DAEPINTEN = 0U; |
||||
|
|
||||
|
/* configure all IN/OUT endpoints */ |
||||
|
for (i = 0U; i < udev->bp.num_ep; i++) |
||||
|
{ |
||||
|
if (udev->regs.er_in[i]->DIEPCTL & DEPCTL_EPEN) |
||||
|
{ |
||||
|
udev->regs.er_in[i]->DIEPCTL |= DEPCTL_EPD | DEPCTL_SNAK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->regs.er_in[i]->DIEPCTL = 0U; |
||||
|
} |
||||
|
|
||||
|
/* set IN endpoint transfer length to 0 */ |
||||
|
udev->regs.er_in[i]->DIEPLEN = 0U; |
||||
|
|
||||
|
/* clear all pending IN endpoint interrupts */ |
||||
|
udev->regs.er_in[i]->DIEPINTF = 0xFFU; |
||||
|
|
||||
|
if (udev->regs.er_out[i]->DOEPCTL & DEPCTL_EPEN) |
||||
|
{ |
||||
|
udev->regs.er_out[i]->DOEPCTL |= DEPCTL_EPD | DEPCTL_SNAK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->regs.er_out[i]->DOEPCTL = 0U; |
||||
|
} |
||||
|
|
||||
|
/* set OUT endpoint transfer length to 0 */ |
||||
|
udev->regs.er_out[i]->DOEPLEN = 0U; |
||||
|
|
||||
|
/* clear all pending OUT endpoint interrupts */ |
||||
|
udev->regs.er_out[i]->DOEPINTF = 0xFFU; |
||||
|
} |
||||
|
|
||||
|
udev->regs.dr->DIEPINTEN |= DIEPINTEN_EPTXFUDEN; |
||||
|
|
||||
|
(void)usb_devint_enable(udev); |
||||
|
|
||||
|
/* configure LPM function */ |
||||
|
if (1U == udev->bp.lpm_enable) |
||||
|
{ |
||||
|
udev->dev.pm.lpm_state = LPM_L0; |
||||
|
udev->regs.gr->GLPMCFG = GLPMCFG_LPMEN | GLPMCFG_ACKLPM | GLPMCFG_BESLEN; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief enable the USB device mode interrupts |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_devint_enable(usb_core_driver *udev) |
||||
|
{ |
||||
|
/* clear any pending USB OTG interrupts */ |
||||
|
udev->regs.gr->GOTGINTF = 0xFFFFFFFFU; |
||||
|
|
||||
|
/* clear any pending interrupts */ |
||||
|
udev->regs.gr->GINTF = 0xBFFFFFFFU; |
||||
|
|
||||
|
/* enable the USB wakeup and suspend interrupts */ |
||||
|
udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE; |
||||
|
|
||||
|
/* enable device_mode-related interrupts */ |
||||
|
if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; |
||||
|
} |
||||
|
|
||||
|
udev->regs.gr->GINTEN |= GINTEN_RSTIE | GINTEN_ENUMFIE | GINTEN_IEPIE | |
||||
|
GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE | GINTEN_ISOINCIE; |
||||
|
|
||||
|
#ifdef VBUS_SENSING_ENABLED |
||||
|
udev->regs.gr->GINTEN |= GINTEN_SESIE | GINTEN_OTGIE; |
||||
|
#endif /* VBUS_SENSING_ENABLED */ |
||||
|
|
||||
|
if (1U == udev->bp.lpm_enable) |
||||
|
{ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_LPMIE; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief active the USB endpoint0 transaction |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB endpoint0 transaction |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc) |
||||
|
{ |
||||
|
__IO uint32_t *reg_addr = NULL; |
||||
|
|
||||
|
uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES; |
||||
|
|
||||
|
/* get the endpoint number */ |
||||
|
uint8_t ep_num = transc->ep_addr.num; |
||||
|
|
||||
|
if (ep_num) |
||||
|
{ |
||||
|
/* not endpoint 0 */ |
||||
|
return USB_FAIL; |
||||
|
} |
||||
|
|
||||
|
if (transc->ep_addr.dir) |
||||
|
{ |
||||
|
reg_addr = &udev->regs.er_in[0]->DIEPCTL; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
reg_addr = &udev->regs.er_out[0]->DOEPCTL; |
||||
|
} |
||||
|
|
||||
|
/* endpoint 0 is activated after USB clock is enabled */ |
||||
|
*reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM); |
||||
|
|
||||
|
/* set endpoint 0 maximum packet length */ |
||||
|
*reg_addr |= EP0_MAXLEN[enum_speed]; |
||||
|
|
||||
|
/* activate endpoint */ |
||||
|
*reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT; |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief active the USB transaction |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB transaction |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
usb_status usb_ep_active(usb_core_driver *udev, uint8_t ep_addr, uint8_t ep_mps, uint8_t ep_attr) |
||||
|
{ |
||||
|
__IO uint32_t *reg_addr = NULL; |
||||
|
uint32_t epinten = 0U; |
||||
|
uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES; |
||||
|
|
||||
|
usb_transc *transc = NULL; |
||||
|
|
||||
|
/* get the endpoint number */ |
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
/* enable endpoint interrupt number */ |
||||
|
if (EP_DIR(ep_addr)) |
||||
|
{ |
||||
|
reg_addr = &udev->regs.er_in[ep_num]->DIEPCTL; |
||||
|
epinten = 1U << ep_num; |
||||
|
transc = &udev->dev.transc_in[ep_num]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
reg_addr = &udev->regs.er_out[ep_num]->DOEPCTL; |
||||
|
epinten = 1U << (16U + ep_num); |
||||
|
transc = &udev->dev.transc_out[ep_num]; |
||||
|
} |
||||
|
|
||||
|
*transc = (usb_transc){ 0 }; |
||||
|
|
||||
|
transc->max_len = ep_mps; |
||||
|
transc->ep_type = ep_attr & USB_EPTYPE_MASK; |
||||
|
|
||||
|
/* if the endpoint is not active, need change the endpoint control register */ |
||||
|
if (!(*reg_addr & DEPCTL_EPACT)) |
||||
|
{ |
||||
|
*reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM); |
||||
|
|
||||
|
/* set endpoint maximum packet length */ |
||||
|
if (0U == ep_num) |
||||
|
{ |
||||
|
*reg_addr |= EP0_MAXLEN[enum_speed]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
*reg_addr |= transc->max_len; |
||||
|
} |
||||
|
|
||||
|
/* activate endpoint */ |
||||
|
*reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT; |
||||
|
} |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
if (1U == ep_num) |
||||
|
{ |
||||
|
udev->regs.dr->DEP1INTEN |= epinten; |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
/* enable the interrupts for this endpoint */ |
||||
|
udev->regs.dr->DAEPINTEN |= epinten; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief deactivate the USB transaction |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB transaction |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
usb_status usb_ep_deactivate(usb_core_driver *udev, uint8_t ep_addr) |
||||
|
{ |
||||
|
uint32_t epinten = 0U; |
||||
|
|
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
/* disable endpoint interrupt number */ |
||||
|
if (EP_DIR(ep_addr)) |
||||
|
{ |
||||
|
epinten = 1U << ep_num; |
||||
|
|
||||
|
udev->regs.er_in[ep_num]->DIEPCTL &= ~DEPCTL_EPACT; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
epinten = 1U << (ep_num + 16U); |
||||
|
|
||||
|
udev->regs.er_out[ep_num]->DOEPCTL &= ~DEPCTL_EPACT; |
||||
|
} |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
if (1U == ep_num) |
||||
|
{ |
||||
|
udev->regs.dr->DEP1INTEN &= ~epinten; |
||||
|
} |
||||
|
else |
||||
|
#endif |
||||
|
{ |
||||
|
/* disable the interrupts for this endpoint */ |
||||
|
udev->regs.dr->DAEPINTEN &= ~epinten; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB transaction to start IN transfer |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB IN transaction |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_ep_inxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count) |
||||
|
{ |
||||
|
usb_status status = USB_OK; |
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
__IO uint32_t epctl = udev->regs.er_in[ep_num]->DIEPCTL; |
||||
|
__IO uint32_t eplen = udev->regs.er_in[ep_num]->DIEPLEN; |
||||
|
|
||||
|
usb_transc *transc = &udev->dev.transc_in[ep_num]; |
||||
|
|
||||
|
eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT); |
||||
|
|
||||
|
transc->xfer_len = count; |
||||
|
transc->xfer_buf = buf; |
||||
|
transc->xfer_count = 0U; |
||||
|
|
||||
|
/* zero length packet or endpoint 0 */ |
||||
|
if (0U == count) |
||||
|
{ |
||||
|
/* set transfer packet count to 1 */ |
||||
|
eplen |= 1U << 19; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* set transfer packet count */ |
||||
|
if (0U == ep_num) |
||||
|
{ |
||||
|
transc->xfer_len = USB_MIN(count, transc->max_len); |
||||
|
|
||||
|
eplen |= 1U << 19; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
eplen |= ((count - 1 + transc->max_len) / transc->max_len) << 19; |
||||
|
} |
||||
|
|
||||
|
/* set endpoint transfer length */ |
||||
|
eplen |= count; |
||||
|
|
||||
|
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) |
||||
|
{ |
||||
|
eplen |= DIEPLEN_MCNT & (1U << 29); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
udev->regs.er_in[ep_num]->DIEPLEN = eplen; |
||||
|
|
||||
|
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) |
||||
|
{ |
||||
|
if (((udev->regs.dr->DSTAT & DSTAT_FNRSOF) >> 8) & 0x01U) |
||||
|
{ |
||||
|
epctl |= DEPCTL_SEVNFRM; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
epctl |= DEPCTL_SODDFRM; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->regs.er_in[ep_num]->DIEPDMAADDR = transc->dma_addr; |
||||
|
} |
||||
|
|
||||
|
/* enable the endpoint and clear the NAK */ |
||||
|
epctl |= DEPCTL_CNAK | DEPCTL_EPEN; |
||||
|
|
||||
|
udev->regs.er_in[ep_num]->DIEPCTL = epctl; |
||||
|
|
||||
|
if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
if ((uint8_t)USB_EPTYPE_ISOC != transc->ep_type) |
||||
|
{ |
||||
|
/* enable the TX FIFO empty interrupt for this endpoint */ |
||||
|
if (count > 0U) |
||||
|
{ |
||||
|
udev->regs.dr->DIEPFEINTEN |= 1U << ep_num; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
(void)usb_txfifo_write(&udev->regs, transc->xfer_buf, ep_num, (uint16_t)transc->xfer_len); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB transaction to start OUT transfer |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB OUT transaction |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
usb_status usb_ep_outxfer(usb_core_driver *udev, uint8_t ep_addr, uint8_t *buf, uint16_t count) |
||||
|
{ |
||||
|
usb_status status = USB_OK; |
||||
|
|
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
uint32_t epctl = udev->regs.er_out[ep_num]->DOEPCTL; |
||||
|
uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN; |
||||
|
|
||||
|
usb_transc *transc = &udev->dev.transc_out[ep_num]; |
||||
|
|
||||
|
transc->xfer_buf = buf; |
||||
|
transc->xfer_len = count; |
||||
|
|
||||
|
eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT); |
||||
|
|
||||
|
/* zero length packet or endpoint 0 */ |
||||
|
if ((0U == count) || (0U == ep_num)) |
||||
|
{ |
||||
|
/* set the transfer length to max packet size */ |
||||
|
eplen |= transc->max_len; |
||||
|
|
||||
|
/* set the transfer packet count to 1 */ |
||||
|
eplen |= 1U << 19; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* configure the transfer size and packet count as follows:
|
||||
|
* pktcnt = N |
||||
|
* xfersize = N * maxpacket |
||||
|
*/ |
||||
|
uint32_t packet_count = (count + transc->max_len - 1) / transc->max_len; |
||||
|
|
||||
|
eplen |= packet_count << 19; |
||||
|
eplen |= packet_count * transc->max_len; |
||||
|
} |
||||
|
|
||||
|
udev->regs.er_out[ep_num]->DOEPLEN = eplen; |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->regs.er_out[ep_num]->DOEPDMAADDR = transc->dma_addr; |
||||
|
} |
||||
|
|
||||
|
if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) |
||||
|
{ |
||||
|
if (transc->frame_num) |
||||
|
{ |
||||
|
epctl |= DEPCTL_SD1PID; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
epctl |= DEPCTL_SD0PID; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* enable the endpoint and clear the NAK */ |
||||
|
epctl |= DEPCTL_EPEN | DEPCTL_CNAK; |
||||
|
|
||||
|
udev->regs.er_out[ep_num]->DOEPCTL = epctl; |
||||
|
|
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief set the USB transaction STALL status |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB transaction |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
usb_status usb_ep_stall(usb_core_driver *udev, uint8_t ep_addr) |
||||
|
{ |
||||
|
__IO uint32_t *reg_addr = NULL; |
||||
|
|
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
if (EP_DIR(ep_addr)) |
||||
|
{ |
||||
|
reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL); |
||||
|
|
||||
|
/* set the endpoint disable bit */ |
||||
|
if (*reg_addr & DEPCTL_EPEN) |
||||
|
{ |
||||
|
*reg_addr |= DEPCTL_EPD; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* set the endpoint STALL bit */ |
||||
|
reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL); |
||||
|
} |
||||
|
|
||||
|
/* set the endpoint STALL bit */ |
||||
|
*reg_addr |= DEPCTL_STALL; |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief clear the USB transaction STALL status |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] transc: the USB transaction |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_ep_clrstall(usb_core_driver *udev, uint8_t ep_addr) |
||||
|
{ |
||||
|
__IO uint32_t *reg_addr = NULL; |
||||
|
uint32_t ep_type = 0U; |
||||
|
|
||||
|
uint8_t ep_num = EP_ID(ep_addr); |
||||
|
|
||||
|
if (EP_DIR(ep_addr)) |
||||
|
{ |
||||
|
reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL); |
||||
|
} |
||||
|
|
||||
|
/* clear the endpoint STALL bit */ |
||||
|
*reg_addr &= ~DEPCTL_STALL; |
||||
|
|
||||
|
ep_type = (DEPCTL_EPTYPE & *reg_addr) >> 18; |
||||
|
|
||||
|
/* reset data PID of the periodic endpoints */ |
||||
|
if (((uint8_t)USB_EPTYPE_INTR == ep_type) || ((uint8_t)USB_EPTYPE_BULK == ep_type)) |
||||
|
{ |
||||
|
*reg_addr |= DEPCTL_SD0PID; |
||||
|
} |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief read device IN endpoint interrupt flag register |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] ep_num: endpoint number |
||||
|
\param[out] none |
||||
|
\retval interrupt value |
||||
|
*/ |
||||
|
uint32_t usb_iepintr_read(usb_core_driver *udev, uint8_t ep_num) |
||||
|
{ |
||||
|
__IO uint32_t value = 0U; |
||||
|
uint32_t fifoemptymask, commonintmask; |
||||
|
|
||||
|
commonintmask = udev->regs.dr->DIEPINTEN; |
||||
|
fifoemptymask = udev->regs.dr->DIEPFEINTEN; |
||||
|
|
||||
|
/* check FIFO empty interrupt enable bit */ |
||||
|
commonintmask |= ((fifoemptymask >> ep_num) & 0x1U) << 7; |
||||
|
|
||||
|
value = udev->regs.er_in[ep_num]->DIEPINTF & commonintmask; |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configures OUT endpoint 0 to receive SETUP packets |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_ctlep_startout(usb_core_driver *udev) |
||||
|
{ |
||||
|
/* set OUT endpoint 0 receive length to 24 bytes, 1 packet and 3 SETUP packets */ |
||||
|
udev->regs.er_out[0]->DOEPLEN = DOEP0_TLEN(8U * 3U) | DOEP0_PCNT(1U) | DOEP0_STPCNT(3U); |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->regs.er_out[0]->DOEPDMAADDR = (uint32_t)&udev->dev.control.req; |
||||
|
|
||||
|
/* endpoint enable */ |
||||
|
udev->regs.er_out[0]->DOEPCTL |= DEPCTL_EPACT | DEPCTL_EPEN; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief active remote wakeup signaling |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_rwkup_active(usb_core_driver *udev) |
||||
|
{ |
||||
|
if (udev->dev.pm.dev_remote_wakeup) |
||||
|
{ |
||||
|
if (udev->regs.dr->DSTAT & DSTAT_SPST) |
||||
|
{ |
||||
|
if (udev->bp.low_power) |
||||
|
{ |
||||
|
/* ungate USB core clock */ |
||||
|
*udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK); |
||||
|
} |
||||
|
|
||||
|
/* active remote wakeup signaling */ |
||||
|
udev->regs.dr->DCTL |= DCTL_RWKUP; |
||||
|
|
||||
|
usb_mdelay(5U); |
||||
|
|
||||
|
udev->regs.dr->DCTL &= ~DCTL_RWKUP; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB device suspend |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_dev_suspend(usb_core_driver *udev) |
||||
|
{ |
||||
|
__IO uint32_t devstat = udev->regs.dr->DSTAT; |
||||
|
|
||||
|
if ((devstat & DSTAT_SPST) && (udev->bp.low_power)) |
||||
|
{ |
||||
|
/* switch-off the USB clocks */ |
||||
|
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SHCLK; |
||||
|
|
||||
|
/* enter DEEP_SLEEP mode with LDO in low power mode */ |
||||
|
pmu_to_deepsleepmode(WFI_CMD); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief stop the device and clean up FIFOs |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_dev_stop(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t i; |
||||
|
|
||||
|
udev->dev.cur_status = 1U; |
||||
|
|
||||
|
/* clear all interrupt flag and enable bits */ |
||||
|
for (i = 0U; i < udev->bp.num_ep; i++) |
||||
|
{ |
||||
|
udev->regs.er_in[i]->DIEPINTF = 0xFFU; |
||||
|
udev->regs.er_out[i]->DOEPINTF = 0xFFU; |
||||
|
} |
||||
|
|
||||
|
udev->regs.dr->DIEPINTEN = 0U; |
||||
|
udev->regs.dr->DOEPINTEN = 0U; |
||||
|
udev->regs.dr->DAEPINTEN = 0U; |
||||
|
udev->regs.dr->DAEPINT = 0xFFFFFFFFU; |
||||
|
|
||||
|
/* flush the FIFO */ |
||||
|
(void)usb_rxfifo_flush(&udev->regs); |
||||
|
(void)usb_txfifo_flush(&udev->regs, 0x10U); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief usb battery charging detect operation |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval bcd type |
||||
|
*/ |
||||
|
bcd_type usbd_bcd_detect(usb_core_driver *udev) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG |= GCCFG_DCDEN; |
||||
|
|
||||
|
usb_mdelay(1000U); |
||||
|
|
||||
|
if (0U == (udev->regs.gr->GCCFG & GCCFG_DCDF)) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_DCDEN; |
||||
|
|
||||
|
return BCD_ERROR; |
||||
|
} |
||||
|
|
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_DCDEN; |
||||
|
usb_mdelay(20U); |
||||
|
udev->regs.gr->GCCFG |= GCCFG_PEMEN; |
||||
|
usb_mdelay(50U); |
||||
|
|
||||
|
if (udev->regs.gr->GCCFG & GCCFG_PDF) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; |
||||
|
usb_mdelay(20U); |
||||
|
udev->regs.gr->GCCFG |= GCCFG_SDMEN; |
||||
|
usb_mdelay(50U); |
||||
|
|
||||
|
if (udev->regs.gr->GCCFG & GCCFG_SDF) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_SDMEN; |
||||
|
usb_mdelay(20U); |
||||
|
|
||||
|
return BCD_DCP; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_SDMEN; |
||||
|
usb_mdelay(20U); |
||||
|
|
||||
|
return BCD_CDP; |
||||
|
} |
||||
|
} |
||||
|
else if (udev->regs.gr->GCCFG & GCCFG_PS2F) |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; |
||||
|
usb_mdelay(20U); |
||||
|
|
||||
|
return BCD_PS2; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; |
||||
|
usb_mdelay(20U); |
||||
|
|
||||
|
return BCD_SDP; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */ |
||||
@ -0,0 +1,448 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usb_hw.h" |
||||
|
#include "drv_usb_host.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
const uint32_t PIPE_DPID[2] = { |
||||
|
PIPE_DPID_DATA0, |
||||
|
PIPE_DPID_DATA1 |
||||
|
}; |
||||
|
|
||||
|
/*!
|
||||
|
\brief initializes USB core for host mode |
||||
|
\param[in] udev: pointer to selected USB host |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_host_init(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t i = 0U, inten = 0U; |
||||
|
|
||||
|
uint32_t nptxfifolen = 0U; |
||||
|
uint32_t ptxfifolen = 0U; |
||||
|
|
||||
|
/* restart the PHY Clock */ |
||||
|
*udev->regs.PWRCLKCTL = 0U; |
||||
|
|
||||
|
/* support HS, FS and LS */ |
||||
|
udev->regs.hr->HCTL &= ~HCTL_SPDFSLS; |
||||
|
|
||||
|
/* set RX FIFO size */ |
||||
|
udev->regs.gr->GRFLEN = USB_RX_FIFO_SIZE; |
||||
|
|
||||
|
/* set non-periodic TX FIFO size and address */ |
||||
|
nptxfifolen |= USB_RX_FIFO_SIZE; |
||||
|
nptxfifolen |= USB_HTX_NPFIFO_SIZE << 16; |
||||
|
udev->regs.gr->DIEP0TFLEN_HNPTFLEN = nptxfifolen; |
||||
|
|
||||
|
/* set periodic TX FIFO size and address */ |
||||
|
ptxfifolen |= USB_RX_FIFO_SIZE + USB_HTX_PFIFO_SIZE; |
||||
|
ptxfifolen |= USB_HTX_PFIFO_SIZE << 16; |
||||
|
udev->regs.gr->HPTFLEN = ptxfifolen; |
||||
|
|
||||
|
#ifdef USE_OTG_MODE |
||||
|
/* clear host set HNP enable in the usb_otg control register */ |
||||
|
udev->regs.gr->GOTGCS &= ~GOTGCS_HHNPEN; |
||||
|
#endif /* USE_OTG_MODE */ |
||||
|
|
||||
|
/* make sure the FIFOs are flushed */ |
||||
|
|
||||
|
/* flush all TX FIFOs in device or host mode */ |
||||
|
usb_txfifo_flush(&udev->regs, 0x10U); |
||||
|
|
||||
|
/* flush the entire RX FIFO */ |
||||
|
usb_rxfifo_flush(&udev->regs); |
||||
|
|
||||
|
/* disable all interrupts */ |
||||
|
udev->regs.gr->GINTEN = 0U; |
||||
|
|
||||
|
/* clear any pending USB OTG interrupts */ |
||||
|
udev->regs.gr->GOTGINTF = 0xFFFFFFFFU; |
||||
|
|
||||
|
/* enable the USB wakeup and suspend interrupts */ |
||||
|
udev->regs.gr->GINTF = 0xBFFFFFFFU; |
||||
|
|
||||
|
/* clear all pending host channel interrupts */ |
||||
|
for (i = 0U; i < udev->bp.num_pipe; i++) |
||||
|
{ |
||||
|
udev->regs.pr[i]->HCHINTF = 0xFFFFFFFFU; |
||||
|
udev->regs.pr[i]->HCHINTEN = 0U; |
||||
|
} |
||||
|
|
||||
|
#ifndef USE_OTG_MODE |
||||
|
usb_portvbus_switch(udev, 1U); |
||||
|
#endif /* USE_OTG_MODE */ |
||||
|
|
||||
|
udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE; |
||||
|
|
||||
|
/* enable host_mode-related interrupts */ |
||||
|
if (USB_USE_FIFO == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
inten = GINTEN_RXFNEIE; |
||||
|
} |
||||
|
|
||||
|
/* configure USBHS interrupts */ |
||||
|
inten |= GINTEN_HPIE | GINTEN_HCIE | GINTEN_ISOINCIE; |
||||
|
udev->regs.gr->GINTEN |= inten; |
||||
|
|
||||
|
inten = GINTEN_DISCIE | GINTEN_SOFIE; |
||||
|
udev->regs.gr->GINTEN &= ~inten; |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief control the VBUS to power |
||||
|
\param[in] udev: pointer to selected USB host |
||||
|
\param[in] state: VBUS state |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_portvbus_switch(usb_core_driver *udev, uint8_t state) |
||||
|
{ |
||||
|
uint32_t port = 0U; |
||||
|
|
||||
|
/* enable or disable the external charge pump */ |
||||
|
usb_vbus_drive(state); |
||||
|
|
||||
|
/* turn on the host port power. */ |
||||
|
port = usb_port_read(udev); |
||||
|
|
||||
|
if ((!(port & HPCS_PP)) && (1U == state)) |
||||
|
{ |
||||
|
port |= HPCS_PP; |
||||
|
} |
||||
|
|
||||
|
if ((port & HPCS_PP) && (0U == state)) |
||||
|
{ |
||||
|
port &= ~HPCS_PP; |
||||
|
} |
||||
|
|
||||
|
*udev->regs.HPCS = port; |
||||
|
|
||||
|
usb_mdelay(200U); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief reset host port |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint32_t usb_port_reset(usb_core_driver *udev) |
||||
|
{ |
||||
|
__IO uint32_t port = usb_port_read(udev); |
||||
|
|
||||
|
*udev->regs.HPCS = port | HPCS_PRST; |
||||
|
|
||||
|
usb_mdelay(20U); /* see note */ |
||||
|
|
||||
|
*udev->regs.HPCS = port & ~HPCS_PRST; |
||||
|
|
||||
|
usb_mdelay(20U); |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief initialize host pipe |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] pipe_num: host pipe number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_pipe_init(usb_core_driver *udev, uint8_t pipe_num) |
||||
|
{ |
||||
|
usb_status status = USB_OK; |
||||
|
|
||||
|
__IO uint32_t pp_ctl = 0U; |
||||
|
__IO uint32_t pp_inten = HCHINTEN_TFIE; |
||||
|
|
||||
|
usb_pipe *pp = &udev->host.pipe[pipe_num]; |
||||
|
|
||||
|
/* clear old interrupt conditions for this host channel */ |
||||
|
udev->regs.pr[pipe_num]->HCHINTF = 0xFFFFFFFFU; |
||||
|
|
||||
|
if (USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
pp_inten |= HCHINTEN_DMAERIE; |
||||
|
} |
||||
|
|
||||
|
if (pp->ep.dir) |
||||
|
{ |
||||
|
pp_inten |= HCHINTEN_BBERIE; |
||||
|
} |
||||
|
|
||||
|
/* enable channel interrupts required for this transfer */ |
||||
|
switch (pp->ep.type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
case USB_EPTYPE_BULK: |
||||
|
pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE | HCHINTEN_NAKIE; |
||||
|
|
||||
|
if (!pp->ep.dir) |
||||
|
{ |
||||
|
if (PORT_SPEED_HIGH == pp->dev_speed) |
||||
|
{ |
||||
|
pp_inten |= HCHINTEN_NYETIE; |
||||
|
pp_inten |= HCHINTEN_ACKIE; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_ISOC: |
||||
|
pp_inten |= HCHINTEN_REQOVRIE | HCHINTEN_ACKIE; |
||||
|
|
||||
|
if (pp->ep.dir) |
||||
|
{ |
||||
|
pp_inten |= HCHINTEN_USBERIE; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHINTEN = pp_inten; |
||||
|
|
||||
|
/* enable the top level host channel interrupt */ |
||||
|
udev->regs.hr->HACHINTEN |= 1U << pipe_num; |
||||
|
|
||||
|
/* make sure host channel interrupts are enabled */ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_HCIE; |
||||
|
|
||||
|
/* program the host channel control register */ |
||||
|
pp_ctl |= PIPE_CTL_DAR(pp->dev_addr); |
||||
|
pp_ctl |= PIPE_CTL_EPNUM(pp->ep.num); |
||||
|
pp_ctl |= PIPE_CTL_EPDIR(pp->ep.dir); |
||||
|
pp_ctl |= PIPE_CTL_EPTYPE(pp->ep.type); |
||||
|
pp_ctl |= PIPE_CTL_LSD(PORT_SPEED_LOW == pp->dev_speed); |
||||
|
|
||||
|
pp_ctl |= pp->ep.mps; |
||||
|
pp_ctl |= ((uint32_t)(USB_EPTYPE_INTR == pp->ep.type) << 29) & HCHCTL_ODDFRM; |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; |
||||
|
|
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief prepare host channel for transferring packets |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] pipe_num: host pipe number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_pipe_xfer(usb_core_driver *udev, uint8_t pipe_num) |
||||
|
{ |
||||
|
usb_status status = USB_OK; |
||||
|
|
||||
|
uint16_t dword_len = 0U; |
||||
|
uint16_t packet_count = 0U; |
||||
|
|
||||
|
__IO uint32_t pp_ctl = 0U; |
||||
|
|
||||
|
usb_pipe *pp = &udev->host.pipe[pipe_num]; |
||||
|
|
||||
|
uint16_t max_packet_len = pp->ep.mps; |
||||
|
|
||||
|
/* compute the expected number of packets associated to the transfer */ |
||||
|
if (pp->xfer_len > 0U) |
||||
|
{ |
||||
|
packet_count = (uint16_t)((pp->xfer_len + max_packet_len - 1U) / max_packet_len); |
||||
|
|
||||
|
if (packet_count > HC_MAX_PACKET_COUNT) |
||||
|
{ |
||||
|
packet_count = HC_MAX_PACKET_COUNT; |
||||
|
pp->xfer_len = (uint16_t)(packet_count * max_packet_len); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
packet_count = 1U; |
||||
|
} |
||||
|
|
||||
|
if (pp->ep.dir) |
||||
|
{ |
||||
|
pp->xfer_len = (uint16_t)(packet_count * max_packet_len); |
||||
|
} |
||||
|
|
||||
|
/* initialize the host channel transfer information */ |
||||
|
udev->regs.pr[pipe_num]->HCHLEN = pp->xfer_len | pp->DPID | PIPE_XFER_PCNT(packet_count); |
||||
|
|
||||
|
if (USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->regs.pr[pipe_num]->HCHDMAADDR = (unsigned int)pp->xfer_buf; |
||||
|
} |
||||
|
|
||||
|
pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; |
||||
|
|
||||
|
if (usb_frame_even(udev)) |
||||
|
{ |
||||
|
pp_ctl |= HCHCTL_ODDFRM; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
pp_ctl &= ~HCHCTL_ODDFRM; |
||||
|
} |
||||
|
|
||||
|
/* set host channel enabled */ |
||||
|
pp_ctl |= HCHCTL_CEN; |
||||
|
pp_ctl &= ~HCHCTL_CDIS; |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; |
||||
|
|
||||
|
if (USB_USE_FIFO == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
if ((0U == pp->ep.dir) && (pp->xfer_len > 0U)) |
||||
|
{ |
||||
|
switch (pp->ep.type) |
||||
|
{ |
||||
|
/* non-periodic transfer */ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
case USB_EPTYPE_BULK: |
||||
|
dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U); |
||||
|
|
||||
|
/* check if there is enough space in FIFO space */ |
||||
|
if (dword_len > (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) |
||||
|
{ |
||||
|
/* need to process data in nptxfempty interrupt */ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_NPTXFEIE; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
/* periodic transfer */ |
||||
|
case USB_EPTYPE_INTR: |
||||
|
case USB_EPTYPE_ISOC: |
||||
|
dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U); |
||||
|
|
||||
|
/* check if there is enough space in FIFO space */ |
||||
|
if (dword_len > (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS)) |
||||
|
{ |
||||
|
/* need to process data in ptxfempty interrupt */ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_PTXFEIE; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* write packet into the TX FIFO */ |
||||
|
usb_txfifo_write(&udev->regs, pp->xfer_buf, pipe_num, (uint16_t)pp->xfer_len); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief halt pipe |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] pipe_num: host pipe number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_pipe_halt(usb_core_driver *udev, uint8_t pipe_num) |
||||
|
{ |
||||
|
__IO uint32_t pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; |
||||
|
|
||||
|
uint8_t ep_type = (uint8_t)((pp_ctl & HCHCTL_EPTYPE) >> 18U); |
||||
|
|
||||
|
pp_ctl |= HCHCTL_CEN | HCHCTL_CDIS; |
||||
|
|
||||
|
switch (ep_type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
case USB_EPTYPE_BULK: |
||||
|
if (0U == (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) |
||||
|
{ |
||||
|
pp_ctl &= ~HCHCTL_CEN; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
case USB_EPTYPE_ISOC: |
||||
|
if (0U == (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS)) |
||||
|
{ |
||||
|
pp_ctl &= ~HCHCTL_CEN; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure host pipe to do ping operation |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[in] pipe_num: host pipe number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usb_status usb_pipe_ping(usb_core_driver *udev, uint8_t pipe_num) |
||||
|
{ |
||||
|
uint32_t pp_ctl = 0U; |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHLEN = HCHLEN_PING; |
||||
|
|
||||
|
pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; |
||||
|
|
||||
|
pp_ctl |= HCHCTL_CEN; |
||||
|
pp_ctl &= ~HCHCTL_CDIS; |
||||
|
|
||||
|
udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; |
||||
|
|
||||
|
return USB_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief stop the USB host and clean up FIFO |
||||
|
\param[in] udev: pointer to USB device |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_host_stop(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t i; |
||||
|
__IO uint32_t pp_ctl = 0U; |
||||
|
|
||||
|
udev->regs.hr->HACHINTEN = 0x0U; |
||||
|
udev->regs.hr->HACHINT = 0xFFFFFFFFU; |
||||
|
|
||||
|
/* flush out any leftover queued requests. */ |
||||
|
for (i = 0U; i < udev->bp.num_pipe; i++) |
||||
|
{ |
||||
|
pp_ctl = udev->regs.pr[i]->HCHCTL; |
||||
|
|
||||
|
pp_ctl &= ~(HCHCTL_CEN | HCHCTL_EPDIR); |
||||
|
pp_ctl |= HCHCTL_CDIS; |
||||
|
|
||||
|
udev->regs.pr[i]->HCHCTL = pp_ctl; |
||||
|
} |
||||
|
|
||||
|
/* flush the FIFO */ |
||||
|
usb_rxfifo_flush(&udev->regs); |
||||
|
usb_txfifo_flush(&udev->regs, 0x10U); |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
@ -0,0 +1,703 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usbd_int.h" |
||||
|
#include "drv_otghs_dev.h" |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_DEVICE) |
||||
|
|
||||
|
static const uint8_t USB_SPEED[4] = { |
||||
|
[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_HIGH, |
||||
|
[DSTAT_EM_FS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_FULL, |
||||
|
[DSTAT_EM_FS_PHY_48MHZ] = (uint8_t)USB_SPEED_FULL, |
||||
|
[DSTAT_EM_LS_PHY_6MHZ] = (uint8_t)USB_SPEED_LOW |
||||
|
}; |
||||
|
|
||||
|
/* local function prototypes ('static') */ |
||||
|
static uint32_t usbd_int_epout(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_epin(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_rxfifo(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_reset(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_enumfinish(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_suspend(usb_core_driver *udev); |
||||
|
static uint32_t usbd_int_wakeup(usb_core_driver *udev); |
||||
|
|
||||
|
#if (1U == LPM_ENABLED) |
||||
|
static uint32_t usbd_int_lpm(usb_core_driver *udev, usb_lpm_type active_type); |
||||
|
#endif /* LPM_ENABLED */ |
||||
|
|
||||
|
static uint32_t usbd_emptytxfifo_write(usb_core_driver *udev, uint32_t ep_num); |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB device-mode interrupts global service routine handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usbd_isr(usb_core_driver *udev) |
||||
|
{ |
||||
|
if (HOST_MODE != (udev->regs.gr->GINTF & GINTF_COPM)) |
||||
|
{ |
||||
|
uint32_t intr = udev->regs.gr->GINTF; |
||||
|
intr &= udev->regs.gr->GINTEN; |
||||
|
|
||||
|
/* there are no interrupts, avoid spurious interrupt */ |
||||
|
if (!intr) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* OUT endpoints interrupts */ |
||||
|
if (intr & GINTF_OEPIF) |
||||
|
{ |
||||
|
(void)usbd_int_epout(udev); |
||||
|
} |
||||
|
|
||||
|
/* IN endpoints interrupts */ |
||||
|
if (intr & GINTF_IEPIF) |
||||
|
{ |
||||
|
(void)usbd_int_epin(udev); |
||||
|
} |
||||
|
|
||||
|
/* suspend interrupt */ |
||||
|
if (intr & GINTF_SP) |
||||
|
{ |
||||
|
(void)usbd_int_suspend(udev); |
||||
|
} |
||||
|
|
||||
|
/* wakeup interrupt */ |
||||
|
if (intr & GINTF_WKUPIF) |
||||
|
{ |
||||
|
(void)usbd_int_wakeup(udev); |
||||
|
} |
||||
|
|
||||
|
/* start of frame interrupt */ |
||||
|
if (intr & GINTF_SOF) |
||||
|
{ |
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_SOF; |
||||
|
} |
||||
|
|
||||
|
/* receive FIFO not empty interrupt */ |
||||
|
if (intr & GINTF_RXFNEIF) |
||||
|
{ |
||||
|
(void)usbd_int_rxfifo(udev); |
||||
|
} |
||||
|
|
||||
|
/* USB reset interrupt */ |
||||
|
if (intr & GINTF_RST) |
||||
|
{ |
||||
|
(void)usbd_int_reset(udev); |
||||
|
} |
||||
|
|
||||
|
/* enumeration has been done interrupt */ |
||||
|
if (intr & GINTF_ENUMFIF) |
||||
|
{ |
||||
|
(void)usbd_int_enumfinish(udev); |
||||
|
} |
||||
|
|
||||
|
/* incomplete synchronization IN transfer interrupt*/ |
||||
|
if (intr & GINTF_ISOINCIF) |
||||
|
{ |
||||
|
if (NULL != udev->dev.class_core->incomplete_isoc_in) |
||||
|
{ |
||||
|
(void)udev->dev.class_core->incomplete_isoc_in(udev); |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_ISOINCIF; |
||||
|
} |
||||
|
|
||||
|
/* incomplete synchronization OUT transfer interrupt*/ |
||||
|
if (intr & GINTF_ISOONCIF) |
||||
|
{ |
||||
|
if (NULL != udev->dev.class_core->incomplete_isoc_out) |
||||
|
{ |
||||
|
(void)udev->dev.class_core->incomplete_isoc_out(udev); |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_ISOONCIF; |
||||
|
} |
||||
|
|
||||
|
#if (1U == LPM_ENABLED) |
||||
|
if (intr & GINTF_LPMIF) |
||||
|
{ |
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_LPMIF; |
||||
|
|
||||
|
udev->dev.pm.BESL = (udev->regs.gr->GLPMCFG & GLPMCFG_BESL) >> 2U; |
||||
|
udev->dev.pm.dev_remote_wakeup = (udev->regs.gr->GLPMCFG & GLPMCFG_REW) >> 6U; |
||||
|
|
||||
|
if (LPM_L0 == udev->dev.pm.lpm_state) |
||||
|
{ |
||||
|
udev->dev.pm.lpm_state = LPM_L1; |
||||
|
usbd_int_lpm(udev, LPM_L1_ACTIVE); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->dev.pm.lpm_state = LPM_L0; |
||||
|
usbd_int_lpm(udev, LPM_L0_ACTIVE); |
||||
|
} |
||||
|
} |
||||
|
#endif /* LPM_ENABLED */ |
||||
|
|
||||
|
#ifdef VBUS_SENSING_ENABLED |
||||
|
|
||||
|
/* session request interrupt */ |
||||
|
if (intr & GINTF_SESIF) |
||||
|
{ |
||||
|
udev->regs.gr->GINTF = GINTF_SESIF; |
||||
|
} |
||||
|
|
||||
|
/* OTG mode interrupt */ |
||||
|
if (intr & GINTF_OTGIF) |
||||
|
{ |
||||
|
if (udev->regs.gr->GOTGINTF & GOTGINTF_SESEND) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/* clear OTG interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_OTGIF; |
||||
|
} |
||||
|
#endif /* VBUS_SENSING_ENABLED */ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief indicates that an OUT endpoint has a pending interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_epout(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t epintnum = 0U; |
||||
|
uint8_t ep_num = 0U; |
||||
|
|
||||
|
for (epintnum = usb_oepintnum_read(udev); epintnum; epintnum >>= 1) |
||||
|
{ |
||||
|
if (epintnum & 0x01U) |
||||
|
{ |
||||
|
__IO uint32_t oepintr = usb_oepintr_read(udev, ep_num); |
||||
|
|
||||
|
/* transfer complete interrupt */ |
||||
|
if (oepintr & DOEPINTF_TF) |
||||
|
{ |
||||
|
/* clear the bit in DOEPINTF for this interrupt */ |
||||
|
udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_TF; |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
__IO uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN; |
||||
|
|
||||
|
udev->dev.transc_out[ep_num].xfer_count = udev->dev.transc_out[ep_num].max_len - |
||||
|
(eplen & DEPLEN_TLEN); |
||||
|
} |
||||
|
|
||||
|
/* inform upper layer: data ready */ |
||||
|
usbd_data_out_stage_callback(ep_num, udev->dev.transc_out[ep_num].xfer_len); |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_OUT == udev->dev.control.ctl_state)) |
||||
|
{ |
||||
|
usb_ctlep_startout(udev); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* SETUP phase finished interrupt (control endpoints) */ |
||||
|
if (oepintr & DOEPINTF_STPF) |
||||
|
{ |
||||
|
/* inform the upper layer that a SETUP packet is available */ |
||||
|
usbd_setup_stage_callback((struct urequest *)&udev->dev.control.req); |
||||
|
|
||||
|
udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_STPF; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ep_num++; |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief indicates that an IN endpoint has a pending interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_epin(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t epintnum = 0U; |
||||
|
uint8_t ep_num = 0U; |
||||
|
|
||||
|
for (epintnum = usb_iepintnum_read(udev); epintnum; epintnum >>= 1) |
||||
|
{ |
||||
|
if (epintnum & 0x1U) |
||||
|
{ |
||||
|
__IO uint32_t iepintr = usb_iepintr_read(udev, ep_num); |
||||
|
|
||||
|
if (iepintr & DIEPINTF_TF) |
||||
|
{ |
||||
|
udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TF; |
||||
|
|
||||
|
/* data transmission is completed */ |
||||
|
usbd_data_in_stage_callback(ep_num, udev->dev.transc_in[ep_num].xfer_len); |
||||
|
|
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_IN == udev->dev.control.ctl_state)) |
||||
|
{ |
||||
|
usb_ctlep_startout(udev); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (iepintr & DIEPINTF_TXFE) |
||||
|
{ |
||||
|
usbd_emptytxfifo_write(udev, (uint32_t)ep_num); |
||||
|
|
||||
|
udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TXFE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ep_num++; |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the RX status queue level interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_rxfifo(usb_core_driver *udev) |
||||
|
{ |
||||
|
usb_transc *transc = NULL; |
||||
|
|
||||
|
uint8_t data_PID = 0U; |
||||
|
uint32_t bcount = 0U; |
||||
|
|
||||
|
__IO uint32_t devrxstat = 0U; |
||||
|
|
||||
|
/* disable the RX status queue non-empty interrupt */ |
||||
|
udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE; |
||||
|
|
||||
|
/* get the status from the top of the FIFO */ |
||||
|
devrxstat = udev->regs.gr->GRSTATP; |
||||
|
|
||||
|
uint8_t ep_num = (uint8_t)(devrxstat & GRSTATRP_EPNUM); |
||||
|
|
||||
|
transc = &udev->dev.transc_out[ep_num]; |
||||
|
|
||||
|
bcount = (devrxstat & GRSTATRP_BCOUNT) >> 4; |
||||
|
data_PID = (uint8_t)((devrxstat & GRSTATRP_DPID) >> 15); |
||||
|
|
||||
|
switch ((devrxstat & GRSTATRP_RPCKST) >> 17) |
||||
|
{ |
||||
|
case RSTAT_GOUT_NAK: |
||||
|
break; |
||||
|
|
||||
|
case RSTAT_DATA_UPDT: |
||||
|
if (bcount > 0U) |
||||
|
{ |
||||
|
(void)usb_rxfifo_read(&udev->regs, transc->xfer_buf, (uint16_t)bcount); |
||||
|
|
||||
|
transc->xfer_buf += bcount; |
||||
|
transc->xfer_count += bcount; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case RSTAT_XFER_COMP: |
||||
|
/* trigger the OUT endpoint interrupt */ |
||||
|
break; |
||||
|
|
||||
|
case RSTAT_SETUP_COMP: |
||||
|
/* trigger the OUT endpoint interrupt */ |
||||
|
break; |
||||
|
|
||||
|
case RSTAT_SETUP_UPDT: |
||||
|
if ((0U == transc->ep_addr.num) && (8U == bcount) && (DPID_DATA0 == data_PID)) |
||||
|
{ |
||||
|
/* copy the SETUP packet received in FIFO into the setup buffer in RAM */ |
||||
|
(void)usb_rxfifo_read(&udev->regs, (uint8_t *)&udev->dev.control.req, (uint16_t)bcount); |
||||
|
|
||||
|
transc->xfer_count += bcount; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* enable the RX status queue level interrupt */ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle USB reset interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_reset(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t i; |
||||
|
|
||||
|
/* clear the remote wakeup signaling */ |
||||
|
udev->regs.dr->DCTL &= ~DCTL_RWKUP; |
||||
|
|
||||
|
/* flush the TX FIFO */ |
||||
|
(void)usb_txfifo_flush(&udev->regs, 0U); |
||||
|
|
||||
|
for (i = 0U; i < udev->bp.num_ep; i++) |
||||
|
{ |
||||
|
udev->regs.er_in[i]->DIEPINTF = 0xFFU; |
||||
|
udev->regs.er_out[i]->DOEPINTF = 0xFFU; |
||||
|
} |
||||
|
|
||||
|
/* clear all pending device endpoint interrupts */ |
||||
|
udev->regs.dr->DAEPINT = 0xFFFFFFFFU; |
||||
|
|
||||
|
/* enable endpoint 0 interrupts */ |
||||
|
udev->regs.dr->DAEPINTEN = 1U | (1U << 16U); |
||||
|
|
||||
|
/* enable OUT endpoint interrupts */ |
||||
|
udev->regs.dr->DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN; |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
udev->regs.dr->DOEP1INTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN; |
||||
|
#endif |
||||
|
|
||||
|
/* enable IN endpoint interrupts */ |
||||
|
udev->regs.dr->DIEPINTEN = DIEPINTEN_TFEN; |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
udev->regs.dr->DIEP1INTEN = DIEPINTEN_TFEN; |
||||
|
#endif |
||||
|
|
||||
|
/* reset device address */ |
||||
|
udev->regs.dr->DCFG &= ~DCFG_DAR; |
||||
|
|
||||
|
/* configure endpoint 0 to receive SETUP packets */ |
||||
|
usb_ctlep_startout(udev); |
||||
|
|
||||
|
/* clear USB reset interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_RST; |
||||
|
|
||||
|
usb_ep_active(udev, 0x00, USB_FS_EP0_MAX_LEN, USB_EPTYPE_CTRL); |
||||
|
usb_ep_active(udev, 0x80, USB_FS_EP0_MAX_LEN, USB_EPTYPE_CTRL); |
||||
|
|
||||
|
usbd_reset_callback(); |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle USB speed enumeration finish interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_enumfinish(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint8_t enum_speed = (uint8_t)((udev->regs.dr->DSTAT & DSTAT_ES) >> 1); |
||||
|
|
||||
|
udev->regs.dr->DCTL &= ~DCTL_CGINAK; |
||||
|
udev->regs.dr->DCTL |= DCTL_CGINAK; |
||||
|
|
||||
|
udev->regs.gr->GUSBCS &= ~GUSBCS_UTT; |
||||
|
|
||||
|
/* set USB turn-around time based on device speed and PHY interface */ |
||||
|
if ((uint8_t)USB_SPEED_HIGH == USB_SPEED[enum_speed]) |
||||
|
{ |
||||
|
udev->bp.core_speed = (uint8_t)USB_SPEED_HIGH; |
||||
|
|
||||
|
udev->regs.gr->GUSBCS |= 0x09U << 10; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->bp.core_speed = (uint8_t)USB_SPEED_FULL; |
||||
|
|
||||
|
udev->regs.gr->GUSBCS |= 0x05U << 10; |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_ENUMFIF; |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB suspend interrupt handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_suspend(usb_core_driver *udev) |
||||
|
{ |
||||
|
__IO uint8_t low_power = udev->bp.low_power; |
||||
|
__IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST); |
||||
|
|
||||
|
udev->dev.backup_status = udev->dev.cur_status; |
||||
|
|
||||
|
if (low_power && suspend) |
||||
|
{ |
||||
|
/* switch-off the USB clocks */ |
||||
|
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK; |
||||
|
|
||||
|
/* enter DEEP_SLEEP mode with LDO in low power mode */ |
||||
|
pmu_to_deepsleepmode(WFI_CMD); |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_SP; |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB wakeup interrupt handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_wakeup(usb_core_driver *udev) |
||||
|
{ |
||||
|
__IO uint8_t low_power = udev->bp.low_power; |
||||
|
__IO uint8_t remote_wakeup = udev->dev.pm.dev_remote_wakeup; |
||||
|
|
||||
|
#if (1U == LPM_ENABLED) |
||||
|
if (LPM_L1 == udev->dev.pm.lpm_state) |
||||
|
{ |
||||
|
udev->dev.pm.lpm_state = LPM_L0; |
||||
|
usbd_int_lpm(udev, LPM_L0_ACTIVE); |
||||
|
} |
||||
|
else |
||||
|
#endif /* LPM_ENABLED */ |
||||
|
{ |
||||
|
if (remote_wakeup && low_power) |
||||
|
{ |
||||
|
/* resume MCU CLK */ |
||||
|
|
||||
|
/* reset SLEEPDEEP bit of Cortex-M33 system control register */ |
||||
|
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); |
||||
|
} |
||||
|
|
||||
|
usb_clock_active(udev); |
||||
|
|
||||
|
/* inform upper layer by the resume event */ |
||||
|
udev->dev.cur_status = udev->dev.backup_status; |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_WKUPIF; |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB dedicated OUT endpoint 1 interrupt service routine handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint32_t usbd_int_dedicated_ep1out(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t oepintr = 0U; |
||||
|
uint32_t oeplen = 0U; |
||||
|
|
||||
|
oepintr = udev->regs.er_out[1]->DOEPINTF; |
||||
|
oepintr &= udev->regs.dr->DOEP1INTEN; |
||||
|
|
||||
|
/* transfer complete */ |
||||
|
if (oepintr & DOEPINTF_TF) |
||||
|
{ |
||||
|
/* clear the bit in DOEPINTn for this interrupt */ |
||||
|
udev->regs.er_out[1]->DOEPINTF = DOEPINTF_TF; |
||||
|
|
||||
|
if (USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
oeplen = udev->regs.er_out[1]->DOEPLEN; |
||||
|
|
||||
|
/* ToDo : handle more than one single MPS size packet */ |
||||
|
udev->dev.transc_out[1].xfer_count = udev->dev.transc_out[1].max_len - |
||||
|
(oeplen & DEPLEN_TLEN); |
||||
|
} |
||||
|
|
||||
|
/* RX COMPLETE */ |
||||
|
usbd_out_transc(udev, 1U); |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB dedicated IN endpoint 1 interrupt service routine handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint32_t usbd_int_dedicated_ep1in(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t inten, intr, emptyen; |
||||
|
|
||||
|
inten = udev->regs.dr->DIEP1INTEN; |
||||
|
emptyen = udev->regs.dr->DIEPFEINTEN; |
||||
|
|
||||
|
inten |= ((emptyen >> 1U) & 0x1U) << 7U; |
||||
|
|
||||
|
intr = udev->regs.er_in[1]->DIEPINTF & inten; |
||||
|
|
||||
|
if (intr & DIEPINTF_TF) |
||||
|
{ |
||||
|
udev->regs.dr->DIEPFEINTEN &= ~(0x1U << 1U); |
||||
|
|
||||
|
udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TF; |
||||
|
|
||||
|
/* TX COMPLETE */ |
||||
|
usbd_in_transc(udev, 1U); |
||||
|
} |
||||
|
|
||||
|
if (intr & DIEPINTF_TXFE) |
||||
|
{ |
||||
|
usbd_emptytxfifo_write(udev, 1U); |
||||
|
|
||||
|
udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TXFE; |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#if (1U == LPM_ENABLED) |
||||
|
|
||||
|
/*!
|
||||
|
\brief USB LPM interrupt handler |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[in] active_type: active type |
||||
|
only one parameter can be selected which is shown as below: |
||||
|
\arg LPM_L0_ACTIVE: select L0 to active |
||||
|
\arg LPM_L1_ACTIVE: select L1 to active |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbd_int_lpm(usb_core_driver *udev, usb_lpm_type active_type) |
||||
|
{ |
||||
|
__IO uint8_t low_power = udev->bp.low_power; |
||||
|
__IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST); |
||||
|
__IO uint8_t is_configured = (udev->dev.cur_status == (uint8_t)USBD_CONFIGURED) ? 1U : 0U; |
||||
|
|
||||
|
switch (active_type) |
||||
|
{ |
||||
|
case LPM_L0_ACTIVE: |
||||
|
udev->dev.cur_status = udev->dev.backup_status; |
||||
|
|
||||
|
/* switch-on the OTG clocks */ |
||||
|
usb_clock_active(udev); |
||||
|
|
||||
|
if (low_power) |
||||
|
{ |
||||
|
/* resume MCU CLK */ |
||||
|
|
||||
|
/* reset SLEEPDEEP bit of Cortex-M7 system control register */ |
||||
|
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case LPM_L1_ACTIVE: |
||||
|
udev->dev.backup_status = udev->dev.cur_status; |
||||
|
udev->dev.cur_status = (uint8_t)USBD_SUSPENDED; |
||||
|
|
||||
|
/* add delay */ |
||||
|
usb_mdelay(300U); |
||||
|
|
||||
|
/* switch-off the OTG clocks */ |
||||
|
*udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK; |
||||
|
|
||||
|
if (low_power) |
||||
|
{ |
||||
|
/* enter DEEP_SLEEP mode with LDO in low power mode */ |
||||
|
pmu_to_deepsleepmode(WFI_CMD); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
#endif /* LPM_ENABLED */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief check FIFO for the next packet to be loaded |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[in] ep_num: endpoint identifier which is in (0..5) |
||||
|
\param[out] none |
||||
|
\retval status |
||||
|
*/ |
||||
|
static uint32_t usbd_emptytxfifo_write(usb_core_driver *udev, uint32_t ep_num) |
||||
|
{ |
||||
|
uint32_t len; |
||||
|
uint32_t word_count; |
||||
|
|
||||
|
usb_transc *transc = &udev->dev.transc_in[ep_num]; |
||||
|
|
||||
|
len = transc->xfer_len - transc->xfer_count; |
||||
|
|
||||
|
/* get the data length to write */ |
||||
|
if (len > transc->max_len) |
||||
|
{ |
||||
|
len = transc->max_len; |
||||
|
} |
||||
|
|
||||
|
word_count = (len + 3U) / 4U; |
||||
|
|
||||
|
while (((udev->regs.er_in[ep_num]->DIEPTFSTAT & DIEPTFSTAT_IEPTFS) >= word_count) && |
||||
|
(transc->xfer_count < transc->xfer_len)) |
||||
|
{ |
||||
|
len = transc->xfer_len - transc->xfer_count; |
||||
|
|
||||
|
if (len > transc->max_len) |
||||
|
{ |
||||
|
len = transc->max_len; |
||||
|
} |
||||
|
|
||||
|
/* write FIFO in word(4bytes) */ |
||||
|
word_count = (len + 3U) / 4U; |
||||
|
|
||||
|
/* write the FIFO */ |
||||
|
(void)usb_txfifo_write(&udev->regs, transc->xfer_buf, (uint8_t)ep_num, (uint16_t)len); |
||||
|
|
||||
|
transc->xfer_buf += len; |
||||
|
transc->xfer_count += len; |
||||
|
|
||||
|
if (transc->xfer_count == transc->xfer_len) |
||||
|
{ |
||||
|
/* disable the device endpoint FIFO empty interrupt */ |
||||
|
udev->regs.dr->DIEPFEINTEN &= ~(0x01U << ep_num); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_DEVICE */ |
||||
@ -0,0 +1,693 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usbh_int.h" |
||||
|
#include "drv_otghs_host.h" |
||||
|
|
||||
|
#if defined(__CC_ARM) /*!< ARM compiler */ |
||||
|
#pragma O0 |
||||
|
#elif defined(__GNUC__) /*!< GNU compiler */ |
||||
|
#pragma GCC optimize("O0") |
||||
|
#elif defined(__TASKING__) /*!< TASKING compiler */ |
||||
|
#pragma optimize = 0 |
||||
|
#endif /* __CC_ARM */ |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
/* local function prototypes ('static') */ |
||||
|
static uint32_t usbh_int_port(usb_core_driver *udev); |
||||
|
static uint32_t usbh_int_pipe(usb_core_driver *udev); |
||||
|
static uint32_t usbh_int_pipe_in(usb_core_driver *udev, uint32_t pp_num); |
||||
|
static uint32_t usbh_int_pipe_out(usb_core_driver *udev, uint32_t pp_num); |
||||
|
static uint32_t usbh_int_rxfifonoempty(usb_core_driver *udev); |
||||
|
static uint32_t usbh_int_txfifoempty(usb_core_driver *udev, usb_pipe_mode pp_mode); |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle global host interrupt |
||||
|
\param[in] udev: pointer to USB core instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint32_t usbh_isr(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t retval = 0U; |
||||
|
|
||||
|
__IO uint32_t intr = 0U; |
||||
|
|
||||
|
/* check if host mode */ |
||||
|
if (HOST_MODE == (udev->regs.gr->GINTF & GINTF_COPM)) |
||||
|
{ |
||||
|
intr = usb_coreintr_get(&udev->regs); |
||||
|
|
||||
|
if (!intr) |
||||
|
{ |
||||
|
return 0U; |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_SOF) |
||||
|
{ |
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_SOF; |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_RXFNEIF) |
||||
|
{ |
||||
|
retval |= usbh_int_rxfifonoempty(udev); |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_NPTXFEIF) |
||||
|
{ |
||||
|
retval |= usbh_int_txfifoempty(udev, PIPE_NON_PERIOD); |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_PTXFEIF) |
||||
|
{ |
||||
|
retval |= usbh_int_txfifoempty(udev, PIPE_PERIOD); |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_HCIF) |
||||
|
{ |
||||
|
retval |= usbh_int_pipe(udev); |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_HPIF) |
||||
|
{ |
||||
|
retval |= usbh_int_port(udev); |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_WKUPIF) |
||||
|
{ |
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_WKUPIF; |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_DISCIF) |
||||
|
{ |
||||
|
if ((*udev->regs.HPCS & HPCS_PCST) == 0) |
||||
|
{ |
||||
|
usbh_disconnect_callback(udev); |
||||
|
} |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_DISCIF; |
||||
|
} |
||||
|
|
||||
|
if (intr & GINTF_ISOONCIF) |
||||
|
{ |
||||
|
udev->regs.pr[0]->HCHCTL |= HCHCTL_CEN | HCHCTL_CDIS; |
||||
|
|
||||
|
/* clear interrupt */ |
||||
|
udev->regs.gr->GINTF = GINTF_ISOONCIF; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return retval; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle USB pipe halt |
||||
|
\param[in] udev: pointer to USB core instance |
||||
|
\param[in] pp_num: pp_num: host channel number which is in (0..7) |
||||
|
\param[in] pp_int: pipe interrupt |
||||
|
\param[in] pp_status: pipe status |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static inline void usb_pp_halt(usb_core_driver *udev, |
||||
|
uint8_t pp_num, |
||||
|
uint32_t pp_int, |
||||
|
usb_pipe_status pp_status) |
||||
|
{ |
||||
|
udev->regs.pr[pp_num]->HCHINTEN |= HCHINTEN_CHIE; |
||||
|
|
||||
|
usb_pipe_halt(udev, pp_num); |
||||
|
|
||||
|
udev->regs.pr[pp_num]->HCHINTF = pp_int; |
||||
|
|
||||
|
udev->host.pipe[pp_num].pp_status = pp_status; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the host port interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
#if defined(__ICCARM__) /*!< IAR compiler */ |
||||
|
#pragma optimize = none |
||||
|
#endif /* __ICCARM */ |
||||
|
static uint32_t usbh_int_port(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t retval = 0U; |
||||
|
|
||||
|
__IO uint32_t port_state = *udev->regs.HPCS; |
||||
|
|
||||
|
__IO uint32_t port_reset = 0U; |
||||
|
|
||||
|
/* clear the interrupt bit in GINTF */ |
||||
|
port_state &= ~(HPCS_PE | HPCS_PCD | HPCS_PEDC); |
||||
|
|
||||
|
/* port connect detected */ |
||||
|
if (*udev->regs.HPCS & HPCS_PCD) |
||||
|
{ |
||||
|
port_state |= HPCS_PCD; |
||||
|
|
||||
|
if ((*udev->regs.HPCS & HPCS_PCST) == HPCS_PCST) |
||||
|
{ |
||||
|
usbh_connect_callback(udev); |
||||
|
} |
||||
|
|
||||
|
retval |= 1U; |
||||
|
} |
||||
|
|
||||
|
/* port enable changed */ |
||||
|
if (*udev->regs.HPCS & HPCS_PEDC) |
||||
|
{ |
||||
|
port_state |= HPCS_PEDC; |
||||
|
|
||||
|
if (*udev->regs.HPCS & HPCS_PE) |
||||
|
{ |
||||
|
uint32_t port_speed = usb_curspeed_get(udev); |
||||
|
|
||||
|
udev->host.connect_status = 1U; |
||||
|
|
||||
|
if (PORT_SPEED_LOW == port_speed) |
||||
|
{ |
||||
|
udev->regs.hr->HFT = 6000U; |
||||
|
} |
||||
|
else if (PORT_SPEED_FULL == port_speed) |
||||
|
{ |
||||
|
udev->regs.hr->HFT = 48000U; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
port_reset = 1U; |
||||
|
|
||||
|
udev->regs.gr->GINTEN |= GINTEN_DISCIE | GINTEN_SOFIE; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (1U == port_reset) |
||||
|
{ |
||||
|
usb_port_reset(udev); |
||||
|
} |
||||
|
|
||||
|
/* clear port interrupts */ |
||||
|
*udev->regs.HPCS = port_state; |
||||
|
|
||||
|
return retval; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle all host channels interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbh_int_pipe(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t pp_num = 0U; |
||||
|
uint32_t retval = 0U; |
||||
|
|
||||
|
for (pp_num = 0U; pp_num < udev->bp.num_pipe; pp_num++) |
||||
|
{ |
||||
|
if ((udev->regs.hr->HACHINT & HACHINT_HACHINT) & (1UL << pp_num)) |
||||
|
{ |
||||
|
if (udev->regs.pr[pp_num]->HCHCTL & HCHCTL_EPDIR) |
||||
|
{ |
||||
|
retval |= usbh_int_pipe_in(udev, pp_num); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
retval |= usbh_int_pipe_out(udev, pp_num); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return retval; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the IN channel interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[in] pp_num: host channel number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
#if defined(__ICCARM__) /*!< IAR compiler */ |
||||
|
#pragma optimize = none |
||||
|
#endif /* __ICCARM */ |
||||
|
static uint32_t usbh_int_pipe_in(usb_core_driver *udev, uint32_t pp_num) |
||||
|
{ |
||||
|
usb_pr *pp_reg = udev->regs.pr[pp_num]; |
||||
|
usb_pipe *pp = &udev->host.pipe[pp_num]; |
||||
|
|
||||
|
uint32_t intr_pp = pp_reg->HCHINTF; |
||||
|
intr_pp &= pp_reg->HCHINTEN; |
||||
|
|
||||
|
uint8_t ep_type = (uint8_t)((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18); |
||||
|
|
||||
|
if (intr_pp & HCHINTF_ACK) |
||||
|
{ |
||||
|
pp_reg->HCHINTF = HCHINTF_ACK; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_STALL) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL); |
||||
|
pp_reg->HCHINTF = HCHINTF_NAK; |
||||
|
|
||||
|
/* note: When there is a 'STALL', reset also NAK,
|
||||
|
else, the udev->host.pp_status = HC_STALL |
||||
|
will be overwritten by 'NAK' in code below */ |
||||
|
intr_pp &= ~HCHINTF_NAK; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_DTER) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR); |
||||
|
pp_reg->HCHINTF = HCHINTF_NAK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
if (intr_pp & HCHINTF_REQOVR) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_TF) |
||||
|
{ |
||||
|
if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
udev->host.backup_xfercount[pp_num] = pp->xfer_len - (pp_reg->HCHLEN & HCHLEN_TLEN); |
||||
|
} |
||||
|
|
||||
|
pp->pp_status = PIPE_XF; |
||||
|
pp->err_count = 0U; |
||||
|
|
||||
|
pp_reg->HCHINTF = HCHINTF_TF; |
||||
|
|
||||
|
switch (ep_type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
case USB_EPTYPE_BULK: |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_XF); |
||||
|
|
||||
|
pp->data_toggle_in ^= 1U; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
case USB_EPTYPE_ISOC: |
||||
|
pp_reg->HCHCTL |= HCHCTL_ODDFRM; |
||||
|
pp->urb_state = URB_DONE; |
||||
|
|
||||
|
#ifdef USBH_USE_RTOS |
||||
|
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state); |
||||
|
#endif /* USBH_USE_RTOS */ |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_CH) |
||||
|
{ |
||||
|
pp_reg->HCHINTEN &= ~HCHINTEN_CHIE; |
||||
|
|
||||
|
switch (pp->pp_status) |
||||
|
{ |
||||
|
case PIPE_XF: |
||||
|
pp->urb_state = URB_DONE; |
||||
|
break; |
||||
|
|
||||
|
case PIPE_STALL: |
||||
|
pp->urb_state = URB_STALL; |
||||
|
break; |
||||
|
|
||||
|
case PIPE_TRACERR: |
||||
|
case PIPE_DTGERR: |
||||
|
pp->err_count = 0U; |
||||
|
pp->urb_state = URB_ERROR; |
||||
|
|
||||
|
pp->data_toggle_in ^= 1U; |
||||
|
break; |
||||
|
|
||||
|
case PIPE_IDLE: |
||||
|
case PIPE_HALTED: |
||||
|
case PIPE_NAK: |
||||
|
case PIPE_NYET: |
||||
|
case PIPE_BBERR: |
||||
|
case PIPE_REQOVR: |
||||
|
default: |
||||
|
if ((uint8_t)USB_EPTYPE_INTR == ep_type) |
||||
|
{ |
||||
|
pp->data_toggle_in ^= 1U; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
#ifdef USBH_USE_RTOS |
||||
|
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state); |
||||
|
#endif /* USBH_USE_RTOS */ |
||||
|
|
||||
|
pp_reg->HCHINTF = HCHINTF_CH; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_USBER) |
||||
|
{ |
||||
|
pp->err_count++; |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_NAK) |
||||
|
{ |
||||
|
pp_reg->HCHINTF = HCHINTF_NAK; |
||||
|
switch (ep_type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
case USB_EPTYPE_BULK: |
||||
|
/* re-activate the channel */ |
||||
|
pp_reg->HCHCTL = (pp_reg->HCHCTL | HCHCTL_CEN) & ~HCHCTL_CDIS; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
pp_reg->HCHINTEN |= HCHINTEN_CHIE; |
||||
|
|
||||
|
(void)usb_pipe_halt(udev, (uint8_t)pp_num); |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
pp->pp_status = PIPE_NAK; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the OUT channel interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[in] pp_num: host channel number which is in (0..7) |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
#if defined(__ICCARM__) /*!< IAR compiler */ |
||||
|
#pragma optimize = none |
||||
|
#endif /* __ICCARM */ |
||||
|
static uint32_t usbh_int_pipe_out(usb_core_driver *udev, uint32_t pp_num) |
||||
|
{ |
||||
|
usb_pr *pp_reg = udev->regs.pr[pp_num]; |
||||
|
usb_pipe *pp = &udev->host.pipe[pp_num]; |
||||
|
|
||||
|
uint32_t intr_pp = pp_reg->HCHINTF; |
||||
|
intr_pp &= pp_reg->HCHINTEN; |
||||
|
|
||||
|
if (intr_pp & HCHINTF_ACK) |
||||
|
{ |
||||
|
if (1U == udev->host.pipe[pp_num].do_ping) |
||||
|
{ |
||||
|
udev->host.pipe[pp_num].do_ping = 0U; |
||||
|
pp->err_count = 0U; |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_ACK, PIPE_NAK); |
||||
|
} |
||||
|
|
||||
|
pp_reg->HCHINTF = HCHINTF_ACK; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_STALL) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_DTER) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR); |
||||
|
pp_reg->HCHINTF = HCHINTF_NAK; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_REQOVR) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_TF) |
||||
|
{ |
||||
|
pp->err_count = 0U; |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_TF, PIPE_XF); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_NAK) |
||||
|
{ |
||||
|
if (0U == udev->host.pipe[pp_num].do_ping) |
||||
|
{ |
||||
|
if (1U == udev->host.pipe[pp_num].supp_ping) |
||||
|
{ |
||||
|
udev->host.pipe[pp_num].do_ping = 1U; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
pp->err_count = 0U; |
||||
|
if (USB_USE_FIFO == udev->bp.transfer_mode) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
pp_reg->HCHINTF = HCHINTF_NAK; |
||||
|
} |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_USBER) |
||||
|
{ |
||||
|
pp->err_count++; |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR); |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_NYET) |
||||
|
{ |
||||
|
usb_pp_halt(udev, (uint8_t)pp_num, HCHINTF_NYET, PIPE_NYET); |
||||
|
|
||||
|
pp->err_count = 0U; |
||||
|
} |
||||
|
else if (intr_pp & HCHINTF_CH) |
||||
|
{ |
||||
|
udev->regs.pr[pp_num]->HCHINTEN &= ~HCHINTEN_CHIE; |
||||
|
|
||||
|
switch (pp->pp_status) |
||||
|
{ |
||||
|
case PIPE_XF: |
||||
|
pp->urb_state = URB_DONE; |
||||
|
|
||||
|
if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U)) |
||||
|
{ |
||||
|
pp->data_toggle_out ^= 1U; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case PIPE_NAK: |
||||
|
pp->urb_state = URB_NOTREADY; |
||||
|
break; |
||||
|
|
||||
|
case PIPE_NYET: |
||||
|
pp->urb_state = URB_DONE; |
||||
|
|
||||
|
if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U)) |
||||
|
{ |
||||
|
pp->data_toggle_out ^= 1U; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case PIPE_STALL: |
||||
|
pp->urb_state = URB_STALL; |
||||
|
break; |
||||
|
|
||||
|
case PIPE_TRACERR: |
||||
|
if (3U == pp->err_count) |
||||
|
{ |
||||
|
pp->urb_state = URB_ERROR; |
||||
|
pp->err_count = 0U; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case PIPE_IDLE: |
||||
|
case PIPE_HALTED: |
||||
|
case PIPE_BBERR: |
||||
|
case PIPE_REQOVR: |
||||
|
case PIPE_DTGERR: |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
#ifdef USBH_USE_RTOS |
||||
|
usbh_hc_notifyurbchange_callback(udev, pp_num, pp->urb_state); |
||||
|
#endif /* USBH_USE_RTOS */ |
||||
|
|
||||
|
pp_reg->HCHINTF = HCHINTF_CH; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the RX FIFO non-empty interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
#if defined(__ICCARM__) /*!< IAR compiler */ |
||||
|
#pragma optimize = none |
||||
|
#endif /* __ICCARM */ |
||||
|
static uint32_t usbh_int_rxfifonoempty(usb_core_driver *udev) |
||||
|
{ |
||||
|
uint32_t count = 0U, xfer_count = 0U; |
||||
|
|
||||
|
__IO uint8_t pp_num = 0U; |
||||
|
__IO uint32_t rx_stat = 0U; |
||||
|
|
||||
|
/* disable the RX status queue level interrupt */ |
||||
|
udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE; |
||||
|
|
||||
|
rx_stat = udev->regs.gr->GRSTATP; |
||||
|
pp_num = (uint8_t)(rx_stat & GRSTATRP_CNUM); |
||||
|
|
||||
|
switch ((rx_stat & GRSTATRP_RPCKST) >> 17) |
||||
|
{ |
||||
|
case GRXSTS_PKTSTS_IN: |
||||
|
count = (rx_stat & GRSTATRP_BCOUNT) >> 4; |
||||
|
|
||||
|
/* read the data into the host buffer. */ |
||||
|
if ((NULL != udev->host.pipe[pp_num].xfer_buf) && (count > 0U)) |
||||
|
{ |
||||
|
(void)usb_rxfifo_read(&udev->regs, udev->host.pipe[pp_num].xfer_buf, (uint16_t)count); |
||||
|
|
||||
|
/* manage multiple transfer packet */ |
||||
|
udev->host.pipe[pp_num].xfer_buf += count; |
||||
|
udev->host.pipe[pp_num].xfer_count += count; |
||||
|
|
||||
|
xfer_count = udev->host.pipe[pp_num].xfer_count; |
||||
|
|
||||
|
udev->host.backup_xfercount[pp_num] = xfer_count; |
||||
|
|
||||
|
if (udev->regs.pr[pp_num]->HCHLEN & HCHLEN_PCNT) |
||||
|
{ |
||||
|
/* re-activate the channel when more packets are expected */ |
||||
|
uint32_t pp_ctl = udev->regs.pr[pp_num]->HCHCTL; |
||||
|
|
||||
|
pp_ctl |= HCHCTL_CEN; |
||||
|
pp_ctl &= ~HCHCTL_CDIS; |
||||
|
|
||||
|
udev->regs.pr[pp_num]->HCHCTL = pp_ctl; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case GRXSTS_PKTSTS_IN_XFER_COMP: |
||||
|
break; |
||||
|
|
||||
|
case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: |
||||
|
count = (rx_stat & GRSTATRP_BCOUNT) >> 4; |
||||
|
|
||||
|
while (count > 0U) |
||||
|
{ |
||||
|
rx_stat = udev->regs.gr->GRSTATP; |
||||
|
count--; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case GRXSTS_PKTSTS_CH_HALTED: |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* enable the RX status queue level interrupt */ |
||||
|
udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief handle the TX FIFO empty interrupt |
||||
|
\param[in] udev: pointer to USB device instance |
||||
|
\param[in] pp_mode: pipe mode |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
#if defined(__ICCARM__) /*!< IAR compiler */ |
||||
|
#pragma optimize = none |
||||
|
#endif /* __ICCARM */ |
||||
|
static uint32_t usbh_int_txfifoempty(usb_core_driver *udev, usb_pipe_mode pp_mode) |
||||
|
{ |
||||
|
uint8_t pp_num = 0U; |
||||
|
uint16_t word_count = 0U, len = 0U; |
||||
|
__IO uint32_t *txfiforeg = 0U, txfifostate = 0U; |
||||
|
|
||||
|
if (PIPE_NON_PERIOD == pp_mode) |
||||
|
{ |
||||
|
txfiforeg = &udev->regs.gr->HNPTFQSTAT; |
||||
|
} |
||||
|
else if (PIPE_PERIOD == pp_mode) |
||||
|
{ |
||||
|
txfiforeg = &udev->regs.hr->HPTFQSTAT; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return 0U; |
||||
|
} |
||||
|
|
||||
|
txfifostate = *txfiforeg; |
||||
|
|
||||
|
pp_num = (uint8_t)((txfifostate & TFQSTAT_CNUM) >> 27); |
||||
|
|
||||
|
word_count = (uint16_t)(udev->host.pipe[pp_num].xfer_len + 3U) / 4U; |
||||
|
|
||||
|
while (((txfifostate & TFQSTAT_TXFS) >= word_count) && (0U != udev->host.pipe[pp_num].xfer_len)) |
||||
|
{ |
||||
|
len = (uint16_t)(txfifostate & TFQSTAT_TXFS) * 4U; |
||||
|
|
||||
|
if (len > udev->host.pipe[pp_num].xfer_len) |
||||
|
{ |
||||
|
/* last packet */ |
||||
|
len = (uint16_t)udev->host.pipe[pp_num].xfer_len; |
||||
|
|
||||
|
if (PIPE_NON_PERIOD == pp_mode) |
||||
|
{ |
||||
|
udev->regs.gr->GINTEN &= ~GINTEN_NPTXFEIE; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
udev->regs.gr->GINTEN &= ~GINTEN_PTXFEIE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
word_count = (uint16_t)((udev->host.pipe[pp_num].xfer_len + 3U) / 4U); |
||||
|
usb_txfifo_write(&udev->regs, udev->host.pipe[pp_num].xfer_buf, pp_num, len); |
||||
|
|
||||
|
udev->host.pipe[pp_num].xfer_buf += len; |
||||
|
udev->host.pipe[pp_num].xfer_len -= len; |
||||
|
udev->host.pipe[pp_num].xfer_count += len; |
||||
|
|
||||
|
txfifostate = *txfiforeg; |
||||
|
} |
||||
|
|
||||
|
return 1U; |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
@ -0,0 +1,178 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usbh_pipe.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
static uint16_t usbh_freepipe_get(usb_core_driver *pudev); |
||||
|
|
||||
|
/*!
|
||||
|
\brief create a pipe |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[in] udev: USB device |
||||
|
\param[in] ep_type: endpoint type |
||||
|
\param[in] ep_mpl: endpoint max packet length |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint8_t usbh_pipe_create(usb_core_driver *pudev, |
||||
|
uint8_t dev_addr, |
||||
|
uint8_t dev_speed, |
||||
|
uint8_t pp_num, |
||||
|
uint8_t ep_num, |
||||
|
uint8_t ep_type, |
||||
|
uint16_t ep_mpl) |
||||
|
{ |
||||
|
usb_pipe *pp = &pudev->host.pipe[pp_num]; |
||||
|
|
||||
|
pp->dev_addr = dev_addr; |
||||
|
pp->dev_speed = dev_speed; |
||||
|
pp->ep.num = ep_num & 0x7FU; |
||||
|
pp->ep.type = ep_type; |
||||
|
pp->ep.mps = ep_mpl; |
||||
|
|
||||
|
if (((USB_EPTYPE_BULK == pp->ep.type) || (USB_EPTYPE_CTRL == pp->ep.type))) |
||||
|
{ |
||||
|
pp->supp_ping = (uint8_t)(pp->dev_speed == PORT_SPEED_HIGH); |
||||
|
} |
||||
|
|
||||
|
if (0x80U == (ep_num & 0x80U)) |
||||
|
{ |
||||
|
pp->ep.dir = 1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
pp->ep.dir = 0; |
||||
|
} |
||||
|
|
||||
|
usb_pipe_init(pudev, pp_num); |
||||
|
|
||||
|
return HC_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief modify a pipe |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[in] dev_addr: device address |
||||
|
\param[in] dev_speed: device speed |
||||
|
\param[in] ep_type: endpoint type |
||||
|
\param[in] ep_mpl: endpoint max packet length |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint8_t usbh_pipe_update(usb_core_driver *pudev, |
||||
|
uint8_t pp_num, |
||||
|
uint8_t dev_addr, |
||||
|
uint32_t dev_speed, |
||||
|
uint16_t ep_mpl) |
||||
|
{ |
||||
|
usb_pipe *pp = &pudev->host.pipe[pp_num]; |
||||
|
|
||||
|
if ((pp->dev_addr != dev_addr) && (dev_addr)) |
||||
|
{ |
||||
|
pp->dev_addr = dev_addr; |
||||
|
} |
||||
|
|
||||
|
if ((pp->dev_speed != dev_speed) && (dev_speed)) |
||||
|
{ |
||||
|
pp->dev_speed = dev_speed; |
||||
|
} |
||||
|
|
||||
|
if ((pp->ep.mps != ep_mpl) && (ep_mpl)) |
||||
|
{ |
||||
|
pp->ep.mps = ep_mpl; |
||||
|
} |
||||
|
|
||||
|
usb_pipe_init(pudev, pp_num); |
||||
|
|
||||
|
return HC_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief allocate a new pipe |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] ep_addr: endpoint address |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint8_t usbh_pipe_allocate(usb_core_driver *pudev, uint8_t ep_addr) |
||||
|
{ |
||||
|
uint16_t pp_num = usbh_freepipe_get(pudev); |
||||
|
|
||||
|
if (HC_ERROR != pp_num) |
||||
|
{ |
||||
|
pudev->host.pipe[pp_num].in_used = 1U; |
||||
|
pudev->host.pipe[pp_num].ep.dir = EP_DIR(ep_addr); |
||||
|
pudev->host.pipe[pp_num].ep.num = EP_ID(ep_addr); |
||||
|
} |
||||
|
|
||||
|
return pp_num; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief free a pipe |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint8_t usbh_pipe_free(usb_core_driver *pudev, uint8_t pp_num) |
||||
|
{ |
||||
|
if (pp_num < HC_MAX) |
||||
|
{ |
||||
|
pudev->host.pipe[pp_num].in_used = 0U; |
||||
|
} |
||||
|
|
||||
|
return USBH_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief delete all USB host pipe |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
uint8_t usbh_pipe_delete(usb_core_driver *pudev) |
||||
|
{ |
||||
|
uint8_t pp_num = 0U; |
||||
|
|
||||
|
for (pp_num = 2U; pp_num < HC_MAX; pp_num++) |
||||
|
{ |
||||
|
pudev->host.pipe[pp_num] = (usb_pipe){ 0 }; |
||||
|
} |
||||
|
|
||||
|
return USBH_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief get a free pipe number for allocation |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint16_t usbh_freepipe_get(usb_core_driver *pudev) |
||||
|
{ |
||||
|
uint8_t pp_num = 0U; |
||||
|
|
||||
|
for (pp_num = 0U; pp_num < HC_MAX; pp_num++) |
||||
|
{ |
||||
|
if (pudev->host.pipe[pp_num].in_used == 0U) |
||||
|
{ |
||||
|
return pp_num; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return HC_ERROR; |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
@ -0,0 +1,147 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usbh_transc.h" |
||||
|
|
||||
|
#if defined(BSP_USING_USB) && defined(RT_USING_USB_HOST) |
||||
|
|
||||
|
#define USB_SETUP_PACKET_LEN 8U |
||||
|
|
||||
|
/*!
|
||||
|
\brief prepare a pipe and start a transfer |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
static uint32_t usbh_request_submit(usb_core_driver *pudev, uint8_t pp_num) |
||||
|
{ |
||||
|
pudev->host.pipe[pp_num].urb_state = URB_IDLE; |
||||
|
pudev->host.pipe[pp_num].xfer_count = 0U; |
||||
|
|
||||
|
return usb_pipe_xfer(pudev, pp_num); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief send the setup packet to the USB device |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] buf: data buffer which will be sent to USB device |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usbh_status usbh_ctlsetup_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num) |
||||
|
{ |
||||
|
usb_pipe *pp = &pudev->host.pipe[pp_num]; |
||||
|
|
||||
|
pp->DPID = PIPE_DPID_SETUP; |
||||
|
pp->xfer_buf = buf; |
||||
|
pp->xfer_len = USB_SETUP_PACKET_LEN; |
||||
|
|
||||
|
return (usbh_status)usbh_request_submit(pudev, pp_num); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief send a data packet to the USB device |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] buf: data buffer which will be sent to USB device |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[in] len: length of the data to be sent |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usbh_status usbh_data_send(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len) |
||||
|
{ |
||||
|
usb_pipe *pp = &pudev->host.pipe[pp_num]; |
||||
|
|
||||
|
pp->xfer_buf = buf; |
||||
|
pp->xfer_len = len; |
||||
|
|
||||
|
switch (pp->ep.type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
if (0U == len) |
||||
|
{ |
||||
|
pp->data_toggle_out = 1U; |
||||
|
} |
||||
|
|
||||
|
pp->DPID = PIPE_DPID[pp->data_toggle_out]; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
pp->DPID = PIPE_DPID[pp->data_toggle_out]; |
||||
|
|
||||
|
pp->data_toggle_out ^= 1U; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_BULK: |
||||
|
pp->DPID = PIPE_DPID[pp->data_toggle_out]; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_ISOC: |
||||
|
pp->DPID = PIPE_DPID[0]; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
usbh_request_submit(pudev, pp_num); |
||||
|
|
||||
|
return USBH_OK; |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief receive a data packet from the USB device |
||||
|
\param[in] pudev: pointer to usb core instance |
||||
|
\param[in] buf: data buffer which will be received from USB device |
||||
|
\param[in] pp_num: pipe number |
||||
|
\param[in] len: length of the data to be received |
||||
|
\param[out] none |
||||
|
\retval operation status |
||||
|
*/ |
||||
|
usbh_status usbh_data_recev(usb_core_driver *pudev, uint8_t *buf, uint8_t pp_num, uint16_t len) |
||||
|
{ |
||||
|
usb_pipe *pp = &pudev->host.pipe[pp_num]; |
||||
|
|
||||
|
pp->xfer_buf = buf; |
||||
|
pp->xfer_len = len; |
||||
|
|
||||
|
switch (pp->ep.type) |
||||
|
{ |
||||
|
case USB_EPTYPE_CTRL: |
||||
|
pp->DPID = PIPE_DPID[1]; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_INTR: |
||||
|
pp->DPID = PIPE_DPID[pp->data_toggle_in]; |
||||
|
|
||||
|
/* Toggle DATA PID */ |
||||
|
pp->data_toggle_in ^= 1U; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_BULK: |
||||
|
pp->DPID = PIPE_DPID[pp->data_toggle_in]; |
||||
|
break; |
||||
|
|
||||
|
case USB_EPTYPE_ISOC: |
||||
|
pp->DPID = PIPE_DPID[0]; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
usbh_request_submit(pudev, pp_num); |
||||
|
|
||||
|
return USBH_OK; |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB && RT_USING_USB_HOST */ |
||||
@ -0,0 +1,733 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2006-2025, RT-Thread Development Team |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Change Logs: |
||||
|
* Date Author Notes |
||||
|
* 2025-11-07 RealThread the first version |
||||
|
*/ |
||||
|
|
||||
|
#include "drv_usb_hw.h" |
||||
|
#include <rtthread.h> |
||||
|
#include <rtdevice.h> |
||||
|
#include <board.h> |
||||
|
|
||||
|
#if defined(BSP_USING_USB) |
||||
|
|
||||
|
#define TIM_MSEC_DELAY 0x01U |
||||
|
#define TIM_USEC_DELAY 0x02U |
||||
|
|
||||
|
#if defined(RT_USING_USB_HOST) |
||||
|
#ifndef USE_ULPI_PHY |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
#if defined(SOC_SERIES_GD32H75E) |
||||
|
#define HOST_POWERSW_PORT_RCC RCU_GPIOG |
||||
|
#define HOST_POWERSW_PORT GPIOG |
||||
|
#define HOST_POWERSW_VBUS GPIO_PIN_8 |
||||
|
#elif defined(SOC_SERIES_GD32H7xx) |
||||
|
#warning "Please refer to the relevant sections in the chip manual to redefine the pins." |
||||
|
#define HOST_POWERSW_PORT_RCC RCU_GPIOB |
||||
|
#define HOST_POWERSW_PORT GPIOB |
||||
|
#define HOST_POWERSW_VBUS GPIO_PIN_13 |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
#define HOST_POWERSW_PORT_RCC RCU_GPIOG |
||||
|
#define HOST_POWERSW_PORT GPIOG |
||||
|
#define HOST_POWERSW_VBUS GPIO_PIN_7 |
||||
|
#endif |
||||
|
|
||||
|
#else |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
#define HOST_POWERSW_PORT_RCC RCU_GPIOC |
||||
|
#define HOST_POWERSW_PORT GPIOC |
||||
|
#define HOST_POWERSW_VBUS GPIO_PIN_7 |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
#define HOST_POWERSW_PORT_RCC RCU_GPIOC |
||||
|
#define HOST_POWERSW_PORT GPIOC |
||||
|
#define HOST_POWERSW_VBUS GPIO_PIN_9 |
||||
|
#endif |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#define HOST_SOF_OUTPUT_RCC RCC_APB2PERIPH_GPIOA |
||||
|
#define HOST_SOF_PORT GPIOA |
||||
|
#define HOST_SOF_SIGNAL GPIO_PIN_8 |
||||
|
#endif |
||||
|
|
||||
|
__IO uint32_t delay_time = 0U; |
||||
|
__IO uint16_t timer_prescaler = 23U; |
||||
|
|
||||
|
/* local function prototypes ('static') */ |
||||
|
static void hw_time_set(uint8_t unit); |
||||
|
static void hw_delay(uint32_t ntime, uint8_t unit); |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB GPIO |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_gpio_config(void) |
||||
|
{ |
||||
|
#ifdef USE_USBHS0 |
||||
|
rcu_periph_clock_enable(RCU_GPIOA); |
||||
|
rcu_periph_clock_enable(RCU_GPIOB); |
||||
|
rcu_periph_clock_enable(RCU_GPIOC); |
||||
|
|
||||
|
/* ULPI_STP(PC0) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_0); |
||||
|
|
||||
|
/* ULPI_CK(PA5) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); |
||||
|
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5); |
||||
|
|
||||
|
/* ULPI_NXT(PC3) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3); |
||||
|
|
||||
|
/* ULPI_DIR(PC2) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); |
||||
|
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_2); |
||||
|
|
||||
|
/* ULPI_D1(PB0), ULPI_D2(PB1), ULPI_D3(PB10), ULPI_D4(PB11) \
|
||||
|
ULPI_D5(PB12), ULPI_D6(PB13) and ULPI_D7(PB5) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, |
||||
|
GPIO_PIN_0 | |
||||
|
GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_11); |
||||
|
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, |
||||
|
GPIO_PIN_12 | |
||||
|
GPIO_PIN_13 | GPIO_PIN_5); |
||||
|
|
||||
|
/* ULPI_D0(PA3) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); |
||||
|
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3); |
||||
|
|
||||
|
gpio_af_set(GPIOA, GPIO_AF_10, GPIO_PIN_5); |
||||
|
gpio_af_set(GPIOB, GPIO_AF_10, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13); |
||||
|
gpio_af_set(GPIOC, GPIO_AF_10, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
rcu_periph_clock_enable(RCU_GPIOH); |
||||
|
rcu_periph_clock_enable(RCU_GPIOG); |
||||
|
|
||||
|
/* ULPI_STP(PH2) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_2); |
||||
|
|
||||
|
|
||||
|
/* ULPI_CK(PH5) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5); |
||||
|
|
||||
|
/* ULPI_NXT(PH4) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_4); |
||||
|
|
||||
|
/* ULPI_DIR(PH3) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_3); |
||||
|
|
||||
|
/* ULPI_D0(PH6) GPIO pin configuration */ |
||||
|
/* ULPI_D1(PH7), ULPI_D2(PH8), ULPI_D3(PH9), ULPI_D4(PH10) \
|
||||
|
ULPI_D5(PH11), ULPI_D6(PH12) and ULPI_D7(PG5) GPIO pin configuration */ |
||||
|
gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, |
||||
|
GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | |
||||
|
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12); |
||||
|
gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, |
||||
|
GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | |
||||
|
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12); |
||||
|
|
||||
|
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); |
||||
|
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_85MHZ, GPIO_PIN_5); |
||||
|
|
||||
|
gpio_af_set(GPIOG, GPIO_AF_8, GPIO_PIN_5); |
||||
|
gpio_af_set(GPIOH, GPIO_AF_8, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
} |
||||
|
|
||||
|
extern usb_core_driver gd_usb_core; |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS0 interrupt |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS0_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
#if defined(RT_USING_USB_DEVICE) |
||||
|
usbd_isr(&gd_usb_core); |
||||
|
#else |
||||
|
usbh_isr(&gd_usb_core); |
||||
|
#endif |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS1 interrupt |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS1_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
#if defined(RT_USING_USB_DEVICE) |
||||
|
usbd_isr(&gd_usb_core); |
||||
|
#else |
||||
|
usbh_isr(&gd_usb_core); |
||||
|
#endif |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief resume MCU clock |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void resume_mcu_clk(void) |
||||
|
{ |
||||
|
/* enable HXTAL */ |
||||
|
rcu_osci_on(RCU_HXTAL); |
||||
|
|
||||
|
/* wait till HXTAL is ready */ |
||||
|
while (RESET == rcu_flag_get(RCU_FLAG_HXTALSTB)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/* enable PLL */ |
||||
|
rcu_osci_on(RCU_PLL0_CK); |
||||
|
|
||||
|
/* wait till PLL is ready */ |
||||
|
while (RESET == rcu_flag_get(RCU_FLAG_PLL0STB)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/* select PLL as system clock source */ |
||||
|
rcu_system_clock_source_config(RCU_CKSYSSRC_PLL0P); |
||||
|
|
||||
|
/* wait till PLL is used as system clock source */ |
||||
|
while (RCU_SCSS_PLL0P != rcu_system_clock_source_get()) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS0 wakeup interrupt request |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS0_WKUP_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
if (gd_usb_core.bp.low_power) |
||||
|
{ |
||||
|
resume_mcu_clk(); |
||||
|
|
||||
|
#ifndef USE_IRC48M |
||||
|
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL0R); |
||||
|
#else |
||||
|
/* enable IRC48M clock */ |
||||
|
rcu_osci_on(RCU_IRC48M); |
||||
|
|
||||
|
/* wait till IRC48M is ready */ |
||||
|
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M); |
||||
|
#endif /* USE_IRC48M */ |
||||
|
|
||||
|
rcu_periph_clock_enable(RCU_USBHS0); |
||||
|
|
||||
|
usb_clock_active(&gd_usb_core); |
||||
|
} |
||||
|
|
||||
|
exti_interrupt_flag_clear(EXTI_31); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS1 wakeup interrupt request |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS1_WKUP_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
if (gd_usb_core.bp.low_power) |
||||
|
{ |
||||
|
resume_mcu_clk(); |
||||
|
|
||||
|
#ifndef USE_IRC48M |
||||
|
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL0R); |
||||
|
#else |
||||
|
/* enable IRC48M clock */ |
||||
|
rcu_osci_on(RCU_IRC48M); |
||||
|
|
||||
|
/* wait till IRC48M is ready */ |
||||
|
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M); |
||||
|
#endif /* USE_IRC48M */ |
||||
|
|
||||
|
rcu_periph_clock_enable(RCU_USBHS1); |
||||
|
|
||||
|
usb_clock_active(&gd_usb_core); |
||||
|
} |
||||
|
|
||||
|
exti_interrupt_flag_clear(EXTI_32); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS0 dedicated endpoint 1 OUT interrupt request. |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS0_EP1_OUT_IRQHandler(void) |
||||
|
{ |
||||
|
usbd_int_dedicated_ep1out(&cdc_acm); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS1 dedicated endpoint 1 OUT interrupt request. |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS1_EP1_OUT_IRQHandler(void) |
||||
|
{ |
||||
|
usbd_int_dedicated_ep1out(&cdc_acm); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS0 dedicated endpoint 1 IN interrupt request |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS0_EP1_IN_IRQHandler(void) |
||||
|
{ |
||||
|
usbd_int_dedicated_ep1in(&cdc_acm); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
/*!
|
||||
|
\brief this function handles USBHS1 dedicated endpoint 1 IN interrupt request |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void USBHS1_EP1_IN_IRQHandler(void) |
||||
|
{ |
||||
|
usbd_int_dedicated_ep1in(&cdc_acm); |
||||
|
} |
||||
|
|
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#endif /* USB_DEDICATED_EP1_ENABLED */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB clock |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_rcu_config(void) |
||||
|
{ |
||||
|
pmu_usb_regulator_enable(); |
||||
|
pmu_usb_voltage_detector_enable(); |
||||
|
while (SET != pmu_flag_get(PMU_FLAG_USB33RF)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
#ifdef USE_USB_FS |
||||
|
|
||||
|
#ifndef USE_IRC48M |
||||
|
|
||||
|
/* configure the pll1 input and output clock range */ |
||||
|
rcu_pll_input_output_clock_range_config(IDX_PLL1, RCU_PLL1RNG_4M_8M, RCU_PLL1VCO_192M_836M); |
||||
|
|
||||
|
rcu_pll1_config(5, 96, 2, 10, 2); |
||||
|
/* enable PLL1Q clock output */ |
||||
|
rcu_pll_clock_output_enable(RCU_PLL1Q); |
||||
|
rcu_osci_on(RCU_PLL1_CK); |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
rcu_usbhs_pll1qpsc_config(IDX_USBHS0, RCU_USBHSPSC_DIV1); |
||||
|
|
||||
|
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLL1Q); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
rcu_usbhs_pll1qpsc_config(IDX_USBHS1, RCU_USBHSPSC_DIV1); |
||||
|
|
||||
|
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_PLL1Q); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#else |
||||
|
/* enable IRC48M clock */ |
||||
|
rcu_osci_on(RCU_IRC48M); |
||||
|
|
||||
|
/* wait till IRC48M is ready */ |
||||
|
while (SUCCESS != rcu_osci_stab_wait(RCU_IRC48M)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M); |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_IRC48M); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_IRC48M); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#endif /* USE_IRC48M */ |
||||
|
|
||||
|
#endif /* USE_USB_FS */ |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
rcu_periph_clock_enable(RCU_USBHS0); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
rcu_periph_clock_enable(RCU_USBHS1); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#ifdef USE_ULPI_PHY |
||||
|
#ifdef USE_USBHS0 |
||||
|
rcu_periph_clock_enable(RCU_USBHS0ULPI); |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
rcu_periph_clock_enable(RCU_USBHS1ULPI); |
||||
|
#endif |
||||
|
#endif /* USE_ULPI_PHY */ |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure USB interrupt |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_intr_config(void) |
||||
|
{ |
||||
|
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
nvic_irq_enable((uint8_t)USBHS0_IRQn, 3U, 0U); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
nvic_irq_enable((uint8_t)USBHS1_IRQn, 3U, 0U); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
/* enable the power module clock */ |
||||
|
rcu_periph_clock_enable(RCU_PMU); |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
/* USB wakeup EXTI line configuration */ |
||||
|
exti_interrupt_flag_clear(EXTI_31); |
||||
|
exti_init(EXTI_31, EXTI_INTERRUPT, EXTI_TRIG_RISING); |
||||
|
exti_interrupt_enable(EXTI_31); |
||||
|
|
||||
|
nvic_irq_enable((uint8_t)USBHS0_WKUP_IRQn, 1U, 0U); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
/* USB wakeup EXTI line configuration */ |
||||
|
exti_interrupt_flag_clear(EXTI_32); |
||||
|
exti_init(EXTI_32, EXTI_INTERRUPT, EXTI_TRIG_RISING); |
||||
|
exti_interrupt_enable(EXTI_32); |
||||
|
|
||||
|
nvic_irq_enable((uint8_t)USBHS1_WKUP_IRQn, 1U, 0U); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#ifdef USB_DEDICATED_EP1_ENABLED |
||||
|
|
||||
|
#ifdef USE_USBHS0 |
||||
|
nvic_irq_enable((uint8_t)USBHS0_EP1_OUT_IRQn, 1U, 0U); |
||||
|
nvic_irq_enable((uint8_t)USBHS0_EP1_IN_IRQn, 1U, 0U); |
||||
|
#endif /* USE_USBHS0 */ |
||||
|
|
||||
|
#ifdef USE_USBHS1 |
||||
|
nvic_irq_enable((uint8_t)USBHS1_EP1_OUT_IRQn, 1U, 0U); |
||||
|
nvic_irq_enable((uint8_t)USBHS1_EP1_IN_IRQn, 1U, 0U); |
||||
|
#endif /* USE_USBHS1 */ |
||||
|
|
||||
|
#endif /* USB_DEDICATED_EP1_ENABLED */ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#if defined(RT_USING_USB_HOST) |
||||
|
/*!
|
||||
|
\brief drives the VBUS signal through GPIO |
||||
|
\param[in] state: VBUS states |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_vbus_drive(uint8_t state) |
||||
|
{ |
||||
|
if (0U == state) |
||||
|
{ |
||||
|
/* disable is needed on output of the power switch */ |
||||
|
gpio_bit_reset(HOST_POWERSW_PORT, HOST_POWERSW_VBUS); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* enable the power switch by driving the enable high */ |
||||
|
gpio_bit_set(HOST_POWERSW_PORT, HOST_POWERSW_VBUS); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configures the GPIO for the VBUS |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_vbus_config(void) |
||||
|
{ |
||||
|
rcu_periph_clock_enable(HOST_POWERSW_PORT_RCC); |
||||
|
|
||||
|
/* USBFS_VBUS_CTRL(PD13) GPIO pin configuration */ |
||||
|
gpio_mode_set(HOST_POWERSW_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HOST_POWERSW_VBUS); |
||||
|
gpio_output_options_set(HOST_POWERSW_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, HOST_POWERSW_VBUS); |
||||
|
|
||||
|
/* by default, disable is needed on output of the power switch */ |
||||
|
usb_vbus_drive(0U); |
||||
|
|
||||
|
/* delay is need for stabilizing the VBUS low in reset condition,
|
||||
|
* when VBUS = 1 and reset-button is pressed by user |
||||
|
*/ |
||||
|
usb_mdelay(200); |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#if defined(BSP_USING_TIMER2) && defined(BSP_USING_USB) |
||||
|
#error "Timer2 has been occupied by USB. Please select another timer resource." |
||||
|
#endif |
||||
|
/*!
|
||||
|
\brief initializes delay unit using Timer2 |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_timer_init(void) |
||||
|
{ |
||||
|
/* configure the priority group to 2 bits */ |
||||
|
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); |
||||
|
|
||||
|
/* enable the TIM2 global interrupt */ |
||||
|
nvic_irq_enable((uint8_t)TIMER2_IRQn, 1U, 0U); |
||||
|
|
||||
|
rcu_periph_clock_enable(RCU_TIMER2); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief delay in microseconds |
||||
|
\param[in] usec: value of delay required in microseconds |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_udelay(const uint32_t usec) |
||||
|
{ |
||||
|
hw_delay(usec, TIM_USEC_DELAY); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief delay in milliseconds |
||||
|
\param[in] msec: value of delay required in milliseconds |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_mdelay(const uint32_t msec) |
||||
|
{ |
||||
|
hw_delay(msec, TIM_MSEC_DELAY); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief time base IRQ |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void usb_timer_irq(void) |
||||
|
{ |
||||
|
if (RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_UP)) |
||||
|
{ |
||||
|
timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP); |
||||
|
|
||||
|
if (delay_time > 0x00U) |
||||
|
{ |
||||
|
delay_time--; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
timer_disable(TIMER2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TIMER2_IRQHandler(void) |
||||
|
{ |
||||
|
rt_interrupt_enter(); |
||||
|
|
||||
|
usb_timer_irq(); |
||||
|
|
||||
|
rt_interrupt_leave(); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief delay routine based on TIMER2 |
||||
|
\param[in] ntime: delay Time |
||||
|
\param[in] unit: delay Time unit = miliseconds / microseconds |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void hw_delay(uint32_t ntime, uint8_t unit) |
||||
|
{ |
||||
|
delay_time = ntime; |
||||
|
|
||||
|
hw_time_set(unit); |
||||
|
|
||||
|
while (0U != delay_time) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
timer_disable(TIMER2); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configures TIMER2 for delay routine based on TIMER2 |
||||
|
\param[in] unit: msec /usec |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void hw_time_set(uint8_t unit) |
||||
|
{ |
||||
|
timer_parameter_struct timer_basestructure; |
||||
|
|
||||
|
timer_disable(TIMER2); |
||||
|
timer_interrupt_disable(TIMER2, TIMER_INT_UP); |
||||
|
|
||||
|
if (TIM_USEC_DELAY == unit) |
||||
|
{ |
||||
|
timer_basestructure.period = 9U; |
||||
|
} |
||||
|
else if (TIM_MSEC_DELAY == unit) |
||||
|
{ |
||||
|
timer_basestructure.period = 9999U; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
/* no operation */ |
||||
|
} |
||||
|
|
||||
|
timer_basestructure.prescaler = timer_prescaler; |
||||
|
timer_basestructure.alignedmode = TIMER_COUNTER_EDGE; |
||||
|
timer_basestructure.counterdirection = TIMER_COUNTER_UP; |
||||
|
timer_basestructure.clockdivision = TIMER_CKDIV_DIV1; |
||||
|
timer_basestructure.repetitioncounter = 0U; |
||||
|
|
||||
|
timer_init(TIMER2, &timer_basestructure); |
||||
|
|
||||
|
timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP); |
||||
|
|
||||
|
timer_auto_reload_shadow_enable(TIMER2); |
||||
|
|
||||
|
/* TIMER IT enable */ |
||||
|
timer_interrupt_enable(TIMER2, TIMER_INT_UP); |
||||
|
|
||||
|
/* TIMER2 enable counter */ |
||||
|
timer_enable(TIMER2); |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure the PLL of USB |
||||
|
\param[in] usb_periph: USBHS0 or USBHS1 |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void pllusb_rcu_config(uint32_t usb_periph) |
||||
|
{ |
||||
|
if (USBHS0 == usb_periph) |
||||
|
{ |
||||
|
rcu_pllusb0_config(RCU_PLLUSBHSPRE_HXTAL, RCU_PLLUSBHSPRE_DIV5, RCU_PLLUSBHS_MUL96, RCU_USBHS_DIV8); |
||||
|
RCU_ADDCTL1 |= RCU_ADDCTL1_PLLUSBHS0EN; |
||||
|
while (0U == (RCU_ADDCTL1 & RCU_ADDCTL1_PLLUSBHS0STB)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
rcu_usbhs_clock_selection_enable(IDX_USBHS0); |
||||
|
rcu_usb48m_clock_config(IDX_USBHS0, RCU_USB48MSRC_PLLUSBHS); |
||||
|
rcu_usbhs_clock_config(IDX_USBHS0, RCU_USBHSSEL_60M); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
rcu_pllusb1_config(RCU_PLLUSBHSPRE_HXTAL, RCU_PLLUSBHSPRE_DIV5, RCU_PLLUSBHS_MUL96, RCU_USBHS_DIV8); |
||||
|
RCU_ADDCTL1 |= RCU_ADDCTL1_PLLUSBHS1EN; |
||||
|
while (0U == (RCU_ADDCTL1 & RCU_ADDCTL1_PLLUSBHS1STB)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
rcu_usbhs_clock_selection_enable(IDX_USBHS1); |
||||
|
rcu_usb48m_clock_config(IDX_USBHS1, RCU_USB48MSRC_PLLUSBHS); |
||||
|
rcu_usbhs_clock_config(IDX_USBHS1, RCU_USBHSSEL_60M); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* BSP_USING_USB */ |
||||
@ -0,0 +1,405 @@ |
|||||
|
/*!
|
||||
|
\file gd32h75e.h |
||||
|
\brief general definitions for GD32H75e |
||||
|
|
||||
|
\version 2025-01-24, V1.1.0, firmware for GD32H75E |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* Copyright (c) 2009-2021 Arm Limited. All rights reserved. |
||||
|
* Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ |
||||
|
|
||||
|
#ifndef GD32H75E_H |
||||
|
#define GD32H75E_H |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#if !defined (GD32H75E) |
||||
|
#error "Please select the target GD32H75E device used in your application (in gd32h75e.h file)" |
||||
|
#endif /* undefine GD32H75E tip */ |
||||
|
|
||||
|
/* define value of high speed crystal oscillator (HXTAL) in Hz */ |
||||
|
#if !defined (HXTAL_VALUE) |
||||
|
#define HXTAL_VALUE ((uint32_t)25000000) |
||||
|
#endif /* high speed crystal oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of high speed crystal oscillator (HXTAL) */ |
||||
|
#if !defined (HXTAL_STARTUP_TIMEOUT) |
||||
|
#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0FFFF) |
||||
|
#endif /* high speed crystal oscillator startup timeout */ |
||||
|
|
||||
|
/* define value of internal 64MHz RC oscillator (IRC64M) in Hz */ |
||||
|
#if !defined (IRC64M_VALUE) |
||||
|
#define IRC64M_VALUE ((uint32_t)64000000) |
||||
|
#endif /* internal 64MHz RC oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of internal 64MHz RC oscillator (IRC64M) */ |
||||
|
#if !defined (IRC64M_STARTUP_TIMEOUT) |
||||
|
#define IRC64M_STARTUP_TIMEOUT ((uint16_t)0x0500) |
||||
|
#endif /* internal 64MHz RC oscillator startup timeout */ |
||||
|
|
||||
|
/* define value of Low Power Internal 4Mhz RC oscillator (LPIRC4M) in Hz */ |
||||
|
#if !defined (LPIRC4M_VALUE) |
||||
|
#define LPIRC4M_VALUE ((uint32_t)4000000) |
||||
|
#endif /* Low Power Internal 4Mhz RC oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of internal Low Power Internal 4Mhz RC oscillator (LPIRC4M) */ |
||||
|
#if !defined (LPIRC4M_STARTUP_TIMEOUT) |
||||
|
#define LPIRC4M_STARTUP_TIMEOUT ((uint16_t)0x0500) |
||||
|
#endif /* Low Power Internal 4Mhz RC oscillator startup timeout */ |
||||
|
|
||||
|
/* define value of internal 48MHz RC oscillator (IRC48M) in Hz */ |
||||
|
#if !defined (IRC48M_VALUE) |
||||
|
#define IRC48M_VALUE ((uint32_t)48000000) |
||||
|
#endif /* internal 48MHz RC oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of internal 48MHz RC oscillator (IRC48M) */ |
||||
|
#if !defined (IRC48M_STARTUP_TIMEOUT) |
||||
|
#define IRC48M_STARTUP_TIMEOUT ((uint16_t)0x0500) |
||||
|
#endif /* internal 48MHz RC oscillator startup timeout */ |
||||
|
|
||||
|
/* define value of internal 32KHz RC oscillator(IRC32K) in Hz */ |
||||
|
#if !defined (IRC32K_VALUE) |
||||
|
#define IRC32K_VALUE ((uint32_t)32000) |
||||
|
#endif /* internal 32KHz RC oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of internal 32KHz RC oscillator (IRC32K) */ |
||||
|
#if !defined (IRC32K_STARTUP_TIMEOUT) |
||||
|
#define IRC32K_STARTUP_TIMEOUT ((uint16_t)0x0500) |
||||
|
#endif /* internal 32KHz RC oscillator startup timeout */ |
||||
|
|
||||
|
/* define value of low speed crystal oscillator (LXTAL)in Hz */ |
||||
|
#if !defined (LXTAL_VALUE) |
||||
|
#define LXTAL_VALUE ((uint32_t)32768) |
||||
|
#endif /* low speed crystal oscillator value */ |
||||
|
|
||||
|
/* define startup timeout value of low speed crystal oscillator (LXTAL) */ |
||||
|
#if !defined (LXTAL_STARTUP_TIMEOUT) |
||||
|
#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x0FFFFFFF) |
||||
|
#endif /* low speed crystal oscillator startup timeout */ |
||||
|
|
||||
|
/* GD32H75E firmware library version number V1.1.0 */ |
||||
|
#define __GD32H75E_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ |
||||
|
#define __GD32H75E_STDPERIPH_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */ |
||||
|
#define __GD32H75E_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ |
||||
|
#define __GD32H75E_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ |
||||
|
#define __GD32H75E_STDPERIPH_VERSION ((__GD32H75E_STDPERIPH_VERSION_MAIN << 24)\ |
||||
|
|(__GD32H75E_STDPERIPH_VERSION_SUB1 << 16)\ |
||||
|
|(__GD32H75E_STDPERIPH_VERSION_SUB2 << 8)\ |
||||
|
|(__GD32H75E_STDPERIPH_VERSION_RC)) |
||||
|
|
||||
|
/* configuration of the Cortex-M7 processor and core peripherals */ |
||||
|
#define __CM7_REV 0x0102U /*!< Cortex-M7 revision r1p2 */ |
||||
|
#define __MPU_PRESENT 1 /*!< CM7 provides an MPU */ |
||||
|
#define __NVIC_PRIO_BITS 4 /*!< CM7 uses 4 Bits for the Priority Levels */ |
||||
|
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ |
||||
|
#define __FPU_PRESENT 1 /*!< FPU present */ |
||||
|
#define __ICACHE_PRESENT 1 /*!< CM7 instruction cache present */ |
||||
|
#define __DCACHE_PRESENT 1 /*!< CM7 data cache present */ |
||||
|
|
||||
|
/* define interrupt number */ |
||||
|
typedef enum IRQn { |
||||
|
/* Cortex-M7 processor exceptions numbers */ |
||||
|
NonMaskableInt_IRQn = -14, /*!< non mask-able interrupt */ |
||||
|
HardFault_IRQn = -13, /*!< hard-fault interrupt */ |
||||
|
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M7 memory management interrupt */ |
||||
|
BusFault_IRQn = -11, /*!< 5 Cortex-M7 bus fault interrupt */ |
||||
|
UsageFault_IRQn = -10, /*!< 6 Cortex-M7 usage fault interrupt */ |
||||
|
SVCall_IRQn = -5, /*!< 11 Cortex-M7 sv call interrupt */ |
||||
|
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M7 debug monitor interrupt */ |
||||
|
PendSV_IRQn = -2, /*!< 14 Cortex-M7 pend sv interrupt */ |
||||
|
SysTick_IRQn = -1, /*!< 15 Cortex-M7 system tick interrupt */ |
||||
|
/* interruput numbers */ |
||||
|
WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ |
||||
|
VAVD_LVD_VOVD_IRQn = 1, /*!< AVD_LVD_OVD_IRQn through EXTI line detect interrupt */ |
||||
|
TAMPER_STAMP_LXTAL_IRQn = 2, /*!< RTC tamper and timestamp interrupt/LXTAL clock stuck interrupt */ |
||||
|
RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt */ |
||||
|
FMC_IRQn = 4, /*!< FMC interrupt */ |
||||
|
RCU_IRQn = 5, /*!< RCU interrupt */ |
||||
|
EXTI0_IRQn = 6, /*!< EXTI line 0 */ |
||||
|
EXTI1_IRQn = 7, /*!< EXTI line 1 */ |
||||
|
EXTI2_IRQn = 8, /*!< EXTI line 2 */ |
||||
|
EXTI3_IRQn = 9, /*!< EXTI line 3 */ |
||||
|
EXTI4_IRQn = 10, /*!< EXTI line 4 */ |
||||
|
DMA0_Channel0_IRQn = 11, /*!< DMA0 channel 0 interrupt */ |
||||
|
DMA0_Channel1_IRQn = 12, /*!< DMA0 channel 1 interrupt */ |
||||
|
DMA0_Channel2_IRQn = 13, /*!< DMA0 channel 2 interrupt */ |
||||
|
DMA0_Channel3_IRQn = 14, /*!< DMA0 channel 3 interrupt */ |
||||
|
DMA0_Channel4_IRQn = 15, /*!< DMA0 channel 4 interrupt */ |
||||
|
DMA0_Channel5_IRQn = 16, /*!< DMA0 channel 5 interrupt */ |
||||
|
DMA0_Channel6_IRQn = 17, /*!< DMA0 channel 6 interrupt */ |
||||
|
ADC0_1_IRQn = 18, /*!< ADC0 and ADC1 */ |
||||
|
EXTI5_9_IRQn = 23, /*!< EXTI line 5 to 9 */ |
||||
|
TIMER0_BRK_IRQn = 24, /*!< TIMER0 break interrupt */ |
||||
|
TIMER0_UP_IRQn = 25, /*!< TIMER0 update interrupt */ |
||||
|
TIMER0_TRG_CMT_IRQn = 26, /*!< TIMER0 trigger/commutation interrupt */ |
||||
|
TIMER0_Channel_IRQn = 27, /*!< TIMER0 capture/compare interrupt */ |
||||
|
TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ |
||||
|
TIMER2_IRQn = 29, /*!< TIMER2 interrupt */ |
||||
|
TIMER3_IRQn = 30, /*!< TIMER3 interrupt */ |
||||
|
I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */ |
||||
|
I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ |
||||
|
I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */ |
||||
|
I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ |
||||
|
SPI0_IRQn = 35, /*!< SPI0 interrupt */ |
||||
|
SPI1_IRQn = 36, /*!< SPI1 interrupt */ |
||||
|
USART0_IRQn = 37, /*!< USART0 global and wakeup interrupt */ |
||||
|
USART1_IRQn = 38, /*!< USART1 global and wakeup interrupt */ |
||||
|
USART2_IRQn = 39, /*!< USART2 global and wakeup interrupt */ |
||||
|
EXTI10_15_IRQn = 40, /*!< EXTI line 10 to 15 */ |
||||
|
RTC_Alarm_IRQn = 41, /*!< RTC Alarm interrupt */ |
||||
|
TIMER7_BRK_IRQn = 43, /*!< TIMER7 Break global interrupt */ |
||||
|
TIMER7_UP_IRQn = 44, /*!< TIMER7 Update global interrupt */ |
||||
|
TIMER7_TRG_CMT_IRQn = 45, /*!< TIMER7 Trigger and Commutation global interrupt */ |
||||
|
TIMER7_Channel_IRQn = 46, /*!< TIMER7 Capture Compare interrupt */ |
||||
|
DMA0_Channel7_IRQn = 47, /*!< DMA0 channel 7 interrupt */ |
||||
|
EXMC_IRQn = 48, /*!< EXMC interrupt */ |
||||
|
SDIO0_IRQn = 49, /*!< SDMMC0 interrupt */ |
||||
|
TIMER4_IRQn = 50, /*!< TIMER4 interrupt */ |
||||
|
SPI2_IRQn = 51, /*!< SPI2 interrupt */ |
||||
|
UART3_IRQn = 52, /*!< UART3 interrupt */ |
||||
|
UART4_IRQn = 53, /*!< UART4 interrupt */ |
||||
|
TIMER5_DAC_UDR_IRQn = 54, /*!< TIMER5 global interrupt and DAC1/DAC0 underrun */ |
||||
|
TIMER6_IRQn = 55, /*!< TIMER6 interrupt */ |
||||
|
DMA1_Channel0_IRQn = 56, /*!< DMA1 channel0 interrupt */ |
||||
|
DMA1_Channel1_IRQn = 57, /*!< DMA1 channel1 interrupt */ |
||||
|
DMA1_Channel2_IRQn = 58, /*!< DMA1 channel2 interrupt */ |
||||
|
DMA1_Channel3_IRQn = 59, /*!< DMA1 channel3 interrupt */ |
||||
|
DMA1_Channel4_IRQn = 60, /*!< DMA1 channel4 interrupt */ |
||||
|
ENET0_IRQn = 61, /*!< ENET 0 interrupt */ |
||||
|
ENET0_WKUP_IRQn = 62, /*!< ENET 0 wakeup through EXTI line interrupt */ |
||||
|
DMA1_Channel5_IRQn = 68, /*!< DMA1 channel 5 interrupt */ |
||||
|
DMA1_Channel6_IRQn = 69, /*!< DMA1 channel 6 interrupt */ |
||||
|
DMA1_Channel7_IRQn = 70, /*!< DMA1 channel 7 interrupt */ |
||||
|
USART5_IRQn = 71, /*!< UART5 global and wakeup interrupt */ |
||||
|
I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */ |
||||
|
I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */ |
||||
|
USBHS0_EP1_OUT_IRQn = 74, /*!< USBHS0 endpoint 1 out interrupt */ |
||||
|
USBHS0_EP1_IN_IRQn = 75, /*!< USBHS0 endpoint 1 in interrupt */ |
||||
|
USBHS0_WKUP_IRQn = 76, /*!< USBHS0 wakeup through EXTI line interrupt */ |
||||
|
USBHS0_IRQn = 77, /*!< USBHS0 interrupt */ |
||||
|
DCI_IRQn = 78, /*!< DCI interrupt */ |
||||
|
CAU_IRQn = 79, /*!< CAU interrupt */ |
||||
|
HAU_TRNG_IRQn = 80, /*!< HAU and TRNG interrupt */ |
||||
|
FPU_IRQn = 81, /*!< FPU interrupt */ |
||||
|
UART6_IRQn = 82, /*!< UART6 interrupt */ |
||||
|
UART7_IRQn = 83, /*!< UART7 interrupt */ |
||||
|
SPI3_IRQn = 84, /*!< SPI3 interrupt */ |
||||
|
SPI4_IRQn = 85, /*!< SPI4 interrupt */ |
||||
|
SPI5_IRQn = 86, /*!< SPI5 interrupt */ |
||||
|
SAI0_IRQn = 87, /*!< SAI0 interrupt */ |
||||
|
TLI_IRQn = 88, /*!< TLI interrupt */ |
||||
|
TLI_ER_IRQn = 89, /*!< TLI error interrupt */ |
||||
|
IPA_IRQn = 90, /*!< IPA interrupt */ |
||||
|
SAI1_IRQn = 91, /*!< SAI1 interrupt */ |
||||
|
OSPI0_IRQn = 92, /*!< OSPI0 global interrupt */ |
||||
|
I2C3_EV_IRQn = 95, /*!< I2C3 event interrupt */ |
||||
|
I2C3_ER_IRQn = 96, /*!< I2C3 error interrupt */ |
||||
|
RSPDIF_IRQn = 97, /*!< RSPDIF global interrupt */ |
||||
|
DMAMUX_OVR_IRQn = 102, /*!< DMAMUX overrun interrupt */ |
||||
|
HPDF_INT0_IRQn = 110, /*!< HPDF filiter 0 interrupt */ |
||||
|
HPDF_INT1_IRQn = 111, /*!< HPDF filiter 1 interrupt */ |
||||
|
HPDF_INT2_IRQn = 112, /*!< HPDF filiter 2 interrupt */ |
||||
|
HPDF_INT3_IRQn = 113, /*!< HPDF filiter 3 interrupt */ |
||||
|
SAI2_IRQn = 114, /*!< SAI2 interrupt */ |
||||
|
TIMER14_IRQn = 116, /*!< TIMER14 interrupt */ |
||||
|
TIMER15_IRQn = 117, /*!< TIMER15 interrupt */ |
||||
|
TIMER16_IRQn = 118, /*!< TIMER16 interrupt */ |
||||
|
MDIO_IRQn = 120, /*!< MDIO interrupt */ |
||||
|
MDMA_IRQn = 122, /*!< MDMA interrupt */ |
||||
|
SDIO1_IRQn = 124, /*!< SDIO1 interrupt */ |
||||
|
HWSEM_IRQn = 125, /*!< HWSEM interrupt */ |
||||
|
ADC2_IRQn = 127, /*!< ADC2 interrupt */ |
||||
|
CMP0_1_IRQn = 137, /*!< CMP0 and CMP1 interrupt */ |
||||
|
CTC_IRQn = 144, /*!< CTC interrupt */ |
||||
|
RAMECCMU_IRQn = 145, /*!< RAMECCMU interrupt */ |
||||
|
OSPI1_IRQn = 150, /*!< OSPI1 interrupt */ |
||||
|
RTDEC0_IRQn = 151, /*!< RTDEC0 interrupt */ |
||||
|
RTDEC1_IRQn = 152, /*!< RTDEC1 interrupt */ |
||||
|
FAC_IRQn = 153, /*!< FAC interrupt */ |
||||
|
TMU_IRQn = 154, /*!< TMU interrupt */ |
||||
|
TIMER22_IRQn = 161, /*!< TIMER22 interrupt */ |
||||
|
TIMER23_IRQn = 162, /*!< TIMER23 interrupt */ |
||||
|
TIMER40_IRQn = 165, /*!< TIMER40 interrupt */ |
||||
|
TIMER41_IRQn = 166, /*!< TIMER41 interrupt */ |
||||
|
TIMER42_IRQn = 167, /*!< TIMER42 interrupt */ |
||||
|
TIMER43_IRQn = 168, /*!< TIMER43 interrupt */ |
||||
|
TIMER44_IRQn = 169, /*!< TIMER44 interrupt */ |
||||
|
TIMER50_IRQn = 170, /*!< TIMER50 interrupt */ |
||||
|
TIMER51_IRQn = 171, /*!< TIMER51 interrupt */ |
||||
|
USBHS1_EP1_OUT_IRQn = 172, /*!< USBHS1 endpoint 1 out interrupt */ |
||||
|
USBHS1_EP1_IN_IRQn = 173, /*!< USBHS1 endpoint 1 in interrupt */ |
||||
|
USBHS1_WKUP_IRQn = 174, /*!< USBHS1 wakeup through EXTI line interrupt */ |
||||
|
USBHS1_IRQn = 175, /*!< USBHS1 interrupt */ |
||||
|
ENET1_IRQn = 176, /*!< ENET1 interrupt */ |
||||
|
ENET1_WKUP_IRQn = 177, /*!< ENET1 wakeup through EXTI line interrupt */ |
||||
|
CAN0_WKUP_IRQn = 179, /*!< CAN 0 wakeup through EXTI line interrupt */ |
||||
|
CAN0_Message_IRQn = 180, /*!< CAN 0 message buffer interrupt */ |
||||
|
CAN0_Busoff_IRQn = 181, /*!< CAN 0 bus off / bus off done interrupt */ |
||||
|
CAN0_Error_IRQn = 182, /*!< CAN 0 error interrupt */ |
||||
|
CAN0_FastError_IRQn = 183, /*!< CAN 0 error in fast transmission interrupt */ |
||||
|
CAN0_TEC_IRQn = 184, /*!< CAN 0 transmit warning interrupt */ |
||||
|
CAN0_REC_IRQn = 185, /*!< CAN 0 receive warning interrupt */ |
||||
|
CAN1_WKUP_IRQn = 186, /*!< CAN 1 wakeup through EXTI line interrupt */ |
||||
|
CAN1_Message_IRQn = 187, /*!< CAN 1 message buffer interrupt */ |
||||
|
CAN1_Busoff_IRQn = 188, /*!< CAN 1 bus off / bus off done interrupt */ |
||||
|
CAN1_Error_IRQn = 189, /*!< CAN 1 error interrupt */ |
||||
|
CAN1_FastError_IRQn = 190, /*!< CAN 1 error in fast transmission interrupt */ |
||||
|
CAN1_TEC_IRQn = 191, /*!< CAN 1 transmit warning interrupt */ |
||||
|
CAN1_REC_IRQn = 192, /*!< CAN 1 receive warning interrupt */ |
||||
|
CAN2_WKUP_IRQn = 193, /*!< CAN 2 wakeup through EXTI line interrupt */ |
||||
|
CAN2_Message_IRQn = 194, /*!< CAN 2 message buffer interrupt */ |
||||
|
CAN2_Busoff_IRQn = 195, /*!< CAN 2 bus off / bus off done interrupt */ |
||||
|
CAN2_Error_IRQn = 196, /*!< CAN 2 error interrupt */ |
||||
|
CAN2_FastError_IRQn = 197, /*!< CAN 2 error in fast transmission interrupt */ |
||||
|
CAN2_TEC_IRQn = 198, /*!< CAN 2 transmit warning interrupt */ |
||||
|
CAN2_REC_IRQn = 199, /*!< CAN 2 receive warning interrupt */ |
||||
|
EFUSE_IRQn = 200, /*!< EFUSE interrupt */ |
||||
|
I2C0_WKUP_IRQn = 201, /*!< I2C 0 wakeup through EXTI line interrupt */ |
||||
|
I2C1_WKUP_IRQn = 202, /*!< I2C 1 wakeup through EXTI line interrupt */ |
||||
|
I2C2_WKUP_IRQn = 203, /*!< I2C 2 wakeup through EXTI line interrupt */ |
||||
|
I2C3_WKUP_IRQn = 204, /*!< I2C 3 wakeup through EXTI line interrupt */ |
||||
|
LPDTS_IRQn = 205, /*!< LPDTS interrupt */ |
||||
|
LPDTS_WKUP_IRQn = 206, /*!< LPDTS wakeup through EXTI line interrupt */ |
||||
|
TIMER0_DEC_IRQn = 207, /*!< TIMER0 DEC interrupt */ |
||||
|
TIMER7_DEC_IRQn = 208, /*!< TIMER7 DEC interrupt */ |
||||
|
TIMER1_DEC_IRQn = 209, /*!< TIMER1 DEC interrupt */ |
||||
|
TIMER2_DEC_IRQn = 210, /*!< TIMER2 DEC interrupt */ |
||||
|
TIMER3_DEC_IRQn = 211, /*!< TIMER3 DEC interrupt */ |
||||
|
TIMER4_DEC_IRQn = 212, /*!< TIMER4 DEC interrupt */ |
||||
|
TIMER22_DEC_IRQn = 213, /*!< TIMER22 DEC interrupt */ |
||||
|
TIMER23_DEC_IRQn = 214, /*!< TIMER23 DEC interrupt */ |
||||
|
} IRQn_Type; |
||||
|
|
||||
|
/* includes */ |
||||
|
#include "core_cm7.h" |
||||
|
#include "system_gd32h75e.h" |
||||
|
#include <stdint.h> |
||||
|
#ifdef FW_DEBUG_ERR_REPORT |
||||
|
#include "gd32h75e_err_report.h" |
||||
|
#endif /* FW_DEBUG_ERR_REPORT */ |
||||
|
|
||||
|
/* enum definitions */ |
||||
|
typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; |
||||
|
typedef enum {RESET = 0, SET = !RESET} FlagStatus; |
||||
|
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; |
||||
|
|
||||
|
/* bit operations */ |
||||
|
#define REG64(addr) (*(volatile uint64_t *)(uint32_t)(addr)) |
||||
|
#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) |
||||
|
#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) |
||||
|
#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) |
||||
|
#define BIT(x) ((uint32_t)((uint32_t)0x01U << (x))) |
||||
|
#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) |
||||
|
#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) |
||||
|
|
||||
|
/* main flash and SRAM memory map */ |
||||
|
#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ |
||||
|
#define SRAM_BASE ((uint32_t)0x24000000U) /*!< SRAM base address */ |
||||
|
/* SRAM and peripheral base bit-band region */ |
||||
|
#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ |
||||
|
#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ |
||||
|
/* peripheral memory map */ |
||||
|
#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ |
||||
|
#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ |
||||
|
#define APB3_BUS_BASE ((uint32_t)0x50000000U) /*!< apb3 base address */ |
||||
|
#define APB4_BUS_BASE ((uint32_t)0x58000000U) /*!< apb4 base address */ |
||||
|
#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ |
||||
|
#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ |
||||
|
#define AHB3_BUS_BASE ((uint32_t)0x51000000U) /*!< ahb3 base address */ |
||||
|
#define AHB4_BUS_BASE ((uint32_t)0x58020000U) /*!< ahb4 base address */ |
||||
|
/* advanced peripheral bus 1 memory map */ |
||||
|
#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ |
||||
|
#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ |
||||
|
#define RSPDIF_BASE (APB1_BUS_BASE + 0x00004000U) /*!< RSPDIF base address */ |
||||
|
#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ |
||||
|
#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ |
||||
|
#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ |
||||
|
#define CTC_BASE (APB1_BUS_BASE + 0x00008400U) /*!< CTC base address */ |
||||
|
#define MDIO_BASE (APB1_BUS_BASE + 0x00009400U) /*!< MDIO base address */ |
||||
|
/* advanced peripheral bus 2 memory map */ |
||||
|
#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ |
||||
|
#define SAI_BASE (APB2_BUS_BASE + 0x00005800U) /*!< SAI base address */ |
||||
|
#define HPDF_BASE (APB2_BUS_BASE + 0x00007000U) /*!< HPDF base address */ |
||||
|
#define TRIGSEL_BASE (APB2_BUS_BASE + 0x00008400U) /*!< TRIGSEL base address */ |
||||
|
#define EDOUT_BASE (APB2_BUS_BASE + 0x00008800U) /*!< EDOUT base address */ |
||||
|
#define CAN_BASE (APB2_BUS_BASE + 0x0000A000U) /*!< CAN base address */ |
||||
|
/* advanced peripheral bus 3 memory map */ |
||||
|
#define TLI_BASE (APB3_BUS_BASE + 0x00001000U) /*!< TLI base address */ |
||||
|
#define WWDGT_BASE (APB3_BUS_BASE + 0x00003000U) /*!< WWDGT base address */ |
||||
|
/* advanced peripheral bus 4 memory map */ |
||||
|
#define EXTI_BASE (APB4_BUS_BASE + 0x00000000U) /*!< EXTI base address */ |
||||
|
#define SYSCFG_BASE (APB4_BUS_BASE + 0x00000400U) /*!< SYSCFG base address */ |
||||
|
#define CMP_BASE (APB4_BUS_BASE + 0x00003800U) /*!< CMP base address */ |
||||
|
#define VREF_BASE (APB4_BUS_BASE + 0x00003C00U) /*!< VREF base address */ |
||||
|
#define RTC_BASE (APB4_BUS_BASE + 0x00004000U) /*!< CMP base address */ |
||||
|
#define FWDGT_BASE (APB4_BUS_BASE + 0x00004800U) /*!< FWDGT base address */ |
||||
|
#define PMU_BASE (APB4_BUS_BASE + 0x00005800U) /*!< PMU base address */ |
||||
|
#define LPDTS_BASE (APB4_BUS_BASE + 0x00006800U) /*!< LPDTS base address */ |
||||
|
/* advanced high performance bus 1 memory map */ |
||||
|
#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ |
||||
|
#define DMAMUX_BASE (AHB1_BUS_BASE + 0x00000800U) /*!< DMAMUX base address */ |
||||
|
#define EFUSE_BASE (AHB1_BUS_BASE + 0x00002800U) /*!< EFUSE base address */ |
||||
|
#define ENET_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< ENET base address */ |
||||
|
#define USBHS_BASE (AHB1_BUS_BASE + 0x00020000U) /*!< USBHS base address */ |
||||
|
/* advanced high performance bus 2 memory map */ |
||||
|
#define DCI_BASE (AHB2_BUS_BASE + 0x00020000U) /*!< DCI base address */ |
||||
|
#define CAU_BASE (AHB2_BUS_BASE + 0x00021000U) /*!< CAU base address */ |
||||
|
#define HAU_BASE (AHB2_BUS_BASE + 0x00021400U) /*!< HAU base address */ |
||||
|
#define TRNG_BASE (AHB2_BUS_BASE + 0x00021800U) /*!< TRNG base address */ |
||||
|
#define SDIO_BASE (AHB2_BUS_BASE + 0x00022400U) /*!< SDIO base address */ |
||||
|
#define CPDM_BASE (AHB2_BUS_BASE + 0x00022800U) /*!< CPDM base address */ |
||||
|
#define RAMECCMU_BASE (AHB2_BUS_BASE + 0x00023000U) /*!< RAMECCMU base address */ |
||||
|
#define TMU_BASE (AHB2_BUS_BASE + 0x00024400U) /*!< TMU base address */ |
||||
|
#define FAC_BASE (AHB2_BUS_BASE + 0x00024800U) /*!< FAC base address */ |
||||
|
/* advanced high performance bus 3 memory map */ |
||||
|
#define AXIM_BASE (AHB3_BUS_BASE + 0x00000000U) /*!< AXIM base address */ |
||||
|
#define MDMA_BASE (AHB3_BUS_BASE + 0x01000000U) /*!< MDMA base address */ |
||||
|
#define IPA_BASE (AHB3_BUS_BASE + 0x01001000U) /*!< IPA base address */ |
||||
|
#define FMC_BASE (AHB3_BUS_BASE + 0x01002000U) /*!< FMC base address */ |
||||
|
#define FLEXRAMC_BASE (AHB3_BUS_BASE + 0x01003000U) /*!< FLEXRAMC base address */ |
||||
|
#define EXMC_BASE (AHB3_BUS_BASE + 0x01004000U) /*!< EXMC base address */ |
||||
|
#define OSPI_BASE (AHB3_BUS_BASE + 0x01005000U) /*!< OSPI base address */ |
||||
|
#define OSPM_BASE (AHB3_BUS_BASE + 0x0100B400U) /*!< OSPM base address */ |
||||
|
#define RTDEC_BASE (AHB3_BUS_BASE + 0x0100B800U) /*!< RTDEC base address */ |
||||
|
/* advanced high performance bus 4 memory map */ |
||||
|
#define GPIO_BASE (AHB4_BUS_BASE + 0x00000000U) /*!< GPIO base address */ |
||||
|
#define RCU_BASE (AHB4_BUS_BASE + 0x00004400U) /*!< RCU base address */ |
||||
|
#define CRC_BASE (AHB4_BUS_BASE + 0x00004C00U) /*!< CRC base address */ |
||||
|
#define HWSEM_BASE (AHB4_BUS_BASE + 0x00006400U) /*!< HWSEM base address */ |
||||
|
/* option byte and debug memory map */ |
||||
|
#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ |
||||
|
#define DBG_BASE ((uint32_t)0xE00E1000U) /*!< DBG base address */ |
||||
|
|
||||
|
/* define marco USE_STDPERIPH_DRIVER */ |
||||
|
#if !defined USE_STDPERIPH_DRIVER |
||||
|
#define USE_STDPERIPH_DRIVER |
||||
|
#endif |
||||
|
#ifdef USE_STDPERIPH_DRIVER |
||||
|
#include "gd32h75e_libopt.h" |
||||
|
#endif /* USE_STDPERIPH_DRIVER */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* GD32H75E_H */ |
||||
@ -0,0 +1,111 @@ |
|||||
|
/*!
|
||||
|
\file gd32h75e_report_err.h |
||||
|
\brief Reporting Error driver |
||||
|
|
||||
|
\version 2025-01-24, V1.1.0, firmware for GD32H75E |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without modification, |
||||
|
are permitted provided that the following conditions are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright notice, this |
||||
|
list of conditions and the following disclaimer. |
||||
|
2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
this list of conditions and the following disclaimer in the documentation |
||||
|
and/or other materials provided with the distribution. |
||||
|
3. Neither the name of the copyright holder nor the names of its contributors |
||||
|
may be used to endorse or promote products derived from this software without |
||||
|
specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
||||
|
OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
#ifndef HSM_ERR_REPORT_H |
||||
|
#define HSM_ERR_REPORT_H |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
/* define the size of the error report buffer */ |
||||
|
#define ERR_REPORT_BUFFER_SIZE 60U |
||||
|
|
||||
|
/* define the unique identifier of peripherals */ |
||||
|
#define SYSCFG_MODULE_ID ((uint8_t)0x01U) /*!< SYSCFG module ID */ |
||||
|
#define RAMECCMU_MODULE_ID ((uint8_t)0x02U) /*!< RAMECCMU module ID */ |
||||
|
#define FMC_MODULE_ID ((uint8_t)0x03U) /*!< FMC module ID */ |
||||
|
#define EFUSE_MODULE_ID ((uint8_t)0x04U) /*!< EFUSE module ID */ |
||||
|
#define PMU_MODULE_ID ((uint8_t)0x05U) /*!< PMU module ID */ |
||||
|
#define RCU_MODULE_ID ((uint8_t)0x06U) /*!< RCU module ID */ |
||||
|
#define CTC_MODULE_ID ((uint8_t)0x07U) /*!< CTC module ID */ |
||||
|
#define EXTI_MODULE_ID ((uint8_t)0x08U) /*!< EXTI module ID */ |
||||
|
#define TRIGSEL_MODULE_ID ((uint8_t)0x09U) /*!< TRIGSEL module ID */ |
||||
|
#define GPIO_MODULE_ID ((uint8_t)0x0AU) /*!< GPIO module ID */ |
||||
|
#define CRC_MODULE_ID ((uint8_t)0x0BU) /*!< CRC module ID */ |
||||
|
#define TRNG_MODULE_ID ((uint8_t)0x0CU) /*!< TRNG module ID */ |
||||
|
#define TMU_MODULE_ID ((uint8_t)0x0DU) /*!< TMU module ID */ |
||||
|
#define DMA_DMAMUX_MODULE_ID ((uint8_t)0x0EU) /*!< DMA and DMAMUX module ID */ |
||||
|
#define MDMA_MODULE_ID ((uint8_t)0x0FU) /*!< MDMA module ID */ |
||||
|
#define DBG_MODULE_ID ((uint8_t)0x10U) /*!< DBG module ID */ |
||||
|
#define ADC_MODULE_ID ((uint8_t)0x11U) /*!< ADC module ID */ |
||||
|
#define DAC_MODULE_ID ((uint8_t)0x12U) /*!< DAC module ID */ |
||||
|
#define FWDGT_MODULE_ID ((uint8_t)0x13U) /*!< FWDGT module ID */ |
||||
|
#define WWDGT_MODULE_ID ((uint8_t)0x14U) /*!< WWDGT module ID */ |
||||
|
#define RTC_MODULE_ID ((uint8_t)0x15U) /*!< RTC module ID */ |
||||
|
#define TIMER_MODULE_ID ((uint8_t)0x16U) /*!< TIMER module ID */ |
||||
|
#define USART_MODULE_ID ((uint8_t)0x17U) /*!< USART module ID */ |
||||
|
#define I2C_MODULE_ID ((uint8_t)0x18U) /*!< I2C module ID */ |
||||
|
#define SPI_MODULE_ID ((uint8_t)0x19U) /*!< SPI module ID */ |
||||
|
#define OSPIM_MODULE_ID ((uint8_t)0x1AU) /*!< OSPIM module ID */ |
||||
|
#define OSPI_MODULE_ID ((uint8_t)0x1BU) /*!< OSPI module ID */ |
||||
|
#define EXMC_MODULE_ID ((uint8_t)0x1CU) /*!< EXMC module ID */ |
||||
|
#define VREF_MODULE_ID ((uint8_t)0x1DU) /*!< VREF module ID */ |
||||
|
#define LPDTS_MODULE_ID ((uint8_t)0x1EU) /*!< LPDTS module ID */ |
||||
|
#define EDOUT_MODULE_ID ((uint8_t)0x1FU) /*!< EDOUT module ID */ |
||||
|
#define CAN_MODULE_ID ((uint8_t)0x20U) /*!< CAN module ID */ |
||||
|
#define CMP_MODULE_ID ((uint8_t)0x21U) /*!< CMP module ID */ |
||||
|
#define HPDF_MODULE_ID ((uint8_t)0x22U) /*!< HPDF module ID */ |
||||
|
#define FAC_MODULE_ID ((uint8_t)0x23U) /*!< FAC module ID */ |
||||
|
#define MISC_MODULE_ID ((uint8_t)0x24U) /*!< MISC module ID */ |
||||
|
#define USBHS_MODULE_ID ((uint8_t)0x25U) /*!< USBHS module ID */ |
||||
|
#define ESC_MODULE_ID ((uint8_t)0x26U) /*!< ESC module ID */ |
||||
|
|
||||
|
/* define the unique identifier of error type */ |
||||
|
#define ERR_PERIPH ((uint8_t)0x01U) /*!< peripheral error */ |
||||
|
#define ERR_PARAM_POINTER ((uint8_t)0x02U) /*!< invalid pointer */ |
||||
|
#define ERR_PARAM_OUT_OF_RANGE ((uint8_t)0x03U) /*!< out of range */ |
||||
|
#define ERR_PARAM_INVALID ((uint8_t)0x04U) /*!< invalid parameter */ |
||||
|
|
||||
|
/* define the unique identifier of API */ |
||||
|
#define API_ID(x) ((uint16_t)(x)) /*!< API ID */ |
||||
|
|
||||
|
/* definitions for parameter checking */ |
||||
|
#define NOT_VALID_POINTER(x) ((void *) 0 == (x)) /*!< check the invalid pointer */ |
||||
|
|
||||
|
/* defining the structure to store the parameters of Report Error function */ |
||||
|
typedef struct { |
||||
|
/* module ID where the error occurred */ |
||||
|
uint16_t moduleid; |
||||
|
/* API ID associated with the error */ |
||||
|
uint16_t apiid; |
||||
|
/* error ID indicating the specific error type */ |
||||
|
uint8_t errid; |
||||
|
} err_report_struct; |
||||
|
|
||||
|
/* declare external arrays and variables for error reporting */ |
||||
|
extern err_report_struct err_report_buffer[ERR_REPORT_BUFFER_SIZE]; |
||||
|
/* index to track the next available position in the error report buffer */ |
||||
|
extern uint8_t err_report_buff_index; |
||||
|
/* reporting errors in debug mode */ |
||||
|
void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid); |
||||
|
|
||||
|
#endif /* ERR_REPORT_H */ |
||||
@ -0,0 +1,76 @@ |
|||||
|
/*!
|
||||
|
\file gd32h75e_libopt.h |
||||
|
\brief library optional for gd32h75e |
||||
|
|
||||
|
\version 2025-08-07, V1.2.0, firmware for GD32H75E |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without modification, |
||||
|
are permitted provided that the following conditions are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright notice, this |
||||
|
list of conditions and the following disclaimer. |
||||
|
2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
this list of conditions and the following disclaimer in the documentation |
||||
|
and/or other materials provided with the distribution. |
||||
|
3. Neither the name of the copyright holder nor the names of its contributors |
||||
|
may be used to endorse or promote products derived from this software without |
||||
|
specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
||||
|
OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef GD32H75E_LIBOPT_H |
||||
|
#define GD32H75E_LIBOPT_H |
||||
|
|
||||
|
#include "gd32h75e_adc.h" |
||||
|
#include "gd32h75e_axiim.h" |
||||
|
#include "gd32h75e_can.h" |
||||
|
#include "gd32h75e_cmp.h" |
||||
|
#include "gd32h75e_crc.h" |
||||
|
#include "gd32h75e_ctc.h" |
||||
|
#include "gd32h75e_dac.h" |
||||
|
#include "gd32h75e_dbg.h" |
||||
|
#include "gd32h75e_dma.h" |
||||
|
#include "gd32h75e_edout.h" |
||||
|
#include "gd32h75e_efuse.h" |
||||
|
#include "gd32h75e_exmc.h" |
||||
|
#include "gd32h75e_exti.h" |
||||
|
#include "gd32h75e_fac.h" |
||||
|
#include "gd32h75e_fmc.h" |
||||
|
#include "gd32h75e_fwdgt.h" |
||||
|
#include "gd32h75e_gpio.h" |
||||
|
#include "gd32h75e_hpdf.h" |
||||
|
#include "gd32h75e_i2c.h" |
||||
|
#include "gd32h75e_lpdts.h" |
||||
|
#include "gd32h75e_mdma.h" |
||||
|
#include "gd32h75e_misc.h" |
||||
|
#include "gd32h75e_ospi.h" |
||||
|
#include "gd32h75e_ospim.h" |
||||
|
#include "gd32h75e_pmu.h" |
||||
|
#include "gd32h75e_rameccmu.h" |
||||
|
#include "gd32h75e_rcu.h" |
||||
|
#include "gd32h75e_rtc.h" |
||||
|
#include "gd32h75e_spi.h" |
||||
|
#include "gd32h75e_syscfg.h" |
||||
|
#include "gd32h75e_timer.h" |
||||
|
#include "gd32h75e_tmu.h" |
||||
|
#include "gd32h75e_trigsel.h" |
||||
|
#include "gd32h75e_trng.h" |
||||
|
#include "gd32h75e_usart.h" |
||||
|
#include "gd32h75e_vref.h" |
||||
|
#include "gd32h75e_wwdgt.h" |
||||
|
|
||||
|
#endif /* GD32H75E_LIBOPT_H */ |
||||
@ -0,0 +1,56 @@ |
|||||
|
/*!
|
||||
|
\file system_gd32h75e.h |
||||
|
\brief CMSIS Cortex-M7 Device Peripheral Access Layer Header File for |
||||
|
gd32h75e Device Series |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* Copyright (c) 2009-2021 Arm Limited. All rights reserved. |
||||
|
* Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ |
||||
|
|
||||
|
#ifndef SYSTEM_GD32H75E_H |
||||
|
#define SYSTEM_GD32H75E_H |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
/* firmware version can be aquired by uncommenting the macro */ |
||||
|
#define __FIRMWARE_VERSION_DEFINE |
||||
|
|
||||
|
/* system clock frequency (core clock) */ |
||||
|
extern uint32_t SystemCoreClock; |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* initialize the system and update the SystemCoreClock variable */ |
||||
|
extern void SystemInit (void); |
||||
|
/* update the SystemCoreClock with current core clock retrieved from cpu registers */ |
||||
|
extern void SystemCoreClockUpdate (void); |
||||
|
#ifdef __FIRMWARE_VERSION_DEFINE |
||||
|
/* get firmware version */ |
||||
|
extern uint32_t gd32h75e_firmware_version_get(void); |
||||
|
#endif /* __FIRMWARE_VERSION_DEFINE */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif /* SYSTEM_GD32H75E_H */ |
||||
@ -0,0 +1,750 @@ |
|||||
|
.syntax unified |
||||
|
.cpu cortex-m7 |
||||
|
.fpu softvfp |
||||
|
.thumb |
||||
|
|
||||
|
.global Default_Handler |
||||
|
|
||||
|
/* necessary symbols defined in linker script to initialize data */ |
||||
|
.word _sidata |
||||
|
.word _sdata |
||||
|
.word _edata |
||||
|
.word _sbss |
||||
|
.word _ebss |
||||
|
|
||||
|
.section .text.Reset_Handler |
||||
|
.weak Reset_Handler |
||||
|
.type Reset_Handler, %function |
||||
|
|
||||
|
/* reset Handler */ |
||||
|
Reset_Handler: |
||||
|
movs r1, #0 |
||||
|
b DataInit |
||||
|
|
||||
|
CopyData: |
||||
|
ldr r3, =_sidata |
||||
|
ldr r3, [r3, r1] |
||||
|
str r3, [r0, r1] |
||||
|
adds r1, r1, #4 |
||||
|
|
||||
|
DataInit: |
||||
|
ldr r0, =_sdata |
||||
|
ldr r3, =_edata |
||||
|
adds r2, r0, r1 |
||||
|
cmp r2, r3 |
||||
|
bcc CopyData |
||||
|
ldr r2, =_sbss |
||||
|
b Zerobss |
||||
|
|
||||
|
FillZerobss: |
||||
|
movs r3, #0 |
||||
|
str r3, [r2], #4 |
||||
|
|
||||
|
Zerobss: |
||||
|
ldr r3, = _ebss |
||||
|
cmp r2, r3 |
||||
|
bcc FillZerobss |
||||
|
/* Call SystemInit function */ |
||||
|
bl SystemInit |
||||
|
/* Call static constructors */ |
||||
|
bl __libc_init_array |
||||
|
/*Call the main function */ |
||||
|
bl entry |
||||
|
bx lr |
||||
|
|
||||
|
.size Reset_Handler, .-Reset_Handler |
||||
|
|
||||
|
.section .text.Default_Handler,"ax",%progbits |
||||
|
Default_Handler: |
||||
|
Infinite_Loop: |
||||
|
b Infinite_Loop |
||||
|
.size Default_Handler, .-Default_Handler |
||||
|
|
||||
|
.section .vectors,"a",%progbits |
||||
|
.global __gVectors |
||||
|
|
||||
|
__gVectors: |
||||
|
.word _sp /* Top of Stack */ |
||||
|
.word Reset_Handler /* Reset Handler */ |
||||
|
.word NMI_Handler /* NMI Handler */ |
||||
|
.word HardFault_Handler /* Hard Fault Handler */ |
||||
|
.word MemManage_Handler /* MPU Fault Handler */ |
||||
|
.word BusFault_Handler /* Bus Fault Handler */ |
||||
|
.word UsageFault_Handler /* Usage Fault Handler */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word SVC_Handler /* SVCall Handler */ |
||||
|
.word DebugMon_Handler /* Debug Monitor Handler */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word PendSV_Handler /* PendSV Handler */ |
||||
|
.word SysTick_Handler /* SysTick Handler */ |
||||
|
|
||||
|
/* External interrupts handler */ |
||||
|
.word WWDGT_IRQHandler /* Vector Number 16,Window Watchdog Timer */ |
||||
|
.word VAVD_LVD_VOVD_IRQHandler /* Vector Number 17,VAVD/LVD/VOVD through EXTI Line detect */ |
||||
|
.word TAMPER_STAMP_LXTAL_IRQHandler /* Vector Number 18,RTC Tamper and TimeStamp through EXTI Line detect, LXTAL clock security system interrupt */ |
||||
|
.word RTC_WKUP_IRQHandler /* Vector Number 19,RTC Wakeup from EXTI interrupt */ |
||||
|
.word FMC_IRQHandler /* Vector Number 20,FMC global interrupt */ |
||||
|
.word RCU_IRQHandler /* Vector Number 21,RCU global interrupt */ |
||||
|
.word EXTI0_IRQHandler /* Vector Number 22,EXTI Line 0 */ |
||||
|
.word EXTI1_IRQHandler /* Vector Number 23,EXTI Line 1 */ |
||||
|
.word EXTI2_IRQHandler /* Vector Number 24,EXTI Line 2 */ |
||||
|
.word EXTI3_IRQHandler /* Vector Number 25,EXTI Line 3 */ |
||||
|
.word EXTI4_IRQHandler /* Vector Number 26,EXTI Line 4 */ |
||||
|
.word DMA0_Channel0_IRQHandler /* Vector Number 27,DMA0 Channel 0 */ |
||||
|
.word DMA0_Channel1_IRQHandler /* Vector Number 28,DMA0 Channel 1 */ |
||||
|
.word DMA0_Channel2_IRQHandler /* Vector Number 29,DMA0 Channel 2 */ |
||||
|
.word DMA0_Channel3_IRQHandler /* Vector Number 30,DMA0 Channel 3 */ |
||||
|
.word DMA0_Channel4_IRQHandler /* Vector Number 31,DMA0 Channel 4 */ |
||||
|
.word DMA0_Channel5_IRQHandler /* Vector Number 32,DMA0 Channel 5 */ |
||||
|
.word DMA0_Channel6_IRQHandler /* Vector Number 33,DMA0 Channel 6 */ |
||||
|
.word ADC0_1_IRQHandler /* Vector Number 34,ADC0 and ADC1 interrupt */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word EXTI5_9_IRQHandler /* Vector Number 39,EXTI5 to EXTI9 */ |
||||
|
.word TIMER0_BRK_IRQHandler /* Vector Number 40,TIMER0 Break */ |
||||
|
.word TIMER0_UP_IRQHandler /* Vector Number 41,TIMER0 Update */ |
||||
|
.word TIMER0_TRG_CMT_IRQHandler /* Vector Number 42,TIMER0 Trigger and Commutation */ |
||||
|
.word TIMER0_Channel_IRQHandler /* Vector Number 43,TIMER0 Capture Compare */ |
||||
|
.word TIMER1_IRQHandler /* Vector Number 44,TIMER1 */ |
||||
|
.word TIMER2_IRQHandler /* Vector Number 45,TIMER2 */ |
||||
|
.word TIMER3_IRQHandler /* Vector Number 46,TIMER3 */ |
||||
|
.word I2C0_EV_IRQHandler /* Vector Number 47,I2C0 Event */ |
||||
|
.word I2C0_ER_IRQHandler /* Vector Number 48,I2C0 Error */ |
||||
|
.word I2C1_EV_IRQHandler /* Vector Number 49,I2C1 Event */ |
||||
|
.word I2C1_ER_IRQHandler /* Vector Number 50,I2C1 Error */ |
||||
|
.word SPI0_IRQHandler /* Vector Number 51,SPI0 */ |
||||
|
.word SPI1_IRQHandler /* Vector Number 52,SPI1 */ |
||||
|
.word USART0_IRQHandler /* Vector Number 53,USART0 global and wakeup */ |
||||
|
.word USART1_IRQHandler /* Vector Number 54,USART1 global and wakeup */ |
||||
|
.word USART2_IRQHandler /* Vector Number 55,USART2 global and wakeup */ |
||||
|
.word EXTI10_15_IRQHandler /* Vector Number 56,EXTI10 to EXTI15 */ |
||||
|
.word RTC_Alarm_IRQHandler /* Vector Number 57,RTC Alarm */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word TIMER7_BRK_IRQHandler /* Vector Number 59,TIMER7 Break */ |
||||
|
.word TIMER7_UP_IRQHandler /* Vector Number 60,TIMER7 Update */ |
||||
|
.word TIMER7_TRG_CMT_IRQHandler /* Vector Number 61,TIMER7 Trigger and Commutation */ |
||||
|
.word TIMER7_Channel_IRQHandler /* Vector Number 62,TIMER7 Channel Capture Compare */ |
||||
|
.word DMA0_Channel7_IRQHandler /* Vector Number 63,DMA0 Channel 7 */ |
||||
|
.word EXMC_IRQHandler /* Vector Number 64,EXMC */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word TIMER4_IRQHandler /* Vector Number 66,TIMER4 */ |
||||
|
.word SPI2_IRQHandler /* Vector Number 67,SPI2 */ |
||||
|
.word UART3_IRQHandler /* Vector Number 68,UART3 */ |
||||
|
.word UART4_IRQHandler /* Vector Number 69,UART4 */ |
||||
|
.word TIMER5_DAC_UDR_IRQHandler /* Vector Number 70,TIMER5 global interrupt and DAC1/DAC0 underrun error */ |
||||
|
.word TIMER6_IRQHandler /* Vector Number 71,TIMER6 */ |
||||
|
.word DMA1_Channel0_IRQHandler /* Vector Number 72,DMA1 Channel0 */ |
||||
|
.word DMA1_Channel1_IRQHandler /* Vector Number 73,DMA1 Channel1 */ |
||||
|
.word DMA1_Channel2_IRQHandler /* Vector Number 74,DMA1 Channel2 */ |
||||
|
.word DMA1_Channel3_IRQHandler /* Vector Number 75,DMA1 Channel3 */ |
||||
|
.word DMA1_Channel4_IRQHandler /* Vector Number 76,DMA1 Channel4 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word DMA1_Channel5_IRQHandler /* Vector Number 84,DMA1 Channel5 */ |
||||
|
.word DMA1_Channel6_IRQHandler /* Vector Number 85,DMA1 Channel6 */ |
||||
|
.word DMA1_Channel7_IRQHandler /* Vector Number 86,DMA1 Channel7 */ |
||||
|
.word USART5_IRQHandler /* Vector Number 87,USART5 global and wakeup */ |
||||
|
.word I2C2_EV_IRQHandler /* Vector Number 88,I2C2 Event */ |
||||
|
.word I2C2_ER_IRQHandler /* Vector Number 89,I2C2 Error */ |
||||
|
.word USBHS0_EP1_OUT_IRQHandler /* Vector Number 90,USBHS0 Endpoint 1 Out */ |
||||
|
.word USBHS0_EP1_IN_IRQHandler /* Vector Number 91,USBHS0 Endpoint 1 in */ |
||||
|
.word USBHS0_WKUP_IRQHandler /* Vector Number 92,USBHS0 Wakeup through EXTI Line */ |
||||
|
.word USBHS0_IRQHandler /* Vector Number 93,USBHS0 */ |
||||
|
.word 0 /* Vector Number 94,Reserved */ |
||||
|
.word 0 /* Vector Number 95,Reserved */ |
||||
|
.word TRNG_IRQHandler /* Vector Number 96,TRNG */ |
||||
|
.word FPU_IRQHandler /* Vector Number 97,FPU */ |
||||
|
.word UART6_IRQHandler /* Vector Number 98,UART6 */ |
||||
|
.word UART7_IRQHandler /* Vector Number 99,UART7 */ |
||||
|
.word SPI3_IRQHandler /* Vector Number 100,SPI3 */ |
||||
|
.word SPI4_IRQHandler /* Vector Number 101,SPI4 */ |
||||
|
.word SPI5_IRQHandler /* Vector Number 102,SPI5 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word OSPI0_IRQHandler /* Vector Number 108,OSPI0 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word I2C3_EV_IRQHandler /* Vector Number 111,I2C3 Event */ |
||||
|
.word I2C3_ER_IRQHandler /* Vector Number 112,I2C3 Error */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word DMAMUX_OVR_IRQHandler /* Vector Number 118,DMAMUX Overrun interrupt */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word HPDF_INT0_IRQHandler /* Vector Number 126,HPDF global interrupt 0 */ |
||||
|
.word HPDF_INT1_IRQHandler /* Vector Number 127,HPDF global interrupt 1 */ |
||||
|
.word HPDF_INT2_IRQHandler /* Vector Number 128,HPDF global interrupt 2 */ |
||||
|
.word HPDF_INT3_IRQHandler /* Vector Number 129,HPDF global interrupt 3 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word TIMER14_IRQHandler /* Vector Number 132,TIMER14 */ |
||||
|
.word TIMER15_IRQHandler /* Vector Number 133,TIMER15 */ |
||||
|
.word TIMER16_IRQHandler /* Vector Number 134,TIMER16 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word MDMA_IRQHandler /* Vector Number 138,MDMA */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word ADC2_IRQHandler /* Vector Number 143,ADC2 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word CMP0_1_IRQHandler /* Vector Number 153,CMP0 and CMP1 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word CTC_IRQHandler /* Vector Number 160,Clock Recovery System */ |
||||
|
.word RAMECCMU_IRQHandler /* Vector Number 161,RAMECCMU */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word OSPI1_IRQHandler /* Vector Number 166,OSPI1 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word FAC_IRQHandler /* Vector Number 169,FAC */ |
||||
|
.word TMU_IRQHandler /* Vector Number 170,TMU */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word TIMER22_IRQHandler /* Vector Number 177,TIMER22 */ |
||||
|
.word TIMER23_IRQHandler /* Vector Number 178,TIMER23 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word TIMER40_IRQHandler /* Vector Number 181,TIMER40 */ |
||||
|
.word TIMER41_IRQHandler /* Vector Number 182,TIMER41 */ |
||||
|
.word TIMER42_IRQHandler /* Vector Number 183,TIMER42 */ |
||||
|
.word TIMER43_IRQHandler /* Vector Number 184,TIMER43 */ |
||||
|
.word TIMER44_IRQHandler /* Vector Number 185,TIMER44 */ |
||||
|
.word TIMER50_IRQHandler /* Vector Number 186,TIMER50 */ |
||||
|
.word TIMER51_IRQHandler /* Vector Number 187,TIMER51 */ |
||||
|
.word USBHS1_EP1_OUT_IRQHandler /* Vector Number 188,USBHS1 endpoint 1 out */ |
||||
|
.word USBHS1_EP1_IN_IRQHandler /* Vector Number 189,USBHS1 endpoint 1 in */ |
||||
|
.word USBHS1_WKUP_IRQHandler /* Vector Number 190,USBHS1 wakeup */ |
||||
|
.word USBHS1_IRQHandler /* Vector Number 191,USBHS1 */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word CAN0_WKUP_IRQHandler /* Vector Number 195,CAN0 wakeup */ |
||||
|
.word CAN0_Message_IRQHandler /* Vector Number 196,CAN0 interrupt for message buffer */ |
||||
|
.word CAN0_Busoff_IRQHandler /* Vector Number 197,CAN0 interrupt for Bus off / Bus off done */ |
||||
|
.word CAN0_Error_IRQHandler /* Vector Number 198,CAN0 interrupt for Error */ |
||||
|
.word CAN0_FastError_IRQHandler /* Vector Number 199,CAN0 interrupt for Error in fast transmission */ |
||||
|
.word CAN0_TEC_IRQHandler /* Vector Number 200,CAN0 interrupt for Transmit warning */ |
||||
|
.word CAN0_REC_IRQHandler /* Vector Number 201,CAN0 interrupt for Receive warning */ |
||||
|
.word CAN1_WKUP_IRQHandler /* Vector Number 202,CAN1 wakeup */ |
||||
|
.word CAN1_Message_IRQHandler /* Vector Number 203,CAN1 interrupt for message buffer */ |
||||
|
.word CAN1_Busoff_IRQHandler /* Vector Number 204,CAN1 interrupt for Bus off / Bus off done */ |
||||
|
.word CAN1_Error_IRQHandler /* Vector Number 205,CAN1 interrupt for Error */ |
||||
|
.word CAN1_FastError_IRQHandler /* Vector Number 206,CAN1 interrupt for Error in fast transmission */ |
||||
|
.word CAN1_TEC_IRQHandler /* Vector Number 207,CAN1 interrupt for Transmit warning */ |
||||
|
.word CAN1_REC_IRQHandler /* Vector Number 208,CAN1 interrupt for Receive warning */ |
||||
|
.word CAN2_WKUP_IRQHandler /* Vector Number 209,CAN2 wakeup */ |
||||
|
.word CAN2_Message_IRQHandler /* Vector Number 210,CAN2 interrupt for message buffer */ |
||||
|
.word CAN2_Busoff_IRQHandler /* Vector Number 211,CAN2 interrupt for Bus off / Bus off done */ |
||||
|
.word CAN2_Error_IRQHandler /* Vector Number 212,CAN2 interrupt for Error */ |
||||
|
.word CAN2_FastError_IRQHandler /* Vector Number 213,CAN2 interrupt for Error in fast transmission */ |
||||
|
.word CAN2_TEC_IRQHandler /* Vector Number 214,CAN2 interrupt for Transmit warning */ |
||||
|
.word CAN2_REC_IRQHandler /* Vector Number 215,CAN2 interrupt for Receive warning */ |
||||
|
.word EFUSE_IRQHandler /* Vector Number 216,EFUSE */ |
||||
|
.word I2C0_WKUP_IRQHandler /* Vector Number 217,I2C0 wakeup */ |
||||
|
.word I2C1_WKUP_IRQHandler /* Vector Number 218,I2C1 wakeup */ |
||||
|
.word I2C2_WKUP_IRQHandler /* Vector Number 219,I2C2 wakeup */ |
||||
|
.word I2C3_WKUP_IRQHandler /* Vector Number 220,I2C3 wakeup */ |
||||
|
.word LPDTS_IRQHandler /* Vector Number 221,LPDTS */ |
||||
|
.word LPDTS_WKUP_IRQHandler /* Vector Number 222,LPDTS wakeup */ |
||||
|
.word TIMER0_DEC_IRQHandler /* Vector Number 223,TIMER0 DEC */ |
||||
|
.word TIMER7_DEC_IRQHandler /* Vector Number 224,TIMER7 DEC */ |
||||
|
.word TIMER1_DEC_IRQHandler /* Vector Number 225,TIMER1 DEC */ |
||||
|
.word TIMER2_DEC_IRQHandler /* Vector Number 226,TIMER2 DEC */ |
||||
|
.word TIMER3_DEC_IRQHandler /* Vector Number 227,TIMER3 DEC */ |
||||
|
.word TIMER4_DEC_IRQHandler /* Vector Number 228,TIMER4 DEC */ |
||||
|
.word TIMER22_DEC_IRQHandler /* Vector Number 229,TIMER22 DEC */ |
||||
|
.word TIMER23_DEC_IRQHandler /* Vector Number 230,TIMER23 DEC */ |
||||
|
.word 0 /* Reserved */ |
||||
|
.word 0 /* Reserved */ |
||||
|
|
||||
|
.size __gVectors, . - __gVectors |
||||
|
|
||||
|
.weak NMI_Handler |
||||
|
.thumb_set NMI_Handler,Default_Handler |
||||
|
|
||||
|
.weak HardFault_Handler |
||||
|
.thumb_set HardFault_Handler,Default_Handler |
||||
|
|
||||
|
.weak MemManage_Handler |
||||
|
.thumb_set MemManage_Handler,Default_Handler |
||||
|
|
||||
|
.weak BusFault_Handler |
||||
|
.thumb_set BusFault_Handler,Default_Handler |
||||
|
|
||||
|
.weak UsageFault_Handler |
||||
|
.thumb_set UsageFault_Handler,Default_Handler |
||||
|
|
||||
|
.weak SVC_Handler |
||||
|
.thumb_set SVC_Handler,Default_Handler |
||||
|
|
||||
|
.weak DebugMon_Handler |
||||
|
.thumb_set DebugMon_Handler,Default_Handler |
||||
|
|
||||
|
.weak PendSV_Handler |
||||
|
.thumb_set PendSV_Handler,Default_Handler |
||||
|
|
||||
|
.weak SysTick_Handler |
||||
|
.thumb_set SysTick_Handler,Default_Handler |
||||
|
|
||||
|
.weak WWDGT_IRQHandler |
||||
|
.thumb_set WWDGT_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak VAVD_LVD_VOVD_IRQHandler |
||||
|
.thumb_set VAVD_LVD_VOVD_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TAMPER_STAMP_LXTAL_IRQHandler |
||||
|
.thumb_set TAMPER_STAMP_LXTAL_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak RTC_WKUP_IRQHandler |
||||
|
.thumb_set RTC_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak FMC_IRQHandler |
||||
|
.thumb_set FMC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak RCU_IRQHandler |
||||
|
.thumb_set RCU_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI0_IRQHandler |
||||
|
.thumb_set EXTI0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI1_IRQHandler |
||||
|
.thumb_set EXTI1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI2_IRQHandler |
||||
|
.thumb_set EXTI2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI3_IRQHandler |
||||
|
.thumb_set EXTI3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI4_IRQHandler |
||||
|
.thumb_set EXTI4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel0_IRQHandler |
||||
|
.thumb_set DMA0_Channel0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel1_IRQHandler |
||||
|
.thumb_set DMA0_Channel1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel2_IRQHandler |
||||
|
.thumb_set DMA0_Channel2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel3_IRQHandler |
||||
|
.thumb_set DMA0_Channel3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel4_IRQHandler |
||||
|
.thumb_set DMA0_Channel4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel5_IRQHandler |
||||
|
.thumb_set DMA0_Channel5_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel6_IRQHandler |
||||
|
.thumb_set DMA0_Channel6_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak ADC0_1_IRQHandler |
||||
|
.thumb_set ADC0_1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI5_9_IRQHandler |
||||
|
.thumb_set EXTI5_9_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER0_BRK_IRQHandler |
||||
|
.thumb_set TIMER0_BRK_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER0_UP_IRQHandler |
||||
|
.thumb_set TIMER0_UP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER0_TRG_CMT_IRQHandler |
||||
|
.thumb_set TIMER0_TRG_CMT_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER0_Channel_IRQHandler |
||||
|
.thumb_set TIMER0_Channel_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER1_IRQHandler |
||||
|
.thumb_set TIMER1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER2_IRQHandler |
||||
|
.thumb_set TIMER2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER3_IRQHandler |
||||
|
.thumb_set TIMER3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C0_EV_IRQHandler |
||||
|
.thumb_set I2C0_EV_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C0_ER_IRQHandler |
||||
|
.thumb_set I2C0_ER_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C1_EV_IRQHandler |
||||
|
.thumb_set I2C1_EV_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C1_ER_IRQHandler |
||||
|
.thumb_set I2C1_ER_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI0_IRQHandler |
||||
|
.thumb_set SPI0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI1_IRQHandler |
||||
|
.thumb_set SPI1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USART0_IRQHandler |
||||
|
.thumb_set USART0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USART1_IRQHandler |
||||
|
.thumb_set USART1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USART2_IRQHandler |
||||
|
.thumb_set USART2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXTI10_15_IRQHandler |
||||
|
.thumb_set EXTI10_15_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak RTC_Alarm_IRQHandler |
||||
|
.thumb_set RTC_Alarm_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER7_BRK_IRQHandler |
||||
|
.thumb_set TIMER7_BRK_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER7_UP_IRQHandler |
||||
|
.thumb_set TIMER7_UP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER7_TRG_CMT_IRQHandler |
||||
|
.thumb_set TIMER7_TRG_CMT_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER7_Channel_IRQHandler |
||||
|
.thumb_set TIMER7_Channel_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA0_Channel7_IRQHandler |
||||
|
.thumb_set DMA0_Channel7_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EXMC_IRQHandler |
||||
|
.thumb_set EXMC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER4_IRQHandler |
||||
|
.thumb_set TIMER4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI2_IRQHandler |
||||
|
.thumb_set SPI2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak UART3_IRQHandler |
||||
|
.thumb_set UART3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak UART4_IRQHandler |
||||
|
.thumb_set UART4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER5_DAC_UDR_IRQHandler |
||||
|
.thumb_set TIMER5_DAC_UDR_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER6_IRQHandler |
||||
|
.thumb_set TIMER6_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel0_IRQHandler |
||||
|
.thumb_set DMA1_Channel0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel1_IRQHandler |
||||
|
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel2_IRQHandler |
||||
|
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel3_IRQHandler |
||||
|
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel4_IRQHandler |
||||
|
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel5_IRQHandler |
||||
|
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel6_IRQHandler |
||||
|
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMA1_Channel7_IRQHandler |
||||
|
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USART5_IRQHandler |
||||
|
.thumb_set USART5_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C2_EV_IRQHandler |
||||
|
.thumb_set I2C2_EV_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C2_ER_IRQHandler |
||||
|
.thumb_set I2C2_ER_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS0_EP1_OUT_IRQHandler |
||||
|
.thumb_set USBHS0_EP1_OUT_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS0_EP1_IN_IRQHandler |
||||
|
.thumb_set USBHS0_EP1_IN_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS0_WKUP_IRQHandler |
||||
|
.thumb_set USBHS0_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS0_IRQHandler |
||||
|
.thumb_set USBHS0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TRNG_IRQHandler |
||||
|
.thumb_set TRNG_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak FPU_IRQHandler |
||||
|
.thumb_set FPU_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak UART6_IRQHandler |
||||
|
.thumb_set UART6_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak UART7_IRQHandler |
||||
|
.thumb_set UART7_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI3_IRQHandler |
||||
|
.thumb_set SPI3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI4_IRQHandler |
||||
|
.thumb_set SPI4_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak SPI5_IRQHandler |
||||
|
.thumb_set SPI5_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak OSPI0_IRQHandler |
||||
|
.thumb_set OSPI0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C3_EV_IRQHandler |
||||
|
.thumb_set I2C3_EV_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C3_ER_IRQHandler |
||||
|
.thumb_set I2C3_ER_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak DMAMUX_OVR_IRQHandler |
||||
|
.thumb_set DMAMUX_OVR_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak HPDF_INT0_IRQHandler |
||||
|
.thumb_set HPDF_INT0_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak HPDF_INT1_IRQHandler |
||||
|
.thumb_set HPDF_INT1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak HPDF_INT2_IRQHandler |
||||
|
.thumb_set HPDF_INT2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak HPDF_INT3_IRQHandler |
||||
|
.thumb_set HPDF_INT3_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER14_IRQHandler |
||||
|
.thumb_set TIMER14_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER15_IRQHandler |
||||
|
.thumb_set TIMER15_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER16_IRQHandler |
||||
|
.thumb_set TIMER16_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak MDMA_IRQHandler |
||||
|
.thumb_set MDMA_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak ADC2_IRQHandler |
||||
|
.thumb_set ADC2_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CMP0_1_IRQHandler |
||||
|
.thumb_set CMP0_1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CTC_IRQHandler |
||||
|
.thumb_set CTC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak RAMECCMU_IRQHandler |
||||
|
.thumb_set RAMECCMU_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak OSPI1_IRQHandler |
||||
|
.thumb_set OSPI1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak FAC_IRQHandler |
||||
|
.thumb_set FAC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TMU_IRQHandler |
||||
|
.thumb_set TMU_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER22_IRQHandler |
||||
|
.thumb_set TIMER22_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER23_IRQHandler |
||||
|
.thumb_set TIMER23_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER40_IRQHandler |
||||
|
.thumb_set TIMER40_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER41_IRQHandler |
||||
|
.thumb_set TIMER41_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER42_IRQHandler |
||||
|
.thumb_set TIMER42_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER43_IRQHandler |
||||
|
.thumb_set TIMER43_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER44_IRQHandler |
||||
|
.thumb_set TIMER44_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER50_IRQHandler |
||||
|
.thumb_set TIMER50_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER51_IRQHandler |
||||
|
.thumb_set TIMER51_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS1_EP1_OUT_IRQHandler |
||||
|
.thumb_set USBHS1_EP1_OUT_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS1_EP1_IN_IRQHandler |
||||
|
.thumb_set USBHS1_EP1_IN_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS1_WKUP_IRQHandler |
||||
|
.thumb_set USBHS1_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak USBHS1_IRQHandler |
||||
|
.thumb_set USBHS1_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_WKUP_IRQHandler |
||||
|
.thumb_set CAN0_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_Message_IRQHandler |
||||
|
.thumb_set CAN0_Message_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_Busoff_IRQHandler |
||||
|
.thumb_set CAN0_Busoff_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_Error_IRQHandler |
||||
|
.thumb_set CAN0_Error_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_FastError_IRQHandler |
||||
|
.thumb_set CAN0_FastError_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_TEC_IRQHandler |
||||
|
.thumb_set CAN0_TEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN0_REC_IRQHandler |
||||
|
.thumb_set CAN0_REC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_WKUP_IRQHandler |
||||
|
.thumb_set CAN1_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_Message_IRQHandler |
||||
|
.thumb_set CAN1_Message_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_Busoff_IRQHandler |
||||
|
.thumb_set CAN1_Busoff_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_Error_IRQHandler |
||||
|
.thumb_set CAN1_Error_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_FastError_IRQHandler |
||||
|
.thumb_set CAN1_FastError_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_TEC_IRQHandler |
||||
|
.thumb_set CAN1_TEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN1_REC_IRQHandler |
||||
|
.thumb_set CAN1_REC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_WKUP_IRQHandler |
||||
|
.thumb_set CAN2_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_Message_IRQHandler |
||||
|
.thumb_set CAN2_Message_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_Busoff_IRQHandler |
||||
|
.thumb_set CAN2_Busoff_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_Error_IRQHandler |
||||
|
.thumb_set CAN2_Error_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_FastError_IRQHandler |
||||
|
.thumb_set CAN2_FastError_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_TEC_IRQHandler |
||||
|
.thumb_set CAN2_TEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak CAN2_REC_IRQHandler |
||||
|
.thumb_set CAN2_REC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak EFUSE_IRQHandler |
||||
|
.thumb_set EFUSE_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C0_WKUP_IRQHandler |
||||
|
.thumb_set I2C0_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C1_WKUP_IRQHandler |
||||
|
.thumb_set I2C1_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C2_WKUP_IRQHandler |
||||
|
.thumb_set I2C2_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak I2C3_WKUP_IRQHandler |
||||
|
.thumb_set I2C3_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak LPDTS_IRQHandler |
||||
|
.thumb_set LPDTS_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak LPDTS_WKUP_IRQHandler |
||||
|
.thumb_set LPDTS_WKUP_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER0_DEC_IRQHandler |
||||
|
.thumb_set TIMER0_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER7_DEC_IRQHandler |
||||
|
.thumb_set TIMER7_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER1_DEC_IRQHandler |
||||
|
.thumb_set TIMER1_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER2_DEC_IRQHandler |
||||
|
.thumb_set TIMER2_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER3_DEC_IRQHandler |
||||
|
.thumb_set TIMER3_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER4_DEC_IRQHandler |
||||
|
.thumb_set TIMER4_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER22_DEC_IRQHandler |
||||
|
.thumb_set TIMER22_DEC_IRQHandler,Default_Handler |
||||
|
|
||||
|
.weak TIMER23_DEC_IRQHandler |
||||
|
.thumb_set TIMER23_DEC_IRQHandler,Default_Handler |
||||
@ -0,0 +1,61 @@ |
|||||
|
/*!
|
||||
|
\file gd32h75e_report_err.c |
||||
|
\brief Reporting Error driver |
||||
|
|
||||
|
\version 2025-01-24, V1.1.0, firmware for GD32H75E |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without modification, |
||||
|
are permitted provided that the following conditions are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright notice, this |
||||
|
list of conditions and the following disclaimer. |
||||
|
2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
this list of conditions and the following disclaimer in the documentation |
||||
|
and/or other materials provided with the distribution. |
||||
|
3. Neither the name of the copyright holder nor the names of its contributors |
||||
|
may be used to endorse or promote products derived from this software without |
||||
|
specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
||||
|
OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
|
||||
|
#include "gd32h75e_err_report.h" |
||||
|
|
||||
|
/* initialize the error report buffer and index */ |
||||
|
err_report_struct err_report_buffer[ERR_REPORT_BUFFER_SIZE]; |
||||
|
uint8_t err_report_buff_index = 0x00U; |
||||
|
|
||||
|
/*!
|
||||
|
\brief reporting error in debug mode |
||||
|
\param[in] moduleid: module ID where the error occurred |
||||
|
\param[in] apiid: API ID associated with the error |
||||
|
\param[in] errid: error ID indicating the specific error type |
||||
|
\param[out] err_report_buffer: stores the id of the error type |
||||
|
\retval none |
||||
|
*/ |
||||
|
void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid) |
||||
|
{ |
||||
|
err_report_struct *debug_report_err_buffer; |
||||
|
|
||||
|
if(err_report_buff_index < ERR_REPORT_BUFFER_SIZE) { |
||||
|
debug_report_err_buffer = &err_report_buffer[err_report_buff_index++]; |
||||
|
debug_report_err_buffer->moduleid = moduleid; |
||||
|
debug_report_err_buffer->apiid = apiid; |
||||
|
debug_report_err_buffer->errid = errid; |
||||
|
} else { |
||||
|
/* illegal parameters */ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,877 @@ |
|||||
|
/*!
|
||||
|
\file system_gd32h75e.c |
||||
|
\brief CMSIS Cortex-M7 Device Peripheral Access Layer Source File for |
||||
|
gd32h75e Device Series |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
* Copyright (c) 2009-2021 Arm Limited. All rights reserved. |
||||
|
* Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ |
||||
|
|
||||
|
#include "gd32h75e.h" |
||||
|
|
||||
|
/* system frequency define */ |
||||
|
#define __IRC64M (IRC64M_VALUE) /* internal 64 MHz RC oscillator frequency */ |
||||
|
#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ |
||||
|
#define __LPIRC4M (LPIRC4M_VALUE) /* low power internal 4 MHz RC oscillator frequency */ |
||||
|
#define __SYS_OSC_CLK (__IRC64M) /* main oscillator frequency */ |
||||
|
|
||||
|
#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */ |
||||
|
#define RCU_APB4EN_SYSCFG (uint32_t)0x01 /* enable SYSCFG clk */ |
||||
|
|
||||
|
/* select a system clock by uncommenting the following line */ |
||||
|
/* use IRC64M */ |
||||
|
//#define __SYSTEM_CLOCK_IRC64M (__IRC64M)
|
||||
|
//#define __SYSTEM_CLOCK_480M_PLL0_IRC64M (uint32_t)(480000000)
|
||||
|
//#define __SYSTEM_CLOCK_600M_PLL0_IRC64M (uint32_t)(600000000)
|
||||
|
|
||||
|
/* use LPIRC4M */ |
||||
|
//#define __SYSTEM_CLOCK_LPIRC4M (__LPIRC4M)
|
||||
|
|
||||
|
/* use HXTAL(CK_HXTAL = 25M) */ |
||||
|
//#define __SYSTEM_CLOCK_HXTAL (__HXTAL)
|
||||
|
//#define __SYSTEM_CLOCK_200M_PLL0_HXTAL (uint32_t)(200000000)
|
||||
|
//#define __SYSTEM_CLOCK_400M_PLL0_HXTAL (uint32_t)(400000000)
|
||||
|
//#define __SYSTEM_CLOCK_480M_PLL0_HXTAL (uint32_t)(480000000)
|
||||
|
#define __SYSTEM_CLOCK_600M_PLL0_HXTAL (uint32_t)(600000000) |
||||
|
|
||||
|
/*
|
||||
|
Note: the power mode need to match the mcu selection and external power supply circuit. |
||||
|
|
||||
|
according to the selected mcu and external power supply circuit to uncomment |
||||
|
the following macro SEL_PMU_SMPS_MODE. |
||||
|
*/ |
||||
|
//#define SEL_PMU_SMPS_MODE PMU_LDO_SUPPLY
|
||||
|
//#define SEL_PMU_SMPS_MODE PMU_DIRECT_SMPS_SUPPLY
|
||||
|
//#define SEL_PMU_SMPS_MODE PMU_BYPASS
|
||||
|
|
||||
|
#define SEL_IRC64MDIV 0x00U |
||||
|
#define SEL_HXTAL 0x01U |
||||
|
#define SEL_LPIRC4M 0x02U |
||||
|
#define SEL_PLL0P 0x03U |
||||
|
|
||||
|
#define PLL0PSC_REG_OFFSET 0U |
||||
|
#define PLL0N_REG_OFFSET 6U |
||||
|
#define PLL0P_REG_OFFSET 16U |
||||
|
#define PLL0Q_REG_OFFSET 0U |
||||
|
#define PLL0R_REG_OFFSET 24U |
||||
|
|
||||
|
/* set the system clock frequency and declare the system clock configuration function */ |
||||
|
#ifdef __SYSTEM_CLOCK_IRC64M |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC64M; |
||||
|
static void system_clock_64m_irc64m(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M) |
||||
|
#define PLL0PSC 16U |
||||
|
#define PLL0N (120U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_IRC64M; |
||||
|
static void system_clock_480m_irc64m(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) |
||||
|
#define PLL0PSC 16U |
||||
|
#define PLL0N (150U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_IRC64M; |
||||
|
static void system_clock_600m_irc64m(void); |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_LPIRC4M; |
||||
|
static void system_clock_4m_lpirc4m(void); |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_HXTAL) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; |
||||
|
static void system_clock_hxtal(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) |
||||
|
#define PLL0PSC 5U |
||||
|
#define PLL0N (40U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL0_HXTAL; |
||||
|
static void system_clock_200m_hxtal(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) |
||||
|
#define PLL0PSC 5U |
||||
|
#define PLL0N (80U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_400M_PLL0_HXTAL; |
||||
|
static void system_clock_400m_hxtal(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL) |
||||
|
#define PLL0PSC 5U |
||||
|
#define PLL0N (96U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_HXTAL; |
||||
|
static void system_clock_480m_hxtal(void); |
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) |
||||
|
#define PLL0PSC 5U |
||||
|
#define PLL0N (120U - 1U) |
||||
|
#define PLL0P (1U - 1U) |
||||
|
#define PLL0Q (2U - 1U) |
||||
|
#define PLL0R (2U - 1U) |
||||
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_HXTAL; |
||||
|
static void system_clock_600m_hxtal(void); |
||||
|
#endif /* __SYSTEM_CLOCK_IRC64M */ |
||||
|
|
||||
|
/* configure the system clock */ |
||||
|
static void system_clock_config(void); |
||||
|
|
||||
|
/*!
|
||||
|
\brief setup the microcontroller system, initialize the system |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void SystemInit(void) |
||||
|
{ |
||||
|
/* FPU settings */ |
||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1U) |
||||
|
/* set CP10 and CP11 Full Access */ |
||||
|
SCB->CPACR |= (uint32_t)((0x03U << 10U * 2U) | (0x03U << 11U * 2U)); |
||||
|
#endif |
||||
|
/* enable IRC64M */ |
||||
|
RCU_CTL |= RCU_CTL_IRC64MEN; |
||||
|
while(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { |
||||
|
} |
||||
|
|
||||
|
/* no TCM wait state */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
|
||||
|
/* reset RCU */ |
||||
|
/* reset HXTALEN, CKMEN, PLL0EN, PLL1EN, PLL2EN, PLLUSB0 and PLLUSB1 bits */ |
||||
|
RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLL0EN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_HXTALBPS); |
||||
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_PLLUSBHS0EN | RCU_ADDCTL1_PLLUSBHS1EN | RCU_ADDCTL1_LPIRC4MEN); |
||||
|
/* reset CFG0, CFG1, CFG2, CFG3 registers */ |
||||
|
RCU_CFG0 &= ~(RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_APB3PSC | RCU_CFG0_APB4PSC | RCU_CFG0_AHBPSC | |
||||
|
RCU_CFG0_I2C0SEL | RCU_CFG0_SCS | RCU_CFG0_RTCDIV); |
||||
|
RCU_CFG1 &= ~(RCU_CFG1_HPDFSEL | RCU_CFG1_TIMERSEL | RCU_CFG1_PERSEL | |
||||
|
RCU_CFG1_USART0SEL | RCU_CFG1_USART1SEL | RCU_CFG1_USART2SEL | RCU_CFG1_USART5SEL | RCU_CFG1_PLL2RDIV); |
||||
|
RCU_CFG2 &= ~(RCU_CFG2_HPDFASEL | RCU_CFG2_CKOUT0SEL | RCU_CFG2_CKOUT1SEL | RCU_CFG2_CKOUT0DIV | RCU_CFG2_CKOUT1DIV); |
||||
|
RCU_CFG3 &= ~(RCU_CFG3_ADC01SEL | RCU_CFG3_ADC2SEL |
||||
|
| RCU_CFG3_I2C3SEL | RCU_CFG3_I2C2SEL | RCU_CFG3_I2C1SEL); |
||||
|
RCU_CFG4 &= ~(RCU_CFG4_EXMCSEL); |
||||
|
RCU_CFG5 &= ~(RCU_CFG5_SPI0SEL | RCU_CFG5_SPI1SEL | RCU_CFG5_SPI2SEL | |
||||
|
RCU_CFG5_SPI3SEL | RCU_CFG5_SPI4SEL | RCU_CFG5_SPI5SEL); |
||||
|
/* disable all interrupts */ |
||||
|
RCU_INT = 0x14FF0000U; |
||||
|
RCU_ADDINT = 0x00700000U; |
||||
|
/* reset all PLL0 parameter */ |
||||
|
RCU_PLL0 = 0x01002020U; |
||||
|
RCU_PLL1 = 0x01012020U; |
||||
|
RCU_PLL2 = 0x01012020U; |
||||
|
RCU_PLLALL = 0x00000000U; |
||||
|
RCU_PLLADDCTL = 0x00010101U; |
||||
|
RCU_PLLUSBCFG = 0x00000000U; |
||||
|
RCU_PLL0FRA = 0x00000000U; |
||||
|
RCU_PLL1FRA = 0x00000000U; |
||||
|
RCU_PLL2FRA = 0x00000000U; |
||||
|
|
||||
|
#if defined (SEL_PMU_SMPS_MODE) |
||||
|
/* power supply config */ |
||||
|
pmu_smps_ldo_supply_config(SEL_PMU_SMPS_MODE); |
||||
|
#endif |
||||
|
|
||||
|
/* configure system clock */ |
||||
|
system_clock_config(); |
||||
|
|
||||
|
#ifdef VECT_TAB_SRAM |
||||
|
nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET); |
||||
|
#else |
||||
|
nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
\brief configure the system clock |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_config(void) |
||||
|
{ |
||||
|
#ifdef __SYSTEM_CLOCK_IRC64M |
||||
|
system_clock_64m_irc64m(); |
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M) |
||||
|
system_clock_480m_irc64m(); |
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) |
||||
|
system_clock_600m_irc64m(); |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M) |
||||
|
system_clock_4m_lpirc4m(); |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_HXTAL) |
||||
|
system_clock_hxtal(); |
||||
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) |
||||
|
system_clock_200m_hxtal(); |
||||
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) |
||||
|
system_clock_400m_hxtal(); |
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL) |
||||
|
system_clock_480m_hxtal(); |
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) |
||||
|
system_clock_600m_hxtal(); |
||||
|
#endif /* __SYSTEM_CLOCK_IRC64M */ |
||||
|
} |
||||
|
|
||||
|
#ifdef __SYSTEM_CLOCK_IRC64M |
||||
|
/*!
|
||||
|
\brief configure the system clock to 64M by IRC64M |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_64m_irc64m(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable IRC64M */ |
||||
|
RCU_CTL |= RCU_CTL_IRC64MEN; |
||||
|
|
||||
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB); |
||||
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout)); |
||||
|
|
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* AHB = SYSCLK / 1 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; |
||||
|
/* APB4 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; |
||||
|
/* APB3 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; |
||||
|
|
||||
|
/* configure IRC64M div */ |
||||
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV); |
||||
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1; |
||||
|
|
||||
|
/* select IRC64M as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_IRC64MDIV; |
||||
|
|
||||
|
/* wait until IRC64M is selected as system clock */ |
||||
|
while(RCU_SCSS_IRC64MDIV != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 480M by PLL0 which selects IRC64M as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_480m_irc64m(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable IRC64M */ |
||||
|
RCU_CTL |= RCU_CTL_IRC64MEN; |
||||
|
|
||||
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB); |
||||
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout)); |
||||
|
|
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* insert TCM wait state at 480MHz */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
/* IRC64M is already stable */ |
||||
|
/* AHB = SYSCLK / 2 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */ |
||||
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV); |
||||
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1; |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = IRC64MDIV / 16 * 120 / 1 = 480 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL0 */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 600M by PLL0 which selects IRC64M as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_600m_irc64m(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable IRC64M */ |
||||
|
RCU_CTL |= RCU_CTL_IRC64MEN; |
||||
|
|
||||
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB); |
||||
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout)); |
||||
|
|
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* insert TCM wait state at 600MHz */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
/* IRC64M is already stable */ |
||||
|
/* AHB = SYSCLK / 2 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */ |
||||
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV); |
||||
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1; |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = IRC64MDIV / 16 * 150 / 1 = 600 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL0 */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M) |
||||
|
/*!
|
||||
|
\brief configure the system clock to LPIRC4M |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_4m_lpirc4m(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable LPIRC4M */ |
||||
|
RCU_ADDCTL1 |= RCU_ADDCTL1_LPIRC4MEN; |
||||
|
|
||||
|
/* wait until LPIRC4M is stable or the startup time is longer than LPIRC4M_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB); |
||||
|
} while((0U == stab_flag) && (LPIRC4M_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* LPIRC4M is stable */ |
||||
|
/* AHB = SYSCLK / 1*/ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; |
||||
|
/* APB4 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; |
||||
|
/* APB3 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; |
||||
|
|
||||
|
/* select LPIRC4M as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_LPIRC4M; |
||||
|
|
||||
|
/* wait until LPIRC4M is selected as system clock */ |
||||
|
while(RCU_SCSS_LPIRC4M != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_HXTAL) |
||||
|
/*!
|
||||
|
\brief configure the system clock to HXTAL |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_hxtal(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable HXTAL */ |
||||
|
RCU_CTL |= RCU_CTL_HXTALEN; |
||||
|
|
||||
|
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); |
||||
|
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* HXTAL is stable */ |
||||
|
/* AHB = SYSCLK / 1*/ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; |
||||
|
/* APB4 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; |
||||
|
/* APB3 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; |
||||
|
|
||||
|
/* select HXTAL as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; |
||||
|
|
||||
|
/* wait until HXTAL is selected as system clock */ |
||||
|
while(RCU_SCSS_HXTAL != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 200M by PLL0 which selects HXTAL as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_200m_hxtal(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable HXTAL */ |
||||
|
RCU_CTL |= RCU_CTL_HXTALEN; |
||||
|
|
||||
|
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); |
||||
|
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* HXTAL is stable */ |
||||
|
/* AHB = SYSCLK / 1 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL0 select HXTAL, configure PLL0 input and output range */ |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = HXTAL / 5 * 40 = 200 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL0 */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 400M by PLL0 which selects HXTAL as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_400m_hxtal(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable HXTAL */ |
||||
|
RCU_CTL |= RCU_CTL_HXTALEN; |
||||
|
|
||||
|
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); |
||||
|
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* insert TCM wait state at 400MHz */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
/* HXTAL is stable */ |
||||
|
/* AHB = SYSCLK / 1 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL0 select HXTAL, configure PLL0 input and output range */ |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = HXTAL / 5 * 80 = 400 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 480M by PLL0 which selects HXTAL as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_480m_hxtal(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable HXTAL */ |
||||
|
RCU_CTL |= RCU_CTL_HXTALEN; |
||||
|
|
||||
|
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); |
||||
|
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* insert TCM wait state at 480MHz */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
/* HXTAL is stable */ |
||||
|
/* AHB = SYSCLK / 2 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL select HXTAL, configure PLL input and output range */ |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = HXTAL / 5 * 96 = 480 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL0 */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) |
||||
|
/*!
|
||||
|
\brief configure the system clock to 600M by PLL0 which selects HXTAL as its clock source |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
static void system_clock_600m_hxtal(void) |
||||
|
{ |
||||
|
uint32_t timeout = 0U; |
||||
|
uint32_t stab_flag = 0U; |
||||
|
|
||||
|
/* enable HXTAL */ |
||||
|
RCU_CTL |= RCU_CTL_HXTALEN; |
||||
|
|
||||
|
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ |
||||
|
do { |
||||
|
timeout++; |
||||
|
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); |
||||
|
} while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); |
||||
|
/* if fail */ |
||||
|
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { |
||||
|
while(1) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* insert TCM wait state at 600MHz */ |
||||
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG; |
||||
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; |
||||
|
|
||||
|
/* HXTAL is stable */ |
||||
|
/* AHB = SYSCLK / 2 */ |
||||
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; |
||||
|
/* APB4 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; |
||||
|
/* APB3 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; |
||||
|
/* APB2 = AHB / 1 */ |
||||
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; |
||||
|
/* APB1 = AHB / 2 */ |
||||
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; |
||||
|
|
||||
|
/* PLL select HXTAL, configure PLL input and output range */ |
||||
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); |
||||
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M); |
||||
|
|
||||
|
/* PLL0P = HXTAL / 5 * 120 = 600 MHz */ |
||||
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); |
||||
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); |
||||
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); |
||||
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); |
||||
|
|
||||
|
/* enable PLL0P, PLL0Q, PLL0R */ |
||||
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; |
||||
|
|
||||
|
/* enable PLL0 */ |
||||
|
RCU_CTL |= RCU_CTL_PLL0EN; |
||||
|
|
||||
|
/* wait until PLL0 is stable */ |
||||
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { |
||||
|
} |
||||
|
|
||||
|
/* select PLL0 as system clock */ |
||||
|
RCU_CFG0 &= ~RCU_CFG0_SCS; |
||||
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; |
||||
|
|
||||
|
/* wait until PLL0 is selected as system clock */ |
||||
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* __SYSTEM_CLOCK_IRC64M */ |
||||
|
|
||||
|
/*!
|
||||
|
\brief update the SystemCoreClock with current core clock retrieved from cpu registers |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval none |
||||
|
*/ |
||||
|
void SystemCoreClockUpdate(void) |
||||
|
{ |
||||
|
uint32_t sws = 0U; |
||||
|
uint32_t irc64div = 0U; |
||||
|
uint32_t pllpsc = 0U, plln = 0U, pllp = 0U, pllsel = 0U; |
||||
|
|
||||
|
sws = GET_BITS(RCU_CFG0, 2, 3); |
||||
|
switch(sws) { |
||||
|
/* IRC64M is selected as CK_SYS */ |
||||
|
case SEL_IRC64MDIV: |
||||
|
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17)); |
||||
|
SystemCoreClock = IRC64M_VALUE / irc64div; |
||||
|
break; |
||||
|
/* HXTAL is selected as CK_SYS */ |
||||
|
case SEL_LPIRC4M: |
||||
|
SystemCoreClock = LPIRC4M_VALUE; |
||||
|
break; |
||||
|
/* HXTAL is selected as CK_SYS */ |
||||
|
case SEL_HXTAL: |
||||
|
SystemCoreClock = HXTAL_VALUE; |
||||
|
break; |
||||
|
/* PLL0P is selected as CK_SYS */ |
||||
|
case SEL_PLL0P: |
||||
|
/* get the value of PLL0PSC[0,5], PLL0N[6,14], PLL0P[16,22] */ |
||||
|
pllpsc = GET_BITS(RCU_PLL0, 0, 5); |
||||
|
plln = GET_BITS(RCU_PLL0, 6, 14) + 1U; |
||||
|
pllp = GET_BITS(RCU_PLL0, 16, 22) + 1U; |
||||
|
|
||||
|
/* PLL clock source selection, HXTAL or IRC64M_VALUE or LPIRC4M_VALUE */ |
||||
|
pllsel = GET_BITS(RCU_PLLALL, 16, 17); |
||||
|
if(0U == pllsel) { |
||||
|
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17)); |
||||
|
SystemCoreClock = (IRC64M_VALUE / irc64div / pllpsc) * plln / pllp; |
||||
|
} else if(1U == pllsel) { |
||||
|
SystemCoreClock = (LPIRC4M_VALUE / pllpsc) * plln / pllp; |
||||
|
} else { |
||||
|
SystemCoreClock = (HXTAL_VALUE / pllpsc) * plln / pllp; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
/* should not be here */ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#ifdef __FIRMWARE_VERSION_DEFINE |
||||
|
/*!
|
||||
|
\brief get firmware version |
||||
|
\param[in] none |
||||
|
\param[out] none |
||||
|
\retval firmware version |
||||
|
*/ |
||||
|
uint32_t gd32h75e_firmware_version_get(void) |
||||
|
{ |
||||
|
return __GD32H75E_STDPERIPH_VERSION; |
||||
|
} |
||||
|
#endif /* __FIRMWARE_VERSION_DEFINE */ |
||||
@ -0,0 +1,446 @@ |
|||||
|
/******************************************************************************
|
||||
|
* @file cachel1_armv7.h |
||||
|
* @brief CMSIS Level 1 Cache API for Armv7-M and later |
||||
|
* @version V1.0.3 |
||||
|
* @date 17. March 2023 |
||||
|
******************************************************************************/ |
||||
|
/*
|
||||
|
* Copyright (c) 2020-2021 Arm Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
#if defined ( __ICCARM__ ) |
||||
|
#pragma system_include /* treat file as system include file for MISRA check */ |
||||
|
#elif defined (__clang__) |
||||
|
#pragma clang system_header /* treat file as system include file */ |
||||
|
#endif |
||||
|
|
||||
|
#ifndef ARM_CACHEL1_ARMV7_H |
||||
|
#define ARM_CACHEL1_ARMV7_H |
||||
|
|
||||
|
/**
|
||||
|
\ingroup CMSIS_Core_FunctionInterface |
||||
|
\defgroup CMSIS_Core_CacheFunctions Cache Functions |
||||
|
\brief Functions that configure Instruction and Data cache. |
||||
|
@{ |
||||
|
*/ |
||||
|
|
||||
|
/* Cache Size ID Register Macros */ |
||||
|
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) |
||||
|
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) |
||||
|
|
||||
|
#ifndef __SCB_DCACHE_LINE_SIZE |
||||
|
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ |
||||
|
#endif |
||||
|
|
||||
|
#ifndef __SCB_ICACHE_LINE_SIZE |
||||
|
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ |
||||
|
#endif |
||||
|
|
||||
|
/**
|
||||
|
\brief Enable I-Cache |
||||
|
\details Turns on I-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_EnableICache (void) |
||||
|
{ |
||||
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) |
||||
|
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
SCB->ICIALLU = 0UL; /* invalidate I-Cache */ |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Disable I-Cache |
||||
|
\details Turns off I-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_DisableICache (void) |
||||
|
{ |
||||
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ |
||||
|
SCB->ICIALLU = 0UL; /* invalidate I-Cache */ |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Invalidate I-Cache |
||||
|
\details Invalidates I-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_InvalidateICache (void) |
||||
|
{ |
||||
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
SCB->ICIALLU = 0UL; |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief I-Cache Invalidate by address |
||||
|
\details Invalidates I-Cache for the given address. |
||||
|
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. |
||||
|
I-Cache memory blocks which are part of given address + given size are invalidated. |
||||
|
\param[in] addr address |
||||
|
\param[in] isize size of memory block (in number of bytes) |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize) |
||||
|
{ |
||||
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) |
||||
|
if ( isize > 0 ) |
||||
|
{ |
||||
|
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); |
||||
|
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; |
||||
|
|
||||
|
__DSB(); |
||||
|
|
||||
|
do { |
||||
|
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ |
||||
|
op_addr += __SCB_ICACHE_LINE_SIZE; |
||||
|
op_size -= __SCB_ICACHE_LINE_SIZE; |
||||
|
} while ( op_size > 0 ); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Enable D-Cache |
||||
|
\details Turns on D-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_EnableDCache (void) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
uint32_t ccsidr; |
||||
|
uint32_t sets; |
||||
|
uint32_t ways; |
||||
|
|
||||
|
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ |
||||
|
|
||||
|
SCB->CSSELR = 0U; /* select Level 1 data cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
ccsidr = SCB->CCSIDR; |
||||
|
|
||||
|
/* invalidate D-Cache */ |
||||
|
sets = (uint32_t)(CCSIDR_SETS(ccsidr)); |
||||
|
do { |
||||
|
ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); |
||||
|
do { |
||||
|
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | |
||||
|
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); |
||||
|
#if defined ( __CC_ARM ) |
||||
|
__schedule_barrier(); |
||||
|
#endif |
||||
|
} while (ways-- != 0U); |
||||
|
} while(sets-- != 0U); |
||||
|
__DSB(); |
||||
|
|
||||
|
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Disable D-Cache |
||||
|
\details Turns off D-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_DisableDCache (void) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
struct { |
||||
|
uint32_t ccsidr; |
||||
|
uint32_t sets; |
||||
|
uint32_t ways; |
||||
|
} locals |
||||
|
#if ((defined(__GNUC__) || defined(__clang__)) && !defined(__OPTIMIZE__)) |
||||
|
__ALIGNED(__SCB_DCACHE_LINE_SIZE) |
||||
|
#endif |
||||
|
; |
||||
|
|
||||
|
SCB->CSSELR = 0U; /* select Level 1 data cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
#if !defined(__OPTIMIZE__) |
||||
|
/*
|
||||
|
* For the endless loop issue with no optimization builds. |
||||
|
* More details, see https://github.com/ARM-software/CMSIS_5/issues/620
|
||||
|
* |
||||
|
* The issue only happens when local variables are in stack. If |
||||
|
* local variables are saved in general purpose register, then the function |
||||
|
* is OK. |
||||
|
* |
||||
|
* When local variables are in stack, after disabling the cache, flush the |
||||
|
* local variables cache line for data consistency. |
||||
|
*/ |
||||
|
/* Clean and invalidate the local variable cache. */ |
||||
|
#if defined(__ICCARM__) |
||||
|
/* As we can't align the stack to the cache line size, invalidate each of the variables */ |
||||
|
SCB->DCCIMVAC = (uint32_t)&locals.sets; |
||||
|
SCB->DCCIMVAC = (uint32_t)&locals.ways; |
||||
|
SCB->DCCIMVAC = (uint32_t)&locals.ccsidr; |
||||
|
#else |
||||
|
SCB->DCCIMVAC = (uint32_t)&locals; |
||||
|
#endif |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
|
||||
|
locals.ccsidr = SCB->CCSIDR; |
||||
|
/* clean & invalidate D-Cache */ |
||||
|
locals.sets = (uint32_t)(CCSIDR_SETS(locals.ccsidr)); |
||||
|
do { |
||||
|
locals.ways = (uint32_t)(CCSIDR_WAYS(locals.ccsidr)); |
||||
|
do { |
||||
|
SCB->DCCISW = (((locals.sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | |
||||
|
((locals.ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); |
||||
|
#if defined ( __CC_ARM ) |
||||
|
__schedule_barrier(); |
||||
|
#endif |
||||
|
} while (locals.ways-- != 0U); |
||||
|
} while(locals.sets-- != 0U); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Invalidate D-Cache |
||||
|
\details Invalidates D-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
uint32_t ccsidr; |
||||
|
uint32_t sets; |
||||
|
uint32_t ways; |
||||
|
|
||||
|
SCB->CSSELR = 0U; /* select Level 1 data cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
ccsidr = SCB->CCSIDR; |
||||
|
|
||||
|
/* invalidate D-Cache */ |
||||
|
sets = (uint32_t)(CCSIDR_SETS(ccsidr)); |
||||
|
do { |
||||
|
ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); |
||||
|
do { |
||||
|
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | |
||||
|
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); |
||||
|
#if defined ( __CC_ARM ) |
||||
|
__schedule_barrier(); |
||||
|
#endif |
||||
|
} while (ways-- != 0U); |
||||
|
} while(sets-- != 0U); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Clean D-Cache |
||||
|
\details Cleans D-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_CleanDCache (void) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
uint32_t ccsidr; |
||||
|
uint32_t sets; |
||||
|
uint32_t ways; |
||||
|
|
||||
|
SCB->CSSELR = 0U; /* select Level 1 data cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
ccsidr = SCB->CCSIDR; |
||||
|
|
||||
|
/* clean D-Cache */ |
||||
|
sets = (uint32_t)(CCSIDR_SETS(ccsidr)); |
||||
|
do { |
||||
|
ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); |
||||
|
do { |
||||
|
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | |
||||
|
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); |
||||
|
#if defined ( __CC_ARM ) |
||||
|
__schedule_barrier(); |
||||
|
#endif |
||||
|
} while (ways-- != 0U); |
||||
|
} while(sets-- != 0U); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief Clean & Invalidate D-Cache |
||||
|
\details Cleans and Invalidates D-Cache |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
uint32_t ccsidr; |
||||
|
uint32_t sets; |
||||
|
uint32_t ways; |
||||
|
|
||||
|
SCB->CSSELR = 0U; /* select Level 1 data cache */ |
||||
|
__DSB(); |
||||
|
|
||||
|
ccsidr = SCB->CCSIDR; |
||||
|
|
||||
|
/* clean & invalidate D-Cache */ |
||||
|
sets = (uint32_t)(CCSIDR_SETS(ccsidr)); |
||||
|
do { |
||||
|
ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); |
||||
|
do { |
||||
|
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | |
||||
|
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); |
||||
|
#if defined ( __CC_ARM ) |
||||
|
__schedule_barrier(); |
||||
|
#endif |
||||
|
} while (ways-- != 0U); |
||||
|
} while(sets-- != 0U); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief D-Cache Invalidate by address |
||||
|
\details Invalidates D-Cache for the given address. |
||||
|
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. |
||||
|
D-Cache memory blocks which are part of given address + given size are invalidated. |
||||
|
\param[in] addr address |
||||
|
\param[in] dsize size of memory block (in number of bytes) |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
if ( dsize > 0 ) |
||||
|
{ |
||||
|
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); |
||||
|
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; |
||||
|
|
||||
|
__DSB(); |
||||
|
|
||||
|
do { |
||||
|
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ |
||||
|
op_addr += __SCB_DCACHE_LINE_SIZE; |
||||
|
op_size -= __SCB_DCACHE_LINE_SIZE; |
||||
|
} while ( op_size > 0 ); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief D-Cache Clean by address |
||||
|
\details Cleans D-Cache for the given address |
||||
|
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. |
||||
|
D-Cache memory blocks which are part of given address + given size are cleaned. |
||||
|
\param[in] addr address |
||||
|
\param[in] dsize size of memory block (in number of bytes) |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
if ( dsize > 0 ) |
||||
|
{ |
||||
|
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); |
||||
|
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; |
||||
|
|
||||
|
__DSB(); |
||||
|
|
||||
|
do { |
||||
|
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ |
||||
|
op_addr += __SCB_DCACHE_LINE_SIZE; |
||||
|
op_size -= __SCB_DCACHE_LINE_SIZE; |
||||
|
} while ( op_size > 0 ); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
\brief D-Cache Clean and Invalidate by address |
||||
|
\details Cleans and invalidates D_Cache for the given address |
||||
|
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. |
||||
|
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. |
||||
|
\param[in] addr address (aligned to 32-byte boundary) |
||||
|
\param[in] dsize size of memory block (in number of bytes) |
||||
|
*/ |
||||
|
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) |
||||
|
{ |
||||
|
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
||||
|
if ( dsize > 0 ) |
||||
|
{ |
||||
|
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); |
||||
|
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; |
||||
|
|
||||
|
__DSB(); |
||||
|
|
||||
|
do { |
||||
|
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ |
||||
|
op_addr += __SCB_DCACHE_LINE_SIZE; |
||||
|
op_size -= __SCB_DCACHE_LINE_SIZE; |
||||
|
} while ( op_size > 0 ); |
||||
|
|
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
/*@} end of CMSIS_Core_CacheFunctions */ |
||||
|
|
||||
|
#endif /* ARM_CACHEL1_ARMV7_H */ |
||||
|
|
||||
@ -0,0 +1,304 @@ |
|||||
|
/**************************************************************************//**
|
||||
|
* @file cmsis_compiler.h |
||||
|
* @brief CMSIS compiler generic header file |
||||
|
* @version V5.3.0 |
||||
|
* @date 04. April 2023 |
||||
|
******************************************************************************/ |
||||
|
/*
|
||||
|
* Copyright (c) 2009-2023 Arm Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __CMSIS_COMPILER_H |
||||
|
#define __CMSIS_COMPILER_H |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
/*
|
||||
|
* Arm Compiler 4/5 |
||||
|
*/ |
||||
|
#if defined ( __CC_ARM ) |
||||
|
#include "cmsis_armcc.h" |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* Arm Compiler 6.6 LTM (armclang) |
||||
|
*/ |
||||
|
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) |
||||
|
#include "cmsis_armclang_ltm.h" |
||||
|
|
||||
|
/*
|
||||
|
* Arm Compiler above 6.10.1 (armclang) |
||||
|
*/ |
||||
|
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) |
||||
|
#include "cmsis_armclang.h" |
||||
|
|
||||
|
/*
|
||||
|
* TI Arm Clang Compiler (tiarmclang) |
||||
|
*/ |
||||
|
#elif defined (__ti__) |
||||
|
#include "cmsis_tiarmclang.h" |
||||
|
|
||||
|
/*
|
||||
|
* GNU Compiler |
||||
|
*/ |
||||
|
#elif defined ( __GNUC__ ) |
||||
|
#include "cmsis_gcc.h" |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* IAR Compiler |
||||
|
*/ |
||||
|
#elif defined ( __ICCARM__ ) |
||||
|
#include <cmsis_iccarm.h> |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
* TI Arm Compiler (armcl) |
||||
|
*/ |
||||
|
#elif defined ( __TI_ARM__ ) |
||||
|
#include <cmsis_ccs.h> |
||||
|
|
||||
|
#ifndef __ASM |
||||
|
#define __ASM __asm |
||||
|
#endif |
||||
|
#ifndef __INLINE |
||||
|
#define __INLINE inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_INLINE |
||||
|
#define __STATIC_INLINE static inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_FORCEINLINE |
||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE |
||||
|
#endif |
||||
|
#ifndef __NO_RETURN |
||||
|
#define __NO_RETURN __attribute__((noreturn)) |
||||
|
#endif |
||||
|
#ifndef __USED |
||||
|
#define __USED __attribute__((used)) |
||||
|
#endif |
||||
|
#ifndef __WEAK |
||||
|
#define __WEAK __attribute__((weak)) |
||||
|
#endif |
||||
|
#ifndef __PACKED |
||||
|
#define __PACKED __attribute__((packed)) |
||||
|
#endif |
||||
|
#ifndef __PACKED_STRUCT |
||||
|
#define __PACKED_STRUCT struct __attribute__((packed)) |
||||
|
#endif |
||||
|
#ifndef __PACKED_UNION |
||||
|
#define __PACKED_UNION union __attribute__((packed)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */ |
||||
|
struct __attribute__((packed))T_UINT32 |
||||
|
{ uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_WRITE |
||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_READ |
||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_WRITE |
||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_READ |
||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __ALIGNED |
||||
|
#define __ALIGNED(x) __attribute__((aligned(x))) |
||||
|
#endif |
||||
|
#ifndef __RESTRICT |
||||
|
#define __RESTRICT __restrict |
||||
|
#endif |
||||
|
#ifndef __COMPILER_BARRIER |
||||
|
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. |
||||
|
#define __COMPILER_BARRIER() (void)0 |
||||
|
#endif |
||||
|
#ifndef __NO_INIT |
||||
|
#define __NO_INIT __attribute__ ((section (".bss.noinit"))) |
||||
|
#endif |
||||
|
#ifndef __ALIAS |
||||
|
#define __ALIAS(x) __attribute__ ((alias(x))) |
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
* TASKING Compiler |
||||
|
*/ |
||||
|
#elif defined ( __TASKING__ ) |
||||
|
/*
|
||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler. |
||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics, |
||||
|
* Including the CMSIS ones. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __ASM |
||||
|
#define __ASM __asm |
||||
|
#endif |
||||
|
#ifndef __INLINE |
||||
|
#define __INLINE inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_INLINE |
||||
|
#define __STATIC_INLINE static inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_FORCEINLINE |
||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE |
||||
|
#endif |
||||
|
#ifndef __NO_RETURN |
||||
|
#define __NO_RETURN __attribute__((noreturn)) |
||||
|
#endif |
||||
|
#ifndef __USED |
||||
|
#define __USED __attribute__((used)) |
||||
|
#endif |
||||
|
#ifndef __WEAK |
||||
|
#define __WEAK __attribute__((weak)) |
||||
|
#endif |
||||
|
#ifndef __PACKED |
||||
|
#define __PACKED __packed__ |
||||
|
#endif |
||||
|
#ifndef __PACKED_STRUCT |
||||
|
#define __PACKED_STRUCT struct __packed__ |
||||
|
#endif |
||||
|
#ifndef __PACKED_UNION |
||||
|
#define __PACKED_UNION union __packed__ |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */ |
||||
|
struct __packed__ T_UINT32 { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_WRITE |
||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_READ |
||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_WRITE |
||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_READ |
||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __ALIGNED |
||||
|
#define __ALIGNED(x) __align(x) |
||||
|
#endif |
||||
|
#ifndef __RESTRICT |
||||
|
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. |
||||
|
#define __RESTRICT |
||||
|
#endif |
||||
|
#ifndef __COMPILER_BARRIER |
||||
|
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. |
||||
|
#define __COMPILER_BARRIER() (void)0 |
||||
|
#endif |
||||
|
#ifndef __NO_INIT |
||||
|
#define __NO_INIT __attribute__ ((section (".bss.noinit"))) |
||||
|
#endif |
||||
|
#ifndef __ALIAS |
||||
|
#define __ALIAS(x) __attribute__ ((alias(x))) |
||||
|
#endif |
||||
|
|
||||
|
/*
|
||||
|
* COSMIC Compiler |
||||
|
*/ |
||||
|
#elif defined ( __CSMC__ ) |
||||
|
#include <cmsis_csm.h> |
||||
|
|
||||
|
#ifndef __ASM |
||||
|
#define __ASM _asm |
||||
|
#endif |
||||
|
#ifndef __INLINE |
||||
|
#define __INLINE inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_INLINE |
||||
|
#define __STATIC_INLINE static inline |
||||
|
#endif |
||||
|
#ifndef __STATIC_FORCEINLINE |
||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE |
||||
|
#endif |
||||
|
#ifndef __NO_RETURN |
||||
|
/* NO RETURN is automatically detected hence no warning here*/ |
||||
|
#define __NO_RETURN |
||||
|
#endif |
||||
|
#ifndef __USED |
||||
|
#warning No compiler specific solution for __USED. __USED is ignored. |
||||
|
#define __USED |
||||
|
#endif |
||||
|
#ifndef __WEAK |
||||
|
#define __WEAK __weak |
||||
|
#endif |
||||
|
#ifndef __PACKED |
||||
|
#define __PACKED @packed |
||||
|
#endif |
||||
|
#ifndef __PACKED_STRUCT |
||||
|
#define __PACKED_STRUCT @packed struct |
||||
|
#endif |
||||
|
#ifndef __PACKED_UNION |
||||
|
#define __PACKED_UNION @packed union |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */ |
||||
|
@packed struct T_UINT32 { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_WRITE |
||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT16_READ |
||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; }; |
||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_WRITE |
||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) |
||||
|
#endif |
||||
|
#ifndef __UNALIGNED_UINT32_READ |
||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; }; |
||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) |
||||
|
#endif |
||||
|
#ifndef __ALIGNED |
||||
|
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. |
||||
|
#define __ALIGNED(x) |
||||
|
#endif |
||||
|
#ifndef __RESTRICT |
||||
|
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. |
||||
|
#define __RESTRICT |
||||
|
#endif |
||||
|
#ifndef __COMPILER_BARRIER |
||||
|
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. |
||||
|
#define __COMPILER_BARRIER() (void)0 |
||||
|
#endif |
||||
|
#ifndef __NO_INIT |
||||
|
#define __NO_INIT __attribute__ ((section (".bss.noinit"))) |
||||
|
#endif |
||||
|
#ifndef __ALIAS |
||||
|
#define __ALIAS(x) __attribute__ ((alias(x))) |
||||
|
#endif |
||||
|
|
||||
|
#else |
||||
|
#error Unknown compiler. |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
#endif /* __CMSIS_COMPILER_H */ |
||||
|
|
||||
File diff suppressed because it is too large
@ -0,0 +1,40 @@ |
|||||
|
/**************************************************************************//**
|
||||
|
* @file cmsis_version.h |
||||
|
* @brief CMSIS Core(M) Version definitions |
||||
|
* @version V5.0.5 |
||||
|
* @date 02. February 2022 |
||||
|
******************************************************************************/ |
||||
|
/*
|
||||
|
* Copyright (c) 2009-2022 ARM Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
#if defined ( __ICCARM__ ) |
||||
|
#pragma system_include /* treat file as system include file for MISRA check */ |
||||
|
#elif defined (__clang__) |
||||
|
#pragma clang system_header /* treat file as system include file */ |
||||
|
#endif |
||||
|
|
||||
|
#ifndef __CMSIS_VERSION_H |
||||
|
#define __CMSIS_VERSION_H |
||||
|
|
||||
|
/* CMSIS Version definitions */ |
||||
|
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ |
||||
|
#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ |
||||
|
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ |
||||
|
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ |
||||
|
#endif |
||||
|
|
||||
File diff suppressed because it is too large
@ -0,0 +1,277 @@ |
|||||
|
/******************************************************************************
|
||||
|
* @file mpu_armv7.h |
||||
|
* @brief CMSIS MPU API for Armv7-M MPU |
||||
|
* @version V5.1.2 |
||||
|
* @date 25. May 2020 |
||||
|
******************************************************************************/ |
||||
|
/*
|
||||
|
* Copyright (c) 2017-2020 Arm Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may |
||||
|
* not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
#if defined ( __ICCARM__ ) |
||||
|
#pragma system_include /* treat file as system include file for MISRA check */ |
||||
|
#elif defined (__clang__) |
||||
|
#pragma clang system_header /* treat file as system include file */ |
||||
|
#endif |
||||
|
|
||||
|
#ifndef ARM_MPU_ARMV7_H |
||||
|
#define ARM_MPU_ARMV7_H |
||||
|
|
||||
|
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) /*/!< MPU Region Size 32 Bytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) /*/!< MPU Region Size 64 Bytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) /*/!< MPU Region Size 128 Bytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) /*/!< MPU Region Size 256 Bytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) /*/!< MPU Region Size 512 Bytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) /*/!< MPU Region Size 1 KByte*/ |
||||
|
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) /*/!< MPU Region Size 2 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) /*/!< MPU Region Size 4 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) /*/!< MPU Region Size 8 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) /*/!< MPU Region Size 16 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) /*/!< MPU Region Size 32 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) /*/!< MPU Region Size 64 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) /*/!< MPU Region Size 128 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) /*/!< MPU Region Size 256 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) /*/!< MPU Region Size 512 KBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) /*/!< MPU Region Size 1 MByte*/ |
||||
|
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) /*/!< MPU Region Size 2 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) /*/!< MPU Region Size 4 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) /*/!< MPU Region Size 8 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) /*/!< MPU Region Size 16 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) /*/!< MPU Region Size 32 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) /*/!< MPU Region Size 64 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) /*/!< MPU Region Size 128 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) /*/!< MPU Region Size 256 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) /*/!< MPU Region Size 512 MBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) /*/!< MPU Region Size 1 GByte*/ |
||||
|
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) /*/!< MPU Region Size 2 GBytes*/ |
||||
|
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) /*/!< MPU Region Size 4 GBytes*/ |
||||
|
|
||||
|
#define ARM_MPU_AP_NONE 0U /*/!< MPU Access Permission no access*/ |
||||
|
#define ARM_MPU_AP_PRIV 1U /*/!< MPU Access Permission privileged access only*/ |
||||
|
#define ARM_MPU_AP_URO 2U /*/!< MPU Access Permission unprivileged access read-only*/ |
||||
|
#define ARM_MPU_AP_FULL 3U /*/!< MPU Access Permission full access*/ |
||||
|
#define ARM_MPU_AP_PRO 5U /*/!< MPU Access Permission privileged access read-only*/ |
||||
|
#define ARM_MPU_AP_RO 6U /*/!< MPU Access Permission read-only access*/ |
||||
|
|
||||
|
/** MPU Region Base Address Register Value
|
||||
|
* |
||||
|
* \param Region The region to be configured, number 0 to 15. |
||||
|
* \param BaseAddress The base address for the region. |
||||
|
*/ |
||||
|
#define ARM_MPU_RBAR(Region, BaseAddress) \ |
||||
|
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ |
||||
|
((Region) & MPU_RBAR_REGION_Msk) | \ |
||||
|
(MPU_RBAR_VALID_Msk)) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attributes |
||||
|
* |
||||
|
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. |
||||
|
* \param IsShareable Region is shareable between multiple bus masters. |
||||
|
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. |
||||
|
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. |
||||
|
*/ |
||||
|
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ |
||||
|
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ |
||||
|
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ |
||||
|
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ |
||||
|
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Region Attribute and Size Register Value |
||||
|
* |
||||
|
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. |
||||
|
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. |
||||
|
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. |
||||
|
* \param SubRegionDisable Sub-region disable field. |
||||
|
* \param Size Region size of the region to be configured, for example 4K, 8K. |
||||
|
*/ |
||||
|
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ |
||||
|
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ |
||||
|
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ |
||||
|
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ |
||||
|
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ |
||||
|
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ |
||||
|
(((MPU_RASR_ENABLE_Msk)))) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Region Attribute and Size Register Value |
||||
|
* |
||||
|
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. |
||||
|
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. |
||||
|
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. |
||||
|
* \param IsShareable Region is shareable between multiple bus masters. |
||||
|
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. |
||||
|
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. |
||||
|
* \param SubRegionDisable Sub-region disable field. |
||||
|
* \param Size Region size of the region to be configured, for example 4K, 8K. |
||||
|
*/ |
||||
|
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ |
||||
|
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute for strongly ordered memory. |
||||
|
* - TEX: 000b |
||||
|
* - Shareable |
||||
|
* - Non-cacheable |
||||
|
* - Non-bufferable |
||||
|
*/ |
||||
|
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute for device memory. |
||||
|
* - TEX: 000b (if shareable) or 010b (if non-shareable) |
||||
|
* - Shareable or non-shareable |
||||
|
* - Non-cacheable |
||||
|
* - Bufferable (if shareable) or non-bufferable (if non-shareable) |
||||
|
* |
||||
|
* \param IsShareable Configures the device memory as shareable or non-shareable. |
||||
|
*/ |
||||
|
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute for normal memory. |
||||
|
* - TEX: 1BBb (reflecting outer cacheability rules) |
||||
|
* - Shareable or non-shareable |
||||
|
* - Cacheable or non-cacheable (reflecting inner cacheability rules) |
||||
|
* - Bufferable or non-bufferable (reflecting inner cacheability rules) |
||||
|
* |
||||
|
* \param OuterCp Configures the outer cache policy. |
||||
|
* \param InnerCp Configures the inner cache policy. |
||||
|
* \param IsShareable Configures the memory as shareable or non-shareable. |
||||
|
*/ |
||||
|
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute non-cacheable policy. |
||||
|
*/ |
||||
|
#define ARM_MPU_CACHEP_NOCACHE 0U |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute write-back, write and read allocate policy. |
||||
|
*/ |
||||
|
#define ARM_MPU_CACHEP_WB_WRA 1U |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute write-through, no write allocate policy. |
||||
|
*/ |
||||
|
#define ARM_MPU_CACHEP_WT_NWA 2U |
||||
|
|
||||
|
/**
|
||||
|
* MPU Memory Access Attribute write-back, no write allocate policy. |
||||
|
*/ |
||||
|
#define ARM_MPU_CACHEP_WB_NWA 3U |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
* Struct for a single MPU Region |
||||
|
*/ |
||||
|
typedef struct { |
||||
|
uint32_t RBAR; /*!< The region base address register value (RBAR)*/ |
||||
|
uint32_t RASR; /*!< The region attribute and size register value (RASR) \ref MPU_RASR*/ |
||||
|
} ARM_MPU_Region_t; |
||||
|
|
||||
|
/** Enable the MPU.
|
||||
|
* \param MPU_Control Default access permissions for unconfigured regions. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) |
||||
|
{ |
||||
|
__DMB(); |
||||
|
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; |
||||
|
#ifdef SCB_SHCSR_MEMFAULTENA_Msk |
||||
|
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; |
||||
|
#endif |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
|
||||
|
/** Disable the MPU.
|
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_Disable(void) |
||||
|
{ |
||||
|
__DMB(); |
||||
|
#ifdef SCB_SHCSR_MEMFAULTENA_Msk |
||||
|
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; |
||||
|
#endif |
||||
|
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; |
||||
|
__DSB(); |
||||
|
__ISB(); |
||||
|
} |
||||
|
|
||||
|
/** Clear and disable the given MPU region.
|
||||
|
* \param rnr Region number to be cleared. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) |
||||
|
{ |
||||
|
MPU->RNR = rnr; |
||||
|
MPU->RASR = 0U; |
||||
|
} |
||||
|
|
||||
|
/** Configure an MPU region.
|
||||
|
* \param rbar Value for RBAR register. |
||||
|
* \param rasr Value for RASR register. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) |
||||
|
{ |
||||
|
MPU->RBAR = rbar; |
||||
|
MPU->RASR = rasr; |
||||
|
} |
||||
|
|
||||
|
/** Configure the given MPU region.
|
||||
|
* \param rnr Region number to be configured. |
||||
|
* \param rbar Value for RBAR register. |
||||
|
* \param rasr Value for RASR register. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) |
||||
|
{ |
||||
|
MPU->RNR = rnr; |
||||
|
MPU->RBAR = rbar; |
||||
|
MPU->RASR = rasr; |
||||
|
} |
||||
|
|
||||
|
/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load().
|
||||
|
* \param dst Destination data is copied to. |
||||
|
* \param src Source data is copied from. |
||||
|
* \param len Amount of data words to be copied. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) |
||||
|
{ |
||||
|
uint32_t i; |
||||
|
for (i = 0U; i < len; ++i) |
||||
|
{ |
||||
|
dst[i] = src[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Load the given number of MPU regions from a table.
|
||||
|
* \param table Pointer to the MPU configuration table. |
||||
|
* \param cnt Amount of regions to be configured. |
||||
|
*/ |
||||
|
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) |
||||
|
{ |
||||
|
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; |
||||
|
while (cnt > MPU_TYPE_RALIASES) |
||||
|
{ |
||||
|
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); |
||||
|
table += MPU_TYPE_RALIASES; |
||||
|
cnt -= MPU_TYPE_RALIASES; |
||||
|
} |
||||
|
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,799 @@ |
|||||
|
/*!
|
||||
|
\file gd32h75e_adc.h |
||||
|
\brief definitions for the ADC |
||||
|
|
||||
|
\version 2025-08-07, V1.2.0, firmware for GD32H75E |
||||
|
*/ |
||||
|
|
||||
|
/*
|
||||
|
Copyright (c) 2025, GigaDevice Semiconductor Inc. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without modification, |
||||
|
are permitted provided that the following conditions are met: |
||||
|
|
||||
|
1. Redistributions of source code must retain the above copyright notice, this |
||||
|
list of conditions and the following disclaimer. |
||||
|
2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
this list of conditions and the following disclaimer in the documentation |
||||
|
and/or other materials provided with the distribution. |
||||
|
3. Neither the name of the copyright holder nor the names of its contributors |
||||
|
may be used to endorse or promote products derived from this software without |
||||
|
specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
||||
|
OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef GD32H75E_ADC_H |
||||
|
#define GD32H75E_ADC_H |
||||
|
|
||||
|
#include "gd32h75e.h" |
||||
|
|
||||
|
/* ADC definitions */ |
||||
|
#define ADC0 ADC_BASE /*!< ADC0 base address */ |
||||
|
#define ADC1 (ADC_BASE + 0x00000400U) /*!< ADC1 base address */ |
||||
|
#define ADC2 (ADC_BASE + 0x00000800U) /*!< ADC2 base address */ |
||||
|
|
||||
|
/* registers definitions */ |
||||
|
#define ADC_STAT(adcx) REG32((adcx) + 0x00000000U) /*!< ADC status register */ |
||||
|
#define ADC_CTL0(adcx) REG32((adcx) + 0x00000004U) /*!< ADC control register 0 */ |
||||
|
#define ADC_CTL1(adcx) REG32((adcx) + 0x00000008U) /*!< ADC control register 1 */ |
||||
|
#define ADC_IOFF0(adcx) REG32((adcx) + 0x0000000CU) /*!< ADC inserted channel data offset register 0 */ |
||||
|
#define ADC_IOFF1(adcx) REG32((adcx) + 0x00000010U) /*!< ADC inserted channel data offset register 1 */ |
||||
|
#define ADC_IOFF2(adcx) REG32((adcx) + 0x00000014U) /*!< ADC inserted channel data offset register 2 */ |
||||
|
#define ADC_IOFF3(adcx) REG32((adcx) + 0x00000018U) /*!< ADC inserted channel data offset register 3 */ |
||||
|
#define ADC_WDHT0(adcx) REG32((adcx) + 0x0000001CU) /*!< ADC watchdog high threshold register 0 */ |
||||
|
#define ADC_WDLT0(adcx) REG32((adcx) + 0x00000020U) /*!< ADC watchdog low threshold register 0 */ |
||||
|
#define ADC_RSQ0(adcx) REG32((adcx) + 0x00000024U) /*!< ADC routine sequence register 0 */ |
||||
|
#define ADC_RSQ1(adcx) REG32((adcx) + 0x00000028U) /*!< ADC routine sequence register 1 */ |
||||
|
#define ADC_RSQ2(adcx) REG32((adcx) + 0x0000002CU) /*!< ADC routine sequence register 2 */ |
||||
|
#define ADC_RSQ3(adcx) REG32((adcx) + 0x00000030U) /*!< ADC routine sequence register 3 */ |
||||
|
#define ADC_RSQ4(adcx) REG32((adcx) + 0x00000034U) /*!< ADC routine sequence register 4 */ |
||||
|
#define ADC_RSQ5(adcx) REG32((adcx) + 0x00000038U) /*!< ADC routine sequence register 5 */ |
||||
|
#define ADC_RSQ6(adcx) REG32((adcx) + 0x0000003CU) /*!< ADC routine sequence register 6 */ |
||||
|
#define ADC_RSQ7(adcx) REG32((adcx) + 0x00000040U) /*!< ADC routine sequence register 7 */ |
||||
|
#define ADC_RSQ8(adcx) REG32((adcx) + 0x00000044U) /*!< ADC routine sequence register 8 */ |
||||
|
#define ADC_ISQ0(adcx) REG32((adcx) + 0x00000048U) /*!< ADC inserted sequence register 0 */ |
||||
|
#define ADC_ISQ1(adcx) REG32((adcx) + 0x0000004CU) /*!< ADC inserted sequence register 1 */ |
||||
|
#define ADC_ISQ2(adcx) REG32((adcx) + 0x00000050U) /*!< ADC inserted sequence register 2 */ |
||||
|
#define ADC_IDATA0(adcx) REG32((adcx) + 0x00000054U) /*!< ADC inserted data register 0 */ |
||||
|
#define ADC_IDATA1(adcx) REG32((adcx) + 0x00000058U) /*!< ADC inserted data register 1 */ |
||||
|
#define ADC_IDATA2(adcx) REG32((adcx) + 0x0000005CU) /*!< ADC inserted data register 2 */ |
||||
|
#define ADC_IDATA3(adcx) REG32((adcx) + 0x00000060U) /*!< ADC inserted data register 3 */ |
||||
|
#define ADC_RDATA(adcx) REG32((adcx) + 0x00000064U) /*!< ADC routine data register */ |
||||
|
#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x00000080U) /*!< ADC oversampling control register */ |
||||
|
#define ADC_WD1SR(adcx) REG32((adcx) + 0x000000A0U) /*!< ADC watchdog 1 channel selection register */ |
||||
|
#define ADC_WD2SR(adcx) REG32((adcx) + 0x000000A4U) /*!< ADC watchdog 2 channel selection register */ |
||||
|
#define ADC_WDHT1(adcx) REG32((adcx) + 0x000000A8U) /*!< ADC watchdog high threshold register 1 */ |
||||
|
#define ADC_WDLT1(adcx) REG32((adcx) + 0x000000ACU) /*!< ADC watchdog low threshold register 1 */ |
||||
|
#define ADC_WDHT2(adcx) REG32((adcx) + 0x000000B0U) /*!< ADC watchdog high threshold register 2 */ |
||||
|
#define ADC_WDLT2(adcx) REG32((adcx) + 0x000000B4U) /*!< ADC watchdog low threshold register 2 */ |
||||
|
#define ADC_DIFCTL(adcx) REG32((adcx) + 0x000000B8U) /*!< ADC differential mode control register */ |
||||
|
#define ADC_SSTAT REG32((ADC0) + 0x00000300U) /*!< ADC summary status register */ |
||||
|
#define ADC_SYNCCTL(adcx) REG32((adcx) + 0x00000304U) /*!< ADC sync control register */ |
||||
|
#define ADC_SYNCDATA0 REG32((ADC0) + 0x00000308U) /*!< ADC sync routine data register 0 */ |
||||
|
#define ADC_SYNCDATA1 REG32((ADC0) + 0x0000030CU) /*!< ADC sync routine data register 1 */ |
||||
|
|
||||
|
/* bits definitions */ |
||||
|
/* ADC_STAT */ |
||||
|
#define ADC_STAT_WDE0 BIT(0) /*!< analog watchdog 0 event flag */ |
||||
|
#define ADC_STAT_EOC BIT(1) /*!< end of sequence conversion flag */ |
||||
|
#define ADC_STAT_EOIC BIT(2) /*!< end of inserted sequence conversion flag */ |
||||
|
#define ADC_STAT_STIC BIT(3) /*!< start flag of inserted sequence */ |
||||
|
#define ADC_STAT_STRC BIT(4) /*!< start flag of routine sequence */ |
||||
|
#define ADC_STAT_ROVF BIT(5) /*!< routine data register overflow */ |
||||
|
#define ADC_STAT_WDE1 BIT(30) /*!< analog watchdog 1 event flag */ |
||||
|
#define ADC_STAT_WDE2 BIT(31) /*!< analog watchdog 2 event flag */ |
||||
|
|
||||
|
/* ADC_CTL0 */ |
||||
|
#define ADC_CTL0_WD0CHSEL BITS(0,4) /*!< analog watchdog channel select */ |
||||
|
#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ |
||||
|
#define ADC_CTL0_WDE0IE BIT(6) /*!< interrupt enable for WDE0 */ |
||||
|
#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for EOIC */ |
||||
|
#define ADC_CTL0_SM BIT(8) /*!< scan mode */ |
||||
|
#define ADC_CTL0_WD0SC BIT(9) /*!< when in scan mode, analog watchdog 0 is effective on a single channel */ |
||||
|
#define ADC_CTL0_ICA BIT(10) /*!< inserted sequence convert automatically */ |
||||
|
#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on routine channels */ |
||||
|
#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ |
||||
|
#define ADC_CTL0_DISNUM BITS(13,15) /*!< number of conversions in discontinuous mode */ |
||||
|
#define ADC_CTL0_IWD0EN BIT(22) /*!< inserted channel analog watchdog 0 enable */ |
||||
|
#define ADC_CTL0_RWD0EN BIT(23) /*!< routine channel analog watchdog 0 enable */ |
||||
|
#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ |
||||
|
#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ |
||||
|
#define ADC_CTL0_WDE1IE BIT(30) /*!< interrupt enable for WDE1 */ |
||||
|
#define ADC_CTL0_WDE2IE BIT(31) /*!< interrupt enable for WDE2 */ |
||||
|
|
||||
|
/* ADC_CTL1 */ |
||||
|
#define ADC_CTL1_ADCON BIT(0) /*!< ADC on */ |
||||
|
#define ADC_CTL1_CTN BIT(1) /*!< continuous mode */ |
||||
|
#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ |
||||
|
#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ |
||||
|
#define ADC_CTL1_CALNUM BITS(4,6) /*!< ADC calibration times */ |
||||
|
#define ADC_CTL1_DMA BIT(8) /*!< DMA request enable */ |
||||
|
#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */ |
||||
|
#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */ |
||||
|
#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ |
||||
|
#define ADC_CTL1_HPDFCFG BIT(12) /*!< HPDF mode configuration */ |
||||
|
#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger mode for inserted channels */ |
||||
|
#define ADC_CTL1_SWICST BIT(22) /*!< software start on inserted channel */ |
||||
|
#define ADC_CTL1_TSVEN1 BIT(23) /*!< temperature sensor channel enable */ |
||||
|
#define ADC_CTL1_INREFEN BIT(24) /*!< vrefint channel enable */ |
||||
|
#define ADC_CTL1_VBATEN BIT(25) /*!< vbat channel enable */ |
||||
|
#define ADC_CTL1_CALMOD BIT(27) /*!< ADC calibration mode */ |
||||
|
#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger mode for routine channels */ |
||||
|
#define ADC_CTL1_SWRCST BIT(30) /*!< software start on routine channel. */ |
||||
|
#define ADC_CTL1_TSVEN2 BIT(31) /*!< high-precision temperature sensor channel enable */ |
||||
|
|
||||
|
/* ADC_IOFFx x=0..3 */ |
||||
|
#define ADC_IOFFX_IOFF BITS(0,23) /*!< data offset for inserted channel x */ |
||||
|
|
||||
|
/* ADC_WDHT0 */ |
||||
|
#define ADC_WDHT0_WDHT0 BITS(0,23) /*!< high threshold for analog watchdog 0 */ |
||||
|
|
||||
|
/* ADC_WDLT0 */ |
||||
|
#define ADC_WDLT0_WDLT0 BITS(0,23) /*!< low threshold for analog watchdog 0 */ |
||||
|
|
||||
|
/* ADC_RSQx x=0..8 */ |
||||
|
#define ADC_RSQX_RSQN BITS(0,4) /*!< nth conversion channel number in the routine sequence */ |
||||
|
#define ADC_RSQX_RSMPN BITS(5,14) /*!< nth conversion sample time in the routine sequence */ |
||||
|
#define ADC_RSQ0_RL BITS(20,23) /*!< routine sequence length */ |
||||
|
|
||||
|
/* ADC_ISQx x=0..2 */ |
||||
|
#define ADC_ISQX_ISQN BITS(0,4) /*!< nth conversion channel number in the inserted sequence */ |
||||
|
#define ADC_ISQX_ISMPN BITS(5,14) /*!< nth conversion sample time in the inserted sequence */ |
||||
|
#define ADC_ISQ0_IL BITS(20,21) /*!< inserted sequence length */ |
||||
|
|
||||
|
/* ADC_IDATAx x=0..3 */ |
||||
|
#define ADC_IDATAX_IDATAN BITS(0,31) /*!< Inserted number n conversion data */ |
||||
|
|
||||
|
/* ADC_RDATA */ |
||||
|
#define ADC_RDATA_RDATA BITS(0,31) /*!< routine channel data */ |
||||
|
|
||||
|
/* ADC_OVSAMPCTL */ |
||||
|
#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ |
||||
|
#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ |
||||
|
#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ |
||||
|
#define ADC_OVSAMPCTL_OVSR BITS(16,25) /*!< oversampling ratio */ |
||||
|
|
||||
|
/* ADC_WD1SR */ |
||||
|
#define ADC_WD1SR_AWD1CS BITS(0,21) /*!< analog watchdog 1 channel selection */ |
||||
|
|
||||
|
/* ADC_WD2SR */ |
||||
|
#define ADC_WD2SR_AWD2CS BITS(0,21) /*!< analog watchdog 2 channel selection */ |
||||
|
|
||||
|
/* ADC_WDHT1 */ |
||||
|
#define ADC_WDHT1_WDHT1 BITS(0,23) /*!< high threshold for analog watchdog 1 */ |
||||
|
|
||||
|
/* ADC_WDHT1 */ |
||||
|
#define ADC_WDLT1_WDLT1 BITS(0,23) /*!< low threshold for analog watchdog 1 */ |
||||
|
|
||||
|
/* ADC_WDHT2 */ |
||||
|
#define ADC_WDHT2_WDHT2 BITS(0,23) /*!< high threshold for analog watchdog 2 */ |
||||
|
|
||||
|
/* ADC_WDHT2 */ |
||||
|
#define ADC_WDLT2_WDLT2 BITS(0,23) /*!< low threshold for analog watchdog 2 */ |
||||
|
|
||||
|
/* ADC_DIFCTL */ |
||||
|
#define ADC_DIFCTL_DIFCTL BITS(0,21) /*!< Differential mode for channel 0..21 */ |
||||
|
|
||||
|
/* ADC_SSTAT */ |
||||
|
#define ADC_SSTAT_ADC0_WDE0 BIT(0) /*!< the bit is mirror image of the WDE0 bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_WDE1 BIT(1) /*!< the bit is mirror image of the WDE1 bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_WDE2 BIT(2) /*!< the bit is mirror image of the WDE2 bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_EOC BIT(3) /*!< the bit is mirror image of the EOC bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_EOIC BIT(4) /*!< the bit is mirror image of the EOIC bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_STIC BIT(5) /*!< the bit is mirror image of the STIC bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_STRC BIT(6) /*!< the bit is mirror image of the STRC bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC0_ROVF BIT(7) /*!< the bit is mirror image of the ROVF bit of ADC0 */ |
||||
|
#define ADC_SSTAT_ADC1_WDE0 BIT(8) /*!< the bit is mirror image of the WDE0 bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_WDE1 BIT(9) /*!< the bit is mirror image of the WDE1 bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_WDE2 BIT(10) /*!< the bit is mirror image of the WDE2 bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_EOC BIT(11) /*!< the bit is mirror image of the EOC bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_EOIC BIT(12) /*!< the bit is mirror image of the EOIC bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_STIC BIT(13) /*!< the bit is mirror image of the STIC bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_STRC BIT(14) /*!< the bit is mirror image of the STRC bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC1_ROVF BIT(15) /*!< the bit is mirror image of the ROVF bit of ADC1 */ |
||||
|
#define ADC_SSTAT_ADC2_WDE0 BIT(16) /*!< the bit is mirror image of the WDE0 bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_WDE1 BIT(17) /*!< the bit is mirror image of the WDE1 bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_WDE2 BIT(18) /*!< the bit is mirror image of the WDE2 bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_EOC BIT(19) /*!< the bit is mirror image of the EOC bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_EOIC BIT(20) /*!< the bit is mirror image of the EOIC bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_STIC BIT(21) /*!< the bit is mirror image of the STIC bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_STRC BIT(22) /*!< the bit is mirror image of the STRC bit of ADC2 */ |
||||
|
#define ADC_SSTAT_ADC2_ROVF BIT(23) /*!< the bit is mirror image of the ROVF bit of ADC2 */ |
||||
|
|
||||
|
/* ADC_SYNCCTL */ |
||||
|
#define ADC_SYNCCTL_SYNCM BITS(0,3) /*!< ADC sync mode */ |
||||
|
#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC sync delay */ |
||||
|
#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC sync DMA disable mode */ |
||||
|
#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC sync DMA mode selection */ |
||||
|
#define ADC_SYNCCTL_ADCSCK BITS(16,19) /*!< ADC sync clock mode */ |
||||
|
#define ADC_SYNCCTL_ADCCK BITS(20,23) /*!< ADC clock prescaler */ |
||||
|
|
||||
|
/* ADC_SYNCDATA0 */ |
||||
|
#define ADC_SYNCDATA0_SYNCDATA0 BITS(0,15) /*!< ADC0 routine data in ADC synchronization mode */ |
||||
|
#define ADC_SYNCDATA0_SYNCDATA1 BITS(16,31) /*!< ADC1 routine data in ADC synchronization mode */ |
||||
|
|
||||
|
/* constants definitions */ |
||||
|
/* ADC status flag */ |
||||
|
#define ADC_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event flag */ |
||||
|
#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion flag */ |
||||
|
#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion flag */ |
||||
|
#define ADC_FLAG_STIC ADC_STAT_STIC /*!< start flag of inserted sequence */ |
||||
|
#define ADC_FLAG_STRC ADC_STAT_STRC /*!< start flag of routine sequence */ |
||||
|
#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */ |
||||
|
#define ADC_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event flag */ |
||||
|
#define ADC_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event flag */ |
||||
|
|
||||
|
/* ADC interrupt */ |
||||
|
#define ADC_INT_WDE0 ADC_CTL0_WDE0IE /*!< interrupt enable for WDE0 */ |
||||
|
#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< interrupt enable for EOC */ |
||||
|
#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< interrupt enable for EOIC */ |
||||
|
#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< interrupt enable for ROVF */ |
||||
|
#define ADC_INT_WDE1 ADC_CTL0_WDE1IE /*!< interrupt enable for WDE1 */ |
||||
|
#define ADC_INT_WDE2 ADC_CTL0_WDE2IE /*!< interrupt enable for WDE2 */ |
||||
|
|
||||
|
/* ADC interrupt flag */ |
||||
|
#define ADC_INT_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event interrupt flag */ |
||||
|
#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion interrupt flag */ |
||||
|
#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion interrupt flag */ |
||||
|
#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow interrupt flag */ |
||||
|
#define ADC_INT_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event interrupt flag */ |
||||
|
#define ADC_INT_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event interrupt flag */ |
||||
|
|
||||
|
/* number of conversions in discontinuous mode */ |
||||
|
#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to ADC_CTL0_DISNUM bit field */ |
||||
|
|
||||
|
/* ADC special function definitions */ |
||||
|
#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ |
||||
|
#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted sequence convert automatically */ |
||||
|
#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ |
||||
|
|
||||
|
/* ADC calibration mode */ |
||||
|
#define ADC_CALIBRATION_OFFSET_MISMATCH ((uint32_t)0x00000000U) /*!< ADC calibration offset and mismatch mode */ |
||||
|
#define ADC_CALIBRATION_OFFSET ADC_CTL1_CALMOD /*!< ADC calibration mode */ |
||||
|
|
||||
|
/* ADC calibration times */ |
||||
|
#define CTL1_CALNUM(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) /*!< write value to ADC_CTL1_CLBNUM bit field */ |
||||
|
#define ADC_CALIBRATION_NUM1 CTL1_CALNUM(0) /*!< ADC calibration 1 time */ |
||||
|
#define ADC_CALIBRATION_NUM2 CTL1_CALNUM(1) /*!< ADC calibration 2 times */ |
||||
|
#define ADC_CALIBRATION_NUM4 CTL1_CALNUM(2) /*!< ADC calibration 4 times */ |
||||
|
#define ADC_CALIBRATION_NUM8 CTL1_CALNUM(3) /*!< ADC calibration 8 times */ |
||||
|
#define ADC_CALIBRATION_NUM16 CTL1_CALNUM(4) /*!< ADC calibration 16 times */ |
||||
|
#define ADC_CALIBRATION_NUM32 CTL1_CALNUM(5) /*!< ADC calibration 32 times */ |
||||
|
|
||||
|
/* ADC data alignment */ |
||||
|
#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ |
||||
|
#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ |
||||
|
|
||||
|
/* end of conversion mode */ |
||||
|
#define ADC_EOC_SET_SEQUENCE ((uint32_t)0x00000000U) /*!< only at the end of a sequence of routine conversions, the EOC bit is set */ |
||||
|
#define ADC_EOC_SET_CONVERSION ADC_CTL1_EOCM /*!< at the end of each routine conversion, the EOC bit is set */ |
||||
|
|
||||
|
/* ADC internal channel definitions */ |
||||
|
#define ADC_CHANNEL_INTERNAL_TEMPSENSOR ADC_CTL1_TSVEN1 /*!< temperature sensor channel */ |
||||
|
#define ADC_CHANNEL_INTERNAL_VREFINT ADC_CTL1_INREFEN /*!< vrefint channel */ |
||||
|
#define ADC_CHANNEL_INTERNAL_VBAT ADC_CTL1_VBATEN /*!< vbat channel */ |
||||
|
#define ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR ADC_CTL1_TSVEN2 /*!< high-precision temperature sensor channel */ |
||||
|
|
||||
|
/* ADC data offset for inserted channel x */ |
||||
|
#define IOFFX_IOFF(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_IOFFX_IOFF bit field */ |
||||
|
|
||||
|
/* ADC high threshold for analog watchdog 0 */ |
||||
|
#define WDHT0_WDHT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT0_WDHT0 bit field */ |
||||
|
|
||||
|
/* ADC low threshold for analog watchdog 0 */ |
||||
|
#define WDLT0_WDLT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT0_WDLT0 bit field */ |
||||
|
|
||||
|
/* ADC high threshold for analog watchdog 1 */ |
||||
|
#define WDHT1_WDHT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT1_WDHT1 bit field */ |
||||
|
|
||||
|
/* ADC low threshold for analog watchdog 1 */ |
||||
|
#define WDLT1_WDLT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT1_WDLT1 bit field */ |
||||
|
|
||||
|
/* ADC high threshold for analog watchdog 2 */ |
||||
|
#define WDHT2_WDHT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT2_WDHT2 bit field */ |
||||
|
|
||||
|
/* ADC low threshold for analog watchdog 2 */ |
||||
|
#define WDLT2_WDLT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT2_WDLT2 bit field */ |
||||
|
|
||||
|
/* ADC sequence sample time */ |
||||
|
#define SQX_SMP(regval) (BITS(5,14) & ((uint32_t)(regval) << 5U)) /*!< write value to RSQX_SMPn or ISQX_SMPn bit field */ |
||||
|
|
||||
|
/* ADC routine sequence length */ |
||||
|
#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_RSQ0_RL bit field */ |
||||
|
|
||||
|
/* ADC inserted sequence length */ |
||||
|
#define ISQ0_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_ISQ0_IL bit field */ |
||||
|
|
||||
|
/* ADC resolution */ |
||||
|
#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) /*!< write value to ADC_CTL0_DRES bit field */ |
||||
|
#define ADC_RESOLUTION_14B ((uint8_t)0x00U) /*!< 14-bit ADC resolution */ |
||||
|
#define ADC_RESOLUTION_12B ((uint8_t)0x01U) /*!< 12-bit ADC resolution */ |
||||
|
#define ADC_RESOLUTION_10B ((uint8_t)0x02U) /*!< 10-bit ADC resolution */ |
||||
|
#define ADC_RESOLUTION_8B ((uint8_t)0x03U) /*!< 8-bit ADC resolution */ |
||||
|
#define ADC_RESOLUTION_6B ((uint8_t)0x04U) /*!< 6-bit ADC resolution */ |
||||
|
|
||||
|
/* oversampling shift */ |
||||
|
#define OVSCR_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5U)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_9B OVSCR_OVSS(9) /*!< 9-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_10B OVSCR_OVSS(10) /*!< 10-bit oversampling shift */ |
||||
|
#define ADC_OVERSAMPLING_SHIFT_11B OVSCR_OVSS(11) /*!< 11-bit oversampling shift */ |
||||
|
|
||||
|
/* oversampling ratio */ |
||||
|
#define OVSCR_OVSR(regval) (BITS(16,25) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ |
||||
|
|
||||
|
/* triggered oversampling */ |
||||
|
#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ |
||||
|
#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ |
||||
|
|
||||
|
/* configure the ADC clock */ |
||||
|
#define SYNCCTL_ADCSCK(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_SYNCCTL_ADCSCK bit field */ |
||||
|
#define SYNCCTL_ADCCK(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_SYNCCTL_ADCCK bit field */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV2 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(8)) /*!< ADC sync clock mode HCLK div2 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV4 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(9)) /*!< ADC sync clock mode HCLK div4 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV6 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(10)) /*!< ADC sync clock mode HCLK div6 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV8 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(11)) /*!< ADC sync clock mode HCLK div8 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV10 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(12)) /*!< ADC sync clock mode HCLK div10 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV12 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(13)) /*!< ADC sync clock mode HCLK div12 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV14 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(14)) /*!< ADC sync clock mode HCLK div14 */ |
||||
|
#define ADC_CLK_SYNC_HCLK_DIV16 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(15)) /*!< ADC sync clock mode HCLK div16 */ |
||||
|
#define ADC_CLK_ASYNC_DIV1 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div1 */ |
||||
|
#define ADC_CLK_ASYNC_DIV2 (SYNCCTL_ADCCK(1) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div2 */ |
||||
|
#define ADC_CLK_ASYNC_DIV4 (SYNCCTL_ADCCK(2) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div4 */ |
||||
|
#define ADC_CLK_ASYNC_DIV6 (SYNCCTL_ADCCK(3) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div6 */ |
||||
|
#define ADC_CLK_ASYNC_DIV8 (SYNCCTL_ADCCK(4) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div8 */ |
||||
|
#define ADC_CLK_ASYNC_DIV10 (SYNCCTL_ADCCK(5) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div10 */ |
||||
|
#define ADC_CLK_ASYNC_DIV12 (SYNCCTL_ADCCK(6) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div12 */ |
||||
|
#define ADC_CLK_ASYNC_DIV16 (SYNCCTL_ADCCK(7) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div16 */ |
||||
|
#define ADC_CLK_ASYNC_DIV32 (SYNCCTL_ADCCK(8) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div32 */ |
||||
|
#define ADC_CLK_ASYNC_DIV64 (SYNCCTL_ADCCK(9) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div64 */ |
||||
|
#define ADC_CLK_ASYNC_DIV128 (SYNCCTL_ADCCK(10) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div128 */ |
||||
|
#define ADC_CLK_ASYNC_DIV256 (SYNCCTL_ADCCK(11) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div256 */ |
||||
|
|
||||
|
/* ADC sync DMA mode selection */ |
||||
|
#define SYNCCTL_SYNCDMA(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) /*!< write value to ADC_SYNCCTL_SYNCDMA bit field */ |
||||
|
#define ADC_SYNC_DMA_DISABLE SYNCCTL_SYNCDMA(0) /*!< ADC sync DMA disabled */ |
||||
|
#define ADC_SYNC_DMA_MODE0 SYNCCTL_SYNCDMA(1) /*!< ADC sync DMA mode 0 */ |
||||
|
#define ADC_SYNC_DMA_MODE1 SYNCCTL_SYNCDMA(2) /*!< ADC sync DMA mode 1 */ |
||||
|
|
||||
|
/* ADC sync delay */ |
||||
|
#define SYNCCTL_SYNCDLY(regval) (BITS(8,11) & ((uint32_t)(regval) << 8U)) /*!< write value to ADC_SYNCCTL_SYNCDLY bit field */ |
||||
|
#define ADC_SYNC_DELAY_5CYCLE SYNCCTL_SYNCDLY(0) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_6CYCLE SYNCCTL_SYNCDLY(1) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_7CYCLE SYNCCTL_SYNCDLY(2) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_8CYCLE SYNCCTL_SYNCDLY(3) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_9CYCLE SYNCCTL_SYNCDLY(4) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_10CYCLE SYNCCTL_SYNCDLY(5) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_11CYCLE SYNCCTL_SYNCDLY(6) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_12CYCLE SYNCCTL_SYNCDLY(7) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_13CYCLE SYNCCTL_SYNCDLY(8) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_14CYCLE SYNCCTL_SYNCDLY(9) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_15CYCLE SYNCCTL_SYNCDLY(10) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_16CYCLE SYNCCTL_SYNCDLY(11) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_17CYCLE SYNCCTL_SYNCDLY(12) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_18CYCLE SYNCCTL_SYNCDLY(13) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_19CYCLE SYNCCTL_SYNCDLY(14) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ |
||||
|
#define ADC_SYNC_DELAY_20CYCLE SYNCCTL_SYNCDLY(15) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ |
||||
|
|
||||
|
/* ADC sync mode */ |
||||
|
#define SYNCCTL_SYNCM(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_SYNCCTL_SYNCM bit field */ |
||||
|
#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */ |
||||
|
#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< combined routine parallel & inserted parallel mode */ |
||||
|
#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< combined routine parallel & trigger rotation mode */ |
||||
|
#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< inserted parallel mode */ |
||||
|
#define ADC_DAUL_ROUTINE_PARALLEL SYNCCTL_SYNCM(6) /*!< routine parallel mode */ |
||||
|
#define ADC_DAUL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< follow-up mode */ |
||||
|
#define ADC_DAUL_INSERTED_TRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< trigger rotation mode */ |
||||
|
|
||||
|
/* external trigger mode for routine and inserted channel */ |
||||
|
#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ |
||||
|
#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ |
||||
|
#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ |
||||
|
#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ |
||||
|
|
||||
|
/* ADC channel definitions */ |
||||
|
#define ADC_ROUTINE_CHANNEL ((uint8_t)0x01U) /*!< ADC routine sequence */ |
||||
|
#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted sequence */ |
||||
|
#define ADC_ROUTINE_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both routine and inserted sequence */ |
||||
|
#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of routine & inserted channel */ |
||||
|
|
||||
|
/* ADC inserted channel definitions */ |
||||
|
#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ |
||||
|
#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ |
||||
|
#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ |
||||
|
#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ |
||||
|
|
||||
|
/* ADC channel definitions */ |
||||
|
#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ |
||||
|
#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ |
||||
|
#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ |
||||
|
#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ |
||||
|
#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ |
||||
|
#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ |
||||
|
#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ |
||||
|
#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ |
||||
|
#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ |
||||
|
#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ |
||||
|
#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ |
||||
|
#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ |
||||
|
#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ |
||||
|
#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ |
||||
|
#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ |
||||
|
#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ |
||||
|
#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ |
||||
|
#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ |
||||
|
#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */ |
||||
|
#define ADC_CHANNEL_19 ((uint8_t)0x13U) /*!< ADC channel 19 */ |
||||
|
#define ADC_CHANNEL_20 ((uint8_t)0x14U) /*!< ADC channel 20 */ |
||||
|
|
||||
|
/* analog watchdog 1/2 channel selection for channel n(n=0..20) */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 analog watchdog 1/2 selection */ |
||||
|
#define ADC_AWD1_2_SELECTION_CHANNEL_ALL ((uint32_t)0x001FFFFFU) /*!< all ADC channels analog watchdog 1/2 selection */ |
||||
|
|
||||
|
/* Differential mode for channel n(n=0..21) */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_21 ((uint32_t)0x00200000U) /*!< ADC channel 21 differential mode */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_ALL ((uint32_t)0x003FFFFFU) /*!< all ADC channels differential mode */ |
||||
|
|
||||
|
/* parameter check definitions */ |
||||
|
#ifdef FW_DEBUG_ERR_REPORT |
||||
|
/* check the adc periph */ |
||||
|
#define NOT_ADC_PERIPH(adc_periph) (((adc_periph) != ADC0) && ((adc_periph) != ADC1) && \ |
||||
|
((adc_periph) != ADC2)) |
||||
|
|
||||
|
/* check the adc prescaler ratio */ |
||||
|
#define NOT_ADC_CLK_MODE(prescaler) (((prescaler) != ADC_CLK_SYNC_HCLK_DIV2) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV4) && \ |
||||
|
((prescaler) != ADC_CLK_SYNC_HCLK_DIV6) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV8) && \ |
||||
|
((prescaler) != ADC_CLK_SYNC_HCLK_DIV10) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV12) && \ |
||||
|
((prescaler) != ADC_CLK_SYNC_HCLK_DIV14) && ((prescaler) != ADC_CLK_SYNC_HCLK_DIV16) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV1) && ((prescaler) != ADC_CLK_ASYNC_DIV2) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV4) && ((prescaler) != ADC_CLK_ASYNC_DIV6) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV8) && ((prescaler) != ADC_CLK_ASYNC_DIV10) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV12) && ((prescaler) != ADC_CLK_ASYNC_DIV16) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV32) && ((prescaler) != ADC_CLK_ASYNC_DIV64) && \ |
||||
|
((prescaler) != ADC_CLK_ASYNC_DIV128) && ((prescaler) != ADC_CLK_ASYNC_DIV256)) |
||||
|
|
||||
|
/* check adc special mode */ |
||||
|
#define ADC_SPECIAL_FUNCTION_LOW ((uint32_t)0x00000002U) |
||||
|
#define ADC_SPECIAL_FUNCTION_HIGH ((uint32_t)0x00000502U) |
||||
|
#define NOT_ADC_SPECIAL_FUNCTION_VALUE(function) ((ADC_SPECIAL_FUNCTION_LOW > (function)) || (ADC_SPECIAL_FUNCTION_HIGH < (function))) |
||||
|
|
||||
|
/* check ENABLE and DISABLE */ |
||||
|
#define NOT_ADC_ENABLE_DISABLE(newvalue) (((newvalue) != ENABLE) && ((newvalue) != DISABLE)) |
||||
|
|
||||
|
/* check data alignment */ |
||||
|
#define NOT_ADC_DATA_ALIGNMENT(data_alignment) (((data_alignment) != ADC_DATAALIGN_RIGHT) && ((data_alignment) != ADC_DATAALIGN_LEFT)) |
||||
|
|
||||
|
/* check adc calibration mode */ |
||||
|
#define NOT_CALIBRATION_MODE(clb_mode) (((clb_mode) != ADC_CALIBRATION_OFFSET_MISMATCH) && ((clb_mode) != ADC_CALIBRATION_OFFSET)) |
||||
|
|
||||
|
/* check adc calibration number */ |
||||
|
#define NOT_ADC_CALIBRATION_NUMBER(clb_num) (((clb_num) != ADC_CALIBRATION_NUM1) && ((clb_num) != ADC_CALIBRATION_NUM2) && \ |
||||
|
((clb_num) != ADC_CALIBRATION_NUM4) && ((clb_num) != ADC_CALIBRATION_NUM8) && \ |
||||
|
((clb_num) != ADC_CALIBRATION_NUM16) && ((clb_num) != ADC_CALIBRATION_NUM32)) |
||||
|
|
||||
|
/* check ADC resolution */ |
||||
|
#define NOT_ADC_RESOLUTION(resolution) (((resolution) != ADC_RESOLUTION_14B) && ((resolution) != ADC_RESOLUTION_12B) && ((resolution) \ |
||||
|
!= ADC_RESOLUTION_10B) && ((resolution) != ADC_RESOLUTION_8B) && ((resolution) != ADC_RESOLUTION_6B)) |
||||
|
|
||||
|
/* check ADC resolution */ |
||||
|
#define NOT_ADC_CHANNEL_INTERNAL(internal_channel) (((internal_channel) != ADC_CHANNEL_INTERNAL_TEMPSENSOR) && ((internal_channel) != ADC_CHANNEL_INTERNAL_VREFINT) && \ |
||||
|
((internal_channel) != ADC_CHANNEL_INTERNAL_VBAT) && ((internal_channel) != ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR)) |
||||
|
|
||||
|
/* check ADC sequence */ |
||||
|
#define NOT_ADC_SEQUENCE(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL)) |
||||
|
|
||||
|
/* check discontinuous mode length */ |
||||
|
#define ADC_DISCONTINUOUS_MODE_LENGTH_LOW ((uint32_t)0x00000001U) |
||||
|
#define ADC_DISCONTINUOUS_MODE_LENGTH_HIGH ((uint32_t)0x00000008U) |
||||
|
#define NOT_ADC_DISCONTINUOUS_MODE_LENGTH(length) ((ADC_DISCONTINUOUS_MODE_LENGTH_LOW > (length)) || (ADC_DISCONTINUOUS_MODE_LENGTH_HIGH < (length))) |
||||
|
|
||||
|
/* check ADC sequence */ |
||||
|
#define NOT_ADC_SEQUENCE(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL)) |
||||
|
|
||||
|
/* check ADC sequence */ |
||||
|
#define NOT_ADC_SEQUENCE_EXD(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL)&& ((adc_sequence) != ADC_CHANNEL_DISCON_DISABLE)) |
||||
|
|
||||
|
/* check ADC channel length */ |
||||
|
#define ADC_CHANNEL_LENGTH_LOW ((uint32_t)0x00000001U) |
||||
|
#define ADC_CHANNEL_LENGTH_HIGH ((uint32_t)0x00000010U) |
||||
|
#define NOT_ADC_CHANNEL_LENGTH(length) ((ADC_CHANNEL_LENGTH_LOW > (length)) || (ADC_CHANNEL_LENGTH_HIGH < (length))) |
||||
|
|
||||
|
/* check routine sequence rank */ |
||||
|
#define ADC_ROUTINE_SEQUENCE_RANK_HIGH ((uint32_t)0x0000000FU) |
||||
|
#define NOT_ADC_ROUTINE_SEQUENCE_RANK_VALUE(rank) (ADC_ROUTINE_SEQUENCE_RANK_HIGH < (rank)) |
||||
|
|
||||
|
/* check ADC channel select */ |
||||
|
#define NOT_ADC_CHANNEL(channel) (((channel) != ADC_CHANNEL_0) && ((channel) != ADC_CHANNEL_1) && \ |
||||
|
((channel) != ADC_CHANNEL_2) && ((channel) != ADC_CHANNEL_3) && \ |
||||
|
((channel) != ADC_CHANNEL_4) && ((channel) != ADC_CHANNEL_5) && \ |
||||
|
((channel) != ADC_CHANNEL_6) && ((channel) != ADC_CHANNEL_7) && \ |
||||
|
((channel) != ADC_CHANNEL_8) && ((channel) != ADC_CHANNEL_9) && \ |
||||
|
((channel) != ADC_CHANNEL_10) && ((channel) != ADC_CHANNEL_11) && \ |
||||
|
((channel) != ADC_CHANNEL_12) && ((channel) != ADC_CHANNEL_13) && \ |
||||
|
((channel) != ADC_CHANNEL_14) && ((channel) != ADC_CHANNEL_15) && \ |
||||
|
((channel) != ADC_CHANNEL_16) && ((channel) != ADC_CHANNEL_17) && \ |
||||
|
((channel) != ADC_CHANNEL_18) && ((channel) != ADC_CHANNEL_19) && \ |
||||
|
((channel) != ADC_CHANNEL_20)) |
||||
|
|
||||
|
/* check ADC sample_time */ |
||||
|
#define ADC_ADC_SAMPLE_TIME_HIGH ((uint32_t)0x00000329U) |
||||
|
#define NOT_ADC_SAMPLE_TIME(sample_time) (ADC_ADC_SAMPLE_TIME_HIGH < (sample_time)) |
||||
|
|
||||
|
/* check inserted sequence rank */ |
||||
|
#define ADC_INSERTED_SEQUENCE_RANK_HIGH ((uint32_t)0x00000003U) |
||||
|
#define NOT_ADC_INSERTED_SEQUENCE_RANK_VALUE(rank) (ADC_INSERTED_SEQUENCE_RANK_HIGH < (rank)) |
||||
|
|
||||
|
/* check inserted channel */ |
||||
|
#define NOT_INSERTED_CHANNEL(inserted_channel) (((inserted_channel) != ADC_INSERTED_CHANNEL_0) && ((inserted_channel) != ADC_INSERTED_CHANNEL_1) && \ |
||||
|
((inserted_channel) != ADC_INSERTED_CHANNEL_2) && ((inserted_channel) != ADC_INSERTED_CHANNEL_3)) |
||||
|
|
||||
|
/* check inserted offset value */ |
||||
|
#define ADC_INSERTED_OFFSET_HIGH ((uint32_t)0x00FFFFFFU) |
||||
|
#define NOT_ADC_INSERTED_OFFSET_VALUE(offset) (ADC_INSERTED_OFFSET_HIGH < (offset)) |
||||
|
|
||||
|
/* check ADC trigger mode */ |
||||
|
#define NOT_ADC_TRIGGER_MODE(trigger_mode) (((trigger_mode) != EXTERNAL_TRIGGER_DISABLE) && ((trigger_mode) != EXTERNAL_TRIGGER_RISING) && \ |
||||
|
((trigger_mode) != EXTERNAL_TRIGGER_FALLING) && ((trigger_mode) != EXTERNAL_TRIGGER_RISING_FALLING)) |
||||
|
|
||||
|
/* end of conversion mode */ |
||||
|
#define NOT_ADC_END_OF_CONVERSION_MODE(end_selection) (((end_selection) != ADC_EOC_SET_SEQUENCE) && ((end_selection) != ADC_EOC_SET_CONVERSION)) |
||||
|
|
||||
|
/* check ADC sequence */ |
||||
|
#define NOT_ADC_SEQUENC_BOTH(adc_sequence) (((adc_sequence) != ADC_ROUTINE_CHANNEL) && ((adc_sequence) != ADC_INSERTED_CHANNEL) && \ |
||||
|
((adc_sequence) != ADC_ROUTINE_INSERTED_CHANNEL)) |
||||
|
|
||||
|
/* check differential mode for ADC channel */ |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_LOW ((uint32_t)0x00000001U) |
||||
|
#define ADC_DIFFERENTIAL_MODE_CHANNEL_HIGH ((uint32_t)0x003FFFFFU) |
||||
|
#define NOT_ADC_DIFFERENTIAL_MODE_CHANNEL(length) ((ADC_DIFFERENTIAL_MODE_CHANNEL_LOW > (length)) || (ADC_DIFFERENTIAL_MODE_CHANNEL_HIGH < (length))) |
||||
|
|
||||
|
/* check ADC analog watchdog 1/2 selection */ |
||||
|
#define ADC_ANALOG_WATCHDOG_SEL_LOW ((uint32_t)0x00000001U) |
||||
|
#define ADC_ANALOG_WATCHDOG_SEL_HIGH ((uint32_t)0x001FFFFFU) |
||||
|
#define NOT_ADC_ANALOG_WATCHDOG_SEL(selection_channel) ((ADC_ANALOG_WATCHDOG_SEL_LOW > (selection_channel)) || (ADC_ANALOG_WATCHDOG_SEL_HIGH < (selection_channel))) |
||||
|
|
||||
|
|
||||
|
/* check analog watchdog threshold */ |
||||
|
#define ADC_ANALOG_WATCHDOG_THRESHOLD_HIGH ((uint32_t)0x00FFFFFFU) |
||||
|
#define NOT_ADC_ANALOG_WATCHDOG_THRESHOLD(threshold) (ADC_ANALOG_WATCHDOG_THRESHOLD_HIGH < (threshold)) |
||||
|
|
||||
|
/* check ADC oversampling mode */ |
||||
|
#define NOT_ADC_OVERSAMPLING_MODE(mode) (((mode) != ADC_OVERSAMPLING_ALL_CONVERT) && ((mode) != ADC_OVERSAMPLING_ONE_CONVERT)) |
||||
|
|
||||
|
/* check ADC oversampling shift */ |
||||
|
#define NOT_ADC_OVERSAMPLING_SHIFT(shift) (((shift) != ADC_OVERSAMPLING_SHIFT_NONE) && ((shift) != ADC_OVERSAMPLING_SHIFT_1B) && \ |
||||
|
((shift) != ADC_OVERSAMPLING_SHIFT_2B) && ((shift) != ADC_OVERSAMPLING_SHIFT_3B) && \ |
||||
|
((shift) != ADC_OVERSAMPLING_SHIFT_4B) && ((shift) != ADC_OVERSAMPLING_SHIFT_5B) && \ |
||||
|
((shift) != ADC_OVERSAMPLING_SHIFT_6B) && ((shift) != ADC_OVERSAMPLING_SHIFT_7B) && \ |
||||
|
((shift) != ADC_OVERSAMPLING_SHIFT_8B) && ((shift) != ADC_OVERSAMPLING_SHIFT_9B) && \ |
||||
|
((shift) != ADC_OVERSAMPLING_SHIFT_10B) && ((shift) != ADC_OVERSAMPLING_SHIFT_11B)) |
||||
|
|
||||
|
/* check ADC oversampling ratio */ |
||||
|
#define ADC_OVERSAMPLING_RATIO_HIGH ((uint32_t)0x000003FFU) |
||||
|
#define NOT_ADC_OVERSAMPLING_RATIO(ratio) (ADC_OVERSAMPLING_RATIO_HIGH < (ratio)) |
||||
|
|
||||
|
/* check ADC falg */ |
||||
|
#define NOT_ADC_FLAG(flag) (((flag) != ADC_FLAG_WDE0) && ((flag) != ADC_FLAG_EOC) && \ |
||||
|
((flag) != ADC_FLAG_EOIC) && ((flag) != ADC_FLAG_STIC) && \ |
||||
|
((flag) != ADC_FLAG_STRC) && ((flag) != ADC_FLAG_ROVF) && \ |
||||
|
((flag) != ADC_FLAG_WDE1) && ((flag) != ADC_FLAG_WDE2)) |
||||
|
|
||||
|
/* check ADC interrupt */ |
||||
|
#define NOT_ADC_INTERRUPT(interrupt) (((interrupt) != ADC_INT_WDE0) && ((interrupt) != ADC_INT_EOC) && \ |
||||
|
((interrupt) != ADC_INT_EOIC) && ((interrupt) != ADC_INT_ROVF) && \ |
||||
|
((interrupt) != ADC_INT_WDE1) && ((interrupt) != ADC_INT_WDE2)) |
||||
|
|
||||
|
/* check ADC interrupt flag */ |
||||
|
#define NOT_ADC_INTERRUPT_FLAG(flag) (((int_flag) != ADC_INT_FLAG_WDE0) && ((int_flag) != ADC_INT_FLAG_EOC) && \ |
||||
|
((int_flag) != ADC_INT_FLAG_EOIC) && ((int_flag) != ADC_INT_FLAG_ROVF) && \ |
||||
|
((int_flag) != ADC_INT_FLAG_WDE1) && ((int_flag) != ADC_INT_FLAG_WDE2)) |
||||
|
|
||||
|
/* check the adc sync mode */ |
||||
|
#define NOT_ADC_SYNC_mode(sync_mode) (((sync_mode) != ADC_SYNC_MODE_INDEPENDENT) && ((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL) && \ |
||||
|
((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION) && ((sync_mode) != ADC_DAUL_INSERTED_PARALLEL) && \ |
||||
|
((sync_mode) != ADC_DAUL_ROUTINE_PARALLEL) && ((sync_mode) != ADC_DAUL_ROUTINE_FOLLOW_UP) && \ |
||||
|
((sync_mode) != ADC_DAUL_INSERTED_TRIGGER_ROTATION)) |
||||
|
|
||||
|
/* check the adc sync delay sample */ |
||||
|
#define NOT_ADC_SYNC_DELAY_SAMPLE(sample_delay) (((sample_delay) != ADC_SYNC_DELAY_5CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_6CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_7CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_8CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_9CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_10CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_11CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_12CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_13CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_14CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_15CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_16CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_17CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_18CYCLE) && \ |
||||
|
((sample_delay) != ADC_SYNC_DELAY_19CYCLE) && ((sample_delay) != ADC_SYNC_DELAY_20CYCLE)) |
||||
|
|
||||
|
/* check the adc sync dma mode */ |
||||
|
#define NOT_ADC_SYNC_DMA_mode(dma_mode) (((dma_mode) != ADC_SYNC_DMA_DISABLE) && ((dma_mode) != ADC_SYNC_DMA_MODE0) && \ |
||||
|
((dma_mode) != ADC_SYNC_DMA_MODE1)) |
||||
|
|
||||
|
#endif /* FW_DEBUG_ERR_REPORT */ |
||||
|
|
||||
|
/* function declarations */ |
||||
|
/* initialization config */ |
||||
|
/* reset ADC */ |
||||
|
void adc_deinit(uint32_t adc_periph); |
||||
|
/* configure the ADC clock */ |
||||
|
void adc_clock_config(uint32_t adc_periph, uint32_t prescaler); |
||||
|
/* enable or disable ADC special function */ |
||||
|
void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue); |
||||
|
/* configure ADC data alignment */ |
||||
|
void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment); |
||||
|
/* enable ADC interface */ |
||||
|
void adc_enable(uint32_t adc_periph); |
||||
|
/* disable ADC interface */ |
||||
|
void adc_disable(uint32_t adc_periph); |
||||
|
/* configure ADC calibration mode */ |
||||
|
void adc_calibration_mode_config(uint32_t adc_periph, uint32_t clb_mode); |
||||
|
/* configure ADC calibration number */ |
||||
|
void adc_calibration_number(uint32_t adc_periph, uint32_t clb_num); |
||||
|
/* ADC calibration and reset calibration */ |
||||
|
void adc_calibration_enable(uint32_t adc_periph); |
||||
|
/* configure ADC resolution */ |
||||
|
void adc_resolution_config(uint32_t adc_periph, uint32_t resolution); |
||||
|
/* enable or disable ADC internal channels */ |
||||
|
void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue); |
||||
|
|
||||
|
/* DMA config */ |
||||
|
/* enable DMA request */ |
||||
|
void adc_dma_mode_enable(uint32_t adc_periph); |
||||
|
/* disable DMA request */ |
||||
|
void adc_dma_mode_disable(uint32_t adc_periph); |
||||
|
/* when DMA=1, the DMA engine issues a request at end of each routine conversion */ |
||||
|
void adc_dma_request_after_last_enable(uint32_t adc_periph); |
||||
|
/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */ |
||||
|
void adc_dma_request_after_last_disable(uint32_t adc_periph); |
||||
|
/* enable hpdf mode */ |
||||
|
void adc_hpdf_mode_enable(uint32_t adc_periph); |
||||
|
/* disable hpdf mode */ |
||||
|
void adc_hpdf_mode_disable(uint32_t adc_periph); |
||||
|
|
||||
|
/* routine sequence and inserted sequence config */ |
||||
|
/* configure ADC discontinuous mode */ |
||||
|
void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length); |
||||
|
/* configure the length of routine sequence or inserted sequence */ |
||||
|
void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length); |
||||
|
/* configure ADC routine channel */ |
||||
|
void adc_routine_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); |
||||
|
/* configure ADC inserted channel */ |
||||
|
void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); |
||||
|
/* configure ADC inserted channel offset */ |
||||
|
void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint32_t offset); |
||||
|
/* configure differential mode for channel */ |
||||
|
void adc_channel_differential_mode_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue); |
||||
|
/* enable ADC external trigger */ |
||||
|
void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t trigger_mode); |
||||
|
/* enable ADC software trigger */ |
||||
|
void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_sequence); |
||||
|
/* configure end of conversion mode */ |
||||
|
void adc_end_of_conversion_config(uint32_t adc_periph, uint32_t end_selection); |
||||
|
|
||||
|
/* get channel data */ |
||||
|
/* read ADC routine sequence data register */ |
||||
|
uint32_t adc_routine_data_read(uint32_t adc_periph); |
||||
|
/* read ADC inserted sequence data register */ |
||||
|
uint32_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel); |
||||
|
|
||||
|
/* ADC analog watchdog functions */ |
||||
|
/* configure ADC analog watchdog 0 single channel */ |
||||
|
void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel); |
||||
|
/* configure ADC analog watchdog 0 group channel */ |
||||
|
void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_sequence); |
||||
|
/* disable ADC analog watchdog 0 */ |
||||
|
void adc_watchdog0_disable(uint32_t adc_periph); |
||||
|
/* configure ADC analog watchdog 1 channel */ |
||||
|
void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue); |
||||
|
/* configure ADC analog watchdog 2 channel */ |
||||
|
void adc_watchdog2_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue); |
||||
|
/* disable ADC analog watchdog 1 */ |
||||
|
void adc_watchdog1_disable(uint32_t adc_periph); |
||||
|
/* disable ADC analog watchdog 2 */ |
||||
|
void adc_watchdog2_disable(uint32_t adc_periph); |
||||
|
/* configure ADC analog watchdog 0 threshold */ |
||||
|
void adc_watchdog0_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); |
||||
|
/* configure ADC analog watchdog 1 threshold */ |
||||
|
void adc_watchdog1_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); |
||||
|
/* configure ADC analog watchdog 2 threshold */ |
||||
|
void adc_watchdog2_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); |
||||
|
|
||||
|
/* ADC oversample functions */ |
||||
|
/* configure ADC oversample mode */ |
||||
|
void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint16_t ratio); |
||||
|
/* enable ADC oversample mode */ |
||||
|
void adc_oversample_mode_enable(uint32_t adc_periph); |
||||
|
/* disable ADC oversample mode */ |
||||
|
void adc_oversample_mode_disable(uint32_t adc_periph); |
||||
|
|
||||
|
/* flag and interrupt functions */ |
||||
|
/* get the ADC flag bits */ |
||||
|
FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t flag); |
||||
|
/* clear the ADC flag bits */ |
||||
|
void adc_flag_clear(uint32_t adc_periph, uint32_t flag); |
||||
|
/* enable ADC interrupt */ |
||||
|
void adc_interrupt_enable(uint32_t adc_periph, uint32_t interrupt); |
||||
|
/* disable ADC interrupt */ |
||||
|
void adc_interrupt_disable(uint32_t adc_periph, uint32_t interrupt); |
||||
|
/* get the ADC interrupt bits */ |
||||
|
FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t int_flag); |
||||
|
/* clear the ADC flag */ |
||||
|
void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t int_flag); |
||||
|
|
||||
|
/* ADC synchronization */ |
||||
|
/* configure the ADC sync mode */ |
||||
|
void adc_sync_mode_config(uint32_t sync_mode); |
||||
|
/* configure the delay between 2 sampling phases in ADC sync modes */ |
||||
|
void adc_sync_delay_config(uint32_t sample_delay); |
||||
|
/* configure ADC sync DMA mode selection */ |
||||
|
void adc_sync_dma_config(uint32_t dma_mode); |
||||
|
/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */ |
||||
|
void adc_sync_dma_request_after_last_enable(void); |
||||
|
/* configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected */ |
||||
|
void adc_sync_dma_request_after_last_disable(void); |
||||
|
/* read ADC sync master adc routine data register 0 */ |
||||
|
uint32_t adc_sync_master_adc_routine_data0_read(void); |
||||
|
/* read ADC sync slave adc routine data register 0 */ |
||||
|
uint32_t adc_sync_slave_adc_routine_data0_read(void); |
||||
|
/* read ADC sync routine data register 1 */ |
||||
|
uint32_t adc_sync_routine_data1_read(void); |
||||
|
|
||||
|
#endif /* GD32H75E_ADC_H */ |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue