This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf52840 System on sleep mode not working 8mA drawing

I have system on sleep mode implemented which is still drawing 8mA of current i would like to take it down to 1mA or less what i need to do to get it that low?

I have two wake up sources which will wake it up from sleep mode one is RTC and other is a GPIO which comes from an accel.

#include "common.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "powermanager.h"
//#include "silego.h"
#include "nrf_drv_rtc.h"
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf_drv_clock.h"
#include "boards.h"
#include "app_error.h"
#include <nrfx_rtc.h>
#include "zoe_ubx.h"
#include "zoe_ubx_gen.h"
#include "nrf_drv_gpiote.h"
#include "rtc_handler.h"
#include "accel.h"
#include "leds.h"
#include "cellular.h"
#include "silego.h"
#include "fuelgauge.h"
#include "nrf.h"
#include "leds.h"
#include "i2c.h"
#define POWER_MANAGER_ON_CHARGER_SIGNAL (0x01)
#define POWER_MANAGER_OFF_CHARGER_SIGNAL (0x02)
#define POWER_MANAGER_TIMER_SIGNAL (0x04)
#define POWER_MANAGER_SHUTDOWN_SIGNAL (0x10)
#define POWER_MANAGER_REQUEST_SLEEP   (0x08)
#define NRF52 1
#define POWER_MANAGER_SHUTDOWN_PERCENTAGE (15)
#define POWER_MANAGER_SHUTDOWN_MILLIVOLTS (3000)
//#define SHUTDOWN_VIA_PERCENTAGE
#define SHUTDOWN_VIA_VOLTAGE

static TaskHandle_t PowerManagerThreadHandle = NULL;
static EventGroupHandle_t PowerManagerEventGroup = NULL;
static TimerHandle_t PowerManagerTimer = NULL;

static void PowerManagerThreadEntry(void * argument);
static void PowerManagerCallbackFunction(TimerHandle_t xTimer);
#define NRF52_ONRAM1_OFFRAM1  	POWER_RAM_POWER_S0POWER_On      << POWER_RAM_POWER_S0POWER_Pos \
												      | POWER_RAM_POWER_S1POWER_On      << POWER_RAM_POWER_S1POWER_Pos  \
												      | POWER_RAM_POWER_S0RETENTION_On  << POWER_RAM_POWER_S0RETENTION_Pos  \
															| POWER_RAM_POWER_S1RETENTION_On  << POWER_RAM_POWER_S1RETENTION_Pos;
#define NRF52_ONRAM1_OFFRAM0    POWER_RAM_POWER_S0POWER_On      << POWER_RAM_POWER_S0POWER_Pos     \
												      | POWER_RAM_POWER_S1POWER_On      << POWER_RAM_POWER_S1POWER_Pos      \
												      | POWER_RAM_POWER_S0RETENTION_Off << POWER_RAM_POWER_S0RETENTION_Pos  \
	                            | POWER_RAM_POWER_S1RETENTION_Off << POWER_RAM_POWER_S1RETENTION_Pos;
#define NRF52_ONRAM0_OFFRAM0    POWER_RAM_POWER_S0POWER_Off     << POWER_RAM_POWER_S0POWER_Pos     \
												      | POWER_RAM_POWER_S1POWER_Off     << POWER_RAM_POWER_S1POWER_Pos;
#define FPU_EXCEPTION_MASK 0x0000009F


volatile bool sleep = true;
volatile bool rtc_flag = false;
volatile bool rtc_config_flag = true;
void power_manager_sleep_exit(void)
{
	sleep = false;
}
bool rtc_event_flag(void)
{
	return rtc_flag = true;
}

void configure_ram_retention(void)
{
#ifdef NRF52
		// Configure nRF52 RAM retention parameters. Set for System On 64kB RAM retention
		NRF_POWER->RAM[0].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[1].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[2].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[3].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[4].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[5].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[6].POWER = NRF52_ONRAM1_OFFRAM0;
		NRF_POWER->RAM[7].POWER = NRF52_ONRAM1_OFFRAM0;
#endif //NRF52
}

int PowerManager_Init(void)
{
		BaseType_t ret;
//		ret_code_t err_code;
		ret = xTaskCreate(PowerManagerThreadEntry, "PMThread", 1*1024, NULL, POWER_MANAGER_THREAD_PRIORITY, &PowerManagerThreadHandle); //TODO: revisit priority
		if (PowerManagerThreadHandle == NULL)
		{
			SEGGER_RTT_printf(0,"ERR: PowerManagerThreadHandle is null: %d\n\r",ret);
			return -1;
		}
		PowerManagerEventGroup = xEventGroupCreate();
		if(PowerManagerEventGroup == NULL)
		{
			SEGGER_RTT_printf(0,"ERR: PowerManagerEventGroup is null\n\r");
			return -1;
		}
		PowerManagerTimer = xTimerCreate("PowerManagerTimer", pdMS_TO_TICKS(60000), pdTRUE, NULL, PowerManagerCallbackFunction);
		if(PowerManagerTimer == NULL)
		{
			SEGGER_RTT_printf(0,"ERR: PowerManagerTimer is null\n\r");
			return -1;
		}
		configure_ram_retention();
		SEGGER_RTT_printf(0,"PowerManager Init OK\n\r");
		return 0;
}

void PowerManager_ShutdownRequest(void)
{
	if(PowerManagerEventGroup == NULL)
	{
		SEGGER_RTT_printf(0,"PowerManager not ready to shutdown\n\r");
		return;
	}

	/* TODO: add any pre-shutdown code here */

	BaseType_t higherPriorityTaskWoken;
	xEventGroupSetBitsFromISR(PowerManagerEventGroup,POWER_MANAGER_SHUTDOWN_SIGNAL,&higherPriorityTaskWoken);
}

