Entering stop 2 mode using HAL functions and waking up MCU using RTC

Hi ,

I want STM32Wb55 to enter stop 2 mode and wake up from RTC interrupt.

For this , I have tried to proceed with STM examples Cube WB55 Package v1.3.

Stated example can be located in project directory as below :

P-NUCLEO-WB55.Nucleo\Examples\PWR\PWR_STOP2_RTC

I am trying to use same piece of code in my mbed os setup and have included required RTC wakeup interrupt handlers and clock configuration .

I am able to enter stop 2 mode as I see same current dropping down (same as benchmark numbers obtained from example code compiled using system workbench tool )

After entering into stop 2 mode and waking MCU up using RTC doesn’t work as expected and code gets stuck somewhat:

Code is as followed :



    /*
     * Copyright (c) 2020 Arm Limited and affiliates.
     * SPDX-License-Identifier: Apache-2.0
     */
    #include "mbed.h"
    #define RTC_ASYNCH_PREDIV    0x7F
    #define RTC_SYNCH_PREDIV     0x00F9  /* 32 kHz RC/128 - 1 */

    DigitalOut led_red(LED3);

    RTC_HandleTypeDef hrtc;

    #define LED_TOGGLE_DELAY         100
    static __IO uint32_t TimingDelay;

    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_RTC_Init(void);

    /* USER CODE BEGIN PFP */
    void SYSCLKConfig_STOP(void);
    void RTC_WKUP_IRQHandler(void);


    void HAL_SYSTICK_Callback(void)
    {


      if (TimingDelay != 0)
      {
        TimingDelay--;
      }
      else
      {
        /* Toggle LED */
    	//led_red!= led_red;
        TimingDelay = LED_TOGGLE_DELAY;
      }
    }

    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      
      /* User can add his own implementation to report the HAL error return state */
      while(1)
      {

      }
      /* USER CODE END Error_Handler_Debug */
    }

    /**
    * @brief RTC MSP Initialization
    * This function configures the hardware resources used in this example
    * @param hrtc: RTC handle pointer
    * @retval None
    */
    void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
    {
      if(hrtc->Instance==RTC)
      {
      /* USER CODE BEGIN RTC_MspInit 0 */
      RCC_OscInitTypeDef RCC_OscInitStruct;
      RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;

      /* Specific procedure on STM32WB before setting RTC clock to LSI1:          */
      /* Need to clear LSE ready flag set from previous program run.              */
      /* Enable backup access */
      HAL_PWR_EnableBkUpAccess();

      /* Reset backup domain */
      LL_RCC_ForceBackupDomainReset();
      LL_RCC_ReleaseBackupDomainReset();

      /* Disable backup access */
      HAL_PWR_DisableBkUpAccess();

      /*## Configure the RTC clock source ######################################*/
      /* Enable LSI Oscillator */
      RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSI1;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      RCC_OscInitStruct.LSIState = RCC_LSI_ON;
      if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        while(1);
      }

      /* -b- Select LSI as RTC clock source */
      PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
      PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
      if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
      {
        while(1);
      }

      /* USER CODE END RTC_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_RTC_ENABLE();
      /* USER CODE BEGIN RTC_MspInit 1 */
      /*## Configure the NVIC for RTC Alarm ###################################*/
      HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 0x0, 0);
      HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
      /* USER CODE END RTC_MspInit 1 */
      }

    }


    /* USER CODE BEGIN 1 */
    /**
      * @brief  This function handles RTC Auto wake-up interrupt request.
      * @param  None
      * @retval None
      */
    void RTC_WKUP_IRQHandler(void)
    {
      HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
    }

    /**
    * @brief RTC MSP De-Initialization
    * This function freeze the hardware resources used in this example
    * @param hrtc: RTC handle pointer
    * @retval None
    */
    void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
    {
      if(hrtc->Instance==RTC)
      {
      /* USER CODE BEGIN RTC_MspDeInit 0 */

      /* USER CODE END RTC_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_RTC_DISABLE();
      /* USER CODE BEGIN RTC_MspDeInit 1 */

      /* USER CODE END RTC_MspDeInit 1 */
      }

    }

    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

      /** Initializes the CPU, AHB and APB busses clocks
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
      RCC_OscInitStruct.MSIState = RCC_MSI_ON;
      RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
      RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
      RCC_OscInitStruct.PLL.PLLN = 32;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5;
      RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
      RCC_OscInitStruct.PLL.PLLQ = 4;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
                                  |RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2;
      RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;

      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
      {
        Error_Handler();
      }
    }

    /**
      * @brief RTC Initialization Function
      * @param None
      * @retval None
      */

    static void MX_RTC_Init(void)
    {

      /* USER CODE BEGIN RTC_Init 0 */

      /* USER CODE END RTC_Init 0 */

      /* USER CODE BEGIN RTC_Init 1 */

      /* USER CODE END RTC_Init 1 */
      /** Initialize RTC Only
      */
      hrtc.Instance = RTC;
      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
      hrtc.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
      hrtc.Init.SynchPrediv = RTC_SYNCH_PREDIV ;
      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
      if (HAL_RTC_Init(&hrtc) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN RTC_Init 2 */

      /* USER CODE END RTC_Init 2 */

    }

    /* USER CODE BEGIN 4 */

    /**
      * @brief  Configures system clock after wake-up from STOP: enable HSE, PLL
      *         and select PLL as system clock source.
      * @param  None
      * @retval None
      */
    void SYSCLKConfig_STOP(void)
    {
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      uint32_t pFLatency = 0;

      /* Get the Oscillators configuration according to the internal RCC registers */
      HAL_RCC_GetOscConfig(&RCC_OscInitStruct);

      /* After wake-up from STOP reconfigure the system clock: Enable HSE and PLL */
      RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState        = RCC_HSE_ON;
      RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }

      /* Get the Clocks configuration according to the internal RCC registers */
      HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);

      /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
         clocks dividers */
      RCC_ClkInitStruct.ClockType     = RCC_CLOCKTYPE_SYSCLK;
      RCC_ClkInitStruct.SYSCLKSource  = RCC_SYSCLKSOURCE_PLLCLK;
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
      {
        Error_Handler();
      }
    }


    int main()
    {

    	//printf("Hello");
    	  /* USER CODE BEGIN 1 */
      GPIO_InitTypeDef GPIO_InitStructure;
      /* USER CODE END 1 */

      /* MCU Configuration--------------------------------------------------------*/

      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      //HAL_Init();

      /* USER CODE BEGIN Init */

      /* USER CODE END Init */

      /* Configure the system clock */
      //SystemClock_Config();

      /* USER CODE BEGIN SysInit */

      /* Set low-power mode of CPU2 */
      /* Note: Typically, action performed by CPU2 on a dual core application.
               Since this example is single core, perform it by CPU1. */
      /* Note: On STM32WB, both CPU1 and CPU2 must be in low-power mode
               to set the entire System in low-power mode, corresponding to
               the deepest low-power mode possible.
               For example, CPU1 in Stop2 mode and CPU2 in Shutdown mode
               will make system enter in Stop2 mode. */
      
      LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2);

      /* USER CODE END SysInit */

      /* Initialize all configured peripherals */
      MX_RTC_Init();
      /* USER CODE BEGIN 2 */
      

      /* USER CODE END 2 */

      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
       /* Insert 5 second delay */
       HAL_Delay(5000);

         /* Enable GPIOs clock */
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOE_CLK_ENABLE();
      __HAL_RCC_GPIOH_CLK_ENABLE();



      /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
      /* Note: Debug using ST-Link is not possible during the execution of this   */
      /*       example because communication between ST-link and the device       */
      /*       under test is done through UART. All GPIO pins are disabled (set   */
      /*       to analog input mode) including  UART I/O pins.           */

      GPIO_InitStructure.Pin = GPIO_PIN_All;
      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
      GPIO_InitStructure.Pull = GPIO_NOPULL;

      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);

      /* Disable GPIOs clock */

      __HAL_RCC_GPIOA_CLK_DISABLE();
      __HAL_RCC_GPIOB_CLK_DISABLE();
      __HAL_RCC_GPIOC_CLK_DISABLE();
      __HAL_RCC_GPIOD_CLK_DISABLE();
      __HAL_RCC_GPIOE_CLK_DISABLE();
      __HAL_RCC_GPIOH_CLK_DISABLE();

      /* In case of debugger probe attached, work-around of issue specified in "ES0394 - STM32WB55Cx/Rx/Vx device errata":
        2.2.9 Incomplete Stop 2 mode entry after a wakeup from debug upon EXTI line 48 event
          "With the JTAG debugger enabled on GPIO pins and after a wakeup from debug triggered by an event on EXTI
          line 48 (CDBGPWRUPREQ), the device may enter in a state in which attempts to enter Stop 2 mode are not fully
          effective ..."
      */
      LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
      LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);

      /* Disable all used wakeup source */
      HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);


      /* Re-enable wakeup source */
      /* ## Setting the Wake up time ############################################*/
      /* RTC Wakeup Interrupt Generation:
        the wake-up counter is set to its maximum value to yield the longuest
        stop time to let the current reach its lowest operating point.
        The maximum value is 0xFFFF, corresponding to about 33 sec. when
        RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16

        Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI))
        Wakeup Time = Wakeup Time Base * WakeUpCounter
          = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI)) * WakeUpCounter
          ==> WakeUpCounter = Wakeup Time / Wakeup Time Base

        To configure the wake up timer to 60s the WakeUpCounter is set to 0xFFFF:
        Wakeup Time Base = 16 /(~32.000KHz) = ~0.5 ms
        Wakeup Time = 0.5 ms  * WakeUpCounter
        Therefore, with wake-up counter =  0xFFFF  = 65,535
           Wakeup Time =  0,5 ms *  65,535 = 32,7675 s ~ 33 sec. */
      HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x0FFFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

        /* Enter STOP 2 mode */
        HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

        /* ... STOP2 mode ... */

        /* Configure system clock after wake-up from STOP: enable HSE, PLL and select
        PLL as system clock source (HSE and PLL are disabled in STOP mode) */
        SYSCLKConfig_STOP();
    	
      }
      /* USER CODE END 3 */
    }


Can someone please guide me what I might be doing wrong?
Is it having conflict with mbed os rtos / clock configuration?
Any help will be much appreciated.
Thanks in advance .