first submission

This commit is contained in:
qiyongshuang
2023-02-01 14:19:13 +08:00
parent d534aad004
commit b79c6ac80d
3711 changed files with 745432 additions and 2 deletions
+160
View File
@@ -0,0 +1,160 @@
<?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.1355869960" 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.2036095834" 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:/CyclingSensor}/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="&quot;${workspace_loc:/${ProjName}/SRC/Core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/SRC/Startup}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/SRC/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/SRC/Peripheral/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/APP/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Profile/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/HAL/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LIB}&quot;"/>
</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="&quot;../&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LIB}&quot;"/>
</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="&quot;${workspace_loc:/${ProjName}/HAL/Link.ld}&quot;"/>
</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"/>
</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="&quot;../LD&quot;"/>
</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="" 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="Profile"/>
<entry excluding="Startup/startup_ch32v20x_D6.S|Startup/startup_ch32v20x_D8.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>
+54
View File
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<projectDescription>
<name>CyclingSensor</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,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,700 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : cyclingsensor.c
* Author : WCH
* Version : V1.0
* Date : 2020/08/06
* Description : Cycling sensor application, initialize the broadcast parameters,
* and then broadcast until the host is connected, the time upload speed and step frequency
*********************************************************************************
* 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 "CONFIG.h"
#include "devinfoservice.h"
#include "cyclingservice.h"
#include "cyclingsensor.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// Fast advertising interval in 625us units. 625*32 = 20ms (recommended)
#define DEFAULT_FAST_ADV_INTERVAL 32
// Duration of fast advertising duration in 625us
#define DEFAULT_FAST_ADV_DURATION 20000
// Duration of advertising to white list members only after link termination
#define DEFAULT_WHITE_LIST_ADV_DURATION 10000
// Slow advertising interval in 625us units. 625*1704 = 1065ms (recommended)
#define DEFAULT_SLOW_ADV_INTERVAL 1704
// Duration of slow advertising duration in 625us (set to 0 for continuous advertising)
#define DEFAULT_SLOW_ADV_DURATION 20000
// How often to perform sensor's periodic event (625us)
#define DEFAULT_CSC_PERIOD 1000
// Minimum connection interval (units of 1.25ms)
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 20
// Maximum connection interval (units of 1.25ms)
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 200
// Slave latency to use if parameter update request
#define DEFAULT_DESIRED_SLAVE_LATENCY 20
// Supervision timeout value (units of 10ms)
#define DEFAULT_DESIRED_CONN_TIMEOUT 1000
// Sensor sends a slave security request.
#define DEFAULT_PAIRING_PARAMETER GAPBOND_PAIRING_MODE_INITIATE
// Bonded devices' addresses are stored in white list.
#define USING_WHITE_LIST FALSE
// Request bonding.
#define REQ_BONDING TRUE
// Time alloted for service discovery before requesting more energy efficient connection parameters
#define SVC_DISC_DELAY 5000
// After 15 seconds of no user input with notifications off, terminate connection
#define NEGLECT_TIMEOUT_DELAY 24000
// Setting this to true lets this device disconnect after a period of no use.
#define USING_NEGLECT_TIMEOUT FALSE
// delay for reset of device's bonds, connections, alerts
#define CSC_RESET_DELAY 3000 // in (625us)
// For simulated measurements
#define FLAGS_IDX_MAX 4
// values for simulated measurements. units in revolutions
#define CRANK_REV_INCREMENT 1
#define WHEEL_REV_INCREMENT 10
// values for simulated measurements. units 1/1024 seconds. 1024 * (1/1024) = 1 seconds
#define WHEEL_EVT_INCREMENT 1024
#define CRANK_EVT_INCREMENT 1024
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8_t sensor_TaskID; // Task ID for internal task/event processing
static gapRole_States_t gapProfileState = GAPROLE_INIT;
static uint8_t sensorUsingWhiteList = FALSE;
// GAP Profile - Name attribute for SCAN RSP data
static uint8_t scanRspData[] = {
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm, default Tx power level
};
static uint8_t advertData[] = {
// flags
0x02,
GAP_ADTYPE_FLAGS,
GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUIDs
0x03,
GAP_ADTYPE_16BIT_MORE,
LO_UINT16(CSC_SERV_UUID),
HI_UINT16(CSC_SERV_UUID),
0x0B, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'C',
'S',
'C',
' ',
'S',
'e',
'n',
's',
'o',
'r',
};
// Device name attribute value
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "CSC Sensor";
// GAP connection handle
static uint16_t gapConnHandle;
// Cycling measurement value stored in this structure
static attHandleValueNoti_t sensorMeas;
// Flags for simulated measurements
static const uint8_t sensorFlags[FLAGS_IDX_MAX] = {
CSC_FLAGS_SPEED_CADENCE,
CSC_FLAGS_AT_REST,
CSC_FLAGS_SPEED,
CSC_FLAGS_CADENCE
};
// Flag index
static uint8_t sensorFlagsIdx = 0;
// Advertising user-cancelled state
static BOOL sensorAdvCancelled = FALSE;
// CSC parameters
uint32_t cummWheelRevs = 0;
uint16_t cummCrankRevs = 0;
uint16_t lastWheelEvtTime = 0;
uint16_t lastCrankEvtTime = 0;
uint16_t mutativeCount = 0;
uint8_t sensorLocation = CSC_SENSOR_LOC_OTHER;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void sensor_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void SensorGapStateCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
static void sensorPeriodicTask(void);
static void sensorMeasNotify(void);
static void SensorCB(uint8_t event, uint32_t *pNewCummVal);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t cyclingPeripheralCB = {
SensorGapStateCB, // Profile State Change Callbacks
NULL, // When a valid RSSI is read from controller
NULL
};
// Bond Manager Callbacks
static gapBondCBs_t cyclingBondCB = {
NULL, // Passcode callback
NULL // Pairing state callback
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn CyclingSensor_Init
*
* @brief Initialization function for the Cycling App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void CyclingSensor_Init()
{
sensor_TaskID = TMOS_ProcessEventRegister(CyclingSensor_ProcessEvent);
// Setup the GAP Peripheral Role Profile
{
uint8_t initial_advertising_enable = TRUE;
// Set the GAP Role Parameters
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
}
// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
// Setup the GAP Bond Manager
{
uint32_t passkey = 0; // passkey "000000"
uint8_t pairMode = DEFAULT_PAIRING_PARAMETER;
uint8_t mitm = FALSE;
uint8_t ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT;
uint8_t bonding = REQ_BONDING;
uint8_t autoSync = USING_WHITE_LIST;
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
GAPBondMgr_SetParameter(GAPBOND_AUTO_SYNC_WL, sizeof(uint8_t), &autoSync);
}
// Initialize GATT attributes
GGS_AddService(GATT_ALL_SERVICES); // GAP
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
Cycling_AddService(GATT_ALL_SERVICES);
DevInfo_AddService();
// Register for cycling service callback
Cycling_Register(SensorCB);
// Setup CSC profile data
{
uint8_t features = CSC_FULL_SUPPORT;
uint8_t sensorLocationCurrent = CSC_SENSOR_LOC_REAR_DROPOUT;
uint8_t sensorLocation1 = CSC_SENSOR_LOC_REAR_DROPOUT;
uint8_t sensorLocation2 = CSC_SENSOR_LOC_LEFT_CRANK;
uint8_t sensorLocation3 = CSC_SENSOR_LOC_REAR_WHEEL;
uint8_t sensorLocation4 = CSC_SENSOR_LOC_HIP;
// Add available sensor locations
Cycling_SetParameter(CSC_AVAIL_SENS_LOCS, 1, &sensorLocation1);
Cycling_SetParameter(CSC_AVAIL_SENS_LOCS, 1, &sensorLocation2);
Cycling_SetParameter(CSC_AVAIL_SENS_LOCS, 1, &sensorLocation3);
Cycling_SetParameter(CSC_AVAIL_SENS_LOCS, 1, &sensorLocation4);
// Set sensor location
Cycling_SetParameter(CSC_SENS_LOC, 1, &sensorLocationCurrent);
// Support all features
Cycling_SetParameter(CSC_FEATURE, 1, &features);
}
// Setup a delayed profile startup
tmos_set_event(sensor_TaskID, START_DEVICE_EVT);
}
/*********************************************************************
* @fn CyclingSensor_ProcessEvent
*
* @brief Cycling Application 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 CyclingSensor_ProcessEvent(uint8_t task_id, uint16_t events)
{
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(sensor_TaskID)) != NULL)
{
sensor_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & START_DEVICE_EVT)
{
// Start the Device
GAPRole_PeripheralStartDevice(sensor_TaskID, &cyclingBondCB, &cyclingPeripheralCB);
return (events ^ START_DEVICE_EVT);
}
if(events & CSC_PERIODIC_EVT)
{
// Perform sensor's periodic task
sensorPeriodicTask();
return (events ^ CSC_PERIODIC_EVT);
}
if(events & CSC_CONN_PARAM_UPDATE_EVT)
{
// Send param update.
GAPRole_PeripheralConnParamUpdateReq(gapConnHandle,
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
DEFAULT_DESIRED_SLAVE_LATENCY,
DEFAULT_DESIRED_CONN_TIMEOUT,
sensor_TaskID);
// Assuming service discovery complete, start neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_start_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY);
}
return (events ^ CSC_CONN_PARAM_UPDATE_EVT);
}
if(events & CSC_NEGLECT_TIMEOUT_EVT)
{
// No user input, terminate connection.
GAPRole_TerminateLink(gapConnHandle);
return (events ^ CSC_NEGLECT_TIMEOUT_EVT);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn sensor_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void sensor_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
default:
break;
}
}
/*********************************************************************
* @fn sensorMeasNotify
*
* @brief Prepare and send a CSC measurement notification
*
* @return none
*/
static void sensorMeasNotify(void)
{
sensorMeas.pValue = GATT_bm_alloc(gapConnHandle, ATT_HANDLE_VALUE_NOTI, CSC_MEAS_LEN, NULL, 0);
if(sensorMeas.pValue != NULL)
{
uint8_t *p = sensorMeas.pValue;
uint8_t flags = sensorFlags[sensorFlagsIdx];
// Build CSC measurement structure from simulated values
// Flags simulate the isPresent bits.
*p++ = flags;
// If flag is present, add speed data into measurement.
if(flags & CSC_FLAGS_SPEED)
{
*p++ = BREAK_UINT32(cummWheelRevs, 0);
*p++ = BREAK_UINT32(cummWheelRevs, 1);
*p++ = BREAK_UINT32(cummWheelRevs, 2);
*p++ = BREAK_UINT32(cummWheelRevs, 3);
*p++ = LO_UINT16(lastWheelEvtTime);
*p++ = HI_UINT16(lastWheelEvtTime);
// Update simulated values (simulate in the reverse direction).
// Don't allow revolutions to roll over.
if(mutativeCount < 10)
{
mutativeCount++;
}
else
{
mutativeCount--;
}
cummWheelRevs += mutativeCount;
lastWheelEvtTime += WHEEL_EVT_INCREMENT;
}
// If present, add cadence data into measurement.
if(flags & CSC_FLAGS_CADENCE)
{
*p++ = LO_UINT16(cummCrankRevs);
*p++ = HI_UINT16(cummCrankRevs);
*p++ = LO_UINT16(lastCrankEvtTime);
*p++ = HI_UINT16(lastCrankEvtTime);
// Update simulated values.
cummCrankRevs += CRANK_REV_INCREMENT;
lastCrankEvtTime += CRANK_EVT_INCREMENT;
}
// Get length.
sensorMeas.len = (uint8_t)(p - sensorMeas.pValue);
// Send to service to send the notification.
if(Cycling_MeasNotify(gapConnHandle, &sensorMeas) != SUCCESS)
{
GATT_bm_free((gattMsg_t *)&sensorMeas, ATT_HANDLE_VALUE_NOTI);
}
}
}
/*********************************************************************
* @fn SensorGapStateCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void SensorGapStateCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
{
// If connected
if(newState == GAPROLE_CONNECTED)
{
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
{
// Get connection handle
gapConnHandle = pEvent->linkCmpl.connectionHandle;
// Set timer to update connection parameters
// 5 seconds should allow enough time for Service Discovery by the collector to finish
tmos_start_task(sensor_TaskID, CSC_CONN_PARAM_UPDATE_EVT, SVC_DISC_DELAY);
}
}
// If disconnected
else if(gapProfileState == GAPROLE_CONNECTED &&
newState != GAPROLE_CONNECTED)
{
uint8_t advState = TRUE;
uint8_t bondCount = 0;
// Stop periodic measurement
tmos_stop_task(sensor_TaskID, CSC_PERIODIC_EVT);
// Reset client characteristic configuration descriptors
Cycling_HandleConnStatusCB(gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED);
// If not already using white list, begin to do so.
GAPBondMgr_GetParameter(GAPBOND_BOND_COUNT, &bondCount);
if(USING_WHITE_LIST && sensorUsingWhiteList == FALSE && bondCount > 0)
{
uint8_t value = GAP_FILTER_POLICY_WHITE;
GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(uint8_t), &value);
sensorUsingWhiteList = TRUE;
}
// link loss -- use fast advertising
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL);
GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_WHITE_LIST_ADV_DURATION);
// Enable advertising
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advState);
}
// if advertising stopped
else if(gapProfileState == GAPROLE_ADVERTISING &&
newState == GAPROLE_WAITING)
{
uint8_t whiteListUsed = FALSE;
// if white list is in use, disable to allow general access
if(sensorUsingWhiteList == TRUE)
{
uint8_t value = GAP_FILTER_POLICY_ALL;
GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(uint8_t), &value);
whiteListUsed = TRUE;
sensorUsingWhiteList = FALSE;
}
// if advertising stopped by user
if(sensorAdvCancelled)
{
sensorAdvCancelled = FALSE;
}
// if fast advertising interrupted to cancel white list
else if(((!USING_WHITE_LIST) || whiteListUsed) &&
(GAP_GetParamValue(TGAP_DISC_ADV_INT_MIN) == DEFAULT_FAST_ADV_INTERVAL))
{
uint8_t advState = TRUE;
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL);
GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION);
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advState);
}
// if fast advertising switch to slow or if was already slow but using white list.
else if(((!USING_WHITE_LIST) || whiteListUsed) ||
(GAP_GetParamValue(TGAP_DISC_ADV_INT_MIN) == DEFAULT_FAST_ADV_INTERVAL))
{
uint8_t advState = TRUE;
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL);
GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION);
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advState);
}
}
// if started
else if(newState == GAPROLE_STARTED)
{
// Set the system ID from the bd addr
uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
GAPRole_GetParameter(GAPROLE_BD_ADDR, systemId);
// shift three bytes up
systemId[7] = systemId[5];
systemId[6] = systemId[4];
systemId[5] = systemId[3];
// set middle bytes to zero
systemId[4] = 0;
systemId[3] = 0;
DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
}
gapProfileState = newState;
}
/*********************************************************************
* @fn SensorCB
*
* @brief Callback function for CSC service.
*
* @param event - service event
* @param pNewCummVal - pointer to new wheel revolution data
* if specified by event. NULL otherwise.
* @return none
*/
static void SensorCB(uint8_t event, uint32_t *pNewCummVal)
{
switch(event)
{
case CSC_CMD_SET_CUMM_VAL:
// Cancel neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_stop_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT);
}
cummWheelRevs = *pNewCummVal;
// Start neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_start_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY);
}
break;
case CSC_CMD_UPDATE_SENS_LOC:
// Cancel neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_stop_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT);
}
// Get updated sensor location
Cycling_GetParameter(CSC_SENS_LOC, &sensorLocation);
// Start neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_start_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY);
}
break;
case CSC_MEAS_NOTI_ENABLED:
// Cancel neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_stop_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT);
}
// If connected start periodic measurement
if(gapProfileState == GAPROLE_CONNECTED)
{
tmos_start_task(sensor_TaskID, CSC_PERIODIC_EVT, DEFAULT_CSC_PERIOD);
}
break;
case CSC_MEAS_NOTI_DISABLED:
// Stop periodic measurement
tmos_stop_task(sensor_TaskID, CSC_PERIODIC_EVT);
// Start neglect timer
if(USING_NEGLECT_TIMEOUT)
{
tmos_start_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY);
}
break;
case CSC_READ_ATTR:
case CSC_WRITE_ATTR:
if(USING_NEGLECT_TIMEOUT)
{
// Cancel neglect timer
tmos_stop_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT);
// Start neglect timer
tmos_start_task(sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY);
}
break;
default:
break;
}
}
/*********************************************************************
* @fn sensorPeriodicTask
*
* @brief Perform a periodic cycling application task.
*
* @param none
*
* @return none
*/
static void sensorPeriodicTask(void)
{
if(gapProfileState == GAPROLE_CONNECTED)
{
// Send speed and cadence measurement notification
sensorMeasNotify();
// Restart timer
tmos_start_task(sensor_TaskID, CSC_PERIODIC_EVT, DEFAULT_CSC_PERIOD);
}
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,67 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0
* Date : 2020/08/06
* Description : The main function and task system of the riding sensor initialization
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/******************************************************************************/
/* Header file contains */
#include "CONFIG.h"
#include "HAL.h"
#include "cyclingservice.h"
#include "cyclingsensor.h"
/*********************************************************************
* GLOBAL TYPEDEFS
*/
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
const uint8_t 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();
GAPRole_PeripheralInit();
CyclingSensor_Init();
Main_Circulation();
}
/******************************** endfile @ main ******************************/
@@ -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,61 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : cyclingsensor.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description :
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef CYCLINGSENSOR_H
#define CYCLINGSENSOR_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// Cycling Sensor Task Events
#define START_DEVICE_EVT 0x0001
#define CSC_PERIODIC_EVT 0x0002
#define CSC_CONN_PARAM_UPDATE_EVT 0x0004
#define CSC_NEGLECT_TIMEOUT_EVT 0x0008
#define CSC_MEAS_LEN 11
/*********************************************************************
* MACROS
*/
/*********************************************************************
* FUNCTIONS
*/
/*
* Task Initialization for the BLE Application
*/
extern void CyclingSensor_Init(void);
/*
* Task Event Processor for the BLE Application
*/
extern uint16_t CyclingSensor_ProcessEvent(uint8_t task_id, uint16_t events);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* CYCLINGSENSOR_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,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.
@@ -0,0 +1,584 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : battservice.c
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : Battery service
*********************************************************************************
* 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 "CONFIG.h"
#include "hiddev.h"
#include "battservice.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// ADC voltage levels
#define BATT_ADC_LEVEL_3V 409
#define BATT_ADC_LEVEL_2V 273
#define BATT_LEVEL_VALUE_IDX 2 // Position of battery level in attribute array
#define BATT_LEVEL_VALUE_CCCD_IDX 3 // Position of battery level CCCD in attribute array
#define BATT_LEVEL_VALUE_LEN 1
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Battery service
const uint8_t battServUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(BATT_SERV_UUID), HI_UINT16(BATT_SERV_UUID)};
// Battery level characteristic
const uint8_t battLevelUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(BATT_LEVEL_UUID), HI_UINT16(BATT_LEVEL_UUID)};
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
// Application callback
static battServiceCB_t battServiceCB;
// Measurement setup callback
static battServiceSetupCB_t battServiceSetupCB = NULL;
// Measurement teardown callback
static battServiceTeardownCB_t battServiceTeardownCB = NULL;
// Measurement calculation callback
static battServiceCalcCB_t battServiceCalcCB = NULL;
static uint16_t battMinLevel = BATT_ADC_LEVEL_2V; // For VDD/3 measurements
static uint16_t battMaxLevel = BATT_ADC_LEVEL_3V; // For VDD/3 measurements
// Critical battery level setting
static uint8_t battCriticalLevel;
// ADC channel to be used for reading
//static uint8_t battServiceAdcCh = HAL_ADC_CHANNEL_VDD;
/*********************************************************************
* Profile Attributes - variables
*/
// Battery Service attribute
static const gattAttrType_t battService = {ATT_BT_UUID_SIZE, battServUUID};
// Battery level characteristic
static uint8_t battLevelProps = GATT_PROP_READ | GATT_PROP_NOTIFY;
static uint8_t battLevel = 100;
static gattCharCfg_t battLevelClientCharCfg[GATT_MAX_NUM_CONN];
// HID Report Reference characteristic descriptor, battery level
static uint8_t hidReportRefBattLevel[HID_REPORT_REF_LEN] = {
HID_RPT_ID_BATT_LEVEL_IN, HID_REPORT_TYPE_INPUT};
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t battAttrTbl[] = {
// Battery Service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&battService /* pValue */
},
// Battery Level Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&battLevelProps},
// Battery Level Value
{
{ATT_BT_UUID_SIZE, battLevelUUID},
GATT_PERMIT_READ,
0,
&battLevel},
// Battery Level Client Characteristic Configuration
{
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8_t *)&battLevelClientCharCfg},
// HID Report Reference characteristic descriptor, batter level input
{
{ATT_BT_UUID_SIZE, reportRefUUID},
GATT_PERMIT_READ,
0,
hidReportRefBattLevel}
};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static bStatus_t battReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
static bStatus_t battWriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
static void battNotifyCB(linkDBItem_t *pLinkItem);
static uint8_t battMeasure(void);
static void battNotifyLevel(void);
/*********************************************************************
* PROFILE CALLBACKS
*/
// Battery Service Callbacks
gattServiceCBs_t battCBs = {
battReadAttrCB, // Read callback function pointer
battWriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Batt_AddService
*
* @brief Initializes the Battery Service by registering
* GATT attributes with the GATT server.
*
* @return Success or Failure
*/
bStatus_t Batt_AddService(void)
{
uint8_t status = SUCCESS;
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, battLevelClientCharCfg);
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService(battAttrTbl,
GATT_NUM_ATTRS(battAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&battCBs);
return (status);
}
/*********************************************************************
* @fn Batt_Register
*
* @brief Register a callback function with the Battery Service.
*
* @param pfnServiceCB - Callback function.
*
* @return None.
*/
extern void Batt_Register(battServiceCB_t pfnServiceCB)
{
battServiceCB = pfnServiceCB;
}
/*********************************************************************
* @fn Batt_SetParameter
*
* @brief Set a Battery Service parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t Batt_SetParameter(uint8_t param, uint8_t len, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case BATT_PARAM_CRITICAL_LEVEL:
battCriticalLevel = *((uint8_t *)value);
// If below the critical level and critical state not set, notify it
if(battLevel < battCriticalLevel)
{
battNotifyLevel();
}
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn Batt_GetParameter
*
* @brief Get a Battery Service parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t Batt_GetParameter(uint8_t param, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case BATT_PARAM_LEVEL:
*((uint8_t *)value) = battLevel;
break;
case BATT_PARAM_CRITICAL_LEVEL:
*((uint8_t *)value) = battCriticalLevel;
break;
case BATT_PARAM_SERVICE_HANDLE:
*((uint16_t *)value) = GATT_SERVICE_HANDLE(battAttrTbl);
break;
case BATT_PARAM_BATT_LEVEL_IN_REPORT:
{
hidRptMap_t *pRpt = (hidRptMap_t *)value;
pRpt->id = hidReportRefBattLevel[0];
pRpt->type = hidReportRefBattLevel[1];
pRpt->handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle;
pRpt->cccdHandle = battAttrTbl[BATT_LEVEL_VALUE_CCCD_IDX].handle;
pRpt->mode = HID_PROTOCOL_MODE_REPORT;
}
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn Batt_MeasLevel
*
* @brief Measure the battery level and update the battery
* level value in the service characteristics. If
* the battery level-state characteristic is configured
* for notification and the battery level has changed
* since the last measurement, then a notification
* will be sent.
*
* @return Success
*/
bStatus_t Batt_MeasLevel(void)
{
uint8_t level;
level = battMeasure();
// If level has gone down
if(level < battLevel)
{
// Update level
battLevel = level;
// Send a notification
battNotifyLevel();
}
return SUCCESS;
}
/*********************************************************************
* @fn Batt_Setup
*
* @brief Set up which ADC source is to be used. Defaults to VDD/3.
*
* @param adc_ch - ADC Channel, e.g. HAL_ADC_CHN_AIN6
* @param minVal - max battery level
* @param maxVal - min battery level
* @param sCB - HW setup callback
* @param tCB - HW tear down callback
* @param cCB - percentage calculation callback
*
* @return none.
*/
void Batt_Setup(uint8_t adc_ch, uint16_t minVal, uint16_t maxVal,
battServiceSetupCB_t sCB, battServiceTeardownCB_t tCB,
battServiceCalcCB_t cCB)
{
//battServiceAdcCh = adc_ch;
battMinLevel = minVal;
battMaxLevel = maxVal;
battServiceSetupCB = sCB;
battServiceTeardownCB = tCB;
battServiceCalcCB = cCB;
}
/*********************************************************************
* @fn battReadAttrCB
*
* @brief Read an attribute.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be read
* @param pLen - length of data to be read
* @param offset - offset of the first octet to be read
* @param maxLen - maximum length of data to be read
*
* @return Success or Failure
*/
static bStatus_t battReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
{
uint16_t uuid;
bStatus_t status = SUCCESS;
// Make sure it's not a blob operation (no attributes in the profile are long)
if(offset > 0)
{
return (ATT_ERR_ATTR_NOT_LONG);
}
uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
// Measure battery level if reading level
if(uuid == BATT_LEVEL_UUID)
{
uint8_t level;
level = battMeasure();
// If level has gone down
if(level < battLevel)
{
// Update level
battLevel = level;
}
*pLen = 1;
pValue[0] = battLevel;
}
else if(uuid == GATT_REPORT_REF_UUID)
{
*pLen = HID_REPORT_REF_LEN;
tmos_memcpy(pValue, pAttr->pValue, HID_REPORT_REF_LEN);
}
else
{
status = ATT_ERR_ATTR_NOT_FOUND;
}
return (status);
}
/*********************************************************************
* @fn battWriteAttrCB
*
* @brief Validate attribute data prior to a write operation
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be written
* @param len - length of data
* @param offset - offset of the first octet to be written
*
* @return Success or Failure
*/
static bStatus_t battWriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
{
bStatus_t status = SUCCESS;
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
if(status == SUCCESS)
{
uint16_t charCfg = BUILD_UINT16(pValue[0], pValue[1]);
if(battServiceCB)
{
(*battServiceCB)((charCfg == GATT_CFG_NO_OPERATION) ? BATT_LEVEL_NOTI_DISABLED : BATT_LEVEL_NOTI_ENABLED);
}
}
break;
default:
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
return (status);
}
/*********************************************************************
* @fn battNotifyCB
*
* @brief Send a notification of the level state characteristic.
*
* @param connHandle - linkDB item
*
* @return None.
*/
static void battNotifyCB(linkDBItem_t *pLinkItem)
{
if(pLinkItem->stateFlags & LINK_CONNECTED)
{
uint16_t value = GATTServApp_ReadCharCfg(pLinkItem->connectionHandle,
battLevelClientCharCfg);
if(value & GATT_CLIENT_CFG_NOTIFY)
{
attHandleValueNoti_t noti;
noti.pValue = GATT_bm_alloc(pLinkItem->connectionHandle, ATT_HANDLE_VALUE_NOTI,
BATT_LEVEL_VALUE_LEN, NULL, 0);
if(noti.pValue != NULL)
{
noti.handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle;
noti.len = BATT_LEVEL_VALUE_LEN;
noti.pValue[0] = battLevel;
if(GATT_Notification(pLinkItem->connectionHandle, &noti, FALSE) != SUCCESS)
{
GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
}
}
}
}
}
/*********************************************************************
* @fn battMeasure
*
* @brief Measure the battery level with the ADC and return
* it as a percentage 0-100%.
*
* @return Battery level.
*/
static uint8_t battMeasure(void)
{
uint16_t adc;
uint8_t percent;
// Call measurement setup callback
if(battServiceSetupCB != NULL)
{
battServiceSetupCB();
}
// Configure ADC and perform a read
adc = 300;
// Call measurement teardown callback
if(battServiceTeardownCB != NULL)
{
battServiceTeardownCB();
}
if(adc >= battMaxLevel)
{
percent = 100;
}
else if(adc <= battMinLevel)
{
percent = 0;
}
else
{
if(battServiceCalcCB != NULL)
{
percent = battServiceCalcCB(adc);
}
else
{
uint16_t range = battMaxLevel - battMinLevel + 1;
// optional if you want to keep it even, otherwise just take floor of divide
// range += (range & 1);
range >>= 2; // divide by 4
percent = (uint8_t)((((adc - battMinLevel) * 25) + (range - 1)) / range);
}
}
return percent;
}
/*********************************************************************
* @fn battNotifyLevelState
*
* @brief Send a notification of the battery level state
* characteristic if a connection is established.
*
* @return None.
*/
static void battNotifyLevel(void)
{
// Execute linkDB callback to send notification
linkDB_PerformFunc(battNotifyCB);
}
/*********************************************************************
* @fn Batt_HandleConnStatusCB
*
* @brief Battery Service link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/
void Batt_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
{
// Make sure this is not loopback connection
if(connHandle != LOOPBACK_CONNHANDLE)
{
// Reset Client Char Config if connection has dropped
if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
(!linkDB_Up(connHandle))))
{
GATTServApp_InitCharCfg(connHandle, battLevelClientCharCfg);
}
}
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,823 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : cyclingservice.c
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description : Cycling service
*********************************************************************************
* 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 "CONFIG.h"
#include "battservice.h"
#include "cyclingservice.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
// Cycling Service Task Events
#define CSC_CMD_IND_SEND_EVT 0x0001
#define CSC_MEAS_VALUE_POS 2
#define CSC_MEAS_CFG_POS 3
#define CSC_COMMAND_VALUE_POS 9
#define CSC_COMMAND_CFG_POS 10
#define COMMAND_IND_LENGTH 2
#define CSC_CMD_LEN (3 + CSC_MAX_SENSOR_LOCS)
/*********************************************************************
* GLOBAL VARIABLES
*/
// CSC service
const uint8_t cyclingServUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(CSC_SERV_UUID), HI_UINT16(CSC_SERV_UUID)};
// CSC measurement characteristic
const uint8_t cyclingMeasUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(CSC_MEAS_UUID), HI_UINT16(CSC_MEAS_UUID)};
// CSC feature characteristic
const uint8_t cyclingFeatureUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(CSC_FEATURE_UUID), HI_UINT16(CSC_FEATURE_UUID)};
// CSC sensor location characteristic
const uint8_t cyclingSensLocUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SENSOR_LOC_UUID), HI_UINT16(SENSOR_LOC_UUID)};
// CSC command characteristic
const uint8_t cyclingCommandUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SC_CTRL_PT_UUID), HI_UINT16(SC_CTRL_PT_UUID)};
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
uint16_t CyclingService_ProcessEvent(uint8_t task_id, uint16_t events);
/*********************************************************************
* LOCAL VARIABLES
*/
static cyclingServiceCB_t cyclingServiceCB = NULL;
static uint8_t supportedSensors = 0;
static BOOL scOpInProgress = FALSE;
// Variables used in CSC command processing
static uint16_t connectionHandle;
static attHandleValueInd_t cscCmdInd;
/*********************************************************************
* Profile Attributes - variables
*/
// TaskID
uint8_t cyclingService_TaskID = 0;
// CSC Service attribute
static const gattAttrType_t cyclingService = {ATT_BT_UUID_SIZE, cyclingServUUID};
// Available sensor locations
static uint8_t supportedSensorLocations[CSC_MAX_SENSOR_LOCS];
// Cycling Measurement Characteristic
// Note: characteristic value is not stored here
static uint8_t cyclingMeasProps = GATT_PROP_NOTIFY;
static uint8_t cyclingMeas = 0;
static gattCharCfg_t cyclingMeasClientCharCfg[GATT_MAX_NUM_CONN];
// Feature Characteristic
static uint8_t cyclingFeatureProps = GATT_PROP_READ;
static uint16_t cyclingFeatures = CSC_NO_SUPPORT;
// Sensor Location Characteristic
static uint8_t cyclingSensLocProps = GATT_PROP_READ;
static uint8_t cyclingSensLoc = CSC_SENSOR_LOC_TOP_OF_SHOE;
// Command Characteristic
static uint8_t cyclingCommandProps = GATT_PROP_WRITE | GATT_PROP_INDICATE;
static uint8_t cyclingCommand = 0;
static gattCharCfg_t cyclingCommandClientCharCfg[GATT_MAX_NUM_CONN];
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t cyclingAttrTbl[] = {
// CSC Service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&cyclingService /* pValue */
},
// CSC Measurement Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&cyclingMeasProps},
// Measurement Value
{
{ATT_BT_UUID_SIZE, cyclingMeasUUID},
0,
0,
&cyclingMeas},
// Measurement Client Characteristic Configuration
{
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8_t *)&cyclingMeasClientCharCfg},
// CSC Feature Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&cyclingFeatureProps},
// Feature Value
{
{ATT_BT_UUID_SIZE, cyclingFeatureUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)&cyclingFeatures},
// CSC Sensor Location Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&cyclingSensLocProps},
// Sensor Location Value
{
{ATT_BT_UUID_SIZE, cyclingSensLocUUID},
GATT_PERMIT_READ,
0,
&cyclingSensLoc},
// CSC Command Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&cyclingCommandProps},
// Command Value
{
{ATT_BT_UUID_SIZE, cyclingCommandUUID},
GATT_PERMIT_WRITE,
0,
&cyclingCommand},
// Command Client Characteristic Configuration
{
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8_t *)&cyclingCommandClientCharCfg}
};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static uint8_t cycling_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset,
uint16_t maxLen, uint8_t method);
static bStatus_t cycling_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset,
uint8_t method);
static void cycling_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void cycling_ProcessGATTMsg(gattMsgEvent_t *pMsg);
static BOOL cycling_SensorLocSupported(uint8_t sensorLoc);
static void cycling_ProcessCSCCmd(uint16_t attrHandle, uint8_t *pValue, uint8_t len);
/*********************************************************************
* PROFILE CALLBACKS
*/
// CSC Service Callbacks
gattServiceCBs_t cyclingCBs = {
cycling_ReadAttrCB, // Read callback function pointer
cycling_WriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn CyclingService_Init
*
* @brief collect the TMOS task ID.
*
* @param task_id - TMOS task ID.
*
* @return none
*/
void CyclingService_Init()
{
// Only purpose is to obtain task ID
cyclingService_TaskID = TMOS_ProcessEventRegister(CyclingService_ProcessEvent);
}
/*********************************************************************
* @fn CyclingService_ProcessEvent
*
* @brief process incoming event.
*
* @param task_id - TMOS task id.
*
* @param events - event bit(s) set for the task(s)
*
* @return none
*/
uint16_t CyclingService_ProcessEvent(uint8_t task_id, uint16_t events)
{
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(cyclingService_TaskID)) != NULL)
{
cycling_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & CSC_CMD_IND_SEND_EVT)
{
// Send the indication.
if(GATT_Indication(connectionHandle, &cscCmdInd, FALSE, cyclingService_TaskID) != SUCCESS)
{
GATT_bm_free((gattMsg_t *)&cscCmdInd, ATT_HANDLE_VALUE_IND);
}
// Set Control Point Cfg done
scOpInProgress = FALSE;
return (events ^ CSC_CMD_IND_SEND_EVT);
}
return 0;
}
/*********************************************************************
* @fn cycling_ProcessTMOSMsg
*
* @brief process incoming TMOS msg.
*
* @param pMsg- pointer to messag to be read.
*
* @return none
*/
void cycling_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
case GATT_MSG_EVENT:
cycling_ProcessGATTMsg((gattMsgEvent_t *)pMsg);
break;
default: // do nothing
break;
}
}
/*********************************************************************
* @fn cycling_ProcessGATTMsg
*
* @brief process incoming GATT msg.
*
* @param pMsg- pointer to messag to be read.
*
* @return none
*/
void cycling_ProcessGATTMsg(gattMsgEvent_t *pMsg)
{
if(pMsg->method == ATT_HANDLE_VALUE_CFM)
{
// Indication receipt was confirmed by the client.
// This is a placeholder for future.
}
}
/*********************************************************************
* @fn cycling_SensorLocSupported
*
* @brief check to see if sensor location is supported
*
* @param sensorLoc - location to check for
*
* @return TRUE if supported, FALSE otherwise
*/
static BOOL cycling_SensorLocSupported(uint8_t sensorLoc)
{
uint8_t i;
for(i = 0; i <= supportedSensors; i++)
{
if(supportedSensorLocations[i] == sensorLoc)
{
return TRUE;
}
}
return FALSE;
}
/*********************************************************************
* @fn Cycling_AddService
*
* @brief Initializes the CSC service by registering
* GATT attributes with the GATT server.
*
* @param services - services to add. This is a bit map and can
* contain more than one service.
*
* @return Success or Failure
*/
bStatus_t Cycling_AddService(uint32_t services)
{
uint8_t status = SUCCESS;
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, cyclingMeasClientCharCfg);
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, cyclingCommandClientCharCfg);
if(services & CYCLING_SERVICE)
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService(cyclingAttrTbl,
GATT_NUM_ATTRS(cyclingAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&cyclingCBs);
}
return (status);
}
/*********************************************************************
* @fn Cycling_Register
*
* @brief Register a callback function with the CSC Service.
*
* @param pfnServiceCB - Callback function.
*
* @return None.
*/
void Cycling_Register(cyclingServiceCB_t pfnServiceCB)
{
cyclingServiceCB = pfnServiceCB;
}
/*********************************************************************
* @fn Cycling_SetParameter
*
* @brief Set a CSC parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t Cycling_SetParameter(uint8_t param, uint8_t len, void *pValue)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case CSC_SENS_LOC:
cyclingSensLoc = *((uint8_t *)pValue);
break;
case CSC_FEATURE:
cyclingFeatures = *((uint8_t *)pValue);
break;
case CSC_AVAIL_SENS_LOCS:
if(supportedSensors < CSC_MAX_SENSOR_LOCS)
{
supportedSensorLocations[supportedSensors++] = *((uint8_t *)pValue);
}
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn Cycling_GetParameter
*
* @brief Get a CSC parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t Cycling_GetParameter(uint8_t param, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case CSC_FEATURE:
*((uint8_t *)value) = cyclingFeatures;
break;
case CSC_SENS_LOC:
*((uint8_t *)value) = cyclingSensLoc;
break;
case CSC_COMMAND:
*((uint8_t *)value) = cyclingCommand;
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn Cycling_MeasNotify
*
* @brief Send a notification containing a CSC
* measurement.
*
* @param connHandle - connection handle
* @param pNoti - pointer to notification structure
*
* @return Success or Failure
*/
bStatus_t Cycling_MeasNotify(uint16_t connHandle, attHandleValueNoti_t *pNoti)
{
uint16_t value = GATTServApp_ReadCharCfg(connHandle, cyclingMeasClientCharCfg);
// If notifications enabled
if(value & GATT_CLIENT_CFG_NOTIFY)
{
// Set the handle
pNoti->handle = cyclingAttrTbl[CSC_MEAS_VALUE_POS].handle;
// Send the notification
return GATT_Notification(connHandle, pNoti, FALSE);
}
return bleIncorrectMode;
}
/*********************************************************************
* @fn cycling_ProcessCSCCmd
*
* @brief process an incoming CSC command.
*
* @param attrHandle - attribute handle
* @param pValue - pointer to data to be written
* @param len - length of data
*
* @return none
*/
static void cycling_ProcessCSCCmd(uint16_t attrHandle, uint8_t *pValue, uint8_t len)
{
uint8_t cscStatus = CSC_SUCCESS;
// See if need to alloc payload for new indication.
if(cscCmdInd.pValue == NULL)
{
cscCmdInd.pValue = GATT_bm_alloc(connectionHandle, ATT_HANDLE_VALUE_IND,
CSC_CMD_LEN, NULL, 0);
if(cscCmdInd.pValue == NULL)
{
return; // failed to alloc space!
}
}
// Set Control Point Cfg in progress
scOpInProgress = TRUE;
// Set indication info to be sent out
cscCmdInd.handle = attrHandle;
cscCmdInd.len = 3;
cscCmdInd.pValue[0] = CSC_COMMAND_RSP;
cscCmdInd.pValue[1] = pValue[0];
switch(pValue[0])
{
case CSC_SET_CUMM_VAL:
// If wheel revolutions is a feature
if((len <= 5) && (cyclingFeatures & CSC_WHEEL_REV_SUPP))
{
uint32_t cummWheelRevolutions;
// full 32 bits were specified.
if((len - 1) == 4)
{
cummWheelRevolutions = BUILD_UINT32(pValue[1], pValue[2], pValue[3], pValue[4]);
}
else
{
int i;
cummWheelRevolutions = 0;
// In case only lower bits were specified and upper bits remain zero.
for(i = 0; i < (len - 1); ++i)
{
cummWheelRevolutions += pValue[i + 1] << (i * 8);
}
}
// Notify app
if(cyclingServiceCB != NULL)
{
(*cyclingServiceCB)(CSC_CMD_SET_CUMM_VAL, &cummWheelRevolutions);
}
}
else // characteristic not supported.
{
cscStatus = CSC_INVALID_PARAMETER;
}
break;
case CSC_UPDATE_SENS_LOC:
// If multiple sensor locations is supported and that this is a valid location.
if((len == 2) &&
(cyclingFeatures & CSC_MULTI_SENS_SUPP) &&
(cycling_SensorLocSupported(pValue[1]) == TRUE))
{
// Update sensor location
cyclingSensLoc = pValue[1];
// Notify app
if(cyclingServiceCB != NULL)
{
(*cyclingServiceCB)(CSC_CMD_UPDATE_SENS_LOC, NULL);
}
}
else // characteristic not supported.
{
cscStatus = CSC_INVALID_PARAMETER;
}
break;
case CSC_REQ_SUPP_SENS_LOC:
// If multiple sensor locations are supported and list requested
if((len == 1) && (cyclingFeatures & CSC_MULTI_SENS_SUPP))
{
cscCmdInd.len += supportedSensors;
tmos_memcpy(&(cscCmdInd.pValue[3]), supportedSensorLocations, supportedSensors);
}
else // characteristic not supported.
{
// Send an indication with the list.
cscStatus = CSC_INVALID_PARAMETER;
}
break;
default:
// Send an indication with opcode not suported response
cscStatus = CSC_OPCODE_NOT_SUPPORTED;
break;
}
// Send indication of operation result
cscCmdInd.pValue[2] = cscStatus;
// Ask our task to send out indication
tmos_set_event(cyclingService_TaskID, CSC_CMD_IND_SEND_EVT);
}
/*********************************************************************
* @fn Cycling_HandleConnStatusCB
*
* @brief CSC Service link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/
void Cycling_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
{
// Make sure this is not loopback connection
if(connHandle != LOOPBACK_CONNHANDLE)
{
// Reset Client Char Config if connection has dropped
if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
(!linkDB_Up(connHandle))))
{
GATTServApp_InitCharCfg(connHandle, cyclingMeasClientCharCfg);
GATTServApp_InitCharCfg(connHandle, cyclingCommandClientCharCfg);
}
}
}
/*********************************************************************
* @fn cycling_ReadAttrCB
*
* @brief Read an attribute.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be read
* @param pLen - length of data to be read
* @param offset - offset of the first octet to be read
* @param maxLen - maximum length of data to be read
*
* @return Success or Failure
*/
static uint8_t cycling_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset,
uint16_t maxLen, uint8_t method)
{
bStatus_t status = SUCCESS;
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
// Make sure it's not a blob operation (no attributes in the profile are long)
if(offset > 0)
{
return (ATT_ERR_ATTR_NOT_LONG);
}
switch(uuid)
{
case SENSOR_LOC_UUID:
{
// Read Sensor Location
*pLen = 1;
pValue[0] = pAttr->pValue[0];
}
break;
case CSC_FEATURE_UUID:
{
//Read Cycling Feature
*pLen = 2;
pValue[0] = LO_UINT16(pAttr->pValue[0]);
pValue[1] = HI_UINT16(pAttr->pValue[0]);
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
{
// Read Measurement or Command Configuration
if(pAttr->pValue == (uint8_t *)cyclingMeasClientCharCfg)
{
*pLen = 1;
pValue[0] = GATTServApp_ReadCharCfg(connHandle, cyclingMeasClientCharCfg);
}
else if(pAttr->pValue == (uint8_t *)cyclingCommandClientCharCfg)
{
*pLen = 1;
pValue[0] = GATTServApp_ReadCharCfg(connHandle, cyclingCommandClientCharCfg);
}
else
{
status = ATT_ERR_ATTR_NOT_FOUND;
}
}
break;
default:
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
// Notify app
if(cyclingServiceCB != NULL)
{
(*cyclingServiceCB)(CSC_READ_ATTR, NULL);
}
return (status);
}
/*********************************************************************
* @fn cycling_WriteAttrCB
*
* @brief Validate attribute data prior to a write operation
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be written
* @param len - length of data
* @param offset - offset of the first octet to be written
*
* @return Success or Failure
*/
static bStatus_t cycling_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset,
uint8_t method)
{
bStatus_t status = SUCCESS;
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
if(offset > 0)
{
return (ATT_ERR_ATTR_NOT_LONG);
}
switch(uuid)
{
case SC_CTRL_PT_UUID:
// Make sure Control Point Cfg is not already in progress
if(scOpInProgress == TRUE)
{
status = CSC_ERR_PROC_IN_PROGRESS;
}
// Make sure Control Point Cfg is configured for Indications
else if((cyclingCommandClientCharCfg[connHandle].value & GATT_CLIENT_CFG_INDICATE) == FALSE)
{
status = CSC_ERR_CCC_IMPROPER_CFG;
}
else
{
// Process CSC command
cycling_ProcessCSCCmd(pAttr->handle, pValue, len);
connectionHandle = connHandle;
}
break;
// For Measure and Commands CCC
case GATT_CLIENT_CHAR_CFG_UUID:
if(pAttr->handle == cyclingAttrTbl[CSC_COMMAND_CFG_POS].handle)
{
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_INDICATE);
// Notify app
if(cyclingServiceCB != NULL)
{
(*cyclingServiceCB)(CSC_WRITE_ATTR, NULL);
}
}
else if(pAttr->handle == cyclingAttrTbl[CSC_MEAS_CFG_POS].handle)
{
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
if(status == SUCCESS)
{
// Notify app
if(cyclingServiceCB != NULL)
{
uint16_t charCfg = BUILD_UINT16(pValue[0], pValue[1]);
(*cyclingServiceCB)(((charCfg == GATT_CFG_NO_OPERATION) ? CSC_MEAS_NOTI_DISABLED : CSC_MEAS_NOTI_ENABLED), NULL);
}
}
}
break;
default:
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
return (status);
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,588 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : devinfoservice.c
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : Device information service
*********************************************************************************
* 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 "CONFIG.h"
#include "devinfoservice.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Device information service
const uint8_t devInfoServUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(DEVINFO_SERV_UUID), HI_UINT16(DEVINFO_SERV_UUID)};
// System ID
const uint8_t devInfoSystemIdUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SYSTEM_ID_UUID), HI_UINT16(SYSTEM_ID_UUID)};
// Model Number String
const uint8_t devInfoModelNumberUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(MODEL_NUMBER_UUID), HI_UINT16(MODEL_NUMBER_UUID)};
// Serial Number String
const uint8_t devInfoSerialNumberUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SERIAL_NUMBER_UUID), HI_UINT16(SERIAL_NUMBER_UUID)};
// Firmware Revision String
const uint8_t devInfoFirmwareRevUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(FIRMWARE_REV_UUID), HI_UINT16(FIRMWARE_REV_UUID)};
// Hardware Revision String
const uint8_t devInfoHardwareRevUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(HARDWARE_REV_UUID), HI_UINT16(HARDWARE_REV_UUID)};
// Software Revision String
const uint8_t devInfoSoftwareRevUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SOFTWARE_REV_UUID), HI_UINT16(SOFTWARE_REV_UUID)};
// Manufacturer Name String
const uint8_t devInfoMfrNameUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(MANUFACTURER_NAME_UUID), HI_UINT16(MANUFACTURER_NAME_UUID)};
// IEEE 11073-20601 Regulatory Certification Data List
const uint8_t devInfo11073CertUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(IEEE_11073_CERT_DATA_UUID), HI_UINT16(IEEE_11073_CERT_DATA_UUID)};
// PnP ID
const uint8_t devInfoPnpIdUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(PNP_ID_UUID), HI_UINT16(PNP_ID_UUID)};
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
/*********************************************************************
* Profile Attributes - variables
*/
// Device Information Service attribute
static const gattAttrType_t devInfoService = {ATT_BT_UUID_SIZE, devInfoServUUID};
// System ID characteristic
static uint8_t devInfoSystemIdProps = GATT_PROP_READ;
static uint8_t devInfoSystemId[DEVINFO_SYSTEM_ID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0};
// Model Number String characteristic
static uint8_t devInfoModelNumberProps = GATT_PROP_READ;
static const uint8_t devInfoModelNumber[] = "Model Number";
// Serial Number String characteristic
static uint8_t devInfoSerialNumberProps = GATT_PROP_READ;
static const uint8_t devInfoSerialNumber[] = "Serial Number";
// Firmware Revision String characteristic
static uint8_t devInfoFirmwareRevProps = GATT_PROP_READ;
static const uint8_t devInfoFirmwareRev[] = "Firmware Revision";
// Hardware Revision String characteristic
static uint8_t devInfoHardwareRevProps = GATT_PROP_READ;
static const uint8_t devInfoHardwareRev[] = "Hardware Revision";
// Software Revision String characteristic
static uint8_t devInfoSoftwareRevProps = GATT_PROP_READ;
static const uint8_t devInfoSoftwareRev[] = "Software Revision";
// Manufacturer Name String characteristic
static uint8_t devInfoMfrNameProps = GATT_PROP_READ;
static const uint8_t devInfoMfrName[] = "Manufacturer Name";
// IEEE 11073-20601 Regulatory Certification Data List characteristic
static uint8_t devInfo11073CertProps = GATT_PROP_READ;
static const uint8_t devInfo11073Cert[] = {
DEVINFO_11073_BODY_EXP, // authoritative body type
0x00, // authoritative body structure type
// authoritative body data follows below:
'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'};
// System ID characteristic
static uint8_t devInfoPnpIdProps = GATT_PROP_READ;
static uint8_t devInfoPnpId[DEVINFO_PNP_ID_LEN] = {
1, // Vendor ID source (1=Bluetooth SIG)
LO_UINT16(0x07D7), HI_UINT16(0x07D7), // Vendor ID (WCH)
LO_UINT16(0x0000), HI_UINT16(0x0000), // Product ID (vendor-specific)
LO_UINT16(0x0110), HI_UINT16(0x0110) // Product version (JJ.M.N)
};
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t devInfoAttrTbl[] = {
// Device Information Service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&devInfoService /* pValue */
},
// System ID Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSystemIdProps},
// System ID Value
{
{ATT_BT_UUID_SIZE, devInfoSystemIdUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSystemId},
// Model Number String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoModelNumberProps},
// Model Number Value
{
{ATT_BT_UUID_SIZE, devInfoModelNumberUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoModelNumber},
// Serial Number String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSerialNumberProps},
// Serial Number Value
{
{ATT_BT_UUID_SIZE, devInfoSerialNumberUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSerialNumber},
// Firmware Revision String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoFirmwareRevProps},
// Firmware Revision Value
{
{ATT_BT_UUID_SIZE, devInfoFirmwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoFirmwareRev},
// Hardware Revision String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoHardwareRevProps},
// Hardware Revision Value
{
{ATT_BT_UUID_SIZE, devInfoHardwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoHardwareRev},
// Software Revision String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSoftwareRevProps},
// Software Revision Value
{
{ATT_BT_UUID_SIZE, devInfoSoftwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSoftwareRev},
// Manufacturer Name String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoMfrNameProps},
// Manufacturer Name Value
{
{ATT_BT_UUID_SIZE, devInfoMfrNameUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoMfrName},
// IEEE 11073-20601 Regulatory Certification Data List Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfo11073CertProps},
// IEEE 11073-20601 Regulatory Certification Data List Value
{
{ATT_BT_UUID_SIZE, devInfo11073CertUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfo11073Cert},
// PnP ID Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoPnpIdProps},
// PnP ID Value
{
{ATT_BT_UUID_SIZE, devInfoPnpIdUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoPnpId}};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static bStatus_t devInfo_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
/*********************************************************************
* PROFILE CALLBACKS
*/
// Device Info Service Callbacks
gattServiceCBs_t devInfoCBs = {
devInfo_ReadAttrCB, // Read callback function pointer
NULL, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* NETWORK LAYER CALLBACKS
*/
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn DevInfo_AddService
*
* @brief Initializes the Device Information service by registering
* GATT attributes with the GATT server.
*
* @return Success or Failure
*/
bStatus_t DevInfo_AddService(void)
{
// Register GATT attribute list and CBs with GATT Server App
return GATTServApp_RegisterService(devInfoAttrTbl,
GATT_NUM_ATTRS(devInfoAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&devInfoCBs);
}
/*********************************************************************
* @fn DevInfo_SetParameter
*
* @brief Set a Device Information parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to write
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t DevInfo_SetParameter(uint8_t param, uint16_t len, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case DEVINFO_SYSTEM_ID:
tmos_memcpy(devInfoSystemId, value, len);
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn DevInfo_GetParameter
*
* @brief Get a Device Information parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t DevInfo_GetParameter(uint8_t param, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case DEVINFO_SYSTEM_ID:
tmos_memcpy(value, devInfoSystemId, sizeof(devInfoSystemId));
break;
case DEVINFO_MODEL_NUMBER:
tmos_memcpy(value, devInfoModelNumber, sizeof(devInfoModelNumber));
break;
case DEVINFO_SERIAL_NUMBER:
tmos_memcpy(value, devInfoSerialNumber, sizeof(devInfoSerialNumber));
break;
case DEVINFO_FIRMWARE_REV:
tmos_memcpy(value, devInfoFirmwareRev, sizeof(devInfoFirmwareRev));
break;
case DEVINFO_HARDWARE_REV:
tmos_memcpy(value, devInfoHardwareRev, sizeof(devInfoHardwareRev));
break;
case DEVINFO_SOFTWARE_REV:
tmos_memcpy(value, devInfoSoftwareRev, sizeof(devInfoSoftwareRev));
break;
case DEVINFO_MANUFACTURER_NAME:
tmos_memcpy(value, devInfoMfrName, sizeof(devInfoMfrName));
break;
case DEVINFO_11073_CERT_DATA:
tmos_memcpy(value, devInfo11073Cert, sizeof(devInfo11073Cert));
break;
case DEVINFO_PNP_ID:
tmos_memcpy(value, devInfoPnpId, sizeof(devInfoPnpId));
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn devInfo_ReadAttrCB
*
* @brief Read an attribute.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be read
* @param pLen - length of data to be read
* @param offset - offset of the first octet to be read
* @param maxLen - maximum length of data to be read
*
* @return Success or Failure
*/
static bStatus_t devInfo_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
{
bStatus_t status = SUCCESS;
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
case SYSTEM_ID_UUID:
// verify offset
if(offset >= sizeof(devInfoSystemId))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length
*pLen = MIN(maxLen, (sizeof(devInfoSystemId) - offset));
// copy data
tmos_memcpy(pValue, &devInfoSystemId[offset], *pLen);
}
break;
case MODEL_NUMBER_UUID:
// verify offset
if(offset >= (sizeof(devInfoModelNumber) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoModelNumber) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoModelNumber[offset], *pLen);
}
break;
case SERIAL_NUMBER_UUID:
// verify offset
if(offset >= (sizeof(devInfoSerialNumber) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoSerialNumber) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoSerialNumber[offset], *pLen);
}
break;
case FIRMWARE_REV_UUID:
// verify offset
if(offset >= (sizeof(devInfoFirmwareRev) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoFirmwareRev) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoFirmwareRev[offset], *pLen);
}
break;
case HARDWARE_REV_UUID:
// verify offset
if(offset >= (sizeof(devInfoHardwareRev) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoHardwareRev) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoHardwareRev[offset], *pLen);
}
break;
case SOFTWARE_REV_UUID:
// verify offset
if(offset >= (sizeof(devInfoSoftwareRev) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoSoftwareRev) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoSoftwareRev[offset], *pLen);
}
break;
case MANUFACTURER_NAME_UUID:
// verify offset
if(offset >= (sizeof(devInfoMfrName) - 1))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length (exclude null terminating character)
*pLen = MIN(maxLen, ((sizeof(devInfoMfrName) - 1) - offset));
// copy data
tmos_memcpy(pValue, &devInfoMfrName[offset], *pLen);
}
break;
case IEEE_11073_CERT_DATA_UUID:
// verify offset
if(offset >= sizeof(devInfo11073Cert))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length
*pLen = MIN(maxLen, (sizeof(devInfo11073Cert) - offset));
// copy data
tmos_memcpy(pValue, &devInfo11073Cert[offset], *pLen);
}
break;
case PNP_ID_UUID:
// verify offset
if(offset >= sizeof(devInfoPnpId))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length
*pLen = MIN(maxLen, (sizeof(devInfoPnpId) - offset));
// copy data
tmos_memcpy(pValue, &devInfoPnpId[offset], *pLen);
}
break;
default:
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
return (status);
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,172 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : battservice.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description :
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef BATTSERVICE_H
#define BATTSERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// Battery Service Get/Set Parameters
#define BATT_PARAM_LEVEL 0
#define BATT_PARAM_CRITICAL_LEVEL 1
#define BATT_PARAM_SERVICE_HANDLE 2
#define BATT_PARAM_BATT_LEVEL_IN_REPORT 3
// Callback events
#define BATT_LEVEL_NOTI_ENABLED 1
#define BATT_LEVEL_NOTI_DISABLED 2
// HID Report IDs for the service
#define HID_RPT_ID_BATT_LEVEL_IN 4 // Battery Level input report ID
/*********************************************************************
* TYPEDEFS
*/
// Battery Service callback function
typedef void (*battServiceCB_t)(uint8_t event);
// Battery measure HW setup function
typedef void (*battServiceSetupCB_t)(void);
// Battery measure percentage calculation function
typedef uint8_t (*battServiceCalcCB_t)(uint16_t adcVal);
// Battery measure HW teardown function
typedef void (*battServiceTeardownCB_t)(void);
/*********************************************************************
* MACROS
*/
/*********************************************************************
* Profile Callbacks
*/
/*********************************************************************
* API FUNCTIONS
*/
/*********************************************************************
* @fn Batt_AddService
*
* @brief Initializes the Battery service by registering
* GATT attributes with the GATT server.
*
* @return Success or Failure
*/
extern bStatus_t Batt_AddService(void);
/*********************************************************************
* @fn Batt_Register
*
* @brief Register a callback function with the Battery Service.
*
* @param pfnServiceCB - Callback function.
*
* @return None.
*/
extern void Batt_Register(battServiceCB_t pfnServiceCB);
/*********************************************************************
* @fn Batt_SetParameter
*
* @brief Set a Battery Service parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
extern bStatus_t Batt_SetParameter(uint8_t param, uint8_t len, void *value);
/*********************************************************************
* @fn Batt_GetParameter
*
* @brief Get a Battery parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
extern bStatus_t Batt_GetParameter(uint8_t param, void *value);
/*********************************************************************
* @fn Batt_MeasLevel
*
* @brief Measure the battery level and update the battery
* level value in the service characteristics. If
* the battery level-state characteristic is configured
* for notification and the battery level has changed
* since the last measurement, then a notification
* will be sent.
*
* @return Success or Failure
*/
extern bStatus_t Batt_MeasLevel(void);
/*********************************************************************
* @fn Batt_Setup
*
* @brief Set up which ADC source is to be used. Defaults to VDD/3.
*
* @param adc_ch - ADC Channel, e.g. HAL_ADC_CHN_AIN6
* @param minVal - max battery level
* @param maxVal - min battery level
* @param sCB - HW setup callback
* @param tCB - HW tear down callback
* @param cCB - percentage calculation callback
*
* @return none.
*/
extern void Batt_Setup(uint8_t adc_ch, uint16_t minVal, uint16_t maxVal,
battServiceSetupCB_t sCB, battServiceTeardownCB_t tCB,
battServiceCalcCB_t cCB);
/*********************************************************************
* @fn Batt_HandleConnStatusCB
*
* @brief Battery Service link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/
void Batt_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* BATTSERVICE_H */
@@ -0,0 +1,231 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : cyclingservice.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description :
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef CYCLINGSERVICE_H
#define CYCLINGSERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
#define CYCLING_SERVICE 0x00000001
//ATT Error Codes
#define CSC_ERR_PROC_IN_PROGRESS 0x80
#define CSC_ERR_CCC_IMPROPER_CFG 0x81
#define CSC_SUCCESS 1
#define CSC_OPCODE_NOT_SUPPORTED 2
#define CSC_INVALID_PARAMETER 3
//CSC Service Parameters
#define CSC_MEAS 1
#define CSC_MEAS_CHAR_CFG 2
#define CSC_FEATURE 3
#define CSC_SENS_LOC 4
#define CSC_COMMAND 5
#define CSC_COMMAND_CHAR_CFG 6
#define CSC_AVAIL_SENS_LOCS 7
//CSC Fields
#define CSC_WHEEL_REV_PRESENT 0x01
#define CSC_CRANK_REV_PRESENT 0x02
//CSC SUPPORTED FEATURES
#define CSC_NO_SUPPORT 0x00
#define CSC_WHEEL_REV_SUPP 0x01
#define CSC_CRANK_REV_SUPP 0x02
#define CSC_MULTI_SENS_SUPP 0x04
#define CSC_FULL_SUPPORT 0x07
//CSC Censor Locations
#define CSC_SENSOR_LOC_OTHER 0
#define CSC_SENSOR_LOC_TOP_OF_SHOE 1
#define CSC_SENSOR_LOC_IN_SHOE 2
#define CSC_SENSOR_LOC_HIP 3
#define CSC_SENSOR_LOC_FRONT_WHEEL 4
#define CSC_SENSOR_LOC_LEFT_CRANK 5
#define CSC_SENSOR_LOC_RIGHT_CRANK 6
#define CSC_SENSOR_LOC_LEFT_PEDAL 7
#define CSC_SENSOR_LOC_RIGHT_PEDAL 8
#define CSC_SENSOR_LOC_FRONT_HUB 9
#define CSC_SENSOR_LOC_REAR_DROPOUT 10
#define CSC_SENSOR_LOC_CHAINSTAY 11
#define CSC_SENSOR_LOC_REAR_WHEEL 12
#define CSC_SENSOR_LOC_REAR_HUB 13
//Spec says there are 14 possible.
#define CSC_MAX_SENSOR_LOCS 14
//CSC Commands
#define CSC_SET_CUMM_VAL 1
#define CSC_START_SENS_CALIB 2
#define CSC_UPDATE_SENS_LOC 3
#define CSC_REQ_SUPP_SENS_LOC 4
#define CSC_COMMAND_RSP 16
// Values for flags
#define CSC_FLAGS_AT_REST 0x00
#define CSC_FLAGS_SPEED 0x01
#define CSC_FLAGS_CADENCE 0x02
#define CSC_FLAGS_SPEED_CADENCE 0x03
#define DEFAULT_NOTI_INTERVAL 1000 // in milliseconds
#define VALUE_ROLL_OVER 64000 // in milliseconds
// Callback events
#define CSC_CMD_SET_CUMM_VAL 1
#define CSC_CMD_START_SENS_CALIB 2
#define CSC_CMD_UPDATE_SENS_LOC 3
#define CSC_MEAS_NOTI_ENABLED 4
#define CSC_MEAS_NOTI_DISABLED 5
#define CSC_READ_ATTR 6
#define CSC_WRITE_ATTR 7
/*********************************************************************
* TYPEDEFS
*/
// CSC service callback function
typedef void (*cyclingServiceCB_t)(uint8_t event, uint32_t *pNewCummVal);
/*********************************************************************
* MACROS
*/
/*********************************************************************
* Profile Callbacks
*/
/*********************************************************************
* API FUNCTIONS
*/
/*********************************************************************
* @fn CyclingService_Init
*
* @brief collect the TMOS task ID.
*
* @param task_id - TMOS task ID.
*
* @return none
*/
extern void CyclingService_Init(void);
/*********************************************************************
* @fn CyclingService_ProcessEvent
*
* @brief process incoming event.
*
* @param task_id - TMOS task id.
*
* @param events - event bit(s) set for the task(s)
*
* @return remaining event bits
*/
extern uint16_t CyclingService_ProcessEvent(uint8_t task_id, uint16_t events);
/*
* @fn Cycling_AddService
*
* @brief Initializes the CSC service by registering
* GATT attributes with the GATT server.
*
* @param services - services to add. This is a bit map and can
* contain more than one service.
*/
extern bStatus_t Cycling_AddService(uint32_t services);
/*
* @fn Cycling_Register
*
* @brief Register a callback function with the
* CSC Service.
*
* @param pfnServiceCB - Callback function.
*
* @return none
*/
extern void Cycling_Register(cyclingServiceCB_t pfnServiceCB);
/*
* @fn Cycling_SetParameter
*
* @brief Set a CSC parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*/
extern bStatus_t Cycling_SetParameter(uint8_t param, uint8_t len, void *value);
/*********************************************************************
* @fn Cycling_GetParameter
*
* @brief Get a CSC parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t Cycling_GetParameter(uint8_t param, void *value);
/*********************************************************************
* @fn Cycling_MeasNotify
*
* @brief Send a notification containing a CSC
* measurement.
*
* @param connHandle - connection handle
* @param pNoti - pointer to notification structure
*
* @return Success or Failure
*/
extern bStatus_t Cycling_MeasNotify(uint16_t connHandle, attHandleValueNoti_t *pNoti);
/*********************************************************************
* @fn Cycling_HandleConnStatusCB
*
* @brief CSC Service link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/
extern void Cycling_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,109 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : devinfoservice.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description :
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef DEVINFOSERVICE_H
#define DEVINFOSERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// Device Information Service Parameters
#define DEVINFO_SYSTEM_ID 0
#define DEVINFO_MODEL_NUMBER 1
#define DEVINFO_SERIAL_NUMBER 2
#define DEVINFO_FIRMWARE_REV 3
#define DEVINFO_HARDWARE_REV 4
#define DEVINFO_SOFTWARE_REV 5
#define DEVINFO_MANUFACTURER_NAME 6
#define DEVINFO_11073_CERT_DATA 7
#define DEVINFO_PNP_ID 8
// IEEE 11073 authoritative body values
#define DEVINFO_11073_BODY_EMPTY 0
#define DEVINFO_11073_BODY_IEEE 1
#define DEVINFO_11073_BODY_CONTINUA 2
#define DEVINFO_11073_BODY_EXP 254
// System ID length
#define DEVINFO_SYSTEM_ID_LEN 8
// PnP ID length
#define DEVINFO_PNP_ID_LEN 7
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* Profile Callbacks
*/
/*********************************************************************
* API FUNCTIONS
*/
/*
* DevInfo_AddService- Initializes the Device Information service by registering
* GATT attributes with the GATT server.
*
*/
extern bStatus_t DevInfo_AddService(void);
/*********************************************************************
* @fn DevInfo_SetParameter
*
* @brief Set a Device Information parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
bStatus_t DevInfo_SetParameter(uint8_t param, uint16_t len, void *value);
/*
* DevInfo_GetParameter - Get a Device Information parameter.
*
* param - Profile parameter ID
* value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*/
extern bStatus_t DevInfo_GetParameter(uint8_t param, void *value);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* DEVINFOSERVICE_H */
@@ -0,0 +1,441 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : hiddev.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description :
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef HIDDEV_H
#define HIDDEV_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// HID Device Parameters
#define HIDDEV_ERASE_ALLBONDS 0 // Erase all of the bonded devices. Write Only. No Size.
// HID read/write operation
#define HID_DEV_OPER_WRITE 0 // Write operation
#define HID_DEV_OPER_READ 1 // Read operation
#define HID_DEV_OPER_ENABLE 2 // Notification enabled for report ID
#define HID_DEV_OPER_DISABLE 3 // Notifications disabled for report ID
// HID callback events
#define HID_DEV_SUSPEND_EVT 0 // HID suspend
#define HID_DEV_EXIT_SUSPEND_EVT 1 // HID exit suspend
#define HID_DEV_SET_BOOT_EVT 2 // HID set boot mode
#define HID_DEV_SET_REPORT_EVT 3 // HID set report mode
/* HID Report type */
#define HID_REPORT_TYPE_INPUT 1
#define HID_REPORT_TYPE_OUTPUT 2
#define HID_REPORT_TYPE_FEATURE 3
/* HID information flags */
#define HID_FLAGS_REMOTE_WAKE 0x01 // RemoteWake
#define HID_FLAGS_NORMALLY_CONNECTABLE 0x02 // NormallyConnectable
/* Control point commands */
#define HID_CMD_SUSPEND 0x00 // Suspend
#define HID_CMD_EXIT_SUSPEND 0x01 // Exit Suspend
/* HID protocol mode values */
#define HID_PROTOCOL_MODE_BOOT 0x00 // Boot Protocol Mode
#define HID_PROTOCOL_MODE_REPORT 0x01 // Report Protocol Mode
/* Attribute value lengths */
#define HID_PROTOCOL_MODE_LEN 1 // HID Protocol Mode
#define HID_INFORMATION_LEN 4 // HID Information
#define HID_REPORT_REF_LEN 2 // HID Report Reference Descriptor
#define HID_EXT_REPORT_REF_LEN 2 // External Report Reference Descriptor
// HID Keyboard/Keypad Usage IDs (subset of the codes available in the USB HID Usage Tables spec)
#define HID_KEYBOARD_RESERVED 0 // 0x00 - No event inidicated
#define HID_KEYBOARD_A 4 // 0x04 - Keyboard a and A
#define HID_KEYBOARD_B 5 // 0x05 - Keyboard b and B
#define HID_KEYBOARD_C 6 // 0x06 - Keyboard c and C
#define HID_KEYBOARD_D 7 // 0x07 - Keyboard d and D
#define HID_KEYBOARD_E 8 // 0x08 - Keyboard e and E
#define HID_KEYBOARD_F 9 // 0x09 - Keyboard f and F
#define HID_KEYBOARD_G 10 // 0x0A - Keyboard g and G
#define HID_KEYBOARD_H 11 // 0x0B - Keyboard h and H
#define HID_KEYBOARD_I 12 // 0x0C - Keyboard i and I
#define HID_KEYBOARD_J 13 // 0x0D - Keyboard j and J
#define HID_KEYBOARD_K 14 // 0x0E - Keyboard k and K
#define HID_KEYBOARD_L 15 // 0x0F - Keyboard l and L
#define HID_KEYBOARD_M 16 // 0x10 - Keyboard m and M
#define HID_KEYBOARD_N 17 // 0x11 - Keyboard n and N
#define HID_KEYBOARD_O 18 // 0x12 - Keyboard o and O
#define HID_KEYBOARD_P 19 // 0x13 - Keyboard p and p
#define HID_KEYBOARD_Q 20 // 0x14 - Keyboard q and Q
#define HID_KEYBOARD_R 21 // 0x15 - Keyboard r and R
#define HID_KEYBOARD_S 22 // 0x16 - Keyboard s and S
#define HID_KEYBOARD_T 23 // 0x17 - Keyboard t and T
#define HID_KEYBOARD_U 24 // 0x18 - Keyboard u and U
#define HID_KEYBOARD_V 25 // 0x19 - Keyboard v and V
#define HID_KEYBOARD_W 26 // 0x1A - Keyboard w and W
#define HID_KEYBOARD_X 27 // 0x1B - Keyboard x and X
#define HID_KEYBOARD_Y 28 // 0x1C - Keyboard y and Y
#define HID_KEYBOARD_Z 29 // 0x1D - Keyboard z and Z
#define HID_KEYBOARD_1 30 // 0x1E - Keyboard 1 and !
#define HID_KEYBOARD_2 31 // 0x1F - Keyboard 2 and @
#define HID_KEYBOARD_3 32 // 0x20 - Keyboard 3 and #
#define HID_KEYBOARD_4 33 // 0x21 - Keyboard 4 and %
#define HID_KEYBOARD_5 34 // 0x22 - Keyboard 5 and %
#define HID_KEYBOARD_6 35 // 0x23 - Keyboard 6 and ^
#define HID_KEYBOARD_7 36 // 0x24 - Keyboard 7 and &
#define HID_KEYBOARD_8 37 // 0x25 - Keyboard 8 and *
#define HID_KEYBOARD_9 38 // 0x26 - Keyboard 9 and (
#define HID_KEYBOARD_0 39 // 0x27 - Keyboard 0 and )
#define HID_KEYBOARD_RETURN 40 // 0x28 - Keyboard Return (ENTER)
#define HID_KEYBOARD_ESCAPE 41 // 0x29 - Keyboard ESCAPE
#define HID_KEYBOARD_DELETE 42 // 0x2A - Keyboard DELETE (Backspace)
#define HID_KEYBOARD_TAB 43 // 0x2B - Keyboard Tab
#define HID_KEYBOARD_SPACEBAR 44 // 0x2C - Keyboard Spacebar
#define HID_KEYBOARD_MINUS 45 // 0x2D - Keyboard - and (underscore)
#define HID_KEYBOARD_EQUAL 46 // 0x2E - Keyboard = and +
#define HID_KEYBOARD_LEFT_BRKT 47 // 0x2F - Keyboard [ and {
#define HID_KEYBOARD_RIGHT_BRKT 48 // 0x30 - Keyboard ] and }
#define HID_KEYBOARD_BACK_SLASH 49 // 0x31 - Keyboard \ and |
#define HID_KEYBOARD_SEMI_COLON 51 // 0x33 - Keyboard ; and :
#define HID_KEYBOARD_SGL_QUOTE 52 // 0x34 - Keyboard ' and "
#define HID_KEYBOARD_GRV_ACCENT 53 // 0x35 - Keyboard Grave Accent and Tilde
#define HID_KEYBOARD_COMMA 54 // 0x36 - Keyboard , and <
#define HID_KEYBOARD_DOT 55 // 0x37 - Keyboard . and >
#define HID_KEYBOARD_FWD_SLASH 56 // 0x38 - Keyboard / and ?
#define HID_KEYBOARD_CAPS_LOCK 57 // 0x39 - Keyboard Caps Lock
#define HID_KEYBOARD_F1 58 // 0x3A - Keyboard F1
#define HID_KEYBOARD_F2 59 // 0x3B - Keyboard F2
#define HID_KEYBOARD_F3 60 // 0x3C - Keyboard F3
#define HID_KEYBOARD_F4 61 // 0x3D - Keyboard F4
#define HID_KEYBOARD_F5 62 // 0x3E - Keyboard F5
#define HID_KEYBOARD_F6 63 // 0x3F - Keyboard F6
#define HID_KEYBOARD_F7 64 // 0x40 - Keyboard F7
#define HID_KEYBOARD_F8 65 // 0x41 - Keyboard F8
#define HID_KEYBOARD_F9 66 // 0x42 - Keyboard F9
#define HID_KEYBOARD_F10 67 // 0x43 - Keyboard F10
#define HID_KEYBOARD_F11 68 // 0x44 - Keyboard F11
#define HID_KEYBOARD_F12 69 // 0x45 - Keyboard F12
#define HID_KEYBOARD_PRNT_SCREEN 70 // 0x46 - Keyboard Print Screen
#define HID_KEYBOARD_SCROLL_LOCK 71 // 0x47 - Keyboard Scroll Lock
#define HID_KEYBOARD_PAUSE 72 // 0x48 - Keyboard Pause
#define HID_KEYBOARD_INSERT 73 // 0x49 - Keyboard Insert
#define HID_KEYBOARD_HOME 74 // 0x4A - Keyboard Home
#define HID_KEYBOARD_PAGE_UP 75 // 0x4B - Keyboard PageUp
#define HID_KEYBOARD_DELETE_FWD 76 // 0x4C - Keyboard Delete Forward
#define HID_KEYBOARD_END 77 // 0x4D - Keyboard End
#define HID_KEYBOARD_PAGE_DOWN 78 // 0x4E - Keyboard PageDown
#define HID_KEYBOARD_RIGHT_ARROW 79 // 0x4F - Keyboard RightArrow
#define HID_KEYBOARD_LEFT_ARROW 80 // 0x50 - Keyboard LeftArrow
#define HID_KEYBOARD_DOWN_ARROW 81 // 0x51 - Keyboard DownArrow
#define HID_KEYBOARD_UP_ARROW 82 // 0x52 - Keyboard UpArrow
#define HID_KEYBPAD_NUM_LOCK 83 // 0x53 - Keypad Num Lock and Clear
#define HID_KEYBPAD_DIVIDE 84 // 0x54 - Keypad /
#define HID_KEYBOARD_MULTIPLY 85 // 0x55 - Keypad *
#define HID_KEYBOARD_SUBTRACT 86 // 0x56 - Keypad -
#define HID_KEYBPAD_ADD 87 // 0x57 - Keypad +
#define HID_KEYBPAD_ENTER 88 // 0x58 - Keypad ENTER
#define HID_KEYBPAD_1 89 // 0x59 - Keypad 1 and End
#define HID_KEYBPAD_2 90 // 0x5A - Keypad 2 and Down Arrow
#define HID_KEYBPAD_3 91 // 0x5B - Keypad 3 and PageDn
#define HID_KEYBPAD_4 92 // 0x5C - Keypad 4 and Lfet Arrow
#define HID_KEYBPAD_5 93 // 0x5D - Keypad 5
#define HID_KEYBPAD_6 94 // 0x5E - Keypad 6 and Right Arrow
#define HID_KEYBPAD_7 95 // 0x5F - Keypad 7 and Home
#define HID_KEYBPAD_8 96 // 0x60 - Keypad 8 and Up Arrow
#define HID_KEYBPAD_9 97 // 0x61 - Keypad 9 and PageUp
#define HID_KEYBPAD_0 98 // 0x62 - Keypad 0 and Insert
#define HID_KEYBPAD_DOT 99 // 0x63 - Keypad . and Delete
#define HID_KEYBOARD_MUTE 127 // 0x7F - Keyboard Mute
#define HID_KEYBOARD_VOLUME_UP 128 // 0x80 - Keyboard Volume up
#define HID_KEYBOARD_VOLUME_DOWN 129 // 0x81 - Keyboard Volume down
#define HID_KEYBOARD_LEFT_CTRL 224 // 0xE0 - Keyboard LeftContorl
#define HID_KEYBOARD_LEFT_SHIFT 225 // 0xE1 - Keyboard LeftShift
#define HID_KEYBOARD_LEFT_ALT 226 // 0xE2 - Keyboard LeftAlt
#define HID_KEYBOARD_LEFT_GUI 227 // 0xE3 - Keyboard LeftGUI
#define HID_KEYBOARD_RIGHT_CTRL 228 // 0xE4 - Keyboard LeftContorl
#define HID_KEYBOARD_RIGHT_SHIFT 229 // 0xE5 - Keyboard LeftShift
#define HID_KEYBOARD_RIGHT_ALT 230 // 0xE6 - Keyboard LeftAlt
#define HID_KEYBOARD_RIGHT_GUI 231 // 0xE7 - Keyboard RightGUI
#define HID_MOUSE_BUTTON_LEFT 253
#define HID_MOUSE_BUTTON_MIDDLE 254
#define HID_MOUSE_BUTTON_RIGHT 255
// HID Consumer Usage IDs (subset of the codes available in the USB HID Usage Tables spec)
#define HID_CONSUMER_POWER 48 // 0x30 - Power
#define HID_CONSUMER_RESET 49 // 0x31 - Reset
#define HID_CONSUMER_SLEEP 50 // 0x32 - Sleep
#define HID_CONSUMER_MENU 64 // 0x40 - Menu
#define HID_CONSUMER_SELECTION 128 // 0x80 - Selection
#define HID_CONSUMER_ASSIGN_SEL 129 // 0x81 - Assign Selection
#define HID_CONSUMER_MODE_STEP 130 // 0x82 - Mode Step
#define HID_CONSUMER_RECALL_LAST 131 // 0x83 - Recall Last
#define HID_CONSUMER_QUIT 148 // 0x94 - Quit
#define HID_CONSUMER_HELP 149 // 0x95 - Help
#define HID_CONSUMER_CHANNEL_UP 156 // 0x9C - Channel Increment
#define HID_CONSUMER_CHANNEL_DOWN 157 // 0x9D - Channel Decrement
#define HID_CONSUMER_PLAY 176 // 0xB0 - Play
#define HID_CONSUMER_PAUSE 177 // 0xB1 - Pause
#define HID_CONSUMER_RECORD 178 // 0xB2 - Record
#define HID_CONSUMER_FAST_FORWARD 179 // 0xB3 - Fast Forward
#define HID_CONSUMER_REWIND 180 // 0xB4 - Rewind
#define HID_CONSUMER_SCAN_NEXT_TRK 181 // 0xB5 - Scan Next Track
#define HID_CONSUMER_SCAN_PREV_TRK 182 // 0xB6 - Scan Previous Track
#define HID_CONSUMER_STOP 183 // 0xB7 - Stop
#define HID_CONSUMER_EJECT 184 // 0xB8 - Eject
#define HID_CONSUMER_RANDOM_PLAY 185 // 0xB9 - Random Play
#define HID_CONSUMER_SELECT_DISC 186 // 0xBA - Select Disk
#define HID_CONSUMER_ENTER_DISC 187 // 0xBB - Enter Disc
#define HID_CONSUMER_REPEAT 188 // 0xBC - Repeat
#define HID_CONSUMER_STOP_EJECT 204 // 0xCC - Stop/Eject
#define HID_CONSUMER_PLAY_PAUSE 205 // 0xCD - Play/Pause
#define HID_CONSUMER_PLAY_SKIP 206 // 0xCE - Play/Skip
#define HID_CONSUMER_VOLUME 224 // 0xE0 - Volume
#define HID_CONSUMER_BALANCE 225 // 0xE1 - Balance
#define HID_CONSUMER_MUTE 226 // 0xE2 - Mute
#define HID_CONSUMER_BASS 227 // 0xE3 - Bass
#define HID_CONSUMER_VOLUME_UP 233 // 0xE9 - Volume Increment
#define HID_CONSUMER_VOLUME_DOWN 234 // 0xEA - Volume Decrement
/*********************************************************************
* TYPEDEFS
*/
// HID report mapping table
typedef struct
{
uint16_t handle; // Handle of report characteristic
uint16_t cccdHandle; // Handle of CCCD for report characteristic
uint8_t id; // Report ID
uint8_t type; // Report type
uint8_t mode; // Protocol mode (report or boot)
} hidRptMap_t;
// HID dev configuration structure
typedef struct
{
uint32_t idleTimeout; // Idle timeout in milliseconds
uint8_t hidFlags; // HID feature flags
} hidDevCfg_t;
/*********************************************************************
* Global Variables
*/
// These variables are defined in the service .c file that uses HID Dev
// HID report map length
extern uint16_t hidReportMapLen;
// HID protocol mode
extern uint8_t hidProtocolMode;
/*********************************************************************
* Profile Callbacks
*/
// HID Report callback
typedef uint8_t (*hidDevReportCB_t)(uint8_t id, uint8_t type, uint16_t uuid,
uint8_t oper, uint16_t *pLen, uint8_t *pData);
// HID event callback
typedef void (*hidDevEvtCB_t)(uint8_t evt);
// HID passcode callback
typedef void (*hidDevPasscodeCB_t)(uint8_t *deviceAddr, uint16_t connectionHandle,
uint8_t uiInputs, uint8_t uiOutputs);
typedef struct
{
hidDevReportCB_t reportCB;
hidDevEvtCB_t evtCB;
hidDevPasscodeCB_t passcodeCB;
gapRolesStateNotify_t pfnStateChange; //!< Whenever the device changes state
} hidDevCB_t;
/*********************************************************************
* @fn HidDev_Init
*
* @brief Initialization function for the Hid Dev Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
extern void HidDev_Init(void);
/*********************************************************************
* @fn HidDev_ProcessEvent
*
* @brief Hid Dev 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
*/
extern uint16_t HidDev_ProcessEvent(uint8_t task_id, uint16_t events);
/*********************************************************************
* @fn HidDev_Register
*
* @brief Register a callback function with HID Dev.
*
* @param pCfg - Parameter configuration.
* @param pCBs - Callback function.
*
* @return None.
*/
extern void HidDev_Register(hidDevCfg_t *pCfg, hidDevCB_t *pCBs);
/*********************************************************************
* @fn HidDev_RegisterReports
*
* @brief Register the report table with HID Dev.
*
* @param numReports - Length of report table.
* @param pRpt - Report table.
*
* @return None.
*/
extern void HidDev_RegisterReports(uint8_t numReports, hidRptMap_t *pRpt);
/*********************************************************************
* @fn HidDev_Report
*
* @brief Send a HID report.
*
* @param id - HID report ID.
* @param type - HID report type.
* @param len - Length of report.
* @param pData - Report data.
*
* @return None.
*/
extern uint8_t HidDev_Report(uint8_t id, uint8_t type, uint8_t len, uint8_t *pData);
/*********************************************************************
* @fn HidDev_Close
*
* @brief Close the connection or stop advertising.
*
* @return None.
*/
extern void HidDev_Close(void);
/*********************************************************************
* @fn HidDev_SetParameter
*
* @brief Set a HID Dev parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to right
* @param pValue - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
extern bStatus_t HidDev_SetParameter(uint8_t param, uint8_t len, void *pValue);
/*********************************************************************
* @fn HidDev_GetParameter
*
* @brief Get a HID Dev parameter.
*
* @param param - Profile parameter ID
* @param pValue - pointer to data to get. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16_t will be cast to
* uint16_t pointer).
*
* @return bStatus_t
*/
extern bStatus_t HidDev_GetParameter(uint8_t param, void *pValue);
/*********************************************************************
* @fn HidDev_PasscodeRsp
*
* @brief Respond to a passcode request.
*
* @param status - SUCCESS if passcode is available, otherwise
* see @ref SMP_PAIRING_FAILED_DEFINES.
* @param passcode - integer value containing the passcode.
*
* @return none
*/
extern void HidDev_PasscodeRsp(uint8_t status, uint32_t passcode);
/*********************************************************************
* @fn HidDev_ReadAttrCB
*
* @brief HID Dev attribute read callback.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be read
* @param pLen - length of data to be read
* @param offset - offset of the first octet to be read
* @param maxLen - maximum length of data to be read
*
* @return Success or Failure
*/
extern bStatus_t HidDev_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
/*********************************************************************
* @fn HidDev_WriteAttrCB
*
* @brief HID Dev attribute read callback.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be written
* @param len - length of data
* @param offset - offset of the first octet to be written
*
* @return Success or Failure
*/
extern bStatus_t HidDev_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* HIDDEV_H */