sys_poweroff not working after sleep in nrf52832_mdk

Hi Community!

I am a beginner with NRF and zephyr and currently doing a small project on nrf52832_mdk on zephyr. I want to deep sleep the system (sys_poweroff) when nothing is happening. I followed the poweroff example and its working fine. I have attached a multimeter in paralell to measure current and I can see the current drop when system poweroff smootly.

In my actual project, when I run the sys_poweroff command in main thread after initialization, it gives the expected results. The system shuts down completely and current drops in micro amperes.

int main(void)
{
	printk("initializing the system \n");
	int ret;
	int errorCode = 0;
	struct sensor_value regValue;

	/**** Initialize LED****/
	ret = led_init();
	if (ret != 0) {
		printk("could not Initialize LED \n");
	}

	/**** Initialize the SC7A20 Sensor ****/
	ret = sc7a20_sensor_init();
	if (ret != 0) {
		printk("sensor Initialization failed \n");
		errorCode = ERROR_SC7A20_SENSOR;
	}

	ret = sc7a20_interrupt_register();
	if (ret != 0) {
		printk("Could not Register Interrupt for SC7A20 \n");
		errorCode = ERROR_SC7A20_INTERRUPT;
	}

	ret = button_init();
	if (ret != 0) {
		printk("could not Initialize Button \n");
		errorCode = ERROR_BUTTON_INIT;
	}

	ret = bluetooth_init(&bluetooth_callbacks, &remote_callbacks);
	if (ret) {
		printk("bt_enable returned %d", ret);
		errorCode = ERROR_BLUETOOTH_INIT;
	}

	sc7a20_interrupt_controller_thread();

	ret = battery_measure_enable(true);
	if (ret != 0) {
		printk("Failed initialize battery measurement: %d\n", ret);
	}
	sys_poweroff();
	
}


However, If I run the sys_poweroff in another thread (or in the same main function after some sleep), it doesn't shut system appropriately. The system freezes there and current also remains same (only a little current drops). Here is a minimal code. The main objective is to poweroff the system from another thread. Its just a minimal example of situation where I get the same strange resuls

