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); } }