Start PWMs synchronous

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:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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),
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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:

Fullscreen
1
2
3
4
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);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Strangely enough, if I reverse the order in which I start the PWMS:

Fullscreen
1
2
3
4
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);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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.