int main(void)
{
	printk("initializing the system \n");
	int ret;
	int errorCode = 0;
	struct sensor_value regValue;

	/**** Initialize LED****/
	ret = led_init();
	if (ret != 0) {
		printk("could not Initialize LED \n");
	}

	/**** Initialize the SC7A20 Sensor ****/
	ret = sc7a20_sensor_init();
	if (ret != 0) {
		printk("sensor Initialization failed \n");
		errorCode = ERROR_SC7A20_SENSOR;
	}

	ret = sc7a20_interrupt_register();
	if (ret != 0) {
		printk("Could not Register Interrupt for SC7A20 \n");
		errorCode = ERROR_SC7A20_INTERRUPT;
	}

	ret = button_init();
	if (ret != 0) {
		printk("could not Initialize Button \n");
		errorCode = ERROR_BUTTON_INIT;
	}

	ret = bluetooth_init(&bluetooth_callbacks, &remote_callbacks);
	if (ret) {
		printk("bt_enable returned %d", ret);
		errorCode = ERROR_BLUETOOTH_INIT;
	}

	sc7a20_interrupt_controller_thread();

	ret = battery_measure_enable(true);
	if (ret != 0) {
		printk("Failed initialize battery measurement: %d\n", ret);
	}
	sys_poweroff();



	if (errorCode == 0) {

		while (1) {
			battery_ble_notifier();
			k_msleep(40000);
			sys_poweroff();
		}
	} else {
		led_error_sender(errorCode);
	}

Parents
  • Hi,

     

    However, If I run the sys_poweroff in another thread (or in the same main function after some sleep), it doesn't shut system appropriately. The system freezes there and current also remains same (only a little current drops). Here is a minimal code. The main objective is to poweroff the system from another thread. Its just a minimal example of situation where I get the same strange resuls

    Do you get any assert / reset that occurs when this happens?

    What is the measured current when this code is running?

     

    Have you tried entering debug mode to see if it hits the specific function after 40 seconds?

     

    Kind regards,

    Håkon

  • First of all, Huge Thanks for replying, Hakon!

    I have observed few things which I want to share and discuss. Its all happening when I open RTT log viewer. In the first case, I was not getting enough time to open RTT viewer as system was initializing itself and immediately going to deep sleep. However, in the 2nd case, I added 40 seconds delay and in that time, I was connecting RTT viewer. So, it was not working fine when RTT viewer was opened. Today, I tried it after sleep (without opening RTT viewer and its working fine). I don't know why its not working fine with RTT viewer opened. Do you have any idea about it?

    Furthermore, I am now stuck in another problem. I am programming beacon using debugger from a nrf52832_mdk. My system is going in deep sleep mode but I have now attached a buttton interrupt which should bring it back to normal state but its not doing so. What I am expecting is that it should restart the main function in code. In the main function, I have now added the LED that should blink after the system comes out of deep sleep mode.

    Here is my device tree overlay for the button. I have checked the button interrupt individually and its working fine. But it does not wake my system from deep sleep.

    &button0 {
    gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    &gpio0 {
    wakeup-source;
    };



    Heres how I initialize the button in my code

        /**** Initialize Buit-in Button on nrf52382_mdk with callback ****/
        if (!gpio_is_ready_dt(&button)) {
            ret = -EINVAL;
        }

        ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
        if (ret != 0) {
            ret = -EINVAL;
        }

        ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_BOTH);
        if (ret != 0) {
            ret = -EINVAL;
        }

        gpio_init_callback(&button_cb_data, button_callback, BIT(button.pin));
        ret = gpio_add_callback(button.port, &button_cb_data);
        if (ret != 0) {
            ret = -EINVAL;
        }

    please tell if I am expecting something wrong (in my opinion, my main function should restart) or I have done something in setting the button interrupt here which is not suitable for waking the system from deep sleep mode?
Reply
  • First of all, Huge Thanks for replying, Hakon!

    I have observed few things which I want to share and discuss. Its all happening when I open RTT log viewer. In the first case, I was not getting enough time to open RTT viewer as system was initializing itself and immediately going to deep sleep. However, in the 2nd case, I added 40 seconds delay and in that time, I was connecting RTT viewer. So, it was not working fine when RTT viewer was opened. Today, I tried it after sleep (without opening RTT viewer and its working fine). I don't know why its not working fine with RTT viewer opened. Do you have any idea about it?

    Furthermore, I am now stuck in another problem. I am programming beacon using debugger from a nrf52832_mdk. My system is going in deep sleep mode but I have now attached a buttton interrupt which should bring it back to normal state but its not doing so. What I am expecting is that it should restart the main function in code. In the main function, I have now added the LED that should blink after the system comes out of deep sleep mode.

    Here is my device tree overlay for the button. I have checked the button interrupt individually and its working fine. But it does not wake my system from deep sleep.

    &button0 {
    gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    &gpio0 {
    wakeup-source;
    };



    Heres how I initialize the button in my code

        /**** Initialize Buit-in Button on nrf52382_mdk with callback ****/
        if (!gpio_is_ready_dt(&button)) {
            ret = -EINVAL;
        }

        ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
        if (ret != 0) {
            ret = -EINVAL;
        }

        ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_BOTH);
        if (ret != 0) {
            ret = -EINVAL;
        }

        gpio_init_callback(&button_cb_data, button_callback, BIT(button.pin));
        ret = gpio_add_callback(button.port, &button_cb_data);
        if (ret != 0) {
            ret = -EINVAL;
        }

    please tell if I am expecting something wrong (in my opinion, my main function should restart) or I have done something in setting the button interrupt here which is not suitable for waking the system from deep sleep mode?
Children
  • Hi,

     

    M.Hassan said:
    I have observed few things which I want to share and discuss. Its all happening when I open RTT log viewer. In the first case, I was not getting enough time to open RTT viewer as system was initializing itself and immediately going to deep sleep. However, in the 2nd case, I added 40 seconds delay and in that time, I was connecting RTT viewer. So, it was not working fine when RTT viewer was opened. Today, I tried it after sleep (without opening RTT viewer and its working fine). I don't know why its not working fine with RTT viewer opened. Do you have any idea about it?

    When the debugger is connected, "emulated SYSTEMOFF" is being executed, to ensure that the power domains are still being powered, ie. that the debugger isn't shut-down when entering deep sleep.

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/power.html?cp=5_2_0_17_1_0#unique_1150026639

     

    M.Hassan said:
    Furthermore, I am now stuck in another problem. I am programming beacon using debugger from a nrf52832_mdk. My system is going in deep sleep mode but I have now attached a buttton interrupt which should bring it back to normal state but its not doing so. What I am expecting is that it should restart the main function in code. In the main function, I have now added the LED that should blink after the system comes out of deep sleep mode.

    Your understanding of system off is correct. Coming out of systemoff / deep sleep will cause a reset; any code after the systemoff call will not be executed.

    This line:

    M.Hassan said:
        ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_BOTH);

    Will effectively configure a GPIOTE IN channel, rather than a GPIOTE PORT SENSE pin.

    To enable a CPU based emulation of edge-triggering, try to add this to your boards/nrf52832_mdk.overlay file:

    &gpio0 {
    	status = "okay";
    	sense-edge-mask = <0xFFFFFFFF>;
    };
    

    This will cause the "gpio_nrfx.c" to emulate edge-triggering based on the PORT event.

     

    Kind regards,

    Håkon

  • Thank You Hakan fo the amazing answer. I badly needed interrupt at both edge in my project and it was not working previously. Now, its working by adding 

    sense-edge-mask = <0xFFFFFFFF>; 

  • Glad to hear that you got things working. Hope you have a wonderful weekend!

     

    Kind regards,

    Håkon

Related