Use of nrfx_dppi with nrf5340 to control one GPIO

Dear,

I need to generate a pulse signal on one IO following this pattern:
HIGH for 12us ; LOW for 106us ;  and so on...


I tried to use TIMER0 with  NRF_TIMER_EVENT_COMPARE0 and NRF_TIMER_EVENT_COMPARE1 but the signal is often not respected (keeping one cycle the IO HIGH also during second period). So I assume I need to use dppi, but using the following code, I still not see anything happening on the io:

struct gpio_dt_spec mofset_ctrl_io = GPIO_DT_SPEC_GET(DT_NODELABEL(mofset_ctrl), gpios);

#define TIMER_INSTANCE_NUMBER 0
const nrfx_timer_t timer_instance = NRFX_TIMER_INSTANCE(TIMER_INSTANCE_NUMBER);


#define TOGGLE_INTERVAL_ON_US 12
#define TOGGLE_INTERVAL_OFF_US 106

static nrfx_gpiote_t const gpiote_inst = NRFX_GPIOTE_INSTANCE(0);
static uint8_t dppi_channel;



static void timer0_init(void)
{
    nrfx_err_t err;

    nrfx_timer_config_t timer_config = NRFX_TIMER_DEFAULT_CONFIG(16000000);
    timer_config.bit_width = NRF_TIMER_BIT_WIDTH_16;
    
    err = nrfx_timer_init(&timer_instance, &timer_config, NULL);
    if (err != NRFX_SUCCESS) {
        LOG_ERR("nrfx_timer_init error: %08x", err);
        return;
    }

    uint32_t ticks1 = nrfx_timer_us_to_ticks(&timer_instance, TOGGLE_INTERVAL_ON_US);
    uint32_t ticks2 = nrfx_timer_us_to_ticks(&timer_instance, TOGGLE_INTERVAL_ON_US + TOGGLE_INTERVAL_OFF_US);

    LOG_INF("COMPARE0: %d ticks, COMPARE1: %d ticks", ticks1, ticks2);

    nrfx_timer_extended_compare(
        &timer_instance,
        NRF_TIMER_CC_CHANNEL0,
        ticks1,
        NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK,  // Efface le compteur après COMPARE1
        true
    );

    nrfx_timer_extended_compare(
        &timer_instance,
        NRF_TIMER_CC_CHANNEL1,
        ticks2,
        NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK,  // On efface à COMPARE1
        true
    );

    // Connexion de l'IRQ
    IRQ_DIRECT_CONNECT(TIMER0_IRQn, 0, nrfx_timer_0_irq_handler, 0);
    irq_enable(TIMER0_IRQn);

    nrfx_timer_enable(&timer_instance);
    LOG_INF("Timer started");
}



static void gpiote_dppi_init(void)
{

    nrfx_err_t err;

    err = nrfx_gpiote_init(&gpiote_inst, NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
    if (err != NRFX_SUCCESS && err != NRFX_ERROR_ALREADY_INITIALIZED) {
        LOG_ERR("nrfx_gpiote_init error: %08x", err);
        return;
    }

    nrfx_gpiote_output_config_t gpiote_config = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;
    err = nrfx_gpiote_output_configure(&gpiote_inst, mofset_ctrl_io.pin, &gpiote_config, NULL);
    if (err != NRFX_SUCCESS) {
        LOG_ERR("nrfx_gpiote_output_configure error: %08x", err);
        return;
    }

    nrfx_gpiote_trigger_enable(&gpiote_inst, mofset_ctrl_io.pin, true);

    err = nrfx_dppi_channel_alloc(&dppi_channel);
    if (err != NRFX_SUCCESS) {
        LOG_ERR("nrfx_dppi_channel_alloc error: %08x", err);
        return;
    }

	nrfx_gppi_channel_endpoints_setup(dppi_channel,
	    nrfx_timer_compare_event_address_get(&timer_instance, NRF_TIMER_CC_CHANNEL0),
		nrfx_gpiote_out_task_address_get(&gpiote_inst, mofset_ctrl_io.pin));
    
    nrfx_gppi_channel_endpoints_setup(dppi_channel,
        nrfx_timer_compare_event_address_get(&timer_instance, NRF_TIMER_CC_CHANNEL1),
        nrfx_gpiote_out_task_address_get(&gpiote_inst, mofset_ctrl_io.pin));

    err = nrfx_dppi_channel_enable(dppi_channel);
    if (err != NRFX_SUCCESS) {
        LOG_ERR("Failed to enable DPPI channel, error: %08x", err);
        return;
    }

    LOG_INF("GPIOTE + DPPI initialized");

}

Do you know why ? I confess it was difficult to setup this with all the API changes on that topic (add of nrfx_gpiote_t in prototypes and other changes), and I never found one full example working for nrf5340 and NCS 2.7.0 I am using.

Thanks in advance for your piece of advice!

Kind regards,

Michael

Related