kopia lustrzana https://github.com/sq8vps/vp-digi
KISS fixes
commit
6dae655f45
69
.cproject
69
.cproject
|
@ -17,16 +17,16 @@
|
|||
<configuration artifactExtension="elf" 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="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917" name="Debug" parent="fr.ac6.managedbuild.config.gnu.cross.exe.debug" postannouncebuildStep="Generating hex and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O ihex "${BuildArtifactFileBaseName}.elf" "${BuildArtifactFileBaseName}.hex" && arm-none-eabi-size "${BuildArtifactFileName}"">
|
||||
<folderInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917." name="/" resourcePath="">
|
||||
<toolChain id="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug.2013979193" name="Ac6 STM32 MCU GCC" superClass="fr.ac6.managedbuild.toolchain.gnu.cross.exe.debug">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" valueType="stringList">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" useByScannerDiscovery="false" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" useByScannerDiscovery="false" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="ARM Cortex-M3"/>
|
||||
<listOptionValue builtIn="false" value="CM3"/>
|
||||
</option>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="fr.ac6.managedbuild.targetPlatform.gnu.cross.2146232636" isAbstract="false" osList="all" superClass="fr.ac6.managedbuild.targetPlatform.gnu.cross"/>
|
||||
<builder buildPath="${workspace_loc:/F103C8T6_DIGI_USB}/Debug" id="fr.ac6.managedbuild.builder.gnu.cross.458407908" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="fr.ac6.managedbuild.builder.gnu.cross">
|
||||
<outputEntries>
|
||||
|
@ -52,7 +52,9 @@
|
|||
<listOptionValue builtIn="false" value="STM32F103xB"/>
|
||||
</option>
|
||||
<option id="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other.1107445133" superClass="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-fmessage-length=0" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.dialect.std.1039445628" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.option.dialect.std.2115782942" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.option.warnings.wconversion.357268975" name="Implicit conversion warnings (-Wconversion)" superClass="gnu.c.compiler.option.warnings.wconversion" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.warnings.extrawarn.1997689762" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1385058365" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s.901665218" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s"/>
|
||||
</tool>
|
||||
|
@ -77,10 +79,10 @@
|
|||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s.314001530" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s"/>
|
||||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.949266977" name="MCU GCC Linker" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker">
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" useByScannerDiscovery="false" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" useByScannerDiscovery="false" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="gnu.c.link.option.other.623842724" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.751662654" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
@ -100,7 +102,7 @@
|
|||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.archiver.1989184041" name="MCU GCC Archiver" superClass="fr.ac6.managedbuild.tool.gnu.archiver"/>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.1762903833" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler">
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.632714311" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.assembler.input.1298773058" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.input"/>
|
||||
</tool>
|
||||
|
@ -133,16 +135,16 @@
|
|||
<configuration artifactExtension="elf" 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="rm -rf" description="" id="fr.ac6.managedbuild.config.gnu.cross.exe.release.2040258153" name="Release" parent="fr.ac6.managedbuild.config.gnu.cross.exe.release" postannouncebuildStep="Generating hex and Printing size information:" postbuildStep="arm-none-eabi-objcopy -O ihex "${BuildArtifactFileBaseName}.elf" "${BuildArtifactFileBaseName}.hex" && arm-none-eabi-size "${BuildArtifactFileName}"">
|
||||
<folderInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.release.2040258153." name="/" resourcePath="">
|
||||
<toolChain id="fr.ac6.managedbuild.toolchain.gnu.cross.exe.release.1401143845" name="Ac6 STM32 MCU GCC" superClass="fr.ac6.managedbuild.toolchain.gnu.cross.exe.release">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" valueType="stringList">
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.prefix.382830450" name="Prefix" superClass="fr.ac6.managedbuild.option.gnu.cross.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.mcu.66405555" name="Mcu" superClass="fr.ac6.managedbuild.option.gnu.cross.mcu" useByScannerDiscovery="false" value="STM32F103C8Tx" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.board.1729153140" name="Board" superClass="fr.ac6.managedbuild.option.gnu.cross.board" useByScannerDiscovery="false" value="F103C8T6_DIGI_USB" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.core.1083960614" name="Core" superClass="fr.ac6.managedbuild.option.gnu.cross.core" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="ARM Cortex-M3"/>
|
||||
<listOptionValue builtIn="false" value="CM3"/>
|
||||
</option>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.1656935294" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.instructionSet.thumbII" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.1493691602" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.fpu.no" valueType="enumerated"/>
|
||||
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.2025609880" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi" useByScannerDiscovery="false" value="fr.ac6.managedbuild.option.gnu.cross.floatabi.soft" valueType="enumerated"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="fr.ac6.managedbuild.targetPlatform.gnu.cross.2146232636" isAbstract="false" osList="all" superClass="fr.ac6.managedbuild.targetPlatform.gnu.cross"/>
|
||||
<builder buildPath="${workspace_loc:/F103C8T6_DIGI_USB}/Release" id="fr.ac6.managedbuild.builder.gnu.cross.458407908" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="fr.ac6.managedbuild.builder.gnu.cross">
|
||||
<outputEntries>
|
||||
|
@ -160,12 +162,15 @@
|
|||
<listOptionValue builtIn="false" value="../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc"/>
|
||||
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32F1xx/Include"/>
|
||||
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
|
||||
<listOptionValue builtIn="false" value="../lwfec"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.600695662" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
|
||||
<listOptionValue builtIn="false" value="ENABLE_FX25"/>
|
||||
<listOptionValue builtIn="false" value="STM32F103xB"/>
|
||||
</option>
|
||||
<option id="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other.1107445133" superClass="fr.ac6.managedbuild.gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-fmessage-length=0" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.dialect.std.372719641" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1385058365" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s.901665218" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s"/>
|
||||
</tool>
|
||||
|
@ -190,10 +195,10 @@
|
|||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s.314001530" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s"/>
|
||||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.949266977" name="MCU GCC Linker" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker">
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script.100896041" name="Linker Script (-T)" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script" useByScannerDiscovery="false" value="../STM32F103C8Tx_FLASH.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.libs.1305202629" name="Libraries (-l)" superClass="gnu.c.link.option.libs" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.paths.1292687187" name="Library search path (-L)" superClass="gnu.c.link.option.paths" useByScannerDiscovery="false"/>
|
||||
<option id="gnu.c.link.option.ldflags.2131178816" name="Linker flags" superClass="gnu.c.link.option.ldflags" useByScannerDiscovery="false" value="-specs=nosys.specs -specs=nano.specs" valueType="string"/>
|
||||
<option id="gnu.c.link.option.other.623842724" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.751662654" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
|
@ -213,17 +218,18 @@
|
|||
</tool>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.archiver.1989184041" name="MCU GCC Archiver" superClass="fr.ac6.managedbuild.tool.gnu.archiver"/>
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.exe.release.1892402399" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.exe.release">
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths"/>
|
||||
<option id="gnu.both.asm.option.include.paths.1278058431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.632714311" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="fr.ac6.managedbuild.tool.gnu.cross.assembler.input.1298773058" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="startup"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Src"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="lwfec"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="startup"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
@ -247,5 +253,14 @@
|
|||
<configuration configurationName="Release"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917;fr.ac6.managedbuild.config.gnu.cross.exe.debug.785246917.;fr.ac6.managedbuild.tool.gnu.cross.c.compiler.736856211;fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1385058365">
|
||||
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="fr.ac6.managedbuild.config.gnu.cross.exe.release.2040258153;fr.ac6.managedbuild.config.gnu.cross.exe.release.2040258153.;fr.ac6.managedbuild.tool.gnu.cross.c.compiler.736856211;fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1385058365">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
</cproject>
|
||||
|
|
72
CHANGELOG.md
72
CHANGELOG.md
|
@ -1,4 +1,63 @@
|
|||
# 1.2.6 (2023-08-29)
|
||||
# 2.0.0 (2023-09-05)
|
||||
## New features
|
||||
* New modems: AFSK Bell 103 (300 Bd, 1600/1800 Hz), GFSK G3RUH (9600 Bd), AFSK V.23 (1200 Bd, 1300/2100 Hz)
|
||||
* FX.25 (AX.25 with Reed-Solomon FEC) support
|
||||
## Bug fixes
|
||||
* none
|
||||
## Other
|
||||
* none
|
||||
## Known bugs
|
||||
* none
|
||||
# 1.3.3 (2023-09-04)
|
||||
## New features
|
||||
* none
|
||||
## Bug fixes
|
||||
* RX buffer pointers bug fix
|
||||
* AX.25 to TNC2 converter bug with non-UI frames
|
||||
## Other
|
||||
* New KISS handling method to support long and multiple frames
|
||||
## Known bugs
|
||||
* none
|
||||
# 1.3.2 (2023-08-31)
|
||||
## New features
|
||||
* none
|
||||
## Bug fixes
|
||||
* Duplicate protection was not working properly
|
||||
## Other
|
||||
* none
|
||||
## Known bugs
|
||||
* none
|
||||
# 1.3.1 (2023-08-30)
|
||||
## New features
|
||||
* none
|
||||
## Bug fixes
|
||||
* Non-APRS switch was not stored in memory
|
||||
## Other
|
||||
* PWM is now the default option
|
||||
## Known bugs
|
||||
* none
|
||||
# 1.3.0 (2023-08-30)
|
||||
## New features
|
||||
* Callsign is now set together with SSID using ```call <call-SSID>```
|
||||
* ```time``` command to show uptime
|
||||
## Removed features
|
||||
* ```ssid``` command is removed
|
||||
* Auto-reset functionality and ```autoreset``` command is removed
|
||||
## Bug fixes
|
||||
* When beacon *n* delay hadn't passed yet, beacon *n+1*, *n+2*, ... were not sent regardless of their delay
|
||||
* Bugs with line ending parsing
|
||||
## Other
|
||||
* Major code refactoring and rewrite
|
||||
* Got rid of *uart_transmitStart()* routine
|
||||
* USB sending is handled the same way as UART
|
||||
* New way of TX and RX frame handling to improve non-APRS compatibility
|
||||
* Much bigger frame buffer
|
||||
* Minimized number of temporary buffers
|
||||
* All *malloc()*s removed
|
||||
* Added copyright notice as required by GNU GPL
|
||||
## Known bugs
|
||||
* none
|
||||
# 1.2.6 (2023-07-29)
|
||||
## New features
|
||||
* Added ```nonaprs [on/off]``` command that enables reception of non-APRS frames, e.g. for full Packet Radio use
|
||||
## Bug fixes
|
||||
|
@ -43,15 +102,6 @@
|
|||
* none
|
||||
## Known bugs
|
||||
* USB in KISS mode has problem with TX frames
|
||||
# 1.2.2 (2022-06-11)
|
||||
## New features
|
||||
* none
|
||||
## Bug fixes
|
||||
* Default de-dupe time was 0, backspace was sometimes stored in config, frame length was not checked in viscous delay mode
|
||||
## Other
|
||||
* none
|
||||
## Known bugs
|
||||
* USB in KISS mode has problem with TX frames
|
||||
# 1.2.1 (2021-10-13)
|
||||
## New features
|
||||
* none
|
||||
|
@ -73,4 +123,4 @@ This is the very first open-source VP-Digi release.
|
|||
## Other
|
||||
* Code was partially rewritten (especially digipeater, modem and AX.25 layer)
|
||||
## Known bugs
|
||||
* none
|
||||
* none
|
31
Inc/ax25.h
31
Inc/ax25.h
|
@ -1,4 +1,6 @@
|
|||
/*
|
||||
Copyright 2020-2023 Piotr Wilkon
|
||||
|
||||
This file is part of VP-Digi.
|
||||
|
||||
VP-Digi is free software: you can redistribute it and/or modify
|
||||
|
@ -21,13 +23,25 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define AX25_NOT_FX25 255
|
||||
|
||||
#ifndef ENABLE_FX25
|
||||
//for AX.25 308 bytes is the theoretical max size assuming 2-byte Control, 256-byte info field and 5 digi address fields
|
||||
#define AX25_FRAME_MAX_SIZE (308) //single frame max length
|
||||
#else
|
||||
//in FX.25 mode the block can be 255 bytes long at most, and the AX.25 frame itself must be even smaller
|
||||
//frames that are too long are sent as standard AX.25 frames
|
||||
//Reed-Solomon library needs a bit of memory and the frame buffer must be smaller
|
||||
//otherwise we run out of RAM
|
||||
#define AX25_FRAME_MAX_SIZE (265) //single frame max length
|
||||
#endif
|
||||
|
||||
enum Ax25RxStage
|
||||
{
|
||||
RX_STAGE_IDLE = 0,
|
||||
RX_STAGE_FLAG,
|
||||
RX_STAGE_FRAME,
|
||||
#ifdef ENABLE_FX25
|
||||
RX_STAGE_FX25_TAG,
|
||||
RX_STAGE_FX25_FRAME,
|
||||
#endif
|
||||
};
|
||||
|
@ -44,12 +58,6 @@ struct Ax25ProtoConfig
|
|||
|
||||
extern struct Ax25ProtoConfig Ax25Config;
|
||||
|
||||
/**
|
||||
* @brief Transmit one or more frames encoded in KISS format
|
||||
* @param *buf Inout buffer
|
||||
* @param len Buffer size
|
||||
*/
|
||||
void Ax25TxKiss(uint8_t *buf, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Write frame to transmit buffer
|
||||
|
@ -75,11 +83,14 @@ void Ax25ClearReceivedFrameBitmap(void);
|
|||
* @brief Get next received frame (if available)
|
||||
* @param **dst Pointer to internal buffer
|
||||
* @param *size Actual frame size
|
||||
* @param *signalLevel Frame signal level (RMS)
|
||||
* @param *fixed Count of fixed bytes (FX.25)
|
||||
<<<<<<< HEAD
|
||||
* @param *peak Signak positive peak value in %
|
||||
* @param *valley Signal negative peak value in %
|
||||
* @param *level Signal level in %
|
||||
* @param *corrected Number of bytes corrected in FX.25 mode. 255 is returned if not a FX.25 packet.
|
||||
* @return True if frame was read, false if no more frames to read
|
||||
*/
|
||||
bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel, uint8_t *fixed);
|
||||
bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, int8_t *peak, int8_t *valley, uint8_t *level, uint8_t *corrected);
|
||||
|
||||
/**
|
||||
* @brief Get current RX stage
|
||||
|
|
|
@ -66,6 +66,15 @@ enum ModemPrefilter
|
|||
|
||||
void pushSample(float s);
|
||||
|
||||
/**
|
||||
* @brief Get measured signal level
|
||||
* @param modem Modem number
|
||||
* @param *peak Output signal positive peak in %
|
||||
* @param *valley Output signal negative peak in %
|
||||
* @param *level Output signal level in %
|
||||
*/
|
||||
void ModemGetSignalLevel(uint8_t modem, int8_t *peak, int8_t *valley, uint8_t *level);
|
||||
|
||||
/**
|
||||
* @brief Get current modem baudrate
|
||||
* @return Baudrate
|
||||
|
|
|
@ -23,7 +23,7 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "usbd_cdc_if.h"
|
||||
#include "ax25.h"
|
||||
|
||||
#define UART_BUFFER_SIZE 250
|
||||
#define UART_BUFFER_SIZE 130
|
||||
|
||||
enum UartMode
|
||||
{
|
||||
|
@ -35,7 +35,6 @@ enum UartMode
|
|||
enum UartDataType
|
||||
{
|
||||
DATA_NOTHING = 0,
|
||||
DATA_KISS,
|
||||
DATA_TERM,
|
||||
DATA_USB,
|
||||
};
|
||||
|
@ -53,20 +52,14 @@ typedef struct
|
|||
uint16_t txBufferHead, txBufferTail;
|
||||
uint8_t txBufferFull : 1;
|
||||
enum UartMode mode;
|
||||
uint32_t kissTimer;
|
||||
uint16_t lastRxBufferHead; //for special characters handling
|
||||
uint8_t kissBuffer[AX25_FRAME_MAX_SIZE + 1];
|
||||
uint16_t kissBufferHead;
|
||||
} Uart;
|
||||
|
||||
extern Uart Uart1, Uart2, UartUsb;
|
||||
|
||||
|
||||
///**
|
||||
// * \brief Copy KISS frame(s) from input buffer to APRS TX buffer
|
||||
// * \param[in] *buf Input buffer
|
||||
// * \param[in] len Input buffer size
|
||||
// */
|
||||
//uint8_t Uart_txKiss(uint8_t *buf, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Send byte
|
||||
* @param[in] *port UART
|
||||
|
@ -111,11 +104,4 @@ void UartConfig(Uart *port, uint8_t state);
|
|||
*/
|
||||
void UartClearRx(Uart *port);
|
||||
|
||||
/**
|
||||
* @brief Handle KISS timeout
|
||||
* @param *port UART pointer
|
||||
* @attention This function must be polled constantly in main loop for USB UART.
|
||||
*/
|
||||
void UartHandleKissTimeout(Uart *port);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright 2020-2023 Piotr Wilkon
|
||||
|
||||
This file is part of VP-Digi.
|
||||
|
||||
VP-Digi is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
VP-Digi is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KISS_H_
|
||||
#define KISS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "drivers/uart.h"
|
||||
|
||||
/**
|
||||
* @brief Convert AX.25 frame to KISS and send
|
||||
* @param *port UART structure
|
||||
* @param *buf Frame buffer
|
||||
* @param size Frame size
|
||||
*/
|
||||
void KissSend(Uart *port, uint8_t *buf, uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief Parse bytes received from UART to form a KISS frame (possibly) and send this frame
|
||||
* @param *port UART structure
|
||||
* @param data Received byte
|
||||
*/
|
||||
void KissParse(Uart *port, uint8_t data);
|
||||
|
||||
#endif /* KISS_H_ */
|
175
Src/ax25.c
175
Src/ax25.c
|
@ -1,4 +1,6 @@
|
|||
/*
|
||||
Copyright 2020-2023 Piotr Wilkon
|
||||
|
||||
This file is part of VP-Digi.
|
||||
|
||||
VP-Digi is free software: you can redistribute it and/or modify
|
||||
|
@ -15,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
|||
along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "ax25.h"
|
||||
#include <stdlib.h>
|
||||
#include "drivers/modem.h"
|
||||
|
@ -22,24 +25,16 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "drivers/systick.h"
|
||||
#include "digipeater.h"
|
||||
|
||||
struct Ax25ProtoConfig Ax25Config;
|
||||
|
||||
//values below must be kept consistent so that FRAME_BUFFER_SIZE >= FRAME_MAX_SIZE * FRAME_MAX_COUNT
|
||||
#ifndef ENABLE_FX25
|
||||
//for AX.25 308 bytes is the theoretical max size assuming 2-byte Control, 256-byte info field and 5 digi address fields
|
||||
#define FRAME_MAX_SIZE (308) //single frame max length
|
||||
#else
|
||||
//in FX.25 mode the block can be 255 bytes long at most, and the AX.25 frame itself must be even smaller
|
||||
//frames that are too long are sent as standard AX.25 frames
|
||||
//Reed-Solomon library needs a bit of memory and the frame buffer must be smaller
|
||||
//otherwise we run out of RAM
|
||||
#define FRAME_MAX_SIZE (265) //single frame max length
|
||||
#ifdef ENABLE_FX25
|
||||
#include "fx25.h"
|
||||
#endif
|
||||
|
||||
#define FRAME_MAX_COUNT (10) //max count of frames in buffer
|
||||
#define FRAME_BUFFER_SIZE (FRAME_MAX_COUNT * FRAME_MAX_SIZE) //circular frame buffer length
|
||||
#define FRAME_BUFFER_SIZE (FRAME_MAX_COUNT * AX25_FRAME_MAX_SIZE) //circular frame buffer length
|
||||
|
||||
#define STATIC_HEADER_FLAG_COUNT 4 //number of flags sent before each frame
|
||||
#define STATIC_FOOTER_FLAG_COUNT 8 //number of flags sent after each frame
|
||||
|
@ -50,7 +45,9 @@ struct FrameHandle
|
|||
{
|
||||
uint16_t start;
|
||||
uint16_t size;
|
||||
uint16_t signalLevel;
|
||||
int8_t peak;
|
||||
int8_t valley;
|
||||
uint8_t level;
|
||||
uint8_t corrected;
|
||||
#ifdef ENABLE_FX25
|
||||
struct Fx25Mode *fx25Mode;
|
||||
|
@ -120,7 +117,7 @@ static enum TxStage txStage; //current TX stage
|
|||
struct RxState
|
||||
{
|
||||
uint16_t crc; //current CRC
|
||||
uint8_t frame[FRAME_MAX_SIZE]; //raw frame buffer
|
||||
uint8_t frame[AX25_FRAME_MAX_SIZE]; //raw frame buffer
|
||||
uint16_t frameIdx; //index for raw frame buffer
|
||||
uint8_t receivedByte; //byte being currently received
|
||||
uint8_t receivedBitIdx; //bit index for recByte
|
||||
|
@ -130,11 +127,10 @@ struct RxState
|
|||
#ifdef ENABLE_FX25
|
||||
struct Fx25Mode *fx25Mode;
|
||||
uint64_t tag; //received correlation tag
|
||||
uint8_t tagBit;
|
||||
#endif
|
||||
};
|
||||
|
||||
static volatile struct RxState rxState[MODEM_MAX_DEMODULATOR_COUNT];
|
||||
static struct RxState rxState[MODEM_MAX_DEMODULATOR_COUNT];
|
||||
|
||||
static uint16_t lastCrc = 0; //CRC of the last received frame. If not 0, a frame was successfully received
|
||||
static uint16_t rxMultiplexDelay = 0; //simple delay for decoder multiplexer to avoid receiving the same frame twice
|
||||
|
@ -142,7 +138,7 @@ static uint16_t rxMultiplexDelay = 0; //simple delay for decoder multiplexer to
|
|||
static uint16_t txDelay; //number of TXDelay bytes to send
|
||||
static uint16_t txTail; //number of TXTail bytes to send
|
||||
|
||||
static uint8_t outputFrameBuffer[FRAME_MAX_SIZE];
|
||||
static uint8_t outputFrameBuffer[AX25_FRAME_MAX_SIZE];
|
||||
|
||||
#define GET_FREE_SIZE(max, head, tail) (((head) < (tail)) ? ((tail) - (head)) : ((max) - (head) + (tail)))
|
||||
#define GET_USED_SIZE(max, head, tail) (max - GET_FREE_SIZE(max, head, tail))
|
||||
|
@ -173,34 +169,10 @@ void Ax25ClearReceivedFrameBitmap(void)
|
|||
frameReceived = 0;
|
||||
}
|
||||
|
||||
void Ax25TxKiss(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
if(len < 18) //frame is too small
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(uint16_t i = 0; i < len; i++)
|
||||
{
|
||||
if(buf[i] == 0xC0) //frame start marker
|
||||
{
|
||||
uint16_t end = i + 1;
|
||||
while(end < len)
|
||||
{
|
||||
if(buf[end] == 0xC0)
|
||||
break;
|
||||
end++;
|
||||
}
|
||||
if(end == len) //no frame end marker found
|
||||
return;
|
||||
Ax25WriteTxFrame(&buf[i + 2], end - (i + 2)); //skip modem number and send frame
|
||||
//DigiStoreDeDupe(&buf[i + 2], end - (i + 2));
|
||||
i = end; //move pointer to the next byte if there are more consecutive frames
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void removeLastFrameFromRxBuffer(void)
|
||||
{
|
||||
rxBufferHead = rxFrame[rxFrameHead].start;
|
||||
if(rxFrameHead == 0)
|
||||
rxFrameHead = FRAME_MAX_COUNT - 1;
|
||||
else
|
||||
|
@ -339,7 +311,6 @@ static void *writeFx25Frame(uint8_t *data, uint16_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct FrameHandle* parseFx25Frame(uint8_t *frame, uint16_t size, uint16_t *crc)
|
||||
{
|
||||
struct FrameHandle *h = &rxFrame[rxFrameHead];
|
||||
|
@ -430,9 +401,6 @@ endParseFx25Frame:
|
|||
|
||||
void *Ax25WriteTxFrame(uint8_t *data, uint16_t size)
|
||||
{
|
||||
while(txStage != TX_STAGE_IDLE)
|
||||
;
|
||||
|
||||
if(txFrameBufferFull)
|
||||
return NULL;
|
||||
|
||||
|
@ -466,15 +434,17 @@ void *Ax25WriteTxFrame(uint8_t *data, uint16_t size)
|
|||
|
||||
|
||||
void *ret = &txFrame[txFrameHead];
|
||||
__disable_irq();
|
||||
txFrameHead++;
|
||||
txFrameHead %= FRAME_MAX_COUNT;
|
||||
if(txFrameHead == txFrameTail)
|
||||
txFrameBufferFull = true;
|
||||
__enable_irq();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel, uint8_t *fixed)
|
||||
bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, int8_t *peak, int8_t *valley, uint8_t *level, uint8_t *corrected)
|
||||
{
|
||||
if((rxFrameHead == rxFrameTail) && !rxFrameBufferFull)
|
||||
return false;
|
||||
|
@ -486,16 +456,17 @@ bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel, u
|
|||
(*dst)[i] = rxBuffer[(rxFrame[rxFrameTail].start + i) % FRAME_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
*signalLevel = rxFrame[rxFrameTail].signalLevel;
|
||||
*peak = rxFrame[rxFrameTail].peak;
|
||||
*valley = rxFrame[rxFrameTail].valley;
|
||||
*level = rxFrame[rxFrameTail].level;
|
||||
*size = rxFrame[rxFrameTail].size;
|
||||
#ifdef ENABLE_FX25
|
||||
*fixed = rxFrame[rxFrameTail].corrected;
|
||||
#endif
|
||||
*corrected = rxFrame[rxFrameTail].corrected;
|
||||
|
||||
__disable_irq();
|
||||
rxFrameBufferFull = false;
|
||||
|
||||
rxFrameTail++;
|
||||
rxFrameTail %= FRAME_MAX_COUNT;
|
||||
__enable_irq();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -504,6 +475,7 @@ enum Ax25RxStage Ax25GetRxStage(uint8_t modem)
|
|||
return rxState[modem].rx;
|
||||
}
|
||||
|
||||
|
||||
void Ax25BitParse(uint8_t bit, uint8_t modem)
|
||||
{
|
||||
if(lastCrc != 0) //there was a frame received
|
||||
|
@ -531,42 +503,20 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
rx->tag >>= 1;
|
||||
if(bit)
|
||||
rx->tag |= 0x8000000000000000;
|
||||
rx->tagBit++;
|
||||
|
||||
|
||||
if((rx->rx == RX_STAGE_FX25_TAG) || (rx->rx == RX_STAGE_FX25_FRAME))
|
||||
if(Ax25Config.fx25
|
||||
&& (rx->rx != RX_STAGE_FX25_FRAME)
|
||||
&& (NULL != (rx->fx25Mode = (struct Fx25Mode*)Fx25GetModeForTag(rx->tag))))
|
||||
{
|
||||
if((rx->rx == RX_STAGE_FX25_TAG) && (rx->tagBit == 64))
|
||||
{
|
||||
if(Ax25Config.fx25)
|
||||
{
|
||||
rx->fx25Mode = (struct Fx25Mode*)Fx25GetModeForTag(rx->tag);
|
||||
if(Ax25Config.fx25 && (rx->fx25Mode != NULL))
|
||||
{
|
||||
rx->rx = RX_STAGE_FX25_FRAME;
|
||||
rx->frameIdx = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->receivedByte = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
rx->rx = RX_STAGE_FRAME;
|
||||
}
|
||||
rx->rx = RX_STAGE_FX25_FRAME;
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if(rx->rx != RX_STAGE_FX25_FRAME)
|
||||
{
|
||||
if(rx->rawData != 0x7E)
|
||||
{
|
||||
if(Ax25Config.fx25)
|
||||
{
|
||||
if((rx->rx == RX_STAGE_FLAG) && (rx->tagBit == 8))
|
||||
rx->rx = RX_STAGE_FX25_TAG;
|
||||
}
|
||||
else
|
||||
rx->rx = RX_STAGE_FRAME;
|
||||
}
|
||||
else
|
||||
rx->tagBit = 0;
|
||||
#endif
|
||||
|
||||
if(rx->rawData == 0x7E) //HDLC flag received
|
||||
|
@ -605,15 +555,17 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
if(!rxFrameBufferFull) //if enough space, store the frame
|
||||
{
|
||||
rxFrame[rxFrameHead].start = rxBufferHead;
|
||||
rxFrame[rxFrameHead].signalLevel = ModemGetRMS(modem);
|
||||
rxFrame[rxBufferHead].corrected = 0;
|
||||
ModemGetSignalLevel(modem, &rxFrame[rxFrameHead].peak, &rxFrame[rxFrameHead].valley, &rxFrame[rxFrameHead].level);
|
||||
#ifdef ENABLE_FX25
|
||||
rxFrame[rxBufferHead].fx25Mode = NULL;
|
||||
rxFrame[rxFrameHead].fx25Mode = NULL;
|
||||
#endif
|
||||
rxFrame[rxFrameHead].corrected = AX25_NOT_FX25;
|
||||
__disable_irq();
|
||||
rxFrame[rxFrameHead++].size = rx->frameIdx;
|
||||
rxFrameHead %= FRAME_MAX_COUNT;
|
||||
if(rxFrameHead == txFrameHead)
|
||||
if(rxFrameHead == rxFrameTail)
|
||||
rxFrameBufferFull = true;
|
||||
__enable_irq();
|
||||
|
||||
for(uint16_t i = 0; i < rx->frameIdx; i++)
|
||||
{
|
||||
|
@ -627,27 +579,27 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
}
|
||||
}
|
||||
rx->rx = RX_STAGE_FLAG;
|
||||
ModemClearRMS(modem);
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
rx->rx = RX_STAGE_FRAME;
|
||||
|
||||
#ifdef ENABLE_FX25
|
||||
}
|
||||
|
||||
|
||||
if((rx->rx != RX_STAGE_FX25_FRAME) && (rx->rx != RX_STAGE_FX25_TAG))
|
||||
if(rx->rx != RX_STAGE_FX25_FRAME)
|
||||
{
|
||||
#else
|
||||
{
|
||||
//this condition must not be checked when FX.25 is enabled
|
||||
//because FX.25 parity bytes and tags contain >= 7 consecutive ones
|
||||
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error (sometimes called "escape byte")
|
||||
if((rx->rawData & 0x7F) == 0x7F) //received 7 consecutive ones, this is an error
|
||||
{
|
||||
rx->rx = RX_STAGE_FLAG;
|
||||
ModemClearRMS(modem);
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
|
@ -669,29 +621,23 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
if((rx->fx25Mode != NULL) && (rx->frameIdx == (rx->fx25Mode->K + rx->fx25Mode->T)))
|
||||
{
|
||||
uint8_t fixed = 0;
|
||||
if(Fx25Decode(rx->frame, rx->fx25Mode, &fixed))
|
||||
bool fecSuccess = Fx25Decode(rx->frame, rx->fx25Mode, &fixed);
|
||||
uint16_t crc;
|
||||
struct FrameHandle *h = parseFx25Frame(rx->frame, rx->frameIdx, &crc);
|
||||
if(h != NULL)
|
||||
{
|
||||
uint16_t crc;
|
||||
struct FrameHandle *h = parseFx25Frame(rx->frame, rx->frameIdx, &crc);
|
||||
if(h != NULL)
|
||||
rx->frameReceived = 1;
|
||||
ModemGetSignalLevel(modem, &h->peak, &h->valley, &h->level);
|
||||
if(fecSuccess)
|
||||
{
|
||||
rx->frameReceived = 1;
|
||||
h->corrected = fixed;
|
||||
//FX.25 (RS) decoding is not reentrant/interrupt safe
|
||||
//use only one modem when FX.25 is enabled
|
||||
// if(crc != lastCrc)
|
||||
// {
|
||||
h->signalLevel = ModemGetRMS(modem);
|
||||
h->fx25Mode = rx->fx25Mode;
|
||||
lastCrc = crc;
|
||||
// }
|
||||
// else
|
||||
// removeLastFrameFromRxBuffer();
|
||||
h->fx25Mode = rx->fx25Mode;
|
||||
}
|
||||
else
|
||||
h->corrected = AX25_NOT_FX25;
|
||||
lastCrc = crc;
|
||||
}
|
||||
rx->rx = RX_STAGE_FX25_TAG;
|
||||
rx->tagBit = 0;
|
||||
ModemClearRMS(modem);
|
||||
rx->rx = RX_STAGE_FLAG;
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
|
@ -700,10 +646,9 @@ void Ax25BitParse(uint8_t bit, uint8_t modem)
|
|||
#else
|
||||
rx->rx = RX_STAGE_FRAME;
|
||||
#endif
|
||||
if(rx->frameIdx > FRAME_MAX_SIZE) //frame is too long
|
||||
if(rx->frameIdx >= AX25_FRAME_MAX_SIZE) //frame is too long
|
||||
{
|
||||
rx->rx = RX_STAGE_IDLE;
|
||||
ModemClearRMS(modem);
|
||||
rx->receivedByte = 0;
|
||||
rx->receivedBitIdx = 0;
|
||||
rx->frameIdx = 0;
|
||||
|
@ -773,8 +718,10 @@ transmitTag:
|
|||
if(txStage == TX_STAGE_DATA) //transmitting normal data
|
||||
{
|
||||
transmitNormalData:
|
||||
__disable_irq();
|
||||
if((txFrameHead != txFrameTail) || txFrameBufferFull)
|
||||
{
|
||||
__enable_irq();
|
||||
if(txByteIdx < txFrame[txFrameTail].size) //send buffer
|
||||
{
|
||||
txByte = txBuffer[(txFrame[txFrameTail].start + txByteIdx) % FRAME_BUFFER_SIZE];
|
||||
|
@ -783,10 +730,12 @@ transmitNormalData:
|
|||
#ifdef ENABLE_FX25
|
||||
else if(txFrame[txFrameTail].fx25Mode != NULL)
|
||||
{
|
||||
__disable_irq();
|
||||
txFrameBufferFull = false;
|
||||
txFrameTail++;
|
||||
txFrameTail %= FRAME_MAX_COUNT;
|
||||
txByteIdx = 0;
|
||||
__enable_irq();
|
||||
if((txFrameHead != txFrameTail) || txFrameBufferFull)
|
||||
{
|
||||
if(txFrame[txFrameTail].fx25Mode != NULL)
|
||||
|
@ -811,6 +760,7 @@ transmitNormalData:
|
|||
else //no more frames
|
||||
{
|
||||
transmitTail:
|
||||
__enable_irq();
|
||||
txByteIdx = 0;
|
||||
txBitIdx = 0;
|
||||
txStage = TX_STAGE_TAIL;
|
||||
|
@ -842,6 +792,7 @@ transmitTail:
|
|||
else
|
||||
{
|
||||
txFlagsElapsed = 0;
|
||||
__disable_irq();
|
||||
txFrameBufferFull = false;
|
||||
txFrameTail++;
|
||||
txFrameTail %= FRAME_MAX_COUNT;
|
||||
|
@ -849,11 +800,13 @@ transmitTail:
|
|||
#ifdef ENABLE_FX25
|
||||
if(((txFrameHead != txFrameTail) || txFrameBufferFull) && (txFrame[txFrameTail].fx25Mode != NULL))
|
||||
{
|
||||
__enable_irq();
|
||||
txStage = TX_STAGE_CORRELATION_TAG;
|
||||
txTagByteIdx = 0;
|
||||
goto transmitTag;
|
||||
}
|
||||
#endif
|
||||
__enable_irq();
|
||||
txStage = TX_STAGE_DATA; //return to normal data transmission stage. There might be a next frame to transmit
|
||||
goto transmitNormalData;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ void BeaconCheck(void)
|
|||
if((beacon[i].interval > 0) && ((SysTickGet() >= beacon[i].next) || (beacon[i].next == 0)))
|
||||
{
|
||||
if(beaconDelay[i] > SysTickGet()) //check for beacon delay (only for the very first transmission)
|
||||
return;
|
||||
continue;
|
||||
beacon[i].next = SysTickGet() + beacon[i].interval; //save next beacon timestamp
|
||||
beaconDelay[i] = 0;
|
||||
BeaconSend(i);
|
||||
|
|
13
Src/common.c
13
Src/common.c
|
@ -32,7 +32,7 @@ struct _GeneralConfig GeneralConfig =
|
|||
|
||||
const char versionString[] = "VP-Digi v. 2.0.0\r\nThe open-source standalone APRS digipeater controller and KISS TNC\r\n"
|
||||
#ifdef ENABLE_FX25
|
||||
"with FX.25 support compiled-in\r\n"
|
||||
"With FX.25 support compiled-in\r\n"
|
||||
#endif
|
||||
;
|
||||
|
||||
|
@ -148,11 +148,16 @@ static void sendTNC2ToUart(Uart *uart, uint8_t *from, uint16_t len)
|
|||
|
||||
}
|
||||
|
||||
UartSendByte(uart, ':'); //separator
|
||||
UartSendByte(uart, ':'); //separator
|
||||
|
||||
nextPathEl += 2; //skip Control and PID
|
||||
if((from[nextPathEl] & 0b11101111) == 0b00000011) //check if UI packet
|
||||
{
|
||||
nextPathEl += 2; //skip Control and PID
|
||||
|
||||
UartSendString(uart, &(from[nextPathEl]), len - nextPathEl); //send information field
|
||||
UartSendString(uart, &(from[nextPathEl]), len - nextPathEl); //send information field
|
||||
}
|
||||
else
|
||||
UartSendString(uart, "<not UI packet>", 0);
|
||||
|
||||
UartSendByte(uart, 0); //terminate with NULL
|
||||
}
|
||||
|
|
|
@ -95,7 +95,8 @@ along with VP-DigiConfig. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define CONFIG_DEST 1208
|
||||
#define CONFIG_ALLOWNONAPRS 1214
|
||||
#define CONFIG_FX25 1216
|
||||
#define CONFIG_XXX 1218 //next address (not used)
|
||||
#define CONFIG_MODEM 1218
|
||||
#define CONFIG_XXX 1220 //next address (not used)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -264,6 +265,7 @@ void ConfigWrite(void)
|
|||
write(CONFIG_KISSMONITOR, GeneralConfig.kissMonitor);
|
||||
write(CONFIG_ALLOWNONAPRS, Ax25Config.allowNonAprs);
|
||||
write(CONFIG_FX25, Ax25Config.fx25 | (Ax25Config.fx25Tx << 1));
|
||||
write(CONFIG_MODEM, ModemConfig.modem);
|
||||
|
||||
write(CONFIG_FLAG, CONFIG_FLAG_WRITTEN);
|
||||
|
||||
|
@ -281,10 +283,10 @@ uint8_t ConfigRead(void)
|
|||
readString(CONFIG_CALL, GeneralConfig.call, sizeof(GeneralConfig.call));
|
||||
GeneralConfig.callSsid = (uint8_t)read(CONFIG_SSID);
|
||||
uint8_t temp[6];
|
||||
readString(CONFIG_DEST, temp, sizeof(temp));
|
||||
readString(CONFIG_DEST, temp, 6);
|
||||
if((temp[0] >= ('A' << 1)) && (temp[0] <= ('Z' << 1)) && ((temp[0] & 1) == 0)) //check if stored destination address is correct (we just assume it by reading the first byte)
|
||||
{
|
||||
memcpy(GeneralConfig.dest, temp, sizeof(temp));
|
||||
memcpy(GeneralConfig.dest, temp, 6);
|
||||
}
|
||||
Ax25Config.txDelayLength = read(CONFIG_TXDELAY);
|
||||
Ax25Config.txTailLength = read(CONFIG_TXTAIL);
|
||||
|
@ -355,6 +357,7 @@ uint8_t ConfigRead(void)
|
|||
t = (uint8_t)read(CONFIG_FX25);
|
||||
Ax25Config.fx25 = t & 1;
|
||||
Ax25Config.fx25Tx = (t & 2) > 0;
|
||||
ModemConfig.modem = read(CONFIG_MODEM);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -50,8 +50,7 @@ static struct DeDupeData deDupe[DEDUPE_SIZE]; //duplicate protection hash buffer
|
|||
static uint8_t deDupeCount = 0; //duplicate protection buffer index
|
||||
|
||||
|
||||
#define DIGI_BUFFER_SIZE 308 //308 is the theoretical max under some assumptions, see ax25.c
|
||||
static uint8_t buf[DIGI_BUFFER_SIZE];
|
||||
static uint8_t buf[AX25_FRAME_MAX_SIZE];
|
||||
|
||||
/**
|
||||
* @brief Check if frame with specified hash is already in viscous-delay buffer and delete it if so
|
||||
|
@ -198,7 +197,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
|
|||
}
|
||||
else //normal mode
|
||||
{
|
||||
if(sizeof(buf) < (len + 7))
|
||||
if((uint16_t)sizeof(buf) < (len + 7))
|
||||
return;
|
||||
buffer = buf;
|
||||
}
|
||||
|
@ -218,7 +217,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
|
|||
{
|
||||
if(elStart != 14)
|
||||
return; //this is not the very first path element, frame not received directly
|
||||
if((alias >= 0) && (alias <= 3) && (ssid != n))
|
||||
if((alias <= 3) && (ssid != n))
|
||||
return; //n-N type alias, but n is not equal to N, frame not received directly
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +321,7 @@ void DigiDigipeat(uint8_t *frame, uint16_t len)
|
|||
|
||||
//calculate frame "hash"
|
||||
uint32_t hash = Crc32(CRC32_INIT, frame, 14); //use destination and source address, skip path
|
||||
hash = Crc32(hash, &frame[t + 1], len - t); //continue through all remaining data
|
||||
hash = Crc32(hash, &frame[t + 1], len - t - 1); //continue through all remaining data
|
||||
|
||||
if(DigiConfig.viscous) //viscous-delay enabled on any slot
|
||||
{
|
||||
|
@ -461,7 +460,7 @@ void DigiStoreDeDupe(uint8_t *buf, uint16_t size)
|
|||
deDupeCount %= DEDUPE_SIZE;
|
||||
|
||||
deDupe[deDupeCount].hash = hash;
|
||||
deDupe[deDupeCount].timeLimit = SysTickGet() + (DigiConfig.dupeTime * 10 / SYSTICK_INTERVAL);
|
||||
deDupe[deDupeCount].timeLimit = SysTickGet() + (DigiConfig.dupeTime * 1000 / SYSTICK_INTERVAL);
|
||||
|
||||
deDupeCount++;
|
||||
}
|
||||
|
|
|
@ -32,27 +32,23 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
* DCD_MAXPULSE and DCD_THRES difference sets the DCD "inertia" so that the DCD state won't change rapidly when a valid signal is present
|
||||
* DCD_DEC is the DCD pulse counter decrementation value when symbol changes too far from PLL counter zero
|
||||
* DCD_INC is the DCD pulse counter incrementation value when symbol changes near the PLL counter zero
|
||||
* DCD_PLLTUNE is the DCD timing coefficient when symbol changes, pll_counter = pll_counter * DCD_PLLTUNE
|
||||
* The DCD mechanism is described in afsk_demod().
|
||||
* The DCD mechanism is described in demodulate().
|
||||
* All values were selected by trial and error
|
||||
*/
|
||||
#define DCD1200_MAXPULSE 100
|
||||
#define DCD1200_THRES 30
|
||||
#define DCD1200_DEC 1
|
||||
#define DCD1200_INC 7
|
||||
#define DCD1200_PLLTUNE 0
|
||||
#define DCD1200_DEC 2
|
||||
#define DCD1200_INC 1
|
||||
|
||||
#define DCD9600_MAXPULSE 200
|
||||
#define DCD9600_THRES 80
|
||||
#define DCD9600_DEC 3
|
||||
#define DCD9600_INC 6
|
||||
#define DCD9600_PLLTUNE 0
|
||||
#define DCD9600_MAXPULSE 70
|
||||
#define DCD9600_THRES 50
|
||||
#define DCD9600_DEC 5
|
||||
#define DCD9600_INC 1
|
||||
|
||||
#define DCD300_MAXPULSE 50
|
||||
#define DCD300_THRES 6
|
||||
#define DCD300_DEC 1
|
||||
#define DCD300_MAXPULSE 140
|
||||
#define DCD300_THRES 120
|
||||
#define DCD300_DEC 3
|
||||
#define DCD300_INC 5
|
||||
#define DCD300_PLLTUNE 0
|
||||
|
||||
#define N1200 8 //samples per symbol @ fs=9600, oversampling = 38400 Hz
|
||||
#define N9600 4 //fs=38400, oversampling = 153600 Hz
|
||||
|
@ -70,13 +66,11 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define PLL300_LOCKED_TUNE 0.74f
|
||||
#define PLL300_NOT_LOCKED_TUNE 0.50f
|
||||
|
||||
//for 9600 modem AGC, but not used
|
||||
// #define AGC9600_ATTACK 0.08f //0.08
|
||||
// #define AGC9600_DECAY 0.0008f
|
||||
|
||||
#define DAC_SINE_SIZE 32 //DAC sine table size
|
||||
#define AMP_TRACKING_ATTACK 0.16f //0.16
|
||||
#define AMP_TRACKING_DECAY 0.00004f //0.00004
|
||||
|
||||
|
||||
#define DAC_SINE_SIZE 128 //DAC sine table size
|
||||
|
||||
|
||||
struct ModemDemodConfig ModemConfig;
|
||||
|
@ -86,7 +80,7 @@ static enum ModemTxTestMode txTestState; //current TX test mode
|
|||
static uint8_t demodCount; //actual number of parallel demodulators
|
||||
static uint16_t dacSine[DAC_SINE_SIZE]; //sine samples for DAC
|
||||
static uint8_t dacSineIdx; //current sine sample index
|
||||
static uint16_t samples[4]; //very raw received samples, filled directly by DMA
|
||||
static volatile uint16_t samples[4]; //very raw received samples, filled directly by DMA
|
||||
static uint8_t currentSymbol; //current symbol for NRZI encoding
|
||||
static uint8_t scrambledSymbol; //current symbol after scrambling
|
||||
static float markFreq; //mark frequency
|
||||
|
@ -119,14 +113,14 @@ static const int16_t bpf1200[8] =
|
|||
*/
|
||||
static const int16_t bpf1200Inv[8] =
|
||||
{
|
||||
-10513,
|
||||
-10854,
|
||||
9589,
|
||||
23884,
|
||||
9589,
|
||||
-10854,
|
||||
-10513,
|
||||
-879
|
||||
-10513,
|
||||
-10854,
|
||||
9589,
|
||||
23884,
|
||||
9589,
|
||||
-10854,
|
||||
-10513,
|
||||
-879
|
||||
};
|
||||
|
||||
//fs=9600, rectangular, fc1=1500, fc2=1900, 0 dB @ 1600 Hz and 1800 Hz, N = 15, gain 65536
|
||||
|
@ -147,21 +141,21 @@ static const int16_t lpf300[14] =
|
|||
//but it seems to be the best among all I have tested
|
||||
static const int16_t lpf1200[15] =
|
||||
{
|
||||
-6128,
|
||||
-5974,
|
||||
-2503,
|
||||
4125,
|
||||
12679,
|
||||
21152,
|
||||
27364,
|
||||
29643,
|
||||
27364,
|
||||
21152,
|
||||
12679,
|
||||
4125,
|
||||
-2503,
|
||||
-5974,
|
||||
-6128
|
||||
-6128,
|
||||
-5974,
|
||||
-2503,
|
||||
4125,
|
||||
12679,
|
||||
21152,
|
||||
27364,
|
||||
29643,
|
||||
27364,
|
||||
21152,
|
||||
12679,
|
||||
4125,
|
||||
-2503,
|
||||
-5974,
|
||||
-6128
|
||||
};
|
||||
|
||||
//fs=38400 Hz, Gaussian, fc=4800 Hz (9600 Bd), N=9, gain=65536
|
||||
|
@ -192,8 +186,6 @@ struct DemodState
|
|||
struct Filter lpf;
|
||||
|
||||
uint8_t dcd : 1; //DCD state
|
||||
uint64_t RMSenergy; //frame energy counter (sum of samples squared)
|
||||
uint32_t RMSsampleCount; //number of samples for RMS
|
||||
|
||||
int32_t pll; //bit recovery PLL counter
|
||||
int32_t pllStep;
|
||||
|
@ -202,12 +194,11 @@ struct DemodState
|
|||
|
||||
int32_t dcdPll; //DCD PLL main counter
|
||||
uint8_t dcdLastSymbol; //last symbol for DCD
|
||||
uint8_t dcdCounter; //DCD "pulse" counter (incremented when RX signal is correct)
|
||||
int32_t dcdMax;
|
||||
int32_t dcdThres;
|
||||
int32_t dcdInc;
|
||||
int32_t dcdDec;
|
||||
float dcdAdjust;
|
||||
uint16_t dcdCounter; //DCD "pulse" counter (incremented when RX signal is correct)
|
||||
uint16_t dcdMax;
|
||||
uint16_t dcdThres;
|
||||
uint16_t dcdInc;
|
||||
uint16_t dcdDec;
|
||||
|
||||
int16_t peak;
|
||||
int16_t valley;
|
||||
|
@ -229,7 +220,7 @@ static int32_t filter(struct Filter *filter, int32_t input)
|
|||
filter->samples[0] = input; //store new sample
|
||||
for(uint8_t i = 0; i < filter->taps; i++)
|
||||
{
|
||||
out += filter->coeffs[i] * filter->samples[i];
|
||||
out += (int32_t)filter->coeffs[i] * filter->samples[i];
|
||||
}
|
||||
return out >> filter->gainShift;
|
||||
}
|
||||
|
@ -257,15 +248,11 @@ uint8_t ModemIsTxTestOngoing(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ModemClearRMS(uint8_t modem)
|
||||
void ModemGetSignalLevel(uint8_t modem, int8_t *peak, int8_t *valley, uint8_t *level)
|
||||
{
|
||||
demodState[modem].RMSenergy = 0;
|
||||
demodState[modem].RMSsampleCount = 0;
|
||||
}
|
||||
|
||||
uint16_t ModemGetRMS(uint8_t modem)
|
||||
{
|
||||
return sqrtf((float)demodState[modem].RMSenergy / (float)demodState[modem].RMSsampleCount);
|
||||
*peak = (100 * (int32_t)demodState[modem].peak) >> 12;
|
||||
*valley = (100 * (int32_t)demodState[modem].valley) >> 12;
|
||||
*level = (100 * (int32_t)(demodState[modem].peak - demodState[modem].valley)) >> 13;
|
||||
}
|
||||
|
||||
enum ModemPrefilter ModemGetFilterType(uint8_t modem)
|
||||
|
@ -321,6 +308,7 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
{
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF2;
|
||||
|
||||
//each sample is 12 bits, output sample is 13 bits
|
||||
int32_t sample = ((samples[0] + samples[1] + samples[2] + samples[3]) >> 1) - 4095; //calculate input sample (decimation)
|
||||
|
||||
bool partialDcd = false;
|
||||
|
@ -359,21 +347,17 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
if(ModemConfig.usePWM)
|
||||
sample = scrambledSymbol ? 89 : 0;
|
||||
sample = scrambledSymbol ? 256 : 1;
|
||||
else
|
||||
sample = scrambledSymbol ? 15 : 0;
|
||||
|
||||
sample = filter(&demodState[0].lpf, sample);
|
||||
if(sample < 0)
|
||||
sample = 0;
|
||||
else if(sample > 15)
|
||||
sample = 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
sample = dacSine[dacSineIdx];
|
||||
dacSineIdx++;
|
||||
dacSineIdx &= (DAC_SINE_SIZE - 1);
|
||||
dacSineIdx %= DAC_SINE_SIZE;
|
||||
}
|
||||
|
||||
if(ModemConfig.usePWM)
|
||||
|
@ -383,22 +367,12 @@ void DMA1_Channel2_IRQHandler(void)
|
|||
else
|
||||
{
|
||||
GPIOB->ODR &= ~0xF000; //zero 4 oldest bits
|
||||
GPIOB->ODR |= (sample << 12); //write sample to 4 oldest bits
|
||||
GPIOB->ODR |= ((uint32_t)sample << 12); //write sample to 4 oldest bits
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void txBit()
|
||||
{
|
||||
if(Ax25GetTxBit() == 0) //get next bit and check if it's 0
|
||||
{
|
||||
currentSymbol ^= 1; //change symbol - NRZI encoding
|
||||
}
|
||||
//if 1, no symbol change
|
||||
|
||||
scrambledSymbol = scramble(currentSymbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ISR for baudrate generator timer. NRZI encoding is done here.
|
||||
*/
|
||||
|
@ -417,36 +391,56 @@ void txBit()
|
|||
}
|
||||
else //transmit test mode
|
||||
{
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
scrambledSymbol ^= 1;
|
||||
return;
|
||||
}
|
||||
currentSymbol ^= 1; //change symbol
|
||||
}
|
||||
|
||||
TIM1->CNT = 0;
|
||||
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
scrambledSymbol = scramble(currentSymbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM1->CNT = 0;
|
||||
if(currentSymbol) //current symbol is space
|
||||
TIM1->ARR = spaceStep;
|
||||
else //mark
|
||||
TIM1->ARR = markStep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Demodulate received sample (4x oversampling)
|
||||
* @param[in] sample Received sample
|
||||
* @param[in] sample Received sample, no more than 13 bits
|
||||
* @param[in] *dem Demodulator state
|
||||
* @return Current tone (0 or 1)
|
||||
*/
|
||||
static int32_t demodulate(int16_t sample, struct DemodState *dem)
|
||||
{
|
||||
dem->RMSenergy += ((sample >> 1) * (sample >> 1)); //square the sample and add it to the sum
|
||||
dem->RMSsampleCount++; //increment number of samples
|
||||
//input signal amplitude tracking
|
||||
if(sample >= dem->peak)
|
||||
{
|
||||
dem->peak += (((int32_t)(AMP_TRACKING_ATTACK * (float)32768) * (int32_t)(sample - dem->peak)) >> 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
dem->peak += (((int32_t)(AMP_TRACKING_DECAY * (float)32768) * (int32_t)(sample - dem->peak)) >> 15);
|
||||
}
|
||||
|
||||
if(sample <= dem->valley)
|
||||
{
|
||||
dem->valley -= (((int32_t)(AMP_TRACKING_ATTACK * (float)32768) * (int32_t)(dem->valley - sample)) >> 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
dem->valley -= (((int32_t)(AMP_TRACKING_DECAY * (float)32768) * (int32_t)(dem->valley - sample)) >> 15);
|
||||
}
|
||||
|
||||
|
||||
if(ModemConfig.modem != MODEM_9600)
|
||||
{
|
||||
|
@ -472,18 +466,17 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
|
|||
outHiQ += t * coeffHiQ[i];
|
||||
}
|
||||
|
||||
outHiI >>= 12;
|
||||
outHiQ >>= 12;
|
||||
outLoI >>= 12;
|
||||
outLoQ >>= 12;
|
||||
outHiI >>= 14;
|
||||
outHiQ >>= 14;
|
||||
outLoI >>= 14;
|
||||
outLoQ >>= 14;
|
||||
|
||||
sample = ABS(outHiI) + ABS(outHiQ) - ABS(outLoI) - ABS(outLoQ);
|
||||
sample = (abs(outLoI) + abs(outLoQ)) - (abs(outHiI) + abs(outHiQ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//DCD using PLL
|
||||
//PLL is running nominally at 1200 Hz (= baudrate)
|
||||
//DCD using "PLL"
|
||||
//PLL is running nominally at the frequency equal to the baudrate
|
||||
//PLL timer is counting up and eventually overflows to a minimal negative value
|
||||
//so it crosses zero in the middle
|
||||
//tone change should happen somewhere near this zero-crossing (in ideal case of exactly same TX and RX baudrates)
|
||||
|
@ -494,18 +487,19 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
|
|||
//when configured properly, it's generally immune to noise, as the detected tone changes much faster than 1200 baud
|
||||
//it's also important to set some maximum value for DCD counter, otherwise the DCD is "sticky"
|
||||
|
||||
dem->dcdPll = (signed)((unsigned)(dem->dcdPll) + (unsigned)(dem->pllStep)); //keep PLL ticking at the frequency equal to baudrate
|
||||
|
||||
dem->dcdPll = (int32_t)((uint32_t)(dem->dcdPll) + (uint32_t)(dem->pllStep)); //keep PLL ticking at the frequency equal to baudrate
|
||||
|
||||
if((sample > 0) != dem->dcdLastSymbol) //tone changed
|
||||
{
|
||||
if(abs(dem->dcdPll) < dem->pllStep) //tone change occurred near zero
|
||||
if((uint32_t)abs(dem->dcdPll) <= (uint32_t)(dem->pllStep)) //tone change occurred near zero
|
||||
dem->dcdCounter += dem->dcdInc; //increase DCD counter
|
||||
else //tone change occurred far from zero
|
||||
{
|
||||
if(dem->dcdCounter >= dem->dcdDec) //avoid overflow
|
||||
dem->dcdCounter -= dem->dcdDec; //decrease DCD counter
|
||||
}
|
||||
dem->dcdPll = (int)(dem->dcdPll * dem->dcdAdjust); //adjust PLL
|
||||
dem->dcdPll = 0;
|
||||
}
|
||||
|
||||
dem->dcdLastSymbol = sample > 0; //store last symbol for symbol change detection
|
||||
|
@ -518,39 +512,7 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
|
|||
else //below DCD threshold
|
||||
dem->dcd = 0; //no DCD
|
||||
|
||||
sample = filter(&dem->lpf, sample);
|
||||
|
||||
// if(ModemConfig.modem == MODEM_9600)
|
||||
// {
|
||||
// //AGC, seems to be not needed
|
||||
// if(sample >= dem->peak)
|
||||
// {
|
||||
// dem->peak += (((int32_t)(AGC9600_ATTACK * (float)32768) * (int32_t)(sample - dem->peak)) >> 15);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dem->peak += (((int32_t)(AGC9600_DECAY * (float)32768) * (int32_t)(sample - dem->peak)) >> 15);
|
||||
// }
|
||||
|
||||
// if(sample <= dem->valley)
|
||||
// {
|
||||
// dem->valley += (((int32_t)(AGC9600_ATTACK * (float)32768) * (int32_t)(sample - dem->valley)) >> 15);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dem->valley += (((int32_t)(AGC9600_DECAY * (float)32768) * (int32_t)(sample - dem->valley)) >> 15);
|
||||
// }
|
||||
|
||||
// //remove DC component (subtract average value of peaks)
|
||||
// //and normalize to 32768 peak-to-peak (-16384:16384)
|
||||
// //32768 is equal to 1 << 15
|
||||
// if(dem->peak > dem->valley)
|
||||
// {
|
||||
// sample = ((((int32_t)(sample) - ((int32_t)(dem->peak + dem->valley) >> 1)) << 15) / (int32_t)(dem->peak - dem->valley));
|
||||
// }
|
||||
// }
|
||||
|
||||
return sample > 0;
|
||||
return filter(&dem->lpf, sample) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,7 +529,7 @@ static void decode(uint8_t symbol, uint8_t demod)
|
|||
//Current symbol is sampled at PLL counter overflow, so symbol transition should occur at PLL counter zero
|
||||
int32_t previous = dem->pll; //store last clock state
|
||||
|
||||
dem->pll = (signed)((unsigned)(dem->pll) + (unsigned)(dem->pllStep)); //keep PLL running
|
||||
dem->pll = (int32_t)((uint32_t)(dem->pll) + (uint32_t)(dem->pllStep)); //keep PLL running
|
||||
|
||||
dem->rawSymbols <<= 1; //store received unsynchronized symbol
|
||||
dem->rawSymbols |= (symbol & 1);
|
||||
|
@ -629,6 +591,15 @@ void ModemTxTestStart(enum ModemTxTestMode type)
|
|||
NVIC_DisableIRQ(DMA1_Channel2_IRQn); //disable RX DMA interrupt
|
||||
NVIC_EnableIRQ(TIM1_UP_IRQn); //enable DAC interrupt
|
||||
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
{
|
||||
TIM1->ARR = 103;
|
||||
//enable baudrate generator
|
||||
TIM3->CR1 = TIM_CR1_CEN; //enable timer
|
||||
NVIC_EnableIRQ(TIM3_IRQn); //enable interrupt in NVIC
|
||||
return;
|
||||
}
|
||||
|
||||
if(type == TEST_MARK)
|
||||
{
|
||||
TIM1->ARR = markStep;
|
||||
|
@ -665,6 +636,8 @@ void ModemTxTestStop(void)
|
|||
void ModemTransmitStart(void)
|
||||
{
|
||||
setPtt(1); //PTT on
|
||||
if(ModemConfig.modem == MODEM_9600)
|
||||
TIM1->ARR = 103;
|
||||
|
||||
TIM3->CR1 = TIM_CR1_CEN;
|
||||
TIM1->CR1 = TIM_CR1_CEN;
|
||||
|
@ -681,17 +654,17 @@ void ModemTransmitStart(void)
|
|||
*/
|
||||
void ModemTransmitStop(void)
|
||||
{
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
TIM3->CR1 &= ~TIM_CR1_CEN;
|
||||
TIM1->CR1 &= ~TIM_CR1_CEN;
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
TIM3->CR1 &= ~TIM_CR1_CEN;
|
||||
TIM1->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
NVIC_DisableIRQ(TIM1_UP_IRQn);
|
||||
NVIC_DisableIRQ(TIM3_IRQn);
|
||||
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||||
NVIC_DisableIRQ(TIM1_UP_IRQn);
|
||||
NVIC_DisableIRQ(TIM3_IRQn);
|
||||
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||||
|
||||
setPtt(0);
|
||||
setPtt(0);
|
||||
|
||||
TIM4->CCR1 = 44; //set around 50% duty cycle
|
||||
TIM4->CCR1 = 44; //set around 50% duty cycle
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -795,9 +768,12 @@ void ModemInit(void)
|
|||
TIM1->DIER |= TIM_DIER_UIE;
|
||||
|
||||
//baudrate timer
|
||||
TIM3->PSC = 71; //72/72=1 MHz
|
||||
TIM3->PSC = 3; //72/9=18 MHz
|
||||
TIM3->DIER |= TIM_DIER_UIE;
|
||||
|
||||
if(ModemConfig.modem > MODEM_9600)
|
||||
ModemConfig.modem = MODEM_1200;
|
||||
|
||||
if((ModemConfig.modem == MODEM_1200) || (ModemConfig.modem == MODEM_1200_V23)
|
||||
#ifdef ENABLE_PSK
|
||||
|| (ModemConfig.modem == MODEM_BPSK_1200) || (ModemConfig.modem == MODEM_QPSK_1200)
|
||||
|
@ -833,7 +809,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD1200_THRES;
|
||||
demodState[0].dcdInc = DCD1200_INC;
|
||||
demodState[0].dcdDec = DCD1200_DEC;
|
||||
demodState[0].dcdAdjust = DCD1200_PLLTUNE;
|
||||
|
||||
demodState[1].pllStep = PLL1200_STEP;
|
||||
demodState[1].pllLockedAdjust = PLL1200_LOCKED_TUNE;
|
||||
|
@ -842,13 +817,13 @@ void ModemInit(void)
|
|||
demodState[1].dcdThres = DCD1200_THRES;
|
||||
demodState[1].dcdInc = DCD1200_INC;
|
||||
demodState[1].dcdDec = DCD1200_DEC;
|
||||
demodState[1].dcdAdjust = DCD1200_PLLTUNE;
|
||||
|
||||
demodState[1].prefilter = PREFILTER_NONE;
|
||||
demodState[1].lpf.coeffs = (int16_t*)lpf1200;
|
||||
demodState[1].lpf.taps = sizeof(lpf1200) / sizeof(*lpf1200);
|
||||
demodState[1].lpf.gainShift = 15;
|
||||
|
||||
|
||||
demodState[0].lpf.coeffs = (int16_t*)lpf1200;
|
||||
demodState[0].lpf.taps = sizeof(lpf1200) / sizeof(*lpf1200);
|
||||
demodState[0].lpf.gainShift = 15;
|
||||
|
@ -914,7 +889,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD300_THRES;
|
||||
demodState[0].dcdInc = DCD300_INC;
|
||||
demodState[0].dcdDec = DCD300_DEC;
|
||||
demodState[0].dcdAdjust = DCD300_PLLTUNE;
|
||||
|
||||
demodState[0].prefilter = PREFILTER_FLAT;
|
||||
demodState[0].bpf.coeffs = (int16_t*)bpf300;
|
||||
|
@ -939,7 +913,6 @@ void ModemInit(void)
|
|||
demodState[0].dcdThres = DCD9600_THRES;
|
||||
demodState[0].dcdInc = DCD9600_INC;
|
||||
demodState[0].dcdDec = DCD9600_DEC;
|
||||
demodState[0].dcdAdjust = DCD9600_PLLTUNE;
|
||||
|
||||
demodState[0].prefilter = PREFILTER_NONE;
|
||||
//this filter will be used for RX and TX
|
||||
|
@ -954,7 +927,7 @@ void ModemInit(void)
|
|||
|
||||
markStep = 4000000 / (DAC_SINE_SIZE * markFreq) - 1;
|
||||
spaceStep = 4000000 / (DAC_SINE_SIZE * spaceFreq) - 1;
|
||||
baudRateStep = 1000000 / baudRate - 1;
|
||||
baudRateStep = 18000000 / baudRate - 1;
|
||||
|
||||
|
||||
TIM3->ARR = baudRateStep;
|
||||
|
@ -970,7 +943,8 @@ void ModemInit(void)
|
|||
for(uint8_t i = 0; i < DAC_SINE_SIZE; i++) //calculate DAC sine samples
|
||||
{
|
||||
if(ModemConfig.usePWM)
|
||||
dacSine[i] = ((sinf(2.f * 3.1416f * (float)i / (float)DAC_SINE_SIZE) + 1.f) * 45.f);
|
||||
//produce values in range 1 to 256
|
||||
dacSine[i] = ((sinf(2.f * 3.1416f * (float)i / (float)DAC_SINE_SIZE) + 1.f) * 128.f);
|
||||
else
|
||||
dacSine[i] = ((7.f * sinf(2.f * 3.1416f * (float)i / (float)DAC_SINE_SIZE)) + 8.f);
|
||||
}
|
||||
|
@ -984,12 +958,12 @@ void ModemInit(void)
|
|||
GPIOB->CRL &= ~GPIO_CRL_CNF6_0;
|
||||
|
||||
//set up PWM generation
|
||||
TIM4->PSC = 7; //72MHz/8=9MHz
|
||||
TIM4->ARR = 90; //9MHz/90=100kHz
|
||||
TIM4->PSC = 2; //72MHz/3=24MHz
|
||||
TIM4->ARR = 257; //18MHz/258=93kHz
|
||||
|
||||
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
|
||||
TIM4->CCER |= TIM_CCER_CC1E;
|
||||
TIM4->CCR1 = 44; //initial duty cycle
|
||||
TIM4->CCR1 = 127; //initial duty cycle
|
||||
|
||||
TIM4->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "common.h"
|
||||
#include <string.h>
|
||||
#include "digipeater.h"
|
||||
#include "kiss.h"
|
||||
|
||||
Uart Uart1, Uart2, UartUsb;
|
||||
|
||||
|
@ -30,28 +31,22 @@ static void handleInterrupt(Uart *port)
|
|||
if(port->port->SR & USART_SR_RXNE) //byte received
|
||||
{
|
||||
port->port->SR &= ~USART_SR_RXNE;
|
||||
port->rxBuffer[port->rxBufferHead++] = port->port->DR; //store it
|
||||
uint8_t data = port->port->DR;
|
||||
port->rxBuffer[port->rxBufferHead++] = data; //store it
|
||||
port->rxBufferHead %= UART_BUFFER_SIZE;
|
||||
|
||||
KissParse(port, data);
|
||||
TermHandleSpecial(port);
|
||||
|
||||
if(port->mode == MODE_KISS)
|
||||
port->kissTimer = SysTickGet() + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
|
||||
}
|
||||
if(port->port->SR & USART_SR_IDLE) //line is idle, end of data reception
|
||||
{
|
||||
port->port->DR; //reset idle flag by dummy read
|
||||
if(port->rxBufferHead != 0)
|
||||
{
|
||||
if((port->rxBuffer[0] == 0xC0) && (port->rxBuffer[port->rxBufferHead - 1] == 0xC0)) //data starts with 0xc0 and ends with 0xc0 - this is a KISS frame
|
||||
{
|
||||
port->rxType = DATA_KISS;
|
||||
port->kissTimer = 0;
|
||||
}
|
||||
else if(((port->rxBuffer[port->rxBufferHead - 1] == '\r') || (port->rxBuffer[port->rxBufferHead - 1] == '\n'))) //data ends with \r or \n, process as data
|
||||
if(((port->rxBuffer[port->rxBufferHead - 1] == '\r') || (port->rxBuffer[port->rxBufferHead - 1] == '\n'))) //data ends with \r or \n, process as data
|
||||
{
|
||||
port->rxType = DATA_TERM;
|
||||
port->kissTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +54,7 @@ static void handleInterrupt(Uart *port)
|
|||
{
|
||||
if((port->txBufferHead != port->txBufferTail) || port->txBufferFull) //if there is anything to transmit
|
||||
{
|
||||
port->port->DR = port->txBuffer[port->txBufferTail++]; //push it to the refister
|
||||
port->port->DR = port->txBuffer[port->txBufferTail++];
|
||||
port->txBufferTail %= UART_BUFFER_SIZE;
|
||||
port->txBufferFull = 0;
|
||||
}
|
||||
|
@ -68,13 +63,6 @@ static void handleInterrupt(Uart *port)
|
|||
port->port->CR1 &= ~USART_CR1_TXEIE;
|
||||
}
|
||||
}
|
||||
|
||||
if((port->kissTimer > 0) && (SysTickGet() >= port->kissTimer)) //KISS timer timeout
|
||||
{
|
||||
port->kissTimer = 0;
|
||||
port->rxBufferHead = 0;
|
||||
memset(port->rxBuffer, 0, sizeof(port->rxBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
void USART1_IRQHandler(void) __attribute__ ((interrupt));
|
||||
|
@ -160,10 +148,11 @@ void UartInit(Uart *port, USART_TypeDef *uart, uint32_t baud)
|
|||
port->txBufferFull = 0;
|
||||
port->mode = MODE_KISS;
|
||||
port->enabled = 0;
|
||||
port->kissTimer = 0;
|
||||
port->kissBufferHead = 0;
|
||||
port->lastRxBufferHead = 0;
|
||||
memset(port->rxBuffer, 0, sizeof(port->rxBuffer));
|
||||
memset(port->txBuffer, 0, sizeof(port->txBuffer));
|
||||
memset(port->kissBuffer, 0, sizeof(port->kissBuffer));
|
||||
}
|
||||
|
||||
|
||||
|
@ -235,12 +224,3 @@ void UartClearRx(Uart *port)
|
|||
port->rxType = DATA_NOTHING;
|
||||
}
|
||||
|
||||
void UartHandleKissTimeout(Uart *port)
|
||||
{
|
||||
if((port->kissTimer > 0) && (SysTickGet() >= port->kissTimer)) //KISS timer timeout
|
||||
{
|
||||
port->kissTimer = 0;
|
||||
port->rxBufferHead = 0;
|
||||
memset(port->rxBuffer, 0, sizeof(port->rxBuffer));
|
||||
}
|
||||
}
|
||||
|
|
27
Src/fx25.c
27
Src/fx25.c
|
@ -25,37 +25,16 @@ const struct Fx25Mode Fx25ModeList[11] =
|
|||
{.tag = 0x4A4ABEC4A724B796, .K = 64, .T = 64}
|
||||
};
|
||||
|
||||
static inline uint8_t hammingDistance(uint64_t x, uint64_t y)
|
||||
{
|
||||
uint8_t distance = 0;
|
||||
for(uint8_t i = 0; i < 64; i++)
|
||||
{
|
||||
distance += (x ^ y) & 1;
|
||||
x >>= 1;
|
||||
y >>= 1;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
|
||||
const struct Fx25Mode* Fx25GetModeForTag(uint64_t tag)
|
||||
{
|
||||
struct Fx25Mode *closest = NULL;
|
||||
uint8_t closestDistance = 255;
|
||||
for(uint8_t i = 0; i < sizeof(Fx25ModeList) / sizeof(*Fx25ModeList); i++)
|
||||
{
|
||||
uint8_t distance = hammingDistance(tag, Fx25ModeList[i].tag);
|
||||
if(distance == 0)
|
||||
if(__builtin_popcountll(tag ^ Fx25ModeList[i].tag) <= FX25_MAX_DISTANCE)
|
||||
return &Fx25ModeList[i];
|
||||
else if(distance < closestDistance)
|
||||
{
|
||||
closest = (struct Fx25Mode*)&Fx25ModeList[i];
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
if(closestDistance <= FX25_MAX_DISTANCE)
|
||||
return closest;
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct Fx25Mode* Fx25GetModeForSize(uint16_t size)
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright 2020-2023 Piotr Wilkon
|
||||
|
||||
This file is part of VP-Digi.
|
||||
|
||||
VP-Digi is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
VP-Digi is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kiss.h"
|
||||
#include "ax25.h"
|
||||
#include "digipeater.h"
|
||||
|
||||
void KissSend(Uart *port, uint8_t *buf, uint16_t size)
|
||||
{
|
||||
if(port->mode == MODE_KISS)
|
||||
{
|
||||
UartSendByte(port, 0xC0);
|
||||
UartSendByte(port, 0x00);
|
||||
for(uint16_t i = 0; i < size; i++)
|
||||
{
|
||||
if(buf[i] == 0xC0) //frame end in data
|
||||
{
|
||||
UartSendByte(port, 0xDB); //frame escape
|
||||
UartSendByte(port, 0xDC); //transposed frame end
|
||||
}
|
||||
else if(buf[i] == 0xDB) //frame escape in data
|
||||
{
|
||||
UartSendByte(port, 0xDB); //frame escape
|
||||
UartSendByte(port, 0xDD); //transposed frame escape
|
||||
}
|
||||
else
|
||||
UartSendByte(port, buf[i]);
|
||||
}
|
||||
UartSendByte(port, 0xC0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KissParse(Uart *port, uint8_t data)
|
||||
{
|
||||
if(data == 0xC0) //frame end marker
|
||||
{
|
||||
if(port->kissBufferHead < 16) //command+source+destination+Control=16
|
||||
{
|
||||
port->kissBufferHead = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if((port->kissBuffer[0] & 0xF) != 0) //check if this is an actual frame
|
||||
{
|
||||
port->kissBufferHead = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
//simple sanity check
|
||||
//check if LSbits in the first 13 bytes are set to 0
|
||||
//they should always be in an AX.25 frame
|
||||
for(uint8_t i = 0; i < 13; i++)
|
||||
{
|
||||
if((port->kissBuffer[i + 1] & 1) != 0)
|
||||
{
|
||||
port->kissBufferHead = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Ax25WriteTxFrame(&port->kissBuffer[1], port->kissBufferHead - 1);
|
||||
DigiStoreDeDupe(&port->kissBuffer[1], port->kissBufferHead - 1);
|
||||
port->kissBufferHead = 0;
|
||||
return;
|
||||
}
|
||||
else if(port->kissBufferHead > 0)
|
||||
{
|
||||
if((data == 0xDC) && (port->kissBuffer[port->kissBufferHead - 1] == 0xDB)) //escape character with transposed frame end
|
||||
{
|
||||
port->kissBuffer[port->kissBufferHead - 1] = 0xC0;
|
||||
return;
|
||||
}
|
||||
else if((data == 0xDD) && (port->kissBuffer[port->kissBufferHead - 1] == 0xDB)) //escape character with transposed escape character
|
||||
{
|
||||
port->kissBuffer[port->kissBufferHead - 1] = 0xDB;
|
||||
return;
|
||||
}
|
||||
}
|
||||
port->kissBuffer[port->kissBufferHead++] = data;
|
||||
port->kissBufferHead %= sizeof(port->kissBuffer);
|
||||
}
|
80
Src/main.c
80
Src/main.c
|
@ -98,70 +98,67 @@ static void handleFrame(void)
|
|||
|
||||
uint8_t *buf;
|
||||
uint16_t size = 0;
|
||||
uint16_t signalLevel = 0;
|
||||
int8_t peak = 0;
|
||||
int8_t valley = 0;
|
||||
uint8_t signalLevel = 0;
|
||||
uint8_t fixed = 0;
|
||||
|
||||
while(Ax25ReadNextRxFrame(&buf, &size, &signalLevel, &fixed))
|
||||
while(Ax25ReadNextRxFrame(&buf, &size, &peak, &valley, &signalLevel, &fixed))
|
||||
{
|
||||
TermSendToAll(MODE_KISS, buf, size);
|
||||
|
||||
if(((UartUsb.mode == MODE_MONITOR) || (Uart1.mode == MODE_MONITOR) || (Uart2.mode == MODE_MONITOR)))
|
||||
{
|
||||
//in general, the RMS of the frame is calculated (excluding preamble!)
|
||||
//it it calculated from samples ranging from -4095 to 4095 (amplitude of 4095)
|
||||
//that should give a RMS of around 2900 for pure sine wave
|
||||
//for pure square wave it should be equal to the amplitude (around 4095)
|
||||
//real data contains lots of imperfections (especially mark/space amplitude imbalance) and this value is far smaller than 2900 for standard frames
|
||||
//division by 9 was selected by trial and error to provide a value of 100(%) when the input signal had peak-peak voltage of 3.3V
|
||||
//TODO: this probably should be done in a different way, like some peak amplitude tracing
|
||||
signalLevel /= 9;
|
||||
|
||||
if(signalLevel > 100)
|
||||
if(signalLevel > 70)
|
||||
{
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"\r\nInput level too high! Please reduce so most stations are around 50-70%.\r\n", 0);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"\r\nInput level too high! Please reduce so most stations are around 30-50%.\r\n", 0);
|
||||
}
|
||||
else if(signalLevel < 10)
|
||||
else if(signalLevel < 5)
|
||||
{
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"\r\nInput level too low! Please increase so most stations are around 50-70%.\r\n", 0);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"\r\nInput level too low! Please increase so most stations are around 30-50%.\r\n", 0);
|
||||
}
|
||||
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"(AX.25) Frame received [", 0);
|
||||
if(fixed == 0)
|
||||
for(uint8_t i = 0; i < ModemGetDemodulatorCount(); i++)
|
||||
{
|
||||
for(uint8_t i = 0; i < ModemGetDemodulatorCount(); i++)
|
||||
if(modemBitmap & (1 << i))
|
||||
{
|
||||
if(modemBitmap & (1 << i))
|
||||
enum ModemPrefilter m = ModemGetFilterType(i);
|
||||
switch(m)
|
||||
{
|
||||
enum ModemPrefilter m = ModemGetFilterType(i);
|
||||
switch(m)
|
||||
{
|
||||
case PREFILTER_PREEMPHASIS:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"P", 1);
|
||||
break;
|
||||
case PREFILTER_DEEMPHASIS:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"D", 1);
|
||||
break;
|
||||
case PREFILTER_FLAT:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"F", 1);
|
||||
break;
|
||||
case PREFILTER_NONE:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"|", 1);
|
||||
}
|
||||
case PREFILTER_PREEMPHASIS:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"P", 1);
|
||||
break;
|
||||
case PREFILTER_DEEMPHASIS:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"D", 1);
|
||||
break;
|
||||
case PREFILTER_FLAT:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"F", 1);
|
||||
break;
|
||||
case PREFILTER_NONE:
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"N", 1);
|
||||
}
|
||||
else
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"_", 1);
|
||||
}
|
||||
else
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"_", 1);
|
||||
}
|
||||
else
|
||||
TermSendNumberToAll(MODE_MONITOR, fixed);
|
||||
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"], signal level ", 0);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"], ", 0);
|
||||
if(fixed != AX25_NOT_FX25)
|
||||
{
|
||||
TermSendNumberToAll(MODE_MONITOR, fixed);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)" bytes fixed, ", 0);
|
||||
}
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"signal level ", 0);
|
||||
TermSendNumberToAll(MODE_MONITOR, signalLevel);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"%: ", 0);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"% (", 0);
|
||||
TermSendNumberToAll(MODE_MONITOR, peak);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"%/", 0);
|
||||
TermSendNumberToAll(MODE_MONITOR, valley);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"%): ", 0);
|
||||
|
||||
SendTNC2(buf, size);
|
||||
TermSendToAll(MODE_MONITOR, (uint8_t*)"\r\n", 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,6 +234,7 @@ int main(void)
|
|||
|
||||
ConfigRead();
|
||||
|
||||
ModemInit();
|
||||
Ax25Init();
|
||||
#ifdef ENABLE_FX25
|
||||
Fx25Init();
|
||||
|
@ -250,7 +248,6 @@ int main(void)
|
|||
UartConfig(&Uart2, 1);
|
||||
UartConfig(&UartUsb, 1);
|
||||
|
||||
ModemInit();
|
||||
BeaconInit();
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
@ -294,7 +291,6 @@ int main(void)
|
|||
TermParse(&Uart2);
|
||||
UartClearRx(&Uart2);
|
||||
}
|
||||
UartHandleKissTimeout(&UartUsb);
|
||||
|
||||
BeaconCheck(); //check beacons
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ along with VP-DigiConfig. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "drivers/modem.h"
|
||||
#include "ax25.h"
|
||||
#include "drivers/systick.h"
|
||||
#include "kiss.h"
|
||||
|
||||
void TermHandleSpecial(Uart *u)
|
||||
{
|
||||
|
@ -57,25 +58,13 @@ void TermHandleSpecial(Uart *u)
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void sendKiss(Uart *port, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
if(port->mode == MODE_KISS) //check if KISS mode
|
||||
{
|
||||
UartSendByte(port, 0xc0); //send data in kiss format
|
||||
UartSendByte(port, 0x00);
|
||||
UartSendString(port, buf, len);
|
||||
UartSendByte(port, 0xc0);
|
||||
}
|
||||
}
|
||||
|
||||
void TermSendToAll(enum UartMode mode, uint8_t *data, uint16_t size)
|
||||
{
|
||||
if(MODE_KISS == mode)
|
||||
{
|
||||
sendKiss(&Uart1, data, size);
|
||||
sendKiss(&Uart2, data, size);
|
||||
sendKiss(&UartUsb, data, size);
|
||||
KissSend(&Uart1, data, size);
|
||||
KissSend(&Uart2, data, size);
|
||||
KissSend(&UartUsb, data, size);
|
||||
}
|
||||
else if(MODE_MONITOR == mode)
|
||||
{
|
||||
|
@ -86,7 +75,6 @@ void TermSendToAll(enum UartMode mode, uint8_t *data, uint16_t size)
|
|||
if(Uart2.mode == MODE_MONITOR)
|
||||
UartSendString(&Uart2, data, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TermSendNumberToAll(enum UartMode mode, int32_t n)
|
||||
|
@ -104,8 +92,6 @@ void TermSendNumberToAll(enum UartMode mode, int32_t n)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const char monitorHelp[] = "\r\nCommans available in monitor mode:\r\n"
|
||||
"help - shows this help page\r\n"
|
||||
"cal {low|high|alt|stop} - transmits/stops transmitter calibration pattern\r\n"
|
||||
|
@ -126,6 +112,7 @@ static const char configHelp[] = "\r\nCommands available in config mode:\r\n"
|
|||
"reboot - reboots the device\r\n"
|
||||
"time - show time since boot\r\n"
|
||||
"version - shows full firmware version info\r\n\r\n"
|
||||
"modem <type> - sets modem type: 1200, 1200_V23, 300 or 9600\r\n"
|
||||
"call <callsign-SSID> - sets callsign with optional SSID\r\n"
|
||||
"dest <address> - sets destination address\r\n"
|
||||
"txdelay <50-2550> - sets TXDelay time (ms)\r\n"
|
||||
|
@ -158,7 +145,23 @@ static const char configHelp[] = "\r\nCommands available in config mode:\r\n"
|
|||
|
||||
static void printConfig(Uart *src)
|
||||
{
|
||||
UartSendString(src, "Callsign: ", 0);
|
||||
UartSendString(src, "Modem: ", 0);
|
||||
switch(ModemConfig.modem)
|
||||
{
|
||||
case MODEM_1200:
|
||||
UartSendString(src, "AFSK Bell 202 1200 Bd 1200/2200 Hz", 0);
|
||||
break;
|
||||
case MODEM_1200_V23:
|
||||
UartSendString(src, "AFSK V.23 1200 Bd 1300/2100 Hz", 0);
|
||||
break;
|
||||
case MODEM_300:
|
||||
UartSendString(src, "AFSK Bell 103 300 Bd 1600/1800 Hz", 0);
|
||||
break;
|
||||
case MODEM_9600:
|
||||
UartSendString(src, "GFSK G3RUH 9600 Bd", 0);
|
||||
break;
|
||||
}
|
||||
UartSendString(src, "\r\nCallsign: ", 0);
|
||||
for(uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
if(GeneralConfig.call[i] != (' ' << 1))
|
||||
|
@ -376,8 +379,9 @@ void TermParse(Uart *src)
|
|||
else if(!strncmp(cmd, "config", 6))
|
||||
{
|
||||
UartSendString(src, (uint8_t*)"Switched to configuration mode\r\n"
|
||||
"Most settings will take effect immediately, but\r\n"
|
||||
"remember to save the configuration using \"save\"\r\n", 0);
|
||||
"Some settings require the device to be rebooted\r\n"
|
||||
"in order to behave correctly\r\n"
|
||||
"Always use \"save\" to save and reboot\r\n", 0);
|
||||
src->mode = MODE_TERM;
|
||||
return;
|
||||
}
|
||||
|
@ -387,14 +391,6 @@ void TermParse(Uart *src)
|
|||
src->mode = MODE_MONITOR;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* KISS parsing
|
||||
*/
|
||||
else if((src->mode == MODE_KISS) && (src->rxType == DATA_KISS))
|
||||
{
|
||||
Ax25TxKiss(src->rxBuffer, src->rxBufferHead);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Monitor mode handling
|
||||
*/
|
||||
|
@ -584,9 +580,24 @@ void TermParse(Uart *src)
|
|||
/*
|
||||
* Settings insertion handling
|
||||
*/
|
||||
else if(!strncmp(cmd, "modem", 5))
|
||||
{
|
||||
if(!strncmp(&cmd[6], "1200_V23", 8))
|
||||
ModemConfig.modem = MODEM_1200_V23;
|
||||
else if(!strncmp(&cmd[6], "1200", 4))
|
||||
ModemConfig.modem = MODEM_1200;
|
||||
else if(!strncmp(&cmd[6], "300", 3))
|
||||
ModemConfig.modem = MODEM_300;
|
||||
else if(!strncmp(&cmd[6], "9600", 4))
|
||||
ModemConfig.modem = MODEM_9600;
|
||||
else
|
||||
{
|
||||
UartSendString(src, "Incorrect modem type!\r\n", 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(!strncmp(cmd, "call", 4))
|
||||
{
|
||||
|
||||
if(!ParseCallsignWithSsid(&cmd[5], len - 5, GeneralConfig.call, &GeneralConfig.callSsid))
|
||||
{
|
||||
UartSendString(src, "Incorrect callsign!\r\n", 0);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "drivers/uart.h"
|
||||
#include "drivers/systick.h"
|
||||
#include "terminal.h"
|
||||
#include "kiss.h"
|
||||
/* USER CODE END INCLUDE */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
@ -274,6 +275,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
|
|||
for(uint16_t i = 0; i < *Len; i++)
|
||||
{
|
||||
UartUsb.rxBuffer[UartUsb.rxBufferHead++] = Buf[i];
|
||||
KissParse(&UartUsb, Buf[i]);
|
||||
UartUsb.rxBufferHead %= UART_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
@ -322,20 +324,11 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
|
|||
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
|
||||
static void handleUsbInterrupt(Uart *port)
|
||||
{
|
||||
if(port->mode == MODE_KISS)
|
||||
port->kissTimer = SysTickGet() + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
|
||||
|
||||
if(port->rxBufferHead != 0)
|
||||
{
|
||||
if((port->rxBuffer[0] == 0xC0) && (port->rxBuffer[port->rxBufferHead - 1] == 0xC0)) //data starts with 0xc0 and ends with 0xc0 - this is a KISS frame
|
||||
{
|
||||
port->rxType = DATA_KISS;
|
||||
port->kissTimer = 0;
|
||||
}
|
||||
else if(((port->rxBuffer[port->rxBufferHead - 1] == '\r') || (port->rxBuffer[port->rxBufferHead - 1] == '\n'))) //data ends with \r or \n, process as data
|
||||
if(((port->rxBuffer[port->rxBufferHead - 1] == '\r') || (port->rxBuffer[port->rxBufferHead - 1] == '\n'))) //data ends with \r or \n, process as data
|
||||
{
|
||||
port->rxType = DATA_TERM;
|
||||
port->kissTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
$CMP BP
|
||||
F https://www.electronicshub.org/getting-started-with-stm32f103c8t6-blue-pill/
|
||||
$ENDCMP
|
||||
#
|
||||
#End Doc Library
|
83028
doc/kicad/fp-info-cache
83028
doc/kicad/fp-info-cache
Plik diff jest za duży
Load Diff
|
@ -1,3 +0,0 @@
|
|||
(fp_lib_table
|
||||
(lib (name kicad)(type KiCad)(uri D:/sw4stm32-projekty/vp-digi/doc/kicad.pretty)(options "")(descr ""))
|
||||
)
|
|
@ -1,3 +0,0 @@
|
|||
(sym_lib_table
|
||||
(lib (name bluepill_breakouts)(type Legacy)(uri ${KIPRJMOD}/bluepill_breakouts.lib)(options "")(descr ""))
|
||||
)
|
|
@ -1,33 +0,0 @@
|
|||
update=22/05/2015 07:44:53
|
||||
version=1
|
||||
last_client=kicad
|
||||
[general]
|
||||
version=1
|
||||
RootSch=
|
||||
BoardNm=
|
||||
[pcbnew]
|
||||
version=1
|
||||
LastNetListRead=
|
||||
UseCmpFile=1
|
||||
PadDrill=0.600000000000
|
||||
PadDrillOvalY=0.600000000000
|
||||
PadSizeH=1.500000000000
|
||||
PadSizeV=1.500000000000
|
||||
PcbTextSizeV=1.500000000000
|
||||
PcbTextSizeH=1.500000000000
|
||||
PcbTextThickness=0.300000000000
|
||||
ModuleTextSizeV=1.000000000000
|
||||
ModuleTextSizeH=1.000000000000
|
||||
ModuleTextSizeThickness=0.150000000000
|
||||
SolderMaskClearance=0.000000000000
|
||||
SolderMaskMinWidth=0.000000000000
|
||||
DrawSegmentWidth=0.200000000000
|
||||
BoardOutlineThickness=0.100000000000
|
||||
ModuleOutlineThickness=0.150000000000
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[eeschema/libraries]
|
|
@ -1,189 +0,0 @@
|
|||
EESchema Schematic File Version 4
|
||||
EELAYER 30 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
$Comp
|
||||
L bluepill_breakouts:BluePill_STM32F103C U?
|
||||
U 1 1 64EDC21B
|
||||
P 3450 3300
|
||||
F 0 "U?" V 3429 1872 50 0000 R CNN
|
||||
F 1 "BluePill_STM32F103C" V 3520 1872 50 0000 R CNN
|
||||
F 2 "BluePill_breakouts:BluePill_STM32F103C" H 3500 1700 50 0001 C CNN
|
||||
F 3 "www.rogerclark.net" H 3450 1800 50 0001 C CNN
|
||||
1 3450 3300
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EDF5C5
|
||||
P 1250 5000
|
||||
F 0 "R?" H 1320 5046 50 0000 L CNN
|
||||
F 1 "20k" H 1320 4955 50 0000 L CNN
|
||||
F 2 "" V 1180 5000 50 0001 C CNN
|
||||
F 3 "~" H 1250 5000 50 0001 C CNN
|
||||
1 1250 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EDFDBD
|
||||
P 1650 5000
|
||||
F 0 "R?" H 1720 5046 50 0000 L CNN
|
||||
F 1 "20k" H 1720 4955 50 0000 L CNN
|
||||
F 2 "" V 1580 5000 50 0001 C CNN
|
||||
F 3 "~" H 1650 5000 50 0001 C CNN
|
||||
1 1650 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE0135
|
||||
P 2050 5000
|
||||
F 0 "R?" H 2120 5046 50 0000 L CNN
|
||||
F 1 "20k" H 2120 4955 50 0000 L CNN
|
||||
F 2 "" V 1980 5000 50 0001 C CNN
|
||||
F 3 "~" H 2050 5000 50 0001 C CNN
|
||||
1 2050 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE0320
|
||||
P 2450 5000
|
||||
F 0 "R?" H 2520 5046 50 0000 L CNN
|
||||
F 1 "20k" H 2520 4955 50 0000 L CNN
|
||||
F 2 "" V 2380 5000 50 0001 C CNN
|
||||
F 3 "~" H 2450 5000 50 0001 C CNN
|
||||
1 2450 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE05F5
|
||||
P 1450 5200
|
||||
F 0 "R?" V 1350 5200 50 0000 C CNN
|
||||
F 1 "10k" V 1250 5200 50 0000 C CNN
|
||||
F 2 "" V 1380 5200 50 0001 C CNN
|
||||
F 3 "~" H 1450 5200 50 0001 C CNN
|
||||
1 1450 5200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE138F
|
||||
P 1850 5200
|
||||
F 0 "R?" V 1750 5200 50 0000 C CNN
|
||||
F 1 "10k" V 1650 5200 50 0000 C CNN
|
||||
F 2 "" V 1780 5200 50 0001 C CNN
|
||||
F 3 "~" H 1850 5200 50 0001 C CNN
|
||||
1 1850 5200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE1BCF
|
||||
P 2250 5200
|
||||
F 0 "R?" V 2150 5200 50 0000 C CNN
|
||||
F 1 "10k" V 2050 5200 50 0000 C CNN
|
||||
F 2 "" V 2180 5200 50 0001 C CNN
|
||||
F 3 "~" H 2250 5200 50 0001 C CNN
|
||||
1 2250 5200
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE1F79
|
||||
P 1250 5400
|
||||
F 0 "R?" H 1050 5450 50 0000 L CNN
|
||||
F 1 "20k" H 1050 5350 50 0000 L CNN
|
||||
F 2 "" V 1180 5400 50 0001 C CNN
|
||||
F 3 "~" H 1250 5400 50 0001 C CNN
|
||||
1 1250 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 64EE4C4F
|
||||
P 1250 5550
|
||||
F 0 "#PWR?" H 1250 5300 50 0001 C CNN
|
||||
F 1 "GND" H 1255 5377 50 0000 C CNN
|
||||
F 2 "" H 1250 5550 50 0001 C CNN
|
||||
F 3 "" H 1250 5550 50 0001 C CNN
|
||||
1 1250 5550
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R?
|
||||
U 1 1 64EE5121
|
||||
P 2450 5400
|
||||
F 0 "R?" H 2520 5446 50 0000 L CNN
|
||||
F 1 "100k" H 2520 5355 50 0000 L CNN
|
||||
F 2 "" V 2380 5400 50 0001 C CNN
|
||||
F 3 "~" H 2450 5400 50 0001 C CNN
|
||||
1 2450 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R_POT RV?
|
||||
U 1 1 64EE57F8
|
||||
P 2450 5750
|
||||
F 0 "RV?" H 2380 5796 50 0000 R CNN
|
||||
F 1 "22k" H 2380 5705 50 0000 R CNN
|
||||
F 2 "" H 2450 5750 50 0001 C CNN
|
||||
F 3 "~" H 2450 5750 50 0001 C CNN
|
||||
1 2450 5750
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L power:GND #PWR?
|
||||
U 1 1 64EE63F8
|
||||
P 2450 5900
|
||||
F 0 "#PWR?" H 2450 5650 50 0001 C CNN
|
||||
F 1 "GND" H 2455 5727 50 0000 C CNN
|
||||
F 2 "" H 2450 5900 50 0001 C CNN
|
||||
F 3 "" H 2450 5900 50 0001 C CNN
|
||||
1 2450 5900
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
2450 5550 2450 5600
|
||||
Wire Wire Line
|
||||
2400 5200 2450 5200
|
||||
Wire Wire Line
|
||||
2450 5200 2450 5150
|
||||
Wire Wire Line
|
||||
2450 5200 2450 5250
|
||||
Connection ~ 2450 5200
|
||||
Wire Wire Line
|
||||
2000 5200 2050 5200
|
||||
Wire Wire Line
|
||||
1600 5200 1650 5200
|
||||
Wire Wire Line
|
||||
1650 5150 1650 5200
|
||||
Connection ~ 1650 5200
|
||||
Wire Wire Line
|
||||
1650 5200 1700 5200
|
||||
Wire Wire Line
|
||||
2050 5150 2050 5200
|
||||
Connection ~ 2050 5200
|
||||
Wire Wire Line
|
||||
2050 5200 2100 5200
|
||||
Wire Wire Line
|
||||
1250 5150 1250 5200
|
||||
Wire Wire Line
|
||||
1300 5200 1250 5200
|
||||
Connection ~ 1250 5200
|
||||
Wire Wire Line
|
||||
1250 5200 1250 5250
|
||||
$EndSCHEMATC
|
Plik binarny nie jest wyświetlany.
|
@ -1,35 +0,0 @@
|
|||
# This is an NUCLEO-F103RB board with a single STM32F103RBTx chip
|
||||
#
|
||||
# Generated by System Workbench for STM32
|
||||
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
set WORKAREASIZE 0x5000
|
||||
|
||||
transport select "hla_swd"
|
||||
|
||||
set CHIPNAME STM32F103RBTx
|
||||
set BOARDNAME NUCLEO-F103RB
|
||||
|
||||
# CHIPNAMES state
|
||||
set CHIPNAME_CPU0_ACTIVATED 1
|
||||
|
||||
# Enable debug when in low power modes
|
||||
set ENABLE_LOW_POWER 1
|
||||
|
||||
# Stop Watchdog counters when halt
|
||||
set STOP_WATCHDOG 1
|
||||
|
||||
# STlink Debug clock frequency
|
||||
set CLOCK_FREQ 4000
|
||||
|
||||
# use software system reset
|
||||
reset_config none
|
||||
set CONNECT_UNDER_RESET 0
|
||||
|
||||
# BCTM CPU variables
|
||||
|
||||
|
||||
|
||||
source [find target/stm32f1x.cfg]
|
|
@ -1,35 +0,0 @@
|
|||
# This is an NUCLEO-F103RB board with a single STM32F103RBTx chip
|
||||
#
|
||||
# Generated by System Workbench for STM32
|
||||
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
set WORKAREASIZE 0x5000
|
||||
|
||||
transport select "hla_swd"
|
||||
|
||||
set CHIPNAME STM32F103RBTx
|
||||
set BOARDNAME NUCLEO-F103RB
|
||||
|
||||
# CHIPNAMES state
|
||||
set CHIPNAME_CPU0_ACTIVATED 1
|
||||
|
||||
# Enable debug when in low power modes
|
||||
set ENABLE_LOW_POWER 1
|
||||
|
||||
# Stop Watchdog counters when halt
|
||||
set STOP_WATCHDOG 1
|
||||
|
||||
# STlink Debug clock frequency
|
||||
set CLOCK_FREQ 4000
|
||||
|
||||
# use software system reset
|
||||
reset_config none
|
||||
set CONNECT_UNDER_RESET 0
|
||||
|
||||
# BCTM CPU variables
|
||||
|
||||
|
||||
|
||||
source [find target/stm32f1x.cfg]
|
Ładowanie…
Reference in New Issue