void PowerManager_OnCharger(void)
{
	if(PowerManagerEventGroup == NULL)
	{
		return;
	}
	BaseType_t higherPriorityTaskWoken;
	xEventGroupSetBitsFromISR(PowerManagerEventGroup,POWER_MANAGER_ON_CHARGER_SIGNAL,&higherPriorityTaskWoken);
}

void PowerManager_request_sleep(void)
{
	if(PowerManagerEventGroup == NULL)
	{
		return;
	}
	xEventGroupSetBits(PowerManagerEventGroup,POWER_MANAGER_REQUEST_SLEEP);
}

void PowerManager_OffCharger(void)
{
	if(PowerManagerEventGroup == NULL)
	{
		return;
	}
	BaseType_t higherPriorityTaskWoken;
	xEventGroupSetBitsFromISR(PowerManagerEventGroup,POWER_MANAGER_OFF_CHARGER_SIGNAL,&higherPriorityTaskWoken);
}

/************************************ Local Functions ****************************/
static void PowerManagerThreadEntry(void * argument)
{
	EventBits_t event = 0;
	xTimerStart(PowerManagerTimer,0);
	while(1)
	{
		SEGGER_RTT_printf(0," In PM thread \n\r");
		event = xEventGroupWaitBits(PowerManagerEventGroup,POWER_MANAGER_REQUEST_SLEEP|POWER_MANAGER_ON_CHARGER_SIGNAL | POWER_MANAGER_OFF_CHARGER_SIGNAL | POWER_MANAGER_TIMER_SIGNAL | POWER_MANAGER_SHUTDOWN_SIGNAL, true, false, portMAX_DELAY);
		if(event & POWER_MANAGER_SHUTDOWN_SIGNAL)
		{
		    SEGGER_RTT_printf(0,"PM Thread: System Shutdown request\n\r");
		    LEDs_IndicateShutdown();
			Cellular_Disable();
			vTaskDelay(pdMS_TO_TICKS(250));
			Silego_SystemShutdown();
			vTaskDelay(pdMS_TO_TICKS(1000));
			PowerManager_ShutdownRequest(); /* needed here in case last shutdown request did not work */
		}
		if(event & POWER_MANAGER_REQUEST_SLEEP)
		{
			if(rtc_config_flag)
			{
			   rtc_config_flag = false;
			   rtc_config();
			}
			lfclk_config();
			Accel_EnableWUM();
			sleep = true;
			led_turn_off();
			SEGGER_RTT_printf(0,"PM Thread: Handling Sleep for both events\n\r");
			vTaskSuspendAll();
			while(sleep)
			{
				__SEV;
				__WFE;
				__WFE;
			}
		 xTaskResumeAll();
		 if(rtc_flag)
		 {
		     Cellular_PublishHello();
		 }
		 SEGGER_RTT_printf(0,"Sleep Mode EXIT Event Triggered \n\r");
		}
		if(event & POWER_MANAGER_ON_CHARGER_SIGNAL)
		{
			SEGGER_RTT_printf(0,"PM Thread: Handling On Charger event\n\r");	
			//TODO: HandleOnChargerEvent();
		}
		if(event & POWER_MANAGER_OFF_CHARGER_SIGNAL)
		{
			SEGGER_RTT_printf(0,"PM Thread: Handling Off Charger event\n\r");	
			//TODO:HandleOffChargerEvent();
		}
		
		if(event & POWER_MANAGER_TIMER_SIGNAL)
		{
			//SEGGER_RTT_printf(0,"PM Thread: Handling Timer event\n\r");
			uint16_t batt_percentage, batt_voltage;
			batt_percentage = FuelGauge_GetPercentage();
			batt_voltage = FuelGauge_GetVoltage();
			SEGGER_RTT_printf(0,"Batt%% = %u, V=%u\n\r",(unsigned int)batt_percentage,(unsigned int)batt_voltage);
			#ifdef SHUTDOWN_VIA_PERCENTAGE
			if(batt_percentage < POWER_MANAGER_SHUTDOWN_PERCENTAGE)
			{
				SEGGER_RTT_printf(0,"Low battery percentage, requesting shutdown\n\r");
				PowerManager_ShutdownRequest();
			}
			#elif defined(SHUTDOWN_VIA_VOLTAGE)
			if(batt_voltage < POWER_MANAGER_SHUTDOWN_MILLIVOLTS)
			{
				SEGGER_RTT_printf(0,"Low battery voltage, requesting shutdown\n\r");
				PowerManager_ShutdownRequest();
			}
			#endif
		}

	}
}

static void PowerManagerCallbackFunction(TimerHandle_t xTimer)
{
	if(xTimer == PowerManagerTimer)
	{
		BaseType_t higherPriorityTaskWoken;
		xEventGroupSetBitsFromISR(PowerManagerEventGroup, POWER_MANAGER_TIMER_SIGNAL, &higherPriorityTaskWoken);
	}
}

Parents
  • Hi. 

    As you are seeing 8mA, it seems that your device isn't going to sleep. 

    Maybe you could double check that there isn't something with the wakeup source that is preventing your device from going to sleep, or waking it up.

    Are you seeing this on a custom board, or are you testing on our development kit? Are you able to reproduce the issue on the nRF52840-DK?

    Best regards, 
    Joakim

Reply
  • Hi. 

    As you are seeing 8mA, it seems that your device isn't going to sleep. 

    Maybe you could double check that there isn't something with the wakeup source that is preventing your device from going to sleep, or waking it up.

    Are you seeing this on a custom board, or are you testing on our development kit? Are you able to reproduce the issue on the nRF52840-DK?

    Best regards, 
    Joakim

Children
No Data
Related