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

  • Ok, so I ran the signal through an logic analyzer to see exactly what is happening. And the 'glitches' I described before are in fact the PWM polarity reversing. It is actually reversing back and forth several times in a row, sometimes like 50 times in a row. I made a few observations: 1. The signal reverses at a predicable timing. When a pattern of reversal starts it happens every 10ms on the dot. I am updating the PWM duty every 10ms, so that timing seems to align. For example: I have one recording where the flipping started at 1s 354ms into the recording, at 364ms it would reverse polarity, at 374ms reverse again, and like that for 40 times and then it was fine. During that pattern the duty value is just gradually changing from ~6% to 11%, so no big changes (besides the polarity). 2. The problem doesn't seem to correspond to the set duty, I've seen it at 33% 6%, etc.

Reply
  • Ok, so I ran the signal through an logic analyzer to see exactly what is happening. And the 'glitches' I described before are in fact the PWM polarity reversing. It is actually reversing back and forth several times in a row, sometimes like 50 times in a row. I made a few observations: 1. The signal reverses at a predicable timing. When a pattern of reversal starts it happens every 10ms on the dot. I am updating the PWM duty every 10ms, so that timing seems to align. For example: I have one recording where the flipping started at 1s 354ms into the recording, at 364ms it would reverse polarity, at 374ms reverse again, and like that for 40 times and then it was fine. During that pattern the duty value is just gradually changing from ~6% to 11%, so no big changes (besides the polarity). 2. The problem doesn't seem to correspond to the set duty, I've seen it at 33% 6%, etc.

Children
No Data
Related