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

app_pwm_channel_duty_set does not transition from 100% duty cycle to 0%, unless (0, 100)% duty cycle set previously.

Hi all,

Using SDK 17.0.2, on a Laird BL653.

I've been messing with creating variable PWM sequences and found an issue where a 100%->0% duty cycle transition does not occur unless previously (since last reset) there has been a (0,100)% duty cycle set. 

Take for example, the below.

#include "nrf.h"
#include "app_error.h"
#include "bsp.h"
#include "nrf_delay.h"
#include "app_pwm.h"

APP_PWM_INSTANCE(PWM1,1);

int main(void)
{
    ret_code_t err_code;
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(200L, 30, 31);

    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,NULL);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM1);
    
    while (app_pwm_channel_duty_set(&PWM1,   0,   0) == NRF_ERROR_BUSY);
    nrf_delay_ms(100);
    while (app_pwm_channel_duty_set(&PWM1,   0, 100) == NRF_ERROR_BUSY);
    nrf_delay_ms(100);
    while (app_pwm_channel_duty_set(&PWM1,   0,   0) == NRF_ERROR_BUSY);
}


If I scope the output of pin 30, I see a transition from 0% duty -> 100% duty cycle, but then no transition back to 0% duty cycle.

Alternatively, if I run the below:
#include "nrf.h"
#include "app_error.h"
#include "bsp.h"
#include "nrf_delay.h"
#include "app_pwm.h"

APP_PWM_INSTANCE(PWM1,1);

int main(void)
{
    ret_code_t err_code;
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(200L, 30, 31);

    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,NULL);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM1);
    
    while (app_pwm_channel_duty_set(&PWM1,   0,   5) == NRF_ERROR_BUSY);
    nrf_delay_ms(100);
    while (app_pwm_channel_duty_set(&PWM1,   0, 100) == NRF_ERROR_BUSY);
    nrf_delay_ms(100);
    while (app_pwm_channel_duty_set(&PWM1,   0,   0) == NRF_ERROR_BUSY);
}


and scope the output, I see a 0->5% transition, 5%->100% transition, then 100%->0% transition.

Not sure if I'm doing something wrong here, or if I've stumbled into an SDK bug.

sdk_config attached.
35608.sdk_config.h

Parents
  • Hi 

    I would not recommend using the app_pwm library on the nRF52 series. 

    This library was implemented back in the nRF51 days, since the nRF51 device didn't have a dedicated PWM controller, and uses a relatively complex combination of the TIMER, PPI and GPIOTE modules in order to realize PWM. 

    On the nRF52 side there are dedicated PWM controllers which allow you to implement PWM in a simpler fashion, like discussed in this case.

    It is not unthinkable that the problem you see is an issue with the driver. For the reasons mentioned above it has not been widely tested on the nRF52. 

    Best regards
    Torbjørn

Reply
  • Hi 

    I would not recommend using the app_pwm library on the nRF52 series. 

    This library was implemented back in the nRF51 days, since the nRF51 device didn't have a dedicated PWM controller, and uses a relatively complex combination of the TIMER, PPI and GPIOTE modules in order to realize PWM. 

    On the nRF52 side there are dedicated PWM controllers which allow you to implement PWM in a simpler fashion, like discussed in this case.

    It is not unthinkable that the problem you see is an issue with the driver. For the reasons mentioned above it has not been widely tested on the nRF52. 

    Best regards
    Torbjørn

Children
No Data
Related