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

How to change duty cycle when using HW driver library

Hi

I am using the HW driver library for the PWM.

I looked at your example and in order to change the duty cycle of a channel, you directly change it in the m_demo1_seq_values.

The change is done in the handler, when NRF_DRV_PWM_EVT_FINISHED event occur.

My questions are:

  1. Can I change a duty cycle in m_demo1_seq_values not in the handler routine? the Duty cycle change occurs no so often, and I don't want to enter the handler every time that NRF_DRV_PWM_EVT_FINISHED occur, as it "disturbs" the cpu
  2. When changing the duty cycle, when the change actually take place?

Thanks

Arik Ramon

Parents
  • Can I change a duty cycle in m_demo1_seq_values not in the handler routine? the Duty cycle change occurs no so often, and I don't want to enter the handler every time that NRF_DRV_PWM_EVT_FINISHED occur, as it "disturbs" the cpu

     Yes, there are two ways you can do it:

    1. You can wait until a EVENTS_SEQSTARTED[0] event has occured. This event signals that the PWM module has read the pointer address from SEQ[0].PTR and stored it in an internal register. This is the address to your array of pwm duty-cycle samples (sequence).
      At this point in time it is safe to update the SEQ[0].PTR with the address to your new sequence of duty-cycles, but it must be done before the next loop will start. 

    2. You can modify the value of your sequence directly, though this is not safe unless you can guarantee there won't be a race condition between you writing and the EasyDMA reading to/from the same address of memory at the same time. You can ensure this by either stopping the PWM, or use longer sequences and time your writing to the EVENTS_SEQSTARTED[0] event, or any other suitable event. 

     

    When changing the duty cycle, when the change actually take place?

     It depends on which method you used:

    1. When using multiple sequences, the PWM value is updated once the previous sequence is finished playing. If you are using loops, then all the loops must finish, unless you stop the PWM instance with a TASKS_STOP and then re-start it with a TASKS_SEQSTART[0].

    2. It will change as soon as the PWM module reads an updated sequence value.
Reply
  • Can I change a duty cycle in m_demo1_seq_values not in the handler routine? the Duty cycle change occurs no so often, and I don't want to enter the handler every time that NRF_DRV_PWM_EVT_FINISHED occur, as it "disturbs" the cpu

     Yes, there are two ways you can do it:

    1. You can wait until a EVENTS_SEQSTARTED[0] event has occured. This event signals that the PWM module has read the pointer address from SEQ[0].PTR and stored it in an internal register. This is the address to your array of pwm duty-cycle samples (sequence).
      At this point in time it is safe to update the SEQ[0].PTR with the address to your new sequence of duty-cycles, but it must be done before the next loop will start. 

    2. You can modify the value of your sequence directly, though this is not safe unless you can guarantee there won't be a race condition between you writing and the EasyDMA reading to/from the same address of memory at the same time. You can ensure this by either stopping the PWM, or use longer sequences and time your writing to the EVENTS_SEQSTARTED[0] event, or any other suitable event. 

     

    When changing the duty cycle, when the change actually take place?

     It depends on which method you used:

    1. When using multiple sequences, the PWM value is updated once the previous sequence is finished playing. If you are using loops, then all the loops must finish, unless you stop the PWM instance with a TASKS_STOP and then re-start it with a TASKS_SEQSTART[0].

    2. It will change as soon as the PWM module reads an updated sequence value.
Children
  • Thank's for the answer

    Two more questions:

    1. If I am using simple playback with two pins, with flag=NRF_DRV_PWM_FLAG_LOOP, when is the duty cycle is updated?
    2. There is a function call "nrfx_pwm_sequence_values_update" is it safe to use it at any time?

    Thanks

    Arik

  • arikramon said:
    • If I am using simple playback with two pins, with flag=NRF_DRV_PWM_FLAG_LOOP, when is the duty cycle is updated?
    • There is a function call "nrfx_pwm_sequence_values_update" is it safe to use it at any time?

     If you use nrfx_pwm_sequence_values_update it will update the next time a TASKS_SEQSTART is triggered. By default, the driver triggers TASKS_SEQSTART when you call nrfx_pwm_simple_playback. You can call nrfx_pwm_simple_playback after the current loop is done or after you've called nrfx_pwm_stop. 

  • If I am using flag=NRF_DRV_PWM_FLAG_LOOP, when the TASKS_SEQSTART is triggered?

    is it triggered only once after nrfx_pwm_simple_playback is called?

    According to nrfx_pwm.h, the function nrfx_pwm_sequence_update is updating the pointer to the duty cycle values  in the specified sequence during playback.

    Arik

  • From nrfx_pwm.h line 142: NRFX_PWM_FLAG_LOOP

    When the requested playback is finished, 
    it will be started from the beginning. This flag is ignored if used together with @ref NRFX_PWM_FLAG_STOP. @note The playback restart is done via a shortcut configured in the PWM peripheral. This shortcut triggers the proper starting task when the final value of the previous playback is read from RAM and applied to the pulse generator counter. When this mechanism is used together with the @ref NRF_PWM_STEP_TRIGGERED mode, the playback restart will occur right after switching to the final value (this final value will be played only once).
     

    arikramon said:
    According to nrfx_pwm.h, the function nrfx_pwm_sequence_update is updating the pointer to the duty cycle values  in the specified sequence during playback.

    Acoording to the documentation you should only need to call this one function in order to update the sequence values when NRFX_PWM_FLAG_LOOP is set.  

Related