| Аутор | SHA1 | Порука | Датум |
|---|---|---|---|
|
|
c134491907 | 标记了未完成项 | пре 1 месец |
|
|
d2ab7d6c0a | 修复了变频后计数不准的问题 | пре 1 месец |
|
|
f4a2216504 | 变频代码 | пре 1 месец |
|
|
a81228b629 | 加入EXT信号 | пре 1 месец |
|
|
ec2aa94775 | 修复EXT 硬件 pending 竞态 | пре 1 месец |
| @@ -1263,22 +1263,16 @@ | |||
| </group> | |||
| </group> | |||
| <group> | |||
| <name>PLSR</name> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Inc\plsr.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_internal.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_platform.h</name> | |||
| </file> | |||
| <name>Modbus</name> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_planner.h</name> | |||
| <name>$PROJ_DIR$\..\Modbus\Src\modbus_rtu_slave.c</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_planner.c</name> | |||
| <name>$PROJ_DIR$\..\Modbus\Inc\modbus_rtu_slave.h</name> | |||
| </file> | |||
| </group> | |||
| <group> | |||
| <name>PLSR</name> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr.c</name> | |||
| <configuration> | |||
| @@ -1289,6 +1283,248 @@ | |||
| <version>35</version> | |||
| <wantNonLocal>0</wantNonLocal> | |||
| <debug>1</debug> | |||
| <option> | |||
| <name>CCOptimizationNoSizeConstraints</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDefines</name> | |||
| <state>USE_HAL_DRIVER</state> | |||
| <state>STM32F407xx</state> | |||
| <state>PLSR_DEBUG_TIMING=1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocComments</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocLine</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCMnemonics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCMessages</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListAssFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListAssSource</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEnableRemarks</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagSuppress</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagRemark</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagWarning</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagError</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCObjPrefix</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCAllowList</name> | |||
| <version>1</version> | |||
| <state>11111110</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDebugInfo</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IEndianMode</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IProcessor</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IExtraOptionsCheck</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IExtraOptions</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCLangConformance</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCSignedPlainChar</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCRequirePrototypes</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagWarnAreErr</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCCompilerRuntimeInfo</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IFpuProcessor</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>OutputFile</name> | |||
| <state>$FILE_BNAME$.o</state> | |||
| </option> | |||
| <option> | |||
| <name>CCLibConfigHeader</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>PreInclude</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraOverride</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCIncludePath2</name> | |||
| <state>$PROJ_DIR$/../USB_DEVICE/App</state> | |||
| <state>$PROJ_DIR$/../USB_DEVICE/Target</state> | |||
| <state>$PROJ_DIR$/../Core/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy</state> | |||
| <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state> | |||
| <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32F4xx/Include</state> | |||
| <state>$PROJ_DIR$/../Drivers/CMSIS/Include</state> | |||
| <state>$PROJ_DIR$\..\Modbus\Inc</state> | |||
| <state>$PROJ_DIR$\..\PLSR\Inc</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\Config</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Source</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Ports\ARM-Cortex-M4\IAR</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU\ARM-Cortex-M4\IAR</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-LIB</state> | |||
| <state>$PROJ_DIR$\..\Modbus\Inc</state> | |||
| </option> | |||
| <option> | |||
| <name>CCStdIncCheck</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCCodeSection</name> | |||
| <state>.text</state> | |||
| </option> | |||
| <option> | |||
| <name>IProcessorMode2</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraRules98</name> | |||
| <version>0</version> | |||
| <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraRules04</name> | |||
| <version>0</version> | |||
| <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndRopi</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndRwpi</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndNoDynInit</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccLang</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCDialect</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccAllowVLA</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccStaticDestr</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCppInlineSemantics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCmsis</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccFloatSemantics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCNoLiteralPool</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncSource</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncOutput</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncOutputBom</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncInput</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccExceptions2</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccRTTI2</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCOptLevel</name> | |||
| <state>3</state> | |||
| @@ -1311,6 +1547,21 @@ | |||
| </settings> | |||
| </configuration> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Inc\plsr.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_internal.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_planner.c</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_planner.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_platform.h</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\PLSR\Src\plsr_platform_f407.c</name> | |||
| <configuration> | |||
| @@ -1321,6 +1572,248 @@ | |||
| <version>35</version> | |||
| <wantNonLocal>0</wantNonLocal> | |||
| <debug>1</debug> | |||
| <option> | |||
| <name>CCOptimizationNoSizeConstraints</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDefines</name> | |||
| <state>USE_HAL_DRIVER</state> | |||
| <state>STM32F407xx</state> | |||
| <state>PLSR_DEBUG_TIMING=1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocComments</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPreprocLine</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCMnemonics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListCMessages</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListAssFile</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCListAssSource</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEnableRemarks</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagSuppress</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagRemark</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagWarning</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagError</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCObjPrefix</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCAllowList</name> | |||
| <version>1</version> | |||
| <state>11111110</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDebugInfo</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IEndianMode</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IProcessor</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IExtraOptionsCheck</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IExtraOptions</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CCLangConformance</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCSignedPlainChar</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCRequirePrototypes</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCDiagWarnAreErr</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCCompilerRuntimeInfo</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IFpuProcessor</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>OutputFile</name> | |||
| <state>$FILE_BNAME$.o</state> | |||
| </option> | |||
| <option> | |||
| <name>CCLibConfigHeader</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>PreInclude</name> | |||
| <state></state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraOverride</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCIncludePath2</name> | |||
| <state>$PROJ_DIR$/../USB_DEVICE/App</state> | |||
| <state>$PROJ_DIR$/../USB_DEVICE/Target</state> | |||
| <state>$PROJ_DIR$/../Core/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy</state> | |||
| <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Core/Inc</state> | |||
| <state>$PROJ_DIR$/../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc</state> | |||
| <state>$PROJ_DIR$/../Drivers/CMSIS/Device/ST/STM32F4xx/Include</state> | |||
| <state>$PROJ_DIR$/../Drivers/CMSIS/Include</state> | |||
| <state>$PROJ_DIR$\..\Modbus\Inc</state> | |||
| <state>$PROJ_DIR$\..\PLSR\Inc</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\Config</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Source</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uCOS-II\Ports\ARM-Cortex-M4\IAR</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-CPU\ARM-Cortex-M4\IAR</state> | |||
| <state>$PROJ_DIR$\..\Middlewares\Third_Party\Micrium\uC-LIB</state> | |||
| <state>$PROJ_DIR$\..\Modbus\Inc</state> | |||
| </option> | |||
| <option> | |||
| <name>CCStdIncCheck</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCCodeSection</name> | |||
| <state>.text</state> | |||
| </option> | |||
| <option> | |||
| <name>IProcessorMode2</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraRules98</name> | |||
| <version>0</version> | |||
| <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state> | |||
| </option> | |||
| <option> | |||
| <name>CompilerMisraRules04</name> | |||
| <version>0</version> | |||
| <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndRopi</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndRwpi</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCPosIndNoDynInit</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccLang</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCDialect</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccAllowVLA</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccStaticDestr</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCppInlineSemantics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccCmsis</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>IccFloatSemantics</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCNoLiteralPool</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncSource</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncOutput</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncOutputBom</name> | |||
| <state>1</state> | |||
| </option> | |||
| <option> | |||
| <name>CCEncInput</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccExceptions2</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>IccRTTI2</name> | |||
| <state>0</state> | |||
| </option> | |||
| <option> | |||
| <name>CCOptLevel</name> | |||
| <state>3</state> | |||
| @@ -1344,13 +1837,4 @@ | |||
| </configuration> | |||
| </file> | |||
| </group> | |||
| <group> | |||
| <name>Modbus</name> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\Modbus\Src\modbus_rtu_slave.c</name> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\Modbus\Inc\modbus_rtu_slave.h</name> | |||
| </file> | |||
| </group> | |||
| </project> | |||
| @@ -111,8 +111,12 @@ def plot_show(path, fs, thresh, ymax, save_path=None): | |||
| fig, ax = plt.subplots(figsize=(15, 7)) | |||
| fig.subplots_adjust(bottom=0.10, top=0.92) | |||
| # 全脉冲散点 | |||
| ax.plot(t * 1000, freq, '.', ms=1.5, color='C0', alpha=0.5, zorder=1) | |||
| # 全脉冲散点:复用 artist,重绘时按可见范围抽稀(大文件流畅) | |||
| MAX_VISIBLE_POINTS = 5000 # 可见范围内最多绘制的点数,超过则等间隔抽稀 | |||
| (scatter,) = ax.plot([], [], '.', ms=1.5, color='C0', alpha=0.5, zorder=1) | |||
| tx_ms = t * 1000 | |||
| x_full = tx_ms | |||
| y_full = freq | |||
| ax.set_xlim(0.0, (t[-1] + hi_w[-1]) * 1000 * 1.02) | |||
| ax.set_ylim(0, ymax if ymax > 0 else freq.max() * 1.08) | |||
| ax.set_title("%s 时频曲线(%d 脉冲,活动时长 %.0f ms)" % ( | |||
| @@ -145,6 +149,19 @@ def plot_show(path, fs, thresh, ymax, save_path=None): | |||
| zorder=6, visible=False) | |||
| hover_last = {'idx': -1, 'visible': False} | |||
| # 可见范围内抽稀绘制散点(大文件性能优化) | |||
| def update_scatter(): | |||
| x0, x1 = ax.get_xlim() | |||
| mask = (x_full >= x0) & (x_full <= x1) | |||
| n_vis = int(np.count_nonzero(mask)) | |||
| if n_vis > MAX_VISIBLE_POINTS: | |||
| # 等间隔抽稀:取 n_vis 中的 MAX_VISIBLE_POINTS 个 | |||
| step = (n_vis + MAX_VISIBLE_POINTS - 1) // MAX_VISIBLE_POINTS | |||
| idx = np.flatnonzero(mask)[::step] | |||
| else: | |||
| idx = np.flatnonzero(mask) | |||
| scatter.set_data(x_full[idx], y_full[idx]) | |||
| def on_scroll(event): | |||
| if event.inaxes is not ax or event.xdata is None: | |||
| return | |||
| @@ -167,6 +184,7 @@ def plot_show(path, fs, thresh, ymax, save_path=None): | |||
| if n1 - n0 < 1e-6: | |||
| return | |||
| ax.set_xlim(n0, n1) | |||
| update_scatter() | |||
| fig.canvas.draw_idle() | |||
| def on_press(event): | |||
| @@ -187,28 +205,29 @@ def plot_show(path, fs, thresh, ymax, save_path=None): | |||
| dy = event.ydata - state['press_y'] | |||
| ax.set_xlim(x0 - dx, x1 - dx) | |||
| ax.set_ylim(y0 - dy, y1 - dy) | |||
| update_scatter() | |||
| fig.canvas.draw_idle() | |||
| return | |||
| # 悬停:找可见范围内距鼠标最近的脉冲点(屏幕像素距离 < 20px 才高亮) | |||
| x0, x1 = ax.get_xlim() | |||
| tx_ms = t * 1000 | |||
| mask = (tx_ms >= x0) & (tx_ms <= x1) | |||
| mask = (x_full >= x0) & (x_full <= x1) | |||
| if not np.any(mask): | |||
| hl_marker.set_visible(False) | |||
| hl_text.set_visible(False) | |||
| if hover_last['visible']: | |||
| hl_marker.set_visible(False) | |||
| hl_text.set_visible(False) | |||
| fig.canvas.draw_idle() | |||
| hover_last['visible'] = False | |||
| fig.canvas.draw_idle() | |||
| return | |||
| px, py = ax.transData.transform(np.column_stack([tx_ms[mask], freq[mask]])).T | |||
| px, py = ax.transData.transform(np.column_stack([x_full[mask], y_full[mask]])).T | |||
| dist = np.hypot(px - event.x, py - event.y) | |||
| k = int(np.argmin(dist)) | |||
| if dist[k] <= 20.0: | |||
| idx = int(np.flatnonzero(mask)[k]) | |||
| hl_marker.set_data([tx_ms[idx]], [freq[idx]]) | |||
| hl_marker.set_data([x_full[idx]], [y_full[idx]]) | |||
| hl_text.set_text("脉冲 #%d\nt = %.3f ms\nf = %.0f Hz" | |||
| % (idx + 1, tx_ms[idx], freq[idx])) | |||
| hl_text.set_position((tx_ms[idx] + (x1 - x0) * 0.01, | |||
| freq[idx] + (ax.get_ylim()[1] - ax.get_ylim()[0]) * 0.02)) | |||
| % (idx + 1, x_full[idx], y_full[idx])) | |||
| hl_text.set_position((x_full[idx] + (x1 - x0) * 0.01, | |||
| y_full[idx] + (ax.get_ylim()[1] - ax.get_ylim()[0]) * 0.02)) | |||
| hl_marker.set_visible(True) | |||
| hl_text.set_visible(True) | |||
| if hover_last['idx'] != idx or not hover_last['visible']: | |||
| @@ -229,8 +248,10 @@ def plot_show(path, fs, thresh, ymax, save_path=None): | |||
| if event.dblclick: | |||
| ax.set_xlim(0.0, (t[-1] + hi_w[-1]) * 1000 * 1.02) | |||
| ax.set_ylim(0, ymax if ymax > 0 else freq.max() * 1.08) | |||
| update_scatter() | |||
| fig.canvas.draw_idle() | |||
| update_scatter() | |||
| fig.canvas.mpl_connect('scroll_event', on_scroll) | |||
| fig.canvas.mpl_connect('button_press_event', on_press) | |||
| fig.canvas.mpl_connect('button_release_event', on_release) | |||
| @@ -93,7 +93,9 @@ uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput); | |||
| uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput, | |||
| uint32_t *activeFrequencyHz); | |||
| uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput, | |||
| uint64_t *observedPulses, | |||
| uint32_t *committedPulses, | |||
| uint64_t *committedTimeUs, | |||
| uint32_t *tailFrequencyHz, | |||
| uint8_t *startsNextSegment); | |||
| uint8_t PlsrPlatformFiniteProgress(uint8_t pulseOutput, | |||
| @@ -118,7 +120,7 @@ uint8_t PlsrExecTakeCountedRunIrq( | |||
| void PlsrExecCountedSegmentBoundaryIrq(uint8_t pulseOutput, | |||
| uint32_t completedPulses); | |||
| void PlsrExecCountedStreamFaultIrq(uint8_t pulseOutput); | |||
| /* EXTI callback: records only an armed WAIT input edge. */ | |||
| /* EXTI callback: records an armed WAIT or active EXT input edge. */ | |||
| void PlsrWaitInputExtiIrq(uint8_t inputSelection); | |||
| PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq( | |||
| uint8_t pulseOutput, | |||
| @@ -145,6 +147,9 @@ PLSR_PLATFORM_STOP_RESULT PlsrPlatformRequestStopLocked( | |||
| uint8_t PlsrPlatformQueueFinalArmFromIrq(uint8_t pulseOutput); | |||
| void PlsrPlatformStopPulse(uint8_t pulseOutput); | |||
| uint8_t PlsrPlatformReadInput(uint8_t inputSelection); | |||
| /* Called from the counted-boundary IRQ before the EXT capture context moves | |||
| to the next segment. Returns and clears a rising edge pending in EXTI. */ | |||
| uint8_t PlsrPlatformTakeInputExtiPending(uint8_t inputSelection); | |||
| uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload); | |||
| PLSR_PLATFORM_SERVICE_RESULT PlsrPlatformServicePersistence(void); | |||
| @@ -551,22 +551,35 @@ uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput, | |||
| } | |||
| uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput, | |||
| uint64_t *observedPulses, | |||
| uint32_t *committedPulses, | |||
| uint64_t *committedTimeUs, | |||
| uint32_t *tailFrequencyHz, | |||
| uint8_t *startsNextSegment) | |||
| { | |||
| uint32_t remaining; | |||
| uint32_t frequencyHz; | |||
| if ((pulseOutput > 3U) || (committedPulses == NULL) | |||
| || (tailFrequencyHz == NULL) || (startsNextSegment == NULL) | |||
| if ((pulseOutput > 3U) || (observedPulses == NULL) | |||
| || (committedPulses == NULL) | |||
| || (committedTimeUs == NULL) || (tailFrequencyHz == NULL) | |||
| || (startsNextSegment == NULL) | |||
| || (PlsrHostFiniteActive[pulseOutput] == 0U)) | |||
| { | |||
| return 0U; | |||
| } | |||
| remaining = PlsrHostFiniteTarget[pulseOutput] | |||
| - PlsrHostFiniteEmitted[pulseOutput]; | |||
| frequencyHz = PlsrHostFrequency[pulseOutput]; | |||
| if (frequencyHz == 0UL) | |||
| { | |||
| return 0U; | |||
| } | |||
| *observedPulses = PlsrHostObservedPulses[pulseOutput]; | |||
| *committedPulses = remaining; | |||
| *tailFrequencyHz = PlsrHostQueuedFrequency[pulseOutput]; | |||
| *committedTimeUs = ((uint64_t)remaining * 1000000ULL | |||
| + frequencyHz - 1UL) / frequencyHz; | |||
| *tailFrequencyHz = frequencyHz; | |||
| *startsNextSegment = 0U; | |||
| return 1U; | |||
| } | |||
| @@ -893,6 +906,12 @@ uint8_t PlsrPlatformReadInput(uint8_t inputSelection) | |||
| return (inputSelection <= 1U) ? PlsrHostInputs[inputSelection] : 0U; | |||
| } | |||
| uint8_t PlsrPlatformTakeInputExtiPending(uint8_t inputSelection) | |||
| { | |||
| (void)inputSelection; | |||
| return 0U; | |||
| } | |||
| uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload) | |||
| { | |||
| if ((payload == NULL) || (PlsrHostPersistentValid == 0U)) | |||
| @@ -1574,8 +1593,8 @@ static void PlsrFiniteArmNextStepPrepare(uint8_t pulseOutput, | |||
| TIM_TypeDef *counter, | |||
| uint32_t blockPulses); | |||
| static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput); | |||
| static void PlsrFiniteCutAtFallingEdge(uint8_t pulseOutput); | |||
| static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput); | |||
| static void PlsrFiniteCutAtIdleBoundary(uint8_t pulseOutput); | |||
| static void PlsrFiniteStopAtIdleBoundary(uint8_t pulseOutput); | |||
| static uint8_t PlsrFinalArmJobOutput(uint8_t pulseOutput) | |||
| { | |||
| @@ -2364,11 +2383,86 @@ static uint64_t PlsrCounterCurrentRaw(uint8_t pulseOutput) | |||
| } | |||
| } | |||
| /* Return completed pulses in the active PUL/DIR run. The one-pulse block | |||
| preload is an implementation detail, and a pending counter update means | |||
| the current block has completed even if its IRQ has not run yet. */ | |||
| static uint32_t PlsrFiniteCompletedPulsesSnapshot(uint8_t pulseOutput) | |||
| { | |||
| uint8_t index = PlsrCounterIndexByOutput[pulseOutput]; | |||
| TIM_TypeDef *counter; | |||
| uint32_t target; | |||
| uint32_t remainingBefore; | |||
| uint32_t remainingAfter; | |||
| uint32_t statusBefore; | |||
| uint32_t statusAfter; | |||
| uint32_t count; | |||
| uint32_t blockCount; | |||
| uint32_t completed; | |||
| if (index >= PLSR_COUNTER_COUNT) | |||
| { | |||
| return 0UL; | |||
| } | |||
| counter = PlsrCounters[index]; | |||
| for (;;) | |||
| { | |||
| remainingBefore = PlsrFiniteRemainingPulses[pulseOutput]; | |||
| statusBefore = counter->SR & TIM_SR_UIF; | |||
| count = (uint16_t)counter->CNT; | |||
| statusAfter = counter->SR & TIM_SR_UIF; | |||
| remainingAfter = PlsrFiniteRemainingPulses[pulseOutput]; | |||
| if ((remainingBefore == remainingAfter) | |||
| && (statusBefore == statusAfter)) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| target = PlsrFiniteTargetPulses[pulseOutput]; | |||
| if (remainingAfter > target) | |||
| { | |||
| return 0UL; | |||
| } | |||
| completed = target - remainingAfter; | |||
| if (statusAfter != 0UL) | |||
| { | |||
| blockCount = (remainingAfter > PLSR_COUNTER_BLOCK_PULSES) | |||
| ? PLSR_COUNTER_BLOCK_PULSES : remainingAfter; | |||
| if (count > (remainingAfter - blockCount)) | |||
| { | |||
| count = remainingAfter - blockCount; | |||
| } | |||
| blockCount += count; | |||
| } | |||
| else if (count >= PlsrFiniteCounterPreload[pulseOutput]) | |||
| { | |||
| blockCount = count - PlsrFiniteCounterPreload[pulseOutput]; | |||
| } | |||
| else | |||
| { | |||
| blockCount = 0UL; | |||
| } | |||
| if (blockCount > remainingAfter) | |||
| { | |||
| blockCount = remainingAfter; | |||
| } | |||
| return completed + blockCount; | |||
| } | |||
| static uint64_t PlsrCounterSnapshot(uint8_t pulseOutput) | |||
| { | |||
| uint64_t current = PlsrCounterCurrentRaw(pulseOutput); | |||
| uint64_t current; | |||
| uint64_t observed; | |||
| if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR) | |||
| && (PlsrFiniteActive[pulseOutput] != 0U)) | |||
| { | |||
| current = PlsrFiniteCompletedPulsesSnapshot(pulseOutput); | |||
| } | |||
| else | |||
| { | |||
| current = PlsrCounterCurrentRaw(pulseOutput); | |||
| } | |||
| if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB) | |||
| && (current > 0UL)) | |||
| { | |||
| @@ -3445,6 +3539,8 @@ uint8_t PlsrPlatformRetargetFiniteStop(uint8_t pulseOutput, | |||
| uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput) | |||
| { | |||
| TIM_TypeDef *timer; | |||
| uint32_t timerCompare; | |||
| uint32_t timerCount; | |||
| uint32_t criticalState; | |||
| if (pulseOutput > 3U) | |||
| @@ -3455,8 +3551,7 @@ uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput) | |||
| criticalState = PlsrPlatformEnterCritical(); | |||
| if ((PlsrFiniteActive[pulseOutput] == 0U) | |||
| || (PlsrFiniteStreamActive[pulseOutput] == 0U) | |||
| || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT) | |||
| || (PlsrFiniteRetargetPending[pulseOutput] != 0U)) | |||
| || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT)) | |||
| { | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 0U; | |||
| @@ -3467,17 +3562,35 @@ uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput) | |||
| return 1U; | |||
| } | |||
| /* Do not allow a run already staged by the producer to cross the cut. | |||
| CC1 reaches the physical pulse's falling edge, where the output is | |||
| idle and can be stopped without shortening the high or low width. */ | |||
| /* EXT supersedes an unpublished retarget and any producer-staged run. */ | |||
| PlsrFiniteRetargetPending[pulseOutput] = 0U; | |||
| PlsrFiniteRetargetDrainPulses[pulseOutput] = 0UL; | |||
| PlsrFiniteStreamNextValid[pulseOutput] = 0U; | |||
| PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U; | |||
| PlsrFiniteStreamSourceDone[pulseOutput] = 1U; | |||
| PlsrFiniteStreamSourceFault[pulseOutput] = 0U; | |||
| PlsrFiniteTailStopPending[pulseOutput] = 1U; | |||
| timer = PlsrTimerMap[pulseOutput].timer; | |||
| timer->DIER &= ~TIM_DIER_CC1IE; | |||
| timer->SR = ~TIM_SR_CC1IF; | |||
| timer->DIER |= TIM_DIER_CC1IE; | |||
| /* PWM1 is idle high before CCR1 and active low after CCR1. Freeze the | |||
| source briefly so the phase decision cannot turn a full pulse into a | |||
| short glitch. A low pulse is resumed and allowed to finish at update. */ | |||
| timer->CR1 &= ~TIM_CR1_CEN; | |||
| __DSB(); | |||
| timerCount = timer->CNT; | |||
| timerCompare = PlsrTimerActiveSetting[pulseOutput].compare; | |||
| if (timerCount < timerCompare) | |||
| { | |||
| PlsrFiniteCutAtIdleBoundary(pulseOutput); | |||
| } | |||
| else | |||
| { | |||
| timer->SR = ~TIM_SR_UIF; | |||
| timer->DIER |= TIM_DIER_UIE; | |||
| timer->CR1 |= TIM_CR1_CEN; | |||
| } | |||
| __DMB(); | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 1U; | |||
| @@ -3503,17 +3616,23 @@ uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput, | |||
| } | |||
| uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput, | |||
| uint64_t *observedPulses, | |||
| uint32_t *committedPulses, | |||
| uint64_t *committedTimeUs, | |||
| uint32_t *tailFrequencyHz, | |||
| uint8_t *startsNextSegment) | |||
| { | |||
| TIM_TypeDef *counter; | |||
| uint32_t criticalState; | |||
| uint32_t blockCount; | |||
| uint32_t completed; | |||
| uint32_t frequencyHz; | |||
| uint32_t remaining; | |||
| uint64_t timeUs; | |||
| uint64_t observed; | |||
| if ((pulseOutput > 3U) || (committedPulses == NULL) | |||
| || (tailFrequencyHz == NULL) || (startsNextSegment == NULL)) | |||
| if ((pulseOutput > 3U) || (observedPulses == NULL) | |||
| || (committedPulses == NULL) | |||
| || (committedTimeUs == NULL) || (tailFrequencyHz == NULL) | |||
| || (startsNextSegment == NULL)) | |||
| { | |||
| return 0U; | |||
| } | |||
| @@ -3525,23 +3644,31 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput, | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 0U; | |||
| } | |||
| counter = PlsrCounters[PlsrCounterIndexByOutput[pulseOutput]]; | |||
| blockCount = (uint16_t)counter->CNT; | |||
| if (blockCount >= PlsrFiniteCounterPreload[pulseOutput]) | |||
| completed = PlsrFiniteCompletedPulsesSnapshot(pulseOutput); | |||
| remaining = PlsrFiniteTargetPulses[pulseOutput]; | |||
| if (completed > remaining) | |||
| { | |||
| blockCount -= PlsrFiniteCounterPreload[pulseOutput]; | |||
| completed = remaining; | |||
| } | |||
| observed = PlsrObservedPulseBase[pulseOutput] + completed; | |||
| if (observed < PlsrObservedPulsePublished[pulseOutput]) | |||
| { | |||
| observed = PlsrObservedPulsePublished[pulseOutput]; | |||
| } | |||
| else | |||
| { | |||
| blockCount = 0UL; | |||
| PlsrObservedPulsePublished[pulseOutput] = observed; | |||
| } | |||
| remaining = PlsrFiniteRemainingPulses[pulseOutput]; | |||
| if (blockCount > remaining) | |||
| remaining -= completed; | |||
| frequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput]; | |||
| if (frequencyHz == 0UL) | |||
| { | |||
| blockCount = remaining; | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 0U; | |||
| } | |||
| remaining -= blockCount; | |||
| *tailFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput]; | |||
| timeUs = ((uint64_t)remaining * 1000000ULL | |||
| + frequencyHz - 1UL) / frequencyHz; | |||
| *tailFrequencyHz = frequencyHz; | |||
| *startsNextSegment = 0U; | |||
| if (PlsrFiniteStreamNextValid[pulseOutput] != 0U) | |||
| { | |||
| @@ -3549,12 +3676,22 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput, | |||
| remaining = (nextPulses > (0xFFFFFFFFUL - remaining)) | |||
| ? 0xFFFFFFFFUL : remaining + nextPulses; | |||
| *tailFrequencyHz = | |||
| frequencyHz = | |||
| PlsrFiniteStreamNextSetting[pulseOutput].actualFrequencyHz; | |||
| if (frequencyHz == 0UL) | |||
| { | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 0U; | |||
| } | |||
| timeUs += ((uint64_t)nextPulses * 1000000ULL | |||
| + frequencyHz - 1UL) / frequencyHz; | |||
| *tailFrequencyHz = frequencyHz; | |||
| *startsNextSegment = | |||
| PlsrFiniteStreamNextStartsSegment[pulseOutput]; | |||
| } | |||
| *observedPulses = observed; | |||
| *committedPulses = remaining; | |||
| *committedTimeUs = timeUs; | |||
| PlsrPlatformExitCritical(criticalState); | |||
| return 1U; | |||
| } | |||
| @@ -4284,6 +4421,30 @@ uint8_t PlsrPlatformReadInput(uint8_t inputSelection) | |||
| return 0U; | |||
| } | |||
| uint8_t PlsrPlatformTakeInputExtiPending(uint8_t inputSelection) | |||
| { | |||
| uint16_t pin; | |||
| if (inputSelection == 0U) | |||
| { | |||
| pin = GPIO_PIN_5; | |||
| } | |||
| else if (inputSelection == 1U) | |||
| { | |||
| pin = GPIO_PIN_12; | |||
| } | |||
| else | |||
| { | |||
| return 0U; | |||
| } | |||
| if (__HAL_GPIO_EXTI_GET_IT(pin) == RESET) | |||
| { | |||
| return 0U; | |||
| } | |||
| __HAL_GPIO_EXTI_CLEAR_IT(pin); | |||
| return 1U; | |||
| } | |||
| uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload) | |||
| { | |||
| PLSR_FLASH_SECTOR_SCAN scanA; | |||
| @@ -4659,7 +4820,8 @@ static void PlsrHandleTimerIrq(uint8_t pulseOutput) | |||
| && (PlsrFiniteTailStopPending[pulseOutput] != 0U)) | |||
| { | |||
| timer->SR = ~TIM_SR_CC1IF; | |||
| PlsrFiniteCutAtFallingEdge(pulseOutput); | |||
| timer->DIER &= ~TIM_DIER_CC1IE; | |||
| timer->DIER |= TIM_DIER_UIE; | |||
| goto irq_done; | |||
| } | |||
| #if PLSR_DEBUG_TIMING | |||
| @@ -4732,6 +4894,12 @@ static void PlsrHandleTimerIrq(uint8_t pulseOutput) | |||
| && ((timer->DIER & TIM_DIER_UIE) != 0UL)) | |||
| { | |||
| timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF); | |||
| if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR) | |||
| && (PlsrFiniteTailStopPending[pulseOutput] != 0U)) | |||
| { | |||
| PlsrFiniteCutAtIdleBoundary(pulseOutput); | |||
| goto irq_done; | |||
| } | |||
| if ((PlsrFiniteActive[pulseOutput] != 0U) | |||
| && (PlsrFiniteFrequencyPending[pulseOutput] != 0U)) | |||
| { | |||
| @@ -5180,13 +5348,9 @@ static void PlsrFiniteCounterIrq(uint8_t pulseOutput, | |||
| counter->CR1 &= ~TIM_CR1_CEN; | |||
| counter->SMCR &= ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0); | |||
| /* | |||
| * An OC rising edge is the terminal pulse's falling edge because the | |||
| * output stage is active low. The target-count update IRQ therefore is | |||
| * already the safe idle boundary: stop here before CCR1 can start an | |||
| * extra terminal pulse. | |||
| */ | |||
| PlsrFiniteStopAtFallingEdge(pulseOutput); | |||
| /* The counter update is sourced by the PWM edge that returns the MCU pin | |||
| high. The terminal pulse is complete and the output is safely idle. */ | |||
| PlsrFiniteStopAtIdleBoundary(pulseOutput); | |||
| } | |||
| static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput) | |||
| @@ -5235,32 +5399,16 @@ static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput) | |||
| PlsrCounterBegin(pulseOutput); | |||
| } | |||
| static void PlsrFiniteCutAtFallingEdge(uint8_t pulseOutput) | |||
| static void PlsrFiniteCutAtIdleBoundary(uint8_t pulseOutput) | |||
| { | |||
| uint8_t counterIndex = PlsrCounterIndexByOutput[pulseOutput]; | |||
| TIM_TypeDef *counter = PlsrCounters[counterIndex]; | |||
| uint32_t blockCount; | |||
| uint32_t completed; | |||
| /* Freeze the external counter at the same falling edge that makes the | |||
| pulse output idle, then convert the partial current run into the | |||
| terminal run consumed by PlsrPlatformTakeFiniteCompletion(). */ | |||
| /* The source output is high here. Freeze the slave counter and publish | |||
| exactly the completed full pulses from the partial current run. */ | |||
| PlsrCounterSuspend(pulseOutput); | |||
| blockCount = (uint16_t)counter->CNT; | |||
| if (blockCount >= PlsrFiniteCounterPreload[pulseOutput]) | |||
| { | |||
| blockCount -= PlsrFiniteCounterPreload[pulseOutput]; | |||
| } | |||
| else | |||
| { | |||
| blockCount = 0UL; | |||
| } | |||
| completed = PlsrFiniteTargetPulses[pulseOutput] | |||
| - PlsrFiniteRemainingPulses[pulseOutput] + blockCount; | |||
| if (completed > PlsrFiniteTargetPulses[pulseOutput]) | |||
| { | |||
| completed = PlsrFiniteTargetPulses[pulseOutput]; | |||
| } | |||
| completed = PlsrFiniteCompletedPulsesSnapshot(pulseOutput); | |||
| PlsrObservedPulseBase[pulseOutput] += completed; | |||
| PlsrObservedPulsePublished[pulseOutput] = | |||
| @@ -5276,10 +5424,10 @@ static void PlsrFiniteCutAtFallingEdge(uint8_t pulseOutput) | |||
| PlsrCounterOverflowPulses[counterIndex] = 0UL; | |||
| counter->CNT = 0UL; | |||
| counter->SR = 0UL; | |||
| PlsrFiniteStopAtFallingEdge(pulseOutput); | |||
| PlsrFiniteStopAtIdleBoundary(pulseOutput); | |||
| } | |||
| static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput) | |||
| static void PlsrFiniteStopAtIdleBoundary(uint8_t pulseOutput) | |||
| { | |||
| TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer; | |||