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.