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

Reasoning behind nrf51-pwm-library implementation

FormerMember
FormerMember

Greetings,

Kudos for implementing a no glitch version of PWM with and without using timeslot.

github.com/.../nrf_pwm_noglitch.c.

Could the reasoning for the following be explained with the above PWM driver:

  • Why is pwm_max_value and pwm_value multiplied by 2 used for the timer instead of just these values?
  • Disabling of the PPI channels done in the IRQ routine? Could waiting for 1.5 or 2 times the PWM cycle work?

Also does this implementation have the infamous bug of the polarity inverting at times as mentioned in other posts in this forum? Thanks!

Parents
  • FormerMember
    0 FormerMember

    Answering my second question: yes, it is possible to wait longer and not use the timer IRQ to disable the PPI. But there is a better way. A bit of optimization of the library to remove the blocking of the processor for a PWM period which can be many microseconds. Could be costly when updating frequently.

    This can be done by commenting out nrf_delay_us(pwm_period_us); and changing the Timer IRQ to

    void PWM_IRQHandler(void)
    {
        PWM_TIMER->EVENTS_COMPARE[3] = 0;
        static bool alternate_flag = false;
    
        if(true == alternate_flag){
          PWM_TIMER->INTENCLR          = TIMER_INTENCLR_COMPARE3_Msk;
    
          ppi_disable_channels((1 << (PWM_MAX_CHANNELS * 2)) | (1 << (PWM_MAX_CHANNELS * 2 + 1)) | (1 << (PWM_MAX_CHANNELS * 2 + 2)));
          ppi_configure_channel_group(pwm_ppi_chg, 0);
          ppi_disable_channel_group(pwm_ppi_chg);
        }
        alternate_flag = (true == alternate_flag)?false:true;
    }
    

    Now the IRQ gets called twice with the actual PPI disabling done the second time. Since it is a low priority IRQ it does not block critical stuff. The CPU gets kept on for lesser time. The nrf_pwm_set_value() now returns immediately.

    With not using softdevice calls for configuring PPIs it is possible to call nrf_pwm_set_value() from high priority IRQ, especially now that the call is non-blocking.

    Makes sense to send a pull request to the library?

Reply
  • FormerMember
    0 FormerMember

    Answering my second question: yes, it is possible to wait longer and not use the timer IRQ to disable the PPI. But there is a better way. A bit of optimization of the library to remove the blocking of the processor for a PWM period which can be many microseconds. Could be costly when updating frequently.

    This can be done by commenting out nrf_delay_us(pwm_period_us); and changing the Timer IRQ to

    void PWM_IRQHandler(void)
    {
        PWM_TIMER->EVENTS_COMPARE[3] = 0;
        static bool alternate_flag = false;
    
        if(true == alternate_flag){
          PWM_TIMER->INTENCLR          = TIMER_INTENCLR_COMPARE3_Msk;
    
          ppi_disable_channels((1 << (PWM_MAX_CHANNELS * 2)) | (1 << (PWM_MAX_CHANNELS * 2 + 1)) | (1 << (PWM_MAX_CHANNELS * 2 + 2)));
          ppi_configure_channel_group(pwm_ppi_chg, 0);
          ppi_disable_channel_group(pwm_ppi_chg);
        }
        alternate_flag = (true == alternate_flag)?false:true;
    }
    

    Now the IRQ gets called twice with the actual PPI disabling done the second time. Since it is a low priority IRQ it does not block critical stuff. The CPU gets kept on for lesser time. The nrf_pwm_set_value() now returns immediately.

    With not using softdevice calls for configuring PPIs it is possible to call nrf_pwm_set_value() from high priority IRQ, especially now that the call is non-blocking.

    Makes sense to send a pull request to the library?

Children
No Data
Related