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

nRF52840 custom board k_sleep()

Dear nRF DevZone,

I have question regarding Zephyr k_sleep() function and NRF52840 timers.

I am developing an application for nRF52840 SOC and for that I am using nRF Connect SDK V1.9.1. in VS Code IDE.
As this is a custom board that was developed by another person and given to me for sw development I am currently going through the board bring-up process.

I used simple blinky as an example just to blink LED using GPIO P1.04..

As this is a custom board, I followed the process described at Nordic Webinar (https://www.youtube.com/watch?v=KSivO9Cf1TE) and based my devicetree on NRF52840 DK board.I managed to set up the board and flash an LED, but the problem is that k_sleep() and k_msleep() are not working properly.
If I give it a 1000 ms Delay, it takes more than 2000ms.

I checked the schematic for the developed board and it is using 32Mhz 20 ppm crystal oscilator.
Now I do not know what could be the problem, is it hardware or software.
Are the timers maybe configured wrong?
Could you give me suggestion where should I start looking as the cause of the problem.

Below is the code of this basic example.
Thank you in advance.


Sincerely,
Matej

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0	DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN	DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS	DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0	""
#define PIN	0
#define FLAGS	0
#endif

void main(void)
{
	const struct device *dev;
	bool led_is_on = true;
	int ret;

	dev = device_get_binding(LED0);
	if (dev == NULL) {
		return;
	}

	ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT | GPIO_ACTIVE_LOW);
	if (ret < 0) {
		return;
	}

	while (1) {
		gpio_pin_set(dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;
		k_msleep((SLEEP_TIME_MS));
	}
}

  • Hi!!!

    Actually this way you go is for Arduino only.

    Zephyr is RTOS - cool system.

    Please try to use Zephyrs timers and use next code

    void FLASH_handler()
    {
        //do something every 1000ms
    }
    
    K_WORK_DEFINE(FLASH_timer_work, FLASH_handler);
    
    void FLASH_timer_handler(struct k_timer *dummy)
    {
        k_work_submit(&FLASH_timer_work);
    }
    
    K_TIMER_DEFINE(k_FLASH_timer, FLASH_timer_handler, NULL);
    
    void main()
    {
        k_timer_start(&k_FLASH_timer,  K_MSEC(1000), K_MSEC(1000));
    }

  • Thank you for providing the code.
    I have tested it but I get the same result.

    Do you maybe have any other tips? 
    I would like to add that the board only has a 32Mhz external oscillator and not an additional 32.768 kHz oscillator, which I see is optional, as it can use an HF clock for the LF clock. Is this maybe the problem? I just do not know if I should change something in .dts files or somewhere else.

    Could you provide additional comment on why this k_sleep() "Arduino only way", as I see it being used in multiple examples and on boards that are not from Arduino, like nrf52840 DK?


    Thank you in advance.

  • If you don't have 32kHz

    #CLOCK_CONTROL
    CONFIG_CLOCK_CONTROL=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
    on board then that makes a difference. Add the following lines to config

Related