This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

low_power_pwm duty_cycle seems buggy.

I've been trying to figure out the duty cycle on the low_power_pwm and it looks pretty buggy to me (SDK v13.0.0). Some of the low_power_pwm code considers duty cycle to be a scale, and some of it considers it to be an absolute value.

The documentation for low_power_pwm_duty_set() says:

[in]	duty_cycle	New high pulse width. 0 means that the pin is always off. 255 means that it is always on.

So it seems to be a scale value. But then if you call low_power_pwm_duty_set with a value higher than the period, it returns an error. In the pwm_timeout_handler there is this code:

   if (duty_cycle == p_pwm_instance->period)    // Process duty cycle 100%
    {
        pin_on(p_pwm_instance);
        p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
    }
    else if (duty_cycle == 0)   // Process duty cycle 0%
    {
        pin_off(p_pwm_instance);
        p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
    }
    else // Process any other duty cycle than 0 or 100%
    {
        pin_on(p_pwm_instance);
        p_pwm_instance->timeout_ticks = ((duty_cycle * p_pwm_instance->period)>>8) + 
                            APP_TIMER_MIN_TIMEOUT_TICKS;
    }

This code considers a duty cycle equal to the period to be 100% on. But in the normal case, it calculates the on time as (duty_cycle * period) / 256 which uses duty_cycle as a scale value.

So for a period of 100 ticks and a duty cycle of 100, the pin will be on for 105 ticks. For a period of 100 ticks and a duty cycle of 99, the pin will be on for 43 ticks and then off for 5 ticks.

Also, I know it's documented as not accurate, but it seems like just always adding the 5 tick fudge factor to make sure it's above the minimum instead of comparing it and making sure it's above the minimum adds some needless inaccuracy.

Parents Reply Children
No Data
Related