Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF5 SDK15.0 - PWM Driver: Just set a fixed duty cycle?

The PWM Driver has all sorts of fancy stuff for dealing with clever sequences - but I can't see anything to just set a simple, steady, fixed duty cycle!

How does one just set a fixed duty cycle?

What I actually want is to be able to fade an LED up to a certain brightness; so what I really want is to be able to specify an increasing sequence, and then a steady duty cycle to last indefinitely once the fade-up sequence completes.

Is there a simple way to do that?

  • Ok. It worked in my tests, but maybe we tried on different chips.

    You can use  7FFF then.

    I can agree that the PWM drivers are a bit confusing, which is why I suggested the PPI implementation, which only uses a timer and the GPIOTE driver to toggle the pins.

    The example actually uses both the GPIO driver and the PWM driver to control the LEDs/pins. The NRF_DRV_PWM_PIN_INVERTED is actually not used when the PWM is running. That is, when you call nrf_drv_pwm_simple_playback(). It is used when the PWM is stopped (which it doesn't do in this example, so it is a bit misleading. 

    If you want to stop the PWM (by not using the loop-flag, but the NRF_DRV_PWM_FLAG_STOP, then the NRF_DRV_PWM_PIN_INVERTED will cause the pin to go high after the sequence. And pin high means LED off. If you remove PIN_INVERTED and use NRF_DRV_PWM_FLAG_STOP, you will see that the LED will turn on after the sequence.

    But if you want to have a constant duty cycle, e.g. for controlling a motor, you might not want to turn it off at all, so then you would have to use the first bit to tell it whether you want to have an active high or an active low PWM signal.

    Best regards,

    Edvin

  • The Assert is actually in nrf_pwm_configure():

    __STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg,
                                           nrf_pwm_clk_t  base_clock,
                                           nrf_pwm_mode_t mode,
                                           uint16_t       top_value)
    {
        NRFX_ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
    
        p_reg->PRESCALER  = base_clock;
        p_reg->MODE       = mode;
        p_reg->COUNTERTOP = top_value;
    }
    

    and PWM_COUNTERTOP_COUNTERTOP_Msk is defined in nrf52810_bitfields.h:

    /* Bits 14..0 : Value up to which the pulse generator counter counts. This register is ignored when DECODER.MODE=WaveForm and only values from RAM are used. */
    #define PWM_COUNTERTOP_COUNTERTOP_Pos (0UL) /*!< Position of COUNTERTOP field. */
    #define PWM_COUNTERTOP_COUNTERTOP_Msk (0x7FFFUL << PWM_COUNTERTOP_COUNTERTOP_Pos) /*!< Bit mask of COUNTERTOP field. */
    

  • Hi Guys,

    Any founding on this topics? How the .base_clock   = NRF_PWM_CLK_2MHz influence the .top_value    = 32768, // = 0x8000?

Related