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
+163
View File
@@ -0,0 +1,163 @@
<?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="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" 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.2004345028" 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.355125912" 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.112280767" 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.983643118" 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:/BackupUpgrade_OTA}/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="BLE_BUFF_MAX_LEN=251"/>
<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}/Ld/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 IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.1069514939" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="wchble"/>
<listOptionValue builtIn="false" value="m"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.64599303" 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">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice.1732540555" name="Output file format (-O)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice.ihex" valueType="enumerated"/>
</tool>
<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.disassemble.578354718" name="Disassemble (--disassemble|-d)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble" 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>
<fileInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.1963756574" name="Link.ld" rcbsApplicability="disable" resourcePath="HAL/Link.ld" toolsToInvoke=""/>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="APP"/>
<entry excluding="Link.ld|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="Ld"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Profile"/>
<entry excluding="Ld|Startup" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="SRC"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/>
</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>BackupUpgrade_OTA</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>1617352987709</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,74 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.c
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : Main Interrupt Service Routines.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ch32v20x_it.h"
#include "CONFIG.h"
/*********************************************************************
* LOCAL FUNCTIONS
*/
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void LLE_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn NMI_Handler
*
* @brief This function handles NMI exception.
*
* @return None
*/
void NMI_Handler(void)
{
}
/*********************************************************************
* @fn HardFault_Handler
*
* @brief This function handles Hard Fault exception.
*
* @return None
*/
void HardFault_Handler(void)
{
while(1)
{
}
}
/*********************************************************************
* @fn BB_IRQHandler
*
* @brief BB Interrupt for BLE.
*
* @return None
*/
void BB_IRQHandler(void)
{
BB_IRQLibHandler();
}
/*********************************************************************
* @fn LLE_IRQHandler
*
* @brief LLE Interrupt for BLE.
*
* @return None
*/
void LLE_IRQHandler(void)
{
LLE_IRQLibHandler();
}
@@ -0,0 +1,37 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_conf.h
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : Library configuration file.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CH32V20x_CONF_H
#define __CH32V20x_CONF_H
#include "ch32v20x_adc.h"
#include "ch32v20x_bkp.h"
#include "ch32v20x_can.h"
#include "ch32v20x_crc.h"
#include "ch32v20x_dbgmcu.h"
#include "ch32v20x_dma.h"
#include "ch32v20x_exti.h"
#include "ch32v20x_flash.h"
#include "ch32v20x_gpio.h"
#include "ch32v20x_i2c.h"
#include "ch32v20x_iwdg.h"
#include "ch32v20x_pwr.h"
#include "ch32v20x_rcc.h"
#include "ch32v20x_rtc.h"
#include "ch32v20x_spi.h"
#include "ch32v20x_tim.h"
#include "ch32v20x_usart.h"
#include "ch32v20x_wwdg.h"
#include "ch32v20x_it.h"
#include "ch32v20x_misc.h"
#endif /* __CH32V20x_CONF_H */
@@ -0,0 +1,18 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.h
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : This file contains the headers of the interrupt handlers.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CH32V20x_IT_H
#define __CH32V20x_IT_H
#include "debug.h"
#endif /* __CH32V20x_IT_H */
@@ -0,0 +1,111 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ota.h
* Author : WCH
* Version : V1.10
* Date : 2018/12/14
* Description : oad相关配置定义
*********************************************************************************
* 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 __OTA_H
#define __OTA_H
/* ------------------------------------------------------------------------------------------------
* OTA FLASH
* ------------------------------------------------------------------------------------------------
*/
/* 整个用户code区分成3块,16K,216K,216K,分别叫做imageIAP 、imageA(用户代码区),imageB(备份代码区)和imageIAP */
/* FLASH定义 */
#define FLASH_PAGE_SIZE 256
#define FLASH_BLOCK_SIZE 4096
#define IMAGE_SIZE 216 * 1024
/* imageIAP定义 */
#define IMAGE_IAP_FLAG 0x03
#define IMAGE_IAP_START_ADD 0x08000000
#define IMAGE_IAP_SIZE 16 * 1024
/* imageA定义 */
#define IMAGE_A_FLAG 0x01
#define IMAGE_A_START_ADD (IMAGE_IAP_START_ADD + IMAGE_IAP_SIZE)
#define IMAGE_A_SIZE IMAGE_SIZE
/* imageB定义 */
#define IMAGE_B_FLAG 0x02
#define IMAGE_B_START_ADD (IMAGE_A_START_ADD + IMAGE_SIZE)
#define IMAGE_B_SIZE IMAGE_SIZE
/* IAP定义 */
/* 以下为IAP下载命令定义 */
#define CMD_IAP_PROM 0x80 // IAP编程命令
#define CMD_IAP_ERASE 0x81 // IAP擦除命令
#define CMD_IAP_VERIFY 0x82 // IAP校验命令
#define CMD_IAP_END 0x83 // IAP结束标志
#define CMD_IAP_INFO 0x84 // IAP获取设备信息
/* 数据帧长度定义 */
#define IAP_LEN 247
/* 存放在DataFlash地址,不能占用蓝牙的位置 */
#define OTA_DATAFLASH_ADD 0x08077000
/* 存放在DataFlash里的OTA信息 */
typedef struct
{
unsigned char ImageFlag; //记录的当前的image标志
unsigned char flag[3];
} OTADataFlashInfo_t;
/* OTA IAP通讯协议定义 */
/* 地址使用4倍偏移 */
typedef union
{
struct
{
unsigned char cmd; /* 命令码 0x81 */
unsigned char len; /* 后续数据长度 */
unsigned char addr[2]; /* 擦除地址 */
unsigned char block_num[2]; /* 擦除块数 */
} erase; /* 擦除命令 */
struct
{
unsigned char cmd; /* 命令码 0x83 */
unsigned char len; /* 后续数据长度 */
unsigned char status[2]; /* 两字节状态,保留 */
} end; /* 结束命令 */
struct
{
unsigned char cmd; /* 命令码 0x82 */
unsigned char len; /* 后续数据长度 */
unsigned char addr[2]; /* 校验地址 */
unsigned char buf[IAP_LEN - 4]; /* 校验数据 */
} verify; /* 校验命令 */
struct
{
unsigned char cmd; /* 命令码 0x80 */
unsigned char len; /* 后续数据长度 */
unsigned char addr[2]; /* 地址 */
unsigned char buf[IAP_LEN - 4]; /* 后续数据 */
} program; /* 编程命令 */
struct
{
unsigned char cmd; /* 命令码 0x84 */
unsigned char len; /* 后续数据长度 */
unsigned char buf[IAP_LEN - 2]; /* 后续数据 */
} info; /* 编程命令 */
struct
{
unsigned char buf[IAP_LEN]; /* 接收数据包*/
} other;
} OTA_IAP_CMD_t;
/* 记录当前的Image */
extern unsigned char CurrImageFlag;
#endif
@@ -0,0 +1,63 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : peripheral.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 PERIPHERAL_H
#define PERIPHERAL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// Simple BLE Peripheral Task Events
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_PERIODIC_EVT 0x0002
#define OTA_FLASH_ERASE_EVT 0x0004 //OTA Flash²Á³ýÈÎÎñ
/*********************************************************************
* MACROS
*/
/*********************************************************************
* FUNCTIONS
*/
/*
* Task Initialization for the BLE Application
*/
extern void Peripheral_Init(void);
/*
* Task Event Processor for the BLE Application
*/
extern uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events);
/*
* Read flash
*/
void FLASH_read(uint32_t addr, uint8_t *pData, uint32_t len);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif
@@ -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,841 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : Peripheral.C
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : Peripheral slave multi-connection application, initialize
* broadcast connection parameters, then broadcast, after connecting
* to the host, request to update connection parameters,
* and transmit data through custom services.
*********************************************************************************
* 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 "GATTprofile.h"
#include "Peripheral.h"
#include "OTA.h"
#include "OTAprofile.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 1000
// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL 160
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 12
// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT 1000
// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE
// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL 6
// Company Identifier: WCH
#define WCH_COMPANY_ID 0x07D7
#define INVALID_CONNHANDLE 0xFFFF
// Length of bd addr as a string
#define B_ADDR_STR_LEN 15
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8_t Peripheral_TaskID = 0xff; // Task ID for internal task/event processing
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[31] = {
// complete name
0x12, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
's', 'i', 'm', 'p', 'l', 'e', ' ', 'P', 'e', 'r', 'i', 'p', 'h', 'e', 'r', 'a', 'l',
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8_t advertData[] = {
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";
// OTA IAP VARIABLES
/* OTA communication frame */
OTA_IAP_CMD_t iap_rec_data;
/* OTA analysis results */
uint32_t OpParaDataLen = 0;
uint32_t OpAdd = 0;
uint16_t block_buf_len=0;
uint32_t prom_addr=0;
/* Flash data temporary storage */
__attribute__((aligned(8))) uint8_t block_buf[512];
/* IMAGE jump function address definition */
typedef int (*pImageTaskFn)(void);
pImageTaskFn user_image_tasks;
/* Flash erase */
uint32_t EraseAdd = 0; //Removal address
uint32_t EraseBlockNum = 0; //Number of blocks that need to be erased
uint32_t EraseBlockCnt = 0; //Scratching block count
/* FLASH verification status */
uint8_t VerifyStatus = 0;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
static void performPeriodicTask(void);
static void simpleProfileChangeCB(uint8_t paramID);
void OTA_IAPReadDataComplete(unsigned char index);
void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len);
void Rec_OTA_IAP_DataDeal(void);
void OTA_IAP_SendCMDDealSta(uint8_t deal_status);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t Peripheral_PeripheralCBs = {
peripheralStateNotificationCB, // Profile State Change Callbacks
NULL, // When a valid RSSI is read from controller (not used by application)
NULL};
// GAP Bond Manager Callbacks
static gapBondCBs_t Peripheral_BondMgrCBs = {
NULL, // Passcode callback (not used by application)
NULL // Pairing / Bonding state Callback (not used by application)
};
// Simple GATT Profile Callbacks
static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
simpleProfileChangeCB // Charactersitic value change callback
};
// Simple GATT Profile Callbacks
static OTAProfileCBs_t Peripheral_OTA_IAPProfileCBs = {
OTA_IAPReadDataComplete, // Charactersitic value change callback
OTA_IAPWriteData
};
// Callback when the connection parameteres are updated.
void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout);
gapRolesParamUpdateCB_t PeripheralParamUpdate_t = NULL;
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Peripheral_Init
*
* @brief Initialization function for the Peripheral 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 Peripheral_Init()
{
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
// Setup the GAP Peripheral Role Profile
{
// For other hardware platforms, device starts advertising upon initialization
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);
//PeripheralParamUpdate_t = (gapRolesParamUpdateCB_t *)PeripheralParamUpdate;
//PRINT( "PeripheralParamUpdate_t %08x \n",(int)PeripheralParamUpdate_t );
//GAPRole_PeripheralRegisterAppCBs( (gapRolesParamUpdateCB_t *)&PeripheralParamUpdate );
}
// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
// Set advertising interval
{
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
}
// Setup the GAP Bond Manager
{
uint32_t passkey = 0; // passkey "000000"
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8_t mitm = TRUE;
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8_t bonding = TRUE;
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);
}
// Initialize GATT attributes
GGS_AddService(GATT_ALL_SERVICES); // GAP
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
DevInfo_AddService(); // Device Information Service
SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
OTAProfile_AddService(GATT_ALL_SERVICES);
// Setup the SimpleProfile Characteristic Values
{
uint8_t charValue1 = 1;
uint8_t charValue2 = 2;
uint8_t charValue3 = 3;
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = "01234567";
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t), &charValue1);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t), &charValue2);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t), &charValue3);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
}
//
{
//GAPRole_PeripheralRegisterAppCBs( (gapRolesParamUpdateCB_t *)PeripheralParamUpdate_t );
}
// Register callback with SimpleGATTprofile
SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);
// Register callback with OTAGATTprofile
OTAProfile_RegisterAppCBs(&Peripheral_OTA_IAPProfileCBs);
// Setup a delayed profile startup
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
}
void PeripheralParamUpdate(uint16_t connInterval, uint16_t connSlaveLatency, uint16_t connTimeout)
{
PRINT("update %d %d %d \n", connInterval, connSlaveLatency, connTimeout);
// GAPRole_SendUpdateParam( DEFAULT_DESIRED_MIN_CONN_INTERVAL, DEFAULT_DESIRED_MAX_CONN_INTERVAL,
// DEFAULT_DESIRED_SLAVE_LATENCY, DEFAULT_DESIRED_CONN_TIMEOUT, GAPROLE_NO_ACTION );
}
/*********************************************************************
* @fn Peripheral_ProcessEvent
*
* @brief Peripheral 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 Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
{
// VOID task_id; // TMOS required parameter that isn't used in this function
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
{
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & SBP_START_DEVICE_EVT)
{
// Start the Device
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
// Set timer for first periodic event
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
return (events ^ SBP_START_DEVICE_EVT);
}
if(events & SBP_PERIODIC_EVT)
{
// Restart timer
if(SBP_PERIODIC_EVT_PERIOD)
{
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
}
// Perform periodic application task
performPeriodicTask();
return (events ^ SBP_PERIODIC_EVT);
}
//OTA_FLASH_ERASE_EVT
if(events & OTA_FLASH_ERASE_EVT)
{
uint8_t status;
PRINT("ERASE:%08x num:%d\r\n", (int)(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE), (int)EraseBlockCnt);
FLASH_Unlock();
status = FLASH_ErasePage(EraseAdd + EraseBlockCnt * FLASH_BLOCK_SIZE);
FLASH_Lock();
/* Erase failed */
if(status != FLASH_COMPLETE)
{
OTA_IAP_SendCMDDealSta(status);
return (events ^ OTA_FLASH_ERASE_EVT);
}
EraseBlockCnt++;
/* End of erase */
if(EraseBlockCnt >= EraseBlockNum)
{
PRINT("ERASE Complete\r\n");
OTA_IAP_SendCMDDealSta(SUCCESS);
return (events ^ OTA_FLASH_ERASE_EVT);
}
return (events);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn Peripheral_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
default:
break;
}
}
/*********************************************************************
* @fn peripheralStateNotificationCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
{
switch(newState)
{
case GAPROLE_STARTED:
PRINT("Initialized..\n");
break;
case GAPROLE_ADVERTISING:
PRINT("Advertising..\n");
break;
case GAPROLE_CONNECTED:
{
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
uint16_t conn_interval = 0;
conn_interval = event->connInterval;
PRINT("Connected.. \n");
if(conn_interval > DEFAULT_DESIRED_MAX_CONN_INTERVAL)
{
PRINT("Send Update\r\n");
GAPRole_PeripheralConnParamUpdateReq(event->connectionHandle,
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
DEFAULT_DESIRED_SLAVE_LATENCY,
DEFAULT_DESIRED_CONN_TIMEOUT,
Peripheral_TaskID);
}
break;
}
case GAPROLE_CONNECTED_ADV:
PRINT("Connected Advertising..\n");
break;
case GAPROLE_WAITING:
{
uint8_t initial_advertising_enable = TRUE;
// Set the GAP Role Parameters
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
PRINT("Disconnected..\n");
}
break;
case GAPROLE_ERROR:
PRINT("Error..\n");
break;
default:
break;
}
}
/*********************************************************************
* @fn performPeriodicTask
*
* @brief Perform a periodic application task. This function gets
* called every five seconds as a result of the SBP_PERIODIC_EVT
* TMOS event. In this example, the value of the third
* characteristic in the SimpleGATTProfile service is retrieved
* from the profile, and then copied into the value of the
* the fourth characteristic.
*
* @param none
*
* @return none
*/
static void performPeriodicTask(void)
{
uint8_t valueToCopy[SIMPLEPROFILE_CHAR4_LEN];
uint8_t stat;
// Call to retrieve the value of the third characteristic in the profile
stat = SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR4, valueToCopy);
if(stat == SUCCESS)
{
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, valueToCopy);
}
}
/*********************************************************************
* @fn simpleProfileChangeCB
*
* @brief Callback from Profile indicating a value change
*
* @param paramID - parameter ID of the value that was changed.
*
* @return none
*/
static void simpleProfileChangeCB(uint8_t paramID)
{
uint8_t newValue;
switch(paramID)
{
case SIMPLEPROFILE_CHAR1:
PRINT("profile ChangeCB CHAR1..\n");
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
break;
case SIMPLEPROFILE_CHAR3:
PRINT("profile ChangeCB CHAR3..\n");
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
break;
default:
// should not reach here!
break;
}
}
/*********************************************************************
* @fn OTA_IAP_SendData
*
* @brief OTA IAP sends data, which is limited to 20 bytes when used
*
* @param p_send_data - Pointer to send data
* @param send_len - Length of data sent
*
* @return none
*/
void OTA_IAP_SendData(uint8_t *p_send_data, uint8_t send_len)
{
OTAProfile_SendData(OTAPROFILE_CHAR, p_send_data, send_len);
}
/*********************************************************************
* @fn OTA_IAP_SendCMDDealSta
*
* @brief Status return of OTA IAP execution
*
* @param deal_status - Return state
*
* @return none
*/
void OTA_IAP_SendCMDDealSta(uint8_t deal_status)
{
uint8_t send_buf[2];
send_buf[0] = deal_status;
send_buf[1] = 0;
OTA_IAP_SendData(send_buf, 2);
}
/*********************************************************************
* @fn OTA_IAP_CMDErrDeal
*
* @brief OTA IAP abnormal command code processing
*
* @return none
*/
void OTA_IAP_CMDErrDeal(void)
{
OTA_IAP_SendCMDDealSta(0xfe);
}
/*********************************************************************
* @fn SwitchImageFlag
*
* @brief Switch ImageFlag in dataflash
*
* @param new_flag - Switching ImageFlag
*
* @return none
*/
void SwitchImageFlag(uint8_t new_flag)
{
uint16_t i;
uint32_t ver_flag;
/* Read the first block */
FLASH_read(OTA_DATAFLASH_ADD, &block_buf[0], 4);
FLASH_Unlock_Fast();
/* Erase the first block */
FLASH_ErasePage_Fast( OTA_DATAFLASH_ADD );
/* Update Image information */
block_buf[0] = new_flag;
block_buf[1] = 0x5A;
block_buf[2] = 0x5A;
block_buf[3] = 0x5A;
/* Program DataFlash */
FLASH_ProgramPage_Fast( OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0]);
FLASH_Lock_Fast();
}
/*********************************************************************
* @fn DisableAllIRQ
*
* @brief Disable all interrupts
*
* @return none
*/
void DisableAllIRQ(void)
{
__disable_irq();
}
/*********************************************************************
* @fn Rec_OTA_IAP_DataDeal
*
* @brief Received OTA packet processing
*
* @return none
*/
void Rec_OTA_IAP_DataDeal(void)
{
switch(iap_rec_data.other.buf[0])
{
/* Programming */
case CMD_IAP_PROM:
{
uint32_t i;
FLASH_Status status = FLASH_COMPLETE;
OpParaDataLen = iap_rec_data.program.len;
OpAdd = (uint32_t)(iap_rec_data.program.addr[0]);
OpAdd |= ((uint32_t)(iap_rec_data.program.addr[1]) << 8);
OpAdd = OpAdd * 16;
OpAdd += IMAGE_A_SIZE+0x08000000;
PRINT("IAP_PROM: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
/* Current is ImageA, programming directly */
tmos_memcpy(&block_buf[block_buf_len], iap_rec_data.program.buf, OpParaDataLen);
block_buf_len+=OpParaDataLen;
if( block_buf_len>=FLASH_PAGE_SIZE )
{
FLASH_Unlock_Fast();
FLASH_ProgramPage_Fast(prom_addr, (uint32_t*)block_buf);
FLASH_Lock_Fast();
tmos_memcpy(block_buf, &block_buf[FLASH_PAGE_SIZE], block_buf_len-FLASH_PAGE_SIZE);
block_buf_len-=FLASH_PAGE_SIZE;
prom_addr+=FLASH_PAGE_SIZE;
}
OTA_IAP_SendCMDDealSta(SUCCESS);
break;
}
/* Erase -- Bluetooth erase is controlled by the host */
case CMD_IAP_ERASE:
{
OpAdd = (uint32_t)(iap_rec_data.erase.addr[0]);
OpAdd |= ((uint32_t)(iap_rec_data.erase.addr[1]) << 8);
OpAdd = OpAdd * 16;
OpAdd += IMAGE_A_SIZE+0x08000000;
EraseBlockNum = (uint32_t)(iap_rec_data.erase.block_num[0]);
EraseBlockNum |= ((uint32_t)(iap_rec_data.erase.block_num[1]) << 8);
EraseAdd = OpAdd;
EraseBlockCnt = 0;
/* The inspection is placed in the era of clearing 0 */
VerifyStatus = 0;
prom_addr = IMAGE_B_START_ADD;
PRINT("IAP_ERASE start:%08x num:%d\r\n", (int)EraseAdd, (int)EraseBlockNum);
if((EraseAdd < IMAGE_B_START_ADD) || ((EraseAdd + (EraseBlockNum - 1) * FLASH_BLOCK_SIZE) > (IMAGE_B_START_ADD+IMAGE_B_SIZE)))
{
OTA_IAP_SendCMDDealSta(0xFF);
}
else
{
/* Start erasing */
tmos_set_event(Peripheral_TaskID, OTA_FLASH_ERASE_EVT);
}
break;
}
/* Verify */
case CMD_IAP_VERIFY:
{
uint32_t i;
uint8_t status = 0;
uint8_t verifyData[iap_rec_data.verify.len];
if( block_buf_len )
{
FLASH_Unlock_Fast();
FLASH_ProgramPage_Fast(prom_addr, (uint32_t*)block_buf);
FLASH_Lock_Fast();
block_buf_len=0;
prom_addr=0;
}
OpParaDataLen = iap_rec_data.verify.len;
OpAdd = (uint32_t)(iap_rec_data.verify.addr[0]);
OpAdd |= ((uint32_t)(iap_rec_data.verify.addr[1]) << 8);
OpAdd = OpAdd * 16;
OpAdd += IMAGE_A_SIZE+0x08000000;
PRINT("IAP_VERIFY: %08x len:%d \r\n", (int)OpAdd, (int)OpParaDataLen);
FLASH_read(OpAdd, verifyData, OpParaDataLen);
/* Currently ImageA, read ImageB for verification directly*/
status = tmos_memcmp(verifyData, iap_rec_data.verify.buf, OpParaDataLen);
if(status == FALSE)
{
PRINT("IAP_VERIFY err \r\n");
VerifyStatus = 0xFF;
}
OTA_IAP_SendCMDDealSta(VerifyStatus);
break;
}
/* End of rogramming */
case CMD_IAP_END:
{
PRINT("IAP_END \r\n");
/* The current one is ImageA */
/* Close all the current use interrupt, or it is convenient to directly close */
DisableAllIRQ();
/* Modify DataFlash and switch to ImageIAP */
SwitchImageFlag(IMAGE_IAP_FLAG);
/* Wait for printing to complete, reset*/
Delay_Ms(10);
NVIC_SystemReset();
break;
}
case CMD_IAP_INFO:
{
uint8_t send_buf[20];
PRINT("IAP_INFO \r\n");
/* IMAGE FLAG */
send_buf[0] = IMAGE_B_FLAG;
/* IMAGE_SIZE */
send_buf[1] = (uint8_t)(IMAGE_SIZE & 0xff);
send_buf[2] = (uint8_t)((IMAGE_SIZE >> 8) & 0xff);
send_buf[3] = (uint8_t)((IMAGE_SIZE >> 16) & 0xff);
send_buf[4] = (uint8_t)((IMAGE_SIZE >> 24) & 0xff);
/* BLOCK SIZE */
send_buf[5] = (uint8_t)(FLASH_BLOCK_SIZE & 0xff);
send_buf[6] = (uint8_t)((FLASH_BLOCK_SIZE >> 8) & 0xff);
send_buf[7] = CHIP_ID&0xFF;
send_buf[8] = (CHIP_ID>>8)&0xFF;
/* Add more if necessary */
/* send message */
OTA_IAP_SendData(send_buf, 20);
break;
}
default:
{
OTA_IAP_CMDErrDeal();
break;
}
}
}
/*********************************************************************
* @fn OTA_IAPReadDataComplete
*
* @brief OTA data reading complete processing
*
* @param index - OTA channel serial number
*
* @return none
*/
void OTA_IAPReadDataComplete(unsigned char index)
{
PRINT("OTA Send Comp \r\n");
}
/*********************************************************************
* @fn OTA_IAPWriteData
*
* @brief OTA channel data receiving complete processing
*
* @param index - OTA channel serial number
* @param p_data - Written data
* @param w_len - Length
*
* @return none
*/
void OTA_IAPWriteData(unsigned char index, unsigned char *p_data, unsigned char w_len)
{
unsigned char rec_len;
unsigned char *rec_data;
rec_len = w_len;
rec_data = p_data;
tmos_memcpy((unsigned char *)&iap_rec_data, rec_data, rec_len);
Rec_OTA_IAP_DataDeal();
}
/*********************************************************************
* @fn FLASH_read
*
* @brief Read flash
*
* @return none
*/
void FLASH_read(uint32_t addr, uint8_t *pData, uint32_t len)
{
uint32_t i;
for(i=0;i<len;i++)
{
*pData++ = *(uint8_t*)addr++;
}
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,103 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.1
* Date : 2019/11/05
* Description : Peripheral slave application main function and task system 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 "GATTprofile.h"
#include "Peripheral.h"
#include "OTA.h"
#include "OTAprofile.h"
/* Record the current image */
unsigned char CurrImageFlag = 0xff;
/*********************************************************************
* 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
/* Used for app judgment file effectiveness */
const uint32_t Address = 0xFFFFFFFF;
__attribute__((aligned(4))) uint32_t Image_Flag __attribute__((section(".ImageFlag"))) = (uint32_t)&Address;
/* Note: The operation of Flash after the program is upgraded must be performed first without
* turning on any interruption to prevent operation interruption and failure */
/*********************************************************************
* @fn ReadImageFlag
*
* @brief Read the iMage logo of the current program. If the DataFlash is empty,
* it will be ImageA by default
*
* @return none
*/
void ReadImageFlag(void)
{
OTADataFlashInfo_t p_image_flash;
FLASH_read(OTA_DATAFLASH_ADD, (uint8_t*)&p_image_flash, 4);
CurrImageFlag = p_image_flash.ImageFlag;
/* The program is executed for the first time, or it has not been updated,
* and the DataFlash will be erased after the subsequent update. */
if((CurrImageFlag != IMAGE_A_FLAG) && (CurrImageFlag != IMAGE_B_FLAG))
{
CurrImageFlag = IMAGE_A_FLAG;
}
}
/*********************************************************************
* @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();
Peripheral_Init();
Main_Circulation();
}
/******************************** endfile @ main ******************************/
@@ -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
+204
View File
@@ -0,0 +1,204 @@
ENTRY( _start )
__stack_size = 2048;
PROVIDE( _stack_size = __stack_size );
MEMORY
{
/* CH32V20x_D6 - CH32V203F6-CH32V203G6-CH32V203K6-CH32V203C6 */
/*
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 32K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 10K
*/
/* CH32V20x_D6 - CH32V203K8-CH32V203C8-CH32V203G8-CH32V203F8 */
/*
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
*/
/* CH32V20x_D8 - CH32V203RB
CH32V20x_D8W - CH32V208x
FLASH + RAM supports the following configuration
FLASH-128K + RAM-64K
FLASH-144K + RAM-48K
FLASH-160K + RAM-32K
*/
FLASH (rx) : ORIGIN = 0x00004000, LENGTH = 216K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
KEEP(*(.ImageFlag))
KEEP(*(.ImageFlag.*))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
.vector :
{
*(.vector);
. = ALIGN(64);
KEEP(*(SORT_NONE(.handle_reset)))
} >FLASH AT>FLASH
.highcode :
{
. = ALIGN(4);
*(.highcode);
*(.highcode.*);
. = ALIGN(4);
} >FLASH AT>FLASH
.text :
{
. = ALIGN(4);
EXCLUDE_FILE (*wchble.a) *(.text .text*)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.sdata2.*)
*(.gnu.linkonce.t.*)
. = ALIGN(4);
} >FLASH AT>FLASH
.fini :
{
KEEP(*(SORT_NONE(.fini)))
. = ALIGN(4);
} >FLASH AT>FLASH
PROVIDE( _etext = . );
PROVIDE( _eitcm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >FLASH AT>FLASH
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >FLASH AT>FLASH
.dalign :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
} >RAM AT>FLASH
.dlalign :
{
. = ALIGN(4);
PROVIDE(_data_lma = .);
} >FLASH AT>FLASH
.data :
{
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAM AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
/*.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
} >RAM */
.stack ORIGIN(RAM)+LENGTH(RAM) :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_eusrstack = . );
} >RAM
}
@@ -0,0 +1,334 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : OTAprofile.C
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : OTA升级蓝牙通讯接口
*********************************************************************************
* 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 "OTAprofile.h"
#include "debug.h"
#include "ota.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Simple GATT Profile Service UUID: 0xFFF0
const uint8_t OTAProfileServUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(OTAPROFILE_SERV_UUID), HI_UINT16(OTAPROFILE_SERV_UUID)};
// Characteristic 1 UUID: 0xFFF1
const uint8_t OTAProfilechar1UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(OTAPROFILE_CHAR_UUID), HI_UINT16(OTAPROFILE_CHAR_UUID)};
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static OTAProfileCBs_t *OTAProfile_AppCBs = NULL;
/*********************************************************************
* Profile Attributes - variables
*/
// Simple Profile Service attribute
static const gattAttrType_t OTAProfileService = {ATT_BT_UUID_SIZE, OTAProfileServUUID};
// Simple Profile Characteristic 1 Properties
static uint8_t OTAProfileCharProps = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
// Characteristic 1 Value
static uint8_t OTAProfileChar = 0;
// Simple Profile Characteristic 1 User Description
static uint8_t OTAProfileCharUserDesp[12] = "OTA Channel";
// write and read buffer
static uint8_t OTAProfileReadLen;
static uint8_t OTAProfileReadBuf[IAP_LEN];
static uint8_t OTAProfileWriteLen;
static uint8_t OTAProfileWriteBuf[IAP_LEN];
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t OTAProfileAttrTbl[4] = {
// Simple Profile Service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&OTAProfileService /* pValue */
},
// Characteristic Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&OTAProfileCharProps},
// Characteristic Value
{
{ATT_BT_UUID_SIZE, OTAProfilechar1UUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
&OTAProfileChar},
// Characteristic User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
OTAProfileCharUserDesp},
};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static bStatus_t OTAProfile_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 OTAProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
/*********************************************************************
* PROFILE CALLBACKS
*/
// OTA Profile Service Callbacks
gattServiceCBs_t OTAProfileCBs = {
OTAProfile_ReadAttrCB, // Read callback function pointer
OTAProfile_WriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn OTAProfile_AddService
*
* @brief OTA Profile初始化
*
* @param services - 服务控制字
*
* @return 初始化的状态
*/
bStatus_t OTAProfile_AddService(uint32_t services)
{
uint8_t status = SUCCESS;
if(services & OTAPROFILE_SERVICE)
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService(OTAProfileAttrTbl,
GATT_NUM_ATTRS(OTAProfileAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&OTAProfileCBs);
}
return (status);
}
/*********************************************************************
* @fn OTAProfile_RegisterAppCBs
*
* @brief OTA Profile读写回调函数注册
*
* @param appCallbacks - 函数结构体指针
*
* @return 函数执行状态
*/
bStatus_t OTAProfile_RegisterAppCBs(OTAProfileCBs_t *appCallbacks)
{
if(appCallbacks)
{
OTAProfile_AppCBs = appCallbacks;
return (SUCCESS);
}
else
{
return (bleAlreadyInRequestedMode);
}
}
/*********************************************************************
* @fn OTAProfile_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 OTAProfile_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;
if(pAttr->type.len == ATT_BT_UUID_SIZE)
{
// 16-bit UUID
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
case OTAPROFILE_CHAR_UUID:
{
*pLen = 0;
if(OTAProfileReadLen)
{
*pLen = OTAProfileReadLen;
tmos_memcpy(pValue, OTAProfileReadBuf, OTAProfileReadLen);
OTAProfileReadLen = 0;
if(OTAProfile_AppCBs && OTAProfile_AppCBs->pfnOTAProfileRead)
{
OTAProfile_AppCBs->pfnOTAProfileRead(OTAPROFILE_CHAR);
}
}
break;
}
default:
{
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
}
else
{
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
}
return (status);
}
/*********************************************************************
* @fn OTAProfile_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 OTAProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
{
bStatus_t status = SUCCESS;
//uint8_t notifyApp = 0xFF;
if(pAttr->type.len == ATT_BT_UUID_SIZE)
{
// 16-bit UUID
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
case OTAPROFILE_CHAR_UUID:
{
//Write the value
if(status == SUCCESS)
{
uint16_t i;
uint8_t *p_rec_buf;
OTAProfileWriteLen = len;
p_rec_buf = pValue;
for(i = 0; i < OTAProfileWriteLen; i++)
OTAProfileWriteBuf[i] = p_rec_buf[i];
}
break;
}
default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}
if(OTAProfileWriteLen && OTAProfile_AppCBs && OTAProfile_AppCBs->pfnOTAProfileWrite)
{
OTAProfile_AppCBs->pfnOTAProfileWrite(OTAPROFILE_CHAR, OTAProfileWriteBuf, OTAProfileWriteLen);
OTAProfileWriteLen = 0;
}
return (status);
}
/*********************************************************************
* @fn OTAProfile_SendData
*
* @brief OTA Profile通道发送数据
*
* @param paramID - OTA通道选择
* @param p_data - 数据指针
* @param send_len - 发送数据长度
*
* @return 函数执行状态
*/
bStatus_t OTAProfile_SendData(unsigned char paramID, unsigned char *p_data, unsigned char send_len)
{
bStatus_t status = SUCCESS;
/* 数据长度超出范围 */
if(send_len > 20)
return 0xfe;
OTAProfileReadLen = send_len;
tmos_memcpy(OTAProfileReadBuf, p_data, OTAProfileReadLen);
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,655 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : gattprofile.C
* 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.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "CONFIG.h"
#include "GATTprofile.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#define SERVAPP_NUM_ATTR_SUPPORTED 17
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Simple GATT Profile Service UUID: 0xFFF0
const uint8_t simpleProfileServUUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
// Characteristic 1 UUID: 0xFFF1
const uint8_t simpleProfilechar1UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)};
// Characteristic 2 UUID: 0xFFF2
const uint8_t simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)};
// Characteristic 3 UUID: 0xFFF3
const uint8_t simpleProfilechar3UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)};
// Characteristic 4 UUID: 0xFFF4
const uint8_t simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)};
// Characteristic 5 UUID: 0xFFF5
const uint8_t simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = {
LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)};
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
/*********************************************************************
* Profile Attributes - variables
*/
// Simple Profile Service attribute
static const gattAttrType_t simpleProfileService = {ATT_BT_UUID_SIZE, simpleProfileServUUID};
// Simple Profile Characteristic 1 Properties
static uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
// Characteristic 1 Value
static uint8_t simpleProfileChar1 = 0;
// Simple Profile Characteristic 1 User Description
static uint8_t simpleProfileChar1UserDesp[17] = "Characteristic 1\0";
// Simple Profile Characteristic 2 Properties
static uint8_t simpleProfileChar2Props = GATT_PROP_READ;
// Characteristic 2 Value
static uint8_t simpleProfileChar2 = 0;
// Simple Profile Characteristic 2 User Description
static uint8_t simpleProfileChar2UserDesp[17] = "Characteristic 2\0";
// Simple Profile Characteristic 3 Properties
static uint8_t simpleProfileChar3Props = GATT_PROP_WRITE;
// Characteristic 3 Value
static uint8_t simpleProfileChar3 = 0;
// Simple Profile Characteristic 3 User Description
static uint8_t simpleProfileChar3UserDesp[17] = "Characteristic 3\0";
// Simple Profile Characteristic 4 Properties
static uint8_t simpleProfileChar4Props = GATT_PROP_NOTIFY;
// Characteristic 4 Value
static uint8_t simpleProfileChar4 = 0;
// Simple Profile Characteristic 4 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t simpleProfileChar4Config[4];
// Simple Profile Characteristic 4 User Description
static uint8_t simpleProfileChar4UserDesp[17] = "Characteristic 4\0";
// Simple Profile Characteristic 5 Properties
static uint8_t simpleProfileChar5Props = GATT_PROP_READ;
// Characteristic 5 Value
static uint8_t simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = {0, 0, 0, 0, 0};
// Simple Profile Characteristic 5 User Description
static uint8_t simpleProfileChar5UserDesp[17] = "Characteristic 5\0";
/*********************************************************************
* Profile Attributes - Table
*/
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = {
// Simple Profile Service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&simpleProfileService /* pValue */
},
// Characteristic 1 Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar1Props},
// Characteristic Value 1
{
{ATT_BT_UUID_SIZE, simpleProfilechar1UUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
&simpleProfileChar1},
// Characteristic 1 User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
simpleProfileChar1UserDesp},
// Characteristic 2 Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar2Props},
// Characteristic Value 2
{
{ATT_BT_UUID_SIZE, simpleProfilechar2UUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar2},
// Characteristic 2 User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
simpleProfileChar2UserDesp},
// Characteristic 3 Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar3Props},
// Characteristic Value 3
{
{ATT_BT_UUID_SIZE, simpleProfilechar3UUID},
GATT_PERMIT_WRITE,
0,
&simpleProfileChar3},
// Characteristic 3 User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
simpleProfileChar3UserDesp},
// Characteristic 4 Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar4Props},
// Characteristic Value 4
{
{ATT_BT_UUID_SIZE, simpleProfilechar4UUID},
0,
0,
&simpleProfileChar4},
// Characteristic 4 configuration
{
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8_t *)simpleProfileChar4Config},
// Characteristic 4 User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
simpleProfileChar4UserDesp},
// Characteristic 5 Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&simpleProfileChar5Props},
// Characteristic Value 5
{
{ATT_BT_UUID_SIZE, simpleProfilechar5UUID},
GATT_PERMIT_AUTHEN_READ,
0,
simpleProfileChar5},
// Characteristic 5 User Description
{
{ATT_BT_UUID_SIZE, charUserDescUUID},
GATT_PERMIT_READ,
0,
simpleProfileChar5UserDesp},
};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static bStatus_t simpleProfile_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 simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
static void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
/*********************************************************************
* PROFILE CALLBACKS
*/
// Simple Profile Service Callbacks
gattServiceCBs_t simpleProfileCBs = {
simpleProfile_ReadAttrCB, // Read callback function pointer
simpleProfile_WriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn SimpleProfile_AddService
*
* @brief Initializes the Simple Profile 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 SimpleProfile_AddService(uint32_t services)
{
uint8_t status = SUCCESS;
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar4Config);
// Register with Link DB to receive link status change callback
linkDB_Register(simpleProfile_HandleConnStatusCB);
if(services & SIMPLEPROFILE_SERVICE)
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService(simpleProfileAttrTbl,
GATT_NUM_ATTRS(simpleProfileAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&simpleProfileCBs);
}
return (status);
}
/*********************************************************************
* @fn SimpleProfile_RegisterAppCBs
*
* @brief Registers the application callback function. Only call
* this function once.
*
* @param callbacks - pointer to application callbacks.
*
* @return SUCCESS or bleAlreadyInRequestedMode
*/
bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks)
{
if(appCallbacks)
{
simpleProfile_AppCBs = appCallbacks;
return (SUCCESS);
}
else
{
return (bleAlreadyInRequestedMode);
}
}
/*********************************************************************
* @fn SimpleProfile_SetParameter
*
* @brief Set a Simple Profile 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 SimpleProfile_SetParameter(uint8_t param, uint16_t len, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case SIMPLEPROFILE_CHAR1:
if(len == sizeof(uint8_t))
{
simpleProfileChar1 = *((uint8_t *)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR2:
if(len == sizeof(uint8_t))
{
simpleProfileChar2 = *((uint8_t *)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR3:
if(len == sizeof(uint8_t))
{
simpleProfileChar3 = *((uint8_t *)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR4:
if(len == sizeof(uint8_t))
{
simpleProfileChar4 = *((uint8_t *)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR5:
if(len == SIMPLEPROFILE_CHAR5_LEN)
{
tmos_memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
}
else
{
ret = bleInvalidRange;
}
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn SimpleProfile_GetParameter
*
* @brief Get a Simple Profile parameter.
*
* @param param - Profile parameter ID
* @param value - pointer to data to put. 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 SimpleProfile_GetParameter(uint8_t param, void *value)
{
bStatus_t ret = SUCCESS;
switch(param)
{
case SIMPLEPROFILE_CHAR1:
*((uint8_t *)value) = simpleProfileChar1;
break;
case SIMPLEPROFILE_CHAR2:
*((uint8_t *)value) = simpleProfileChar2;
break;
case SIMPLEPROFILE_CHAR3:
*((uint8_t *)value) = simpleProfileChar3;
break;
case SIMPLEPROFILE_CHAR4:
*((uint8_t *)value) = simpleProfileChar4;
break;
case SIMPLEPROFILE_CHAR5:
tmos_memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
break;
default:
ret = INVALIDPARAMETER;
break;
}
return (ret);
}
/*********************************************************************
* @fn simpleProfile_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 simpleProfile_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;
// Make sure it's not a blob operation (no attributes in the profile are long)
if(offset > 0)
{
return (ATT_ERR_ATTR_NOT_LONG);
}
if(pAttr->type.len == ATT_BT_UUID_SIZE)
{
// 16-bit UUID
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
// characteristics 1 and 2 have read permissions
// characteritisc 3 does not have read permissions; therefore it is not
// included here
// characteristic 4 does not have read permissions, but because it
// can be sent as a notification, it is included here
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR2_UUID:
case SIMPLEPROFILE_CHAR4_UUID:
*pLen = 1;
pValue[0] = *pAttr->pValue;
break;
case SIMPLEPROFILE_CHAR5_UUID:
*pLen = SIMPLEPROFILE_CHAR5_LEN;
tmos_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN);
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
}
return (status);
}
/*********************************************************************
* @fn simpleProfile_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 simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
{
bStatus_t status = SUCCESS;
uint8_t notifyApp = 0xFF;
// If attribute permissions require authorization to write, return error
if(gattPermitAuthorWrite(pAttr->permissions))
{
// Insufficient authorization
return (ATT_ERR_INSUFFICIENT_AUTHOR);
}
if(pAttr->type.len == ATT_BT_UUID_SIZE)
{
// 16-bit UUID
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch(uuid)
{
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR3_UUID:
//Validate the value
// Make sure it's not a blob oper
if(offset == 0)
{
if(len != 1)
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if(status == SUCCESS)
{
uint8_t *pCurValue = (uint8_t *)pAttr->pValue;
*pCurValue = pValue[0];
if(pAttr->pValue == &simpleProfileChar1)
{
notifyApp = SIMPLEPROFILE_CHAR1;
}
else
{
notifyApp = SIMPLEPROFILE_CHAR3;
}
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
break;
default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}
// If a charactersitic value changed then callback function to notify application of change
if((notifyApp != 0xFF) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange)
{
simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp);
}
return (status);
}
/*********************************************************************
* @fn simpleProfile_HandleConnStatusCB
*
* @brief Simple Profile link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/
static void simpleProfile_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, simpleProfileChar4Config);
}
}
}
/*********************************************************************
*********************************************************************/
@@ -0,0 +1,79 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : OTAprofile.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 OTAPROFILE_H
#define OTAPROFILE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// OTA Profile通道Index定义
#define OTAPROFILE_CHAR 0
// OTA 服务的UUID定义
#define OTAPROFILE_SERV_UUID 0xFEE0
// OTA 通讯通道UUID定义
#define OTAPROFILE_CHAR_UUID 0xFEE1
// Simple Keys Profile Services bit fields
#define OTAPROFILE_SERVICE 0x00000001
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* Profile Callbacks
*/
// 读写操作函数回调
typedef void (*OTAProfileRead_t)(unsigned char paramID);
typedef void (*OTAProfileWrite_t)(unsigned char paramID, unsigned char *p_data, unsigned char w_len);
typedef struct
{
OTAProfileRead_t pfnOTAProfileRead;
OTAProfileWrite_t pfnOTAProfileWrite;
} OTAProfileCBs_t;
/*********************************************************************
* API FUNCTIONS
*/
bStatus_t OTAProfile_AddService(uint32_t services);
bStatus_t OTAProfile_RegisterAppCBs(OTAProfileCBs_t *appCallbacks);
bStatus_t OTAProfile_SendData(unsigned char paramID, unsigned char *p_data, unsigned char send_len);
/*********************************************************************
*********************************************************************/
#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,124 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : gattprofile.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 GATTPROFILE_H
#define GATTPROFILE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
/*********************************************************************
* CONSTANTS
*/
// Profile Parameters
#define SIMPLEPROFILE_CHAR1 0 // RW uint8_t - Profile Characteristic 1 value
#define SIMPLEPROFILE_CHAR2 1 // RW uint8_t - Profile Characteristic 2 value
#define SIMPLEPROFILE_CHAR3 2 // RW uint8_t - Profile Characteristic 3 value
#define SIMPLEPROFILE_CHAR4 3 // RW uint8_t - Profile Characteristic 4 value
#define SIMPLEPROFILE_CHAR5 4 // RW uint8_t - Profile Characteristic 4 value
// Simple Profile Service UUID
#define SIMPLEPROFILE_SERV_UUID 0xFFE0
// Key Pressed UUID
#define SIMPLEPROFILE_CHAR1_UUID 0xFFE1
#define SIMPLEPROFILE_CHAR2_UUID 0xFFE2
#define SIMPLEPROFILE_CHAR3_UUID 0xFFE3
#define SIMPLEPROFILE_CHAR4_UUID 0xFFE4
#define SIMPLEPROFILE_CHAR5_UUID 0xFFE5
// Simple Keys Profile Services bit fields
#define SIMPLEPROFILE_SERVICE 0x00000001
// Length of Characteristic 5 in bytes
#define SIMPLEPROFILE_CHAR4_LEN 8
#define SIMPLEPROFILE_CHAR5_LEN 5
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* MACROS
*/
/*********************************************************************
* Profile Callbacks
*/
// Callback when a characteristic value has changed
typedef void (*simpleProfileChange_t)(uint8_t paramID);
typedef struct
{
simpleProfileChange_t pfnSimpleProfileChange; // Called when characteristic value changes
} simpleProfileCBs_t;
/*********************************************************************
* API FUNCTIONS
*/
/*
* SimpleProfile_AddService- Initializes the Simple GATT Profile 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 SimpleProfile_AddService(uint32_t services);
/*
* SimpleProfile_RegisterAppCBs - Registers the application callback function.
* Only call this function once.
*
* appCallbacks - pointer to application callbacks.
*/
extern bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks);
/*
* SimpleProfile_SetParameter - Set a Simple GATT Profile parameter.
*
* param - Profile parameter ID
* len - length of data to right
* 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 SimpleProfile_SetParameter(uint8_t param, uint16_t len, void *value);
/*
* SimpleProfile_GetParameter - Get a Simple GATT Profile 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 SimpleProfile_GetParameter(uint8_t param, void *value);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,287 @@
;/********************************** (C) COPYRIGHT *******************************
;* File Name : startup_ch32v20x_D8W.s
;* Author : WCH
;* Version : V1.0.0
;* Date : 2021/06/06
;* Description : CH32V208x
;* vector table for eclipse toolchain.
;*********************************************************************************
;* 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.
*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 1
_start:
j handle_reset
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00000013
.word 0x00100073
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word _start
.word 0
.word NMI_Handler /* NMI */
.word HardFault_Handler /* Hard Fault */
.word 0
.word Ecall_M_Mode_Handler /* Ecall M Mode */
.word 0
.word 0
.word Ecall_U_Mode_Handler /* Ecall U Mode */
.word Break_Point_Handler /* Break Point */
.word 0
.word 0
.word SysTick_Handler /* SysTick */
.word 0
.word SW_Handler /* SW */
.word 0
/* External Interrupts */
.word WWDG_IRQHandler /* Window Watchdog */
.word PVD_IRQHandler /* PVD through EXTI Line detect */
.word TAMPER_IRQHandler /* TAMPER */
.word RTC_IRQHandler /* RTC */
.word FLASH_IRQHandler /* Flash */
.word RCC_IRQHandler /* RCC */
.word EXTI0_IRQHandler /* EXTI Line 0 */
.word EXTI1_IRQHandler /* EXTI Line 1 */
.word EXTI2_IRQHandler /* EXTI Line 2 */
.word EXTI3_IRQHandler /* EXTI Line 3 */
.word EXTI4_IRQHandler /* EXTI Line 4 */
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
.word ADC1_2_IRQHandler /* ADC1_2 */
.word USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
.word USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
.word EXTI9_5_IRQHandler /* EXTI Line 9..5 */
.word TIM1_BRK_IRQHandler /* TIM1 Break */
.word TIM1_UP_IRQHandler /* TIM1 Update */
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.word TIM2_IRQHandler /* TIM2 */
.word TIM3_IRQHandler /* TIM3 */
.word TIM4_IRQHandler /* TIM4 */
.word I2C1_EV_IRQHandler /* I2C1 Event */
.word I2C1_ER_IRQHandler /* I2C1 Error */
.word I2C2_EV_IRQHandler /* I2C2 Event */
.word I2C2_ER_IRQHandler /* I2C2 Error */
.word SPI1_IRQHandler /* SPI1 */
.word SPI2_IRQHandler /* SPI2 */
.word USART1_IRQHandler /* USART1 */
.word USART2_IRQHandler /* USART2 */
.word USART3_IRQHandler /* USART3 */
.word EXTI15_10_IRQHandler /* EXTI Line 15..10 */
.word RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
.word USBWakeUp_IRQHandler /* USB Wake up from suspend */
.word USBHD_IRQHandler /* USBHD Break */
.word USBHDWakeUp_IRQHandler /* USBHD Wake up from suspend */
.word ETH_IRQHandler /* ETH global */
.word ETHWakeUp_IRQHandler /* ETH Wake up */
.word BB_IRQHandler /* BLE BB */
.word LLE_IRQHandler /* BLE LLE */
.word TIM5_IRQHandler /* TIM5 */
.word UART4_IRQHandler /* UART4 */
.word DMA1_Channel8_IRQHandler /* DMA1 Channel8 */
.word OSC32KCal_IRQHandler /* OSC32KCal */
.word OSCWakeUp_IRQHandler /* OSC Wake Up */
.option rvc;
.section .text.vector_handler, "ax", @progbits
.weak NMI_Handler /* NMI */
.weak HardFault_Handler /* Hard Fault */
.weak Ecall_M_Mode_Handler /* Ecall M Mode */
.weak Ecall_U_Mode_Handler /* Ecall U Mode */
.weak Break_Point_Handler /* Break Point */
.weak SysTick_Handler /* SysTick */
.weak SW_Handler /* SW */
.weak WWDG_IRQHandler /* Window Watchdog */
.weak PVD_IRQHandler /* PVD through EXTI Line detect */
.weak TAMPER_IRQHandler /* TAMPER */
.weak RTC_IRQHandler /* RTC */
.weak FLASH_IRQHandler /* Flash */
.weak RCC_IRQHandler /* RCC */
.weak EXTI0_IRQHandler /* EXTI Line 0 */
.weak EXTI1_IRQHandler /* EXTI Line 1 */
.weak EXTI2_IRQHandler /* EXTI Line 2 */
.weak EXTI3_IRQHandler /* EXTI Line 3 */
.weak EXTI4_IRQHandler /* EXTI Line 4 */
.weak DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.weak DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
.weak DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
.weak DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
.weak DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
.weak DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
.weak DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
.weak ADC1_2_IRQHandler /* ADC1_2 */
.weak USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
.weak USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
.weak CAN1_RX1_IRQHandler /* CAN1 RX1 */
.weak CAN1_SCE_IRQHandler /* CAN1 SCE */
.weak EXTI9_5_IRQHandler /* EXTI Line 9..5 */
.weak TIM1_BRK_IRQHandler /* TIM1 Break */
.weak TIM1_UP_IRQHandler /* TIM1 Update */
.weak TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
.weak TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.weak TIM2_IRQHandler /* TIM2 */
.weak TIM3_IRQHandler /* TIM3 */
.weak TIM4_IRQHandler /* TIM4 */
.weak I2C1_EV_IRQHandler /* I2C1 Event */
.weak I2C1_ER_IRQHandler /* I2C1 Error */
.weak I2C2_EV_IRQHandler /* I2C2 Event */
.weak I2C2_ER_IRQHandler /* I2C2 Error */
.weak SPI1_IRQHandler /* SPI1 */
.weak SPI2_IRQHandler /* SPI2 */
.weak USART1_IRQHandler /* USART1 */
.weak USART2_IRQHandler /* USART2 */
.weak USART3_IRQHandler /* USART3 */
.weak EXTI15_10_IRQHandler /* EXTI Line 15..10 */
.weak RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
.weak USBWakeUp_IRQHandler /* USB Wakeup from suspend */
.weak USBHD_IRQHandler /* USBHD */
.weak USBHDWakeUp_IRQHandler /* USBHD Wake Up */
.weak ETH_IRQHandler /* ETH global */
.weak ETHWakeUp_IRQHandler /* ETHWakeUp */
.weak BB_IRQHandler /* BB */
.weak LLE_IRQHandler /* LLE */
.weak TIM5_IRQHandler /* TIM5 */
.weak UART4_IRQHandler /* UART4 */
.weak DMA1_Channel8_IRQHandler /* DMA1 Channel8 */
.weak OSC32KCal_IRQHandler /* OSC32 KCal */
.weak OSCWakeUp_IRQHandler /* OSC Wake Up */
NMI_Handler: 1: j 1b
HardFault_Handler: 1: j 1b
Ecall_M_Mode_Handler: 1: j 1b
Ecall_U_Mode_Handler: 1: j 1b
Break_Point_Handler: 1: j 1b
SysTick_Handler: 1: j 1b
SW_Handler: 1: j 1b
WWDG_IRQHandler: 1: j 1b
PVD_IRQHandler: 1: j 1b
TAMPER_IRQHandler: 1: j 1b
RTC_IRQHandler: 1: j 1b
FLASH_IRQHandler: 1: j 1b
RCC_IRQHandler: 1: j 1b
EXTI0_IRQHandler: 1: j 1b
EXTI1_IRQHandler: 1: j 1b
EXTI2_IRQHandler: 1: j 1b
EXTI3_IRQHandler: 1: j 1b
EXTI4_IRQHandler: 1: j 1b
DMA1_Channel1_IRQHandler: 1: j 1b
DMA1_Channel2_IRQHandler: 1: j 1b
DMA1_Channel3_IRQHandler: 1: j 1b
DMA1_Channel4_IRQHandler: 1: j 1b
DMA1_Channel5_IRQHandler: 1: j 1b
DMA1_Channel6_IRQHandler: 1: j 1b
DMA1_Channel7_IRQHandler: 1: j 1b
ADC1_2_IRQHandler: 1: j 1b
USB_HP_CAN1_TX_IRQHandler: 1: j 1b
USB_LP_CAN1_RX0_IRQHandler: 1: j 1b
CAN1_RX1_IRQHandler: 1: j 1b
CAN1_SCE_IRQHandler: 1: j 1b
EXTI9_5_IRQHandler: 1: j 1b
TIM1_BRK_IRQHandler: 1: j 1b
TIM1_UP_IRQHandler: 1: j 1b
TIM1_TRG_COM_IRQHandler: 1: j 1b
TIM1_CC_IRQHandler: 1: j 1b
TIM2_IRQHandler: 1: j 1b
TIM3_IRQHandler: 1: j 1b
TIM4_IRQHandler: 1: j 1b
I2C1_EV_IRQHandler: 1: j 1b
I2C1_ER_IRQHandler: 1: j 1b
I2C2_EV_IRQHandler: 1: j 1b
I2C2_ER_IRQHandler: 1: j 1b
SPI1_IRQHandler: 1: j 1b
SPI2_IRQHandler: 1: j 1b
USART1_IRQHandler: 1: j 1b
USART2_IRQHandler: 1: j 1b
USART3_IRQHandler: 1: j 1b
EXTI15_10_IRQHandler: 1: j 1b
RTCAlarm_IRQHandler: 1: j 1b
USBWakeUp_IRQHandler: 1: j 1b
USBHD_IRQHandler: 1: j 1b
USBHDWakeUp_IRQHandler: 1: j 1b
ETH_IRQHandler: 1: j 1b
ETHWakeUp_IRQHandler: 1: j 1b
BB_IRQHandler: 1: j 1b
LLE_IRQHandler: 1: j 1b
TIM5_IRQHandler: 1: j 1b
UART4_IRQHandler: 1: j 1b
DMA1_Channel8_IRQHandler: 1: j 1b
OSC32KCal_IRQHandler: 1: j 1b
OSCWakeUp_IRQHandler: 1: j 1b
.section .text.handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
1:
la sp, _eusrstack
2:
/* Load data section from flash to RAM */
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
li t0, 0x1f
csrw 0xbc0, t0
/* Enable nested and hardware stack */
li t0, 0x3
csrw 0x804, t0
/* Enable interrupt */
li t0, 0x88
csrs mstatus, t0
la t0, _vector_base
ori t0, t0, 3
csrw mtvec, t0
jal SystemInit
la t0, main
csrw mepc, t0
mret