Set GPIO with SYS_INIT() #gpio #nrf52840 #sys_init


Bob Recny
 

Greetings,

I'm working on adding a board to Zephyr. I'm attempting to use a board.c file to configure GPIO pins as output and initialize them low on start-up. I've attempted to follow existing boards, but am not being successful. device_get_binding() always returns NULL so the call to gpio_pin_configure() never occurs. I took the nrf52840dk_nrf52840 board and added CMakeLists.txt and board.c.

CMakeLists.txt:

zephyr_library()
zephyr_library_sources(board.c)

board.c:

#include <init.h>
#include <drivers/gpio.h>

#define TEST_PIN	31		/* P0.31 */

static int board_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	int ret;
	const struct device *gpio_port;
	gpio_port = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0)));

        if (!mode_asel_port_dev) {
                return -ENODEV;
        }

	ret = gpio_pin_configure(mode_asel_port_dev, TEST_PIN, GPIO_OUTPUT_HIGH);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

SYS_INIT(board_init,  POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

Any suggestions?

Thanks, Bob


Bob Recny
 

I realize I mentioned the need to set the pin low and that code above is attempting to set the pin high. If I just start the board without this code, the pin is measured low on my oscilloscope even with it unconfigured. I'm first setting the pin high so I can observe the change, then make the adjustment to low.


Bob Recny
 
Edited

Thanks Erik for the pointer. There was a race issue in initializing the pin before the driver was ready.

I changed from

SYS_INIT(board_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

to

SYS_INIT(board_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

and the pins worked as expected.