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

How to start pwm sequence after particular time delay of gpio event?

I am working on an application where I need to start pwm sequence after particular delay (accurate delay of multiple of 100us).

I am quite new to nordic environment.

Here is my code . Can please guide me what is wrong here??

#define    Period    20000 //20ms

const nrf_drv_timer_t TIMER_LED = NRF_DRV_TIMER_INSTANCE(0);

APP_PWM_INSTANCE(PWM1,1); 

static int gpio_flag =0;

void pwm_update(void)
{
      uint32_t value;
      value = duty_1;
      ready_flag = false;
      /* Set the duty cycle - keep trying until PWM is ready... */
      
      

      while ((app_pwm_channel_duty_set(&PWM1, 0, value))&(app_pwm_channel_duty_set(&PWM1, 1, value)) == NRF_ERROR_BUSY);
 
      /* ... or wait for callback. */
      while (!ready_flag);
      APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 1, value));
      APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 0, value));

}


void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
   gpio_flag =1;
   nrf_drv_timer_enable(&TIMER_LED);

   
}

void timer0_handler(nrf_timer_event_t event_type, void* p_context)
{
  switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
             timer_flg =1;
             nrf_drv_timer_clear(&TIMER_LED);
             gpio_flag=0;
             pwm_update();
            break;

        default:
            //Do nothing.
            break;
    }
}


void timer_init(void)
{
    uint32_t time_us = 500; 
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer0_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_LED, time_us);
    nrf_drv_timer_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, true);

    
}

Parents
  • Hello,

    I am quite new to nordic environment.

    Welcome! Please do not hesitate to ask if you should have any questions.

    I am working on an application where I need to start pwm sequence after particular delay (accurate delay of multiple of 100us).

    Could you show me the entirety of your main.c code?
    Right now I do not see where you setup your gpio for triggering the enabling of the timer, so I am not sure that the timer is ever started, for instance.

    Could you also elaborate on what behavior you are seeing, and how this differs from what you would expect? Does the device reset for example, or is it just that 'nothing' is happening, for example?

    Best regards,
    Karl

  • Hello Karl,

    Right now I do not see where you setup your gpio for triggering the enabling of the timer, so I am not sure that the timer is ever started, for instance.

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
       gpio_flag =1;
       nrf_drv_timer_enable(&TIMER_LED);
    
       
    }

    Could you also elaborate on what behavior you are seeing, and how this differs from what you would expect? Does the device reset for example, or is it just that 'nothing' is happening, for example?

    I am not getting the delay I am expecting.

    I think I have done some wrong configuration in linking to timer from gpio interrupt routine. 

    Best regards,
    Ram



  • Hello again, Ram

    RAM_MS said:
    Actually I just want to discuss same ,is this approach is ok?

    It will depend on your applications requirements and constraints. For example, how detrimental is it that the waveform is accurately periodic and well-behaved?
    If you use the CPU to generate the waveform and you have other things happening in your program with equal or higher priority you will never be able to guarantee a correct waveform with the CPU approach, which is why this often is not a viable method for waveform generation.

    RAM_MS said:

    At the same time I am trying the method what we discussed yet and given you the tested result but you didn't reply that.

    Please reply on that also.

    Oh, I thought your previous comment meant that you had moved on from that approach.

    Do you see any difference to the behavior of the waveform when you disable the peripherals?

    Best regards,
    Karl

  • Hello Karl,

    It will depend on your applications requirements and constraints. For example, how detrimental is it that the waveform is accurately periodic and well-behaved?

    Yes till now Its accurately periodic and well-behaved but till now CPU only handling GPIO , GPIO interrupt ,Timer and UART .

    It might be problematic later .

    Do you see any difference to the behavior of the waveform when you disable the peripherals?

    No ,after disabling also same shifting of waveform issue is there.

    Best regards,
    Ram

  • Hello again, Ram

    Thank you for your patience with this.

    RAM_MS said:

    Yes till now Its accurately periodic and well-behaved but till now CPU only handling GPIO , GPIO interrupt ,Timer and UART .

    It might be problematic later .

    I too would think that this could become problematic later if you intend on having the device do additional things at equal or higher priority of the PWM generation.

    RAM_MS said:
    No ,after disabling also same shifting of waveform issue is there.

    That is most peculiar. Could you send me an updated version of the project so I may take a look at this on my end?

    Best regards,
    Karl

  • Hello again , Karl 

                 Thank you for your support,

    I too would think that this could become problematic later if you intend on having the device do additional things at equal or higher priority of the PWM generation.

    Yeah, That's why I persisted with your suggested way and hoping we could solve this issue very soon.

    That is most peculiar. Could you send me an updated version of the project so I may take a look at this on my end?

    Here I am attaching the updated project zip file for your reference.

    pwm_complementary_mode.zip

    Best regards,
    Ram

  • Hello again Ram,

    I regret to inform you that I unfortunately have been unable to properly look into and debug the project you provided me in your previous comment - I have been unavailable for some time now, and I will now be out of office until over new years.

    I still believe that the suggested PPI approach is the best fit for the application you have described, and so all that should remain is to pinpoint and resolve the reason for the added delay between the PWM periods.

    If you require support with this issue before I am back in office again I recommend that you open another ticket for this. Please know that the forum is operating on reduced staffing during the upcoming holiday season here in Norway, apologies for the inconvenience.

    I hope you will have a great holiday season, Ram!

    Best regards,
    Karl

Reply
  • Hello again Ram,

    I regret to inform you that I unfortunately have been unable to properly look into and debug the project you provided me in your previous comment - I have been unavailable for some time now, and I will now be out of office until over new years.

    I still believe that the suggested PPI approach is the best fit for the application you have described, and so all that should remain is to pinpoint and resolve the reason for the added delay between the PWM periods.

    If you require support with this issue before I am back in office again I recommend that you open another ticket for this. Please know that the forum is operating on reduced staffing during the upcoming holiday season here in Norway, apologies for the inconvenience.

    I hope you will have a great holiday season, Ram!

    Best regards,
    Karl

Children
  • Hello again Karl,

    I regret to inform you that I unfortunately have been unable to properly look into and debug the project you provided me in your previous comment - I have been unavailable for some time now, and I will now be out of office until over new years.

    No issue Karl, It will be really helpful if you look into the project after your vacation .

    Because for new tickets Its really slight hard for new person to get into the exact issue .

    I hope you will have a great holiday season, Karl !

    Best regards,
    Ram

  • Hello again, Ram

    I am now back in office again, thank you for your patience and well wishes for the holiday season!
    I hope you had a great holiday season as well! :) 

    I took a closer look at the video from the oscilloscope that you sent earlier, and I notice that this might just be drift from the HFCLK (which is 20 ppm) since it drifts for what approximately seems to be a total of 200 µs over 30 seconds, from what I could gather from the oscilloscope settings visible in the video. In that case, we should just need to synchronize the output PWM with the input PWM every so often, to avoid this being an issue.

    To synchronize them you could make use of the same mechanic as already implemented for the startup of the PWM: have the timer again started on an incoming flank, which in turn starts the waveform generation.
    Depending on how smooth the calibration/shift have to be (if it is acceptable to drop a couple of PWM periods or not, for example), there might have to be added some additional functionality for the restarting of the PWM waveform generation, or alternatively that another PWM instance is prepared, and it's output is switched over to the phase-shifted PWM's output when ready, for example. Could you give this a try - restarting the phase-shifted PWM waveform generation every so often - and see if it alleviates the issue?

    How often this synchronization will need to happen also depends on your application - how much drift is the maximum acceptable drift for your application?

    Best regards,
    Karl

Related