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

Should PWM end_delay be honoured or ignored if playback_count is 1 ?

I've modified the simple_pwm example from : devzone.nordicsemi.com/.../

I've either misunderstood or have found a bug where by the 'end_delay' value is ignored if the 'playback_count' prameter is set to 1 when calling 'nrf_drv_pwm_simple_playback'.

I wondered if someone could clarify this for me please?

Thanks Wayne

The code:

static void pwm_simple(void)
{
	uint32_t err_code;
	nrf_drv_pwm_config_t const config0 =
	{
			.output_pins =
			{
					BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
					NRF_DRV_PWM_PIN_NOT_USED,             // channel 1
					NRF_DRV_PWM_PIN_NOT_USED,             // channel 2
					NRF_DRV_PWM_PIN_NOT_USED,             // channel 3
			},
			.irq_priority = APP_IRQ_PRIORITY_LOW,
			.base_clock   = NRF_PWM_CLK_1MHz,
			.count_mode   = NRF_PWM_MODE_UP,
			.top_value    = 10,
			.load_mode    = NRF_PWM_LOAD_COMMON,
			.step_mode    = NRF_PWM_STEP_AUTO
	};

	err_code = nrf_drv_pwm_init(&m_pwm0, &config0, NULL);
	APP_ERROR_CHECK(err_code);

	static nrf_pwm_values_common_t seq_values[] =
	{
			10, 0
	};

	nrf_pwm_sequence_t const seq =
	{
			.values.p_common = seq_values,
			.length          = NRF_PWM_VALUES_LENGTH(seq_values),
			.repeats         = 0,
			.end_delay       = 5        // Has no effect unless the '1' below is >1
	};

	nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);

}
Parents
  • Hello Wayne

    You are right. When using the LOOP flag the end_delay will be ignored for the last duty cycle during the final execution of the sequence. However, the correct number of repeats are executed.

    When using the STOP flag both end_delay and repeats are ignored for the last duty cycle on the final execution of the sequence.

    It seems this isn't mentioned in the documentation. I will bring it forward.

    As a work-around to get the correct number of repeats for the final duty cycle you can reduce the number of repeats per duty cycle, and add several instances for each duty cycle.

    i.e. if you have top value 100 and sequence = {50, 20}; and you want 50 to be repeated 10 times, while 20 is repeated 15 times you can use

    sequence = {50, 50, 20, 20, 20};
    

    with

    .repeats = 4; 
    .end_delay=0;
    

    This way each duty cycle is executed 5 times each.

    Best regards

    Jørn Frøysa

Reply
  • Hello Wayne

    You are right. When using the LOOP flag the end_delay will be ignored for the last duty cycle during the final execution of the sequence. However, the correct number of repeats are executed.

    When using the STOP flag both end_delay and repeats are ignored for the last duty cycle on the final execution of the sequence.

    It seems this isn't mentioned in the documentation. I will bring it forward.

    As a work-around to get the correct number of repeats for the final duty cycle you can reduce the number of repeats per duty cycle, and add several instances for each duty cycle.

    i.e. if you have top value 100 and sequence = {50, 20}; and you want 50 to be repeated 10 times, while 20 is repeated 15 times you can use

    sequence = {50, 50, 20, 20, 20};
    

    with

    .repeats = 4; 
    .end_delay=0;
    

    This way each duty cycle is executed 5 times each.

    Best regards

    Jørn Frøysa

Children
  • Is this really a documentation fix? I would have hoped the library would work using the principle of 'the path of least surprise'. Or is this a silicon issue?

    For context I am creating sequences dynamically in response to messages received via BLE.
    Based on your example it will be necessary generate the numbers via a simple algorithm rather than a basic mapping.

    I must admit that I'm having trouble understanding your example in order to generalise it, I may need to revisit the docs as I though the 'repeat' would treat the whole sequence as a unit to repeat, not the individual items of the sequence repeated in turn.

    Thanks Wayne

  • Also for context, and may explain in part why your example doesn't immediately work for me, is that I'm trying to generate a signal based on timing, e.g. not using the PWM peripheral for the averaging effects of the duty cycle, but for generating a specific (and very very simple) waveform.

  • The issue lies in hardware, and not the library as it is a matter of how the hardware responds to the PWM finished event, which is also generated by hardware. The library enables the hardware short between the loops done event and the event that starts sequence 0. The same issue arises when programming the PWM bare-metal.

    The repeats setting affects each individual duty cycle, and not the sequence as a whole. Essentially it determines how many times it should repeat the count process for each compare value. If you want to repeat the sequence as a whole, you would typically use the playback_count argument in the playback function call.

  • It looks like three years passed and the documentation is still not updated. It says just about ignoring end_delay in NRF_PWM_STEP_TRIGGERED.

Related