This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM48L952: PWM Waveform doesn't match the duty cycle and frequency we set

Part Number: RM48L952
Other Parts Discussed in Thread: HALCOGEN

Hi,

  We are using your RM48L952zwt platform with the HalCoGen 4.03.00 generated drivers and based on a sample function we got from TI a few years ago. Our hardware teeam dicovered that the waveform does not match the transmitted settings. i.e., screen shot pwm duty cycle = 37 and freq = 100, the waveform generated has a duty cycle of 28.6

or if pwm duty cycle set to 38 - 40 and freq to 100, the waveform has a duty cycle of 42.9:

/**
* void setPWMOutput(PWM_CHANNEL_TYPE pwm, CPU_INT32U hertz , CPU_FP32 percentage)
*
* @brief sets pwm value for specific channel
*
* @param[in]    pwm                pwm channel
* @param[in]    hertz                frequency to use
* @param[in]    percentage    floating point value
*
* @return      void
*/
void setPWMOutput(PWM_CHANNEL_TYPE pwm, CPU_INT32U hertz , CPU_FP32 percentage)
{
    CPU_FP64 period = 0;
    CPU_FP32 dutyCycle = 0;
    CPU_FP32 polarityReversedDutyCycle = 0;
    HW_PWM_CONTROL_SET_FN setFn = 0;

    //duty cycle can not be more than 100%
    if( percentage > MAX_DUTY_CYCLE_PERCENTAGE_VALUE)
        percentage = MAX_DUTY_CYCLE_PERCENTAGE_VALUE;

    period = (1/((CPU_FP64)hertz)) * 1000 * 1000;
    dutyCycle = percentage;

    //TODO clean up magic numbers
    if(g_pwmPinPolarity[pwm] == POLARITY_ACTIVE_LOW)
        polarityReversedDutyCycle = 100 - dutyCycle;
    else
        polarityReversedDutyCycle = dutyCycle;

    if(pwm < PWM_LAST)
        setFn = g_pwmPinSetFn[pwm];

    if(setFn != 0)
    {
        //can not set pwm straight to 0, must first set it to an intermediate value then 0
        if(polarityReversedDutyCycle == 0)
        {
            if(g_pwmPinPolarity[pwm] == POLARITY_ACTIVE_LOW)
                (*setFn)(g_pwmPinMapping[pwm], period, (100.0 - ONE_PERCENT_DUTY_CYCLE));
            else
                (*setFn)(g_pwmPinMapping[pwm], period, ONE_PERCENT_DUTY_CYCLE);

            OSTimeDlyHMSM(0, 0, 0, PWM_TIME_DELAY);
        }

        (*setFn)(g_pwmPinMapping[pwm], period, polarityReversedDutyCycle);

        dataStruct_setPWMFrequency(pwm, hertz);
        dataStruct_setPWMDutyCycle(pwm, percentage);
    }
}

Thank you.

  • Hello Tammy,

    Please clear hr_lr bit to use HR delay. This will improve the accuracy of the duty cycle.

    For example, VCLK=100MHz,

                          hr=1 --> HRP = 10ns

                          lr=32 --> LRP= lr*HRP = 320ns

                          Frequency = 100Khz, p=10us --> CNT_Max=31.25-1=30  --> real period = 31*320=9920ns --> frequency=100.8Khz

                          If duty cycle is 37%, the ECMP data field is: 31*(0.63)*128=2500=b1001_1100_0100  --> HR delay will be b10001=17 HR clock cycle = 17/32 LRP

    If the hr_lr is SET, don't use HR delay

                         the duty will be about 19/31= 61.3%  (or 38.7%)  where 19=b10011

    If the hr_lr is cleared, use the HR delay:

                         the duty will be about (19+17/32)/31= 63%  (or 37%) 

    Where are your settings in your HET code?