6 Commits

Author SHA1 Message Date
roy01 0b22368e6f 暫存 2026-06-02 11:46:13 +08:00
roy01 1aacb07132 ai模組化 2026-04-21 17:10:04 +08:00
Roy_01 16d792d62b feat: add control commands for DDS parameters 2026-03-30 17:22:53 +08:00
Roy_01 7d03c00122 dds 2026-03-26 16:35:48 +08:00
Roy_01 aab1672cb2 [example] add JF_02_motor example 2026-03-26 13:13:47 +08:00
Roy_01 79b18664d3 feat: 1. add uart RX decoder
2. enabled pwm on/of control via uart cmd
3. known Issue: observed unexpected spikes on the pwm waveform
2026-03-26 09:50:04 +08:00
46 changed files with 2962 additions and 153 deletions
@@ -0,0 +1,52 @@
#Generated from Visual Studio settings
---
BasedOnStyle: webkit
BraceWrapping:
BeforeCatch: true
BeforeElse: true
AfterClass: true
AfterFunction: true
AfterControlStatement: true
AfterEnum: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
ColumnLimit: 80
BreakBeforeBraces: Custom
NamespaceIndentation: All
TabWidth: 4
IndentCaseLabels: true
AlignAfterOpenBracket: Align
PointerAlignment: Right
AlignOperands: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: false
BreakAfterJavaFieldAnnotations: true
AlignTrailingComments: true
BreakConstructorInitializers: AfterColon
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignArrayOfStructures: Right
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: true
PadOperators: true
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: true
PadOperators: true
AlignEscapedNewlines: Right
...
@@ -0,0 +1,294 @@
<?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.debug.926872659">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.926872659" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.RV_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<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.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.926872659" name="Debug" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug" postbuildStep="${cross_prefix}${cross_objcopy}${cross_suffix} -O binary ${ProjName}.elf ${ProjName}.bin">
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.926872659." name="/" resourcePath="">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug.1243233573" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.debug">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.249191345" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.243120876" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1566043258" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.1801001334" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.none" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.651682061" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.1219903449" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.168524687" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.2098519515" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1093129020" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.max" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.449325272" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.758656032" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" value="2262347901" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.932361954" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" value="RISC-V GCC/Newlib" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.1942787399" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" value="riscv64-unknown-elf-" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.684525315" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" value="gcc" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1638988330" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" value="g++" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1234563299" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" value="ar" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1492404953" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" value="objcopy" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1394253527" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" value="objdump" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1332389637" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" value="size" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.2031126337" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" value="make" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.1285759101" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" value="rm" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1410576671" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32e" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.353152664" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.1735833830" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32e" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.796386542" name="Code model" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.low" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune.90660292" name="Tuning" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune.n200series" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.preferxpacksbin.159763604" name="Prefer xpacks/.bin" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.preferxpacksbin" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1863445619" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1533438913" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.extensions.447179843" name="Other extensions" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.extensions" value="_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond" valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.RV_ELF;org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.624485565" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<builder buildPath="${workspace_loc:/Project}/Debug" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1494546460" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1909166920" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1982625252" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.defs.1756055012" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.defs" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
<listOptionValue builtIn="false" value="CONFIG_USE_PEC930"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.1624800055" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/NMSIS/Core/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/Device/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/HAL_Lib/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/BSP/StarterKit}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Common}&quot;"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.724532243" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.991594434" 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.defs.1630974101" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
<listOptionValue builtIn="false" value="CONFIG_USE_PEC930"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1504538192" 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}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/NMSIS/Core/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/Device/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/HAL_Lib/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/BSP/StarterKit}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Common}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.345216805" 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.c99" valueType="enumerated"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1843576227" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.958908384" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.compiler.defs.665145577" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
</option>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1832379824" 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.1847575804" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.other.962260539" name="Other linker flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.other" value="" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.1331613792" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nodeflibs.1405041078" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nodeflibs" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printmap.663083040" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printmap" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.cref.986670320" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.cref" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.1007616047" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/gcc_flashxip.ld}&quot;"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.2005823803" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" valueType="libs">
<listOptionValue builtIn="false" value="c_nano"/>
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="gcc"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.1425978507" name="Linker flags (-Xlinker [option])" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags" valueType="stringList"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.grouplibs.1661588098" name="Group libraries (-Wl,--start-group, ... ,--end-group)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.grouplibs" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.393723091" 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.1387419752" 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.297993148" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.other.720519285" name="Other linker flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.other" value="-u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek " valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.libs.2127007227" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.libs"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.2145124977" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
<tool command="${cross_prefix}${cross_objcopy}${cross_suffix}" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}" id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.586549949" 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.283218197" name="Output file format (-O)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice.ihex" valueType="enumerated"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1070118556" 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.1733954628" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.1626209232" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.280684598" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1695987115" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.1148871387" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble.1301534980" name="Disassemble (--disassemble|-d)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.315205585" 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.1467048234" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
</cconfiguration>
<cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.RV_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552" name="Release" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release">
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552." name="/" resourcePath="">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.837856819" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1208613512" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1016401583" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1246797237" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.2012455781" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.size" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1493955924" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.651822097" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.1717953891" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.541048735" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.360621726" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.1281181250" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.723143813" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" value="2262347901" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.399597377" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" value="RISC-V GCC/Newlib" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.568227293" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" value="riscv64-unknown-elf-" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.639974320" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" value="gcc" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1733841476" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" value="g++" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.789308737" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" value="ar" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1273467405" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" value="objcopy" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1863146323" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" value="objdump" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.350346878" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" value="size" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.1982710953" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" value="make" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.1369963916" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" value="rm" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.371627411" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32e" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.325570710" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.268981471" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32e" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.1135863126" name="Code model" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.low" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune.1264121613" name="Tuning" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune.n200series" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.2138851355" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1576924112" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.RV_ELF;org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.930977981" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<builder buildPath="${workspace_loc:/Project}/Release" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1235026887" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1274001025" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1238271906" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.defs.1967727594" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.defs" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.284910497" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/NMSIS/Core/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/Device/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/HAL_Lib/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/BSP/StarterKit}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Common}&quot;"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1276065282" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1901433257" 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.defs.687116111" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
<listOptionValue builtIn="false" value="NDEBUG"/>
<listOptionValue builtIn="false" value="CONFIG_USE_PEC930"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.140100445" 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}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/NMSIS/Core/Include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/Device/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/HAL_Lib/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/BSP/StarterKit}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Common}&quot;"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.868354821" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1780721496" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.compiler.defs.1060583602" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__IDE_RV_CORE=N203E"/>
</option>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1023024678" 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.589554014" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.other.170075676" name="Other linker flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.other" value="--specs=nosys.specs" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.123103120" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Drivers/PEC930/gcc_flashxip.ld}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nodeflibs.122457886" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nodeflibs" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.507700170" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.1049690196" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" valueType="libs">
<listOptionValue builtIn="false" value="c_nano"/>
<listOptionValue builtIn="false" value="gcc"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.1639406854" 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.554290345" 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.1904431755" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.other.450429501" name="Other linker flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.other" value="-u _isatty -u _write -u _sbrk -u _read -u _close -u _fstat -u _lseek " valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.libs.1125125661" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.libs"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1507570544" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.841899246" 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.413941719" name="Output file format (-O)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createflash.choice.ihex" valueType="enumerated"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.39250443" 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.778908801" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.1081260692" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.212671820" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1206119075" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.625905344" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.1552514466" 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.1158424346" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="Project.ilg.gnumcueclipse.managedbuild.cross.riscv.target.rvelf.1157615279" name="Executable" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.rvelf"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.926872659;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.926872659.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.991594434;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1843576227">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.16434552.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1901433257;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.868354821">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/Project"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/Project"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Project</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>Common</name>
<type>2</type>
<locationURI>PARENT-3-PROJECT_LOC/Common</locationURI>
</link>
<link>
<name>Drivers</name>
<type>2</type>
<locationURI>PARENT-3-PROJECT_LOC/Drivers</locationURI>
</link>
<link>
<name>Profiles</name>
<type>2</type>
<locationURI>PARENT-3-PROJECT_LOC/Tools/scripts/Profiles</locationURI>
</link>
</linkedResources>
<filteredResources>
<filter>
<id>0</id>
<name></name>
<type>6</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.nuproject</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
@@ -0,0 +1,25 @@
SDK_CONFIG:
Debug:
core: N203E
extra_asmflags:
archext:
extra_cxxflags:
cmodel: medlow
extra_commonflags:
abi: ilp32e
arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond
toolchain: gnu
extra_cflags:
extra_ldflags:
Release:
core: N203E
extra_asmflags:
archext:
extra_cxxflags:
cmodel: medlow
extra_commonflags:
abi: ilp32e
arch: rv32emac_zba_zbb_zbs
toolchain: gnu
extra_cflags:
extra_ldflags:
@@ -0,0 +1,16 @@
#
# component Makefile
#
C_SOURCES += \
$(srctree)/$(PROJ)/src/isr.c \
$(srctree)/$(PROJ)/src/main.c
C_INCLUDES += -I$(srctree)/$(PROJ)/inc
LIBS +=
CFLAGS +=
LDFLAGS +=
LIBDIR +=
@@ -0,0 +1,24 @@
/*
* init.h
*
* Created on: 2025年10月9日
* Author: jim_liao
*/
#ifndef INC_INIT_H_
#define INC_INIT_H_
#include "main.h"
void SYS_Config();
void gpio_config();
void opa_config();
void adc_config();
void pwm_config();
void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val);
void pwm_enable();
void pwm_disable();
void pwm_brake();
void uart_config();
void UART_Send_Wait(UART_Type *pHUart, uint16_t value);
#endif /* INC_INIT_H_ */
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file isr.h
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/09/16
* @license
* @description
*/
#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__
#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__
#ifdef __cplusplus
extern "C"
{
#endif
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
extern volatile bool flag_24Khz_timer;
extern volatile bool stringComplete;
extern volatile char rxBuffer[128];
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
void isr_epwm_handle(void);
void isr_adc_handle(void);
void isr_uart0_handle(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file main.h
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/08/29
* @license
* @description
*/
#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__
#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__
#ifdef __cplusplus
extern "C"
{
#endif
#include "hal_device.h"
#include "syslog.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,8 @@
demo_project
---
This example is a demo project to descript `how to log message`
## Log
Use serial port with baudrate 115200, 8bit, no parity check.
@@ -0,0 +1,258 @@
/*
* init.c
*
* Created on: 2025年8月18日
* Author: jim_liao
*/
#include "init.h"
#include "hal_device.h"
#include "isr.h"
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5
unsigned long ADC0Sum = 0;
unsigned char k;
#define HIRC_Freq 60000000 // Hz
#define CurrentLoopIsrFreq 24000 // Hz
#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq
#define DEAD_TIME 200 // ns
#define DEAD_TIME_VALUE DEAD_TIME * 0.06
//=============================================================================
// Public Function Definition
//=============================================================================
void SYS_Config()
{
SYSCFG_ClkInitTypeDef SysClkInit = { 0 };
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
SYSCFG_SysClkConfig(&SysClkInit);
sys_config_systick(SYS_TICK_1_MS);
gpio_config();
opa_config();
adc_config();
pwm_config();
uart_config();
__enable_irq();
}
void gpio_config()
{
//-----------------//
// PWM
//-----------------//
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02
| GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//-----------------//
// UART
// PB3:TX PB5:RX
//-----------------//
GPIO_InitTypeDef GPIOA_InitUart;
GPIOA_InitUart.GPIO_Pin = GPIO_Pin_03;
GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1;
GPIO_Init(GPIOB, &GPIOA_InitUart);
GPIO_InitTypeDef GPIOB_InitUart;
GPIOB_InitUart.GPIO_Pin = GPIO_Pin_05;
GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1;
GPIO_Init(GPIOB, &GPIOB_InitUart);
//-----------------//
// ADC
// PA12/13/14:OVP/OTP/CMD
//-----------------//
GPIO_InitTypeDef GPIO_InitADC;
GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12;
GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL;
GPIO_Init(GPIOA, &GPIO_InitADC);
#if 1
//-----------------//
// test
//-----------------//
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
#endif
}
void opa_config(void)
{
OPAMP_InitTypeDef opa_init = { 0 };
opa_init.OPAMP_VinP = OPAMP_VinP_IO;
opa_init.OPAMP_VinM = OPAMP_VinM_GND;
opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN;
OPAMP_Init(OPAMP0, &opa_init);
OPAMP_Init(OPAMP1, &opa_init);
OPAMP_Enable(OPAMP0);
OPAMP_Enable(OPAMP1);
}
void adc_config(void)
{
ADC_InitTypeDef init = { 0 };
ADC_StructInit(&init);
//-----------------//
// set
//-----------------//
ADC_InitTypeDef init1 = { 0 };
ADC_StructInit(&init1);
init1.SelChannels = ADC_Channel_06 | ADC_Channel_08;
init1.ClkPrescaler = ADC_ClkDiv_4;
init1.DataAlign = ADC_DataAlign_Right;
init1.Mode = ADC_Mode_Scan;
ADC_Init(ADC0, &init1);
ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCR4_UP,
ADC_ExtTrigMode_Enable);
ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCDR4_UP,
ADC_ExtTrigMode_Enable);
#if 0
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = { .disable_vector = false, };
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr);
ADC0->CON0_b.INT_EN = 1;
}
#endif
}
void pwm_config()
{
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = {
.disable_vector = false,
};
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr);
}
TIM_DeInit(EPWM);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct);
TIM_ARRPreloadConfig(EPWM, ENABLE);
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OC1Init(EPWM, &TIM_OCInitStruct);
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OC2Init(EPWM, &TIM_OCInitStruct);
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OC3Init(EPWM, &TIM_OCInitStruct);
{ /* Automatic Output enable, Break, dead time and lock configuration */
TIM_BDTRInitTypeDef bdtr_init = { 0 };
bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF;
bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE;
TIM_BDTRConfig(EPWM, &bdtr_init);
}
EPWM->DIER |= 0x0800; // over flow
// enable preload for CCR1, CCR2 and CCR3
EPWM->CCMR1_OUTPUT_b.OC1PE = 1;
EPWM->CCMR1_OUTPUT_b.OC2PE = 1;
EPWM->CCMR2_OUTPUT_b.OC3PE = 1;
TIM_Cmd(EPWM, ENABLE);
TIM_CtrlPWMOutputs(EPWM, ENABLE);
}
void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
{
EPWM->CCR1 = ch1_val;
EPWM->CCR2 = ch2_val;
EPWM->CCR3 = ch3_val;
return;
}
void pwm_enable()
{
REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk
| TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk
| TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
return;
}
void pwm_disable()
{
REG_CLR_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk
| TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk
| TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
return;
}
void uart_config()
{
UART_InitTypeDef uart_init = { 0 };
uart_init.BaudRate = 115200;
uart_init.WordLength = UART_WordLength_8b;
uart_init.StopBits = UART_StopBits_1;
uart_init.Parity = UART_Parity_No;
uart_init.Mode = UART_Mode_TxRx;
UART_Init(UART0, &uart_init);
UART_Start(UART0);
UART_ITConfig(UART0, UART_FLAG_RXNE, ENABLE);
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = {
.disable_vector = false,
};
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(UART0_IRQn, isr_uart0_handle, &irq_attr);
}
}
void UART_Send_Wait(UART_Type *pHUart, uint16_t value)
{
UART_SendData(pHUart, value);
UART_WaitTxFifoEmpty(pHUart);
}
@@ -0,0 +1,75 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file isr.c
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/09/16
* @license
* @description
*/
#include "isr.h"
#include "init.h"
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
#define RX_BUFFER_SIZE 128
//=============================================================================
// Global Data Definition
//=============================================================================
long ADC_DATA[10];
volatile bool flag_24Khz_timer = false;
volatile char rxBuffer[RX_BUFFER_SIZE];
volatile bool stringComplete = false;
volatile uint16_t rxIndex = 0;
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
__INTERRUPT void isr_epwm_handle(void)
{
if ((EPWM->SR & 0x10000) == 0x10000)
{
flag_24Khz_timer = true;
ADC_DATA[0] = ADC0->DAT6_b.DATA;
ADC_DATA[1] = ADC0->DAT8_b.DATA;
TIM_ClearITPendingBit(EPWM, 0x10000); // clear OVIF
}
}
__INTERRUPT void isr_uart0_handle(void)
{
if (UART_GetITStatus(UART0, UART_FLAG_RXNE) == 1)
{
char receivedChar = (char)UART_ReceiveData(UART0);
if (receivedChar == '\n' || receivedChar == '\r')
{
if (rxIndex > 0)
{
rxBuffer[rxIndex] = '\0';
stringComplete = true;
rxIndex = 0;
msg("Received: %s\n", rxBuffer);
}
}
else if (rxIndex < RX_BUFFER_SIZE - 1)
{
rxBuffer[rxIndex++] = receivedChar;
}
}
}
@@ -0,0 +1,214 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file main.c
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/08/29
* @license
* @description
*/
#include <string.h>
#include "hal_gpio.h"
#include "hal_tim.h"
#include "init.h"
#include "isr.h"
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
#define PWM_TABLE_SIZE 64
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
const uint16_t pwm_table[PWM_TABLE_SIZE]
= { 1250, 1372, 1493, 1612, 1728, 1839, 1944, 2042, 2133, 2216, 2289,
2352, 2404, 2446, 2475, 2493, 2499, 2493, 2475, 2446, 2404, 2352,
2289, 2216, 2133, 2042, 1944, 1839, 1728, 1612, 1493, 1372, 1250,
1127, 1006, 887, 771, 660, 555, 457, 366, 283, 210, 147,
95, 53, 24, 6, 0, 6, 24, 53, 95, 147, 210,
283, 366, 457, 555, 660, 771, 887, 1006, 1127 };
// 64-point sine wave lookup table (-2048-2047 range)
// Sine_table[i] = sin(i*2*pi/64)*(4095/2) where i = 0 to 63
// Use sine_amplitude parameter to scale to desired duty cycle range later
const int16_t LUT_sin[64]
= { 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582,
1702, 1805, 1891, 1959, 2008, 2037, 2047, 2037, 2008, 1959,
1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594,
399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298,
-1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037,
-2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965,
-783, -594, -399, -200 };
const int16_t LUT_cos[64]
= { 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298,
1137, 965, 783, 594, 399, 200, 0, -200, -399, -594,
-783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959,
-2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582,
-1447, -1298, -1137, -965, -783, -594, -399, -200, 0, 200,
399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805,
1891, 1959, 2008, 2037 };
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
#define ENABLE_DDS
#ifdef ENABLE_DDS
struct dds_cal_param
{
uint32_t phase_acc;
uint8_t lut_idx;
uint8_t nquadrant;
uint8_t last_quadrant;
int16_t lut_sin_val;
int16_t lut_cos_val;
uint16_t duty;
};
struct dds_param_t dds ={0};
#define PHASE_COUNT 3
const uint32_t phase_offset[PHASE_COUNT] = { 0, 1398101, 2796203 };
static struct dds_cal_param phase[PHASE_COUNT] = { 0 };
void dds_pwm_duty_cycle_update(void)
{
for (int i = 0; i < PHASE_COUNT; i++)
{
struct dds_cal_param *p = &phase[i];
p->phase_acc = (dds.phase_acc_base + phase_offset[i]) % 0x003FFFFF;
}
for (int i = 0; i < PHASE_COUNT; i++)
{
struct dds_cal_param *p = &phase[i];
p->last_quadrant = p->nquadrant;
p->lut_idx = p->phase_acc >> 16;
p->nquadrant = p->lut_idx >> 4;
p->lut_sin_val = LUT_sin[p->lut_idx];
p->lut_cos_val = LUT_cos[p->lut_idx];
p->duty = (((int32_t)p->lut_sin_val * dds.set_dds_amp) >> 18) + 1250; // 0~2500 duty cycle range
}
pwm_set_duty(phase[0].duty, phase[1].duty, phase[2].duty);
}
#else
void uvw_set_duty(uint16_t base_idx)
{
uint16_t iA = base_idx;
uint16_t iB = (base_idx + PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE;
uint16_t iC = (base_idx + 2 * PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE;
EPWM->CCR1 = pwm_table[iA];
EPWM->CCR2 = pwm_table[iB];
EPWM->CCR3 = pwm_table[iC];
}
#endif
static void cmd_parser(char *data, uint32_t len)
{
char cmd_reply[64] = { 0 };
// echo back received command
sprintf(cmd_reply, "Received command: %s\r\n", data);
msg("%s", cmd_reply);
// parse commands
if (strncmp(data, "help", 4) == 0)
{
msg("Available commands:\r\n");
msg(" help - Show this help message\r\n");
msg(" fw_ver - Show firmware version\r\n");
}
else if (strncmp(data, "fw_ver", 6) == 0)
{
msg("FW_VER_1.0.0_20260320\r\n");
}
else if (strncmp(data, "pwm_enable", 10) == 0)
{
memset(phase, 0, sizeof(phase));
dds.phase_acc_base = 0;
dds.set_dds_ftw = 1740;
dds.set_dds_amp = 160000;
pwm_enable();
msg("PWM enabled.\r\n");
}
else if (strncmp(data, "pwm_disable", 11) == 0)
{
pwm_disable();
msg("PWM disabled.\r\n");
}
else
{
msg("Unknown command. Type 'help' for available commands.\r\n");
}
}
int main(void)
{
uint16_t base_idx = 0;
uint32_t timer = sys_get_tick();
SYS_Config();
info("This is a demo project: JF_02\n");
#ifdef ENABLE_DDS
pwm_set_duty(1250, 1250, 1250);
dds.phase_acc_base = 0;
dds.set_dds_ftw = 1740;
dds.set_dds_amp = 160000;
pwm_enable();
#else
uvw_set_duty(base_idx);
pwm_enable();
#endif
while (1)
{
if (stringComplete)
{
cmd_parser((char *)rxBuffer, strlen((char *)rxBuffer));
stringComplete = false;
}
if (sys_get_tick() - timer >= 1)
{
msg("%d tick\n", sys_get_tick());
timer = sys_get_tick();
}
#ifdef ENABLE_DDS
if (flag_24Khz_timer)
{
dds_pwm_duty_cycle_update();
flag_24Khz_timer = false;
}
#else
if (flag_24Khz_timer)
{
base_idx = (base_idx + 1) % PWM_TABLE_SIZE;
uvw_set_duty(base_idx);
flag_24Khz_timer = false;
}
#endif
}
}
@@ -0,0 +1,6 @@
#ifndef APP2_CMD_SRV_H
#define APP2_CMD_SRV_H
void cmd_srv_process(void);
#endif
@@ -0,0 +1,27 @@
#ifndef APP2_HAL_DRV_H
#define APP2_HAL_DRV_H
#include <stdbool.h>
#include <stdint.h>
#define APP2_UART_RX_BUF_SIZE 128u
void hal_init(void);
/* Producer-side UART RX APIs */
void hal_uart_rx_isr_push_char(char ch);
bool hal_uart_is_frame_ready(void);
const volatile char *hal_uart_get_rx_frame(void);
void hal_uart_clear_rx_frame(void);
/* Consumer-side TX and peripheral APIs */
void hal_uart_send_str(const char *str);
bool hal_spi_send_bytes(const uint8_t *data, uint16_t len);
uint16_t hal_adc_get_latest_mv(void);
int32_t hal_speed_get_feedback_rpm(void);
/* Time base used by services */
uint32_t hal_get_tick_ms(void);
void hal_tick_inc_1ms(void);
#endif
@@ -0,0 +1,29 @@
#ifndef APP2_MOTOR_CTRL_CORE_H
#define APP2_MOTOR_CTRL_CORE_H
#include <stdbool.h>
#include <stdint.h>
typedef struct
{
int32_t target_speed_rpm;
int32_t current_speed_rpm;
int32_t target_amp_permille;
int32_t current_amp_permille;
uint8_t fault_state;
bool motor_enable;
bool regular_data_enable;
uint16_t regular_data_period_ms;
} Motor_Ctrl_t;
extern Motor_Ctrl_t g_motor_ctrl;
void motor_ctrl_init(void);
void motor_ctrl_tick_1ms(void);
bool motor_ctrl_set_target_speed(int32_t rpm);
bool motor_ctrl_set_target_amp(int32_t permille);
void motor_ctrl_set_regular_data_enable(bool en);
void motor_ctrl_set_regular_period_ms(uint16_t period_ms);
#endif
@@ -0,0 +1,6 @@
#ifndef APP2_STREAM_SRV_H
#define APP2_STREAM_SRV_H
void stream_srv_process(void);
#endif
@@ -0,0 +1,124 @@
#include "cmd_srv.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hal_drv.h"
#include "motor_ctrl_core.h"
static int cmd_strcmp(const char *buf, const char *cmd)
{
while (*cmd)
{
if (*buf != *cmd)
return 1;
buf++;
cmd++;
}
return (*buf != '\0');
}
static bool cmd_match_with_arg(const char *buf, const char *prefix, const char **arg_out)
{
size_t len = strlen(prefix);
for (size_t i = 0; i < len; i++)
{
if (buf[i] != prefix[i])
return false;
}
if (buf[len] == ' ')
{
*arg_out = &buf[len + 1];
return true;
}
return false;
}
void cmd_srv_process(void)
{
char cmd_line[APP2_UART_RX_BUF_SIZE] = { 0 };
uint16_t i = 0u;
const char *arg = NULL;
if (!hal_uart_is_frame_ready())
return;
{
const volatile char *rx = hal_uart_get_rx_frame();
while ((i < (APP2_UART_RX_BUF_SIZE - 1u)) && (rx[i] != '\0'))
{
cmd_line[i] = (char)rx[i];
i++;
}
cmd_line[i] = '\0';
}
if (cmd_strcmp(cmd_line, "help") == 0)
{
hal_uart_send_str("help\r\n");
hal_uart_send_str(" spd_set <rpm>\r\n");
hal_uart_send_str(" amp_set <0..1000>\r\n");
hal_uart_send_str(" regular_data_en 1/0\r\n");
hal_uart_send_str(" regular_data_period <ms>\r\n");
hal_uart_send_str(" motor_get\r\n");
}
else if (cmd_match_with_arg(cmd_line, "spd_set", &arg))
{
int32_t rpm = (int32_t)strtol(arg, NULL, 10);
(void)motor_ctrl_set_target_speed(rpm);
hal_uart_send_str("OK spd_set\r\n");
}
else if (cmd_match_with_arg(cmd_line, "amp_set", &arg))
{
int32_t amp = (int32_t)strtol(arg, NULL, 10);
(void)motor_ctrl_set_target_amp(amp);
hal_uart_send_str("OK amp_set\r\n");
}
else if (cmd_match_with_arg(cmd_line, "regular_data_en", &arg))
{
if (arg[0] == '1')
{
motor_ctrl_set_regular_data_enable(true);
hal_uart_send_str("OK regular_data on\r\n");
}
else if (arg[0] == '0')
{
motor_ctrl_set_regular_data_enable(false);
hal_uart_send_str("OK regular_data off\r\n");
}
else
{
hal_uart_send_str("ERR usage: regular_data_en 1/0\r\n");
}
}
else if (cmd_match_with_arg(cmd_line, "regular_data_period", &arg))
{
uint16_t ms = (uint16_t)strtoul(arg, NULL, 10);
motor_ctrl_set_regular_period_ms(ms);
hal_uart_send_str("OK regular_data_period\r\n");
}
else if (cmd_strcmp(cmd_line, "motor_get") == 0)
{
char out[96] = { 0 };
snprintf(out,
sizeof(out),
"target_spd=%ld cur_spd=%ld target_amp=%ld cur_amp=%ld fault=%u stream=%u\r\n",
(long)g_motor_ctrl.target_speed_rpm,
(long)g_motor_ctrl.current_speed_rpm,
(long)g_motor_ctrl.target_amp_permille,
(long)g_motor_ctrl.current_amp_permille,
(unsigned)g_motor_ctrl.fault_state,
(unsigned)g_motor_ctrl.regular_data_enable);
hal_uart_send_str(out);
}
else
{
hal_uart_send_str("ERR unknown cmd\r\n");
}
hal_uart_clear_rx_frame();
}
@@ -0,0 +1,86 @@
#include "hal_drv.h"
#include <stdio.h>
static volatile char s_uart_rx_buf[APP2_UART_RX_BUF_SIZE];
static volatile uint16_t s_uart_rx_idx;
static volatile bool s_uart_frame_ready;
static uint32_t s_tick_ms;
void hal_init(void)
{
s_uart_rx_idx = 0u;
s_uart_rx_buf[0] = '\0';
s_uart_frame_ready = false;
s_tick_ms = 0u;
}
void hal_uart_rx_isr_push_char(char ch)
{
if (s_uart_frame_ready)
return;
if ((ch == '\r') || (ch == '\n'))
{
if (s_uart_rx_idx > 0u)
{
s_uart_rx_buf[s_uart_rx_idx] = '\0';
s_uart_frame_ready = true;
}
return;
}
if (s_uart_rx_idx < (APP2_UART_RX_BUF_SIZE - 1u))
{
s_uart_rx_buf[s_uart_rx_idx++] = ch;
}
}
bool hal_uart_is_frame_ready(void)
{
return s_uart_frame_ready;
}
const volatile char *hal_uart_get_rx_frame(void)
{
return s_uart_rx_buf;
}
void hal_uart_clear_rx_frame(void)
{
s_uart_rx_idx = 0u;
s_uart_rx_buf[0] = '\0';
s_uart_frame_ready = false;
}
void hal_uart_send_str(const char *str)
{
(void)printf("%s", str);
}
bool hal_spi_send_bytes(const uint8_t *data, uint16_t len)
{
(void)data;
(void)len;
return true;
}
uint16_t hal_adc_get_latest_mv(void)
{
return 12000u;
}
int32_t hal_speed_get_feedback_rpm(void)
{
return 1000;
}
uint32_t hal_get_tick_ms(void)
{
return s_tick_ms;
}
void hal_tick_inc_1ms(void)
{
s_tick_ms++;
}
@@ -0,0 +1,28 @@
#include "cmd_srv.h"
#include "hal_drv.h"
#include "motor_ctrl_core.h"
#include "stream_srv.h"
int main(void)
{
hal_init();
motor_ctrl_init();
hal_uart_send_str("app2 demo start\r\n");
while (1)
{
hal_tick_inc_1ms();
/* Parse command frames from HAL RX producer */
cmd_srv_process();
/* Run motor control law at fixed rate */
motor_ctrl_tick_1ms();
/* Stream telemetry when regular_data_en is on */
stream_srv_process();
}
return 0;
}
@@ -0,0 +1,64 @@
#include "motor_ctrl_core.h"
#include "hal_drv.h"
Motor_Ctrl_t g_motor_ctrl;
static int32_t clamp_i32(int32_t x, int32_t lo, int32_t hi)
{
if (x < lo)
return lo;
if (x > hi)
return hi;
return x;
}
void motor_ctrl_init(void)
{
g_motor_ctrl.target_speed_rpm = 0;
g_motor_ctrl.current_speed_rpm = 0;
g_motor_ctrl.target_amp_permille = 0;
g_motor_ctrl.current_amp_permille = 0;
g_motor_ctrl.fault_state = 0u;
g_motor_ctrl.motor_enable = false;
g_motor_ctrl.regular_data_enable = false;
g_motor_ctrl.regular_data_period_ms = 20u;
}
bool motor_ctrl_set_target_speed(int32_t rpm)
{
g_motor_ctrl.target_speed_rpm = clamp_i32(rpm, -6000, 6000);
return true;
}
bool motor_ctrl_set_target_amp(int32_t permille)
{
g_motor_ctrl.target_amp_permille = clamp_i32(permille, 0, 1000);
return true;
}
void motor_ctrl_set_regular_data_enable(bool en)
{
g_motor_ctrl.regular_data_enable = en;
}
void motor_ctrl_set_regular_period_ms(uint16_t period_ms)
{
if (period_ms == 0u)
period_ms = 1u;
g_motor_ctrl.regular_data_period_ms = period_ms;
}
void motor_ctrl_tick_1ms(void)
{
int32_t speed_fb = hal_speed_get_feedback_rpm();
g_motor_ctrl.current_speed_rpm = speed_fb;
if (g_motor_ctrl.current_amp_permille < g_motor_ctrl.target_amp_permille)
g_motor_ctrl.current_amp_permille++;
else if (g_motor_ctrl.current_amp_permille > g_motor_ctrl.target_amp_permille)
g_motor_ctrl.current_amp_permille--;
g_motor_ctrl.fault_state = 0u;
}
@@ -0,0 +1,52 @@
#include "stream_srv.h"
#include <stdint.h>
#include "hal_drv.h"
#include "motor_ctrl_core.h"
static uint32_t s_last_tx_ms;
static void pack_u16_le(uint8_t *buf, uint16_t v)
{
buf[0] = (uint8_t)(v & 0xFFu);
buf[1] = (uint8_t)((v >> 8) & 0xFFu);
}
static void pack_i32_le(uint8_t *buf, int32_t v)
{
uint32_t u = (uint32_t)v;
buf[0] = (uint8_t)(u & 0xFFu);
buf[1] = (uint8_t)((u >> 8) & 0xFFu);
buf[2] = (uint8_t)((u >> 16) & 0xFFu);
buf[3] = (uint8_t)((u >> 24) & 0xFFu);
}
void stream_srv_process(void)
{
uint8_t frame[16];
uint32_t now;
uint16_t bus_mv;
if (!g_motor_ctrl.regular_data_enable)
return;
now = hal_get_tick_ms();
if ((now - s_last_tx_ms) < g_motor_ctrl.regular_data_period_ms)
return;
s_last_tx_ms = now;
bus_mv = hal_adc_get_latest_mv();
frame[0] = 0xA5u;
frame[1] = 0x5Au;
pack_i32_le(&frame[2], g_motor_ctrl.target_speed_rpm);
pack_i32_le(&frame[6], g_motor_ctrl.current_speed_rpm);
frame[10] = (uint8_t)g_motor_ctrl.current_amp_permille;
frame[11] = g_motor_ctrl.fault_state;
pack_u16_le(&frame[12], bus_mv);
frame[14] = 0u;
frame[15] = 0u;
(void)hal_spi_send_bytes(frame, (uint16_t)sizeof(frame));
}
@@ -0,0 +1,8 @@
#ifndef APP_COPYB_CMD_SRV_H
#define APP_COPYB_CMD_SRV_H
#include "comm_if.h"
void cmd_srv_process(const CommIf_t *comm);
#endif
@@ -0,0 +1,27 @@
#ifndef APP_COPYB_COMM_IF_H
#define APP_COPYB_COMM_IF_H
#include <stdbool.h>
#include <stdint.h>
typedef struct
{
const uint8_t *data;
uint16_t len;
} CommFrame_t;
typedef bool (*CommIsReadyFn)(void *ctx);
typedef bool (*CommGetFrameFn)(void *ctx, CommFrame_t *frame);
typedef void (*CommClearFrameFn)(void *ctx);
typedef bool (*CommTxBytesFn)(void *ctx, const uint8_t *data, uint16_t len);
typedef struct
{
void *ctx;
CommIsReadyFn is_ready;
CommGetFrameFn get_frame;
CommClearFrameFn clear_frame;
CommTxBytesFn tx_bytes;
} CommIf_t;
#endif
@@ -0,0 +1,28 @@
#ifndef APP_COPYB_MOTOR_CTRL_CORE_H
#define APP_COPYB_MOTOR_CTRL_CORE_H
#include <stdbool.h>
#include <stdint.h>
typedef struct
{
int32_t target_speed_rpm;
int32_t current_speed_rpm;
int32_t target_amp_permille;
int32_t current_amp_permille;
uint8_t fault_state;
bool regular_data_en;
uint16_t regular_period_ms;
} MotorCtrl_t;
extern MotorCtrl_t g_motor_ctrl;
void motor_ctrl_init(void);
void motor_ctrl_tick_1ms(void);
bool motor_ctrl_set_speed(int32_t rpm);
bool motor_ctrl_set_amp(int32_t amp_permille);
void motor_ctrl_set_regular_en(bool en);
void motor_ctrl_set_regular_period(uint16_t period_ms);
#endif
@@ -0,0 +1,11 @@
#ifndef APP_COPYB_PLATFORM_STUB_H
#define APP_COPYB_PLATFORM_STUB_H
#include <stdint.h>
uint32_t platform_tick_ms(void);
void platform_tick_inc_1ms(void);
uint16_t platform_adc_bus_mv(void);
int32_t platform_speed_feedback_rpm(void);
#endif
@@ -0,0 +1,8 @@
#ifndef APP_COPYB_STREAM_SRV_H
#define APP_COPYB_STREAM_SRV_H
#include "comm_if.h"
void stream_srv_process(const CommIf_t *comm);
#endif
@@ -0,0 +1,14 @@
#ifndef APP_COPYB_TRANSPORT_I2C_H
#define APP_COPYB_TRANSPORT_I2C_H
#include <stdint.h>
#include "comm_if.h"
void transport_i2c_init(void);
const CommIf_t *transport_i2c_get_if(void);
/* ISR callback example for packetized I2C slave writes */
void transport_i2c_rx_frame_push(const uint8_t *data, uint16_t len);
#endif
@@ -0,0 +1,14 @@
#ifndef APP_COPYB_TRANSPORT_SPI_H
#define APP_COPYB_TRANSPORT_SPI_H
#include <stdint.h>
#include "comm_if.h"
void transport_spi_init(void);
const CommIf_t *transport_spi_get_if(void);
/* ISR/DMA callback example for frame push in SPI slave mode */
void transport_spi_rx_frame_push(const uint8_t *data, uint16_t len);
#endif
@@ -0,0 +1,14 @@
#ifndef APP_COPYB_TRANSPORT_UART_H
#define APP_COPYB_TRANSPORT_UART_H
#include <stdint.h>
#include "comm_if.h"
void transport_uart_init(void);
const CommIf_t *transport_uart_get_if(void);
/* ISR entry point example for byte push from UART RX interrupt */
void transport_uart_rx_isr_push_byte(uint8_t ch);
#endif
@@ -0,0 +1,133 @@
#include "cmd_srv.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "motor_ctrl_core.h"
static int cmd_strcmp(const char *buf, const char *cmd)
{
while (*cmd)
{
if (*buf != *cmd)
return 1;
buf++;
cmd++;
}
return (*buf != '\0');
}
static bool cmd_match_with_arg(const char *buf, const char *prefix, const char **arg_out)
{
size_t len = strlen(prefix);
for (size_t i = 0; i < len; i++)
{
if (buf[i] != prefix[i])
return false;
}
if (buf[len] == ' ')
{
*arg_out = &buf[len + 1];
return true;
}
return false;
}
static void comm_send_str(const CommIf_t *comm, const char *str)
{
(void)comm->tx_bytes(comm->ctx, (const uint8_t *)str, (uint16_t)strlen(str));
}
void cmd_srv_process(const CommIf_t *comm)
{
char cmd_line[128] = { 0 };
CommFrame_t frame = { 0 };
uint16_t copy_len;
const char *arg = NULL;
if (!comm->is_ready(comm->ctx))
return;
if (!comm->get_frame(comm->ctx, &frame))
{
comm->clear_frame(comm->ctx);
return;
}
copy_len = frame.len;
if (copy_len >= sizeof(cmd_line))
copy_len = (uint16_t)(sizeof(cmd_line) - 1u);
(void)memcpy(cmd_line, frame.data, copy_len);
cmd_line[copy_len] = '\0';
if (cmd_strcmp(cmd_line, "help") == 0)
{
comm_send_str(comm, "help\r\n");
comm_send_str(comm, " spd_set <rpm>\r\n");
comm_send_str(comm, " amp_set <0..1000>\r\n");
comm_send_str(comm, " regular_data_en 1/0\r\n");
comm_send_str(comm, " regular_data_period <ms>\r\n");
comm_send_str(comm, " motor_get\r\n");
}
else if (cmd_match_with_arg(cmd_line, "spd_set", &arg))
{
int32_t rpm = (int32_t)strtol(arg, NULL, 10);
(void)motor_ctrl_set_speed(rpm);
comm_send_str(comm, "OK spd_set\r\n");
}
else if (cmd_match_with_arg(cmd_line, "amp_set", &arg))
{
int32_t amp = (int32_t)strtol(arg, NULL, 10);
(void)motor_ctrl_set_amp(amp);
comm_send_str(comm, "OK amp_set\r\n");
}
else if (cmd_match_with_arg(cmd_line, "regular_data_en", &arg))
{
if (arg[0] == '1')
{
motor_ctrl_set_regular_en(true);
comm_send_str(comm, "OK regular_data on\r\n");
}
else if (arg[0] == '0')
{
motor_ctrl_set_regular_en(false);
comm_send_str(comm, "OK regular_data off\r\n");
}
else
{
comm_send_str(comm, "ERR usage: regular_data_en 1/0\r\n");
}
}
else if (cmd_match_with_arg(cmd_line, "regular_data_period", &arg))
{
uint16_t period = (uint16_t)strtoul(arg, NULL, 10);
motor_ctrl_set_regular_period(period);
comm_send_str(comm, "OK regular_data_period\r\n");
}
else if (cmd_strcmp(cmd_line, "motor_get") == 0)
{
char out[128] = { 0 };
(void)snprintf(out,
sizeof(out),
"target_spd=%ld cur_spd=%ld target_amp=%ld cur_amp=%ld fault=%u stream=%u\r\n",
(long)g_motor_ctrl.target_speed_rpm,
(long)g_motor_ctrl.current_speed_rpm,
(long)g_motor_ctrl.target_amp_permille,
(long)g_motor_ctrl.current_amp_permille,
(unsigned)g_motor_ctrl.fault_state,
(unsigned)g_motor_ctrl.regular_data_en);
comm_send_str(comm, out);
}
else
{
comm_send_str(comm, "ERR unknown cmd\r\n");
}
comm->clear_frame(comm->ctx);
}
@@ -0,0 +1,47 @@
#include "cmd_srv.h"
#include "motor_ctrl_core.h"
#include "platform_stub.h"
#include "stream_srv.h"
#include "transport_i2c.h"
#include "transport_spi.h"
#include "transport_uart.h"
#define APP_COPYB_TRANSPORT_UART 1
#define APP_COPYB_TRANSPORT_SPI 2
#define APP_COPYB_TRANSPORT_I2C 3
#ifndef APP_COPYB_TRANSPORT_SELECT
#define APP_COPYB_TRANSPORT_SELECT APP_COPYB_TRANSPORT_UART
#endif
static const CommIf_t *select_transport(void)
{
#if APP_COPYB_TRANSPORT_SELECT == APP_COPYB_TRANSPORT_UART
transport_uart_init();
return transport_uart_get_if();
#elif APP_COPYB_TRANSPORT_SELECT == APP_COPYB_TRANSPORT_SPI
transport_spi_init();
return transport_spi_get_if();
#else
transport_i2c_init();
return transport_i2c_get_if();
#endif
}
int main(void)
{
const CommIf_t *comm = select_transport();
motor_ctrl_init();
while (1)
{
platform_tick_inc_1ms();
cmd_srv_process(comm);
motor_ctrl_tick_1ms();
stream_srv_process(comm);
}
return 0;
}
@@ -0,0 +1,61 @@
#include "motor_ctrl_core.h"
#include "platform_stub.h"
MotorCtrl_t g_motor_ctrl;
static int32_t clamp_i32(int32_t value, int32_t min_v, int32_t max_v)
{
if (value < min_v)
return min_v;
if (value > max_v)
return max_v;
return value;
}
void motor_ctrl_init(void)
{
g_motor_ctrl.target_speed_rpm = 0;
g_motor_ctrl.current_speed_rpm = 0;
g_motor_ctrl.target_amp_permille = 0;
g_motor_ctrl.current_amp_permille = 0;
g_motor_ctrl.fault_state = 0u;
g_motor_ctrl.regular_data_en = false;
g_motor_ctrl.regular_period_ms = 20u;
}
void motor_ctrl_tick_1ms(void)
{
g_motor_ctrl.current_speed_rpm = platform_speed_feedback_rpm();
if (g_motor_ctrl.current_amp_permille < g_motor_ctrl.target_amp_permille)
g_motor_ctrl.current_amp_permille++;
else if (g_motor_ctrl.current_amp_permille > g_motor_ctrl.target_amp_permille)
g_motor_ctrl.current_amp_permille--;
g_motor_ctrl.fault_state = 0u;
}
bool motor_ctrl_set_speed(int32_t rpm)
{
g_motor_ctrl.target_speed_rpm = clamp_i32(rpm, -6000, 6000);
return true;
}
bool motor_ctrl_set_amp(int32_t amp_permille)
{
g_motor_ctrl.target_amp_permille = clamp_i32(amp_permille, 0, 1000);
return true;
}
void motor_ctrl_set_regular_en(bool en)
{
g_motor_ctrl.regular_data_en = en;
}
void motor_ctrl_set_regular_period(uint16_t period_ms)
{
if (period_ms == 0u)
period_ms = 1u;
g_motor_ctrl.regular_period_ms = period_ms;
}
@@ -0,0 +1,23 @@
#include "platform_stub.h"
static uint32_t s_tick_ms;
uint32_t platform_tick_ms(void)
{
return s_tick_ms;
}
void platform_tick_inc_1ms(void)
{
s_tick_ms++;
}
uint16_t platform_adc_bus_mv(void)
{
return 12000u;
}
int32_t platform_speed_feedback_rpm(void)
{
return 1000;
}
@@ -0,0 +1,50 @@
#include "stream_srv.h"
#include <stdint.h>
#include "motor_ctrl_core.h"
#include "platform_stub.h"
static uint32_t s_last_tx_ms;
static void pack_u16_le(uint8_t *buf, uint16_t v)
{
buf[0] = (uint8_t)(v & 0xFFu);
buf[1] = (uint8_t)((v >> 8) & 0xFFu);
}
static void pack_i32_le(uint8_t *buf, int32_t v)
{
uint32_t uv = (uint32_t)v;
buf[0] = (uint8_t)(uv & 0xFFu);
buf[1] = (uint8_t)((uv >> 8) & 0xFFu);
buf[2] = (uint8_t)((uv >> 16) & 0xFFu);
buf[3] = (uint8_t)((uv >> 24) & 0xFFu);
}
void stream_srv_process(const CommIf_t *comm)
{
uint8_t frame[16];
uint32_t now;
if (!g_motor_ctrl.regular_data_en)
return;
now = platform_tick_ms();
if ((now - s_last_tx_ms) < g_motor_ctrl.regular_period_ms)
return;
s_last_tx_ms = now;
frame[0] = 0xA5u;
frame[1] = 0x5Au;
pack_i32_le(&frame[2], g_motor_ctrl.target_speed_rpm);
pack_i32_le(&frame[6], g_motor_ctrl.current_speed_rpm);
frame[10] = (uint8_t)g_motor_ctrl.current_amp_permille;
frame[11] = g_motor_ctrl.fault_state;
pack_u16_le(&frame[12], platform_adc_bus_mv());
frame[14] = 0u;
frame[15] = 0u;
(void)comm->tx_bytes(comm->ctx, frame, (uint16_t)sizeof(frame));
}
@@ -0,0 +1,79 @@
#include "transport_i2c.h"
#include <string.h>
typedef struct
{
volatile uint8_t rx_buf[128];
volatile uint16_t rx_len;
volatile bool frame_ready;
} I2cTransport_t;
static I2cTransport_t s_i2c;
static bool i2c_is_ready(void *ctx)
{
I2cTransport_t *i = (I2cTransport_t *)ctx;
return i->frame_ready;
}
static bool i2c_get_frame(void *ctx, CommFrame_t *frame)
{
I2cTransport_t *i = (I2cTransport_t *)ctx;
if (!i->frame_ready)
return false;
frame->data = (const uint8_t *)i->rx_buf;
frame->len = i->rx_len;
return true;
}
static void i2c_clear_frame(void *ctx)
{
I2cTransport_t *i = (I2cTransport_t *)ctx;
i->rx_len = 0u;
i->rx_buf[0] = 0u;
i->frame_ready = false;
}
static bool i2c_tx_bytes(void *ctx, const uint8_t *data, uint16_t len)
{
(void)ctx;
(void)data;
(void)len;
return true;
}
static const CommIf_t s_i2c_if = {
.ctx = &s_i2c,
.is_ready = i2c_is_ready,
.get_frame = i2c_get_frame,
.clear_frame = i2c_clear_frame,
.tx_bytes = i2c_tx_bytes,
};
void transport_i2c_init(void)
{
(void)memset((void *)&s_i2c, 0, sizeof(s_i2c));
}
const CommIf_t *transport_i2c_get_if(void)
{
return &s_i2c_if;
}
void transport_i2c_rx_frame_push(const uint8_t *data, uint16_t len)
{
uint16_t copy_len;
if ((data == NULL) || (len == 0u) || s_i2c.frame_ready)
return;
copy_len = len;
if (copy_len >= (uint16_t)sizeof(s_i2c.rx_buf))
copy_len = (uint16_t)(sizeof(s_i2c.rx_buf) - 1u);
(void)memcpy((void *)s_i2c.rx_buf, data, copy_len);
s_i2c.rx_buf[copy_len] = 0u;
s_i2c.rx_len = copy_len;
s_i2c.frame_ready = true;
}
@@ -0,0 +1,80 @@
#include "transport_spi.h"
#include <stdio.h>
#include <string.h>
typedef struct
{
volatile uint8_t rx_buf[128];
volatile uint16_t rx_len;
volatile bool frame_ready;
} SpiTransport_t;
static SpiTransport_t s_spi;
static bool spi_is_ready(void *ctx)
{
SpiTransport_t *s = (SpiTransport_t *)ctx;
return s->frame_ready;
}
static bool spi_get_frame(void *ctx, CommFrame_t *frame)
{
SpiTransport_t *s = (SpiTransport_t *)ctx;
if (!s->frame_ready)
return false;
frame->data = (const uint8_t *)s->rx_buf;
frame->len = s->rx_len;
return true;
}
static void spi_clear_frame(void *ctx)
{
SpiTransport_t *s = (SpiTransport_t *)ctx;
s->rx_len = 0u;
s->rx_buf[0] = 0u;
s->frame_ready = false;
}
static bool spi_tx_bytes(void *ctx, const uint8_t *data, uint16_t len)
{
(void)ctx;
(void)data;
(void)len;
return true;
}
static const CommIf_t s_spi_if = {
.ctx = &s_spi,
.is_ready = spi_is_ready,
.get_frame = spi_get_frame,
.clear_frame = spi_clear_frame,
.tx_bytes = spi_tx_bytes,
};
void transport_spi_init(void)
{
(void)memset((void *)&s_spi, 0, sizeof(s_spi));
}
const CommIf_t *transport_spi_get_if(void)
{
return &s_spi_if;
}
void transport_spi_rx_frame_push(const uint8_t *data, uint16_t len)
{
uint16_t copy_len;
if ((data == NULL) || (len == 0u) || s_spi.frame_ready)
return;
copy_len = len;
if (copy_len >= (uint16_t)sizeof(s_spi.rx_buf))
copy_len = (uint16_t)(sizeof(s_spi.rx_buf) - 1u);
(void)memcpy((void *)s_spi.rx_buf, data, copy_len);
s_spi.rx_buf[copy_len] = 0u;
s_spi.rx_len = copy_len;
s_spi.frame_ready = true;
}
@@ -0,0 +1,81 @@
#include "transport_uart.h"
#include <stdio.h>
#include <string.h>
typedef struct
{
volatile uint8_t rx_buf[128];
volatile uint16_t rx_len;
volatile bool frame_ready;
} UartTransport_t;
static UartTransport_t s_uart;
static bool uart_is_ready(void *ctx)
{
UartTransport_t *u = (UartTransport_t *)ctx;
return u->frame_ready;
}
static bool uart_get_frame(void *ctx, CommFrame_t *frame)
{
UartTransport_t *u = (UartTransport_t *)ctx;
if (!u->frame_ready)
return false;
frame->data = (const uint8_t *)u->rx_buf;
frame->len = u->rx_len;
return true;
}
static void uart_clear_frame(void *ctx)
{
UartTransport_t *u = (UartTransport_t *)ctx;
u->rx_len = 0u;
u->rx_buf[0] = 0u;
u->frame_ready = false;
}
static bool uart_tx_bytes(void *ctx, const uint8_t *data, uint16_t len)
{
(void)ctx;
(void)fwrite(data, 1u, len, stdout);
return true;
}
static const CommIf_t s_uart_if = {
.ctx = &s_uart,
.is_ready = uart_is_ready,
.get_frame = uart_get_frame,
.clear_frame = uart_clear_frame,
.tx_bytes = uart_tx_bytes,
};
void transport_uart_init(void)
{
(void)memset((void *)&s_uart, 0, sizeof(s_uart));
}
const CommIf_t *transport_uart_get_if(void)
{
return &s_uart_if;
}
void transport_uart_rx_isr_push_byte(uint8_t ch)
{
if (s_uart.frame_ready)
return;
if ((ch == '\r') || (ch == '\n'))
{
if (s_uart.rx_len > 0u)
s_uart.frame_ready = true;
return;
}
if (s_uart.rx_len < (uint16_t)(sizeof(s_uart.rx_buf) - 1u))
{
s_uart.rx_buf[s_uart.rx_len++] = ch;
s_uart.rx_buf[s_uart.rx_len] = 0u;
}
}
@@ -8,6 +8,8 @@
#ifndef INC_INIT_H_
#define INC_INIT_H_
#include "main.h"
void SYS_Config();
void gpio_config();
void opa_config();
@@ -14,35 +14,39 @@
#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
extern volatile bool flag_24Khz_timer;
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
extern volatile bool flag_24Khz_timer;
extern volatile bool stringComplete;
extern volatile char rxBuffer[128];
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
void isr_epwm_handle(void);
void isr_adc_handle(void);
//=============================================================================
// Public Function Definition
//=============================================================================
void isr_epwm_handle(void);
void isr_adc_handle(void);
void isr_uart0_handle(void);
#ifdef __cplusplus
}
#endif
@@ -14,35 +14,45 @@
#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include "hal_device.h"
#include "syslog.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
struct dds_param_t
{
uint32_t phase_acc_base;
uint32_t set_dds_ftw;
int32_t set_dds_amp;
uint8_t notify_en;
};
extern struct dds_param_t dds;
#ifdef __cplusplus
}
@@ -4,34 +4,38 @@
* Created on: 2025年8月18日
* Author: jim_liao
*/
#include "main.h"
#include "isr.h"
#include "init.h"
#include "hal_device.h"
#include "isr.h"
//=============================================================================
// Constant Definition
//=============================================================================
#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5
#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5
unsigned long ADC0Sum = 0;
unsigned char k;
#define HIRC_Freq 60000000 //Hz
#define CurrentLoopIsrFreq 24000 //Hz
#define PWM_PERIOD HIRC_Freq/CurrentLoopIsrFreq
#define DEAD_TIME 200 //ns
#define DEAD_TIME_VALUE DEAD_TIME*0.06
#define HIRC_Freq 60000000 // Hz
#define CurrentLoopIsrFreq 24000 // Hz
#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq
#define DEAD_TIME 200 // ns
#define DEAD_TIME_VALUE DEAD_TIME * 0.06
//=============================================================================
// Public Function Definition
//=============================================================================
void SYS_Config()
{
SYSCFG_ClkInitTypeDef SysClkInit = {0};
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
SYSCFG_ClkInitTypeDef SysClkInit = { 0 };
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
SYSCFG_SysClkConfig(&SysClkInit);
sys_config_systick(SYS_TICK_1_MS);
sys_delay(3000);
/* Disable ICE I/O */
//SYSCFG_SetICEPin2NormalIO(true);
gpio_config();
opa_config();
@@ -44,54 +48,54 @@ void SYS_Config()
void gpio_config()
{
//-----------------//
// PWM
//-----------------//
GPIO_InitTypeDef GPIO_InitStruct;
//-----------------//
// PWM
//-----------------//
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | \
GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02
| GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//-----------------//
// UART
// PB3:TX PB5:RX
//-----------------//
GPIO_InitTypeDef GPIOA_InitUart;
GPIOA_InitUart.GPIO_Pin = GPIO_Pin_03;
GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1;
//-----------------//
// UART
// PB3:TX PB5:RX
//-----------------//
GPIO_InitTypeDef GPIOA_InitUart;
GPIOA_InitUart.GPIO_Pin = GPIO_Pin_03;
GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1;
GPIO_Init(GPIOB, &GPIOA_InitUart);
GPIO_InitTypeDef GPIOB_InitUart;
GPIOB_InitUart.GPIO_Pin = GPIO_Pin_05;
GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1;
GPIO_InitTypeDef GPIOB_InitUart;
GPIOB_InitUart.GPIO_Pin = GPIO_Pin_05;
GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF;
GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1;
GPIO_Init(GPIOB, &GPIOB_InitUart);
//-----------------//
// ADC
// PA12/13/14:OVP/OTP/CMD
//-----------------//
GPIO_InitTypeDef GPIO_InitADC;
GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12;
GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL;
//-----------------//
// ADC
// PA06/12:VBUS/ADC_KEY
//-----------------//
GPIO_InitTypeDef GPIO_InitADC;
GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12;
GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL;
GPIO_Init(GPIOA, &GPIO_InitADC);
#if 1
//-----------------//
// test
//-----------------//
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA , &GPIO_InitStruct);
//-----------------//
// test
//-----------------//
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
#endif
}
void opa_config(void)
{
OPAMP_InitTypeDef opa_init = {0};
OPAMP_InitTypeDef opa_init = { 0 };
opa_init.OPAMP_VinP = OPAMP_VinP_IO;
opa_init.OPAMP_VinM = OPAMP_VinM_GND;
@@ -104,28 +108,27 @@ void opa_config(void)
OPAMP_Enable(OPAMP1);
}
void adc_config(void)
{
ADC_InitTypeDef init = {0};
ADC_InitTypeDef init = { 0 };
ADC_StructInit(&init);
//-----------------//
// set
//-----------------//
ADC_InitTypeDef init1 = {0};
//-----------------//
// set
//-----------------//
ADC_InitTypeDef init1 = { 0 };
ADC_StructInit(&init1);
init1.SelChannels = ADC_Channel_06 |ADC_Channel_08;
init1.ClkPrescaler = ADC_ClkDiv_4;
init1.DataAlign = ADC_DataAlign_Right;
init1.Mode = ADC_Mode_Scan;
init1.SelChannels = ADC_Channel_06 | ADC_Channel_08;
init1.ClkPrescaler = ADC_ClkDiv_4;
init1.DataAlign = ADC_DataAlign_Right;
init1.Mode = ADC_Mode_Scan;
ADC_Init(ADC0, &init1);
ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCR4_UP,ADC_ExtTrigMode_Enable);
ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCDR4_UP,ADC_ExtTrigMode_Enable);
ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCR4_UP,
ADC_ExtTrigMode_Enable);
ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCDR4_UP,
ADC_ExtTrigMode_Enable);
#if 0
{ /* Configure TIM interrupts */
@@ -140,18 +143,19 @@ void adc_config(void)
#endif
}
void pwm_config()
{
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = { .disable_vector = false, };
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = {
.disable_vector = false,
};
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr);
}
@@ -160,23 +164,23 @@ void pwm_config()
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD-1;
TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct);
TIM_ARRPreloadConfig(EPWM,ENABLE);
TIM_ARRPreloadConfig(EPWM, ENABLE);
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OC1Init(EPWM, &TIM_OCInitStruct);
TIM_OCInitStruct.TIM_Pulse = 1;
@@ -185,8 +189,8 @@ void pwm_config()
TIM_OCInitStruct.TIM_Pulse = 1;
TIM_OC3Init(EPWM, &TIM_OCInitStruct);
{ /* Automatic Output enable, Break, dead time and lock configuration */
TIM_BDTRInitTypeDef bdtr_init = {0};
{ /* Automatic Output enable, Break, dead time and lock configuration */
TIM_BDTRInitTypeDef bdtr_init = { 0 };
bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF;
bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE;
@@ -201,8 +205,7 @@ void pwm_config()
EPWM->CCMR2_OUTPUT_b.OC3PE = 1;
TIM_Cmd(EPWM, ENABLE);
TIM_CtrlPWMOutputs(EPWM,ENABLE);
TIM_CtrlPWMOutputs(EPWM, ENABLE);
}
void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
@@ -214,28 +217,49 @@ void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
}
void pwm_enable()
{
REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk | \
TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk | \
TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk
| TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk
| TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
return;
}
void pwm_disable()
{
REG_CLR_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk
| TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk
| TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk);
return;
}
void uart_config()
{
UART_InitTypeDef uart_init = {0};
uart_init.BaudRate = 115200;
uart_init.WordLength = UART_WordLength_8b;
uart_init.StopBits = UART_StopBits_1;
uart_init.Parity = UART_Parity_No;
uart_init.Mode = UART_Mode_TxRx;
UART_InitTypeDef uart_init = { 0 };
uart_init.BaudRate = 115200;
uart_init.WordLength = UART_WordLength_8b;
uart_init.StopBits = UART_StopBits_1;
uart_init.Parity = UART_Parity_No;
uart_init.Mode = UART_Mode_TxRx;
UART_Init(UART0, &uart_init);
UART_Start(UART0);
// Wait for UART to be ready after initialization
for (volatile uint32_t i = 0; i < 10000; i++);
UART_ITConfig(UART0, UART_FLAG_RXNE, ENABLE);
{ /* Configure TIM interrupts */
sys_irq_attr_t irq_attr = {
.disable_vector = false,
};
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(UART0_IRQn, isr_uart0_handle, &irq_attr);
}
}
void UART_Send_Wait(UART_Type *pHUart, uint16_t value)
{
UART_SendData(pHUart,value);
UART_SendData(pHUart, value);
UART_WaitTxFifoEmpty(pHUart);
}
@@ -11,9 +11,11 @@
*/
#include "main.h"
#include "isr.h"
#include "init.h"
//=============================================================================
// Constant Definition
//=============================================================================
@@ -21,12 +23,16 @@
//=============================================================================
// Macro Definition
//=============================================================================
#define RX_BUFFER_SIZE 128
//=============================================================================
// Global Data Definition
//=============================================================================
long ADC_DATA[10];
volatile bool flag_24Khz_timer = false;
volatile char rxBuffer[RX_BUFFER_SIZE];
volatile bool stringComplete = false;
volatile uint16_t rxIndex = 0;
//=============================================================================
// Private Function Definition
//=============================================================================
@@ -37,17 +43,35 @@ volatile bool flag_24Khz_timer = false;
__INTERRUPT void isr_epwm_handle(void)
{
if ((EPWM->SR & 0x10000) == 0x10000)
if ((EPWM->SR & 0x10000) == 0x10000)
{
flag_24Khz_timer = true;
ADC_DATA[0] = ADC0->DAT6_b.DATA;
ADC_DATA[1] = ADC0->DAT8_b.DATA;
TIM_ClearITPendingBit(EPWM, 0x10000); // clear OVIF
GPIO_TogglePin(GPIOA, GPIO_Pin_14);
flag_24Khz_timer = true;
ADC_DATA[0] = ADC0->DAT6_b.DATA;
ADC_DATA[1] = ADC0->DAT8_b.DATA;
dds.phase_acc_base += dds.set_dds_ftw;
TIM_ClearITPendingBit(EPWM, 0x10000); // clear OVIF
}
}
__INTERRUPT void isr_uart0_handle(void)
{
if (UART_GetITStatus(UART0, UART_FLAG_RXNE) == 1)
{
char receivedChar = (char)UART_ReceiveData(UART0);
if (receivedChar == '\n' || receivedChar == '\r')
{
if (rxIndex > 0)
{
rxBuffer[rxIndex] = '\0';
stringComplete = true;
rxIndex = 0;
msg("Received: %s\n", rxBuffer);
}
}
else if (rxIndex < RX_BUFFER_SIZE - 1)
{
rxBuffer[rxIndex++] = receivedChar;
}
}
}
@@ -9,10 +9,11 @@
* @license
* @description
*/
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "hal_gpio.h"
#include "hal_tim.h"
#include "init.h"
#include "isr.h"
@@ -38,6 +39,28 @@ const uint16_t pwm_table[PWM_TABLE_SIZE]
1127, 1006, 887, 771, 660, 555, 457, 366, 283, 210, 147,
95, 53, 24, 6, 0, 6, 24, 53, 95, 147, 210,
283, 366, 457, 555, 660, 771, 887, 1006, 1127 };
// 64-point sine wave lookup table (-2048-2047 range)
// Sine_table[i] = sin(i*2*pi/64)*(4095/2) where i = 0 to 63
// Use sine_amplitude parameter to scale to desired duty cycle range later
const int16_t LUT_sin[64]
= { 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582,
1702, 1805, 1891, 1959, 2008, 2037, 2047, 2037, 2008, 1959,
1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594,
399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298,
-1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037,
-2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965,
-783, -594, -399, -200 };
const int16_t LUT_cos[64]
= { 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298,
1137, 965, 783, 594, 399, 200, 0, -200, -399, -594,
-783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959,
-2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582,
-1447, -1298, -1137, -965, -783, -594, -399, -200, 0, 200,
399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805,
1891, 1959, 2008, 2037 };
//=============================================================================
// Private Function Definition
//=============================================================================
@@ -45,6 +68,50 @@ const uint16_t pwm_table[PWM_TABLE_SIZE]
//=============================================================================
// Public Function Definition
//=============================================================================
#define ENABLE_DDS
#ifdef ENABLE_DDS
struct dds_cal_param
{
uint32_t phase_acc;
uint8_t lut_idx;
uint8_t nquadrant;
uint8_t last_quadrant;
int16_t lut_sin_val;
int16_t lut_cos_val;
uint16_t duty;
};
struct dds_param_t dds = { 0 };
#define PHASE_COUNT 3
const uint32_t phase_offset[PHASE_COUNT] = { 0, 1398101, 2796203 };
static struct dds_cal_param phase[PHASE_COUNT] = { 0 };
void dds_pwm_duty_cycle_update(void)
{
for (int i = 0; i < PHASE_COUNT; i++)
{
struct dds_cal_param *p = &phase[i];
p->phase_acc = (dds.phase_acc_base + phase_offset[i]) % 0x003FFFFF;
}
for (int i = 0; i < PHASE_COUNT; i++)
{
struct dds_cal_param *p = &phase[i];
p->last_quadrant = p->nquadrant;
p->lut_idx = p->phase_acc >> 16;
p->nquadrant = p->lut_idx >> 4;
p->lut_sin_val = LUT_sin[p->lut_idx];
p->lut_cos_val = LUT_cos[p->lut_idx];
p->duty = (((int32_t)p->lut_sin_val * dds.set_dds_amp) >> 18)
+ 1250; // 0~2500 duty cycle range
}
pwm_set_duty(phase[0].duty, phase[1].duty, phase[2].duty);
}
#else
void uvw_set_duty(uint16_t base_idx)
{
uint16_t iA = base_idx;
@@ -55,30 +122,140 @@ void uvw_set_duty(uint16_t base_idx)
EPWM->CCR2 = pwm_table[iB];
EPWM->CCR3 = pwm_table[iC];
}
#endif
static void cmd_parser(char *data, uint32_t len)
{
char cmd_reply[64] = { 0 };
// echo back received command
sprintf(cmd_reply, "Received command: %s\r\n", data);
printf("%s", cmd_reply);
// parse commands
if (strncmp(data, "help", 4) == 0)
{
printf("Available commands:\r\n");
printf(" help - Show this help message\r\n");
printf(" fw_ver - Show firmware version\r\n");
}
else if (strncmp(data, "fw_ver", 6) == 0)
{
printf("FW_VER_1.0.0_20260320\r\n");
}
else if (strncmp(data, "dds_init", 8) == 0)
{
memset(phase, 0, sizeof(phase));
dds.phase_acc_base = 0;
dds.set_dds_ftw = 174;
dds.set_dds_amp = 0;
}
else if (strncmp(data, "pwm_enable", 10) == 0)
{
pwm_enable();
printf("PWM enabled.\r\n");
}
else if (strncmp(data, "pwm_disable", 11) == 0)
{
pwm_disable();
printf("PWM disabled.\r\n");
}
else if (strncmp(data, "dds_amp++", 9) == 0)
{
dds.set_dds_amp++;
printf("dds_amp++\r\n");
}
else if (strncmp(data, "dds_amp--", 9) == 0)
{
dds.set_dds_amp--;
printf("dds_amp--\r\n");
}
else if (strncmp(data, "dds_ftw++", 9) == 0)
{
dds.set_dds_ftw++;
printf("dds_ftw++\r\n");
}
else if (strncmp(data, "dds_ftw--", 9) == 0)
{
dds.set_dds_ftw--;
printf("dds_ftw--\r\n");
}
else if (strncmp(data, "dds_amp:", 8) == 0)
{
dds.set_dds_amp = atoi(data + 8);
printf("dds_amp set to %d\r\n", dds.set_dds_amp);
}
else if (strncmp(data, "dds_ftw:", 8) == 0)
{
dds.set_dds_ftw = atoi(data + 8);
printf("dds_ftw set to %d\r\n", dds.set_dds_ftw);
}
else if (strncmp(data, "notify_en:", 10) == 0)
{
dds.notify_en = atoi(data + 10);
if (dds.notify_en)
{
printf("Notification enabled.\r\n");
}
else
{
printf("Notification disabled.\r\n");
}
}
else
{
printf("Unknown command. Type 'help' for available commands.\r\n");
}
}
int main(void)
{
uint16_t base_idx = 0;
uint32_t timer = sys_get_tick();
uint32_t timer;
SYS_Config();
info("This is a demo project: JF_02\n");
printf("This is a demo project: JF_02\n");
#ifdef ENABLE_DDS
pwm_set_duty(1250, 1250, 1250);
dds.phase_acc_base = 0;
dds.set_dds_ftw = 174;
dds.set_dds_amp = 0;
pwm_enable();
#else
uvw_set_duty(base_idx);
pwm_enable();
#endif
timer = sys_get_tick();
while (1)
{
if (sys_get_tick() - timer >= 1000)
if (stringComplete)
{
msg("%d tick\n", sys_get_tick());
timer = sys_get_tick();
cmd_parser((char *)rxBuffer, strlen((char *)rxBuffer));
stringComplete = false;
}
#ifdef ENABLE_DDS
if (flag_24Khz_timer)
{
dds_pwm_duty_cycle_update();
if (dds.notify_en)
{
printf("%d tick: %d, %d, %d\n", sys_get_tick(), phase[0].duty,
phase[1].duty, phase[2].duty);
}
flag_24Khz_timer = false;
}
#else
if (flag_24Khz_timer)
{
base_idx = (base_idx + 1) % PWM_TABLE_SIZE;
uvw_set_duty(base_idx);
flag_24Khz_timer = false;
}
#endif
}
}
@@ -57,7 +57,7 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/>
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;peripherals/&gt;&#13;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration>
+198
View File
@@ -0,0 +1,198 @@
/**
* Copyright (c) 2026 Wisetop. All Rights Reserved.
*/
/** @file main.c
*
* @version 0.0.1
* @date 2026/04/22
* @license
* @description
*/
#include "main.h"
#include "hal_gpio.h"
#include "hal_tim.h"
#include "uart_cmd_srv.h"
//=============================================================================
// Constant Definition
//=============================================================================
#define EPWM_TARGET_FREQ_HZ (24000U)
#define EPWM_TIM_CLOCK_HZ (60000000U)
#define PWM_TABLE_SIZE (64U)
// Example: 50Hz electrical frequency in Q0.32 phase accumulator domain.
#define PHASE_TARGET_FREQ_HZ (50U)
#define PHASE_OFFSET_120_DEG_Q32 (0x55555555UL)
#define PHASE_OFFSET_240_DEG_Q32 (0xAAAAAAAAUL)
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
static const uint16_t pwm_table[PWM_TABLE_SIZE]
= { 1250, 1372, 1493, 1612, 1728, 1839, 1944, 2042, 2133, 2216, 2289,
2352, 2404, 2446, 2475, 2493, 2499, 2493, 2475, 2446, 2404, 2352,
2289, 2216, 2133, 2042, 1944, 1839, 1728, 1612, 1493, 1372, 1250,
1127, 1006, 887, 771, 660, 555, 457, 366, 283, 210, 147,
95, 53, 24, 6, 0, 6, 24, 53, 95, 147, 210,
283, 366, 457, 555, 660, 771, 887, 1006, 1127 };
static volatile uint32_t phase_acc_base = 0U;
static uint32_t phase_acc_step = 0U;
//=============================================================================
// Private Function Definition
//=============================================================================
static void epwm_set_3phase_duty_from_phase(uint32_t phase_q32)
{
const uint16_t idx_a = (uint16_t)(phase_q32 >> 26U);
const uint16_t idx_b = (uint16_t)((phase_q32 + PHASE_OFFSET_120_DEG_Q32) >> 26U);
const uint16_t idx_c = (uint16_t)((phase_q32 + PHASE_OFFSET_240_DEG_Q32) >> 26U);
EPWM->CCR1 = pwm_table[idx_a & (PWM_TABLE_SIZE - 1U)];
EPWM->CCR2 = pwm_table[idx_b & (PWM_TABLE_SIZE - 1U)];
EPWM->CCR3 = pwm_table[idx_c & (PWM_TABLE_SIZE - 1U)];
}
__INTERRUPT static void epwm_irq_handler(void)
{
if ((EPWM->SR & 0x10000U) == 0x10000U)
{
phase_acc_base += phase_acc_step;
epwm_set_3phase_duty_from_phase(phase_acc_base);
TIM_ClearITPendingBit(EPWM, 0x10000U); // clear EPWM OVIF
}
}
static uint16_t epwm_calc_prescaler(uint32_t tim_clk_hz, uint32_t pwm_freq_hz,
uint16_t period)
{
const uint32_t denom = pwm_freq_hz * ((uint32_t)period + 1U);
uint32_t psc = (tim_clk_hz + (denom / 2U)) / denom;
if (psc == 0U)
{
psc = 1U;
}
return (uint16_t)(psc - 1U);
}
static uint16_t epwm_calc_max_period(uint32_t tim_clk_hz, uint32_t pwm_freq_hz)
{
uint32_t period = (tim_clk_hz / pwm_freq_hz);
if (period == 0U)
{
return 0U;
}
period -= 1U;
if (period > 0xFFFFU)
{
period = 0xFFFFU;
}
return (uint16_t)period;
}
static uint32_t phase_acc_calc_step(uint32_t target_freq_hz,
uint32_t update_freq_hz)
{
return (uint32_t)(((uint64_t)target_freq_hz << 32) / update_freq_hz);
}
static void epwm_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
TIM_OCInitTypeDef TIM_OCInitStruct = { 0 };
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStr = { 0 };
sys_irq_attr_t irq_attr = { 0 };
const uint16_t period = epwm_calc_max_period(EPWM_TIM_CLOCK_HZ,
EPWM_TARGET_FREQ_HZ);
const uint16_t prescaler = epwm_calc_prescaler(EPWM_TIM_CLOCK_HZ,
EPWM_TARGET_FREQ_HZ, period);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02
| GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6;
GPIO_Init(GPIOA, &GPIO_InitStruct);
irq_attr.disable_vector = false;
irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL;
irq_attr.level = SYS_IRQ_LEVEL_H;
irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN;
sys_register_IRQ(EPWM_IRQn, epwm_irq_handler, &irq_attr);
TIM_DeInit(EPWM);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStr);
TIM_TimeBaseInitStr.TIM_Prescaler = prescaler;
TIM_TimeBaseInitStr.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStr.TIM_Period = period;
TIM_TimeBaseInitStr.TIM_ClockDivision = TIM_CKD_Div1;
TIM_TimeBaseInitStr.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStr);
TIM_ARRPreloadConfig(EPWM, ENABLE);
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStruct.TIM_Pulse = pwm_table[0];
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(EPWM, &TIM_OCInitStruct);
TIM_OC2Init(EPWM, &TIM_OCInitStruct);
TIM_OC3Init(EPWM, &TIM_OCInitStruct);
EPWM->CCMR1_OUTPUT_b.OC1PE = 1U;
EPWM->CCMR1_OUTPUT_b.OC2PE = 1U;
EPWM->CCMR2_OUTPUT_b.OC3PE = 1U;
EPWM->DIER |= 0x0800U; // overflow interrupt enable
TIM_ClearITPendingBit(EPWM, 0x10000U);
TIM_Cmd(EPWM, ENABLE);
TIM_CtrlPWMOutputs(EPWM, ENABLE);
epwm_set_3phase_duty_from_phase(phase_acc_base);
__enable_irq();
}
static void sysclk_init(void)
{
SYSCFG_ClkInitTypeDef SysClkInit = { 0 };
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
SYSCFG_SysClkConfig(&SysClkInit);
sys_config_systick(SYS_TICK_1_MS);
}
//=============================================================================
// Public Function Definition
//=============================================================================
int main(void)
{
sysclk_init();
phase_acc_step = phase_acc_calc_step(PHASE_TARGET_FREQ_HZ, EPWM_TARGET_FREQ_HZ);
epwm_init();
uart_init();
uart_send_msg("%s\r\n", "uart ok");
while (1)
{
uart_cmd_process();
}
return 0;
}
+145
View File
@@ -0,0 +1,145 @@
#include "uart_cmd_srv.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "epwm_drv.h"
static bool cmd_match_with_arg(const volatile char *buf, const char *prefix, const char **arg_out)
{
size_t len = strlen(prefix);
for (size_t i = 0; i < len; i++)
{
if (buf[i] != prefix[i])
return false;
}
if (buf[len] == ' ')
{
*arg_out = (const char *)&buf[len + 1];
return true;
}
return false;
}
static int32_t cmd_parse_int_list(const char *arg, int32_t *out, int32_t max_count)
{
int32_t count = 0;
char *end = NULL;
const char *p = arg;
while (*p != '\0' && count < max_count)
{
while (*p == ' ')
p++;
if (*p == '\0')
break;
out[count] = strtol(p, &end, 10);
if (end == p)
return -1;
count++;
p = end;
}
while (*p == ' ')
p++;
if (*p != '\0')
return -1;
return count;
}
static bool cmd_parse_int_args(const char *arg, int32_t *out, int32_t expect_count,
const char *usage_msg)
{
int32_t parsed = cmd_parse_int_list(arg, out, expect_count);
if (parsed != expect_count)
{
uart_send_msg("%s", usage_msg);
return false;
}
return true;
}
static void cmd_handle_val(const char *arg)
{
int32_t values[8] = { 0 };
int32_t parsed = cmd_parse_int_list(arg, values, 8);
if (parsed <= 0)
{
uart_send_msg("ERR usage: val n1 n2 ...\r\n");
return;
}
for (int32_t i = 0; i < parsed; i++)
{
uart_send_msg("%d\r\n", values[i]);
}
}
void uart_cmd_process(void)
{
if (!uart_is_frame_ready())
return;
const char *arg = NULL;
char *cmd = (char *)g_uart_rx_buf;
if (strcmp(cmd, "help") == 0)
{
uart_send_msg("Commands:\r\n");
uart_send_msg(" help - show this help\r\n");
uart_send_msg(" fw_ver - show firmware version\r\n");
uart_send_msg(" pwm_en 1/0 - enable/disable PWM output\r\n");
uart_send_msg(" epwm_set_duty d1 d2 d3 - set duty for 3 channels\r\n");
uart_send_msg(" val n1 n2 ... - parse integer values\r\n");
}
else if (strcmp(cmd, "fw_ver") == 0)
{
uart_send_msg("FW: " FW_VERSION "\r\n");
}
else if (cmd_match_with_arg(cmd, "pwm_en", &arg))
{
if (arg[0] == '1')
{
epwm_en(1);
uart_send_msg("OK pwm on\r\n");
}
else if (arg[0] == '0')
{
epwm_en(0);
uart_send_msg("OK pwm off\r\n");
}
else
{
uart_send_msg("ERR usage: pwm_en 1/0\r\n");
}
}
else if (cmd_match_with_arg(cmd, "epwm_set_duty", &arg))
{
int32_t values[3] = { 0 };
if (cmd_parse_int_args(arg, values, 3,
"ERR usage: epwm_set_duty duty1 duty2 duty3\r\n"))
{
epwm_set_duty(values[0], values[1], values[2]);
uart_send_msg("OK epwm_set_duty: %d %d %d\r\n", values[0], values[1], values[2]);
}
}
else if (cmd_match_with_arg(cmd, "val", &arg))
{
cmd_handle_val(arg);
}
else
{
uart_send_msg("ERR unknown cmd\r\n");
}
/* Reset for next command */
uart_clear_rx_frame();
}