Porting gpiote driver from NCS 2.5.1 to NCS 2.6.1

I need a clarification about the update of gpiote driver. I've passed from the NCS 2.5.1 to the 2.6.1 and now I have issues in the configuration of my ppi infrastructure. The original code that works in the NCS 2.5.1 is

uint8_t taskChannel;

void Enable_Stream_Ppi_Infrastructure( void )
{
    spiStartTaskAddr = nrfx_spim_start_task_address_get( &inertialSpiInst );
    spiEndEventAddr = nrfx_spim_end_event_address_get( &inertialSpiInst );
    timerCompareEventAddr = nrfx_timer_compare_event_address_get( &inertialReadingTimerInst, NRF_TIMER_CC_CHANNEL0 );

    if ( nrfx_gpiote_channel_alloc( &taskChannel ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Allocation gpiote channel failed" );
        return;
    }

    nrfx_gpiote_output_config_t outputConfig = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;
    nrfx_gpiote_task_config_t taskConfig = {
        .task_ch = taskChannel,
        .polarity = NRF_GPIOTE_POLARITY_TOGGLE,
        .init_val = NRF_GPIOTE_INITIAL_VALUE_HIGH
    };

    if ( nrfx_gpiote_output_configure( ICM20948_CS_PIN, &outputConfig, &taskConfig ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Configure ICM20948_CS_PIN failed" );
        return;
	}

	nrfx_gpiote_out_task_enable( ICM20948_CS_PIN );
    spiCsTaskAddr = nrfx_gpiote_out_task_address_get( ICM20948_CS_PIN );

    if ( nrfx_ppi_channel_assign( spiStartPpiChan, timerCompareEventAddr, spiStartTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiStartPpiChan ppi channel to timerCompareEventAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_fork_assign( spiStartPpiChan, spiCsTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiStartPpiChan ppi channel fork to spiCsTaskAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_assign( spiEndPpiChan, spiEndEventAddr, spiCsTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiEndPpiChan ppi channel to spiEndEventAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_enable( spiStartPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Enable spiStartPpiChan ppi channel failed" );
        return;
    }

    if ( nrfx_ppi_channel_enable( spiEndPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Enable spiEndPpiChan ppi channel failed" );
        return;
    }
}


void Disable_Stream_Ppi_Infrastructure( void )
{
    nrfx_gpiote_out_task_disable( ICM20948_CS_PIN );
    nrfx_gpiote_pin_uninit( ICM20948_CS_PIN );
    nrfx_gpiote_channel_free( taskChannel );

    if ( nrfx_ppi_channel_disable( spiStartPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Disable spiStartPpiChan ppi channel failed" );
        return;
    }

    if ( nrfx_ppi_channel_disable( spiEndPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Disable spiEndPpiChan ppi channel failed" );
        return;
    }
}

Now in the NCS 2.6.1 the gpiote driver needs to define a gpiote instance so I modified the code above:

uint8_t taskChannel;
nrfx_gpiote_t gpioteInstance;

void Enable_Stream_Ppi_Infrastructure( void )
{
    spiStartTaskAddr = nrfx_spim_start_task_address_get( &inertialSpiInst );
    spiEndEventAddr = nrfx_spim_end_event_address_get( &inertialSpiInst );
    timerCompareEventAddr = nrfx_timer_compare_event_address_get( &inertialReadingTimerInst, NRF_TIMER_CC_CHANNEL0 );

    if ( nrfx_gpiote_channel_alloc( &gpioteInstance, &taskChannel ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Allocation gpiote channel failed" );
        return;
    }

    nrfx_gpiote_output_config_t outputConfig = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;
    nrfx_gpiote_task_config_t taskConfig = {
        .task_ch = taskChannel,
        .polarity = NRF_GPIOTE_POLARITY_TOGGLE,
        .init_val = NRF_GPIOTE_INITIAL_VALUE_HIGH
    };

    if ( nrfx_gpiote_output_configure( &gpioteInstance, ICM20948_CS_PIN, &outputConfig, &taskConfig ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Configure ICM20948_CS_PIN failed" );
        return;
	}

	nrfx_gpiote_out_task_enable( &gpioteInstance, ICM20948_CS_PIN );
    spiCsTaskAddr = nrfx_gpiote_out_task_address_get( &gpioteInstance, ICM20948_CS_PIN );

    if ( nrfx_ppi_channel_assign( spiStartPpiChan, timerCompareEventAddr, spiStartTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiStartPpiChan ppi channel to timerCompareEventAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_fork_assign( spiStartPpiChan, spiCsTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiStartPpiChan ppi channel fork to spiCsTaskAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_assign( spiEndPpiChan, spiEndEventAddr, spiCsTaskAddr ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Assign spiEndPpiChan ppi channel to spiEndEventAddr failed" );
        return;
    }

    if ( nrfx_ppi_channel_enable( spiStartPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Enable spiStartPpiChan ppi channel failed" );
        return;
    }

    if ( nrfx_ppi_channel_enable( spiEndPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Enable spiEndPpiChan ppi channel failed" );
        return;
    }
}


void Disable_Stream_Ppi_Infrastructure( void )
{
    nrfx_gpiote_out_task_disable( &gpioteInstance, ICM20948_CS_PIN );
    nrfx_gpiote_pin_uninit( &gpioteInstance, ICM20948_CS_PIN );
    nrfx_gpiote_channel_free( &gpioteInstance, taskChannel );

    if ( nrfx_ppi_channel_disable( spiStartPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Disable spiStartPpiChan ppi channel failed" );
        return;
    }

    if ( nrfx_ppi_channel_disable( spiEndPpiChan ) != NRFX_SUCCESS )
    {
        LOG_WRN( "\n[W] DEVICE - Disable spiEndPpiChan ppi channel failed" );
        return;
    }
}

But it doesn't work. Then I assumed that I had to initialize the instance with

if ( nrfx_gpiote_init( &gpioteInstance, 0 ) != NRFX_SUCCESS )
{
	LOG_WRN( "\n[W] DEVICE - Initializzation gpiote instance failed" );
	return;
}

but I found this example that for initializzation uses

#define GPIOTE_INST	NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios)

const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(GPIOTE_INST);

err = nrfx_gpiote_init(&gpiote, 0);
if (err != NRFX_SUCCESS) {
	LOG_ERR("nrfx_gpiote_init error: 0x%08X", err);
	return 0;
}

Now my doubts:

Is the use of NRFX_GPIOTE_INSTANCE(x) macro mandatory in the definition of gpiote instance? And if so, can anyone explain me the use of NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios)?

How to initialize in the rght way the gpiote driver in my case?

  • Hello,

    Is the use of NRFX_GPIOTE_INSTANCE(x) macro mandatory in the definition of gpiote instance?

    Well, you can do directly what the macro does, if you prefer that. 

    And if so, can anyone explain me the use of NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios)?

    This is used to target the correct gpiote driver. 

    What does the error in the log message say?

    I agree that this can be a bit confusing. Myself, I never get it right on the first try, but that is the cost of having an OS that is supposed to work with so many different targets. 

    Best regards,

    Edvin

Related