cancel
Showing results for 
Search instead for 
Did you mean: 

B-L072Z-LRWAN1 with sleep-on-exit feature

JLe.1
Associate

Hi there, I'm using a customized board based on B-L072Z-LRWAN1. I also use I-CUBE-LRWAN (v1.1.4), compiled on Keil uVision. Everything works fine. I can get about 2uA in Stop mode.

Now I'm doing a project requiring power consumption optimized so I enable Sleep-On-Exit feature. At first, the process of initialization -> sleep (3s) -> uplink first time (enable an interrupt here) -> sleep is fine. However, after the interrupt executed, I can see it isn't back to main function but the current consumption is about 3.5mA. I figured out somehow the uC cleared the SLEEPDEEP bit in SCR register. So inside the interrupt I've set it again. And it did partially works. The current consumption is down to less 900uA but not what I want which is about 2uA or so.

So far I've followed instructions in both programming manual PM0223 and reference manual RM0376 but no luck. Do you guys have any suggestion?

Thanks in advance.

1 REPLY 1
JLe.1
Associate

Hi guys, I've narrowed down the problem. I have a sleep function. The main block of entering stop mode is described below.

void Sleep(time_interval_ms)
{
...
 
DISABLE_IRQ();	// Commented out here
 
LL_LPM_EnableSleepOnExit();
// sleep
LPM_EnterStopMode();
 
//wake up
LPM_ExitStopMode();
 
...
}
 
void LPM_EnterStopMode(void)
{
  uint32_t tmpreg = 0U;
 
  BACKUP_PRIMASK();
 
  DISABLE_IRQ();
 
  HW_IoDeInit();
 
  /*clear wake up flag*/
  LL_PWR_ClearFlag_WU();
 
  RESTORE_PRIMASK();
 
  /* Enter Stop Mode - is a LL implementatin of HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI) */
  /* Select the regulator state in Stop mode ---------------------------------*/
  tmpreg = PWR->CR;
 
  /* Clear PDDS and LPDS bits */
  CLEAR_BIT(tmpreg, (PWR_CR_PDDS | PWR_CR_LPSDSR));
 
  /* Set LPSDSR bit according to PWR_Regulator value */
  SET_BIT(tmpreg, LL_PWR_REGU_LPMODES_LOW_POWER);
 
  /* Store the new value */
  PWR->CR = tmpreg;
 
  /* Set SLEEPDEEP bit of Cortex System Control Register */
  LL_LPM_EnableDeepSleep();
 
  /* Select Stop mode entry --------------------------------------------------*/
  __WFI();
 
  /* Reset SLEEPDEEP bit of Cortex System Control Register */
  LL_LPM_EnableSleep();
}

If I comment out the DISABLE_IRQ();, the code should work fine. However, it's original code from STM32CubeExpansion_LRWAN package as shown below

/**
 * @brief  Main program
 * @param  None
 * @retval None
 */
int main(void)
{
  /* STM32 HAL library initialization*/
  HAL_Init();
 
  /* Configure the system clock*/
  SystemClock_Config();
 
  /* Configure the hardware*/
  HW_Init();
 
  /* Configure Debug mode */
  DBG_Init();
 
  /* USER CODE BEGIN 1 */
  CMD_Init();
  /*Disable standby mode*/
  LPM_SetOffMode(LPM_APPLI_Id, LPM_Disable);
 
  PPRINTF("ATtention command interface\n\r");
  /* USER CODE END 1 */
 
  /* Configure the Lora Stack*/
  LORA_Init(&LoRaMainCallbacks, &LoRaParamInit);
 
  /* main loop*/
  while (1)
  {
    /* Handle UART commands */
    CMD_Process();
 
    if (LoraMacProcessRequest == LORA_SET)
    {
      /*reset notification flag*/
      LoraMacProcessRequest = LORA_RESET;
      LoRaMacProcess();
    }
    /*
     * low power section
     */
    DISABLE_IRQ();
    /*
     * if an interrupt has occurred after DISABLE_IRQ, it is kept pending
     * and cortex will not enter low power anyway
     * don't go in low power mode if we just received a char
     */
    if (LoraMacProcessRequest != LORA_SET)
    {
#ifndef LOW_POWER_DISABLE
      LPM_EnterLowPower();
#endif
    }
    ENABLE_IRQ();
 
    /* USER CODE BEGIN 2 */
    /* USER CODE END 2 */
  }
}

I would like to understand why it's there, and if I comment out DISABLE_IRQ();, will it affect to any thing? Otherwise any way to work around is much appreciate.

Thanks in advance!