LPC54606 SCTimer change period problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC54606 SCTimer change period problem

809 Views
luimarma
Contributor III

Hello,

I am working with SCTimer to generate a PWM signal.

This signal I need to change the period and duty cycle frequently.

I have created a function in fs_timer library using the code of " SCTIMER_UpdatePwmDutycycle".

The function works when stepping in debug mode step by step, but when runing normal it stops generating the pulses. I am missing abything needed to change the match register and do not break anything?

The following is the function code used:

void SCTIMER_UpdatePwmPeriod(SCT_Type *base, sctimer_out_t output,
        sctimer_pwm_mode_t mode,
        uint32_t pwmFreq_Hz,
		uint8_t dutyCyclePercent,
        uint32_t srcClock_Hz,
        uint32_t event)
{
    assert(0U != srcClock_Hz);
    assert(0U != pwmFreq_Hz);
    assert((uint32_t)output < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS);
    assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK));
    status_t status = kStatus_Fail;
    status_t status2;
    uint32_t period, pulsePeriod = 0;
    uint32_t sctClock    = srcClock_Hz / (((base->CTRL & SCT_CTRL_PRE_L_MASK) >> SCT_CTRL_PRE_L_SHIFT) + 1U);
    uint32_t periodEvent = 0, pulseEvent = 0;
    uint32_t reg;
    uint32_t periodMatchReg, pulseMatchReg;
    bool isHighTrue      = (0U != (base->OUT[output].CLR & (1UL << (event + 1U))));

   if ((s_currentEvent + 2U) <= (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS)
     {
       /* Calculate PWM period match value */
       if (mode == kSCTIMER_EdgeAlignedPwm)
          {
            period = (sctClock / pwmFreq_Hz) - 1U;
          }
          else
          {
            period = sctClock / (pwmFreq_Hz * 2U);
          }

          /* For 100% dutycyle, make pulse period greater than period so the event will never occur */
          if (dutyCyclePercent >= 100U)
          {
             pulsePeriod = period + 2U;
             /* Set the initial output level base on output mode */
             if (isHighTrue)
             {
                 base->OUTPUT |= (1UL << (uint32_t)output);
             }
             else
             {
                 base->OUTPUT &= ~(1UL << (uint32_t)output);
             }
          }
          else
          {
             pulsePeriod = (uint32_t)(((uint64_t)period * dutyCyclePercent) / 100U);
          }

          /* Retrieve the match register number for the PWM period */
          periodMatchReg = base->EV[event].CTRL & SCT_EV_CTRL_MATCHSEL_MASK;

          /* Retrieve the match register number for the PWM pulse period */
          pulseMatchReg = base->EV[event + 1U].CTRL & SCT_EV_CTRL_MATCHSEL_MASK;
          /* Stop the counter before updating match register */
          SCTIMER_StopTimer(base, (uint32_t)kSCTIMER_Counter_U);
          /* Update dutycycle */
          base->MATCH[periodMatchReg]    = period;
          base->MATCHREL[periodMatchReg] = period;
          base->MATCH[pulseMatchReg]    = pulsePeriod;
          base->MATCHREL[pulseMatchReg] = pulsePeriod;

          /* Restart the counter */
          SCTIMER_StartTimer(base, (uint32_t)kSCTIMER_Counter_U);
      }
}

 

Labels (2)
0 Kudos
Reply
1 Reply

786 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello @luimarma 

How about low the change frequency, it means delay the time before change period.

 

BR

Alice

0 Kudos
Reply