multiple GPIOTE with DPPI button toggles LED / nrfx use example

Hello,

I use the nrfx use example and changed to 

/*
 * Copyright (c) 2019 Nordic Semiconductor ASA
 *	
 * SPDX-License-Identifier: Apache-2.0
 * 	https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/zephyr/samples/boards/nrf/nrfx/README.html
 * 
 * button 1 creats event when pushed,  which calls button_handler() callback and triggers LED 1 pin OUT task. LED is then toggled.
 */

#include <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 <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)

#define INPUT_PIN2	DT_GPIO_PIN(DT_ALIAS(sw1), gpios)
#define OUTPUT_PIN2	DT_GPIO_PIN(DT_ALIAS(led1), gpios)

static void button_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	LOG_INF("GPIO input event callback");
}

static void button_handler2(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	LOG_INF("GPIO input event callback functiopn self 2");
}

void main(void)
{
	LOG_INF("nrfx_gpiote sample on %s", CONFIG_BOARD);

	nrfx_err_t err;	//error value

	/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
	//IRQ_CONNECT initialize an interrupt handler, handler handls interrupts
	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: %08x", err);
		return;
	}
	//NRF_GPIOTE_POLARITY_HITOLO
	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,
	};

	nrfx_gpiote_in_config_t const in_config2 = {
		.sense = NRF_GPIOTE_POLARITY_LOTOHI,
		.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);

	// err = nrfx_gpiote_in_init(INPUT_PIN2, &in_config2, button_handler2);

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

	nrfx_gpiote_out_config_t const out_config = {
		.action = NRF_GPIOTE_POLARITY_TOGGLE,
		.init_state = 1,
		.task_pin = true,
	};

	// nrfx_gpiote_out_config_t const out_config2 = {
	// 	.action = NRF_GPIOTE_POLARITY_TOGGLE,
	// 	.init_state = 1,
	// 	.task_pin = true,
	// };

	/* Initialize output pin. SET task will turn the LED on,
	 * CLR will turn it off and OUT will toggle it.
	 */
	err = nrfx_gpiote_out_init(OUTPUT_PIN, &out_config);

	// err = nrfx_gpiote_out_init(OUTPUT_PIN2, &out_config2);

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

	nrfx_gpiote_in_event_enable(INPUT_PIN, true);
	nrfx_gpiote_out_task_enable(OUTPUT_PIN);

	// nrfx_gpiote_in_event_enable(INPUT_PIN2, true);
	// nrfx_gpiote_out_task_enable(OUTPUT_PIN2);

	LOG_INF("nrfx_gpiote initialized");

	/* Allocate a (D)PPI channel. */
#if defined(DPPI_PRESENT)
	uint8_t channel;
	//uint8_t channel2;
	err = nrfx_dppi_channel_alloc(&channel);
	//err = nrfx_dppi_channel_alloc(&channel2);
#else
	nrf_ppi_channel_t channel;
	err = nrfx_ppi_channel_alloc(&channel);
#endif
	if (err != NRFX_SUCCESS) {
		LOG_ERR("(D)PPI channel allocation error: %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(channel,
		nrfx_gpiote_in_event_addr_get(INPUT_PIN),
		nrfx_gpiote_out_task_addr_get(OUTPUT_PIN));

	// nrfx_gppi_channel_endpoints_setup(channel2,
	// 	nrfx_gpiote_in_event_addr_get(INPUT_PIN2),
	// 	nrfx_gpiote_out_task_addr_get(OUTPUT_PIN2));

	/* Enable (D)PPI channel. */
#if defined(DPPI_PRESENT)
	err = nrfx_dppi_channel_enable(channel);
	//err = nrfx_dppi_channel_enable(channel2);
#else
	err = nrfx_ppi_channel_enable(channel);
#endif
	if (err != NRFX_SUCCESS) {
		LOG_ERR("Failed to enable (D)PPI channel, error: %08x", err);
		return;
	}

	LOG_INF("(D)PPI configured, leaving main()");
	while(1)
	{
		k_msleep(3000);
		//printk("while sleep\n");
	}
}

I tried to creat the same process again , button when pressed toggles LED.

	/* 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);

	// err = nrfx_gpiote_in_init(INPUT_PIN2, &in_config2, button_handler2);

I get the error

can someone explain what I am doing wrong ?

Many thanks,

Christoph

Parents
  • Hi Christoph.

    Thank you for your patience.

    I started with the sample you are using, and flashed onto the nrf5340dk. The sample works as intented.

    Next, I modified the main.c code as per your requirements (to use two buttons to control two leds). 

    I got this information from your code / comments. Also, I am using ncs1.9.1.

    After modifications, I am able to build, flash and see the correct output. 

    Pins / port correctly configured without problem.

    I am able to use both of the buttons (sw0 and sw1) to control both of the leds (led0 and led1) independently.

    Here is snapshot of output:

    I am attaching complete zip format for your reference. c_298038_nrfx.zip

    You may unzip and try to build and flash this on the DK and see if you are getting same results as mine or not.

    You may then compare with your code if required. Let me know accordingly.

    Hope it helps.

    Regards,

    Naeem

Reply
  • Hi Christoph.

    Thank you for your patience.

    I started with the sample you are using, and flashed onto the nrf5340dk. The sample works as intented.

    Next, I modified the main.c code as per your requirements (to use two buttons to control two leds). 

    I got this information from your code / comments. Also, I am using ncs1.9.1.

    After modifications, I am able to build, flash and see the correct output. 

    Pins / port correctly configured without problem.

    I am able to use both of the buttons (sw0 and sw1) to control both of the leds (led0 and led1) independently.

    Here is snapshot of output:

    I am attaching complete zip format for your reference. c_298038_nrfx.zip

    You may unzip and try to build and flash this on the DK and see if you are getting same results as mine or not.

    You may then compare with your code if required. Let me know accordingly.

    Hope it helps.

    Regards,

    Naeem

Children
No Data
Related