first submission
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" moduleId="org.eclipse.cdt.core.settings" name="obj">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" name="obj" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release">
|
||||
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074." name="/" resourcePath="">
|
||||
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.231146001" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.size" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32i" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" useByScannerDiscovery="false" value="GNU MCU RISC-V GCC" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" useByScannerDiscovery="false" value="riscv-none-embed-" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" useByScannerDiscovery="false" value="512258282" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.fp.962468442" name="Floating point ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.fp" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.fp.none" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.1234945999" name="Code model" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.any" valueType="enumerated"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.985553432" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon.1027770482" name="No common unitialized (-fno-common)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw.1095966167" name="Extra Compressed extension (RVXW)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw" value="true" valueType="boolean"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1944008784" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
|
||||
<builder buildPath="${workspace_loc:/RF_PHY}/obj" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1421508906" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1692176068" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.1034038285" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath"/>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.126366858" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1567947810" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/SRC/Core}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/SRC/Startup}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/SRC/Debug}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/SRC/Peripheral/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/APP/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Profile/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/HAL/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/LIB}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/LWNS}""/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.2020844713" name="Language standard" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.gnu99" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.177116515" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="CH32V20x_D8W"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.files.288896968" name="Include files (-include)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.preprocessonly.1594987158" name="Preprocess only (-E)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.preprocessonly" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.nostdinc.698774408" name="Do not search system directories (-nostdinc)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.nostdinc" useByScannerDiscovery="true" value="false" valueType="boolean"/>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.194760422" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths.2057340378" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""../""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/LWNS}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/LIB}""/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.1390103472" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/HAL/Link.ld}""/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.913830613" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano.239404511" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys.351964161" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs.16994550" name="Other objects" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs" useByScannerDiscovery="false" valueType="userObjs"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.strip.1780837525" name="Omit all symbol information (-s)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.strip" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.cref.1847421489" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.cref" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printmap.548776282" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printmap" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.1350862782" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="wchble"/>
|
||||
<listOptionValue builtIn="false" value="WCHLWNS"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.1577723329" name="Linker flags (-Xlinker [option])" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="--print-memory-usage"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.1859223768" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1689063433" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths.1029177148" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""../LD""/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile.1751226764" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="Link.ld"/>
|
||||
</option>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart.642896175" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano.1540675679" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.2052761852" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.439659821" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.67111865" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1549373929" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.1298918921" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.other.108640181" name="Other flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.other" useByScannerDiscovery="false" value="-D" valueType="string"/>
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.debugging.1148933762" name="Display debugging info (--debugging|-g)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.debugging" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">
|
||||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.1404031980" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="APP"/>
|
||||
<entry excluding="Profile|KEY.c|LED.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="HAL"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="LIB"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="LWNS"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Profile"/>
|
||||
<entry excluding="Startup/startup_ch32v20x_D8.S|Startup/startup_ch32v20x_D6.S|Ld/" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="SRC"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="999.ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf.275846018" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1375371130;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1473381709">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
</cproject>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<projectDescription>
|
||||
<name>LWNS</name>
|
||||
<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.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>HAL</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-1-PROJECT_LOC/HAL</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>LIB</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-1-PROJECT_LOC/LIB</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>SRC</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/SRC</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1602468250279</id>
|
||||
<name/>
|
||||
<type>22</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
<arguments>1.0-name-matches-false-false-*.wvproj</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,73 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_settings_version=1
|
||||
@@ -0,0 +1,93 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2020/08/06
|
||||
* Description :
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "CONFIG.h"
|
||||
#include "HAL.h"
|
||||
#include "stdlib.h"
|
||||
#include "lwns_adapter_csma_mac.h"
|
||||
#include "lwns_adapter_blemesh_mac.h"
|
||||
#include "lwns_adapter_no_mac.h"
|
||||
#include "lwns_broadcast_example.h"
|
||||
#include "lwns_ruc_example.h"
|
||||
#include "lwns_rucft_example.h"
|
||||
#include "lwns_unicast_example.h"
|
||||
#include "lwns_multicast_example.h"
|
||||
#include "lwns_netflood_example.h"
|
||||
#include "lwns_uninetflood_example.h"
|
||||
#include "lwns_multinetflood_example.h"
|
||||
#include "lwns_mesh_example.h"
|
||||
|
||||
//The switch printed by each file separately, and 0 can prohibit the internal printing of this file.
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
__attribute__((aligned(4))) u32 MEM_BUF[BLE_MEMHEAP_SIZE/4];
|
||||
|
||||
#if (defined (BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
uint8_t const MacAddr[6] = {0x84,0xC2,0xE4,0x03,0x02,0x02};
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Main_Circulation
|
||||
*
|
||||
* @brief Main loop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__((section(".highcode")))
|
||||
__attribute__((noinline))
|
||||
void Main_Circulation(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main function
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
Delay_Init();
|
||||
#ifdef DEBUG
|
||||
USART_Printf_Init( 115200 );
|
||||
#endif
|
||||
PRINT("%s\n", VER_LIB);
|
||||
WCHBLE_Init();
|
||||
HAL_Init( );
|
||||
RF_RoleInit( );
|
||||
RF_Init( );
|
||||
lwns_init();//初始lwns协议栈
|
||||
//lwns_broadcast_process_init();//广播
|
||||
//lwns_multicast_process_init();//组播
|
||||
//lwns_unicast_process_init();//单播
|
||||
//lwns_ruc_process_init();//可靠单播
|
||||
//lwns_rucft_process_init();//可靠单播文件传输
|
||||
lwns_netflood_process_init();//网络泛洪
|
||||
//lwns_uninetflood_process_init();//单播网络泛洪
|
||||
//lwns_multinetflood_process_init();//组播网络泛洪
|
||||
//lwns_mesh_process_init();//mesh组网
|
||||
Main_Circulation();
|
||||
}
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,74 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "ch32v20x_it.h"
|
||||
#include "CONFIG.h"
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void LLE_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn BB_IRQHandler
|
||||
*
|
||||
* @brief BB Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void BB_IRQHandler(void)
|
||||
{
|
||||
BB_IRQLibHandler();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn LLE_IRQHandler
|
||||
*
|
||||
* @brief LLE Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void LLE_IRQHandler(void)
|
||||
{
|
||||
LLE_IRQLibHandler();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
@@ -0,0 +1,72 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_blemesh_mac.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,模拟ble sig mesh的mac协议
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_ADAPTER_BLEMESH_MAC_H_
|
||||
#define _LWNS_ADAPTER_BLEMESH_MAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define LWNS_USE_BLEMESH_MAC 1 //是否使能模仿blemesh的mac协议,注意只能使能一个mac层协议。
|
||||
|
||||
#if LWNS_USE_BLEMESH_MAC
|
||||
|
||||
struct blemesh_mac_phy_manage_struct
|
||||
{
|
||||
struct blemesh_mac_phy_manage_struct *next;
|
||||
uint8_t *data;
|
||||
}; //模仿blemesh mac层发送管理结构体
|
||||
|
||||
#define LWNS_MAC_TRANSMIT_TIMES 2 //一次发送,调用硬件发送几次
|
||||
|
||||
#define LWNS_MAC_PERIOD_MS 10 //mac接收周期,轮流切换
|
||||
|
||||
#define LWNS_MAC_SEND_DELAY_MAX_MS 10 //蓝牙mesh就是10ms以内的随机数。
|
||||
|
||||
#define LWNS_MAC_SEND_PACKET_MAX_NUM 8 //发送链表最多支持几个数据包等待发送
|
||||
|
||||
#define BLE_PHY_ONE_PACKET_MAX_625US 5 //ble mac发送一个包最大可能需要的周期
|
||||
|
||||
#define LLE_MODE_ORIGINAL_RX (0x80) //如果配置LLEMODE时加上此宏,则接收第一字节为原始数据(原来为RSSI)
|
||||
|
||||
#define LWNS_HTIMER_PERIOD_MS 20 //为(1000/HTIMER_SECOND_NUM)
|
||||
|
||||
//RF_TX和RF_RX所用的类型,可以修改,不推荐改
|
||||
#define USER_RF_RX_TX_TYPE 0xff
|
||||
|
||||
#define LWNS_PHY_OUTPUT_TIMEOUT_MS 5
|
||||
|
||||
//receive process evt
|
||||
#define LWNS_PHY_RX_OPEN_EVT 1
|
||||
#define LWNS_PHY_RX_CHANGE_CHANNEL_EVT 2
|
||||
//send process evt
|
||||
#define LWNS_HTIMER_PERIOD_EVT 1
|
||||
#define LWNS_PHY_OUTPUT_PREPARE_EVT 2
|
||||
#define LWNS_PHY_OUTPUT_FINISH_EVT 4
|
||||
|
||||
extern void RF_Init(void);
|
||||
|
||||
extern void lwns_init(void);
|
||||
|
||||
extern void lwns_shut(void);
|
||||
|
||||
extern void lwns_start(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWNS_USE_BLEMESH_MAC */
|
||||
|
||||
#endif /* _LWNS_ADAPTER_BLEMESH_MAC_H_ */
|
||||
@@ -0,0 +1,78 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_csma_mac.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,模拟csma的mac协议
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_ADAPTER_CSMA_MAC_H_
|
||||
#define _LWNS_ADAPTER_CSMA_MAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define LWNS_USE_CSMA_MAC 0 //是否使能模仿csma的mac协议,注意只能使能一个mac层协议。
|
||||
|
||||
#if LWNS_USE_CSMA_MAC
|
||||
|
||||
struct csma_mac_phy_manage_struct
|
||||
{
|
||||
struct csma_mac_phy_manage_struct *next;
|
||||
uint8_t *data;
|
||||
}; //模拟csma mac层发送管理结构体
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BLE_PHY_MANAGE_STATE_FREE = 0,
|
||||
BLE_PHY_MANAGE_STATE_RECEIVED,
|
||||
BLE_PHY_MANAGE_STATE_WAIT_SEND,
|
||||
BLE_PHY_MANAGE_STATE_SENDING,
|
||||
} BLE_PHY_MANAGE_STATE_t;
|
||||
|
||||
#define LWNS_MAC_TRANSMIT_TIMES 2 //一次发送,调用硬件发送几次
|
||||
|
||||
#define LWNS_MAC_PERIOD_MS 20 //mac发送接收检测周期,如果有需要发送的数据包,则开始随机延迟检测冲突。//为(1000/HTIMER_SECOND_NUM)
|
||||
|
||||
#define LWNS_MAC_SEND_DELAY_MAX_625US LWNS_NEIGHBOR_MAX_NUM //随机延迟,该值越小,越容易出现错误,推荐大一些,8测试概率还可以。
|
||||
|
||||
#define BLE_PHY_ONE_PACKET_MAX_625US 5
|
||||
|
||||
#define LWNS_MAC_SEND_PACKET_MAX_NUM 8 //发送链表最多支持几个数据包等待发送
|
||||
|
||||
#define LWNS_MAC_SEND_DELAY_MAX_TIMES LWNS_NEIGHBOR_MAX_NUM / 2 //在发送被取消,延迟几次后,不再随机等待,立刻发送
|
||||
|
||||
#define LLE_MODE_ORIGINAL_RX (0x80) //如果配置LLEMODE时加上此宏,则接收第一字节为原始数据(原来为RSSI)
|
||||
|
||||
//RF_TX和RF_RX所用的类型,可以修改,不推荐改
|
||||
#define USER_RF_RX_TX_TYPE 0xff
|
||||
|
||||
#define LWNS_PHY_OUTPUT_TIMEOUT_MS 5
|
||||
//receive process evt
|
||||
#define LWNS_PHY_RX_OPEN_EVT 1
|
||||
//send process evt
|
||||
#define LWNS_PHY_PERIOD_EVT 1
|
||||
#define LWNS_PHY_OUTPUT_EVT 2
|
||||
#define LWNS_PHY_OUTPUT_FINISH_EVT 4
|
||||
|
||||
extern void RF_Init(void);
|
||||
|
||||
extern void lwns_init(void);
|
||||
|
||||
extern void lwns_shut(void);
|
||||
|
||||
extern void lwns_start(void);
|
||||
|
||||
#endif /* LWNS_USE_CSMA_MAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LWNS_ADAPTER_CSMA_MAC_H_ */
|
||||
@@ -0,0 +1,60 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_no_mac.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,不使用mac协议,纯透传
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_ADAPTER_NO_MAC_H_
|
||||
#define _LWNS_ADAPTER_NO_MAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define LWNS_USE_NO_MAC 0 //是否使能纯透传mac协议,适合不存在并发情况的星型网络,即主机问从机答的星型网络。
|
||||
|
||||
#if LWNS_USE_NO_MAC
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BLE_PHY_MANAGE_STATE_FREE = 0,
|
||||
BLE_PHY_MANAGE_STATE_SENDING,
|
||||
} BLE_PHY_MANAGE_STATE_t;
|
||||
|
||||
#define LLE_MODE_ORIGINAL_RX (0x80) //如果配置LLEMODE时加上此宏,则接收第一字节为原始数据(原来为RSSI)
|
||||
|
||||
#define LWNS_HTIMER_PERIOD_MS 20 //为(1000/HTIMER_SECOND_NUM)
|
||||
|
||||
//RF_TX和RF_RX所用的类型,可以修改,不推荐改
|
||||
#define USER_RF_RX_TX_TYPE 0xff
|
||||
|
||||
#define LWNS_PHY_OUTPUT_TIMEOUT_MS 5
|
||||
|
||||
//receive process evt
|
||||
#define LWNS_PHY_RX_OPEN_EVT 1
|
||||
//send process evt
|
||||
#define LWNS_HTIMER_PERIOD_EVT 1
|
||||
#define LWNS_PHY_OUTPUT_FINISH_EVT 2
|
||||
|
||||
extern void RF_Init(void);
|
||||
|
||||
extern void lwns_init(void);
|
||||
|
||||
extern void lwns_shut(void);
|
||||
|
||||
extern void lwns_start(void);
|
||||
|
||||
#endif /* LWNS_USE_NO_MAC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LWNS_ADAPTER_NO_MAC_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_broadcast_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : broadcast£¬¹ã²¥³ÌÐòÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_BROADCAST_EXAMPLE_H_
|
||||
#define _LWNS_BROADCAST_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define BROADCAST_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_broadcast_process_init(void);
|
||||
|
||||
#endif /* LWNS_BROADCAST_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,28 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_config.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/11/17
|
||||
* Description : lwns配置选项
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_CONFIG_H_
|
||||
#define _LWNS_CONFIG_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "WCH_LWNS_LIB.h"
|
||||
|
||||
#define LWNS_ADDR_USE_BLE_MAC 1 //是否使用蓝牙硬件的mac地址作为默认lwns地址
|
||||
|
||||
#define LWNS_ENCRYPT_ENABLE 1 //是否使能加密
|
||||
|
||||
#define QBUF_MANUAL_NUM 4 //qbuf缓存数量配置
|
||||
|
||||
#define ROUTE_ENTRY_MANUAL_NUM 32 //路由条目数量配置
|
||||
|
||||
#define LWNS_NEIGHBOR_MAX_NUM 8 //最大邻居数量
|
||||
|
||||
#endif /* _LWNS_CONFIG_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_mesh_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/28
|
||||
* Description : mesh´«Êä³ÌÐòÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_MESH_EXAMPLE_H_
|
||||
#define _LWNS_MESH_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define MESH_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
#define MESH_EXAMPLE_TX_NODE_EVT 1 << (1)
|
||||
void lwns_mesh_process_init(void);
|
||||
|
||||
#endif /* _LWNS_MESH_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_multicast_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : single-hop multicast£¬×é²¥´«ÊäÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_MULTICAST_EXAMPLE_H_
|
||||
#define _LWNS_MULTICAST_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define MULTICAST_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_multicast_process_init(void);
|
||||
|
||||
#endif /* _LWNS_MULTICAST_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_multinetflood_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/11/10
|
||||
* Description : multinetflood,组播网络泛洪传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_MULTINETFLOOD_EXAMPLE_H_
|
||||
#define _LWNS_MULTINETFLOOD_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define MULTINETFLOOD_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_multinetflood_process_init(void);
|
||||
|
||||
#endif /* _LWNS_MULTINETFLOOD_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_netflood_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/07/12
|
||||
* Description : netflood£¬ÍøÂç·ººé´«ÊäÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_NETFLOOD_EXAMPLE_H_
|
||||
#define _LWNS_NETFLOOD_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define NETFLOOD_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_netflood_process_init(void);
|
||||
|
||||
#endif /* _LWNS_NETFLOOD_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_ruc_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/30
|
||||
* Description : reliable unicast£¬¿É¿¿µ¥²¥´«ÊäÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_RUC_EXAMPLE_H_
|
||||
#define _LWNS_RUC_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define RUC_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_ruc_process_init(void);
|
||||
|
||||
#endif /* _LWNS_RUC_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_rucft_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/30
|
||||
* Description : reliable unicast file transfer,可靠单播文件传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_RUCFT_EXAMPLE_H_
|
||||
#define _LWNS_RUCFT_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define RUCFT_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_rucft_process_init(void);
|
||||
|
||||
#endif /* _LWNS_RUCFT_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_sec.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/09/17
|
||||
* Description : lwnsÏûÏ¢¼ÓÃÜ
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_SEC_H_
|
||||
#define _LWNS_SEC_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
int lwns_msg_encrypt(uint8_t *src, uint8_t *to, uint8_t mlen);
|
||||
|
||||
int lwns_msg_decrypt(uint8_t *src, uint8_t *to, uint8_t mlen);
|
||||
|
||||
#endif /* _LWNS_SEC_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_unicast_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/19
|
||||
* Description : lwnsµ¥²¥´«ÊäÀý×Ó
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_UNICAST_EXAMPLE_H_
|
||||
#define _LWNS_UNICAST_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define UNICAST_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_unicast_process_init(void);
|
||||
|
||||
#endif /* _LWNS_UNICAST_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_uninetflood_example.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/10/25
|
||||
* Description : lwns单播网络泛洪传输例子,将数据网络泛洪发送至指定节点
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef _LWNS_UNINETFLOOD_EXAMPLE_H_
|
||||
#define _LWNS_UNINETFLOOD_EXAMPLE_H_
|
||||
|
||||
#include "lwns_config.h"
|
||||
|
||||
#define UNINETFLOOD_EXAMPLE_TX_PERIOD_EVT 1 << (0)
|
||||
|
||||
void lwns_uninetflood_process_init(void);
|
||||
|
||||
#endif /* _LWNS_UNINETFLOOD_EXAMPLE_H_ */
|
||||
@@ -0,0 +1,31 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
@@ -0,0 +1,528 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_blemesh_mac.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,模拟ble sig mesh的mac协议
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_adapter_blemesh_mac.h"
|
||||
#include "lwns_sec.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 本文件中ble_phy_channelmap为需要发送和接收的通道列表,用户根据自己需求修改为蓝牙通道中的任意三个通道。
|
||||
* 蓝牙mesh是在37、38、39三个广播通道的广播accessaddress:0x8E89BED6进行周期性发送。正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
* 本文件采用的发送通道数量和通道号还有accessaddress可以自定,accessaddress切换通道时不变,通道建议3个,不要太多。
|
||||
*/
|
||||
|
||||
#if LWNS_USE_BLEMESH_MAC //是否使能模仿blemesh的mac协议,注意只能使能一个mac层协议。
|
||||
|
||||
//for lwns_packet_buffer save
|
||||
__attribute__((aligned(4))) static lwns_qbuf_list_t qbuf_memp[QBUF_MANUAL_NUM];
|
||||
|
||||
//for lwns_route_entry manage
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
__attribute__((aligned(4))) static lwns_route_entry_data_t route_entry_memp[ROUTE_ENTRY_MANUAL_NUM];
|
||||
#endif
|
||||
|
||||
//for neighbor manage
|
||||
__attribute__((aligned(4))) static lwns_neighbor_list_t neighbor_memp[LWNS_NEIGHBOR_MAX_NUM];
|
||||
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n); //发现新邻居回调函数
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len); //发送接口函数
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf);
|
||||
|
||||
static uint8_t lwns_adapter_taskid;
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static uint8_t lwns_phyoutput_taskid;
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/**
|
||||
* lwns必用的函数接口,将指针传递给lwns库内部使用
|
||||
*/
|
||||
static lwns_fuc_interface_t ble_lwns_fuc_interface = {
|
||||
.lwns_phy_output = ble_phy_output,
|
||||
.lwns_rand = tmos_rand,
|
||||
.lwns_memcpy = tmos_memcpy,
|
||||
.lwns_memcmp = tmos_memcmp,
|
||||
.lwns_memset = tmos_memset,
|
||||
.new_neighbor_callback = ble_new_neighbor_callback,
|
||||
};
|
||||
|
||||
static const uint8_t ble_phy_channelmap[] = {8, 18, 28}; //所需要用到的通道集合,用户自行更换为想要发送的通道集合。
|
||||
static uint8_t ble_phy_channelmap_send_seq = 0, ble_phy_channelmap_receive_seq = 0, ble_phy_send_cnt = 0; //发送接收当前通道序号和发送次数管理
|
||||
static struct blemesh_mac_phy_manage_struct *blemesh_phy_manage_list_head = NULL; //mac管理发送LIST列表指针
|
||||
static struct blemesh_mac_phy_manage_struct blemesh_phy_manage_list[LWNS_MAC_SEND_PACKET_MAX_NUM]; //mac管理发送列表管理数组
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_2G4StatusCallBack
|
||||
*
|
||||
* @brief RF 状态回调,注意:不可在此函数中直接调用RF接收或者发送API,需要使用事件的方式调用
|
||||
*
|
||||
* @param sta - 状态类型
|
||||
* @param crc - crc校验结果
|
||||
* @param rxBuf - 数据buf指针
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
|
||||
{ //rxBuf[0]为信号强度,rxBuf[1]为本次收到数据的长度
|
||||
switch(sta)
|
||||
{
|
||||
case RX_MODE_RX_DATA:
|
||||
{
|
||||
if(crc == 1)
|
||||
{
|
||||
PRINTF("crc error\n");
|
||||
}
|
||||
else if(crc == 2)
|
||||
{
|
||||
PRINTF("match type error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
#if LWNS_ENCRYPT_ENABLE //是否启用消息加密
|
||||
if(((rxBuf[1] % 16) == 1) && (rxBuf[1] >= 17) && (rxBuf[1] > rxBuf[2]))
|
||||
{ //对齐后数据区最少16个字节,加上真实数据长度一字节
|
||||
//长度校验通过,所以rxBuf[1] - 1必为16的倍数
|
||||
pMsg = tmos_msg_allocate(rxBuf[1]); //申请内存空间,真实数据长度不需要解密
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
lwns_msg_decrypt(rxBuf + 3, pMsg + 1, rxBuf[1] - 1); //解密数据
|
||||
if((rxBuf[2] ^ pMsg[rxBuf[2]]) == pMsg[rxBuf[2] + 1])
|
||||
{
|
||||
pMsg[0] = rxBuf[2]; //校验通过,存储真实数据长度
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("verify rx msg err\n"); //校验失败
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#else
|
||||
if(rxBuf[1] >= LWNS_PHY_OUTPUT_MIN_SIZE)
|
||||
{ //数据长度符合,才会发送至协议栈内部处理
|
||||
pMsg = tmos_msg_allocate(rxBuf[1] + 1);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_memcpy(pMsg, rxBuf + 1, rxBuf[1] + 1);
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#endif
|
||||
}
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //重新打开接收
|
||||
break;
|
||||
}
|
||||
case TX_MODE_TX_FINISH:
|
||||
case TX_MODE_TX_FAIL:
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //停止超时计数
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //进入发送完成处理
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_Init
|
||||
*
|
||||
* @brief RF 初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void RF_Init(void)
|
||||
{
|
||||
uint8_t state;
|
||||
rfConfig_t rfConfig;
|
||||
tmos_memset(&rfConfig, 0, sizeof(rfConfig_t));
|
||||
rfConfig.accessAddress = 0x17267162; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 ),正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
rfConfig.CRCInit = 0x555555;
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
rfConfig.Channel = ble_phy_channelmap[0];
|
||||
rfConfig.LLEMode = LLE_MODE_BASIC; //|LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rfConfig.Frequency 作为通信频点
|
||||
rfConfig.rfStatusCB = RF_2G4StatusCallBack;
|
||||
state = RF_Config(&rfConfig);
|
||||
PRINTF("rf 2.4g init: %x\n", state);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_init
|
||||
*
|
||||
* @brief lwns初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_init(void)
|
||||
{
|
||||
uint8_t s;
|
||||
lwns_config_t cfg;
|
||||
tmos_memset(&cfg, 0, sizeof(lwns_config_t));
|
||||
cfg.lwns_lib_name = (uint8_t *)VER_LWNS_FILE; //验证函数库名称,防止版本出错
|
||||
cfg.qbuf_num = QBUF_MANUAL_NUM; //必须分配,至少1个内存单位,根据你程序中使用的端口数对应模块使用的qbuf单位来定义。
|
||||
cfg.qbuf_ptr = qbuf_memp; //mesh最多使用3个qbuf单位,(uni/multi)netflood最多使用2个,其他模块都使用1个。
|
||||
cfg.routetable_num = ROUTE_ENTRY_MANUAL_NUM; //如果需要使用mesh,必须分配路由表内存空间。不然mesh初始化不会成功。
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
cfg.routetable_ptr = route_entry_memp;
|
||||
#else
|
||||
cfg.routetable_ptr = NULL;
|
||||
#endif
|
||||
cfg.neighbor_num = LWNS_NEIGHBOR_MAX_NUM; //邻居表数量,必须分配
|
||||
cfg.neighbor_list_ptr = neighbor_memp; //邻居表内存空间
|
||||
cfg.neighbor_mod = LWNS_NEIGHBOR_AUTO_ADD_STATE_RECALL_ADDALL; //邻居表初始化默认管理模式为接收所有包,添加所有邻居并且过滤重复包的模式
|
||||
#if LWNS_ADDR_USE_BLE_MAC
|
||||
FLASH_GetMACAddress(cfg.addr.v8); //蓝牙硬件的mac地址
|
||||
#else
|
||||
//自行定义的地址
|
||||
uint8_t MacAddr[6] = {0, 0, 0, 0, 0, 1};
|
||||
tmos_memcpy(cfg.addr.v8, MacAddr, LWNS_ADDR_SIZE);
|
||||
#endif
|
||||
s = lwns_lib_init(&ble_lwns_fuc_interface, &cfg); //lwns库底层初始化
|
||||
if(s)
|
||||
{
|
||||
PRINTF("%s init err:%d\n", VER_LWNS_FILE, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("%s init ok\n", VER_LWNS_FILE);
|
||||
}
|
||||
lwns_adapter_taskid = TMOS_ProcessEventRegister(lwns_adapter_ProcessEvent);
|
||||
lwns_phyoutput_taskid = TMOS_ProcessEventRegister(lwns_phyoutput_ProcessEvent);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
tmos_memset(blemesh_phy_manage_list, 0, sizeof(blemesh_phy_manage_list)); //清除发送管理结构体
|
||||
ble_phy_send_cnt = 0; //清空发送次数计数
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_new_neighbor_callback
|
||||
*
|
||||
* @brief 当发现一个新邻居时的回调函数.
|
||||
*
|
||||
* @param n - 新邻居的地址.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n)
|
||||
{
|
||||
PRINTF("new neighbor: %02x %02x %02x %02x %02x %02x\n", n->v8[0], n->v8[1],
|
||||
n->v8[2], n->v8[3], n->v8[4], n->v8[5]);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_phy_output
|
||||
*
|
||||
* @brief lwns发送函数接口
|
||||
*
|
||||
* @param dataptr - 待发送的数据缓冲头指针.
|
||||
* @param len - 待发送的数据缓冲长度.
|
||||
*
|
||||
* @return TRUE if success, FLASE is failed.
|
||||
*/
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len)
|
||||
{
|
||||
uint8_t *pMsg, i;
|
||||
struct blemesh_mac_phy_manage_struct *p;
|
||||
for(i = 0; i < LWNS_MAC_SEND_PACKET_MAX_NUM; i++)
|
||||
{
|
||||
if(blemesh_phy_manage_list[i].data == NULL)
|
||||
{
|
||||
break; //寻找到了一个空的结构体可以使用。
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i == (LWNS_MAC_SEND_PACKET_MAX_NUM - 1))
|
||||
{
|
||||
PRINTF("send failed!\n"); //列表满了,发送失败,直接返回。
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
pMsg = tmos_msg_allocate((((len + 1 + 15) & 0xf0) + 1 + 1)); //校验位1位加上后再进行16字节对齐,存储发送长度+1,真实数据长度+1
|
||||
#else
|
||||
pMsg = tmos_msg_allocate(len + 1); //申请内存空间存储消息,存储发送长度+1
|
||||
#endif
|
||||
if(pMsg != NULL)
|
||||
{ //成功申请
|
||||
p = blemesh_phy_manage_list_head;
|
||||
if(p != NULL)
|
||||
{
|
||||
while(p->next != NULL)
|
||||
{ //寻找发送链表的终点
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
//lwns buffer内部预留有两字节,用户可直接使用dataptr[len]进行赋值两字节内容
|
||||
dataptr[len] = dataptr[len - 1] ^ len; //校验字节仅取最后一个字节和长度进行异或运算,首字节相同port是一样的,可能有影响。和校验比较浪费时间,所以不采用
|
||||
pMsg[1] = len; //真实数据长度占一字节,不加密,用来接收做第一步校验
|
||||
pMsg[0] = lwns_msg_encrypt(dataptr, pMsg + 2, len + 1) + 1; //获取数据加密后的长度,也就是需要发送出去的字节数,真实数据长度不加密
|
||||
#else
|
||||
pMsg[0] = len;
|
||||
tmos_memcpy(pMsg + 1, dataptr, len);
|
||||
#endif
|
||||
if(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
p->next = &blemesh_phy_manage_list[i]; //链表添加尾结点
|
||||
}
|
||||
else
|
||||
{
|
||||
blemesh_phy_manage_list_head = &blemesh_phy_manage_list[i]; //链表为空,则节点作为头结点
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送,不是头结点不需要启动,因为在发送流程中。
|
||||
}
|
||||
blemesh_phy_manage_list[i].data = pMsg; //绑定消息
|
||||
blemesh_phy_manage_list[i].next = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send failed!\n"); //无法申请到内存,则无法发送
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_adapter_ProcessEvent
|
||||
*
|
||||
* @brief lwns adapter Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_PHY_RX_CHANGE_CHANNEL_EVT) //处理更换接收通道事件
|
||||
{
|
||||
ble_phy_channelmap_receive_seq++;
|
||||
if(ble_phy_channelmap_receive_seq >= sizeof(ble_phy_channelmap))
|
||||
{
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
}
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_receive_seq]); //周期性更改发送通道
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
return ((events & (~LWNS_PHY_RX_OPEN_EVT)) ^ LWNS_PHY_RX_CHANGE_CHANNEL_EVT ); //停止可能已经置位的、可能会打开接收的任务
|
||||
}
|
||||
if(events & LWNS_PHY_RX_OPEN_EVT)
|
||||
{ //重新打开接收事件
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
return (events ^ LWNS_PHY_RX_OPEN_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{ //处理打开接收后,再处理数据
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
lwns_input(pMsg + 1, pMsg[0]); //将数据存入协议栈缓冲区
|
||||
tmos_msg_deallocate(pMsg); //先释放内存,在数据处理前释放,防止数据处理中需要发送数据,而内存不够。
|
||||
lwns_dataHandler(); //调用协议栈处理数据函数
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_phyoutput_ProcessEvent
|
||||
*
|
||||
* @brief lwns phyoutput Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_HTIMER_PERIOD_EVT)
|
||||
{
|
||||
lwns_htimer_update(); //htimer更新。
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS)); //周期性更新
|
||||
return (events ^ LWNS_HTIMER_PERIOD_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_PREPARE_EVT)
|
||||
{ //准备发送工作
|
||||
uint8_t rand_delay;
|
||||
rand_delay = tmos_rand() % MS1_TO_SYSTEM_TIME(LWNS_MAC_SEND_DELAY_MAX_MS) + BLE_PHY_ONE_PACKET_MAX_625US; //随机延迟
|
||||
ble_phy_channelmap_send_seq = 0; //发送通道序号
|
||||
PRINTF("rand send:%d\n", rand_delay);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, rand_delay); //随机延迟后立刻发送
|
||||
return (events ^ LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_FINISH_EVT)
|
||||
{ //发送完成任务
|
||||
if(ble_phy_channelmap_send_seq < sizeof(ble_phy_channelmap))
|
||||
{
|
||||
if(ble_phy_channelmap_send_seq == 0)
|
||||
{ //只需要在开始发送的时候停任务
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //发送期间,停止继续切换接收通道
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
}
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_send_seq]); //周期性更改发送通道
|
||||
RF_Tx((uint8_t *)(blemesh_phy_manage_list_head->data + 1),
|
||||
blemesh_phy_manage_list_head->data[0], USER_RF_RX_TX_TYPE,
|
||||
USER_RF_RX_TX_TYPE);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, MS1_TO_SYSTEM_TIME(LWNS_PHY_OUTPUT_TIMEOUT_MS)); //开始发送超时计数,防止有意外打断发送,导致无法继续发送
|
||||
ble_phy_channelmap_send_seq++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//三个通道一次发送结束完
|
||||
ble_phy_send_cnt++;
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //间隔期间继续接收
|
||||
if(ble_phy_send_cnt < LWNS_MAC_TRANSMIT_TIMES)
|
||||
{ //发送次数不够
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送
|
||||
}
|
||||
else
|
||||
{
|
||||
//指定次数发送结束
|
||||
ble_phy_send_cnt = 0; //清空发送次数计数
|
||||
tmos_msg_deallocate(blemesh_phy_manage_list_head->data); //释放内存
|
||||
blemesh_phy_manage_list_head->data = NULL; //恢复默认参数
|
||||
blemesh_phy_manage_list_head = blemesh_phy_manage_list_head->next; //链表pop,去除掉首元素
|
||||
if(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT); //启动发送
|
||||
}
|
||||
}
|
||||
}
|
||||
return (events ^ LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_phyoutput_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
tmos_msg_deallocate(pMsg); //释放内存
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_shut
|
||||
*
|
||||
* @brief 停止lwns,不可以在这lwns_phyoutput_taskid和lwns_adapter_taskid的processEvent中调用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_shut()
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
RF_Shut(); //关闭RF接收
|
||||
while(blemesh_phy_manage_list_head != NULL)
|
||||
{
|
||||
/* 清除所有缓存中待发送的消息 */
|
||||
tmos_msg_deallocate(blemesh_phy_manage_list_head->data);
|
||||
blemesh_phy_manage_list_head->data = NULL;
|
||||
blemesh_phy_manage_list_head = blemesh_phy_manage_list_head->next;
|
||||
}
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT); //停止Htimer心跳时钟
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT);
|
||||
/* 超时重发全部清除 */
|
||||
lwns_htimer_flush_all();
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_PREPARE_EVT);
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
while((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
/* 清除所有缓存的消息 */
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT); //停止Htimer心跳时钟
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT);
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, SYS_EVENT_MSG);
|
||||
|
||||
/* 清空发送次数计数 */
|
||||
ble_phy_send_cnt = 0;
|
||||
/* 清空发送序号 */
|
||||
ble_phy_channelmap_send_seq = 0;
|
||||
/* 清空接收通道序号 */
|
||||
ble_phy_channelmap_receive_seq = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_start
|
||||
*
|
||||
* @brief lwns开始运行,在使用lwns_shut后,重新开始时使用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_start()
|
||||
{
|
||||
RF_Shut();
|
||||
RF_SetChannel(ble_phy_channelmap[ble_phy_channelmap_receive_seq]); //周期性更改发送通道
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_adapter_taskid, LWNS_PHY_RX_CHANGE_CHANNEL_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
}
|
||||
|
||||
#endif /* LWNS_USE_BLEMESH_MAC */
|
||||
@@ -0,0 +1,514 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_csma_mac.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,模拟csma的mac协议
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_adapter_csma_mac.h"
|
||||
#include "lwns_sec.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if LWNS_USE_CSMA_MAC //是否使能模仿csma的mac协议,注意只能使能一个mac层协议。
|
||||
|
||||
//for lwns_packet_buffer save
|
||||
__attribute__((aligned(4))) static lwns_qbuf_list_t qbuf_memp[QBUF_MANUAL_NUM];
|
||||
|
||||
//for lwns_route_entry manage
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
__attribute__((aligned(4))) static lwns_route_entry_data_t route_entry_memp[ROUTE_ENTRY_MANUAL_NUM];
|
||||
#endif
|
||||
|
||||
//for neighbor manage
|
||||
__attribute__((aligned(4))) static lwns_neighbor_list_t neighbor_memp[LWNS_NEIGHBOR_MAX_NUM];
|
||||
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n); //发现新邻居回调函数
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len); //发送接口函数
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf);
|
||||
|
||||
static uint8_t lwns_adapter_taskid;
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static uint8_t lwns_phyoutput_taskid;
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/**
|
||||
* lwns必用的函数接口,将指针传递给lwns库内部使用
|
||||
*/
|
||||
static lwns_fuc_interface_t ble_lwns_fuc_interface = {
|
||||
.lwns_phy_output = ble_phy_output,
|
||||
.lwns_rand = tmos_rand,
|
||||
.lwns_memcpy = tmos_memcpy,
|
||||
.lwns_memcmp = tmos_memcmp,
|
||||
.lwns_memset = tmos_memset,
|
||||
.new_neighbor_callback = ble_new_neighbor_callback,
|
||||
};
|
||||
|
||||
static uint8_t ble_phy_manage_state, ble_phy_send_cnt = 0, ble_phy_wait_cnt = 0; //ble phy状态管理,发送次数计数,等待次数计数
|
||||
static struct csma_mac_phy_manage_struct *csma_phy_manage_list_head = NULL; //mac管理发送列表指针
|
||||
static struct csma_mac_phy_manage_struct csma_phy_manage_list[LWNS_MAC_SEND_PACKET_MAX_NUM]; //mac管理发送列表管理数组
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_2G4StatusCallBack
|
||||
*
|
||||
* @brief RF 状态回调,注意:不可在此函数中直接调用RF接收或者发送API,需要使用事件的方式调用
|
||||
*
|
||||
* @param sta - 状态类型
|
||||
* @param crc - crc校验结果
|
||||
* @param rxBuf - 数据buf指针
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
|
||||
{
|
||||
switch(sta)
|
||||
{
|
||||
case RX_MODE_RX_DATA:
|
||||
{
|
||||
if(crc == 1)
|
||||
{
|
||||
PRINTF("crc error\n");
|
||||
}
|
||||
else if(crc == 2)
|
||||
{
|
||||
PRINTF("match type error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
#if LWNS_ENCRYPT_ENABLE //是否启用消息加密
|
||||
if(((rxBuf[1] % 16) == 1) && (rxBuf[1] >= 17) && (rxBuf[1] > rxBuf[2]))
|
||||
{ //对齐后数据区最少16个字节,加上真实数据长度一字节
|
||||
//长度校验通过,所以rxBuf[1] - 1必为16的倍数
|
||||
pMsg = tmos_msg_allocate(rxBuf[1]); //申请内存空间,真实数据长度不需要解密
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
lwns_msg_decrypt(rxBuf + 3, pMsg + 1, rxBuf[1] - 1); //解密数据
|
||||
if((rxBuf[2] ^ pMsg[rxBuf[2]]) == pMsg[rxBuf[2] + 1])
|
||||
{
|
||||
pMsg[0] = rxBuf[2]; //校验通过,存储真实数据长度
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("verify rx msg err\n"); //校验失败
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#else
|
||||
if(rxBuf[1] >= LWNS_PHY_OUTPUT_MIN_SIZE)
|
||||
{ //数据长度符合,才会发送至协议栈内部处理
|
||||
pMsg = tmos_msg_allocate(rxBuf[1] + 1);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收任务中
|
||||
tmos_memcpy(pMsg, rxBuf + 1, rxBuf[1] + 1);
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#endif
|
||||
//当接收到一个数据包时,将本时间段内的还未开始的发送任务停止,等待下一时间段发送,已经开始的发送任务不暂停,模仿csma/ca,进行防碰撞相关检测。
|
||||
if(ble_phy_manage_state == BLE_PHY_MANAGE_STATE_WAIT_SEND)
|
||||
{ //等待发送状态中收到数据包
|
||||
PRINTF("send delay\n");
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_RECEIVED; //等待发送周期内收到了数据包状态
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT); //竞争发送权限失败,放弃自己的发送任务。
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT); //放弃自己的发送任务
|
||||
}
|
||||
}
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //重新打开接收
|
||||
break;
|
||||
}
|
||||
case TX_MODE_TX_FINISH:
|
||||
case TX_MODE_TX_FAIL:
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //停止超时计数
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //进入发送完成处理
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_Init
|
||||
*
|
||||
* @brief RF 初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void RF_Init(void)
|
||||
{
|
||||
uint8_t state;
|
||||
rfConfig_t rfConfig;
|
||||
tmos_memset(&rfConfig, 0, sizeof(rfConfig_t));
|
||||
rfConfig.accessAddress = 0x17267162; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 ),正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
rfConfig.CRCInit = 0x555555;
|
||||
rfConfig.Channel = 8;
|
||||
rfConfig.LLEMode = LLE_MODE_BASIC; //|LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rfConfig.Frequency 作为通信频点
|
||||
rfConfig.rfStatusCB = RF_2G4StatusCallBack;
|
||||
state = RF_Config(&rfConfig);
|
||||
PRINTF("rf 2.4g init: %x\n", state);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_init
|
||||
*
|
||||
* @brief lwns初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_init(void)
|
||||
{
|
||||
uint8_t s;
|
||||
lwns_config_t cfg;
|
||||
tmos_memset(&cfg, 0, sizeof(lwns_config_t));
|
||||
cfg.lwns_lib_name = (uint8_t *)VER_LWNS_FILE; //验证函数库名称,防止版本出错
|
||||
cfg.qbuf_num = QBUF_MANUAL_NUM; //必须分配,至少1个内存单位,根据你程序中使用的端口数对应模块使用的qbuf单位来定义。
|
||||
cfg.qbuf_ptr = qbuf_memp; //mesh最多使用3个qbuf单位,(uni/multi)netflood最多使用2个,其他模块都使用1个。
|
||||
cfg.routetable_num = ROUTE_ENTRY_MANUAL_NUM; //如果需要使用mesh,必须分配路由表内存空间。不然mesh初始化不会成功。
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
cfg.routetable_ptr = route_entry_memp;
|
||||
#else
|
||||
cfg.routetable_ptr = NULL;
|
||||
#endif
|
||||
cfg.neighbor_num = LWNS_NEIGHBOR_MAX_NUM; //邻居表数量,必须分配
|
||||
cfg.neighbor_list_ptr = neighbor_memp; //邻居表内存空间
|
||||
cfg.neighbor_mod = LWNS_NEIGHBOR_AUTO_ADD_STATE_RECALL_ADDALL; //邻居表初始化默认管理模式为接收所有包,添加所有邻居并且过滤重复包的模式
|
||||
#if LWNS_ADDR_USE_BLE_MAC
|
||||
GetMACAddress(cfg.addr.v8); //蓝牙硬件的mac地址
|
||||
#else
|
||||
//自行定义的地址
|
||||
uint8_t MacAddr[6] = {0, 0, 0, 0, 0, 1};
|
||||
tmos_memcpy(cfg.addr.v8, MacAddr, LWNS_ADDR_SIZE);
|
||||
#endif
|
||||
s = lwns_lib_init(&ble_lwns_fuc_interface, &cfg); //lwns库底层初始化
|
||||
if(s)
|
||||
{
|
||||
PRINTF("%s init err:%d\n", VER_LWNS_FILE, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("%s init ok\n", VER_LWNS_FILE);
|
||||
}
|
||||
lwns_adapter_taskid = TMOS_ProcessEventRegister(lwns_adapter_ProcessEvent);
|
||||
lwns_phyoutput_taskid = TMOS_ProcessEventRegister(lwns_phyoutput_ProcessEvent);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
tmos_memset(csma_phy_manage_list, 0, sizeof(csma_phy_manage_list)); //清除发送管理结构体
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_FREE; //清除phy状态
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_new_neighbor_callback
|
||||
*
|
||||
* @brief 当发现一个新邻居时的回调函数.
|
||||
*
|
||||
* @param n - 新邻居的地址.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n)
|
||||
{
|
||||
PRINTF("new neighbor: %02x %02x %02x %02x %02x %02x\n", n->v8[0], n->v8[1],
|
||||
n->v8[2], n->v8[3], n->v8[4], n->v8[5]);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_phy_output
|
||||
*
|
||||
* @brief lwns发送函数接口
|
||||
*
|
||||
* @param dataptr - 待发送的数据缓冲头指针.
|
||||
* @param len - 待发送的数据缓冲长度.
|
||||
*
|
||||
* @return TRUE if success, FLASE is failed.
|
||||
*/
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len)
|
||||
{
|
||||
uint8_t *pMsg, i;
|
||||
struct csma_mac_phy_manage_struct *p;
|
||||
for(i = 0; i < LWNS_MAC_SEND_PACKET_MAX_NUM; i++)
|
||||
{
|
||||
if(csma_phy_manage_list[i].data == NULL)
|
||||
{
|
||||
break; //寻找到了一个空的结构体可以使用。
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i == (LWNS_MAC_SEND_PACKET_MAX_NUM - 1))
|
||||
{
|
||||
PRINTF("send failed!\n"); //列表满了,发送失败,直接返回。
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
pMsg = tmos_msg_allocate((((len + 1 + 15) & 0xf0) + 1 + 1)); //校验位1位加上后再进行16字节对齐,存储发送长度+1,真实数据长度+1
|
||||
#else
|
||||
pMsg = tmos_msg_allocate(len + 1); //申请内存空间存储消息,存储发送长度+1
|
||||
#endif
|
||||
if(pMsg != NULL)
|
||||
{ //成功申请
|
||||
p = csma_phy_manage_list_head;
|
||||
if(p != NULL)
|
||||
{
|
||||
while(p->next != NULL)
|
||||
{ //寻找发送链表的终点
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
//lwns buffer内部预留有两字节,用户可直接使用dataptr[len]进行赋值两字节内容
|
||||
dataptr[len] = dataptr[len - 1] ^ len; //校验字节仅取最后一个字节和长度进行异或运算,首字节相同port是一样的,可能有影响。和校验比较浪费时间,所以不采用
|
||||
pMsg[1] = len; //真实数据长度占一字节,不加密,用来接收做第一步校验
|
||||
pMsg[0] = lwns_msg_encrypt(dataptr, pMsg + 2, len + 1) + 1; //获取数据加密后的长度,也就是需要发送出去的字节数,真实数据长度不加密
|
||||
#else
|
||||
pMsg[0] = len;
|
||||
tmos_memcpy(pMsg + 1, dataptr, len);
|
||||
#endif
|
||||
if(csma_phy_manage_list_head != NULL)
|
||||
{
|
||||
p->next = &csma_phy_manage_list[i]; //链表添加尾结点
|
||||
}
|
||||
else
|
||||
{
|
||||
csma_phy_manage_list_head = &csma_phy_manage_list[i]; //链表为空,则节点作为头结点
|
||||
}
|
||||
csma_phy_manage_list[i].data = pMsg; //绑定消息
|
||||
csma_phy_manage_list[i].next = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send failed!\n"); //无法申请到内存,则无法发送
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_adapter_ProcessEvent
|
||||
*
|
||||
* @brief lwns adapter Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_PHY_RX_OPEN_EVT)
|
||||
{
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
return (events ^ LWNS_PHY_RX_OPEN_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
lwns_input(pMsg + 1, pMsg[0]); //将数据存入协议栈缓冲区
|
||||
tmos_msg_deallocate(pMsg); //先释放内存,在数据处理前释放,防止数据处理中需要发送数据,而内存不够。
|
||||
lwns_dataHandler(); //调用协议栈处理数据函数
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_phyoutput_ProcessEvent
|
||||
*
|
||||
* @brief lwns phyoutput Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_PHY_PERIOD_EVT)
|
||||
{
|
||||
lwns_htimer_update(); //htimer的更新需要和mac的phy管理放一起,保持一致。
|
||||
if((csma_phy_manage_list_head != NULL))
|
||||
{ //有需要发送的包
|
||||
if((ble_phy_manage_state == BLE_PHY_MANAGE_STATE_FREE) || (ble_phy_manage_state == BLE_PHY_MANAGE_STATE_RECEIVED))
|
||||
{ //当前不在发送过程中
|
||||
if(ble_phy_manage_state == BLE_PHY_MANAGE_STATE_RECEIVED)
|
||||
{ //当前周期发送碰撞,延迟发送
|
||||
ble_phy_wait_cnt++; //记录发送延迟次数
|
||||
}
|
||||
else
|
||||
{ //BLE_PHY_MANAGE_STATE_FREE
|
||||
ble_phy_send_cnt = 0; //清除计数
|
||||
ble_phy_wait_cnt = 0; //清除计数
|
||||
}
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_WAIT_SEND; //设置为等待发送状态
|
||||
if(ble_phy_wait_cnt >= LWNS_MAC_SEND_DELAY_MAX_TIMES)
|
||||
{ //发送被取消次数,延迟过多,不再随机等待,立刻开始发送
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT);
|
||||
PRINTF("too many delay\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t rand_delay;
|
||||
rand_delay = tmos_rand() % LWNS_MAC_SEND_DELAY_MAX_625US + BLE_PHY_ONE_PACKET_MAX_625US; //随机延迟,防止冲突,随机延迟等待周期里收到了数据包就下次再发送
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT, rand_delay);
|
||||
PRINTF("rand send:%d\n", rand_delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS)); //每个周期毫秒检测一次有误数据要发送,并且更新htimer。
|
||||
return (events ^ LWNS_PHY_PERIOD_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_EVT)
|
||||
{ //发送任务,竞争发送成功
|
||||
if(ble_phy_manage_state == BLE_PHY_MANAGE_STATE_WAIT_SEND)
|
||||
{
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_SENDING; //改为发送中状态,竞争包发送完毕,需要等待一下接收方做好准备工作
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
}
|
||||
RF_Shut();
|
||||
RF_Tx((uint8_t *)(csma_phy_manage_list_head->data + 1),
|
||||
csma_phy_manage_list_head->data[0], USER_RF_RX_TX_TYPE,
|
||||
USER_RF_RX_TX_TYPE);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, MS1_TO_SYSTEM_TIME(LWNS_PHY_OUTPUT_TIMEOUT_MS)); //开始发送超时计数
|
||||
return (events ^ LWNS_PHY_OUTPUT_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_FINISH_EVT)
|
||||
{ //发送完成任务
|
||||
ble_phy_send_cnt++; //发送计数
|
||||
if(ble_phy_send_cnt < LWNS_MAC_TRANSMIT_TIMES)
|
||||
{ //发送没结束
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT); //发送次数没结束,继续发送
|
||||
}
|
||||
else
|
||||
{ //发送流程结束
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_FREE; //清除状态
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
tmos_msg_deallocate(csma_phy_manage_list_head->data); //释放内存
|
||||
csma_phy_manage_list_head->data = NULL; //恢复默认参数
|
||||
csma_phy_manage_list_head = csma_phy_manage_list_head->next; //链表pop,去除掉首元素
|
||||
}
|
||||
return (events ^ LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(lwns_phyoutput_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
tmos_msg_deallocate(pMsg); //释放内存
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_shut
|
||||
*
|
||||
* @brief 停止lwns,不可以在这lwns_phyoutput_taskid和lwns_adapter_taskid的processEvent中调用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_shut()
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
RF_Shut(); //关闭RF接收
|
||||
while(csma_phy_manage_list_head != NULL)
|
||||
{
|
||||
/* 清除所有缓存中待发送的消息 */
|
||||
tmos_msg_deallocate(csma_phy_manage_list_head->data);
|
||||
csma_phy_manage_list_head->data = NULL;
|
||||
csma_phy_manage_list_head = csma_phy_manage_list_head->next;
|
||||
}
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_EVT);
|
||||
|
||||
/* 超时重发全部清除 */
|
||||
lwns_htimer_flush_all();
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_PERIOD_EVT); //停止Htimer心跳时钟和发送列表检测
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_PERIOD_EVT);
|
||||
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
|
||||
while((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
/* 清除所有缓存的消息 */
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_start
|
||||
*
|
||||
* @brief lwns开始运行,在使用lwns_shut后,重新开始时使用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_start()
|
||||
{
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_MAC_PERIOD_MS));
|
||||
}
|
||||
|
||||
#endif /* LWNS_USE_CSMA_MAC */
|
||||
@@ -0,0 +1,423 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_adapter_no_mac.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : lwns适配器,不使用mac协议,纯透传
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_adapter_no_mac.h"
|
||||
#include "lwns_sec.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if LWNS_USE_NO_MAC //是否使能纯透传mac协议,即mac层不参与任何动作,注意只能使能一个mac层协议。
|
||||
|
||||
//for lwns_packet_buffer save
|
||||
__attribute__((aligned(4))) static lwns_qbuf_list_t qbuf_memp[QBUF_MANUAL_NUM];
|
||||
|
||||
//for lwns_route_entry manage
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
__attribute__((aligned(4))) static lwns_route_entry_data_t route_entry_memp[ROUTE_ENTRY_MANUAL_NUM];
|
||||
#endif
|
||||
|
||||
//for neighbor manage
|
||||
__attribute__((aligned(4))) static lwns_neighbor_list_t neighbor_memp[LWNS_NEIGHBOR_MAX_NUM];
|
||||
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n); //发现新邻居回调函数
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len); //发送接口函数
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf);
|
||||
|
||||
static uint8_t lwns_adapter_taskid;
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static uint8_t lwns_phyoutput_taskid;
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/**
|
||||
* lwns必用的函数接口,将指针传递给lwns库内部使用
|
||||
*/
|
||||
static lwns_fuc_interface_t ble_lwns_fuc_interface = {
|
||||
.lwns_phy_output = ble_phy_output,
|
||||
.lwns_rand = tmos_rand,
|
||||
.lwns_memcpy = tmos_memcpy,
|
||||
.lwns_memcmp = tmos_memcmp,
|
||||
.lwns_memset = tmos_memset,
|
||||
.new_neighbor_callback = ble_new_neighbor_callback,
|
||||
};
|
||||
|
||||
static uint8_t ble_phy_manage_state; //phy状态管理
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_2G4StatusCallBack
|
||||
*
|
||||
* @brief RF 状态回调,注意:不可在此函数中直接调用RF接收或者发送API,需要使用事件的方式调用
|
||||
*
|
||||
* @param sta - 状态类型
|
||||
* @param crc - crc校验结果
|
||||
* @param rxBuf - 数据buf指针
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf)
|
||||
{
|
||||
switch(sta)
|
||||
{
|
||||
case RX_MODE_RX_DATA:
|
||||
{
|
||||
if(crc == 1)
|
||||
{
|
||||
PRINTF("crc error\n");
|
||||
}
|
||||
else if(crc == 2)
|
||||
{
|
||||
PRINTF("match type error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
#if LWNS_ENCRYPT_ENABLE //是否启用消息加密
|
||||
if(((rxBuf[1] % 16) == 1) && (rxBuf[1] >= 17) && (rxBuf[1] > rxBuf[2]))
|
||||
{ //对齐后数据区最少16个字节,加上真实数据长度一字节
|
||||
//长度校验通过,所以rxBuf[1] - 1必为16的倍数
|
||||
pMsg = tmos_msg_allocate(rxBuf[1]); //申请内存空间,真实数据长度不需要解密
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
lwns_msg_decrypt(rxBuf + 3, pMsg + 1, rxBuf[1] - 1); //解密数据
|
||||
if((rxBuf[2] ^ pMsg[rxBuf[2]]) == pMsg[rxBuf[2] + 1])
|
||||
{
|
||||
pMsg[0] = rxBuf[2]; //校验通过,存储真实数据长度
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("verify rx msg err\n"); //校验失败
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#else
|
||||
if(rxBuf[1] >= LWNS_PHY_OUTPUT_MIN_SIZE)
|
||||
{ //数据长度符合,才会发送至协议栈内部处理
|
||||
pMsg = tmos_msg_allocate(rxBuf[1] + 1);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
PRINTF("send rx msg\n"); //发送接收到的数据到接收进程中
|
||||
tmos_memcpy(pMsg, rxBuf + 1, rxBuf[1] + 1);
|
||||
tmos_msg_send(lwns_adapter_taskid, pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("rx msg failed\n"); //申请内存失败,无法发送接收到的数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("bad len\n"); //包长度不对
|
||||
}
|
||||
#endif
|
||||
}
|
||||
tmos_set_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //重新打开接收
|
||||
break;
|
||||
}
|
||||
case TX_MODE_TX_FINISH:
|
||||
case TX_MODE_TX_FAIL:
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //停止超时计数
|
||||
tmos_set_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //进入发送完成处理
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RF_Init
|
||||
*
|
||||
* @brief RF 初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void RF_Init(void)
|
||||
{
|
||||
uint8_t state;
|
||||
rfConfig_t rfConfig;
|
||||
tmos_memset(&rfConfig, 0, sizeof(rfConfig_t));
|
||||
rfConfig.accessAddress = 0x17267162; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 ),正确符合相应规则的accessaddress接入地址约有23亿个
|
||||
rfConfig.CRCInit = 0x555555;
|
||||
rfConfig.Channel = 8;
|
||||
rfConfig.LLEMode = LLE_MODE_BASIC; //|LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rfConfig.Frequency 作为通信频点
|
||||
rfConfig.rfStatusCB = RF_2G4StatusCallBack;
|
||||
state = RF_Config(&rfConfig);
|
||||
PRINTF("rf 2.4g init: %x\n", state);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_init
|
||||
*
|
||||
* @brief lwns初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_init(void)
|
||||
{
|
||||
uint8_t s;
|
||||
lwns_config_t cfg;
|
||||
tmos_memset(&cfg, 0, sizeof(lwns_config_t));
|
||||
cfg.lwns_lib_name = (uint8_t *)VER_LWNS_FILE; //验证函数库名称,防止版本出错
|
||||
cfg.qbuf_num = QBUF_MANUAL_NUM; //必须分配,至少1个内存单位,根据你程序中使用的端口数对应模块使用的qbuf单位来定义。
|
||||
cfg.qbuf_ptr = qbuf_memp; //mesh最多使用3个qbuf单位,(uni/multi)netflood最多使用2个,其他模块都使用1个。
|
||||
cfg.routetable_num = ROUTE_ENTRY_MANUAL_NUM; //如果需要使用mesh,必须分配路由表内存空间。不然mesh初始化不会成功。
|
||||
#if ROUTE_ENTRY_MANUAL_NUM
|
||||
cfg.routetable_ptr = route_entry_memp;
|
||||
#else
|
||||
cfg.routetable_ptr = NULL;
|
||||
#endif
|
||||
cfg.neighbor_num = LWNS_NEIGHBOR_MAX_NUM; //邻居表数量,必须分配
|
||||
cfg.neighbor_list_ptr = neighbor_memp; //邻居表内存空间
|
||||
cfg.neighbor_mod = LWNS_NEIGHBOR_AUTO_ADD_STATE_RECALL_NOTADD; //邻居表初始化默认管理模式为接收所有包,不添加邻居的模式
|
||||
#if LWNS_ADDR_USE_BLE_MAC
|
||||
GetMACAddress(cfg.addr.v8); //蓝牙硬件的mac地址
|
||||
#else
|
||||
//自行定义的地址
|
||||
uint8_t MacAddr[6] = {0, 0, 0, 0, 0, 1};
|
||||
tmos_memcpy(cfg.addr.v8, MacAddr, LWNS_ADDR_SIZE);
|
||||
#endif
|
||||
s = lwns_lib_init(&ble_lwns_fuc_interface, &cfg); //lwns库底层初始化
|
||||
if(s)
|
||||
{
|
||||
PRINTF("%s init err:%d\n", VER_LWNS_FILE, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("%s init ok\n", VER_LWNS_FILE);
|
||||
}
|
||||
lwns_adapter_taskid = TMOS_ProcessEventRegister(lwns_adapter_ProcessEvent);
|
||||
lwns_phyoutput_taskid = TMOS_ProcessEventRegister(lwns_phyoutput_ProcessEvent);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_FREE;
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_new_neighbor_callback
|
||||
*
|
||||
* @brief 当发现一个新邻居时的回调函数.
|
||||
*
|
||||
* @param n - 新邻居的地址.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void ble_new_neighbor_callback(lwns_addr_t *n)
|
||||
{
|
||||
PRINTF("new neighbor: %02x %02x %02x %02x %02x %02x\n", n->v8[0], n->v8[1],
|
||||
n->v8[2], n->v8[3], n->v8[4], n->v8[5]);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_phy_output
|
||||
*
|
||||
* @brief lwns发送函数接口
|
||||
*
|
||||
* @param dataptr - 待发送的数据缓冲头指针.
|
||||
* @param len - 待发送的数据缓冲长度.
|
||||
*
|
||||
* @return TRUE if success, FLASE is failed.
|
||||
*/
|
||||
static BOOL ble_phy_output(uint8_t *dataptr, uint8_t len)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
pMsg = tmos_msg_allocate((((len + 1 + 15) & 0xf0) + 1 + 1)); //校验位1位加上后再进行16字节对齐,存储发送长度+1,真实数据长度+1
|
||||
#else
|
||||
pMsg = tmos_msg_allocate(len + 1); //申请内存空间存储消息,存储发送长度+1
|
||||
#endif
|
||||
if(pMsg != NULL)
|
||||
{ //成功申请
|
||||
#if LWNS_ENCRYPT_ENABLE
|
||||
//lwns buffer内部预留有两字节,用户可直接使用dataptr[len]进行赋值两字节内容
|
||||
dataptr[len] = dataptr[len - 1] ^ len; //校验字节仅取最后一个字节和长度进行异或运算,首字节相同port是一样的,可能有影响。和校验比较浪费时间,所以不采用
|
||||
pMsg[1] = len; //真实数据长度占一字节,不加密,用来接收做第一步校验
|
||||
pMsg[0] = lwns_msg_encrypt(dataptr, pMsg + 2, len + 1) + 1; //获取数据加密后的长度,也就是需要发送出去的字节数,真实数据长度不加密
|
||||
#else
|
||||
pMsg[0] = len;
|
||||
tmos_memcpy(pMsg + 1, dataptr, len);
|
||||
#endif
|
||||
tmos_msg_send(lwns_phyoutput_taskid, pMsg);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("send failed!\n"); //无法申请到内存,则无法发送
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_adapter_ProcessEvent
|
||||
*
|
||||
* @brief lwns adapter Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_adapter_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_PHY_RX_OPEN_EVT)
|
||||
{ //重新打开接收
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
return (events ^ LWNS_PHY_RX_OPEN_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
lwns_input(pMsg + 1, pMsg[0]); //将数据存入协议栈缓冲区
|
||||
tmos_msg_deallocate(pMsg); //先释放内存,在数据处理前释放,防止数据处理中需要发送数据,而内存不够。
|
||||
lwns_dataHandler(); //调用协议栈处理数据函数
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_phyoutput_ProcessEvent
|
||||
*
|
||||
* @brief lwns phyoutput Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_phyoutput_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & LWNS_HTIMER_PERIOD_EVT)
|
||||
{
|
||||
lwns_htimer_update(); //htimer更新
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS)); //周期性更新
|
||||
return (events ^ LWNS_HTIMER_PERIOD_EVT);
|
||||
}
|
||||
if(events & LWNS_PHY_OUTPUT_FINISH_EVT)
|
||||
{ //发送完成任务
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //重新打开接收
|
||||
ble_phy_manage_state = BLE_PHY_MANAGE_STATE_FREE; //发送完成,释放phy
|
||||
return (events ^ LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if(ble_phy_manage_state == BLE_PHY_MANAGE_STATE_SENDING)
|
||||
{
|
||||
PRINTF("phy busy\n");
|
||||
return 0; //发送过程中,不再发送新的数据包,直接返回
|
||||
}
|
||||
if((pMsg = tmos_msg_receive(lwns_phyoutput_taskid)) != NULL)
|
||||
{
|
||||
// Release the TMOS message,tmos_msg_allocate
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT); //停止可能已经置位的、可能会打开接收的任务
|
||||
RF_Shut();
|
||||
RF_Tx((uint8_t *)(pMsg + 1), pMsg[0], USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE);
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT, MS1_TO_SYSTEM_TIME(LWNS_PHY_OUTPUT_TIMEOUT_MS)); //开始发送超时计数,防止有意外打断发送,导致无法继续发送
|
||||
tmos_msg_deallocate(pMsg); //释放内存
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_shut
|
||||
*
|
||||
* @brief 停止lwns,不可以在这lwns_phyoutput_taskid和lwns_adapter_taskid的processEvent中调用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_shut()
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
RF_Shut(); //关闭RF接收
|
||||
/* 超时重发全部清除 */
|
||||
lwns_htimer_flush_all();
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT);
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT);
|
||||
|
||||
tmos_stop_task(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT); //停止Htimer心跳时钟和发送列表检测
|
||||
tmos_clear_event(lwns_phyoutput_taskid, LWNS_PHY_OUTPUT_FINISH_EVT);
|
||||
|
||||
while((pMsg = tmos_msg_receive(lwns_phyoutput_taskid)) != NULL)
|
||||
{
|
||||
/* 清除所有缓存的消息 */
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
tmos_clear_event(lwns_phyoutput_taskid, SYS_EVENT_MSG);
|
||||
|
||||
while((pMsg = tmos_msg_receive(lwns_adapter_taskid)) != NULL)
|
||||
{
|
||||
/* 清除所有缓存的消息 */
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
tmos_stop_task(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, LWNS_PHY_RX_OPEN_EVT);
|
||||
tmos_clear_event(lwns_adapter_taskid, SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_start
|
||||
*
|
||||
* @brief lwns开始运行,在使用lwns_shut后,重新开始时使用。
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_start()
|
||||
{
|
||||
RF_Shut();
|
||||
RF_Rx(NULL, 0, USER_RF_RX_TX_TYPE, USER_RF_RX_TX_TYPE); //打开RF接收,如果需要低功耗管理,在其他地方打开。
|
||||
tmos_start_task(lwns_phyoutput_taskid, LWNS_HTIMER_PERIOD_EVT, MS1_TO_SYSTEM_TIME(LWNS_HTIMER_PERIOD_MS));
|
||||
}
|
||||
|
||||
#endif /* LWNS_USE_NO_MAC */
|
||||
@@ -0,0 +1,154 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_broadcast_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : broadcast,广播程序例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_broadcast_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
//用户需要发送的数据缓冲区
|
||||
static uint8_t TX_DATA[10] =
|
||||
{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
|
||||
|
||||
static uint8_t RX_DATA[10]; //用户接收数据的缓冲区
|
||||
static uint16_t lwns_broadcast_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void broadcast_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender); //接收回调函数声明
|
||||
static void broadcast_sent(lwns_controller_ptr ptr); //发送回调函数声明
|
||||
|
||||
static lwns_broadcast_controller broadcast; //广播控制结构体
|
||||
|
||||
static uint8_t broadcast_taskID;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn broadcast_recv
|
||||
*
|
||||
* @brief lwns broadcast接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的广播控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void broadcast_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
if(len == 10)
|
||||
{
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("broadcast %d rec from %02x %02x %02x %02x %02x %02x\n", get_lwns_object_port(ptr),
|
||||
sender->v8[0], sender->v8[1], sender->v8[2], sender->v8[3],
|
||||
sender->v8[4], sender->v8[5]); //打印出本次消息的发送者地址
|
||||
PRINTF("data:");
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]); //打印数据
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("data len err\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn broadcast_sent
|
||||
*
|
||||
* @brief lwns broadcast发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的广播控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void broadcast_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("broadcast %d sent\n", get_lwns_object_port(ptr)); //打印发送完成信息
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns广播回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_broadcast_callbacks broadcast_call = {
|
||||
broadcast_recv, broadcast_sent};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_broadcast_process_init
|
||||
*
|
||||
* @brief lwns broadcast例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_broadcast_process_init(void)
|
||||
{
|
||||
broadcast_taskID = TMOS_ProcessEventRegister(lwns_broadcast_ProcessEvent);
|
||||
lwns_broadcast_init(&broadcast, 136, &broadcast_call); //打开一个端口号为136的广播端口,注册回调函数
|
||||
tmos_start_task(broadcast_taskID, BROADCAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //开始周期性广播任务
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_broadcast_ProcessEvent
|
||||
*
|
||||
* @brief lwns broadcast Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_broadcast_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & BROADCAST_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
lwns_broadcast_send(&broadcast); //广播发送数据
|
||||
tmos_start_task(broadcast_taskID, BROADCAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //周期性发送
|
||||
|
||||
return events ^ BROADCAST_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_mesh_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/28
|
||||
* Description : mesh传输程序例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_mesh_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define MESH_TEST_ROUTE_AUTO 1 //设置是否自动管理路由表
|
||||
#define MESH_TEST_SELF_ADDR_IDX 2 //当前测试中节点地址,在device_addr数组中
|
||||
#define MESH_TEST_ADDR_MAX_IDX 2 //当前测试中,有多少个节点
|
||||
|
||||
static uint8_t mesh_test_send_dst = 0;
|
||||
|
||||
static lwns_mesh_controller lwns_mesh_test;
|
||||
|
||||
static uint8_t lwns_mesh_test_taskID;
|
||||
static uint16_t lwns_mesh_test_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static uint8_t TX_DATA[10] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39};
|
||||
static const lwns_addr_t device_addr[] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, //根节点地址
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x01}, //组1路由节点1
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x02}, //组1节点2
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x03}, //组1节点3
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x04}, //组1节点4
|
||||
{0x00, 0x00, 0x00, 0x00, 0x02, 0x01}, //组2路由节点1
|
||||
{0x00, 0x00, 0x00, 0x00, 0x02, 0x02}, //组2节点2
|
||||
{0x00, 0x00, 0x00, 0x00, 0x02, 0x03}, //组2节点3
|
||||
{0x00, 0x00, 0x00, 0x00, 0x02, 0x04}, //组2节点4
|
||||
{0x00, 0x00, 0x00, 0x00, 0x03, 0x01}, //组3路由节点1
|
||||
{0x00, 0x00, 0x00, 0x00, 0x03, 0x02}, //组3节点2
|
||||
{0x00, 0x00, 0x00, 0x00, 0x03, 0x03}, //组3节点3
|
||||
{0x00, 0x00, 0x00, 0x00, 0x03, 0x04}, //组3节点4
|
||||
};
|
||||
|
||||
static void lwns_mesh_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender, uint8_t hops);
|
||||
static void lwns_mesh_sent(lwns_controller_ptr ptr);
|
||||
static void lwns_mesh_timedout(lwns_controller_ptr ptr);
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_mesh_recv
|
||||
*
|
||||
* @brief lwns mesh接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的mesh控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
* @param hops - 本次接收到的数据的从发送方到本节点经历的跳数.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void lwns_mesh_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender, uint8_t hops)
|
||||
{
|
||||
PRINTF("mesh %d received from %02x.%02x.%02x.%02x.%02x.%02x: %s (%d)\n",
|
||||
get_lwns_object_port(ptr), sender->v8[0], sender->v8[1],
|
||||
sender->v8[2], sender->v8[3], sender->v8[4], sender->v8[5],
|
||||
(char *)lwns_buffer_dataptr(), lwns_buffer_datalen());
|
||||
if(MESH_TEST_SELF_ADDR_IDX != 0)
|
||||
{
|
||||
//不为0,证明是从机,收到后回复主机
|
||||
lwns_buffer_save_data(TX_DATA);
|
||||
tmos_set_event(lwns_mesh_test_taskID, MESH_EXAMPLE_TX_NODE_EVT);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_mesh_sent
|
||||
*
|
||||
* @brief lwns mesh发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的mesh控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void lwns_mesh_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("mesh %d packet sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_mesh_timedout
|
||||
*
|
||||
* @brief lwns mesh发送超时回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的mesh控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void lwns_mesh_timedout(lwns_controller_ptr ptr)
|
||||
{
|
||||
//寻找路由超时才会进入该回调,如果已经有路由,但是下一跳节点掉线,不会进入该回调。由lwns_route_init(TRUE, 60, HTIMER_SECOND_NUM);来管理掉线时间。
|
||||
PRINTF("mesh %d packet timedout\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns mesh回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_mesh_callbacks callbacks = {lwns_mesh_recv,
|
||||
lwns_mesh_sent, lwns_mesh_timedout};
|
||||
|
||||
/*
|
||||
* mesh采用netflood模块进行寻找路由,所以初始化参数中包括了netflood所需要的参数
|
||||
* mesh为利用路由进行多跳转发的基础结构
|
||||
* mesh模块使用前必须初始化路由,包括库初始化时给路由表提供的内存空间。
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_mesh_process_init
|
||||
*
|
||||
* @brief lwns mesh例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_mesh_process_init(void)
|
||||
{
|
||||
uint8_t route_enable = FALSE;
|
||||
lwns_addr_set(
|
||||
(lwns_addr_t *)(&device_addr[MESH_TEST_SELF_ADDR_IDX])); //改变lwns内部addr
|
||||
if(device_addr[MESH_TEST_SELF_ADDR_IDX].v8[5] == 1)
|
||||
{
|
||||
//每一组第一个节点打开路由功能,其他节点不打开路由功能
|
||||
route_enable = TRUE;
|
||||
}
|
||||
lwns_mesh_test_taskID = TMOS_ProcessEventRegister(lwns_mesh_test_ProcessEvent);
|
||||
#if MESH_TEST_ROUTE_AUTO
|
||||
lwns_route_init(TRUE, 60, HTIMER_SECOND_NUM);
|
||||
#else
|
||||
lwns_route_init(TRUE, 0, HTIMER_SECOND_NUM); //disable auto clean route entry
|
||||
#endif /*MESH_TEST_ROUTE_AUTO*/
|
||||
lwns_mesh_init(&lwns_mesh_test, 132, //打开一个端口号132的mesh网络,同时占用后其他的两个端口用作寻找路由,即133,134也同时打开了。
|
||||
HTIMER_SECOND_NUM / 2, //netflood的QUEUETIME功能
|
||||
1, //netflood的dups功能
|
||||
2, //最大跳跃次数层级为5级,即数据包最多可以经过5次转发,超出就丢弃数据包
|
||||
FALSE, //在路由请求的转发过程中,收到了新的需要转发的数据包,旧数据包是立刻发送出去还是丢弃,FALSE为立刻发送,TRUE为丢弃。
|
||||
50, //网络恢复参数,该值定义了一个差距,如果包序号比内存内保存的数据包序号小的值大于此值,则会认为网络故障恢复,继续接收该数据包。
|
||||
//同时,该值也决定了判定为新数据包的差值,即来自同一个节点的新数据包的序号不可以比内存中的大过多,即比此值还大。
|
||||
//例如,内存中保存的为10,新数据包序号为60,差值为50,大于等于此时设置的50,所以将不会被认为为新的数据包,被丢弃。
|
||||
//只有序号为59,差值为49,小于该值,才会被接收。
|
||||
route_enable, //是否使能本机的路由功能,如果为false,不会响应其他节点的路由请求。
|
||||
TRUE, //决定是否添加路由回路,比如收到了一个来自a节点的mesh数据包,本机是否需要存储前往a节点的路由表。FALSE不存,TRUE存。
|
||||
HTIMER_SECOND_NUM * 2, //路由超时时间,超过时间,停止寻找路由,进入timeout回调,该值应大于 route_discovery_hoptime * (hops+1) * 2
|
||||
&callbacks); //没有初始化路由表的话,会返回0,代表打开失败。返回1打开成功。
|
||||
if(MESH_TEST_SELF_ADDR_IDX == 0)
|
||||
{ //如果是主机,则开始周期性轮训其他节点。
|
||||
mesh_test_send_dst = 1;
|
||||
tmos_start_task(lwns_mesh_test_taskID, MESH_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(200));
|
||||
#if MESH_TEST_ROUTE_AUTO
|
||||
PRINTF("Auto route\n");
|
||||
#else
|
||||
uint8_t i;
|
||||
for(i = 1; i < 5; i++)
|
||||
{
|
||||
lwns_route_add(&device_addr[i], &device_addr[1], 2); //手动管理,添加路由条目
|
||||
}
|
||||
for(i = 5; i < 9; i++)
|
||||
{
|
||||
lwns_route_add(&device_addr[i], &device_addr[5], 2); //手动管理,添加路由条目
|
||||
}
|
||||
for(i = 9; i < 13; i++)
|
||||
{
|
||||
lwns_route_add(&device_addr[i], &device_addr[9], 2); //手动管理,添加路由条目
|
||||
}
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 1)
|
||||
{
|
||||
lwns_route_add(&device_addr[4], &device_addr[4], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[3], &device_addr[3], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[2], &device_addr[2], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[0], &device_addr[0], 1); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 2)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[1], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 3)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[1], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 4)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[1], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 5)
|
||||
{
|
||||
lwns_route_add(&device_addr[6], &device_addr[6], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[7], &device_addr[7], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[8], &device_addr[8], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[0], &device_addr[0], 1); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 6)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[5], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 7)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[5], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 8)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[5], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 9)
|
||||
{
|
||||
lwns_route_add(&device_addr[10], &device_addr[10], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[11], &device_addr[11], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[12], &device_addr[12], 1); //手动管理,添加路由条目
|
||||
lwns_route_add(&device_addr[0], &device_addr[0], 1); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 10)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[9], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 11)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[9], 2); //手动管理,添加路由条目
|
||||
}
|
||||
else if(MESH_TEST_SELF_ADDR_IDX == 12)
|
||||
{
|
||||
lwns_route_add(&device_addr[0], &device_addr[9], 2); //手动管理,添加路由条目
|
||||
#endif /*MESH_TEST_ROUTE_AUTO*/
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_mesh_test_ProcessEvent
|
||||
*
|
||||
* @brief lwns mesh Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_mesh_test_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & MESH_EXAMPLE_TX_PERIOD_EVT)
|
||||
{ //主机周期性轮询从机任务
|
||||
uint8_t temp;
|
||||
struct lwns_route_entry *rt;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
rt = lwns_route_lookup(&device_addr[mesh_test_send_dst]); //在路由表中寻找下一跳路由
|
||||
if(rt != NULL)
|
||||
{
|
||||
//打印下一跳路由信息
|
||||
PRINTF("dst:%d,forwarding to %02x.%02x.%02x.%02x.%02x.%02x\n",
|
||||
mesh_test_send_dst, rt->nexthop.v8[0], rt->nexthop.v8[1],
|
||||
rt->nexthop.v8[2], rt->nexthop.v8[3], rt->nexthop.v8[4],
|
||||
rt->nexthop.v8[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("no route to dst:%d\n", mesh_test_send_dst);
|
||||
}
|
||||
lwns_mesh_send(&lwns_mesh_test, &device_addr[mesh_test_send_dst]); //发送mesh消息
|
||||
mesh_test_send_dst++; //轮询目标节点改为下一个
|
||||
if(mesh_test_send_dst > MESH_TEST_ADDR_MAX_IDX)
|
||||
{ //循环往复轮询
|
||||
mesh_test_send_dst = 1;
|
||||
}
|
||||
tmos_start_task(lwns_mesh_test_taskID, MESH_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(2500)); //周期性轮询
|
||||
return (events ^ MESH_EXAMPLE_TX_PERIOD_EVT);
|
||||
}
|
||||
if(events & MESH_EXAMPLE_TX_NODE_EVT)
|
||||
{ //节点给主机发送数据的任务
|
||||
struct lwns_route_entry *rt;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
rt = lwns_route_lookup(&device_addr[0]); //在路由表中寻找下一跳路由
|
||||
if(rt != NULL)
|
||||
{
|
||||
//打印出下一跳路由信息
|
||||
PRINTF("src:%d,forwarding to %02x.%02x.%02x.%02x.%02x.%02x\n",
|
||||
MESH_TEST_SELF_ADDR_IDX, rt->nexthop.v8[0],
|
||||
rt->nexthop.v8[1], rt->nexthop.v8[2], rt->nexthop.v8[3],
|
||||
rt->nexthop.v8[4], rt->nexthop.v8[5]);
|
||||
}
|
||||
lwns_mesh_send(&lwns_mesh_test, &device_addr[0]); //调用mesh发送函数,进行数据的发送
|
||||
return (events ^ MESH_EXAMPLE_TX_NODE_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_multicast_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/20
|
||||
* Description : single-hop multicast,组播传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_multicast_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
static uint8_t subaddrs_index = 0; //发送订阅地址序号
|
||||
#define SUBADDR_NUM 3 //订阅地址数量
|
||||
static uint16_t subaddrs[SUBADDR_NUM] = {1, 2, 3}; //订阅地址数组
|
||||
|
||||
static uint8_t TX_DATA[10] =
|
||||
{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
|
||||
static uint8_t RX_DATA[10];
|
||||
static uint16_t lwns_multicast_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void multicast_recv(lwns_controller_ptr c, uint16_t subaddr, const lwns_addr_t *sender); //组播接收回调函数
|
||||
static void multicast_sent(lwns_controller_ptr ptr); //组播发送完成回调函数
|
||||
|
||||
static lwns_multicast_controller multicast; //声明组播控制结构体
|
||||
|
||||
static uint8_t multicast_taskID; //声明组播控制任务id
|
||||
|
||||
/*********************************************************************
|
||||
* @fn multicast_recv
|
||||
*
|
||||
* @brief lwns multicast接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的组播控制结构体指针.
|
||||
* @param subaddr - 本次接收到的数据的订阅地址.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void multicast_recv(lwns_controller_ptr ptr, uint16_t subaddr, const lwns_addr_t *sender)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
if(len == 10)
|
||||
{
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("multicast %d rec from %02x %02x %02x %02x %02x %02x\n",
|
||||
get_lwns_object_port(ptr),
|
||||
sender->v8[0], sender->v8[1], sender->v8[2], sender->v8[3],
|
||||
sender->v8[4], sender->v8[5]); //from为接收到的数据的发送方地址
|
||||
PRINTF("subaddr:%d data:", subaddr);
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]);
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("data len err\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn multicast_sent
|
||||
*
|
||||
* @brief lwns multicast发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的组播控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void multicast_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("multicast %d sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns组播回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_multicast_callbacks multicast_callbacks =
|
||||
{multicast_recv, multicast_sent};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_multicast_process_init
|
||||
*
|
||||
* @brief lwns multicast例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_multicast_process_init(void)
|
||||
{
|
||||
multicast_taskID = TMOS_ProcessEventRegister(lwns_multicast_ProcessEvent);
|
||||
lwns_multicast_init(&multicast,
|
||||
136, //打开一个端口号为136的组播
|
||||
subaddrs, //订阅地址数组指针
|
||||
SUBADDR_NUM, //订阅地址数量
|
||||
&multicast_callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
tmos_start_task(multicast_taskID, MULTICAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_multicast_ProcessEvent
|
||||
*
|
||||
* @brief lwns multicast Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_multicast_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & MULTICAST_EXAMPLE_TX_PERIOD_EVT)
|
||||
{ //周期性在不同的组播地址上发送组播消息
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
if(subaddrs_index >= SUBADDR_NUM)
|
||||
{
|
||||
subaddrs_index = 0;
|
||||
}
|
||||
lwns_multicast_send(&multicast, subaddrs[subaddrs_index]); //组播发送数据给指定节点
|
||||
subaddrs_index++;
|
||||
tmos_start_task(multicast_taskID, MULTICAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //周期性发送
|
||||
return events ^ MULTICAST_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_multinetflood_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/11/10
|
||||
* Description : multinetflood,组播网络泛洪传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_multinetflood_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 订阅的地址为2字节u16类型。
|
||||
*/
|
||||
static uint8_t subaddrs_index = 0; //发送订阅地址序号
|
||||
#define SUBADDR_NUM 3 //订阅地址数量
|
||||
static uint16_t subaddrs[SUBADDR_NUM] = {1, 2, 3}; //订阅地址数组
|
||||
|
||||
static uint8_t TX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint8_t RX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint16_t lwns_multinetflood_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void multinetflood_recv(lwns_controller_ptr ptr, uint16_t subaddr, const lwns_addr_t *sender, uint8_t hops); //组播网络泛洪接收回调函数
|
||||
static void multinetflood_sent(lwns_controller_ptr ptr); //组播网络泛洪发送完成回调函数
|
||||
|
||||
static lwns_multinetflood_controller multinetflood; //声明组播网络泛洪控制结构体
|
||||
|
||||
static uint8_t multinetflood_taskID; //组播网络泛洪控制任务id
|
||||
|
||||
/*********************************************************************
|
||||
* @fn multinetflood_recv
|
||||
*
|
||||
* @brief lwns multinetflood接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的multinetflood控制结构体指针.
|
||||
* @param subaddr - 本次接收到的数据的订阅地址.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
* @param hops - 本次接收到的数据的从发送方到本节点经历的跳数.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void multinetflood_recv(lwns_controller_ptr ptr, uint16_t subaddr, const lwns_addr_t *sender, uint8_t hops)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("multinetflood %d rec from %02x %02x %02x %02x %02x %02x\n",
|
||||
get_lwns_object_port(ptr),
|
||||
sender->v8[0], sender->v8[1], sender->v8[2], sender->v8[3],
|
||||
sender->v8[4], sender->v8[5]); //from为接收到的数据的发送方地址
|
||||
PRINTF("subaddr:%d,data:", subaddr);
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]); //打印出数据
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn multinetflood_sent
|
||||
*
|
||||
* @brief lwns multinetflood发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的组播网络泛洪控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void multinetflood_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("multinetflood %d sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns 组播网络泛洪回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_multinetflood_callbacks multinetflood_callbacks =
|
||||
{multinetflood_recv, multinetflood_sent};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_multinetflood_process_init
|
||||
*
|
||||
* @brief lwns multinetflood例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_multinetflood_process_init(void)
|
||||
{
|
||||
multinetflood_taskID = TMOS_ProcessEventRegister(lwns_multinetflood_ProcessEvent);
|
||||
for(uint8_t i = 0; i < LWNS_DATA_SIZE; i++)
|
||||
{
|
||||
TX_DATA[i] = i;
|
||||
}
|
||||
lwns_multinetflood_init(&multinetflood,
|
||||
137, //打开一个端口号为137的组播网络泛洪结构体
|
||||
HTIMER_SECOND_NUM, //最大等待转发时间
|
||||
1, //在等待期间,接收到几次同样的数据包就取消本数据包的发送
|
||||
3, //最大转发层级
|
||||
FALSE, //在等待转发过程中,收到了新的需要转发的数据包,旧数据包是立刻发送出去还是丢弃,FALSE为立刻发送,TRUE为丢弃。
|
||||
50, //网络恢复参数,该值定义了一个差距,如果包序号比内存内保存的数据包序号小的值大于此值,则会认为网络故障恢复,继续接收该数据包。
|
||||
//同时,该值也决定了判定为新数据包的差值,即来自同一个节点的新数据包的序号不可以比内存中的大过多,即比此值还大。
|
||||
//例如,内存中保存的为10,新数据包序号为60,差值为50,大于等于此时设置的50,所以将不会被认为为新的数据包,被丢弃。
|
||||
//只有序号为59,差值为49,小于该值,才会被接收。
|
||||
TRUE, //本机是否转发目标非本机的数据包,类似于蓝牙mesh是否启用relay功能。
|
||||
subaddrs, //订阅的地址数组指针
|
||||
SUBADDR_NUM, //订阅地址数量
|
||||
&multinetflood_callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
#if 1
|
||||
tmos_start_task(multinetflood_taskID, MULTINETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_multinetflood_ProcessEvent
|
||||
*
|
||||
* @brief lwns multinetflood Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_multinetflood_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & MULTINETFLOOD_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
if(subaddrs_index >= SUBADDR_NUM)
|
||||
{
|
||||
subaddrs_index = 0;
|
||||
}
|
||||
lwns_multinetflood_send(&multinetflood, subaddrs[subaddrs_index]); //组播网络泛洪发送数据到订阅地址
|
||||
subaddrs_index++;
|
||||
|
||||
tmos_start_task(multinetflood_taskID, MULTINETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //周期性发送
|
||||
return events ^ MULTINETFLOOD_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_netflood_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/07/12
|
||||
* Description : netflood,网络泛洪传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_netflood_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
static uint8_t TX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint8_t RX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint16_t lwns_netflood_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static int netflood_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *from,
|
||||
const lwns_addr_t *originator, uint8_t hops);
|
||||
static void netflood_sent(lwns_controller_ptr ptr);
|
||||
static void netflood_dropped(lwns_controller_ptr ptr);
|
||||
|
||||
/**
|
||||
* lwns 网络泛洪回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_netflood_callbacks callbacks = {netflood_recv,
|
||||
netflood_sent, netflood_dropped};
|
||||
|
||||
static uint8_t netflood_taskID;
|
||||
|
||||
void lwns_netflood_process_init(void);
|
||||
|
||||
static lwns_netflood_controller netflood; //网络泛洪控制结构体
|
||||
|
||||
/*********************************************************************
|
||||
* @fn netflood_recv
|
||||
*
|
||||
* @brief lwns netflood接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的netflood控制结构体指针.
|
||||
* @param from - 本次接收到的数据的上一跳转发者的地址指针.
|
||||
* @param originator - 本次接收到的数据的发送者地址指针.
|
||||
* @param hops - 本次接收到的数据的从发送方到本节点经历的跳数.
|
||||
*
|
||||
* @return 0/1 - 0表示本节点不再转发该数据包,1表示本节点继续转发该数据包.
|
||||
*/
|
||||
static int netflood_recv(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *from,
|
||||
const lwns_addr_t *originator, uint8_t hops)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
PRINTF("netflood %d rec %02x %02x %02x %02x %02x %02x,hops=%d\r\n", get_lwns_object_port(ptr),
|
||||
from->v8[0], from->v8[1], from->v8[2], from->v8[3], from->v8[4],
|
||||
from->v8[5], hops); //打印转发者,即为收到的本次转发数据是谁转发的。
|
||||
PRINTF("netflood orec %02x %02x %02x %02x %02x %02x,hops=%d\r\n",
|
||||
originator->v8[0], originator->v8[1], originator->v8[2],
|
||||
originator->v8[3], originator->v8[4], originator->v8[5],
|
||||
hops); //打印出信息发起者,即为发起本次网络泛洪的节点地址。
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("data:");
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]);
|
||||
}
|
||||
PRINTF("\n");
|
||||
return 1; //返回1,则本节点将继续发送netflood,转发数据
|
||||
//return 0;//返回0,则本节点不再继续netflood,直接终止
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn netflood_sent
|
||||
*
|
||||
* @brief lwns netflood发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的网络泛洪控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void netflood_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("netflood %d sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn netflood_dropped
|
||||
*
|
||||
* @brief lwns netflood数据包丢弃回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的网络泛洪控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void netflood_dropped(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("netflood %d dropped\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_netflood_process_init
|
||||
*
|
||||
* @brief lwns netflood例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_netflood_process_init(void)
|
||||
{
|
||||
netflood_taskID = TMOS_ProcessEventRegister(lwns_netflood_ProcessEvent);
|
||||
for(uint8_t i = 0; i < LWNS_DATA_SIZE; i++)
|
||||
{
|
||||
TX_DATA[i] = i;
|
||||
}
|
||||
lwns_netflood_init(&netflood,
|
||||
137, //打开一个端口号为137的泛洪结构体
|
||||
HTIMER_SECOND_NUM * 1, //等待转发时间
|
||||
1, //在等待期间,接收到几次同样的数据包就取消本数据包的发送
|
||||
3, //最大转发层级
|
||||
FALSE, //在等待转发过程中,收到了新的需要转发的数据包,旧数据包是立刻发送出去还是丢弃,FALSE为立刻发送,TRUE为丢弃。
|
||||
50, //网络恢复参数,该值定义了一个差距,如果包序号比内存内保存的数据包序号小的值大于此值,则会认为网络故障恢复,继续接收该数据包。
|
||||
//同时,该值也决定了判定为新数据包的差值,即来自同一个节点的新数据包的序号不可以比内存中的大过多,即比此值还大。
|
||||
//例如,内存中保存的为10,新数据包序号为60,差值为50,大于等于此时设置的50,所以将不会被认为为新的数据包,被丢弃。
|
||||
//只有序号为59,差值为49,小于该值,才会被接收。
|
||||
&callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
#if 1
|
||||
tmos_start_task(netflood_taskID, NETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_netflood_ProcessEvent
|
||||
*
|
||||
* @brief lwns netflood Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
static uint16_t lwns_netflood_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & NETFLOOD_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
PRINTF("send\n");
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
lwns_netflood_send(&netflood); //发送网络泛洪数据包
|
||||
tmos_start_task(netflood_taskID, NETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(3000)); //10s发送一次
|
||||
return (events ^ NETFLOOD_EXAMPLE_TX_PERIOD_EVT);
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_ruc_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/30
|
||||
* Description : reliable unicast,可靠单播传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_ruc_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static lwns_addr_t dst_addr = {{0xa3, 0xdf, 0x38, 0xe4, 0xc2, 0x84}}; //目标节点地址,测试时,请根据电路板芯片MAC地址不同进行修改。修改为接收方的MAC地址,请勿使用自己的MAC地址
|
||||
#else
|
||||
static lwns_addr_t dst_addr = {{0xd9, 0x37, 0x3c, 0xe4, 0xc2, 0x84}};
|
||||
#endif
|
||||
|
||||
static lwns_ruc_controller ruc; //声明可靠单播控制结构体
|
||||
|
||||
static uint8_t TX_DATA[10] =
|
||||
{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
|
||||
static uint8_t RX_DATA[10];
|
||||
|
||||
static uint8_t ruc_taskID;
|
||||
uint16_t lwns_ruc_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
static void recv_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender);
|
||||
|
||||
static void sent_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *to, uint8_t retransmissions);
|
||||
static void timedout_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *to);
|
||||
|
||||
/*********************************************************************
|
||||
* @fn recv_ruc
|
||||
*
|
||||
* @brief lwns ruc接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的可靠单播控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void recv_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *sender)
|
||||
{
|
||||
//ruc中接收到发送给自己的数据后,才会调用该回调
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
if(len == 10)
|
||||
{
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("ruc %d rec %02x %02x %02x %02x %02x %02x\r\n", get_lwns_object_port(ptr), sender->v8[0],
|
||||
sender->v8[1], sender->v8[2], sender->v8[3], sender->v8[4], sender->v8[5]);
|
||||
PRINTF("data:");
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]);
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("data len err\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn sent_ruc
|
||||
*
|
||||
* @brief lwns ruc发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的可靠单播控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void sent_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *to, uint8_t retransmissions)
|
||||
{
|
||||
//ruc中发送成功,并且收到目标节点的ack回复后,才会调用该回调
|
||||
PRINTF("ruc %d sent %d\r\n", get_lwns_object_port(ptr), retransmissions);
|
||||
tmos_start_task(ruc_taskID, RUC_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //更新任务时间,发送并收到回复后,1秒钟后再发送
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn timedout_ruc
|
||||
*
|
||||
* @brief lwns ruc发送超时回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的ruc控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void timedout_ruc(lwns_controller_ptr ptr,
|
||||
const lwns_addr_t *to)
|
||||
{
|
||||
//ruc中,再重发次数超过最大重发次数后,会调用该回调。
|
||||
PRINTF("ruc %d timedout\n", get_lwns_object_port(ptr));
|
||||
tmos_start_task(ruc_taskID, RUC_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns 可靠单播回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_ruc_callbacks ruc_callbacks = {
|
||||
recv_ruc, sent_ruc, timedout_ruc}; //声明可靠单播回调结构体
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_ruc_process_init
|
||||
*
|
||||
* @brief lwns ruc例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_ruc_process_init(void)
|
||||
{
|
||||
lwns_ruc_init(&ruc,
|
||||
144, //打开一个端口号为144的可靠单播
|
||||
HTIMER_SECOND_NUM, //等待ack时间间隔,没收到就会重发
|
||||
&ruc_callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
ruc_taskID = TMOS_ProcessEventRegister(lwns_ruc_ProcessEvent);
|
||||
tmos_start_task(ruc_taskID, RUC_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_ruc_ProcessEvent
|
||||
*
|
||||
* @brief lwns ruc Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_ruc_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & RUC_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
lwns_ruc_send(&ruc,
|
||||
&dst_addr, //可靠单播目标地址
|
||||
4 //最大重发次数
|
||||
); //可靠单播发送函数:发送参数,目标地址,最大重发次数,默认一秒钟重发一次
|
||||
return events ^ RUC_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_rucft_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/30
|
||||
* Description : reliable unicast file transfer,可靠单播文件传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_rucft_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static lwns_addr_t dst_addr = {{0x66, 0xdf, 0x38, 0xe4, 0xc2, 0x84}}; //目标节点地址,测试时,请根据电路板芯片MAC地址不同进行修改。修改为接收方的MAC地址,请勿使用自己的MAC地址
|
||||
#else
|
||||
static lwns_addr_t dst_addr = {{0xd9, 0x37, 0x3c, 0xe4, 0xc2, 0x84}};
|
||||
#endif
|
||||
|
||||
static uint8_t rucft_taskID;
|
||||
|
||||
static lwns_rucft_controller rucft; //声明rucft控制结构体
|
||||
|
||||
#define FILESIZE 4000
|
||||
static char strsend[FILESIZE]; //发送缓冲区
|
||||
static char *strp;
|
||||
static void write_file(lwns_controller_ptr ptr, const lwns_addr_t *sender,
|
||||
int offset, int flag, char *data, int datalen);
|
||||
static int read_file(lwns_controller_ptr ptr, int offset, char *to);
|
||||
static void timedout_rucft(lwns_controller_ptr ptr);
|
||||
|
||||
/**
|
||||
* lwns 可靠单播文件传输回调函数结构体,注册回调函数
|
||||
*/
|
||||
const static struct lwns_rucft_callbacks rucft_callbacks = {write_file,
|
||||
read_file, timedout_rucft};
|
||||
|
||||
uint16_t lwns_rucft_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/*********************************************************************
|
||||
* @fn write_file
|
||||
*
|
||||
* @brief lwns rucft接收回调函数,作为写入文件回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的netflood控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
* @param offset - 本次接收到的数据的偏移量,也是本次文件传输接收已经收到的数据量.
|
||||
* @param flag - 本次接收到数据的标志,LWNS_RUCFT_FLAG_NONE/LWNS_RUCFT_FLAG_NEWFILE/LWNS_RUCFT_FLAG_END.
|
||||
* @param data - 本次接收到的数据的头指针.
|
||||
* @param datalen - 本次接收到的数据的长度.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void write_file(lwns_controller_ptr ptr, const lwns_addr_t *sender,
|
||||
int offset, int flag, char *data, int datalen)
|
||||
{
|
||||
//sender为发送方的地址
|
||||
//如果需要接收不同的文件,需要在此函数中做好接口
|
||||
if(datalen > 0)
|
||||
{ //声明个缓冲从data里取数据打印
|
||||
PRINTF("r:%c\n", *data);
|
||||
}
|
||||
if(flag == LWNS_RUCFT_FLAG_END)
|
||||
{
|
||||
PRINTF("re\n");
|
||||
//本次文件传输的最后一个包
|
||||
}
|
||||
else if(flag == LWNS_RUCFT_FLAG_NONE)
|
||||
{
|
||||
PRINTF("ru\n");
|
||||
//本次文件传输正常的包
|
||||
}
|
||||
else if(flag == LWNS_RUCFT_FLAG_NEWFILE)
|
||||
{
|
||||
PRINTF("rn\n");
|
||||
//本次文件传输的第一个包
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn read_file
|
||||
*
|
||||
* @brief lwns rucft发送完成回调函数,作为读取文件回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的netflood控制结构体指针.
|
||||
* @param offset - 本次接收到的数据的偏移量,也是本次文件传输发送已经发送的数据量.
|
||||
* @param to - 本次需要发送的数据缓冲区的头指针,用户将数据拷贝到此指针指向的内存空间。.
|
||||
*
|
||||
* @return size - 返回的size即为本次需要发送的数据长度,不可大于LWNS_RUCFT_DATASIZE.
|
||||
*/
|
||||
static int read_file(lwns_controller_ptr ptr, int offset, char *to)
|
||||
{
|
||||
//to为需要保存数据过去的指针
|
||||
//如果需要发送不同的文件,需要在此函数中做好接口
|
||||
int size = LWNS_RUCFT_DATASIZE;
|
||||
if(offset >= FILESIZE)
|
||||
{
|
||||
//上次已经发完,本次是最后确认
|
||||
PRINTF("Send done\n");
|
||||
tmos_start_task(rucft_taskID, RUCFT_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(5000)); //5秒钟后继续发送测试
|
||||
return 0;
|
||||
}
|
||||
else if(offset + LWNS_RUCFT_DATASIZE >= FILESIZE)
|
||||
{
|
||||
size = FILESIZE - offset;
|
||||
}
|
||||
//把本次需要发送的内容压进包缓冲
|
||||
tmos_memcpy(to, strp + offset, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn timedout_rucft
|
||||
*
|
||||
* @brief lwns rucft发送超时回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的ruc控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void timedout_rucft(lwns_controller_ptr ptr)
|
||||
{
|
||||
//rucft中,发送方再重发次数超过最大重发次数后,会调用该回调。
|
||||
//接收方超时没接收到下一个包也会调用
|
||||
PRINTF("rucft %d timedout\r\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_rucft_process_init
|
||||
*
|
||||
* @brief lwns rucft例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_rucft_process_init(void)
|
||||
{
|
||||
lwns_addr_t MacAddr;
|
||||
rucft_taskID = TMOS_ProcessEventRegister(lwns_rucft_ProcessEvent);
|
||||
lwns_rucft_init(&rucft, 137, //端口号
|
||||
HTIMER_SECOND_NUM / 10, //等待目标节点ack时间
|
||||
5, //最大重发次数,与ruc中的ruc_send的重发次数功能一样
|
||||
&rucft_callbacks //回调函数
|
||||
); //返回0代表打开失败。返回1打开成功。
|
||||
int i;
|
||||
for(i = 0; i < FILESIZE; i++)
|
||||
{ //LWNS_RUCFT_DATASIZE个LWNSNK_RUCFT_DATASIZE个b,等等,初始化需要发送的数据
|
||||
strsend[i] = 'a' + i / LWNS_RUCFT_DATASIZE;
|
||||
}
|
||||
strp = strsend;
|
||||
FLASH_GetMACAddress(MacAddr.v8);
|
||||
if(lwns_addr_cmp(&MacAddr, &dst_addr))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
tmos_start_task(rucft_taskID, RUCFT_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_rucft_ProcessEvent
|
||||
*
|
||||
* @brief lwns rucft Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_rucft_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & RUCFT_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
PRINTF("send\n");
|
||||
lwns_rucft_send(&rucft, &dst_addr); //开始发送至目标节点,用户启用发送时要配置好回调函数中的数据包读取
|
||||
return events ^ RUCFT_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_sec.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/09/17
|
||||
* Description : lwns消息加密
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_sec.h"
|
||||
|
||||
static uint8_t lwns_sec_key[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; //用户自行更改为自己的秘钥,或者改为可以从主机获取,并存储在eeprom中
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_msg_encrypt
|
||||
*
|
||||
* @brief lwns消息加密
|
||||
*
|
||||
* @param src - 待加密的数据缓冲头指针.
|
||||
* @param to - 待存储加密数据的数据缓存区头指针.
|
||||
* @param mlen - 待加密的数据长度.
|
||||
*
|
||||
* @return 加密后的数据长度.
|
||||
*/
|
||||
int lwns_msg_encrypt(uint8_t *src, uint8_t *to, uint8_t mlen)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
uint8_t esrc[16];
|
||||
while(1)
|
||||
{
|
||||
if((mlen - i) < 16)
|
||||
{
|
||||
tmos_memcpy(esrc, src + i, (mlen - i)); //扩充到16字节,其他为0
|
||||
LL_Encrypt(lwns_sec_key, esrc, to + i);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_Encrypt(lwns_sec_key, src + i, to + i);
|
||||
}
|
||||
i += 16;
|
||||
if(i >= mlen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i; //返回加密后数据长度
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_msg_decrypt
|
||||
*
|
||||
* @brief lwns消息解密
|
||||
*
|
||||
* @param src - 待解密的数据缓冲头指针.
|
||||
* @param to - 待存储解密数据的数据缓存区头指针.
|
||||
* @param mlen - 待解密的数据长度,必须为16的倍数.
|
||||
*
|
||||
* @return 解密后的数据长度.
|
||||
*/
|
||||
int lwns_msg_decrypt(uint8_t *src, uint8_t *to, uint8_t mlen)
|
||||
{
|
||||
unsigned short i = 0;
|
||||
while(1)
|
||||
{
|
||||
LL_Decrypt(lwns_sec_key, src + i, to + i);
|
||||
i += 16;
|
||||
if(i >= mlen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_unicast_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/06/19
|
||||
* Description : lwns单播传输例子
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_unicast_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static lwns_addr_t dst_addr = {{0xab, 0xdf, 0x38, 0xe4, 0xc2, 0x84}}; //目标节点地址,测试时,请根据电路板芯片MAC地址不同进行修改。修改为接收方的MAC地址,请勿使用自己的MAC地址
|
||||
#else
|
||||
static lwns_addr_t dst_addr = {{0xd9, 0x37, 0x3c, 0xe4, 0xc2, 0x84}};
|
||||
#endif
|
||||
|
||||
static uint8_t TX_DATA[10] =
|
||||
{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
|
||||
static uint8_t RX_DATA[10];
|
||||
static uint16_t lwns_unicast_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void unicast_recv(lwns_controller_ptr c, const lwns_addr_t *from); //单播接收回调函数
|
||||
static void unicast_sent(lwns_controller_ptr ptr); //单播发送完成回调函数
|
||||
|
||||
static lwns_unicast_controller unicast; //声明单播控制结构体
|
||||
|
||||
static uint8_t unicast_taskID; //声明单播控制任务id
|
||||
|
||||
/*********************************************************************
|
||||
* @fn unicast_recv
|
||||
*
|
||||
* @brief lwns unicast接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的单播控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void unicast_recv(lwns_controller_ptr ptr, const lwns_addr_t *sender)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
if(len == 10)
|
||||
{
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("unicast %d rec from %02x %02x %02x %02x %02x %02x\n",
|
||||
get_lwns_object_port(ptr),
|
||||
sender->v8[0], sender->v8[1], sender->v8[2], sender->v8[3],
|
||||
sender->v8[4], sender->v8[5]); //sender为接收到的数据的发送方地址
|
||||
PRINTF("data:");
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]);
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("data len err\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn unicast_sent
|
||||
*
|
||||
* @brief lwns unicast发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的可靠单播控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void unicast_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("unicast %d sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns 单播回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_unicast_callbacks unicast_callbacks =
|
||||
{unicast_recv, unicast_sent};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_unicast_process_init
|
||||
*
|
||||
* @brief lwns unicast例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_unicast_process_init(void)
|
||||
{
|
||||
unicast_taskID = TMOS_ProcessEventRegister(lwns_unicast_ProcessEvent);
|
||||
lwns_unicast_init(&unicast,
|
||||
136, //打开一个端口号为136的单播
|
||||
&unicast_callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
tmos_start_task(unicast_taskID, UNICAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_unicast_ProcessEvent
|
||||
*
|
||||
* @brief lwns unicast Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_unicast_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & UNICAST_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
lwns_unicast_send(&unicast, &dst_addr); //单播发送数据给指定节点
|
||||
tmos_start_task(unicast_taskID, UNICAST_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //周期性发送
|
||||
return events ^ UNICAST_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : lwns_uninetflood_example.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2021/10/25
|
||||
* Description : lwns单播网络泛洪传输例子,将数据网络泛洪发送至指定节点
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "lwns_uninetflood_example.h"
|
||||
|
||||
//每个文件单独debug打印的开关,置0可以禁止本文件内部打印
|
||||
#define DEBUG_PRINT_IN_THIS_FILE 1
|
||||
#if DEBUG_PRINT_IN_THIS_FILE
|
||||
#define PRINTF(...) PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...) \
|
||||
do \
|
||||
{ \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static lwns_addr_t dst_addr = {{0xa3, 0xdf, 0x38, 0xe4, 0xc2, 0x84}}; //目标节点地址,测试时,请根据电路板芯片MAC地址不同进行修改。修改为接收方的MAC地址,请勿使用自己的MAC地址
|
||||
#else
|
||||
static lwns_addr_t dst_addr = {{0xd9, 0x37, 0x3c, 0xe4, 0xc2, 0x84}};
|
||||
#endif
|
||||
|
||||
static uint8_t TX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint8_t RX_DATA[LWNS_DATA_SIZE] = {0}; //最大长度数据收发测试
|
||||
static uint16_t lwns_uninetflood_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
static void uninetflood_recv(lwns_controller_ptr ptr, const lwns_addr_t *sender, uint8_t hops); //单播网络泛洪接收回调函数
|
||||
static void uninetflood_sent(lwns_controller_ptr ptr); //单播网络泛洪发送完成回调函数
|
||||
|
||||
static lwns_uninetflood_controller uninetflood; //单播网络泛洪控制结构体
|
||||
|
||||
static uint8_t uninetflood_taskID; //单播网络泛洪控制任务id
|
||||
|
||||
/*********************************************************************
|
||||
* @fn uninetflood_recv
|
||||
*
|
||||
* @brief lwns uninetflood接收回调函数
|
||||
*
|
||||
* @param ptr - 本次接收到的数据所属的uninetflood控制结构体指针.
|
||||
* @param sender - 本次接收到的数据的发送者地址指针.
|
||||
* @param hops - 本次接收到的数据的从发送方到本节点经历的跳数.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void uninetflood_recv(lwns_controller_ptr ptr, const lwns_addr_t *sender, uint8_t hops)
|
||||
{
|
||||
uint8_t len;
|
||||
len = lwns_buffer_datalen(); //获取当前缓冲区接收到的数据长度
|
||||
lwns_buffer_save_data(RX_DATA); //接收数据到用户数据区域
|
||||
PRINTF("uninetflood %d rec from %02x %02x %02x %02x %02x %02x\n",
|
||||
get_lwns_object_port(ptr),
|
||||
sender->v8[0], sender->v8[1], sender->v8[2], sender->v8[3],
|
||||
sender->v8[4], sender->v8[5]); //from为接收到的数据的发送方地址
|
||||
PRINTF("data:");
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
PRINTF("%02x ", RX_DATA[i]); //打印出数据
|
||||
}
|
||||
PRINTF("\n");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn uninetflood_sent
|
||||
*
|
||||
* @brief lwns uninetflood发送完成回调函数
|
||||
*
|
||||
* @param ptr - 本次发送完成的可靠单播控制结构体指针.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void uninetflood_sent(lwns_controller_ptr ptr)
|
||||
{
|
||||
PRINTF("uninetflood %d sent\n", get_lwns_object_port(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* lwns 单播网络泛洪回调函数结构体,注册回调函数
|
||||
*/
|
||||
static const struct lwns_uninetflood_callbacks uninetflood_callbacks =
|
||||
{uninetflood_recv, uninetflood_sent};
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_uninetflood_process_init
|
||||
*
|
||||
* @brief lwns uninetflood例程初始化.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void lwns_uninetflood_process_init(void)
|
||||
{
|
||||
uninetflood_taskID = TMOS_ProcessEventRegister(lwns_uninetflood_ProcessEvent);
|
||||
for(uint8_t i = 0; i < LWNS_DATA_SIZE; i++)
|
||||
{
|
||||
TX_DATA[i] = i;
|
||||
}
|
||||
lwns_uninetflood_init(&uninetflood,
|
||||
137, //打开一个端口号为137的单播网络泛洪结构体
|
||||
HTIMER_SECOND_NUM * 2, //最大等待转发时间
|
||||
1, //在等待期间,接收到几次同样的数据包就取消本数据包的发送
|
||||
3, //最大转发层级
|
||||
FALSE, //在等待转发过程中,收到了新的需要转发的数据包,旧数据包是立刻发送出去还是丢弃,FALSE为立刻发送,TRUE为丢弃。
|
||||
50, //网络恢复参数,该值定义了一个差距,如果包序号比内存内保存的数据包序号小的值大于此值,则会认为网络故障恢复,继续接收该数据包。
|
||||
//同时,该值也决定了判定为新数据包的差值,即来自同一个节点的新数据包的序号不可以比内存中的大过多,即比此值还大。
|
||||
//例如,内存中保存的为10,新数据包序号为60,差值为50,大于等于此时设置的50,所以将不会被认为为新的数据包,被丢弃。
|
||||
//只有序号为59,差值为49,小于该值,才会被接收。
|
||||
TRUE, //本机是否转发目标非本机的数据包,类似于蓝牙mesh是否启用relay功能。
|
||||
&uninetflood_callbacks); //返回0代表打开失败。返回1打开成功。
|
||||
tmos_start_task(uninetflood_taskID, UNINETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn lwns_uninetflood_ProcessEvent
|
||||
*
|
||||
* @brief lwns uninetflood Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed.
|
||||
*/
|
||||
uint16_t lwns_uninetflood_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
if(events & UNINETFLOOD_EXAMPLE_TX_PERIOD_EVT)
|
||||
{
|
||||
uint8_t temp;
|
||||
temp = TX_DATA[0];
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
{
|
||||
TX_DATA[i] = TX_DATA[i + 1]; //移位发送数据,以便观察效果
|
||||
}
|
||||
TX_DATA[9] = temp;
|
||||
lwns_buffer_load_data(TX_DATA, sizeof(TX_DATA)); //载入需要发送的数据到缓冲区
|
||||
lwns_uninetflood_send(&uninetflood, &dst_addr); //单播网络泛洪发送数据给目标地址
|
||||
tmos_start_task(uninetflood_taskID, UNINETFLOOD_EXAMPLE_TX_PERIOD_EVT,
|
||||
MS1_TO_SYSTEM_TIME(1000)); //周期性发送
|
||||
return events ^ UNINETFLOOD_EXAMPLE_TX_PERIOD_EVT;
|
||||
}
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
if((pMsg = tmos_msg_receive(task_id)) != NULL)
|
||||
{
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,989 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
//#define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( void );
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user