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);

    
}

  • Hello Karl,

                    I am implemented a new logic with a different controller and its working properly .

                     And its very small code also using only external interrupt ,Timer (in one shot mode)and GPIO

                    without PWM.

    I am attaching that for your reference .

    void EINT024_IRQHandler(void)
    {
        /* To check if PA.6 external interrupt occurred */
        if(GPIO_GET_INT_FLAG(PA, BIT6))
        {
    			  
                  GPIO_CLR_INT_FLAG(PA, BIT6);
    			  flg_Start_PWM=1;
    			  TIMER_SET_CMP_VALUE(TIMER0, delay);
    			  TIMER_Start(TIMER0);	
    		}
       
    }
    
    void TMR0_IRQHandler(void)
    {
        if(TIMER_GetIntFlag(TIMER0) == 1)
        {
    			  if(PA6 == 1) // Checking either rising edge or falling
    			 {
    				/* Clear Timer0 time-out interrupt flag */
            TIMER_ClearIntFlag(TIMER0);
    				
    				PB5=1;
    				PB4=0;
    				
    	     }
    			 else    //logic for falling edge
    				{
    					/* Clear Timer0 time-out interrupt flag */
              TIMER_ClearIntFlag(TIMER0);
    					
    					PB5=0;
    				    PB4=1;
    			    
    					
    				}      
        }
                
     }
    

    Explanation for details.

    1)Enabled External Interrupt pin For both edge for INPUTTED PWM Signal.

    2) Then start Timer in Both Edge in ONE SHOT MODE.(That's why I loaded Compare value every time)

    3)Then in TMR_INTERRUPT HANDLER handle the GPIO as per required.

    4) And Finally Tested with external INPUTTED PWM SIGNAL .

    I am attaching video of that for your reference .

    So Karl Please guide to implement  these steps in NORDIC .

    Best regards,
    Ram 

  • Hello again, Ram

    RAM_MS said:
    I am implemented a new logic with a different controller and its working properly .
    RAM_MS said:
    So Karl Please guide to implement  these steps in NORDIC .

    The big difference between the implementation you have made for the other µC and the one we have been working on is that the one for the other µC uses the CPU to set and clear the GPIO.
    This is not a viable approach for a larger project - since you will not have any guarantees that the CPU will not be busy in a higher / equal priority interrupt, which will delay the set/clear execution and lead to a incorrect waveform.

    I've attached an example that shows how what you describe can be done. A toggle on the PIN_IN starts a timer that repeatedly toggles the PIN_OUT at a given interval. If you would like the start delay and pulse length to be different you will need to add another timer instance to implement the start delay, and then have it start the toggle timer upon expiring.
    __delayed_gpiote_toggle.zip

    Best regards,
    Karl

  • Hello Karl,

    The big difference between the implementation you have made for the other µC and the one we have been working on is that the one for the other µC uses the CPU to set and clear the GPIO.
    This is not a viable approach for a larger project - since you will not have any guarantees that the CPU will not be busy in a higher / equal priority interrupt, which will delay the set/clear execution and lead to a incorrect waveform.

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

    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.

    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

Related