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

Issues with PWM and S210

Hi everyone,

When I run 4 instances (i.e., x2 PWM channels) of PWM with S210 (same example as the ant_background_scanning from SDK 10), after few seconds of constantly changing PWM duty cycle of 2 out of 4 PWM instances, the chip restarts by itself. Issue was not seen with PWM when softdevice and ANT were not enabled. Initialization of the softdevice and ANT is the same as the abovementioned example and the PWM is initialized as shown below:

APP_PWM_INSTANCE(PWM1,1);			// Create the instance "PWM1" using TIMER1.
APP_PWM_INSTANCE(PWM2,2);			// Create the instance "PWM2" using TIMER2.

void pwm_ready_callback(uint32_t pwm_id)
{
    ready_flag = true;
}

...

int main(void) {
...
     setup softdevice and ANT here
...

     // begin initialization of PWM channels
     app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(4096L, 25, 26);
     app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(4096L, 28, 29);
     //app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(4096L, 26, 28);
     // initialize and enable PWM
     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, pwm_ready_callback);
     APP_ERROR_CHECK(err_code);
     pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
     pwm2_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
     err_code = app_pwm_init(&PWM2, &pwm2_cfg, pwm_ready_callback);
     APP_ERROR_CHECK(err_code);
     // enable PWMs
     app_pwm_enable(&PWM1);
     app_pwm_enable(&PWM2);

     ...

     while(1) {
              while (app_pwm_channel_duty_set(&PWM1, 1, 16) == NRF_ERROR_BUSY);	// left forward
              while (app_pwm_channel_duty_set(&PWM2, 1, 16) == NRF_ERROR_BUSY);	// right backward
              nrf_delay_ms(1000);
              while (app_pwm_channel_duty_set(&PWM1, 1, 0) == NRF_ERROR_BUSY);	// left forward
              while (app_pwm_channel_duty_set(&PWM2, 1, 0) == NRF_ERROR_BUSY);	// right backward
              nrf_delay_ms(1000);
     }

One observation that I made was that the PWM gets stuck at the first bit of the while loop when both instances are set to '16' percent before restarting. That is, instead of stopping all PWM after 1 second, the PWM continues at 16% duty cycle for several seconds and then restarts.

Thank you for your help.

  • Which SDK are you using? Can you find out why the code resets? Probably it is because you are running into an error condition, see here.

  • The issue is coming from here in app_pwm.c

    if (p_cb->state != NRF_DRV_STATE_POWERED_ON)
    {
        return NRF_ERROR_INVALID_STATE;
    }
    

    where it returns the NRF_ERROR_INVALID_STATE after few seconds of running the above code. I changed NRF_ERROR_INVALID_STATE to NRF_SUCCESS and after, instead of getting stuck at 16% PWM and restarting after few seconds, the PWM continues at 16% and never restarts. So, as your link suggests, it seems like an error condition is returned from the PWM duty cycle set function and system restarts. However, I commented out the following in the app_error.c but the nRF51422 still restarts:

    ...
    NVIC_SystemReset();
    ...
    m_error_code = error_code;
    m_line_num = line_num;
    m_p_file_name = p_file_name;
    UNUSED_VARIABLE(m_error_code);
    UNUSED_VARIABLE(m_line_num);
    UNUSED_VARIABLE(m_p_file_name);
    __disable_irq();
    while(loop);
    
  • Which SDK are you using? You should find out why it returns NRF_ERROR_INVALID_STATE, not change the return value to NRF_SUCCESS, then you will get undefined behaviour. The state is set in the init, uninit, enable and disable functions. The state is set to NRF_DRV_STATE_POWERED_ON in the enable function. You are probably calling init, uninit or disable after you called the enable functions.

Related