Hello there,
I have configured the 4 PWM peripherals to generate a certain waveform. I need to start all 4 pwm peripherals simultaneous.
I thought of achieving this through usage of the PPI + EGU.
EGU channel 0 event triggers EGU channel 1 and channel 2 tasks.
EGU channel 1 event triggers PWM0/1 SEQSTART tasks.
EGU channel 2 event triggers PWM2/3 SEQSTART tasks.
This is written in the code below:
static void setup_ppi(nrf_ppi_channel_t *channel, uint32_t event, uint32_t task1, uint32_t task2)
{
nrfx_err_t err = nrfx_ppi_channel_alloc(channel);
assert(err == NRFX_SUCCESS);
err = nrfx_ppi_channel_assign(*channel, event, task1);
assert(err == NRFX_SUCCESS);
err = nrfx_ppi_channel_fork_assign(*channel, task2);
assert(err == NRFX_SUCCESS);
err = nrfx_ppi_channel_enable(*channel);
assert(err == NRFX_SUCCESS);
}
static void start_pwms(const nrfx_pwm_t *pwms)
{
nrf_ppi_channel_t channel[3];
setup_ppi(&channel[0], nrf_egu_event_address_get(NRF_EGU0, NRF_EGU_EVENT_TRIGGERED0),
nrf_egu_task_address_get(NRF_EGU0, NRF_EGU_TASK_TRIGGER1),
nrf_egu_task_address_get(NRF_EGU0, NRF_EGU_TASK_TRIGGER2));
setup_ppi(&channel[1], nrf_egu_event_address_get(NRF_EGU0, NRF_EGU_EVENT_TRIGGERED1),
nrfx_pwm_task_address_get(&pwms[0], NRF_PWM_TASK_SEQSTART1),
nrfx_pwm_task_address_get(&pwms[1], NRF_PWM_TASK_SEQSTART1));
setup_ppi(&channel[2], nrf_egu_event_address_get(NRF_EGU0, NRF_EGU_EVENT_TRIGGERED2),
nrfx_pwm_task_address_get(&pwms[2], NRF_PWM_TASK_SEQSTART1),
nrfx_pwm_task_address_get(&pwms[3], NRF_PWM_TASK_SEQSTART1));
nrf_egu_task_trigger(NRF_EGU0, NRF_EGU_TASK_TRIGGER0);
for (size_t k = 0; k < ARRAY_SIZE(channel); k++) {
nrfx_err_t err = nrfx_ppi_channel_free(channel[k]);
assert(NRFX_SUCCESS == err);
}
}
The following 4 signals should rise at the same time, however they are 1.85 us out of sync.

Triggering the PWM SEQSTART tasks manually has the same result:
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM3, NRF_PWM_TASK_SEQSTART1);
Strangely enough, if I reverse the order in which I start the PWMS:
nrf_pwm_task_trigger(NRF_PWM3, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART1);
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART1);
The PWM signals are still generated in order PWM0->PWM3

Can anyone explain this? Is there no way to start the PWMs at the same time?
I am using NCS V2.5.0.
