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.

Parents
  • Update: This issue is fixed since SDK 10.

    This is fresh copy from our development repository: (This is obsolete. See the newest driver attached below) pwm.7z This fix is going to be presented in the nearest release. There are also some functions added to give the possibility to set PWM duty in cycles - it was something I needed for testing and probably it would be left in official API.

    The error is really subtle and quite hard to find - the order of some operations gives a possibility to break the synchronisation if interrupt occurs between them. This version was simulated whole night with simulated interrupting in random places and in the morning today no errors was found.

    Beside of that this is a real masterpiece of code and as I have told - the error was really subtle.


    Ok - it was a really crazy work. Yesterday I have detected that it is changing channel 1 that breaks channel 2, and additionally it was only after second change from 0 of 100% duty to another value. I mean - first change from 0 to 1... or from 100 to 99 and then second change to any value that is not 0 nor 100% and BAM - because of some event to interrupt race sometimes phase was switched.

    So god news everyone: hardware looks ok. Updated software preview here: pwm_20150708.7z

Reply
  • Update: This issue is fixed since SDK 10.

    This is fresh copy from our development repository: (This is obsolete. See the newest driver attached below) pwm.7z This fix is going to be presented in the nearest release. There are also some functions added to give the possibility to set PWM duty in cycles - it was something I needed for testing and probably it would be left in official API.

    The error is really subtle and quite hard to find - the order of some operations gives a possibility to break the synchronisation if interrupt occurs between them. This version was simulated whole night with simulated interrupting in random places and in the morning today no errors was found.

    Beside of that this is a real masterpiece of code and as I have told - the error was really subtle.


    Ok - it was a really crazy work. Yesterday I have detected that it is changing channel 1 that breaks channel 2, and additionally it was only after second change from 0 of 100% duty to another value. I mean - first change from 0 to 1... or from 100 to 99 and then second change to any value that is not 0 nor 100% and BAM - because of some event to interrupt race sometimes phase was switched.

    So god news everyone: hardware looks ok. Updated software preview here: pwm_20150708.7z

Children
Related