This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf5340 zephyr blink not waking from sleep

Hello,

I am currently trying to get a slightly modified version of the blink example from zephyr to work on the nrf5340. 

As you can see below, I am starting two threads, one for the input button and one for the LED, and as soon as the LED thread is started, the LED should start blinking. Nevertheless, it doesn't and if I take a look in the serial output, I see the "ON" message but never the "OFF" message. Therefore it seems, that the thread never wakes up from the k_msleep() function.

Does anyone have a clue for me why this is happening?

Thanks in advance! 

PS: I am using a nrf5340 DK

#include <zephyr.h>
#include <device.h>
#include <drivers/gpio.h>
#include <sys/printk.h>
#include <sys/__assert.h>
#include <string.h>

/* size of stack area used by each thread */
#define STACKSIZE 1024

/* scheduling priority used by each thread */
#define PRIORITY 7

#define LED_NODE DT_ALIAS(led0)
#define BUTTON_NODE DT_ALIAS(sw0)

struct led {
	struct gpio_dt_spec spec;
	const char *gpio_pin_name;
};

struct button {
	struct gpio_dt_spec spec;
	const char *gpio_pin_name;
};

static const struct led led = {
	.spec = GPIO_DT_SPEC_GET_OR(LED_NODE, gpios, {0}),
	.gpio_pin_name = DT_PROP_OR(LED_NODE, label, ""),
};

static const struct button button = {
	.spec = GPIO_DT_SPEC_GET_OR(BUTTON_NODE, gpios, {0}),
	.gpio_pin_name = DT_PROP_OR(BUTTON_NODE, label, ""),
};

void blink(const struct led *led, uint32_t sleep_ms, uint32_t id)
{
	gpio_pin_configure_dt(&led->spec, GPIO_OUTPUT);

	while (1) {
		gpio_pin_set_dt(&led->spec, 1);
		printk("ON\n");
		k_msleep(sleep_ms);
		
		gpio_pin_set_dt(&led->spec, 0);
		printk("OFF\n");
		k_msleep(sleep_ms);
	}
}

void blinkThread(void)
{
	blink(&led, 100, 0);
}

void inputThread(void)
{
	gpio_pin_configure_dt(&button.spec, GPIO_INPUT);

	while (1) {
		if (gpio_pin_get(button.spec.port, button.spec.pin)) {
			printk("Button pressed\n");
		}
	}
}

K_THREAD_DEFINE(blinkThread_id, STACKSIZE, blinkThread, NULL, NULL, NULL,
		PRIORITY, 0, 0);
K_THREAD_DEFINE(inputThread_id, STACKSIZE, inputThread, NULL, NULL, NULL,
		PRIORITY, 0, 0);

  • `inputThread` is infinitely calling a blocking function (gpio_pin_get), so no other events can be processed. Use button interupts f if you want to detect when a button is pressed without blocking. 

    samples\basic\button has an example on how to do this with `gpio_init_callback`.

  • Aaah thank you very much! This makes sense!

    I've adjusted the sample program now and it works as expected.

    #include <zephyr.h>
    #include <device.h>
    #include <drivers/gpio.h>
    #include <sys/printk.h>
    #include <sys/__assert.h>
    #include <string.h>
    
    /* size of stack area used by each thread */
    #define STACKSIZE 1024
    
    /* scheduling priority used by each thread */
    #define PRIORITY 7
    
    #define LED_NODE DT_ALIAS(led0)
    #define BUTTON_NODE DT_ALIAS(sw0)
    
    struct led {
    	struct gpio_dt_spec spec;
    	const char *gpio_pin_name;
    };
    
    struct button {
    	struct gpio_dt_spec spec;
    	struct gpio_callback cb_data;
    	const char *gpio_pin_name;
    };
    
    static struct led led = {
    	.spec = GPIO_DT_SPEC_GET_OR(LED_NODE, gpios, {0}),
    	.gpio_pin_name = DT_PROP_OR(LED_NODE, label, ""),
    };
    
    static struct button button = {
    	.spec = GPIO_DT_SPEC_GET_OR(BUTTON_NODE, gpios, {0}),
    	.gpio_pin_name = DT_PROP_OR(BUTTON_NODE, label, ""),
    };
    
    void blink(const struct led *led, uint32_t sleep_ms, uint32_t id)
    {
    	gpio_pin_configure_dt(&led->spec, GPIO_OUTPUT);
    
    	while (1) {
    		gpio_pin_set_dt(&led->spec, 1);
    		k_msleep(sleep_ms);
    		
    		gpio_pin_set_dt(&led->spec, 0);
    		k_msleep(sleep_ms);
    	}
    }
    
    void blinkThread(void)
    {
    	blink(&led, 100, 0);
    }
    
    void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
    	printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
    }
    
    void inputThread(void)
    {
    	gpio_pin_configure_dt(&button.spec, GPIO_INPUT);
    	gpio_pin_interrupt_configure_dt(&button.spec, GPIO_INT_EDGE_TO_ACTIVE);
    
    	gpio_init_callback(&button.cb_data, button_pressed, BIT(button.spec.pin));
    	gpio_add_callback(button.spec.port, &button.cb_data);
    }
    
    K_THREAD_DEFINE(blinkThread_id, STACKSIZE, blinkThread, NULL, NULL, NULL,
    		PRIORITY, 0, 0);
    K_THREAD_DEFINE(inputThread_id, STACKSIZE, inputThread, NULL, NULL, NULL,
    		PRIORITY, 0, 0);

Related