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

sometimes PWM signal is reversed .

Hi Nordics!

I am using app_pwm.c file in SDK 8.1, and when I use it with softdevice(advertising or data transfer event), sometimes pwm signal is reversed.

I guess, reversed signal's reason is the BLE interrupt. Because this problem is not occurred, when I don't use softdevice ( advertising or data transfer event)

And I need your advice for overcome this problem.

These are my development environment.


SDK 8.1

SD 8.0

nRF51822 AA G0

custom board

Timer1- 2channels

Timer2-1 channel.

3 PWM channels - Red led, Green led, Blue led.


first, I used app_pwm library. (100Hz )

/* */

static void pwm_init(void)

{

    ret_code_t err_code;
    
    /* 2-channel PWM, 100Hz, output on LED pins. */
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(10000L, GPIO_LED_RED, GPIO_LED_GREEN);
    app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_1CH(10000L, GPIO_LED_BLUE);
    
    /* Set the polarity of the channel. */
    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
        
    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_1_ready_callback);
    APP_ERROR_CHECK(err_code);
    err_code = app_pwm_init(&PWM2,&pwm2_cfg,pwm_2_ready_callback);
    APP_ERROR_CHECK(err_code);
    
    app_pwm_enable(&PWM1);
    app_pwm_enable(&PWM2);
}



void pwm_1_ready_callback(uint32_t pwm_id)   

{
    pwm_1_ready_flag = true;
}

void pwm_2_ready_callback(uint32_t pwm_id)   
{
    pwm_2_ready_flag = true;
}





second, I set the pwm chanel duty by using below code. 

(in this function, I didn't wait callback. I just keep trying until PWM is ready)

static void color_setting(uint8_t red, uint8_t green, uint8_t blue)
{
    
    color_red=red;
    color_green=green;
    color_blue=blue;
    
    pwm_1_ready_flag = false;
    pwm_2_ready_flag = false;
    
    /* Set the duty cycle - keep trying until PWM is ready... */    
    while (app_pwm_channel_duty_set(&PWM1, 0, (uint32_t)(sin_table[color_red]/2.55)) == NRF_ERROR_BUSY);
    while (app_pwm_channel_duty_set(&PWM1, 1, (uint32_t)(sin_table[color_green]/2.55)) == NRF_ERROR_BUSY);
    while (app_pwm_channel_duty_set(&PWM2, 0, (uint32_t)(sin_table[color_blue]/2.55)) == NRF_ERROR_BUSY);

    /* ... or wait for callback. */
   //    while(!pwm_1_ready_flag);


}

sin_table's value is from 0 to 255. so I divided it by 2.55

And this color_setting function is called in app_timer call_back function.

my app timer's interval is 40ms.

In other words, PWM values is changed in every 40ms, and it repeat 0~100 value.

This "PWM signal reversed" issue is not appeared, when I don't use softDevice.

Is there any idea for avoiding this problem??

This problem is critical issue on my project.

Please help me.

Thanks.

  • Hi, I can see it. It is some clue to build new test. If I understand you correctly during this changes you was rising values from 6 to 11%? What was the step? Correct polarity is positive?

    I am not able to recreate this problem. A few questions:

    1. Why do you need such small period? Code suggests that you are using it for LED driving. 64us gives over 15kHz period.
    2. Can you include the code that generates this glitch?
    3. What exact version of the chip are you using? Please include also the production code from the case.
  • Yes, the values in that example were raising from 6 to 11%, but the problem exists in other cases and at other rates/steps.

    1. The reason I need such a small period is I am driving a induction coil to activate an electromagnet. If the frequency is lower, say with a 128us period, the PWM is audible.
    2. The code is somewhat complex and relies on a BLE connection to an iOS app. I can make a simplified version to demonstrate the glitch, what part of the code are you most interested in?
    3. I am using the nRF51-DK dev board. And on the nRF51 chip itself these numbers are printed: N51422 QFACA1 1503AD. I also have the same issue on a Red Bear Lab Nano module I have. Also, on the DK there is a sticker that has 'PCA10028 V1.1.0 2015.11' not sure if that is helpful.

    Let me know what code would work best for me to send for your test routine.

  • I found another possible clue, and hopefully it isn't just me being stupid:

    So I need to set the duty at a higher resolution than the 0-100 provided by the app_pwm_channel_duty_set function in the PWM library, so I added a function to the PWM library that accepts 0-1024. I have been using that function, and it mirrors the original function except 100UL is replaced with 1024UL. Today when I was creating a test program to send I went back to the original app_pwm_channel_duty_set function and the polarity reversals went away as far as I can tell with my testing.

    I am not sure how the function I added would create the problem. Here is the function I added and used called 'app_pwm_channel_duty_set_hires':

  • ret_code_t app_pwm_channel_duty_set_hires(app_pwm_t const * const p_instance, uint8_t channel, app_pwm_duty_t duty) { uint32_t ticks = ((uint32_t)app_pwm_cycle_ticks_get(p_instance) * (uint32_t)duty) / 1024UL; return app_pwm_channel_duty_ticks_set(p_instance, channel, ticks); }

  • I make sure that only 0-1024 is ever passed to the function. Not sure why this would create the problem.

Related