GPIOTE + PPI SDK v2.5.2 issue + zephyr

Hi all,

I am using nrf SDK v2.5.2 and zephyr. In my application I want to measure a signal frequency coming from a GPIO, I read about the PPI and I thought it was good for my use case.

I tried to make it work, and it required the use of GPIOTE and timers peripherals, but I am not able to make it work, the timer (configured in counter mode) does not really counts my button press (that as now they simulate the signal coming), here the code snippet:

static void pulse_count_init(uint32_t pin)
{
	uint32_t err;
	int ret;

	// Enable a GPIOTE channel in IN mode. Enable pullup when using DK buttons for test. 
	nrfx_gpiote_input_config_t gpiote_cfg;
	gpiote_cfg.pull = NRF_GPIO_PIN_PULLUP;
	// set trigger configuration
	nrfx_gpiote_trigger_config_t trigger_cfg;
	trigger_cfg.trigger = NRFX_GPIOTE_TRIGGER_LOTOHI;

	
	//nrfx_gpiote_in_event_enable(pin, false);

	// Initialize the timer in counter mode
	nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG(NRF_TIMER_BASE_FREQUENCY_16MHZ);
	timer_cfg.mode = NRF_TIMER_MODE_COUNTER;
	timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
	err = nrfx_timer_init(&timer_inst, &timer_cfg, NULL);
	NRFX_ASSERT(err == NRFX_SUCCESS);

	// Set up a PPI channel to connect the GPIOTE event to the timer COUNT task
	uint8_t gppi_ch;
	err = nrfx_gppi_channel_alloc(&gppi_ch);
	NRFX_ASSERT(err == NRFX_SUCCESS);

	///
	//trigger_cfg.p_in_channel = &gppi_ch;
	err = nrfx_gpiote_input_configure(pin, &gpiote_cfg, &trigger_cfg, NULL);
	NRFX_ASSERT(err == NRFX_SUCCESS);
	nrfx_gpiote_trigger_enable( pin, false);
	///

	nrfx_gppi_channel_endpoints_setup(gppi_ch,
		nrfx_gpiote_in_event_address_get(pin),
		nrfx_timer_task_address_get(&timer_inst, NRF_TIMER_TASK_COUNT));

	nrfx_gppi_channels_enable(BIT(gppi_ch));

	nrfx_timer_enable(&timer_inst);
}

static void pulse_count_reset(void)
{
	nrfx_timer_clear(&timer_inst);
}

static uint32_t pulse_count_sample(void)
{
	nrfx_timer_capture(&timer_inst, NRF_TIMER_CC_CHANNEL0);
	return nrfx_timer_capture_get(&timer_inst, NRF_TIMER_CC_CHANNEL0);
}

Am I missing something or doing something wrong?

Thank you very much.

Parents Reply
  • I solved!

    I was assigning the wrong channel to the GPIOTE trigger configuration, I was assigning the one of the PPI channel, instead a new one needs to be allocated in this way:

    	uint8_t out_channel;
    	err = nrfx_gpiote_channel_alloc(&out_channel);
        NRFX_ASSERT(err == NRFX_SUCCESS);
    	trigger_cfg.p_in_channel = &out_channel;
    	err = nrfx_gpiote_input_configure(pin, &gpiote_cfg, &trigger_cfg, NULL);
    	NRFX_ASSERT(err == NRFX_SUCCESS);
    	nrfx_gpiote_trigger_enable( pin, false);

Children
  • Hi. I try to make measurement of low level signal (10us-2ms). I know I should configure both edges on gpioe, but I have problem with timer and ppi. Could you help me with gpioe, timer and ppi config? It will be work on SDK2.6.0

    Best regards. PW

  • Hi, when i faced the problem i also discovered that the solution i adopted was working only for SDK 2.5.2... you must perform a porting for your reference SDK, however i can put here the solution just for reference:

    	/////////// GPIOTE configuration ///////////
    	// Enable a GPIOTE channel in IN mode. 
    	nrfx_gpiote_input_config_t gpiote_cfg;
    
    	gpiote_cfg.pull = NRF_GPIO_PIN_PULLUP; // Enable pullup to stabilize the input signal
    	// set trigger configuration
    
    	nrfx_gpiote_trigger_config_t trigger_cfg;
    
    	// Set the GPIOTE channel to be triggered by a rising edge
    	trigger_cfg.trigger = NRFX_GPIOTE_TRIGGER_LOTOHI;
    
    	// Allocate a GPIOTE channel
    	uint8_t in_channel;
    	err = nrfx_gpiote_channel_alloc(&in_channel);
        if(err != NRFX_SUCCESS)
    	{
    		LOG_ERR("Failed to allocate GPIOTE channel");
    		return -1;
    	}
    	trigger_cfg.p_in_channel = &in_channel;
    	err = nrfx_gpiote_input_configure(pin, &gpiote_cfg, &trigger_cfg, NULL);
    	if(err != NRFX_SUCCESS)
    	{
    		LOG_ERR("Failed to configure GPIOTE input");
    		return -1;
    	}
    	// enable the trigger event without using the interrupt mode (PPI has to handle the event)
    	nrfx_gpiote_trigger_enable(pin, false);
    	////////////////////////////////////////////
    
    	/////////// TIMER configuration ///////////
    	// Initialize the timer in counter mode, with 32-bit width and 16MHz frequency
    
    	nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG(NRF_TIMER_BASE_FREQUENCY_16MHZ);
    
    	timer_cfg.mode = NRF_TIMER_MODE_COUNTER;
    	timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    	err = nrfx_timer_init(&timer_inst, &timer_cfg, NULL);
    	if(err != NRFX_SUCCESS)
    	{
    		LOG_ERR("Failed to initialize timer");
    		return -1;
    	}
    	///////////////////////////////////////////
    
    	/////////// PPI configuration ///////////
    	// Set up a PPI channel to connect the GPIOTE event to the timer COUNT task
    	uint8_t gppi_ch;
    	// Allocate a PPI channel
    	err = nrfx_gppi_channel_alloc(&gppi_ch);
    	if(err != NRFX_SUCCESS)
    	{
    		LOG_ERR("Failed to allocate PPI channel");
    		return -1;
    	}
    
    	// Set up the PPI: connect the GPIOTE event to the timer COUNT task
    	nrfx_gppi_channel_endpoints_setup(gppi_ch, nrfx_gpiote_in_event_address_get(pin), nrfx_timer_task_address_get(&timer_inst, NRF_TIMER_TASK_COUNT));
    
    	nrfx_gppi_channels_enable(BIT(gppi_ch));
    	///////////////////////////////////////////
    
    	// Enable the timer
    	nrfx_timer_enable(&timer_inst);

  • Thanks.I see, there is a lot of differences between SDK2.6.0 and github /hal_nordic  repo, especcialy in nrfx_gpiote.c. So situation is unstable :)

Related