How to link nrfx_gpiote and GPIO1 port on Zephyr?

Hi guys. 

I'm using the development board NFR52840DK and I modified the sample in zephyr\samples\boards\nrf\nrfx to use twp buttons, sw0 and sw1. 

The sw0 button reset a counter when interruption occours and sw1 increments the counter. 

I tried this using two DK buttons and eveything worked fine.

The problem occours when I try to configure an enternal button using GPOI1 and pin 3 (P1.3). The code don't work like before. Only sw0 works fine, but sw1 don't.

Using an osciloscope I observed that the pull up on P1.3 wasn't hign and looks like the pin wasn't configured properly. 

When I use P0.2 like an external button the code works again.

Then my doubt is how configure GPIO1 with nrfx? What's I'm missing? 

The configuration code is 

void gpiote_config_pins(void)
{
	nrfx_err_t err;

	nrfx_gpiote_in_config_t const in_config = {
		.sense = NRF_GPIOTE_POLARITY_HITOLO,
		.pull = NRF_GPIO_PIN_PULLUP,
		.is_watcher = false,
		.hi_accuracy = true,
		.skip_gpio_setup = false,
	};

	/* Initialize input pin to generate event on high to low transition
	 * (falling edge) and call button_handler()
	 */
	
	err = nrfx_gpiote_in_init(INPUT_PIN, &in_config, button_handler);
	if (err != NRFX_SUCCESS) {
		LOG_ERR("nrfx_gpiote_in_init error: %08x", err);
		return;
	}

	err = nrfx_gpiote_in_init(INPUT_PIN1, &in_config, button_handler);
	if (err != NRFX_SUCCESS) {
		LOG_ERR("input1 nrfx_gpiote_in_init error: %08x", err);
		return;
	}

	nrfx_gpiote_in_event_enable(INPUT_PIN, true); //once per time
	nrfx_gpiote_in_event_enable(INPUT_PIN1, true); //once per time
}

and the nrf52840dk_nrf52840.overlay is 

&button1 {
	gpios = <&gpio1 03 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};

Someone can help me with this? 
Thanks.

