RT1176 PWM startup failed

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

RT1176 PWM startup failed

182 次查看
liu626
Contributor I

I am using PWM + fault + QTimer to implement motor pulse control, but the PWM3 submodule 0 PWM_A channel occasionally fails to start, where after the first high level it remains constant and subsequent pulses do not appear.After the inspection, it was found that the "run" bit of the pwm was not correctly set. Even though repeated startup operations were added in the program later, this anomaly still occurred.

liu626_0-1782287927569.png

 

0 项奖励
回复
2 回复数

111 次查看
Pablo_Ramos
NXP Employee
NXP Employee

Hi @liu626,

Are you using a custom board or an EVK? If you are using the EVK, did you make any rework to it?

Could you share the configuration you are using for PWM3?

Are you using an example as a reference? If so, which one?

If you try to replicate the issue using a project with only PWM3, does the problem persist?

Does this only happen with PWM3 submodule 0 PWM_A channel? Has this occurred on other PWM modules or submodules?

Is there any other task or interrupt that manipulates PWM3 registers and could affect or overwrite the run bit?

Best Regards,
Pablo

0 项奖励
回复

92 次查看
liu626
Contributor I
hi,I used a custom circuit board. I didn't refer to any examples. This was a problem that was discovered during the official development of the project. I configured six PWM channels for pulse control. Only this channel had problems, while no such issue occurred on the other sub-modules. I checked and found that only this channel was using the PWM3 module. No other interfering factors were detected. Below is my configuration.
static axis_ctrl_t g_axes[AXIS_NUM] =
{
{
.id = AXIS_X1, .name = "X1",
.pwmBase = PWM1, .pwmModule = kPWM_Module_0, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR3, .lowCh = kQTMR_Channel_2, .highCh = kQTMR_Channel_3,
.tmrInputsrc=kQTMR_ClockCounter2InputPin, .cascadePcs = 6U,
.faultNum = 0U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},

{
.id = AXIS_X2, .name = "X2",
.pwmBase = PWM2, .pwmModule = kPWM_Module_0, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR2, .lowCh = kQTMR_Channel_0, .highCh = kQTMR_Channel_1,
.tmrInputsrc=kQTMR_ClockCounter0InputPin, .cascadePcs = 4U,
.faultNum = 0U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},

{
.id = AXIS_Y, .name = "Y",
.pwmBase = PWM3, .pwmModule = kPWM_Module_0, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR3, .lowCh = kQTMR_Channel_0, .highCh = kQTMR_Channel_1,
.tmrInputsrc=kQTMR_ClockCounter0InputPin, .cascadePcs = 4U,
.faultNum = 0U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},

{
.id = AXIS_Z, .name = "Z",
.pwmBase = PWM4, .pwmModule = kPWM_Module_0, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR1, .lowCh = kQTMR_Channel_0, .highCh = kQTMR_Channel_1,
.tmrInputsrc=kQTMR_ClockCounter0InputPin, .cascadePcs = 4U,
.faultNum = 0U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},

{
.id = AXIS_EX1, .name = "EX1",
.pwmBase = PWM1, .pwmModule = kPWM_Module_1, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR1, .lowCh = kQTMR_Channel_2, .highCh = kQTMR_Channel_3,
.tmrInputsrc=kQTMR_ClockCounter2InputPin, .cascadePcs = 6U,
.faultNum = 1U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},

{
.id = AXIS_EX2, .name = "EX2",
.pwmBase = PWM2, .pwmModule = kPWM_Module_1, .pwmChannel = kPWM_PwmA,
.tmrBase = TMR2, .lowCh = kQTMR_Channel_2, .highCh = kQTMR_Channel_3,
.tmrInputsrc=kQTMR_ClockCounter2InputPin, .cascadePcs = 6U,
.faultNum = 1U, .hwExactSupported = true, .outTrigMask = kPWM_ValueRegisterMask_3,
},
};static void APP_Init_PWM_QTMR(void)
{
pwm_config_t pwmConfig;
pwm_fault_param_t faultConfig;
qtmr_config_t qtmrConfig;

PWM_GetDefaultConfig(&pwmConfig);
pwmConfig.pairOperation = kPWM_Independent;
pwmConfig.reloadLogic = kPWM_ReloadImmediate;

PWM_FaultDefaultConfig(&faultConfig);
faultConfig.faultLevel = true;

faultConfig.enableCombinationalPath = false;
faultConfig.faultClearingMode = kPWM_ManualSafety;
faultConfig.recoverMode = kPWM_NoRecovery;

QTMR_GetDefaultConfig(&qtmrConfig);
CLOCK_EnableClock(kCLOCK_Qtimer1);
CLOCK_EnableClock(kCLOCK_Qtimer2);
CLOCK_EnableClock(kCLOCK_Qtimer3);

PWM_StopTimer(PWM1, 0x0FU); PWM_StopTimer(PWM2, 0x0FU);
PWM_StopTimer(PWM3, 0x0FU); PWM_StopTimer(PWM4, 0x0FU);
pwm_fault_input_filter_param_t faultFilter;
faultFilter.faultFilterPeriod = 255U;
faultFilter.faultFilterCount = 7U;
faultFilter.faultGlitchStretch = false;

/* 记录每个 PWM 实例上已配置的 fault channel,避免重复设置 */
uint16_t pwm1FaultDone = 0U, pwm2FaultDone = 0U, pwm3FaultDone = 0U, pwm4FaultDone = 0U;

for (uint8_t i = 0U; i < AXIS_NUM; i++)
{
axis_ctrl_t *ax = &g_axes[i];
PWM_Init(ax->pwmBase, ax->pwmModule, &pwmConfig);
PWM_SetupFaults(ax->pwmBase, (pwm_fault_input_t)ax->faultNum, &faultConfig);

/* 故障滤波(每个 PWM 实例的每个 fault channel 只设一次) */
{
uint16_t *faultDone;
if (ax->pwmBase == PWM1) faultDone = &pwm1FaultDone;
else if (ax->pwmBase == PWM2) faultDone = &pwm2FaultDone;
else if (ax->pwmBase == PWM3) faultDone = &pwm3FaultDone;
else faultDone = &pwm4FaultDone;

uint16_t faultBit = (uint16_t)(1U << ax->faultNum);
if ((*faultDone & faultBit) == 0U)
{
PWM_SetupFaultInputFilterExt(ax->pwmBase,
(pwm_fault_channels_t)ax->faultNum,
&faultFilter);
*faultDone |= faultBit;
}
}

/* Fault 时输出低电平 */
ax->pwmBase->SM[ax->pwmModule].OCTRL &= ~(PWM_OCTRL_PWMAFS_MASK | PWM_OCTRL_PWMBFS_MASK);

APP_PWM_Unmap_Selected_Fault(ax);
APP_PWM_ClearFault_Safe(ax);

ax->pwmBase->SM[ax->pwmModule].INIT = 0U;
ax->pwmBase->SM[ax->pwmModule].VAL0 = 0U;
ax->pwmBase->SM[ax->pwmModule].VAL1 = 1U;
ax->pwmBase->SM[ax->pwmModule].VAL2 = 0U;
ax->pwmBase->SM[ax->pwmModule].VAL3 = 0U;
ax->pwmBase->SM[ax->pwmModule].VAL4 = 0U;
ax->pwmBase->SM[ax->pwmModule].VAL5 = 0U;
ax->pwmBase->SM[ax->pwmModule].TCTRL = PWM_TCTRL_OUT_TRIG_EN(ax->outTrigMask);
APP_PWM_Disable_Output(ax);

if (ax->hwExactSupported)
{
qtmrConfig.primarySource = ax->tmrInputSrc;
QTMR_Init(ax->tmrBase, ax->lowCh, &qtmrConfig);
QTMR_Init(ax->tmrBase, ax->highCh, &qtmrConfig);

ax->tmrBase->CHANNEL[ax->lowCh].CTRL = TMR_CTRL_CM(kQTMR_PriSrcRiseEdge)
| TMR_CTRL_PCS(ax->tmrInputSrc);
ax->tmrBase->CHANNEL[ax->highCh].CTRL = TMR_CTRL_CM(kQTMR_CascadeCount)
| TMR_CTRL_PCS(ax->cascadePcs);

APP_QTMR_Disable_Low_OFLAG_Output(ax);
QTMR_DisableInterrupts(ax->tmrBase, ax->lowCh, 0xFFU);
QTMR_DisableInterrupts(ax->tmrBase, ax->highCh, 0xFFU);
QTMR_ClearStatusFlags(ax->tmrBase, ax->lowCh, 0xFFU);
QTMR_ClearStatusFlags(ax->tmrBase, ax->highCh, 0xFFU);
}

ax->phase = kAxisIdle;

ax->armed = false;
ax->running = false;
ax->done = true;
#if HARD_PWM_STATE_GUARD_ENABLE
APP_StateGuard_Reset(ax);
#endif
}

/* 使能 QTMR 中断 */
NVIC_SetPriority(TMR1_IRQn, 2U);
NVIC_SetPriority(TMR2_IRQn, 2U);
NVIC_SetPriority(TMR3_IRQn, 2U);
EnableIRQ(TMR1_IRQn);
EnableIRQ(TMR2_IRQn);
EnableIRQ(TMR3_IRQn);
}static bool APP_PWM_Config_Pulse(axis_ctrl_t *axis,
uint32_t highCnt400M,
uint32_t lowCnt400M)
{
pwm_clock_prescale_t prescale;
uint16_t periodTicks;
uint32_t totalCnt400M = highCnt400M + lowCnt400M;

if ((axis == NULL) || (totalCnt400M == 0U)) return false;
if (!APP_PWM_SelectPrescaler_FromPeriodCnt400M(totalCnt400M, &prescale, &periodTicks))
return false;

uint32_t highTicks32 = (uint32_t)(((uint64_t)periodTicks * (uint64_t)highCnt400M +
((uint64_t)totalCnt400M / 2ULL)) /
(uint64_t)totalCnt400M);
if (highTicks32 == 0U) highTicks32 = 1U;
if (highTicks32 >= periodTicks) highTicks32 = (uint32_t)periodTicks - 1U;

uint32_t riseTicks32 = 0U;
uint32_t fallTicks32 = highTicks32;

#if HARD_PWM_LOW_START_PHASE_ENABLE
uint32_t lowTicks32 = (uint32_t)periodTicks - highTicks32;
if (lowTicks32 >= (2U * HARD_PWM_LOW_START_PHASE_MIN_TICKS))
{
uint32_t desiredLeadCnt400M = highCnt400M;
uint32_t minLeadCnt400M = (uint32_t)HARD_PWM_LOW_START_PHASE_MIN_US * 400U;
if (desiredLeadCnt400M < minLeadCnt400M) desiredLeadCnt400M = minLeadCnt400M;

uint32_t desiredLeadTicks32 = (uint32_t)(((uint64_t)periodTicks * (uint64_t)desiredLeadCnt400M +
((uint64_t)totalCnt400M / 2ULL)) /
(uint64_t)totalCnt400M);
if (desiredLeadTicks32 < HARD_PWM_LOW_START_PHASE_MIN_TICKS)
desiredLeadTicks32 = HARD_PWM_LOW_START_PHASE_MIN_TICKS;

uint32_t maxRiseByHalfTicks32 = lowTicks32 / 2U;
uint32_t postGuardTicks32 = (uint32_t)(((uint64_t)periodTicks *
(uint64_t)(HARD_PWM_VAL3_POST_LOW_GUARD_US * 400U) +
((uint64_t)totalCnt400M / 2ULL)) /
(uint64_t)totalCnt400M);
if (postGuardTicks32 < HARD_PWM_VAL3_POST_LOW_GUARD_MIN_TICKS)
postGuardTicks32 = HARD_PWM_VAL3_POST_LOW_GUARD_MIN_TICKS;
uint32_t maxRiseByPostGuardTicks32 = (lowTicks32 > postGuardTicks32) ?
(lowTicks32 - postGuardTicks32) : 0U;

uint32_t selectedRiseTicks32;
if (maxRiseByHalfTicks32 >= desiredLeadTicks32)
{
selectedRiseTicks32 = desiredLeadTicks32;
if (selectedRiseTicks32 > maxRiseByHalfTicks32)
selectedRiseTicks32 = maxRiseByHalfTicks32;
}
else if (maxRiseByPostGuardTicks32 >= desiredLeadTicks32)
{
selectedRiseTicks32 = desiredLeadTicks32;
if (selectedRiseTicks32 > maxRiseByPostGuardTicks32)
selectedRiseTicks32 = maxRiseByPostGuardTicks32;
}
else
{
selectedRiseTicks32 = maxRiseByPostGuardTicks32;
}

if (selectedRiseTicks32 >= HARD_PWM_LOW_START_PHASE_MIN_TICKS)
{
riseTicks32 = selectedRiseTicks32;
fallTicks32 = riseTicks32 + highTicks32;
}
}
#endif

if (fallTicks32 >= (uint32_t)periodTicks) fallTicks32 = (uint32_t)periodTicks - 1U;
uint16_t riseTicks = (uint16_t)riseTicks32;
uint16_t fallTicks = (uint16_t)fallTicks32;
PWM_SetPwmLdok(axis->pwmBase, APP_PwmModuleMask(axis), false);
uint16_t ctrl = axis->pwmBase->SM[axis->pwmModule].CTRL;
ctrl &= (uint16_t)(~PWM_CTRL_PRSC_MASK);
ctrl |= PWM_CTRL_PRSC(prescale);
axis->pwmBase->SM[axis->pwmModule].CTRL = ctrl;

axis->pwmBase->SM[axis->pwmModule].INIT = 0U;
axis->pwmBase->SM[axis->pwmModule].VAL0 = 0U;
axis->pwmBase->SM[axis->pwmModule].VAL1 = (uint16_t)(periodTicks - 1U);
if (axis->pwmChannel == kPWM_PwmA) {
axis->pwmBase->SM[axis->pwmModule].VAL2 = riseTicks;
axis->pwmBase->SM[axis->pwmModule].VAL3 = fallTicks;
} else if (axis->pwmChannel == kPWM_PwmB) {
axis->pwmBase->SM[axis->pwmModule].VAL4 = riseTicks;
axis->pwmBase->SM[axis->pwmModule].VAL5 = fallTicks;
}
axis->pwmBase->SM[axis->pwmModule].TCTRL = PWM_TCTRL_OUT_TRIG_EN(axis->outTrigMask);

PWM_SetPwmLdok(axis->pwmBase, APP_PwmModuleMask(axis), true);
PWM_SetPwmLdok(axis->pwmBase, APP_PwmModuleMask(axis), true);
axis->pwmConfigValid = true;
axis->cachedHighCnt400M = highCnt400M;
axis->cachedLowCnt400M = lowCnt400M;
return true;
}
0 项奖励
回复
%3CLINGO-SUB%20id%3D%22lingo-sub-2385575%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3ERT1176%20PWM%E5%90%AF%E5%8A%A8%E5%A4%B1%E8%B4%A5%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2385575%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E6%88%91%E4%BD%BF%E7%94%A8PWM%2B%E6%95%85%E9%9A%9C%2BQTimer%E6%9D%A5%E5%AE%9E%E7%8E%B0%E7%94%B5%E6%9C%BA%E8%84%89%E5%86%B2%E6%8E%A7%E5%88%B6%EF%BC%8C%E4%BD%86PWM3%E5%AD%90%E6%A8%A1%E5%9D%970%E7%9A%84PWM_A%E9%80%9A%E9%81%93%E5%81%B6%E5%B0%94%E6%97%A0%E6%B3%95%E5%90%AF%E5%8A%A8%EF%BC%8C%E5%9C%A8%E7%AC%AC%E4%B8%80%E4%B8%AA%E9%AB%98%E7%94%B5%E5%B9%B3%E4%B9%8B%E5%90%8E%E5%B0%B1%E4%B8%80%E7%9B%B4%E4%BF%9D%E6%8C%81%E9%AB%98%E7%94%B5%E5%B9%B3%EF%BC%8C%E5%90%8E%E7%BB%AD%E8%84%89%E5%86%B2%E4%B8%8D%E5%86%8D%E5%87%BA%E7%8E%B0%E3%80%82%E6%A3%80%E6%9F%A5%E5%90%8E%E5%8F%91%E7%8E%B0%EF%BC%8CPWM%E7%9A%84%E2%80%9C%E8%BF%90%E8%A1%8C%E2%80%9D%E4%BD%8D%E6%B2%A1%E6%9C%89%E6%AD%A3%E7%A1%AE%E8%AE%BE%E7%BD%AE%E3%80%82%E5%8D%B3%E4%BD%BF%E5%90%8E%E6%9D%A5%E5%9C%A8%E7%A8%8B%E5%BA%8F%E4%B8%AD%E6%B7%BB%E5%8A%A0%E4%BA%86%E9%87%8D%E5%A4%8D%E5%90%AF%E5%8A%A8%E6%93%8D%E4%BD%9C%EF%BC%8C%E8%BF%99%E7%A7%8D%E5%BC%82%E5%B8%B8%E6%83%85%E5%86%B5%E4%BB%8D%E7%84%B6%E5%8F%91%E7%94%9F%E3%80%82%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22liu626_0-1782287927569.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22liu626_0-1782287927569.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22liu626_0-1782287927569.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22liu626_0-1782287927569.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F389985i82C105A58467F67F%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22liu626_0-1782287927569.png%22%20alt%3D%22liu626_0-1782287927569.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2386554%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20RT1176%20PWM%20startup%20failed%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2386554%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%E4%BD%A0%E5%A5%BD%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F264017%22%20target%3D%22_blank%22%3E%40liu626%3C%2FA%3E%20%EF%BC%8C%3C%2FP%3E%0A%3CP%3E%E4%BD%A0%E7%94%A8%E7%9A%84%E6%98%AF%E5%AE%9A%E5%88%B6%E6%9D%BF%E8%BF%98%E6%98%AFEVK%E6%9D%BF%EF%BC%9F%E5%A6%82%E6%9E%9C%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AF%20EVK%EF%BC%8C%E4%BD%A0%E5%AF%B9%E5%AE%83%E8%BF%9B%E8%A1%8C%E8%BF%87%E4%BB%BB%E4%BD%95%E4%BF%AE%E6%94%B9%E5%90%97%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E8%83%BD%E5%90%A6%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%8B%E6%82%A8%E4%BD%BF%E7%94%A8%E7%9A%84PWM3%E9%85%8D%E7%BD%AE%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E6%82%A8%E6%98%AF%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%E4%BD%9C%E4%B8%BA%E5%8F%82%E8%80%83%E5%90%97%EF%BC%9F%E5%A6%82%E6%9E%9C%E6%98%AF%EF%BC%8C%E6%98%AF%E5%93%AA%E4%B8%80%E4%B8%AA%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E5%A6%82%E6%9E%9C%E5%B0%9D%E8%AF%95%E4%BD%BF%E7%94%A8%E4%BB%85%E5%8C%85%E5%90%AB%20PWM3%20%E7%9A%84%E9%A1%B9%E7%9B%AE%E6%9D%A5%E9%87%8D%E7%8E%B0%E8%AF%A5%E9%97%AE%E9%A2%98%EF%BC%8C%E9%97%AE%E9%A2%98%E6%98%AF%E5%90%A6%E4%BB%8D%E7%84%B6%E5%AD%98%E5%9C%A8%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5%E6%98%AF%E5%90%A6%E5%8F%AA%E5%8F%91%E7%94%9F%E5%9C%A8%20PWM3%20%E5%AD%90%E6%A8%A1%E5%9D%97%200%20PWM_A%20%E9%80%9A%E9%81%93%E4%B8%8A%EF%BC%9F%E5%85%B6%E4%BB%96PWM%E6%A8%A1%E5%9D%97%E6%88%96%E5%AD%90%E6%A8%A1%E5%9D%97%E6%98%AF%E5%90%A6%E4%B9%9F%E5%87%BA%E7%8E%B0%E8%BF%87%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E6%98%AF%E5%90%A6%E8%BF%98%E6%9C%89%E5%85%B6%E4%BB%96%E4%BB%BB%E5%8A%A1%E6%88%96%E4%B8%AD%E6%96%AD%E4%BC%9A%E6%93%8D%E4%BD%9C%20PWM3%20%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%8C%E4%BB%8E%E8%80%8C%E5%BD%B1%E5%93%8D%E6%88%96%E8%A6%86%E7%9B%96%E8%BF%90%E8%A1%8C%E4%BD%8D%EF%BC%9F%3C%2FP%3E%0A%3CP%3E%E6%AD%A4%E8%87%B4%EF%BC%8C%3CBR%20%2F%3E%E5%B7%B4%E5%8B%83%E7%BD%97%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2386633%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20RT1176%20PWM%20startup%20failed%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2386633%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%E6%82%A8%E5%A5%BD%EF%BC%8C%E6%88%91%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AF%E5%AE%9A%E5%88%B6%E7%94%B5%E8%B7%AF%E6%9D%BF%E3%80%82%E6%88%91%E6%B2%A1%E6%9C%89%E4%B8%BE%E4%BB%BB%E4%BD%95%E4%BE%8B%E5%AD%90%E3%80%82%E8%BF%99%E6%98%AF%E5%9C%A8%E9%A1%B9%E7%9B%AE%E6%AD%A3%E5%BC%8F%E5%BC%80%E5%8F%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E5%8F%91%E7%8E%B0%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%E6%88%91%E9%85%8D%E7%BD%AE%E4%BA%86%E5%85%AD%E4%B8%AAPWM%E9%80%9A%E9%81%93%E7%94%A8%E4%BA%8E%E8%84%89%E5%86%B2%E6%8E%A7%E5%88%B6%E3%80%82%E5%8F%AA%E6%9C%89%E8%BF%99%E4%B8%AA%E9%80%9A%E9%81%93%E5%87%BA%E7%8E%B0%E4%BA%86%E9%97%AE%E9%A2%98%EF%BC%8C%E5%85%B6%E4%BB%96%E5%AD%90%E6%A8%A1%E5%9D%97%E9%83%BD%E6%B2%A1%E6%9C%89%E5%87%BA%E7%8E%B0%E6%AD%A4%E7%B1%BB%E9%97%AE%E9%A2%98%E3%80%82%E6%88%91%E6%A3%80%E6%9F%A5%E5%90%8E%E5%8F%91%E7%8E%B0%EF%BC%8C%E5%8F%AA%E6%9C%89%E8%BF%99%E4%B8%AA%E9%80%9A%E9%81%93%E4%BD%BF%E7%94%A8%E4%BA%86%20PWM3%20%E6%A8%A1%E5%9D%97%E3%80%82%E6%9C%AA%E6%A3%80%E6%B5%8B%E5%88%B0%E5%85%B6%E4%BB%96%E5%B9%B2%E6%89%B0%E5%9B%A0%E7%B4%A0%E3%80%82%E4%BB%A5%E4%B8%8B%E6%98%AF%E6%88%91%E7%9A%84%E9%85%8D%E7%BD%AE%E3%80%82%3CBR%20%2F%3E%E9%9D%99%E6%80%81%20axis_ctrl_t%20g_axes%5BAXIS_NUM%5D%20%3D%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_X1%EF%BC%8C.name%3D%20%22X1%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM1%EF%BC%8C.pwmModule%3D%20kPWM_Module_0%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR3%EF%BC%8C.lowCh%3D%20kQTMR_Channel_2%EF%BC%8C.highCh%3D%20kQTMR_Channel_3%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter2InputPin%2C.cascadePcs%3D%206U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%200U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_X2%EF%BC%8C.name%3D%20%22X2%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM2%EF%BC%8C.pwmModule%3D%20kPWM_Module_0%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR2%EF%BC%8C.lowCh%3D%20kQTMR_Channel_0%2C%20.highCh%3D%20kQTMR_Channel_1%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter0InputPin%2C.cascadePcs%3D%204U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%200U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_Y%EF%BC%8C.name%3D%20%22Y%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM3%EF%BC%8C.pwmModule%3D%20kPWM_Module_0%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR3%EF%BC%8C.lowCh%3D%20kQTMR_Channel_0%2C%20.highCh%3D%20kQTMR_Channel_1%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter0InputPin%2C.cascadePcs%3D%204U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%200U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_Z%EF%BC%8C.name%3D%20%22Z%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM4%EF%BC%8C.pwmModule%3D%20kPWM_Module_0%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR1%EF%BC%8C.lowCh%3D%20kQTMR_Channel_0%2C%20.highCh%3D%20kQTMR_Channel_1%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter0InputPin%2C.cascadePcs%3D%204U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%200U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_EX1%EF%BC%8C.name%3D%20%22EX1%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM1%EF%BC%8C.pwmModule%3D%20kPWM_Module_1%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR1%EF%BC%8C.lowCh%3D%20kQTMR_Channel_2%EF%BC%8C.highCh%3D%20kQTMR_Channel_3%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter2InputPin%2C.cascadePcs%3D%206U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%201U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20%E3%80%82ID%3D%20AXIS_EX2%EF%BC%8C.name%3D%20%22EX2%22%2C%3CBR%20%2F%3E%20.pwmBase%3D%20PWM2%EF%BC%8C.pwmModule%3D%20kPWM_Module_1%EF%BC%8C.pwmChannel%3D%20kPWM_PwmA%EF%BC%8C%3CBR%20%2F%3E%20.tmrBase%3D%20TMR2%EF%BC%8C.lowCh%3D%20kQTMR_Channel_2%EF%BC%8C.highCh%3D%20kQTMR_Channel_3%EF%BC%8C%3CBR%20%2F%3E%20.tmrInputsrc%3DkQTMR_ClockCounter2InputPin%2C.cascadePcs%3D%206U%EF%BC%8C%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E7%BC%96%E5%8F%B7%3D%201U%EF%BC%8C.hwExactSupported%3D%20true%EF%BC%8C.outTrigMask%3D%20kPWM_ValueRegisterMask_3%EF%BC%8C%3CBR%20%2F%3E%20%7D%2C%3CBR%20%2F%3E%20%7D%3Bstatic%20void%20APP_Init_PWM_QTMR(void)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20pwm_config_t%20pwmConfig%3B%3CBR%20%2F%3E%20pwm_fault_param_t%20faultConfig%3B%3CBR%20%2F%3E%20qtmr_config_t%20qtmrConfig%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20PWM_GetDefaultConfig(%26amp%3BpwmConfig)%3B%3CBR%20%2F%3E%20pwmConfig.pairOperation%3D%20kPWM_Independent%3B%3CBR%20%2F%3E%20pwmConfig.reloadLogic%20%3D%20kPWM_ReloadImmediate%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20PWM_FaultDefaultConfig(%26amp%3BfaultConfig)%3B%3CBR%20%2F%3E%20faultConfig.faultLevel%20%3D%20true%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20faultConfig.enableCombinationPath%3D%20false%EF%BC%9B%3CBR%20%2F%3E%20faultConfig.faultClearingMode%3D%20kPWM_%E6%89%8B%E5%8A%A8%E5%AE%89%E5%85%A8%EF%BC%9B%3CBR%20%2F%3E%20faultConfig.recoverMode%20%3D%20kPWM_NoRecovery%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20QTMR_GetDefaultConfig(%26amp%3BqtmrConfig)%3B%3CBR%20%2F%3E%20CLOCK_EnableClock(kCLOCK_Qtimer1)%3B%3CBR%20%2F%3E%20CLOCK_EnableClock(kCLOCK_Qtimer2)%3B%3CBR%20%2F%3E%20CLOCK_EnableClock(kCLOCK_Qtimer3)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20PWM_StopTimer(PWM1%2C%200x0FU)%3B%20PWM_StopTimer(PWM2%2C%200x0FU)%3B%3CBR%20%2F%3E%20PWM_StopTimer(PWM3%2C%200x0FU)%3B%20PWM_StopTimer(PWM4%2C%200x0FU)%3B%3CBR%20%2F%3E%20pwm_fault_input_filter_param_t%20faultFilter%3B%3CBR%20%2F%3E%E6%95%85%E9%9A%9C%E8%BF%87%E6%BB%A4%E5%99%A8.%E6%95%85%E9%9A%9C%E8%BF%87%E6%BB%A4%E5%99%A8%E5%91%A8%E6%9C%9F%3D%20255U%EF%BC%9B%3CBR%20%2F%3E%20faultFilter.faultFilterCount%3D%207U%EF%BC%9B%3CBR%20%2F%3E%20faultFilter.faultGlitchStretch%3D%20false%EF%BC%9B%3CBR%20%2F%3E%3CBR%20%2F%3E%20%2F*%20%E8%AE%B0%E5%BD%95%E6%AF%8F%E4%B8%AAPWM%E5%AE%9E%E4%BE%8B%E4%B8%8A%E5%B7%B2%E9%85%8D%E7%BD%AE%E7%9A%84%E6%95%85%E9%9A%9C%E9%80%9A%E9%81%93%EF%BC%8C%E9%81%BF%E5%85%8D%E9%87%8D%E5%A4%8D%E8%AE%BE%E7%BD%AE%20*%2F%3CBR%20%2F%3E%20uint16_t%20pwm1FaultDone%20%3D%200U%2C%20pwm2FaultDone%20%3D%200U%2C%20pwm3FaultDone%20%3D%200U%2C%20pwm4FaultDone%20%3D%200U%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20for%20(uint8_t%20i%20%3D%200U%3B%20i%20%26lt%3B%20AXIS_NUM%3B%20i%2B%2B)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20axis_ctrl_t%20*ax%20%3D%20%26amp%3Bg_axes%5Bi%5D%3B%3CBR%20%2F%3E%20PWM_Init(ax-%26gt%3BpwmBase%2C%20ax-%26gt%3BpwmModule%2C%20%26amp%3BpwmConfig)%3B%3CBR%20%2F%3E%20PWM_SetupFaults(ax-%26gt%3BpwmBase%2C%20(pwm_fault_input_t)ax-%26gt%3BfaultNum%2C%20%26amp%3BfaultConfig)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20%2F*%20%E6%95%85%E9%9A%9C%E6%8F%90%E7%A4%BA%EF%BC%88%E6%AF%8F%E4%B8%AA%20PWM%20%E5%AE%9E%E4%BE%8B%E7%9A%84%E6%AF%8F%E4%B8%AA%E6%95%85%E9%9A%9C%E9%80%9A%E9%81%93%E5%8F%AA%E8%AE%BE%E7%BD%AE%E4%B8%80%E6%AC%A1%EF%BC%89%20*%2F%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20uint16_t%20*faultDone%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(ax-%26gt%3BpwmBase%20%3D%3D%20PWM1)%20faultDone%20%3D%20%26amp%3Bpwm1FaultDone%3B%3CBR%20%2F%3E%E5%90%A6%E5%88%99%E5%A6%82%E6%9E%9C%20(ax-%26gt%3BpwmBase%20%3D%3D%20PWM2)%20faultDone%20%3D%20%26amp%3Bpwm2FaultDone%3B%3CBR%20%2F%3E%E5%90%A6%E5%88%99%E5%A6%82%E6%9E%9C%20(ax-%26gt%3BpwmBase%20%3D%3D%20PWM3)%20faultDone%20%3D%20%26amp%3Bpwm3FaultDone%3B%3CBR%20%2F%3E%E5%90%A6%E5%88%99%20faultDone%20%3D%20%26amp%3Bpwm4FaultDone%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint16_t%20faultBit%20%3D%20(uint16_t)(1U%20%26lt%3B%26lt%3B%20ax-%26gt%3BfaultNum)%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20((*faultDone%20%26amp%3B%20faultBit)%20%3D%3D%200U)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20PWM_SetupFaultInputFilterExt(ax-%26gt%3BpwmBase%2C%3CBR%20%2F%3E%20(pwm_fault_channels_t)ax-%26gt%3BfaultNum%2C%3CBR%20%2F%3E%20%26amp%3BfaultFilter)%3B%3CBR%20%2F%3E%20*faultDone%20%7C%3D%20faultBit%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%20%2F*%20%E6%95%85%E9%9A%9C%E6%97%B6%E8%BE%93%E5%87%BA%E4%BD%8E%E7%94%B5%E5%B9%B3%20*%2F%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.OCTRL%20%26amp%3B%3D%20~(PWM_OCTRL_PWMAFS_MASK%20%7C%20PWM_OCTRL_PWMBFS_MASK)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20APP_PWM_Unmap_Selected_Fault(ax)%3B%3CBR%20%2F%3E%20APP_PWM_ClearFault_Safe(ax)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.INIT%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL0%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL1%20%3D%201U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL2%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL3%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL4%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.VAL5%20%3D%200U%3B%3CBR%20%2F%3E%20ax-%26gt%3BpwmBase-%26gt%3BSM%5Bax-%26gt%3BpwmModule%5D.TCTRL%20%3D%20PWM_TCTRL_OUT_TRIG_EN(ax-%26gt%3BoutTrigMask)%3B%3CBR%20%2F%3E%20APP_PWM_Disable_Output(ax)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(ax-%26gt%3BhwExactSupported)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20qtmrConfig.primarySource%3D%20ax-%26gt%3BtmrInputSrc%3B%3CBR%20%2F%3E%20QTMR_Init(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BlowCh%2C%20%26amp%3BqtmrConfig)%3B%3CBR%20%2F%3E%20QTMR_Init(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BhighCh%2C%20%26amp%3BqtmrConfig)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20ax-%26gt%3BtmrBase-%26gt%3BCHANNEL%5Bax-%26gt%3BlowCh%5D.CTRL%20%3D%20TMR_CTRL_CM(kQTMR_PriSrcRiseEdge)%3CBR%20%2F%3E%20%7C%20TMR_CTRL_PCS(ax-%26gt%3BtmrInputSrc)%3B%3CBR%20%2F%3E%20ax-%26gt%3BtmrBase-%26gt%3BCHANNEL%5Bax-%26gt%3BhighCh%5D.CTRL%20%3D%20TMR_CTRL_CM(kQTMR_CascadeCount)%3CBR%20%2F%3E%20%7C%20TMR_CTRL_PCS(ax-%26gt%3BcascadePcs)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20APP_QTMR_Disable_Low_OFLAG_Output(ax)%3B%3CBR%20%2F%3E%20QTMR_DisableInterrupts(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BlowCh%2C%200xFFU)%3B%3CBR%20%2F%3E%20QTMR_DisableInterrupts(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BhighCh%2C%200xFFU)%3B%3CBR%20%2F%3E%20QTMR_ClearStatusFlags(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BlowCh%2C%200xFFU)%3B%3CBR%20%2F%3E%20QTMR_ClearStatusFlags(ax-%26gt%3BtmrBase%2C%20ax-%26gt%3BhighCh%2C%200xFFU)%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%20ax-%26gt%3Bphase%20%3D%20kAxisIdle%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20ax-%26gt%3Barmed%20%3D%20false%3B%3CBR%20%2F%3E%20ax-%26gt%3Brunning%20%3D%20false%3B%3CBR%20%2F%3E%20ax-%26gt%3Bdone%20%3D%20true%3B%3CBR%20%2F%3E%20%23if%20HARD_PWM_STATE_GUARD_ENABLE%3CBR%20%2F%3E%20APP_StateGuard_Reset(ax)%3B%3CBR%20%2F%3E%20%23endif%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%20%2F*%20%E4%BD%BF%E8%83%BD%20QTMR%20%E4%B8%AD%E6%96%AD%20*%2F%3CBR%20%2F%3E%20NVIC_SetPriority(TMR1_IRQn%2C%202U)%3B%3CBR%20%2F%3E%20NVIC_SetPriority(TMR2_IRQn%2C%202U)%3B%3CBR%20%2F%3E%20NVIC_SetPriority(TMR3_IRQn%2C%202U)%3B%3CBR%20%2F%3E%E5%90%AF%E7%94%A8IRQ(TMR1_IRQn)%3B%3CBR%20%2F%3E%E5%90%AF%E7%94%A8IRQ(TMR2_IRQn)%3B%3CBR%20%2F%3E%E5%90%AF%E7%94%A8IRQ(TMR3_IRQn)%3B%3CBR%20%2F%3E%20%7Dstatic%20bool%20APP_PWM_Config_Pulse(axis_ctrl_t%20*axis%2C%3CBR%20%2F%3E%20uint32_t%20highCnt400M%EF%BC%8C%3CBR%20%2F%3E%20uint32_t%20lowCnt400M)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20pwm_clock_prescale_t%20%E9%A2%84%E5%88%86%E9%A2%91%EF%BC%9B%3CBR%20%2F%3E%20uint16_t%20periodTicks%3B%3CBR%20%2F%3E%20uint32_t%20totalCnt400M%20%3D%20highCnt400M%20%2B%20lowCnt400M%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20((axis%20%3D%3D%20NULL)%20%7C%7C%20(totalCnt400M%20%3D%3D%200U))%20%E8%BF%94%E5%9B%9E%20false%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(!APP_PWM_SelectPrescaler_FromPeriodCnt400M(totalCnt400M%2C%20%26amp%3Bprescale%2C%20%26amp%3BperiodTicks))%3CBR%20%2F%3E%E8%BF%94%E5%9B%9E%20false%EF%BC%9B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint32_t%20highTicks32%20%3D%20(uint32_t)(((uint64_t)periodTicks%20*%20(uint64_t)highCnt400M%20%2B%3CBR%20%2F%3E%20((uint64_t)totalCnt400M%20%2F%202ULL))%20%2F%3CBR%20%2F%3E%20%EF%BC%88uint64_t%EF%BC%89totalCnt400M%EF%BC%89%EF%BC%9B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(highTicks32%20%3D%3D%200U)%20highTicks32%20%3D%201U%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(highTicks32%20%26gt%3B%3D%20periodTicks)%20highTicks32%20%3D%20(uint32_t)periodTicks%20-%201U%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint32_t%20riseTicks32%20%3D%200U%3B%3CBR%20%2F%3E%20uint32_t%20fallTicks32%20%3D%20highTicks32%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20%23if%20HARD_PWM_LOW_START_PHASE_ENABLE%3CBR%20%2F%3E%20uint32_t%20lowTicks32%20%3D%20(uint32_t)periodTicks%20-%20highTicks32%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(lowTicks32%20%26gt%3B%3D%20(2U%20*%20HARD_PWM_LOW_START_PHASE_MIN_TICKS))%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20uint32_t%20desiredLeadCnt400M%20%3D%20highCnt400M%3B%3CBR%20%2F%3E%20uint32_t%20minLeadCnt400M%20%3D%20(uint32_t)HARD_PWM_LOW_START_PHASE_MIN_US%20*%20400U%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(desiredLeadCnt400M%20%26lt%3B%20minLeadCnt400M)%20desiredLeadCnt400M%20%3D%20minLeadCnt400M%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint32_t%20desiredLeadTicks32%20%3D%20(uint32_t)(((uint64_t)periodTicks%20*%20(uint64_t)desiredLeadCnt400M%20%2B%3CBR%20%2F%3E%20((uint64_t)totalCnt400M%20%2F%202ULL))%20%2F%3CBR%20%2F%3E%20%EF%BC%88uint64_t%EF%BC%89totalCnt400M%EF%BC%89%EF%BC%9B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(desiredLeadTicks32%20%26lt%3B%20HARD_PWM_LOW_START_PHASE_MIN_TICKS)%3CBR%20%2F%3E%20desiredLeadTicks32%20%3D%20HARD_PWM_LOW_START_PHASE_MIN_TICKS%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint32_t%20maxRiseByHalfTicks32%20%3D%20lowTicks32%20%2F%202U%3B%3CBR%20%2F%3E%20uint32_t%20postGuardTicks32%20%3D%20(uint32_t)(((uint64_t)periodTicks%20*%3CBR%20%2F%3E%20(uint64_t)(HARD_PWM_VAL3_POST_LOW_GUARD_US%20*%20400U)%20%2B%3CBR%20%2F%3E%20((uint64_t)totalCnt400M%20%2F%202ULL))%20%2F%3CBR%20%2F%3E%20%EF%BC%88uint64_t%EF%BC%89totalCnt400M%EF%BC%89%EF%BC%9B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(postGuardTicks32%20%26lt%3B%20HARD_PWM_VAL3_POST_LOW_GUARD_MIN_TICKS)%3CBR%20%2F%3E%20postGuardTicks32%20%3D%20HARD_PWM_VAL3_POST_LOW_GUARD_MIN_TICKS%3B%3CBR%20%2F%3E%20uint32_t%20maxRiseByPostGuardTicks32%20%3D%20(lowTicks32%20%26gt%3B%20postGuardTicks32)%20%3F%3CBR%20%2F%3E%20%EF%BC%88lowTicks32%20-%20postGuardTicks32%EF%BC%89%EF%BC%9A0U%EF%BC%9B%3CBR%20%2F%3E%3CBR%20%2F%3E%20uint32_t%20selectedRiseTicks32%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(maxRiseByHalfTicks32%20%26gt%3B%3D%20desiredLeadTicks32)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20selectedRiseTicks32%20%3D%20desiredLeadTicks32%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(selectedRiseTicks32%20%26gt%3B%20maxRiseByHalfTicks32)%3CBR%20%2F%3E%20selectedRiseTicks32%20%3D%20maxRiseByHalfTicks32%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%E5%90%A6%E5%88%99%E5%A6%82%E6%9E%9C%EF%BC%88maxRiseByPostGuardTicks32%20%26gt%3B%3D%20desiredLeadTicks32%EF%BC%89%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20selectedRiseTicks32%20%3D%20desiredLeadTicks32%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(selectedRiseTicks32%20%26gt%3B%20maxRiseByPostGuardTicks32)%3CBR%20%2F%3E%20selectedRiseTicks32%20%3D%20maxRiseByPostGuardTicks32%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%E5%88%AB%E7%9A%84%3CBR%20%2F%3E%7B%3CBR%20%2F%3E%20selectedRiseTicks32%20%3D%20maxRiseByPostGuardTicks32%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(selectedRiseTicks32%20%26gt%3B%3D%20HARD_PWM_LOW_START_PHASE_MIN_TICKS)%3CBR%20%2F%3E%20%7B%3CBR%20%2F%3E%20riseTicks32%20%3D%20selectedRiseTicks32%3B%3CBR%20%2F%3E%20fallTicks32%20%3D%20riseTicks32%20%2B%20highTicks32%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%20%23endif%3CBR%20%2F%3E%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(fallTicks32%20%26gt%3B%3D%20(uint32_t)periodTicks)%20fallTicks32%20%3D%20(uint32_t)periodTicks%20-%201U%3B%3CBR%20%2F%3E%20uint16_t%20riseTicks%20%3D%20(uint16_t)riseTicks32%3B%3CBR%20%2F%3E%20uint16_t%20fallTicks%20%3D%20(uint16_t)fallTicks32%3B%3CBR%20%2F%3E%20PWM_SetPwmLdok(axis-%26gt%3BpwmBase%2C%20APP_PwmModuleMask(axis)%2C%20false)%3B%3CBR%20%2F%3E%20uint16_t%20ctrl%20%3D%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.CTRL%3B%3CBR%20%2F%3E%20ctrl%20%26amp%3B%3D%20(uint16_t)(~PWM_CTRL_PRSC_MASK)%3B%3CBR%20%2F%3E%20ctrl%20%7C%3D%20PWM_CTRL_PRSC%EF%BC%88%E9%A2%84%E5%88%86%E9%A2%91%EF%BC%89%EF%BC%9B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.CTRL%20%3D%20ctrl%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.INIT%20%3D%200U%3B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.VAL0%20%3D%200U%3B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.VAL1%20%3D%20(uint16_t)(periodTicks%20-%201U)%3B%3CBR%20%2F%3E%E5%A6%82%E6%9E%9C%20(axis-%26gt%3BpwmChannel%20%3D%3D%20kPWM_PwmA)%20%7B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.VAL2%20%3D%20riseTicks%3B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.VAL3%20%3D%20fallTicks%3B%3CBR%20%2F%3E%20%7D%20%E5%90%A6%E5%88%99%E5%A6%82%E6%9E%9C%20(axis-%26gt%3BpwmChannel%20%3D%3D%20kPWM_PwmB)%20%7B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D%E3%80%82VAL4%20%3D%20riseTicks%3B%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.VAL5%20%3D%20fallTicks%3B%3CBR%20%2F%3E%20%7D%3CBR%20%2F%3E%20axis-%26gt%3BpwmBase-%26gt%3BSM%5Baxis-%26gt%3BpwmModule%5D.TCTRL%20%3D%20PWM_TCTRL_OUT_TRIG_EN(axis-%26gt%3BoutTrigMask)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%20PWM_SetPwmLdok(axis-%26gt%3BpwmBase%2C%20APP_PwmModuleMask(axis)%2C%20true)%3B%3CBR%20%2F%3E%20PWM_SetPwmLdok(axis-%26gt%3BpwmBase%2C%20APP_PwmModuleMask(axis)%2C%20true)%3B%3CBR%20%2F%3E%20axis-%26gt%3BpwmConfigValid%20%3D%20true%3B%3CBR%20%2F%3E%20axis-%26gt%3BcachedHighCnt400M%20%3D%20highCnt400M%3B%3CBR%20%2F%3E%20axis-%26gt%3BcachedLowCnt400M%20%3D%20lowCnt400M%3B%3CBR%20%2F%3E%E8%BF%94%E5%9B%9E%20true%EF%BC%9B%3CBR%20%2F%3E%20%7D%3C%2FLINGO-BODY%3E