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

M33 core in nRF9160 low power mode - Constant latency mode

Hello, I am working on low power modes of MCU M33 core in nRF9160 SOC.

From the document of nRF9160 product specification v1.0, understood that there are two low power modes for M33 core 

1. System ON Mode

     a. Low power mode - Default mode after reset

     b. Constant Latency mode.

2.System OFF Mode - The device is put into System OFF mode using the REGULATORS register interface.

As you suggested in my previous case Case ID: 246126, In serial Link monitor example code, I found enter_sleep() function which is actually System OFF Mode.

I have changed the enter_Sleep() function to enter into system ON mode instead of System OFF mode as in the example.

Below are my code which I am trying to wake up using GPIO button from system ON mode - low power mode but not successful.

When I checked the TASKS_LOWPWR register in embedded segger studio mode, the value in this register is still 0  though I am writing 1 to this register using nrf_power_task_trigger(NRF_POWER_NS,NRF_POWER_TASK_LOWPWR) API

I have also checked operation of the System ON mode - Constant Latency Mode, TASKS_CONSTLAT register is still 0.

void enter_sleep(void)
{

nrf_gpio_cfg_input(CONFIG_SLM_INTERFACE_PIN,
NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(CONFIG_SLM_INTERFACE_PIN,
NRF_GPIO_PIN_SENSE_LOW);


lte_lc_power_off();
bsd_shutdown();
nrf_power_task_trigger(NRF_POWER_NS,NRF_POWER_TASK_LOWPWR);

}

Can you guide me how to enable these modes- low power and contant latency mode.

Parents Reply Children
  • Hi, could I take a look at your code?

    Based on the values you're getting, it looks like the modem is still running when in System ON Mode. Is this intended? If yes, you will need to implement PSM or eDRX intervals to reduce power consumption. 

    Best regards,

    Heidi

  • Hi Heidi,

    Here I have attached by source file, in function sleepModeEnter(shutdown_modes_t modes) i have implemented Idle mode and SYSTEM OFF mode functions.

    I have disabled the Modem using AT+CFUN=0 in lte_lc_power_off function and also bsd shutdown.


    
    
    
    #include <drivers/gpio.h>
    #include <modem/lte_lc.h>
    #include <bsd.h>
    #include <hal/nrf_power.h>
    #include <hal/nrf_regulators.h>
    #include "Uarts.h"
    #include "TaskDefs.h"
    #include "Common.h"
    
    
    #define BUTTON_PORT  DT_GPIO_KEYS_BUTTON_2_GPIOS_CONTROLLER
    #define BUTTON_PIN   DT_GPIO_KEYS_SW0_GPIOS_PIN
    
    static struct gpio_callback wakeup_cb;
    static struct device *gpio_dev;
    taskAttributes_t taskAttributeTable[TOTAL_NUMBER_OF_TASKS];
    bool isReadyToSleep = false;
    extern uartDevice_t uartDevs[];
    extern const k_tid_t tid_EvcComm; 
    
    K_SEM_DEFINE(task_state, 1, 1); //Statically define and intialize a semaphore
    
    LOG_MODULE_REGISTER(CommonTask, CONFIG_CP_LOG_LEVEL);
    
    void t_CommonTask(void *p1, void *p2, void *p3)
    {
        ARG_UNUSED(p1);
        ARG_UNUSED(p2);
        ARG_UNUSED(p3);
        LOG_INF("Periodic Task started");
        for (;;)
        {
            MonitorTasksState();
    
            if (isReadyToSleep)
            {
                sleepModeEnter(SHUTDOWN_MODE_IDLE);
            }
        }
    }
    
    void sleepModeEnter(shutdown_modes_t modes)
    {
       wakeupSource_init();
       switch(modes)
       {
          case SHUTDOWN_MODE_IDLE:
        
          uartDeinitial(&uartDevs[EVC_UART_IDX],DEVICE_PM_OFF_STATE);
          lte_lc_power_off();
          bsd_shutdown();
    
          /* As suggested in ticket 
             https://devzone.nordicsemi.com/f/nordic-q-a/59812/m33-core-in-nrf9160-low-power-mode---constant-latency-mode
             to use Zephry Idle mode API.
          */
          k_cpu_idle();
    
          break;
    
          case SHUTDOWN_MODE_SLEEP:
    
              lte_lc_power_off();
              bsd_shutdown();
    //          sys_set_power_state(SYS_POWER_STATE_DEEP_SLEEP_1);
              nrf_regulators_system_off(NRF_REGULATORS_NS);
    
              break;
    
          default:
          break;
       }
    }
    
    void SleepModeExit(struct device *gpiob,u32_t pins)
    {
        gpio_pin_disable_callback(gpiob, pins);
        gpio_remove_callback(gpiob, &wakeup_cb);
        gpio_pin_configure(gpiob, pins, GPIO_DIR_IN | GPIO_PUD_NORMAL);
    }
    
    
    void wakeupSource_init(void)
    {
    
        int err;
    
        gpio_dev = device_get_binding(BUTTON_PORT);
        if (gpio_dev == NULL)
        {
            LOG_ERR("Error in GPIO binding: %d", err);
            return;
        }
        err = gpio_pin_configure(gpio_dev, BUTTON_PIN,
                GPIO_DIR_IN | GPIO_INT | GPIO_INT_LEVEL |
                GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP |
                GPIO_INT_DEBOUNCE);
        if (err)
        {
            LOG_ERR("GPIO_0 config error: %d", err);
            return;
        }
        gpio_init_callback(&wakeup_cb,buttonPresscallback,BIT(BUTTON_PIN));
    
        err = gpio_add_callback(gpio_dev, &wakeup_cb);
        if (err)
        {
            LOG_ERR("GPIO_0 add callback error: %d", err);
            return;
        }
        err = gpio_pin_enable_callback(gpio_dev, BUTTON_PIN);
        if (err)
        {
            LOG_ERR("GPIO_0 enable callback error: %d", err);
        }
    }
    
    void buttonPresscallback(struct device *gpiob, struct gpio_callback *cb,u32_t pins)
    {
    
      SleepModeExit(gpiob,BUTTON_PIN); 
    }
    
    
    void updateTaskState(u8_t TaskNum , taskStates_t state)
    {
        if (taskAttributeTable[TaskNum].taskCurrentState != state)
        {
    
            k_sem_take(&task_state, K_FOREVER);
    
            taskAttributeTable[TaskNum].taskPreviousState = taskAttributeTable[TaskNum].taskCurrentState;
    
            taskAttributeTable[TaskNum].taskCurrentState = state;
    
            k_sem_give(&task_state);
        }
    }
    
    
    
    /*! \fn       void MonitorTasksState(void)
     *  \brief
     *  \details  This function monitors all tasks' state. If all the tasks are in sleep state
     *  \details  Put the system to sleep
     *  \param    void
     *  \return   void
     */
    void MonitorTasksState( void )
    {
        u8_t taskCounter = 0;
        bool allTasksInSleep = true;
    
    
        for(taskCounter = 1; taskCounter < TOTAL_NUMBER_OF_TASKS; taskCounter++)
        {
            if(taskAttributeTable[taskCounter].taskCurrentState != TASK_STATE_ASLEEP)
            {
                allTasksInSleep = false;
                break;
            }
        }
    
        if(allTasksInSleep == true)
        {
           isReadyToSleep = true;
        }
      
    }
    
    K_THREAD_DEFINE(tid_Common, COMMON_TASK_STACKSIZE, t_CommonTask, NULL, NULL, NULL, COMMON_TASK_PRIORITY, 0, K_NO_WAIT);

  • Do I also need to set application data profile in low power mode

    %XDATAPRFL=<power_level>

    0 – Ultra-low power

    1 – Low power

    2 – Normal

    3 – Performance

    4 – High performance

  • Hi!

    No, setting %XDATAPRFL won't have a large impact as you can read from the application note:

    As Martin mentioned in the email thread, it looks like your CPU is still running. 

    However, I think the optimal situation for your use-case would be to keep the modem turned on, in power-saving mode, for lower overall power consumption. Turning the modem off means every time you want to transmit or receive, you need to turn the modem back on and re-attach to the network which takes a lot of power compared to having the modem in PSM, which has a floor-current of 4 uA. 

    You can use the lte_lc_psm_req(bool enable) function to go to or disable PSM. 

    Best regards,

    Heidi

  • Hi Heidi,

    Yeah, I just replied to that mail chain.

    Again here I am copying the same :-)

    Still we are not clear on the end application use case( Modem should be ON with PSM or completely OFF), as of now we want to evaluate power consumption of M33 core. May be after getting hands on low power states of M33 core in SoC, we will evaluate Modem ON Idle mode with PSM, Modem ON idle mode without PSM then conclude the best possible approach.

    We are working in gas meter application. We have two modes of operation

    1. TCP client mode we call it as CALL-IN mode.

    2.TCP server mode we call it as CALL-OUT mode/continuous server mode.

    In CALL-IN mode we are not always connected to network, we will turn of the radio. If we get request from gas meter to connect to network and transfer the data to headend system(cloud), we will wakeup M33 core and turn on nRF9160 radio in SoC, register to network,  transfer data to cloud then switch off the radio and move the M33 core to sleep.For this use case we are trying to evulate sleep modes in M33 core.

    As martin suggested approach is good and best suited for our CALL-IN mode. We will consider it but before we want to have a hands on sleep mode in M33 core in SoC.

    Coming to CALL-OUT mode or continuous server mode, nRF9160 radio will always connected to network and with eDRX enabled. If there is no data transaction on the network, nRF9160 will move to eDRX  mode and M33 core should also move to sleep mode. If a remote client connection request comes to radio nRF9160 in paging time window, radio internally should wake up M33 core for processing data received.

Related