Parents
  • Hi,

    Which version of nRF Connect SDK are you using? It seems that the APIs in the sample have changed in v2.1.0, compared to what you have in your code snippets. Can you try the same using the latest release?

    What is the definition of INPUT_PIN1? 

    Best regards,
    Jørgen

  • Hi. 

    I'm using the SDK version v1.9.0.

    The definitions of input pins are

    #define INPUT_PIN DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
    #define INPUT_PIN1 DT_GPIO_PIN(DT_ALIAS(sw1), gpios)
    

    I will try with SDK 2.1.0.

  • Hi, 

    I tried with SDK 2.1.0 and the problem is still there. 

    To eliminate any mistake that I could have done in my early program, I tried with the original sample but I did one modification on it. This modification is an overlay for button0 . 

    If I use P0.02 in the overlay everything works fine.

    Now for P0.03 I notice that instead P1.03 the program is working with P0.03. 

    Someone has any idea why is this happening? 

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/zephyr.h>
    
    #include <nrfx_gpiote.h>
    #include <helpers/nrfx_gppi.h>
    #if defined(DPPI_PRESENT)
    #include <nrfx_dppi.h>
    #else
    #include <nrfx_ppi.h>
    #endif
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF);
    
    #define INPUT_PIN	DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
    #define OUTPUT_PIN	DT_GPIO_PIN(DT_ALIAS(led0), gpios)
    
    static void button_handler(nrfx_gpiote_pin_t pin,
    			   nrfx_gpiote_trigger_t trigger,
    			   void *context)
    {
    	LOG_INF("GPIO input event callback");
    }
    
    void main(void)
    {
    	LOG_INF("nrfx_gpiote sample on %s", CONFIG_BOARD);
    
    	nrfx_err_t err;
    	uint8_t in_channel, out_channel;
    	uint8_t ppi_channel;
    
    	/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
    	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
    		    DT_IRQ(DT_NODELABEL(gpiote), priority),
    		    nrfx_isr, nrfx_gpiote_irq_handler, 0);
    
    	/* Initialize GPIOTE (the interrupt priority passed as the parameter
    	 * here is ignored, see nrfx_glue.h).
    	 */
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_init error: 0x%08X", err);
    		return;
    	}
    
    	err = nrfx_gpiote_channel_alloc(&in_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("Failed to allocate in_channel, error: 0x%08X", err);
    		return;
    	}
    
    	err = nrfx_gpiote_channel_alloc(&out_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("Failed to allocate out_channel, error: 0x%08X", err);
    		return;
    	}
    
    	/* Initialize input pin to generate event on high to low transition
    	 * (falling edge) and call button_handler()
    	 */
    	static const nrfx_gpiote_input_config_t input_config = {
    		.pull = NRF_GPIO_PIN_PULLUP,
    	};
    	const nrfx_gpiote_trigger_config_t trigger_config = {
    		.trigger = NRFX_GPIOTE_TRIGGER_HITOLO,
    		.p_in_channel = &in_channel,
    	};
    	static const nrfx_gpiote_handler_config_t handler_config = {
    		.handler = button_handler,
    	};
    	err = nrfx_gpiote_input_configure(INPUT_PIN,
    					  &input_config,
    					  &trigger_config,
    					  &handler_config);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_input_configure error: 0x%08X", err);
    		return;
    	}
    
    	/* Initialize output pin. SET task will turn the LED on,
    	 * CLR will turn it off and OUT will toggle it.
    	 */
    	static const nrfx_gpiote_output_config_t output_config = {
    		.drive = NRF_GPIO_PIN_S0S1,
    		.input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT,
    		.pull = NRF_GPIO_PIN_NOPULL,
    	};
    	const nrfx_gpiote_task_config_t task_config = {
    		.task_ch = out_channel,
    		.polarity = NRF_GPIOTE_POLARITY_TOGGLE,
    		.init_val = 1,
    	};
    	err = nrfx_gpiote_output_configure(OUTPUT_PIN,
    					   &output_config,
    					   &task_config);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_output_configure error: 0x%08X", err);
    		return;
    	}
    
    	nrfx_gpiote_trigger_enable(INPUT_PIN, true);
    	nrfx_gpiote_out_task_enable(OUTPUT_PIN);
    
    	LOG_INF("nrfx_gpiote initialized");
    
    	/* Allocate a (D)PPI channel. */
    	err = nrfx_gppi_channel_alloc(&ppi_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gppi_channel_alloc error: 0x%08X", err);
    		return;
    	}
    
    	/* Configure endpoints of the channel so that the input pin event is
    	 * connected with the output pin OUT task. This means that each time
    	 * the button is pressed, the LED pin will be toggled.
    	 */
    	nrfx_gppi_channel_endpoints_setup(ppi_channel,
    		nrfx_gpiote_in_event_addr_get(INPUT_PIN),
    		nrfx_gpiote_out_task_addr_get(OUTPUT_PIN));
    
    	/* Enable the channel. */
    	nrfx_gppi_channels_enable(BIT(ppi_channel));
    
    	LOG_INF("(D)PPI configured, leaving main()");
    }
    

    nrf52840dk_nrf52840.overlay

    // P0.02 works
    // P1.03 for some unknow reason configure P0.03
    &button0 {
    	gpios = <&gpio1 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };
    

Reply
  • Hi, 

    I tried with SDK 2.1.0 and the problem is still there. 

    To eliminate any mistake that I could have done in my early program, I tried with the original sample but I did one modification on it. This modification is an overlay for button0 . 

    If I use P0.02 in the overlay everything works fine.

    Now for P0.03 I notice that instead P1.03 the program is working with P0.03. 

    Someone has any idea why is this happening? 

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/zephyr.h>
    
    #include <nrfx_gpiote.h>
    #include <helpers/nrfx_gppi.h>
    #if defined(DPPI_PRESENT)
    #include <nrfx_dppi.h>
    #else
    #include <nrfx_ppi.h>
    #endif
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF);
    
    #define INPUT_PIN	DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
    #define OUTPUT_PIN	DT_GPIO_PIN(DT_ALIAS(led0), gpios)
    
    static void button_handler(nrfx_gpiote_pin_t pin,
    			   nrfx_gpiote_trigger_t trigger,
    			   void *context)
    {
    	LOG_INF("GPIO input event callback");
    }
    
    void main(void)
    {
    	LOG_INF("nrfx_gpiote sample on %s", CONFIG_BOARD);
    
    	nrfx_err_t err;
    	uint8_t in_channel, out_channel;
    	uint8_t ppi_channel;
    
    	/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
    	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
    		    DT_IRQ(DT_NODELABEL(gpiote), priority),
    		    nrfx_isr, nrfx_gpiote_irq_handler, 0);
    
    	/* Initialize GPIOTE (the interrupt priority passed as the parameter
    	 * here is ignored, see nrfx_glue.h).
    	 */
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_init error: 0x%08X", err);
    		return;
    	}
    
    	err = nrfx_gpiote_channel_alloc(&in_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("Failed to allocate in_channel, error: 0x%08X", err);
    		return;
    	}
    
    	err = nrfx_gpiote_channel_alloc(&out_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("Failed to allocate out_channel, error: 0x%08X", err);
    		return;
    	}
    
    	/* Initialize input pin to generate event on high to low transition
    	 * (falling edge) and call button_handler()
    	 */
    	static const nrfx_gpiote_input_config_t input_config = {
    		.pull = NRF_GPIO_PIN_PULLUP,
    	};
    	const nrfx_gpiote_trigger_config_t trigger_config = {
    		.trigger = NRFX_GPIOTE_TRIGGER_HITOLO,
    		.p_in_channel = &in_channel,
    	};
    	static const nrfx_gpiote_handler_config_t handler_config = {
    		.handler = button_handler,
    	};
    	err = nrfx_gpiote_input_configure(INPUT_PIN,
    					  &input_config,
    					  &trigger_config,
    					  &handler_config);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_input_configure error: 0x%08X", err);
    		return;
    	}
    
    	/* Initialize output pin. SET task will turn the LED on,
    	 * CLR will turn it off and OUT will toggle it.
    	 */
    	static const nrfx_gpiote_output_config_t output_config = {
    		.drive = NRF_GPIO_PIN_S0S1,
    		.input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT,
    		.pull = NRF_GPIO_PIN_NOPULL,
    	};
    	const nrfx_gpiote_task_config_t task_config = {
    		.task_ch = out_channel,
    		.polarity = NRF_GPIOTE_POLARITY_TOGGLE,
    		.init_val = 1,
    	};
    	err = nrfx_gpiote_output_configure(OUTPUT_PIN,
    					   &output_config,
    					   &task_config);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_output_configure error: 0x%08X", err);
    		return;
    	}
    
    	nrfx_gpiote_trigger_enable(INPUT_PIN, true);
    	nrfx_gpiote_out_task_enable(OUTPUT_PIN);
    
    	LOG_INF("nrfx_gpiote initialized");
    
    	/* Allocate a (D)PPI channel. */
    	err = nrfx_gppi_channel_alloc(&ppi_channel);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gppi_channel_alloc error: 0x%08X", err);
    		return;
    	}
    
    	/* Configure endpoints of the channel so that the input pin event is
    	 * connected with the output pin OUT task. This means that each time
    	 * the button is pressed, the LED pin will be toggled.
    	 */
    	nrfx_gppi_channel_endpoints_setup(ppi_channel,
    		nrfx_gpiote_in_event_addr_get(INPUT_PIN),
    		nrfx_gpiote_out_task_addr_get(OUTPUT_PIN));
    
    	/* Enable the channel. */
    	nrfx_gppi_channels_enable(BIT(ppi_channel));
    
    	LOG_INF("(D)PPI configured, leaving main()");
    }
    

    nrf52840dk_nrf52840.overlay

    // P0.02 works
    // P1.03 for some unknow reason configure P0.03
    &button0 {
    	gpios = <&gpio1 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };
    

Children
No Data
Related